diff --git a/deployment-apps/02-M-TIC_idx_indexes_base/default/indexes.conf b/deployment-apps/02-M-TIC_idx_indexes_base/default/indexes.conf index 821331f..cc7d968 100644 --- a/deployment-apps/02-M-TIC_idx_indexes_base/default/indexes.conf +++ b/deployment-apps/02-M-TIC_idx_indexes_base/default/indexes.conf @@ -62,4 +62,38 @@ datatype = metric [idx_ldap] -[idx_m-tic_synology] \ No newline at end of file +[idx_m-tic_synology] + +# nmon data ingested as metrics +[os-unix-nmon-metrics] +disabled = false +coldPath = $SPLUNK_DB/os-unix-nmon-metrics/colddb +datatype = metric +homePath = $SPLUNK_DB/os-unix-nmon-metrics/db +splitByIndexKeys = metric_name,host +thawedPath = $SPLUNK_DB/os-unix-nmon-metrics/thaweddb +repFactor = auto + +# nmon data ingested as regular events +[os-unix-nmon-events] +disabled = false +coldPath = $SPLUNK_DB/os-unix-nmon-events/colddb +homePath = $SPLUNK_DB/os-unix-nmon-events/db +thawedPath = $SPLUNK_DB/os-unix-nmon-events/thaweddb +repFactor = auto + +# nmon config ingested as regular events +[os-unix-nmon-config] +disabled = false +coldPath = $SPLUNK_DB/os-unix-nmon-config/colddb +homePath = $SPLUNK_DB/os-unix-nmon-config/db +thawedPath = $SPLUNK_DB/os-unix-nmon-config/thaweddb +repFactor = auto + +# nmon internal data +[os-unix-nmon-internal] +disabled = false +coldPath = $SPLUNK_DB/os-unix-nmon-internal/colddb +homePath = $SPLUNK_DB/os-unix-nmon-internal/db +thawedPath = $SPLUNK_DB/os-unix-nmon-internal/thaweddb +repFactor = auto \ No newline at end of file diff --git a/deployment-apps/SA-metricator-for-nmon/README.md b/deployment-apps/SA-metricator-for-nmon/README.md new file mode 100644 index 0000000..c14469e --- /dev/null +++ b/deployment-apps/SA-metricator-for-nmon/README.md @@ -0,0 +1,60 @@ +# SA-metricator-for-nmon + +Copyright 2017 Octamis limited - Copyright 2017 Guilhem Marchand + +All rights reserved. + +Sample indexes.conf: + +# indexes.conf + +######################## +# default Indexes scheme +######################## + +# The default indexing scheme uses a combination of 4 indexes: + +# - metrics ingested with the metric stores +# - nmon metric data ingested as regular events +# - nmon configuration data ingested as regular events +# - application internal data ingested as regular events + +# CUSTOMIZATION: + +# if you need more segmentation, for example if you are indexing data from several data centers, we suggest you use +# the same naming convention across naming convention such that you easily customize eventtypes and macros + +# nmon data ingested as metrics +[os-unix-nmon-metrics] +disabled = false +coldPath = $SPLUNK_DB/os-unix-nmon-metrics/colddb +datatype = metric +homePath = $SPLUNK_DB/os-unix-nmon-metrics/db +splitByIndexKeys = metric_name,host +thawedPath = $SPLUNK_DB/os-unix-nmon-metrics/thaweddb +repFactor = auto + +# nmon data ingested as regular events +[os-unix-nmon-events] +disabled = false +coldPath = $SPLUNK_DB/os-unix-nmon-events/colddb +homePath = $SPLUNK_DB/os-unix-nmon-events/db +thawedPath = $SPLUNK_DB/os-unix-nmon-events/thaweddb +repFactor = auto + +# nmon config ingested as regular events +[os-unix-nmon-config] +disabled = false +coldPath = $SPLUNK_DB/os-unix-nmon-config/colddb +homePath = $SPLUNK_DB/os-unix-nmon-config/db +thawedPath = $SPLUNK_DB/os-unix-nmon-config/thaweddb +repFactor = auto + +# nmon internal data +[os-unix-nmon-internal] +disabled = false +coldPath = $SPLUNK_DB/os-unix-nmon-internal/colddb +homePath = $SPLUNK_DB/os-unix-nmon-internal/db +thawedPath = $SPLUNK_DB/os-unix-nmon-internal/thaweddb +repFactor = auto + diff --git a/deployment-apps/SA-metricator-for-nmon/default/app.conf b/deployment-apps/SA-metricator-for-nmon/default/app.conf new file mode 100644 index 0000000..82ae58e --- /dev/null +++ b/deployment-apps/SA-metricator-for-nmon/default/app.conf @@ -0,0 +1,19 @@ +# +# Splunk app configuration file +# + +[install] +is_configured = 0 + +[package] +id = SA-metricator-for-nmon +check_for_updates = true + +[ui] +is_visible = 0 +label = SA-metricator-for-nmon + +[launcher] +author = Guilhem Marchand for Octamis +description = SA-metricator-for-nmon +version = 1.0.4 diff --git a/deployment-apps/SA-metricator-for-nmon/default/eventtypes.conf b/deployment-apps/SA-metricator-for-nmon/default/eventtypes.conf new file mode 100644 index 0000000..7a3d5b5 --- /dev/null +++ b/deployment-apps/SA-metricator-for-nmon/default/eventtypes.conf @@ -0,0 +1,47 @@ +# eventtypes.conf + +##### Customization #### +# In case of index name customization or spliting data into multiple indexes, you should +# copy the eventtypes.conf to local/eventtypes.conf to adapt eventtypes definition to your needs +######################## + +#################### +# All data # +#################### + +[nmon] +search = (index=os-unix-nmon-events* OR index=os-unix-nmon-internal* OR index=os-unix-nmon-config*) + +#################### +# Performance data # +#################### + +[nmon:events] +search = index=os-unix-nmon-events* sourcetype=nmon_data + +##################### +# Others type of data +##################### + +[nmon:config] +search = index=os-unix-nmon-config* sourcetype=nmon_config + +[nmon:collect] +search = index=os-unix-nmon-internal* sourcetype=nmon_collect + +[nmon:processing] +search = index=os-unix-nmon-internal* sourcetype=nmon_processing + +[nmon:clean] +search = index=os-unix-nmon-internal* sourcetype=nmon_clean + +################### +# CIM normalization +################### + +# CIM - Uptime stdout (nmon external) +[uptime] +search = index=os-unix-nmon-events* sourcetype=nmon_data type=UPTIME + +[inventory] +search = index=os-unix-nmon-config* sourcetype=nmon_config diff --git a/deployment-apps/SA-metricator-for-nmon/default/props.conf b/deployment-apps/SA-metricator-for-nmon/default/props.conf new file mode 100644 index 0000000..a22c2da --- /dev/null +++ b/deployment-apps/SA-metricator-for-nmon/default/props.conf @@ -0,0 +1,171 @@ +# props.conf + +############################### +# nmon metrics for metric store +############################### + +# Introduced with Splunk 7, metrics are now natively supported +# Nmon uses its own copy of the default metrics_csv sourcetype + +[nmon_metrics_csv] +SHOULD_LINEMERGE = False +pulldown_type = true +INDEXED_EXTRACTIONS = csv +ADD_EXTRA_TIME_FIELDS = False +KV_MODE = none +TIMESTAMP_FIELDS = metric_timestamp +TIME_FORMAT = %s.%Q +category = Metrics +description = Comma-separated value format for metrics. Nmon implementation. + +# Overwritting default host field based on event data for nmon_data sourcetype (useful when managing Nmon central shares) +TRANSFORMS-hostfield=nmon_metrics_csv_hostoverride + +# Metrics can be sent by http using the Splunk Http Event Collector (HEC) +[nmon_metrics_http] +TIME_PREFIX = metric_timestamp=\"(\d+)\" +TIME_FORMAT = %s +TRANSFORMS-nmon_metrics_http = nmon_metrics_http_host, nmon_metrics_http_metric_name, nmon_metrics_http_metric_value, nmon_metrics_http_dims, nmon_metrics_http_OStype, nmon_metrics_http_serialnum +NO_BINARY_CHECK = true +SHOULD_LINEMERGE = false +pulldown_type = 1 +category = Metrics + +######################## +# nmon metrics as events +######################## + +# This sourcetype stanza will be used to index nmon csv converted data +# Every generated csv file will contain a CSV header used by Splunk to identify fields + +[nmon_data] +FIELD_DELIMITER=, +FIELD_QUOTE=" +HEADER_FIELD_LINE_NUMBER=1 + +# your settings +INDEXED_EXTRACTIONS=csv +NO_BINARY_CHECK=1 +SHOULD_LINEMERGE=false +TIMESTAMP_FIELDS=ZZZZ +TIME_FORMAT=%d-%m-%Y %H:%M:%S + +# set by detected source type +KV_MODE=none +pulldown_type=true + +# Leaving PUNCT enabled can impact indexing performance, and uses space +# For structured data, it has poor interest and shall be deactivated +ANNOTATE_PUNCT=false + +# Overwritting default host field based on event data for nmon_data sourcetype (useful when managing Nmon central shares) +TRANSFORMS-hostfield=nmon_data_hostoverride + +# nmon_data sent over http using the Splunk Http Event Collector (HEC) +# This sourcetype will be automatically renamed to nmon_data + +[nmon_data_http] +SHOULD_LINEMERGE=false +NO_BINARY_CHECK=true +CHARSET=UTF-8 +TIME_FORMAT=%s +TIME_PREFIX=timestamp=" +MAX_TIMESTAMP_LOOKAHEAD=26 +KV_MODE=auto + +# Apply indexing time parsing configuration +TRANSFORMS-nmon_data_http = nmon_data_http_host, nmon_data_http_OStype, nmon_data_http_type, nmon_data_http_sourcetype + +# For search time extractions, activate kvmode to auto for that source +[source::nmon_data:http] +KV_MODE=auto + +######################## +# nmon processing events +######################## + +[nmon_processing] +SHOULD_LINEMERGE=false +NO_BINARY_CHECK=true +CHARSET=UTF-8 +TIME_PREFIX=^ +TIME_FORMAT=%d-%m-%Y %H:%M:%S +MAX_TIMESTAMP_LOOKAHEAD=19 +LINE_BREAKER=([\n\r]+)\d{2}-\d{2}-\d{4}\s\d{2}:\d{2}:\d{2} +TRUNCATE=999999 + +# Deactivate KV +KV_MODE=none + +#################### +# nmon config events +#################### + +[nmon_config] +SHOULD_LINEMERGE=false +NO_BINARY_CHECK=true +CHARSET=UTF-8 +TIME_PREFIX=^CONFIG, +TIME_FORMAT=%d-%b-%Y:%H:%M.%S +LINE_BREAKER=([\r\n]+)CONFIG,\d{2}-\w{3}-\d{4}:\d{2}:\d{2}\.\d{2}, +TRUNCATE=0 +MAX_EVENTS=100000 +MAX_TIMESTAMP_LOOKAHEAD=30 + +# Deactivate KV +KV_MODE = none + +# Overwritting default host field based on event data for nmon_data sourcetype (useful when managing Nmon central shares) +TRANSFORMS-hostfield=nmon_config_hostoverride + +# nmon_config sent over http +[nmon_config:http] +SHOULD_LINEMERGE=false +NO_BINARY_CHECK=true +CHARSET=UTF-8 +LINE_BREAKER=([\r\n]+)timestamp=\" +MAX_EVENTS=100000 +TIME_FORMAT=%s +TIME_PREFIX=timestamp=" +TRUNCATE=0 + +# Rewrite the source Metadata to manage search time extraction +TRANSFORMS-nmon_config_http = nmon_config_http_rewrite_host, nmon_config_http_rewrite_sourcetype + +# For search heads +[source::nmon_config:http] +KV_MODE=none + +##################### +# nmon collect events +##################### + +[nmon_collect] +SHOULD_LINEMERGE=false +NO_BINARY_CHECK=true +CHARSET=UTF-8 +TIME_PREFIX=^ +TIME_FORMAT=%d-%m-%Y %H:%M:%S +MAX_TIMESTAMP_LOOKAHEAD=19 +LINE_BREAKER=([\n\r]+)\d{2}-\d{2}-\d{4}\s\d{2}:\d{2}:\d{2} +TRUNCATE=999999 + +# Deactivate KV +KV_MODE = none + +################### +# nmon clean events +################### + +[nmon_clean] +SHOULD_LINEMERGE=false +NO_BINARY_CHECK=true +CHARSET=UTF-8 +TIME_PREFIX=^ +TIME_FORMAT=%d-%m-%Y %H:%M:%S +MAX_TIMESTAMP_LOOKAHEAD=19 +LINE_BREAKER=([\n\r]+)\d{2}-\d{2}-\d{4}\s\d{2}:\d{2}:\d{2} +TRUNCATE=999999 + +# Deactivate KV +KV_MODE = none diff --git a/deployment-apps/SA-metricator-for-nmon/default/transforms.conf b/deployment-apps/SA-metricator-for-nmon/default/transforms.conf new file mode 100644 index 0000000..7c542af --- /dev/null +++ b/deployment-apps/SA-metricator-for-nmon/default/transforms.conf @@ -0,0 +1,114 @@ +# transforms.conf + +############## +# nmon metrics +############## + +# host Meta overridden with 5th column +[nmon_metrics_csv_hostoverride] +DEST_KEY = MetaData:Host +REGEX = ^\d*,\"{0,1}[^\"\,]*\"{0,1},\"{0,1}[^\"\,]*\"{0,1}[^\"\,]*\"{0,1},\"{0,1}[^\"\,]*\"{0,1},\"{0,1}([^\"\,]*)\"{0,1} +FORMAT = host::$1 + +# Metrics sent over http - host +[nmon_metrics_http_host] +DEST_KEY = MetaData:Host +REGEX = hostname=\"([^\"]*)\" +FORMAT = host::$1 + +# Metrics sent over http - metric_name +[nmon_metrics_http_metric_name] +REGEX = metric_name=\"([^\"]*)\" +FORMAT = metric_name::$1 +WRITE_META = true + +[nmon_metrics_http_metric_value] +REGEX = _value=\"([\d|\.]*)\" +FORMAT = _value::$1 +WRITE_META = true + +# Metrics sent over http - dimensions +[nmon_metrics_http_dims] +REGEX = (dimension\_\w*)=\"([^\"]*)\" +FORMAT = $1::$2 +WRITE_META = true +REPEAT_MATCH = true + +# Metrics sent over http - OStype +[nmon_metrics_http_OStype] +REGEX = OStype=\"([^\"]*)\" +FORMAT = OStype::$1 +WRITE_META = true + +# Metrics sent over http - serialnum +[nmon_metrics_http_serialnum] +REGEX = serialnum=\"([^\"]*)\" +FORMAT = serialnum::$1 +WRITE_META = true + +########### +# nmon data +########### + +# Host override based on event data form nmon_data sourcetype + +[nmon_data_hostoverride] +DEST_KEY = MetaData:Host +REGEX = ^\"{0,1}[a-zA-Z0-9\_]+\"{0,1},\"{0,1}[a-zA-Z0-9\-\_\.]+\"{0,1},\"{0,1}([a-zA-Z0-9\-\_\.]+)\"{0,1},.+ +FORMAT = host::$1 + +# nmon data as events sent over http - host indexed field +[nmon_data_http_host] +DEST_KEY = MetaData:Host +REGEX = hostname=\"([^\"]*)\" +FORMAT = host::$1 + +# nmon data as events sent over http - OStype indexed field +[nmon_data_http_OStype] +REGEX = \sOStype=\"([^\"]*)\" +WRITE_META = true +FORMAT = OStype::$1 +DEFAULT_VALUE = NULL + +# nmon data as events sent over http - type indexed field +[nmon_data_http_type] +REGEX = \stype=\"([^\"]*)\" +WRITE_META = true +FORMAT = type::$1 +DEFAULT_VALUE = NULL + +# nmon data as events sent over http - rewrite sourcetype +[nmon_data_http_sourcetype] +DEST_KEY = MetaData:Sourcetype +REGEX = .* +FORMAT = sourcetype::nmon_data + +############# +# nmon config +############# + +# Host override based on event data form nmon_config sourcetype + +[nmon_config_hostoverride] +DEST_KEY = MetaData:Host +REGEX = CONFIG\,[a-zA-Z0-9\-\:\.]+\,([a-zA-Z0-9\-\_\.]+)\,[a-zA-Z0-9\-\_\.]+ +FORMAT = host::$1 + +# nmon_config sent over http + +[nmon_config_http_rewrite_host] +DEST_KEY = MetaData:Host +REGEX = host=\"{0,}([a-zA-Z0-9\-\_\.]+)\"{0,} +FORMAT = host::$1 + +# nmon_config source +[nmon_config_http_rewrite_source] +DEST_KEY = MetaData:Source +REGEX = .* +FORMAT = source::configdata:http + +# nmon_config sourcetype +[nmon_config_http_rewrite_sourcetype] +DEST_KEY = MetaData:Sourcetype +REGEX = .* +FORMAT = sourcetype::nmon_config diff --git a/deployment-apps/SA-metricator-for-nmon/metadata/default.meta b/deployment-apps/SA-metricator-for-nmon/metadata/default.meta new file mode 100644 index 0000000..539d8c4 --- /dev/null +++ b/deployment-apps/SA-metricator-for-nmon/metadata/default.meta @@ -0,0 +1,7 @@ + +# Application-level permissions + +[] +owner = admin +access = read : [ * ], write : [ admin ] +export = system diff --git a/deployment-apps/SA-metricator-for-nmon/splunkbase.manifest b/deployment-apps/SA-metricator-for-nmon/splunkbase.manifest new file mode 100644 index 0000000..9099d07 --- /dev/null +++ b/deployment-apps/SA-metricator-for-nmon/splunkbase.manifest @@ -0,0 +1,115 @@ +{ + "version": "1.0", + "date": "2022-11-14T10:00:27.298956691Z", + "hashAlgorithm": "SHA-256", + "app": { + "id": 3949, + "version": "1.0.4", + "files": [ + { + "path": "license.txt", + "hash": "16b42e565a723507298adfca58a3e970f87f1fdde7dc638a02fa320daf918979" + }, + { + "path": "metadata/default.meta", + "hash": "6b6c91fc18940aeb1580da6c06f92810beef8af632f73714070bae9e4a777af2" + }, + { + "path": "default/app.conf", + "hash": "4e9ee565f1d95ec2e0edba40945ed3dbd21a8973eca5db675c5777fb11245b00" + }, + { + "path": "default/props.conf", + "hash": "865bce58bea6b7ae664d6b1f4d95457dfb41ab34e4588af9efa2625ac36325eb" + }, + { + "path": "default/transforms.conf", + "hash": "4c575ce58234455c879370ab8f69ed4ea6b9bd7901b6bceb53ac1049c9ad1b82" + }, + { + "path": "default/eventtypes.conf", + "hash": "66cfa9ca9fe2fecce3d1a15692a7fa2dad36df96773050c14316d0977b4ee72b" + }, + { + "path": "static/appLogo_2x.png", + "hash": "845f9bcdcd947b60e7c6d110f03debad96fee327b13a1bda2457788e069c350e" + }, + { + "path": "static/appIconAlt.png", + "hash": "e0611349e349b6cee55d123f85ed286a4ac2c0f1bbdbbedcbf230207bc2404ee" + }, + { + "path": "static/appIconAlt_2x.png", + "hash": "5434fede7130f1bacc4d8e3ec48f2b3bd67367f55658b6d07d5b232b8f60f522" + }, + { + "path": "static/appLogo.png", + "hash": "0736204483f4205c90d49c1f212e70d4e15c4d79aee19d43a0ab8247455118d1" + }, + { + "path": "static/appIcon.png", + "hash": "e0611349e349b6cee55d123f85ed286a4ac2c0f1bbdbbedcbf230207bc2404ee" + }, + { + "path": "static/appIcon_2x.png", + "hash": "5434fede7130f1bacc4d8e3ec48f2b3bd67367f55658b6d07d5b232b8f60f522" + }, + { + "path": "README.md", + "hash": "4cb28100eb177f1de9a173a7861e6e9a9b847ef55d819cc42ce41b2dc2b9f414" + } + ] + }, + "products": [ + { + "platform": "splunk", + "product": "enterprise", + "versions": [ + "7.0", + "7.1", + "7.2", + "7.3", + "8.0", + "8.1", + "8.2", + "9.0" + ], + "architectures": [ + "x86_64" + ], + "operatingSystems": [ + "windows", + "linux", + "macos", + "freebsd", + "solaris", + "aix" + ] + }, + { + "platform": "splunk", + "product": "cloud", + "versions": [ + "7.0", + "7.1", + "7.2", + "7.3", + "8.0", + "8.1", + "8.2", + "9.0" + ], + "architectures": [ + "x86_64" + ], + "operatingSystems": [ + "windows", + "linux", + "macos", + "freebsd", + "solaris", + "aix" + ] + } + ] +} \ No newline at end of file diff --git a/deployment-apps/SA-metricator-for-nmon/static/appIcon.png b/deployment-apps/SA-metricator-for-nmon/static/appIcon.png new file mode 100644 index 0000000..b283ac0 Binary files /dev/null and b/deployment-apps/SA-metricator-for-nmon/static/appIcon.png differ diff --git a/deployment-apps/SA-metricator-for-nmon/static/appIconAlt.png b/deployment-apps/SA-metricator-for-nmon/static/appIconAlt.png new file mode 100644 index 0000000..b283ac0 Binary files /dev/null and b/deployment-apps/SA-metricator-for-nmon/static/appIconAlt.png differ diff --git a/deployment-apps/SA-metricator-for-nmon/static/appIconAlt_2x.png b/deployment-apps/SA-metricator-for-nmon/static/appIconAlt_2x.png new file mode 100644 index 0000000..00ac7be Binary files /dev/null and b/deployment-apps/SA-metricator-for-nmon/static/appIconAlt_2x.png differ diff --git a/deployment-apps/SA-metricator-for-nmon/static/appIcon_2x.png b/deployment-apps/SA-metricator-for-nmon/static/appIcon_2x.png new file mode 100644 index 0000000..00ac7be Binary files /dev/null and b/deployment-apps/SA-metricator-for-nmon/static/appIcon_2x.png differ diff --git a/deployment-apps/SA-metricator-for-nmon/static/appLogo.png b/deployment-apps/SA-metricator-for-nmon/static/appLogo.png new file mode 100644 index 0000000..f6b6881 Binary files /dev/null and b/deployment-apps/SA-metricator-for-nmon/static/appLogo.png differ diff --git a/deployment-apps/SA-metricator-for-nmon/static/appLogo_2x.png b/deployment-apps/SA-metricator-for-nmon/static/appLogo_2x.png new file mode 100644 index 0000000..ef699ce Binary files /dev/null and b/deployment-apps/SA-metricator-for-nmon/static/appLogo_2x.png differ diff --git a/deployment-apps/TA-metricator-for-nmon/README.md b/deployment-apps/TA-metricator-for-nmon/README.md new file mode 100644 index 0000000..c573001 --- /dev/null +++ b/deployment-apps/TA-metricator-for-nmon/README.md @@ -0,0 +1,5 @@ +# TA-metricator-for-nmon + +Copyright 2017 Octamis - Copyright 2017 Guilhem Marchand + +All rights reserved. diff --git a/deployment-apps/TA-metricator-for-nmon/README/nmon.conf.spec b/deployment-apps/TA-metricator-for-nmon/README/nmon.conf.spec new file mode 100644 index 0000000..4f07139 --- /dev/null +++ b/deployment-apps/TA-metricator-for-nmon/README/nmon.conf.spec @@ -0,0 +1,238 @@ +# nmon.conf.spec + +# This file contains possibles attributes and values you can use to configure nmon processes generation. + +# There is an nmon.conf in $SPLUNK_HOME/etc/[nmon|TA-nmon|PA-nmon]/default/. To set custom configurations, +# place an nmon.conf in $SPLUNK_HOME/etc/[nmon|TA-nmon|PA-nmon]/default/. + +# *** FILE ENCODING: UTF-8 ! *** +# When creating a local/nmon.conf, pay attention to file encoding specially when working under Windows. +# The file must be UTF-8 encoded or you may run in trouble. + +# *** DON'T MODIFY THIS FILE *** + +######################################################################################################################## +### NMON COLLECT OPTIONS ### +######################################################################################################################## + +# The metricator_helper.sh input script is set by default to run every 60 seconds +# If Nmon is not running, the script will start Nmon using the configuration above + +### +### FIFO options: +### + +# Using FIFO files (named pipe) are now used to minimize the CPU footprint of the technical addons +# As such, it is not required anymore to use short cycle of Nmon run to reduce the CPU usage + +# You can still want to manage the volume of data to be generated by managing the interval and snapshot values +# as a best practice recommendation, the time to live of nmon processes writing to FIFO should be 24 hours + +# value for interval: time in seconds between 2 performance measures +fifo_interval= + +# value for snapshot: number of measure to perform +fifo_snapshot= + +######################################################################################################################## +### VARIOUS COMMON OPTIONS ### +######################################################################################################################## + +# Time in seconds of margin before running a new iteration of Nmon process to prevent data gaps between 2 iterations of Nmon +# the metricator_helper.sh script will spawn a new Nmon process when the age in seconds of the current process gets higher than this value + +# The endtime is evaluated the following way: +# endtime=$(( ${interval} * ${snapshot} - ${endtime_margin} )) + +# When the endtime gets higher than the endtime_margin, a new Nmon process will be spawned +# default value to 240 seconds which will start a new process 4 minutes before the current process ends + +# Setting this value to "0" will totally disable this feature + +# Default value: +# endtime_margin="240" + +endtime_margin= + +### NFS OPTIONS ### + +# Change to "1" to activate NFS V2 / V3 (option -N) for AIX hosts +# Default value: +# AIX_NFS23="0" + +AIX_NFS23= + +# Change to "1" to activate NFS V4 (option -NN) for AIX hosts +# Default value: +# AIX_NFS4="0" + +AIX_NFS4= + +# Change to "1" to activate NFS V2 / V3 / V4 (option -N) for Linux hosts +# Note: Some versions of Nmon introduced a bug that makes Nmon to core when activating NFS, ensure your version is not outdated +# Default value: +# Linux_NFS="0" + +Linux_NFS= + +######################################################################################################################## +### LINUX OPTIONS ### +######################################################################################################################## + +# Change the priority applied while looking at nmon binary +# by default, the metricator_helper.sh script will use any nmon binary found in PATH +# Set to "1" to give the priority to embedded nmon binaries +# Note: Since release 1.6.07, priority is given by default to embedded binaries + +# Default value: +# Linux_embedded_nmon_priority="1" + +Linux_embedded_nmon_priority= + +# Change the limit for processes and disks capture of nmon for Linux +# In default configuration, nmon will capture most of the process table by capturing main consuming processes +# This function is percentage limit of CPU time, with a default limit of 0.01 +# Changing this value can influence the volume of data to be generated, and the associated CPU overhead for that data to be parsed + +# Possible values are: +# Linux_unlimited_capture="0" --> Default nmon behavior, capture main processes (no -I option) +# Linux_unlimited_capture="-1" --> Set the capture mode to unlimited (-I -1) +# Linux_unlimited_capture="x.xx" --> Set the percentage limit to a custom value, ex: "0.01" will set "-I 0.01" +Linux_unlimited_capture= + +# Set the maximum number of devices collected by Nmon, default is set to 1500 devices +# Increase this value if you have systems with more devices +# Up to 3000 devices will be taken in charge by the Application (hard limit in nmonparser.py / nmonparser.pl) + +# Default value: +# Linux_devices="1500" + +Linux_devices= + +# Enable disks extended statistics (DG*) +# Default is true, which activates and generates DG statistics +Linux_disk_dg_enable= + +# Name of the User Defined Disk Groups file, "auto" generates this for you +Linux_disk_dg_group= + +######################################################################################################################## +### SOLARIS OPTIONS ### +######################################################################################################################## + +# Change to "1" to activate VxVM volumes IO statistics +# Default value: + +# Solaris_VxVM="0" + +Solaris_VxVM= + +# UARG collection (new in Version 1.11), Change to "0" to deactivate, "1" to activate (default is activate) +# Default value: + +# Solaris_UARG="1" + +Solaris_UARG= + +######################################################################################################################## +### AIX OPTIONS ### +######################################################################################################################## + +# CAUTION: Since release 1.3.0, we use fifo files, which requires the option "-yoverwrite=1" + +# Change this line if you add or remove common options for AIX, do not change NFS options here (see NFS options) +# the -p option is mandatory as it is used at launch time to save instance pid + +# Default value: +# AIX_options="-f -T -A -d -K -L -M -P -^ -p -yoverwrite=1" + +AIX_options= + +############################# +# Application related options +############################# + + +###################### +# hostname definition: +###################### + +# This option can be used to force the technical add-on to use the Splunk configured value of the server hostname +# If for some reason, you need to use the Splunk host value instead of the system real hostname value, set this value to "1" + +# We will search for the value of host= in $SPLUNK_HOME/etc/system/local/inputs.conf +# If no value can be found, or if the file does not exist, we will fallback to the normal behavior + +# Default is use system hostname + +# FQDN management in nmonparser: The --fqdn option is not compatible with the host name override, if the override_sys_hostname +# is activated, the --fqdn argument will have no effect + +override_sys_hostname= + +##################### +# frameID definition: +##################### + +# The frameID definition is an enrichment mechanism used within the application to associate a given host with a given frame identifier +# By default, the mapping is operated against the value of "serialnum" which is defined at the raw level by nmon binaries + +# On AIX systems, the serialnum value is equal to the serial number of the frame hosting the partition +# On Linux and Solaris systems, the serialnum is equal to the value of the hostname + +# Using this option allows you to override the serialnum value by a static value defined in the nmon.conf configuration file +# nmon.conf precedence allows defining the serialnum value on per deployment basis (local/nmon.conf) or on a per server basis (/etc/nmon.conf) + +# default is: +# override_sys_serialnum="0" +# which lets nmon set the serialnum value + +# Set this value to: +# override_sys_serialnum="1" +# to activate the serialnum override based on the value defined in: + +# override_sys_serialnum_value="" +# Acceptable values for are letters (lower and upper case), numbers and "-" / "_" + +override_sys_serialnum= +override_sys_serialnum_value= + +######################## +# nmon external metrics: +######################## + +# nmon external generation management + +# This option will manage the activation or deactivation of the nmon external data generation at the lower level, before it comes to parsers +# default is activated (value=1), set to "0" to deactivate + +nmon_external_generation= + +############### +# fifo options: +############### + +# Fifo options + +# The realtime mode which corresponds to the old mechanism is now deprecated +# fifo mode is mandatory + +# Default is "1" which means write to fifo + +mode_fifo= + +####################### +# nmon parsers options: +####################### + +# consult the documentation to get the full list of available options + +# --mode fifo|colddata --> explicitly manage data in fifo/colddata +# --use_fqdn --> use the host fully qualified domain name (default) +# --silent --> minimize the processing output to save data volume (deactivated by default) +# --show_zero_values --> allows generating metrics with 0 values (default removes any metric with a zero value before it reaches the ingestion) + +# In fifo mode, options are sent by the metricator_consumer.sh +# In file mode, options are sent by Splunk via the nmon_processing stanza in props.conf + +nmonparser_options= diff --git a/deployment-apps/TA-metricator-for-nmon/bin/README b/deployment-apps/TA-metricator-for-nmon/bin/README new file mode 100644 index 0000000..9a70db0 --- /dev/null +++ b/deployment-apps/TA-metricator-for-nmon/bin/README @@ -0,0 +1 @@ +This is where you put any scripts you want to add to this app. diff --git a/deployment-apps/TA-metricator-for-nmon/bin/create_agent.py b/deployment-apps/TA-metricator-for-nmon/bin/create_agent.py new file mode 100755 index 0000000..c4c2e1c --- /dev/null +++ b/deployment-apps/TA-metricator-for-nmon/bin/create_agent.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python + +# Program name: create_agent.py +# Compatibility: Python 2x +# Purpose - Create a customized version of the TA-metricator-for-nmon +# Licence: + +# Copyright 2018 Guilhem Marchand + +import sys +import os +import tarfile +import glob +import fnmatch +import argparse +import shutil + +version = '2.0.0' + +#################################################################### +############# Arguments Parser +#################################################################### + +# Define Arguments + +parser = argparse.ArgumentParser() + +parser.add_argument('-f', action='store', dest='INFILE', + help='Name of the tgz archive file') + +parser.add_argument('--agentname', action='store', dest='TARGET', + help='Define the TA Agent name and root directory') + +parser.add_argument('--version', action='version', version='%(prog)s ' + version) + +parser.add_argument('--debug', dest='debug', action='store_true') + +parser.set_defaults(debug=False) + +args = parser.parse_args() + +# Set debug +if args.debug: + debug = True + +#################################################################### +############# Functions +#################################################################### + +# String replacement function +# Can be called by: +# findreplace(path, string_to_search, replace_by, file_extension) + +def findreplace(directory, find, replace, filepattern): + for path, dirs, files in os.walk(os.path.abspath(directory)): + for filename in fnmatch.filter(files, filepattern): + filepath = os.path.join(path, filename) + + # Prevents binaries modification + if "bin/linux" in filepath: + if debug: + print("file " + str(filename) + " is binary or binary related") + elif "bin/sarmon" in filepath: + if debug: + print("file " + str(filename) + " is binary or binary related") + else: + with open(filepath) as f: + s = f.read() + s = s.replace(find, replace) + with open(filepath, "w") as f: + f.write(s) + + +#################################################################### +############# Main Program +#################################################################### + +# Check Arguments +if len(sys.argv) < 2: + print "\n%s" % os.path.basename(sys.argv[0]) + print "\nThis utility had been designed to allow creating customized agents for the TA-metricator-for-nmon" \ + " please follow these instructions:\n" + print "- Download the current release of the technical add-on" + print "- Ensure to have this Python script and the TGZ archive in the same directory" + print "- Run the tool: ./create_agent.py and check for available options" + print "- After the execution, a new agent package will have been created in the resources directory" + print "- Extract its content to your Splunk deployment server, configure the server class, associated clients and" \ + " deploy the agent" + print "- Don't forget to set the application to restart splunkd after deployment\n" + print "\nRun this tool such as:\n" + print "./create_agent.py -f TA-metricator-for-nmon_xxx.tgz --agentname TA-metricator-for-nmon-custom \n" + + sys.exit(0) + +# Will expect in first Argument the name of the tgz Archive of the Application to be downloaded in Splunk Base +if not args.INFILE: + print "\nERROR: Please provide the tgz Archive file with -f statement\n" + sys.exit(1) +else: + infile = args.INFILE + +# If the root directory of the TA-nmon is not defined, exit and show message +if not args.TARGET: + print "ERROR: You must specify the name of the agent package you want to create, and it must be different from" \ + " the default package: TA-metricator-for-nmon" + sys.exit(0) +else: + ta_root_dir = args.TARGET + +# Avoid naming the TA ascore application +if not "TA-" in ta_root_dir: + print "ERROR: The TA package name should always start by TA_ as good Splunk practice." + sys.exit(1) + +# Verify tgz Archive file exists +if not os.path.exists(infile): + print ('ERROR: invalid file, could not find: ' + infile) + sys.exit(1) + +# Ensure the same package name does not already exist in current directory +if os.path.exists(ta_root_dir): + print ('ERROR: A directory named ' + ta_root_dir + ' already exist in current directory, please remove it and' + ' restart') + sys.exit(1) +elif os.path.exists(ta_root_dir + ".tgz"): + print ('ERROR: A tgz archive named ' + ta_root_dir + ".tgz" + ' already exist in current directory, please' + ' remove it and restart') + sys.exit(1) + +# Extract Archive +tar = tarfile.open(infile) +msg = 'Extracting tgz Archive: ' + infile +print (msg) +tar.extractall() +tar.close() + +# Operate + +# Get current directory +curdir = os.getcwd() + +# Extract the TA-nmon default package in current directory + +print ('INFO: Extracting Agent tgz resources Archives') + +tgz_files = 'TA-metricator-for-nmon*.tgz' +for tgz in glob.glob(str(tgz_files)): + tar = tarfile.open(tgz) + tar.extractall() + tar.close() + +# Rename the TA directory to match agent name + +msg = 'INFO: Renaming TA-metricator-for-nmon default agent to ' + ta_root_dir +print (msg) + +shutil.copytree('TA-metricator-for-nmon', ta_root_dir) + +################# STRING REPLACEMENTS ################# + +# Replace the old agent name in files + +# Achieve string replacements + +print ('Achieving files transformation...') + +search = 'TA-metricator-for-nmon' +replace = ta_root_dir +findreplace(ta_root_dir, search, replace, "*.sh") +findreplace(ta_root_dir, search, replace, "*.py") +findreplace(ta_root_dir, search, replace, "*.pl") +findreplace(ta_root_dir, search, replace, "*.conf") + +print ('Done.') + +# Don't use "with" statement in tar creation for Python 2.6 backward compatibility +tar_file = ta_root_dir + '.tgz' +out = tarfile.open(tar_file, mode='w:gz') + +try: + out.add(ta_root_dir) +finally: + msg = 'INFO: ************* Tar creation done of: ' + tar_file + ' *************' + print (msg) + out.close() + +# remove Agent directory +if os.path.isdir(ta_root_dir): + shutil.rmtree(ta_root_dir) + +print ('\n*** Agent Creation terminated: To install the agent: ***\n') +print (' - Upload the tgz Archive ' + tar_file + ' to your Splunk deployment server') +print (' - Extract the content of the TA package in $SPLUNK_HOME/etc/deployment-apps/') +print (' - Configure the Application (set splunkd to restart), server class and associated clients to push the new' + ' package to your clients\n') + +# END +print ('Operation terminated.\n') +sys.exit(0) diff --git a/deployment-apps/TA-metricator-for-nmon/bin/lib/aix/README b/deployment-apps/TA-metricator-for-nmon/bin/lib/aix/README new file mode 100644 index 0000000..f750e11 --- /dev/null +++ b/deployment-apps/TA-metricator-for-nmon/bin/lib/aix/README @@ -0,0 +1,3 @@ +Text-CSV-1.95: http://search.cpan.org/~ishigaki/Text-CSV-1.95/lib/Text/CSV.pm + +Compiled on AIX 7.1, certified under AIX 7.1 and 7.2 diff --git a/deployment-apps/TA-metricator-for-nmon/bin/lib/aix/Text/CSV.pm b/deployment-apps/TA-metricator-for-nmon/bin/lib/aix/Text/CSV.pm new file mode 100644 index 0000000..5dd7226 --- /dev/null +++ b/deployment-apps/TA-metricator-for-nmon/bin/lib/aix/Text/CSV.pm @@ -0,0 +1,2467 @@ +package Text::CSV; + + +use strict; +use Exporter; +use Carp (); +use vars qw( $VERSION $DEBUG @ISA @EXPORT_OK ); +@ISA = qw( Exporter ); +@EXPORT_OK = qw( csv ); + +BEGIN { + $VERSION = '1.95'; + $DEBUG = 0; +} + +# if use CSV_XS, requires version +my $Module_XS = 'Text::CSV_XS'; +my $Module_PP = 'Text::CSV_PP'; +my $XS_Version = '1.02'; + +my $Is_Dynamic = 0; + +my @PublicMethods = qw/ + version new error_diag error_input + known_attributes csv + PV IV NV +/; +# + +# Check the environment variable to decide worker module. + +unless ($Text::CSV::Worker) { + $Text::CSV::DEBUG and Carp::carp("Check used worker module..."); + + if ( exists $ENV{PERL_TEXT_CSV} ) { + if ($ENV{PERL_TEXT_CSV} eq '0' or $ENV{PERL_TEXT_CSV} eq 'Text::CSV_PP') { + _load_pp() or Carp::croak $@; + } + elsif ($ENV{PERL_TEXT_CSV} eq '1' or $ENV{PERL_TEXT_CSV} =~ /Text::CSV_XS\s*,\s*Text::CSV_PP/) { + _load_xs() or _load_pp() or Carp::croak $@; + } + elsif ($ENV{PERL_TEXT_CSV} eq '2' or $ENV{PERL_TEXT_CSV} eq 'Text::CSV_XS') { + _load_xs() or Carp::croak $@; + } + else { + Carp::croak "The value of environmental variable 'PERL_TEXT_CSV' is invalid."; + } + } + else { + _load_xs() or _load_pp() or Carp::croak $@; + } + +} + +sub new { # normal mode + my $proto = shift; + my $class = ref($proto) || $proto; + + unless ( $proto ) { # for Text::CSV_XS/PP::new(0); + return eval qq| $Text::CSV::Worker\::new( \$proto ) |; + } + + #if (ref $_[0] and $_[0]->{module}) { + # Carp::croak("Can't set 'module' in non dynamic mode."); + #} + + if ( my $obj = $Text::CSV::Worker->new(@_) ) { + $obj->{_MODULE} = $Text::CSV::Worker; + bless $obj, $class; + return $obj; + } + else { + return; + } + + +} + + +sub require_xs_version { $XS_Version; } + + +sub module { + my $proto = shift; + return !ref($proto) ? $Text::CSV::Worker + : ref($proto->{_MODULE}) ? ref($proto->{_MODULE}) : $proto->{_MODULE}; +} + +*backend = *module; + + +sub is_xs { + return $_[0]->module eq $Module_XS; +} + + +sub is_pp { + return $_[0]->module eq $Module_PP; +} + + +sub is_dynamic { $Is_Dynamic; } + +sub _load_xs { _load($Module_XS, $XS_Version) } + +sub _load_pp { _load($Module_PP) } + +sub _load { + my ($module, $version) = @_; + $version ||= ''; + + $Text::CSV::DEBUG and Carp::carp "Load $module."; + + eval qq| use $module $version |; + + return if $@; + + push @Text::CSV::ISA, $module; + $Text::CSV::Worker = $module; + + local $^W; + no strict qw(refs); + + for my $method (@PublicMethods) { + *{"Text::CSV::$method"} = \&{"$module\::$method"}; + } + return 1; +} + + + +1; +__END__ + +=pod + +=head1 NAME + +Text::CSV - comma-separated values manipulator (using XS or PurePerl) + + +=head1 SYNOPSIS + + use Text::CSV; + + my @rows; + my $csv = Text::CSV->new ( { binary => 1 } ) # should set binary attribute. + or die "Cannot use CSV: ".Text::CSV->error_diag (); + + open my $fh, "<:encoding(utf8)", "test.csv" or die "test.csv: $!"; + while ( my $row = $csv->getline( $fh ) ) { + $row->[2] =~ m/pattern/ or next; # 3rd field should match + push @rows, $row; + } + $csv->eof or $csv->error_diag(); + close $fh; + + $csv->eol ("\r\n"); + + open $fh, ">:encoding(utf8)", "new.csv" or die "new.csv: $!"; + $csv->print ($fh, $_) for @rows; + close $fh or die "new.csv: $!"; + + # + # parse and combine style + # + + $status = $csv->combine(@columns); # combine columns into a string + $line = $csv->string(); # get the combined string + + $status = $csv->parse($line); # parse a CSV string into fields + @columns = $csv->fields(); # get the parsed fields + + $status = $csv->status (); # get the most recent status + $bad_argument = $csv->error_input (); # get the most recent bad argument + $diag = $csv->error_diag (); # if an error occurred, explains WHY + + $status = $csv->print ($io, $colref); # Write an array of fields + # immediately to a file $io + $colref = $csv->getline ($io); # Read a line from file $io, + # parse it and return an array + # ref of fields + $csv->column_names (@names); # Set column names for getline_hr () + $ref = $csv->getline_hr ($io); # getline (), but returns a hashref + $eof = $csv->eof (); # Indicate if last parse or + # getline () hit End Of File + + $csv->types(\@t_array); # Set column types + +=head1 DESCRIPTION + +Text::CSV is a thin wrapper for L-compatible modules now. +All the backend modules provide facilities for the composition and +decomposition of comma-separated values. Text::CSV uses Text::CSV_XS +by default, and when Text::CSV_XS is not available, falls back on +L, which is bundled in the same distribution as this module. + +=head1 CHOOSING BACKEND + +This module respects an environmental variable called C +when it decides a backend module to use. If this environmental variable +is not set, it tries to load Text::CSV_XS, and if Text::CSV_XS is not +available, falls back on Text::CSV_PP; + +If you always don't want it to fall back on Text::CSV_PP, set the variable +like this (C may be C, C and the likes, depending +on your environment): + + > export PERL_TEXT_CSV=Text::CSV_XS + +If you prefer Text::CSV_XS to Text::CSV_PP (default), then: + + > export PERL_TEXT_CSV=Text::CSV_XS,Text::CSV_PP + +You may also want to set this variable at the top of your test files, in order +not to be bothered with incompatibilities between backends (you need to wrap +this in C, and set before actually C-ing Text::CSV module, as it +decides its backend as soon as it's loaded): + + BEGIN { $ENV{PERL_TEXT_CSV}='Text::CSV_PP'; } + use Text::CSV; + +=head1 NOTES + +This section is taken from Text::CSV_XS. + +=head2 Embedded newlines + +B: The default behavior is to accept only ASCII characters +in the range from C<0x20> (space) to C<0x7E> (tilde). This means that the +fields can not contain newlines. If your data contains newlines embedded in +fields, or characters above C<0x7E> (tilde), or binary data, you B> +set C<< binary => 1 >> in the call to L. To cover the widest range of +parsing options, you will always want to set binary. + +But you still have the problem that you have to pass a correct line to the +L method, which is more complicated from the usual point of usage: + + my $csv = Text::CSV->new ({ binary => 1, eol => $/ }); + while (<>) { # WRONG! + $csv->parse ($_); + my @fields = $csv->fields (); + } + +this will break, as the C might read broken lines: it does not care +about the quoting. If you need to support embedded newlines, the way to go +is to B pass L|/eol> in the parser (it accepts C<\n>, C<\r>, +B C<\r\n> by default) and then + + my $csv = Text::CSV->new ({ binary => 1 }); + open my $io, "<", $file or die "$file: $!"; + while (my $row = $csv->getline ($io)) { + my @fields = @$row; + } + +The old(er) way of using global file handles is still supported + + while (my $row = $csv->getline (*ARGV)) { ... } + +=head2 Unicode + +Unicode is only tested to work with perl-5.8.2 and up. + +The simplest way to ensure the correct encoding is used for in- and output +is by either setting layers on the filehandles, or setting the L +argument for L. + + open my $fh, "<:encoding(UTF-8)", "in.csv" or die "in.csv: $!"; +or + my $aoa = csv (in => "in.csv", encoding => "UTF-8"); + + open my $fh, ">:encoding(UTF-8)", "out.csv" or die "out.csv: $!"; +or + csv (in => $aoa, out => "out.csv", encoding => "UTF-8"); + +On parsing (both for L and L), if the source is marked +being UTF8, then all fields that are marked binary will also be marked UTF8. + +On combining (L and L): if any of the combining fields +was marked UTF8, the resulting string will be marked as UTF8. Note however +that all fields I the first field marked UTF8 and contained 8-bit +characters that were not upgraded to UTF8, these will be C in the +resulting string too, possibly causing unexpected errors. If you pass data +of different encoding, or you don't know if there is different encoding, +force it to be upgraded before you pass them on: + + $csv->print ($fh, [ map { utf8::upgrade (my $x = $_); $x } @data ]); + +For complete control over encoding, please use L: + + use Text::CSV::Encoded; + my $csv = Text::CSV::Encoded->new ({ + encoding_in => "iso-8859-1", # the encoding comes into Perl + encoding_out => "cp1252", # the encoding comes out of Perl + }); + + $csv = Text::CSV::Encoded->new ({ encoding => "utf8" }); + # combine () and print () accept *literally* utf8 encoded data + # parse () and getline () return *literally* utf8 encoded data + + $csv = Text::CSV::Encoded->new ({ encoding => undef }); # default + # combine () and print () accept UTF8 marked data + # parse () and getline () return UTF8 marked data + +=head1 METHODS + +This whole section is also taken from Text::CSV_XS. + +=head2 version () + +(Class method) Returns the current backend module version. + +=head2 new (\%attr) + +(Class method) Returns a new instance of Text::CSV backend. The attributes +are described by the (optional) hash ref C<\%attr>. + + my $csv = Text::CSV->new ({ attributes ... }); + +The following attributes are available: + +=head3 eol + + my $csv = Text::CSV->new ({ eol => $/ }); + $csv->eol (undef); + my $eol = $csv->eol; + +The end-of-line string to add to rows for L or the record separator +for L. + +When not passed in a B instance, the default behavior is to accept +C<\n>, C<\r>, and C<\r\n>, so it is probably safer to not specify C at +all. Passing C or the empty string behave the same. + +When not passed in a B instance, records are not terminated at +all, so it is probably wise to pass something you expect. A safe choice for +C on output is either C<$/> or C<\r\n>. + +Common values for C are C<"\012"> (C<\n> or Line Feed), C<"\015\012"> +(C<\r\n> or Carriage Return, Line Feed), and C<"\015"> (C<\r> or Carriage +Return). The L|/eol> attribute cannot exceed 7 (ASCII) characters. + +If both C<$/> and L|/eol> equal C<"\015">, parsing lines that end on +only a Carriage Return without Line Feed, will be Ld correct. + +=head3 sep_char + + my $csv = Text::CSV->new ({ sep_char => ";" }); + $csv->sep_char (";"); + my $c = $csv->sep_char; + +The char used to separate fields, by default a comma. (C<,>). Limited to a +single-byte character, usually in the range from C<0x20> (space) to C<0x7E> +(tilde). When longer sequences are required, use L|/sep>. + +The separation character can not be equal to the quote character or to the +escape character. + +=head3 sep + + my $csv = Text::CSV->new ({ sep => "\N{FULLWIDTH COMMA}" }); + $csv->sep (";"); + my $sep = $csv->sep; + +The chars used to separate fields, by default undefined. Limited to 8 bytes. + +When set, overrules L|/sep_char>. If its length is one byte it +acts as an alias to L|/sep_char>. + +=head3 quote_char + + my $csv = Text::CSV->new ({ quote_char => "'" }); + $csv->quote_char (undef); + my $c = $csv->quote_char; + +The character to quote fields containing blanks or binary data, by default +the double quote character (C<">). A value of undef suppresses quote chars +(for simple cases only). Limited to a single-byte character, usually in the +range from C<0x20> (space) to C<0x7E> (tilde). When longer sequences are +required, use L|/quote>. + +C can not be equal to L|/sep_char>. + +=head3 quote + + my $csv = Text::CSV->new ({ quote => "\N{FULLWIDTH QUOTATION MARK}" }); + $csv->quote ("'"); + my $quote = $csv->quote; + +The chars used to quote fields, by default undefined. Limited to 8 bytes. + +When set, overrules L|/quote_char>. If its length is one byte +it acts as an alias to L|/quote_char>. + +=head3 escape_char + + my $csv = Text::CSV->new ({ escape_char => "\\" }); + $csv->escape_char (undef); + my $c = $csv->escape_char; + +The character to escape certain characters inside quoted fields. This is +limited to a single-byte character, usually in the range from C<0x20> +(space) to C<0x7E> (tilde). + +The C defaults to being the double-quote mark (C<">). In other +words the same as the default L|/quote_char>. This means that +doubling the quote mark in a field escapes it: + + "foo","bar","Escape ""quote mark"" with two ""quote marks""","baz" + +If you change the L|/quote_char> without changing the +C, the C will still be the double-quote (C<">). +If instead you want to escape the L|/quote_char> by doubling +it you will need to also change the C to be the same as what +you have changed the L|/quote_char> to. + +The escape character can not be equal to the separation character. + +=head3 binary + + my $csv = Text::CSV->new ({ binary => 1 }); + $csv->binary (0); + my $f = $csv->binary; + +If this attribute is C<1>, you may use binary characters in quoted fields, +including line feeds, carriage returns and C bytes. (The latter could +be escaped as C<"0>.) By default this feature is off. + +If a string is marked UTF8, C will be turned on automatically when +binary characters other than C and C are encountered. Note that a +simple string like C<"\x{00a0}"> might still be binary, but not marked UTF8, +so setting C<< { binary => 1 } >> is still a wise option. + +=head3 decode_utf8 + + my $csv = Text::CSV->new ({ decode_utf8 => 1 }); + $csv->decode_utf8 (0); + my $f = $csv->decode_utf8; + +This attributes defaults to TRUE. + +While I, fields that are valid UTF-8, are automatically set to be +UTF-8, so that + + $csv->parse ("\xC4\xA8\n"); + +results in + + PV("\304\250"\0) [UTF8 "\x{128}"] + +Sometimes it might not be a desired action. To prevent those upgrades, set +this attribute to false, and the result will be + + PV("\304\250"\0) + +=head3 auto_diag + + my $csv = Text::CSV->new ({ auto_diag => 1 }); + $csv->auto_diag (2); + my $l = $csv->auto_diag; + +Set this attribute to a number between C<1> and C<9> causes L +to be automatically called in void context upon errors. + +In case of error C<2012 - EOF>, this call will be void. + +If C is set to a numeric value greater than C<1>, it will C +on errors instead of C. If set to anything unrecognized, it will be +silently ignored. + +Future extensions to this feature will include more reliable auto-detection +of C being active in the scope of which the error occurred which +will increment the value of C with C<1> the moment the error is +detected. + +=head3 diag_verbose + + my $csv = Text::CSV->new ({ diag_verbose => 1 }); + $csv->diag_verbose (2); + my $l = $csv->diag_verbose; + +Set the verbosity of the output triggered by C. Currently only +adds the current input-record-number (if known) to the diagnostic output +with an indication of the position of the error. + +=head3 blank_is_undef + + my $csv = Text::CSV->new ({ blank_is_undef => 1 }); + $csv->blank_is_undef (0); + my $f = $csv->blank_is_undef; + +Under normal circumstances, C data makes no distinction between quoted- +and unquoted empty fields. These both end up in an empty string field once +read, thus + + 1,"",," ",2 + +is read as + + ("1", "", "", " ", "2") + +When I C files with either L|/always_quote> +or L|/quote_empty> set, the unquoted I field is the +result of an undefined value. To enable this distinction when I +C data, the C attribute will cause unquoted empty +fields to be set to C, causing the above to be parsed as + + ("1", "", undef, " ", "2") + +note that this is specifically important when loading C fields into a +database that allows C values, as the perl equivalent for C is +C in L land. + +=head3 empty_is_undef + + my $csv = Text::CSV->new ({ empty_is_undef => 1 }); + $csv->empty_is_undef (0); + my $f = $csv->empty_is_undef; + +Going one step further than L|/blank_is_undef>, this +attribute converts all empty fields to C, so + + 1,"",," ",2 + +is read as + + (1, undef, undef, " ", 2) + +Note that this effects only fields that are originally empty, not fields +that are empty after stripping allowed whitespace. YMMV. + +=head3 allow_whitespace + + my $csv = Text::CSV->new ({ allow_whitespace => 1 }); + $csv->allow_whitespace (0); + my $f = $csv->allow_whitespace; + +When this option is set to true, the whitespace (C's and C's) +surrounding the separation character is removed when parsing. If either +C or C is one of the three characters L|/sep_char>, +L|/quote_char>, or L|/escape_char> it will not +be considered whitespace. + +Now lines like: + + 1 , "foo" , bar , 3 , zapp + +are parsed as valid C, even though it violates the C specs. + +Note that B whitespace is stripped from both start and end of each +field. That would make it I than a I to enable parsing bad +C lines, as + + 1, 2.0, 3, ape , monkey + +will now be parsed as + + ("1", "2.0", "3", "ape", "monkey") + +even if the original line was perfectly acceptable C. + +=head3 allow_loose_quotes + + my $csv = Text::CSV->new ({ allow_loose_quotes => 1 }); + $csv->allow_loose_quotes (0); + my $f = $csv->allow_loose_quotes; + +By default, parsing unquoted fields containing L|/quote_char> +characters like + + 1,foo "bar" baz,42 + +would result in parse error 2034. Though it is still bad practice to allow +this format, we cannot help the fact that some vendors make their +applications spit out lines styled this way. + +If there is B bad C data, like + + 1,"foo "bar" baz",42 + +or + + 1,""foo bar baz"",42 + +there is a way to get this data-line parsed and leave the quotes inside the +quoted field as-is. This can be achieved by setting C +B making sure that the L|/escape_char> is I equal +to L|/quote_char>. + +=head3 allow_loose_escapes + + my $csv = Text::CSV->new ({ allow_loose_escapes => 1 }); + $csv->allow_loose_escapes (0); + my $f = $csv->allow_loose_escapes; + +Parsing fields that have L|/escape_char> characters that +escape characters that do not need to be escaped, like: + + my $csv = Text::CSV->new ({ escape_char => "\\" }); + $csv->parse (qq{1,"my bar\'s",baz,42}); + +would result in parse error 2025. Though it is bad practice to allow this +format, this attribute enables you to treat all escape character sequences +equal. + +=head3 allow_unquoted_escape + + my $csv = Text::CSV->new ({ allow_unquoted_escape => 1 }); + $csv->allow_unquoted_escape (0); + my $f = $csv->allow_unquoted_escape; + +A backward compatibility issue where L|/escape_char> differs +from L|/quote_char> prevents L|/escape_char> +to be in the first position of a field. If L|/quote_char> is +equal to the default C<"> and L|/escape_char> is set to C<\>, +this would be illegal: + + 1,\0,2 + +Setting this attribute to C<1> might help to overcome issues with backward +compatibility and allow this style. + +=head3 always_quote + + my $csv = Text::CSV->new ({ always_quote => 1 }); + $csv->always_quote (0); + my $f = $csv->always_quote; + +By default the generated fields are quoted only if they I to be. For +example, if they contain the separator character. If you set this attribute +to C<1> then I defined fields will be quoted. (C fields are not +quoted, see L). This makes it quite often easier to handle +exported data in external applications. + +=head3 quote_space + + my $csv = Text::CSV->new ({ quote_space => 1 }); + $csv->quote_space (0); + my $f = $csv->quote_space; + +By default, a space in a field would trigger quotation. As no rule exists +this to be forced in C, nor any for the opposite, the default is true +for safety. You can exclude the space from this trigger by setting this +attribute to 0. + +=head3 quote_empty + + my $csv = Text::CSV->new ({ quote_empty => 1 }); + $csv->quote_empty (0); + my $f = $csv->quote_empty; + +By default the generated fields are quoted only if they I to be. An +empty (defined) field does not need quotation. If you set this attribute to +C<1> then I defined fields will be quoted. (C fields are not +quoted, see L). See also L|/always_quote>. + +=head3 quote_binary + + my $csv = Text::CSV->new ({ quote_binary => 1 }); + $csv->quote_binary (0); + my $f = $csv->quote_binary; + +By default, all "unsafe" bytes inside a string cause the combined field to +be quoted. By setting this attribute to C<0>, you can disable that trigger +for bytes >= C<0x7F>. + +=head3 escape_null or quote_null (deprecated) + + my $csv = Text::CSV->new ({ escape_null => 1 }); + $csv->escape_null (0); + my $f = $csv->escape_null; + +By default, a C byte in a field would be escaped. This option enables +you to treat the C byte as a simple binary character in binary mode +(the C<< { binary => 1 } >> is set). The default is true. You can prevent +C escapes by setting this attribute to C<0>. + +The default when using the C function is C. + +=head3 keep_meta_info + + my $csv = Text::CSV->new ({ keep_meta_info => 1 }); + $csv->keep_meta_info (0); + my $f = $csv->keep_meta_info; + +By default, the parsing of input records is as simple and fast as possible. +However, some parsing information - like quotation of the original field - +is lost in that process. Setting this flag to true enables retrieving that +information after parsing with the methods L, L, +and L described below. Default is false for performance. + +If you set this attribute to a value greater than 9, than you can control +output quotation style like it was used in the input of the the last parsed +record (unless quotation was added because of other reasons). + + my $csv = Text::CSV->new ({ + binary => 1, + keep_meta_info => 1, + quote_space => 0, + }); + + my $row = $csv->parse (q{1,,"", ," ",f,"g","h""h",help,"help"}); + + $csv->print (*STDOUT, \@row); + # 1,,, , ,f,g,"h""h",help,help + $csv->keep_meta_info (11); + $csv->print (*STDOUT, \@row); + # 1,,"", ," ",f,"g","h""h",help,"help" + +=head3 verbatim + + my $csv = Text::CSV->new ({ verbatim => 1 }); + $csv->verbatim (0); + my $f = $csv->verbatim; + +This is a quite controversial attribute to set, but makes some hard things +possible. + +The rationale behind this attribute is to tell the parser that the normally +special characters newline (C) and Carriage Return (C) will not be +special when this flag is set, and be dealt with as being ordinary binary +characters. This will ease working with data with embedded newlines. + +When C is used with L, L auto-C's +every line. + +Imagine a file format like + + M^^Hans^Janssen^Klas 2\n2A^Ja^11-06-2007#\r\n + +where, the line ending is a very specific C<"#\r\n">, and the sep_char is a +C<^> (caret). None of the fields is quoted, but embedded binary data is +likely to be present. With the specific line ending, this should not be too +hard to detect. + +By default, Text::CSV' parse function is instructed to only know about +C<"\n"> and C<"\r"> to be legal line endings, and so has to deal with the +embedded newline as a real C, so it can scan the next line if +binary is true, and the newline is inside a quoted field. With this option, +we tell L to parse the line as if C<"\n"> is just nothing more than +a binary character. + +For L this means that the parser has no more idea about line ending +and L Cs line endings on reading. + +=head3 types + +A set of column types; the attribute is immediately passed to the L +method. + +=head3 callbacks + +See the L section below. + +=head3 accessors + +To sum it up, + + $csv = Text::CSV->new (); + +is equivalent to + + $csv = Text::CSV->new ({ + eol => undef, # \r, \n, or \r\n + sep_char => ',', + sep => undef, + quote_char => '"', + quote => undef, + escape_char => '"', + binary => 0, + decode_utf8 => 1, + auto_diag => 0, + diag_verbose => 0, + blank_is_undef => 0, + empty_is_undef => 0, + allow_whitespace => 0, + allow_loose_quotes => 0, + allow_loose_escapes => 0, + allow_unquoted_escape => 0, + always_quote => 0, + quote_empty => 0, + quote_space => 1, + escape_null => 1, + quote_binary => 1, + keep_meta_info => 0, + verbatim => 0, + types => undef, + callbacks => undef, + }); + +For all of the above mentioned flags, an accessor method is available where +you can inquire the current value, or change the value + + my $quote = $csv->quote_char; + $csv->binary (1); + +It is not wise to change these settings halfway through writing C data +to a stream. If however you want to create a new stream using the available +C object, there is no harm in changing them. + +If the L constructor call fails, it returns C, and makes the +fail reason available through the L method. + + $csv = Text::CSV->new ({ ecs_char => 1 }) or + die "".Text::CSV->error_diag (); + +L will return a string like + + "INI - Unknown attribute 'ecs_char'" + +=head2 known_attributes + + @attr = Text::CSV->known_attributes; + @attr = Text::CSV::known_attributes; + @attr = $csv->known_attributes; + +This method will return an ordered list of all the supported attributes as +described above. This can be useful for knowing what attributes are valid +in classes that use or extend Text::CSV. + +=head2 print + + $status = $csv->print ($io, $colref); + +Similar to L + L + L, but much more efficient. +It expects an array ref as input (not an array!) and the resulting string +is not really created, but immediately written to the C<$io> object, +typically an IO handle or any other object that offers a L method. + +For performance reasons C does not create a result string, so all +L, L, L, and L methods will return +undefined information after executing this method. + +If C<$colref> is C (explicit, not through a variable argument) and +L was used to specify fields to be printed, it is possible +to make performance improvements, as otherwise data would have to be copied +as arguments to the method call: + + $csv->bind_columns (\($foo, $bar)); + $status = $csv->print ($fh, undef); + +=head2 say + + $status = $csv->say ($io, $colref); + +Like L|/print>, but L|/eol> defaults to C<$\>. + +=head2 print_hr + + $csv->print_hr ($io, $ref); + +Provides an easy way to print a C<$ref> (as fetched with L) +provided the column names are set with L. + +It is just a wrapper method with basic parameter checks over + + $csv->print ($io, [ map { $ref->{$_} } $csv->column_names ]); + +=head2 combine + + $status = $csv->combine (@fields); + +This method constructs a C record from C<@fields>, returning success +or failure. Failure can result from lack of arguments or an argument that +contains an invalid character. Upon success, L can be called to +retrieve the resultant C string. Upon failure, the value returned by +L is undefined and L could be called to retrieve the +invalid argument. + +=head2 string + + $line = $csv->string (); + +This method returns the input to L or the resultant C string +of L, whichever was called more recently. + +=head2 getline + + $colref = $csv->getline ($io); + +This is the counterpart to L, as L is the counterpart to +L: it parses a row from the C<$io> handle using the L +method associated with C<$io> and parses this row into an array ref. This +array ref is returned by the function or C for failure. When C<$io> +does not support C, you are likely to hit errors. + +When fields are bound with L the return value is a reference +to an empty list. + +The L, L, and L methods are meaningless again. + +=head2 getline_all + + $arrayref = $csv->getline_all ($io); + $arrayref = $csv->getline_all ($io, $offset); + $arrayref = $csv->getline_all ($io, $offset, $length); + +This will return a reference to a list of L results. +In this call, C is disabled. If C<$offset> is negative, as +with C, only the last C records of C<$io> are taken +into consideration. + +Given a CSV file with 10 lines: + + lines call + ----- --------------------------------------------------------- + 0..9 $csv->getline_all ($io) # all + 0..9 $csv->getline_all ($io, 0) # all + 8..9 $csv->getline_all ($io, 8) # start at 8 + - $csv->getline_all ($io, 0, 0) # start at 0 first 0 rows + 0..4 $csv->getline_all ($io, 0, 5) # start at 0 first 5 rows + 4..5 $csv->getline_all ($io, 4, 2) # start at 4 first 2 rows + 8..9 $csv->getline_all ($io, -2) # last 2 rows + 6..7 $csv->getline_all ($io, -4, 2) # first 2 of last 4 rows + +=head2 getline_hr + +The L and L methods work together to allow you +to have rows returned as hashrefs. You must call L first to +declare your column names. + + $csv->column_names (qw( code name price description )); + $hr = $csv->getline_hr ($io); + print "Price for $hr->{name} is $hr->{price} EUR\n"; + +L will croak if called before L. + +Note that L creates a hashref for every row and will be much +slower than the combined use of L and L but still +offering the same ease of use hashref inside the loop: + + my @cols = @{$csv->getline ($io)}; + $csv->column_names (@cols); + while (my $row = $csv->getline_hr ($io)) { + print $row->{price}; + } + +Could easily be rewritten to the much faster: + + my @cols = @{$csv->getline ($io)}; + my $row = {}; + $csv->bind_columns (\@{$row}{@cols}); + while ($csv->getline ($io)) { + print $row->{price}; + } + +Your mileage may vary for the size of the data and the number of rows. + +=head2 getline_hr_all + + $arrayref = $csv->getline_hr_all ($io); + $arrayref = $csv->getline_hr_all ($io, $offset); + $arrayref = $csv->getline_hr_all ($io, $offset, $length); + +This will return a reference to a list of L +results. In this call, L|/keep_meta_info> is disabled. + +=head2 parse + + $status = $csv->parse ($line); + +This method decomposes a C string into fields, returning success or +failure. Failure can result from a lack of argument or the given C +string is improperly formatted. Upon success, L can be called to +retrieve the decomposed fields. Upon failure calling L will return +undefined data and L can be called to retrieve the invalid +argument. + +You may use the L method for setting column types. See L' +description below. + +The C<$line> argument is supposed to be a simple scalar. Everything else is +supposed to croak and set error 1500. + +=head2 fragment + +This function tries to implement RFC7111 (URI Fragment Identifiers for the +text/csv Media Type) - http://tools.ietf.org/html/rfc7111 + + my $AoA = $csv->fragment ($io, $spec); + +In specifications, C<*> is used to specify the I item, a dash (C<->) +to indicate a range. All indices are C<1>-based: the first row or column +has index C<1>. Selections can be combined with the semi-colon (C<;>). + +When using this method in combination with L, the returned +reference will point to a list of hashes instead of a list of lists. A +disjointed cell-based combined selection might return rows with different +number of columns making the use of hashes unpredictable. + + $csv->column_names ("Name", "Age"); + my $AoH = $csv->fragment ($io, "col=3;8"); + +If the L callback is active, it is also called on every line +parsed and skipped before the fragment. + +=over 2 + +=item row + + row=4 + row=5-7 + row=6-* + row=1-2;4;6-* + +=item col + + col=2 + col=1-3 + col=4-* + col=1-2;4;7-* + +=item cell + +In cell-based selection, the comma (C<,>) is used to pair row and column + + cell=4,1 + +The range operator (C<->) using Cs can be used to define top-left and +bottom-right C location + + cell=3,1-4,6 + +The C<*> is only allowed in the second part of a pair + + cell=3,2-*,2 # row 3 till end, only column 2 + cell=3,2-3,* # column 2 till end, only row 3 + cell=3,2-*,* # strip row 1 and 2, and column 1 + +Cells and cell ranges may be combined with C<;>, possibly resulting in rows +with different number of columns + + cell=1,1-2,2;3,3-4,4;1,4;4,1 + +Disjointed selections will only return selected cells. The cells that are +not specified will not be included in the returned set, not even as +C. As an example given a C like + + 11,12,13,...19 + 21,22,...28,29 + : : + 91,...97,98,99 + +with C will return: + + 11,12,14 + 21,22 + 33,34 + 41,43,44 + +Overlapping cell-specs will return those cells only once, So +C will return: + + 11,12,13 + 21,22,23,24 + 31,32,33,34 + 42,43,44 + +=back + +L does B allow different +types of specs to be combined (either C I C I C). +Passing an invalid fragment specification will croak and set error 2013. + +=head2 column_names + +Set the "keys" that will be used in the L calls. If no keys +(column names) are passed, it will return the current setting as a list. + +L accepts a list of scalars (the column names) or a single +array_ref, so you can pass the return value from L too: + + $csv->column_names ($csv->getline ($io)); + +L does B checking on duplicates at all, which might lead +to unexpected results. Undefined entries will be replaced with the string +C<"\cAUNDEF\cA">, so + + $csv->column_names (undef, "", "name", "name"); + $hr = $csv->getline_hr ($io); + +Will set C<< $hr->{"\cAUNDEF\cA"} >> to the 1st field, C<< $hr->{""} >> to +the 2nd field, and C<< $hr->{name} >> to the 4th field, discarding the 3rd +field. + +L croaks on invalid arguments. + +=head2 header + +This method does NOT work in perl-5.6.x + +Parse the CSV header and set L|/sep>, column_names and encoding. + + my @hdr = $csv->header ($fh); + $csv->header ($fh, { sep_set => [ ";", ",", "|", "\t" ] }); + $csv->header ($fh, { detect_bom => 1, munge_column_names => "lc" }); + +The first argument should be a file handle. + +Assuming that the file opened for parsing has a header, and the header does +not contain problematic characters like embedded newlines, read the first +line from the open handle then auto-detect whether the header separates the +column names with a character from the allowed separator list. + +If any of the allowed separators matches, and none of the I allowed +separators match, set L|/sep> to that separator for the current +CSV_PP instance and use it to parse the first line, map those to lowercase, +and use that to set the instance L: + + my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1 }); + open my $fh, "<", "file.csv"; + binmode $fh; # for Windows + $csv->header ($fh); + while (my $row = $csv->getline_hr ($fh)) { + ... + } + +If the header is empty, contains more than one unique separator out of the +allowed set, contains empty fields, or contains identical fields (after +folding), it will croak with error 1010, 1011, 1012, or 1013 respectively. + +If the header contains embedded newlines or is not valid CSV in any other +way, this method will croak and leave the parse error untouched. + +A successful call to C
will always set the L|/sep> of the +C<$csv> object. This behavior can not be disabled. + +=head3 return value + +On error this method will croak. + +In list context, the headers will be returned whether they are used to set +L or not. + +In scalar context, the instance itself is returned. B: the values as +found in the header will effectively be B if C is +false. + +=head3 Options + +=over 2 + +=item sep_set + + $csv->header ($fh, { sep_set => [ ";", ",", "|", "\t" ] }); + +The list of legal separators defaults to C<[ ";", "," ]> and can be changed +by this option. As this is probably the most often used option, it can be +passed on its own as an unnamed argument: + + $csv->header ($fh, [ ";", ",", "|", "\t", "::", "\x{2063}" ]); + +Multi-byte sequences are allowed, both multi-character and Unicode. See +L|/sep>. + +=item detect_bom + + $csv->header ($fh, { detect_bom => 1 }); + +The default behavior is to detect if the header line starts with a BOM. If +the header has a BOM, use that to set the encoding of C<$fh>. This default +behavior can be disabled by passing a false value to C. + +Supported encodings from BOM are: UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, and +UTF-32LE. BOM's also support UTF-1, UTF-EBCDIC, SCSU, BOCU-1, and GB-18030 +but L does not (yet). UTF-7 is not supported. + +The encoding is set using C on C<$fh>. + +If the handle was opened in a (correct) encoding, this method will B +alter the encoding, as it checks the leading B of the first line. + +=item munge_column_names + +This option offers the means to modify the column names into something that +is most useful to the application. The default is to map all column names +to lower case. + + $csv->header ($fh, { munge_column_names => "lc" }); + +The following values are available: + + lc - lower case + uc - upper case + none - do not change + \&cb - supply a callback + + $csv->header ($fh, { munge_column_names => sub { fc } }); + $csv->header ($fh, { munge_column_names => sub { "column_".$col++ } }); + $csv->header ($fh, { munge_column_names => sub { lc (s/\W+/_/gr) } }); + +As this callback is called in a C, you can use C<$_> directly. + +=item set_column_names + + $csv->header ($fh, { set_column_names => 1 }); + +The default is to set the instances column names using L if +the method is successful, so subsequent calls to L can return +a hash. Disable setting the header can be forced by using a false value for +this option. + +=back + +=head3 Validation + +When receiving CSV files from external sources, this method can be used to +protect against changes in the layout by restricting to known headers (and +typos in the header fields). + + my %known = ( + "record key" => "c_rec", + "rec id" => "c_rec", + "id_rec" => "c_rec", + "kode" => "code", + "code" => "code", + "vaule" => "value", + "value" => "value", + ); + my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1 }); + open my $fh, "<", $source or die "$source: $!"; + $csv->header ($fh, { munge_column_names => sub { + s/\s+$//; + s/^\s+//; + $known{lc $_} or die "Unknown column '$_' in $source"; + }}); + while (my $row = $csv->getline_hr ($fh)) { + say join "\t", $row->{c_rec}, $row->{code}, $row->{value}; + } + +=head2 bind_columns + +Takes a list of scalar references to be used for output with L or +to store in the fields fetched by L. When you do not pass enough +references to store the fetched fields in, L will fail with error +C<3006>. If you pass more than there are fields to return, the content of +the remaining references is left untouched. + + $csv->bind_columns (\$code, \$name, \$price, \$description); + while ($csv->getline ($io)) { + print "The price of a $name is \x{20ac} $price\n"; + } + +To reset or clear all column binding, call L with the single +argument C. This will also clear column names. + + $csv->bind_columns (undef); + +If no arguments are passed at all, L will return the list of +current bindings or C if no binds are active. + +Note that in parsing with C, the fields are set on the fly. +That implies that if the third field of a row causes an error, the first +two fields already have been assigned the values of the current row, while +the rest will still hold the values of the previous row. + +=head2 eof + + $eof = $csv->eof (); + +If L or L was used with an IO stream, this method will +return true (1) if the last call hit end of file, otherwise it will return +false (''). This is useful to see the difference between a failure and end +of file. + +Note that if the parsing of the last line caused an error, C is still +true. That means that if you are I using L, an idiom like + + while (my $row = $csv->getline ($fh)) { + # ... + } + $csv->eof or $csv->error_diag; + +will I report the error. You would have to change that to + + while (my $row = $csv->getline ($fh)) { + # ... + } + +$csv->error_diag and $csv->error_diag; + +=head2 types + + $csv->types (\@tref); + +This method is used to force that (all) columns are of a given type. For +example, if you have an integer column, two columns with doubles and a +string column, then you might do a + + $csv->types ([Text::CSV::IV (), + Text::CSV::NV (), + Text::CSV::NV (), + Text::CSV::PV ()]); + +Column types are used only for I columns while parsing, in other +words by the L and L methods. + +You can unset column types by doing a + + $csv->types (undef); + +or fetch the current type settings with + + $types = $csv->types (); + +=over 4 + +=item IV + +Set field type to integer. + +=item NV + +Set field type to numeric/float. + +=item PV + +Set field type to string. + +=back + +=head2 fields + + @columns = $csv->fields (); + +This method returns the input to L or the resultant decomposed +fields of a successful L, whichever was called more recently. + +Note that the return value is undefined after using L, which does +not fill the data structures returned by L. + +=head2 meta_info + + @flags = $csv->meta_info (); + +This method returns the "flags" of the input to L or the flags of +the resultant decomposed fields of L, whichever was called more +recently. + +For each field, a meta_info field will hold flags that inform something +about the field returned by the L method or passed to the +L method. The flags are bit-wise-C'd like: + +=over 2 + +=item C< >0x0001 + +The field was quoted. + +=item C< >0x0002 + +The field was binary. + +=back + +See the C methods below. + +=head2 is_quoted + + my $quoted = $csv->is_quoted ($column_idx); + +Where C<$column_idx> is the (zero-based) index of the column in the last +result of L. + +This returns a true value if the data in the indicated column was enclosed +in L|/quote_char> quotes. This might be important for fields +where content C<,20070108,> is to be treated as a numeric value, and where +C<,"20070108",> is explicitly marked as character string data. + +This method is only valid when L is set to a true value. + +=head2 is_binary + + my $binary = $csv->is_binary ($column_idx); + +Where C<$column_idx> is the (zero-based) index of the column in the last +result of L. + +This returns a true value if the data in the indicated column contained any +byte in the range C<[\x00-\x08,\x10-\x1F,\x7F-\xFF]>. + +This method is only valid when L is set to a true value. + +=head2 is_missing + + my $missing = $csv->is_missing ($column_idx); + +Where C<$column_idx> is the (zero-based) index of the column in the last +result of L. + + $csv->keep_meta_info (1); + while (my $hr = $csv->getline_hr ($fh)) { + $csv->is_missing (0) and next; # This was an empty line + } + +When using L, it is impossible to tell if the parsed fields +are C because they where not filled in the C stream or because +they were not read at all, as B the fields defined by L +are set in the hash-ref. If you still need to know if all fields in each +row are provided, you should enable L|/keep_meta_info> so +you can check the flags. + +If L|/keep_meta_info> is C, C will +always return C, regardless of C<$column_idx> being valid or not. If +this attribute is C it will return either C<0> (the field is present) +or C<1> (the field is missing). + +A special case is the empty line. If the line is completely empty - after +dealing with the flags - this is still a valid CSV line: it is a record of +just one single empty field. However, if C is set, invoking +C with index C<0> will now return true. + +=head2 status + + $status = $csv->status (); + +This method returns the status of the last invoked L or L +call. Status is success (true: C<1>) or failure (false: C or C<0>). + +=head2 error_input + + $bad_argument = $csv->error_input (); + +This method returns the erroneous argument (if it exists) of L or +L, whichever was called more recently. If the last invocation was +successful, C will return C. + +=head2 error_diag + + Text::CSV->error_diag (); + $csv->error_diag (); + $error_code = 0 + $csv->error_diag (); + $error_str = "" . $csv->error_diag (); + ($cde, $str, $pos, $rec, $fld) = $csv->error_diag (); + +If (and only if) an error occurred, this function returns the diagnostics +of that error. + +If called in void context, this will print the internal error code and the +associated error message to STDERR. + +If called in list context, this will return the error code and the error +message in that order. If the last error was from parsing, the rest of the +values returned are a best guess at the location within the line that was +being parsed. Their values are 1-based. The position currently is index of +the byte at which the parsing failed in the current record. It might change +to be the index of the current character in a later release. The records is +the index of the record parsed by the csv instance. The field number is the +index of the field the parser thinks it is currently trying to parse. See +F for how this can be used. + +If called in scalar context, it will return the diagnostics in a single +scalar, a-la C<$!>. It will contain the error code in numeric context, and +the diagnostics message in string context. + +When called as a class method or a direct function call, the diagnostics +are that of the last L call. + +=head2 record_number + + $recno = $csv->record_number (); + +Returns the records parsed by this csv instance. This value should be more +accurate than C<$.> when embedded newlines come in play. Records written by +this instance are not counted. + +=head2 SetDiag + + $csv->SetDiag (0); + +Use to reset the diagnostics if you are dealing with errors. + +=head1 ADDITIONAL METHODS + +=over + +=item backend + +Returns the backend module name called by Text::CSV. +C is an alias. + +=item is_xs + +Returns true value if Text::CSV uses an XS backend. + +=item is_pp + +Returns true value if Text::CSV uses a pure-Perl backend. + +=back + +=head1 FUNCTIONS + +This whole section is also taken from Text::CSV_XS. + +=head2 csv + +This function is not exported by default and should be explicitly requested: + + use Text::CSV qw( csv ); + +This is an high-level function that aims at simple (user) interfaces. This +can be used to read/parse a C file or stream (the default behavior) or +to produce a file or write to a stream (define the C attribute). It +returns an array- or hash-reference on parsing (or C on fail) or the +numeric value of L on writing. When this function fails you +can get to the error using the class call to L + + my $aoa = csv (in => "test.csv") or + die Text::CSV->error_diag; + +This function takes the arguments as key-value pairs. This can be passed as +a list or as an anonymous hash: + + my $aoa = csv ( in => "test.csv", sep_char => ";"); + my $aoh = csv ({ in => $fh, headers => "auto" }); + +The arguments passed consist of two parts: the arguments to L itself +and the optional attributes to the C object used inside the function +as enumerated and explained in L. + +If not overridden, the default option used for CSV is + + auto_diag => 1 + escape_null => 0 + +The option that is always set and cannot be altered is + + binary => 1 + +As this function will likely be used in one-liners, it allows C to +be abbreviated as C, and C to be abbreviated as C +or C. + +Alternative invocations: + + my $aoa = Text::CSV::csv (in => "file.csv"); + + my $csv = Text::CSV->new (); + my $aoa = $csv->csv (in => "file.csv"); + +In the latter case, the object attributes are used from the existing object +and the attribute arguments in the function call are ignored: + + my $csv = Text::CSV->new ({ sep_char => ";" }); + my $aoh = $csv->csv (in => "file.csv", bom => 1); + +will parse using C<;> as C, not C<,>. + +=head3 in + +Used to specify the source. C can be a file name (e.g. C<"file.csv">), +which will be opened for reading and closed when finished, a file handle +(e.g. C<$fh> or C), a reference to a glob (e.g. C<\*ARGV>), the glob +itself (e.g. C<*STDIN>), or a reference to a scalar (e.g. C<\q{1,2,"csv"}>). + +When used with L, C should be a reference to a CSV structure (AoA +or AoH) or a CODE-ref that returns an array-reference or a hash-reference. +The code-ref will be invoked with no arguments. + + my $aoa = csv (in => "file.csv"); + + open my $fh, "<", "file.csv"; + my $aoa = csv (in => $fh); + + my $csv = [ [qw( Foo Bar )], [ 1, 2 ], [ 2, 3 ]]; + my $err = csv (in => $csv, out => "file.csv"); + +If called in void context without the L attribute, the resulting ref +will be used as input to a subsequent call to csv: + + csv (in => "file.csv", filter => { 2 => sub { length > 2 }}) + +will be a shortcut to + + csv (in => csv (in => "file.csv", filter => { 2 => sub { length > 2 }})) + +where, in the absence of the C attribute, this is a shortcut to + + csv (in => csv (in => "file.csv", filter => { 2 => sub { length > 2 }}), + out => *STDOUT) + +=head3 out + +In output mode, the default CSV options when producing CSV are + + eol => "\r\n" + +The L attribute is ignored in output mode. + +C can be a file name (e.g. C<"file.csv">), which will be opened for +writing and closed when finished, a file handle (e.g. C<$fh> or C), a +reference to a glob (e.g. C<\*STDOUT>), or the glob itself (e.g. C<*STDOUT>). + + csv (in => sub { $sth->fetch }, out => "dump.csv"); + csv (in => sub { $sth->fetchrow_hashref }, out => "dump.csv", + headers => $sth->{NAME_lc}); + +When a code-ref is used for C, the output is generated per invocation, +so no buffering is involved. This implies that there is no size restriction +on the number of records. The C function ends when the coderef returns +a false value. + +=head3 encoding + +If passed, it should be an encoding accepted by the C<:encoding()> option +to C. There is no default value. This attribute does not work in perl +5.6.x. C can be abbreviated to C for ease of use in command +line invocations. + +If C is set to the literal value C<"auto">, the method L
+will be invoked on the opened stream to check if there is a BOM and set the +encoding accordingly. This is equal to passing a true value in the option +L|/detect_bom>. + +=head3 detect_bom + +If C is given, the method L will be invoked on the +opened stream to check if there is a BOM and set the encoding accordingly. + +C can be abbreviated to C. + +This is the same as setting L|/encoding> to C<"auto">. + +Note that as L is invoked, its default is to also set the headers. + +=head3 headers + +If this attribute is not given, the default behavior is to produce an array +of arrays. + +If C is supplied, it should be an anonymous list of column names, +an anonymous hashref, a coderef, or a literal flag: C, C, C, +or C. + +=over 2 + +=item skip + +When C is used, the header will not be included in the output. + + my $aoa = csv (in => $fh, headers => "skip"); + +=item auto + +If C is used, the first line of the C source will be read as the +list of field headers and used to produce an array of hashes. + + my $aoh = csv (in => $fh, headers => "auto"); + +=item lc + +If C is used, the first line of the C source will be read as the +list of field headers mapped to lower case and used to produce an array of +hashes. This is a variation of C. + + my $aoh = csv (in => $fh, headers => "lc"); + +=item uc + +If C is used, the first line of the C source will be read as the +list of field headers mapped to upper case and used to produce an array of +hashes. This is a variation of C. + + my $aoh = csv (in => $fh, headers => "uc"); + +=item CODE + +If a coderef is used, the first line of the C source will be read as +the list of mangled field headers in which each field is passed as the only +argument to the coderef. This list is used to produce an array of hashes. + + my $aoh = csv (in => $fh, + headers => sub { lc ($_[0]) =~ s/kode/code/gr }); + +this example is a variation of using C where all occurrences of C +are replaced with C. + +=item ARRAY + +If C is an anonymous list, the entries in the list will be used +as field names. The first line is considered data instead of headers. + + my $aoh = csv (in => $fh, headers => [qw( Foo Bar )]); + csv (in => $aoa, out => $fh, headers => [qw( code description price )]); + +=item HASH + +If C is an hash reference, this implies C, but header fields +for that exist as key in the hashref will be replaced by the value for that +key. Given a CSV file like + + post-kode,city,name,id number,fubble + 1234AA,Duckstad,Donald,13,"X313DF" + +using + + csv (headers => { "post-kode" => "pc", "id number" => "ID" }, ... + +will return an entry like + + { pc => "1234AA", + city => "Duckstad", + name => "Donald", + ID => "13", + fubble => "X313DF", + } + +=back + +See also L|/munge_column_names> and +L|/set_column_names>. + +=head3 munge_column_names + +If C is set, the method L is invoked on the +opened stream with all matching arguments to detect and set the headers. + +C can be abbreviated to C. + +=head3 key + +If passed, will default L|/headers> to C<"auto"> and return a +hashref instead of an array of hashes. + + my $ref = csv (in => "test.csv", key => "code"); + +with test.csv like + + code,product,price,color + 1,pc,850,gray + 2,keyboard,12,white + 3,mouse,5,black + +will return + + { 1 => { + code => 1, + color => 'gray', + price => 850, + product => 'pc' + }, + 2 => { + code => 2, + color => 'white', + price => 12, + product => 'keyboard' + }, + 3 => { + code => 3, + color => 'black', + price => 5, + product => 'mouse' + } + } + +=head3 fragment + +Only output the fragment as defined in the L method. This option +is ignored when I C. See L. + +Combining all of them could give something like + + use Text::CSV qw( csv ); + my $aoh = csv ( + in => "test.txt", + encoding => "utf-8", + headers => "auto", + sep_char => "|", + fragment => "row=3;6-9;15-*", + ); + say $aoh->[15]{Foo}; + +=head3 sep_set + +If C is set, the method L is invoked on the opened stream +to detect and set L|/sep_char> with the given set. + +C can be abbreviated to C. + +Note that as L is invoked, its default is to also set the headers. + +=head3 set_column_names + +If C is passed, the method L is invoked on the +opened stream with all arguments meant for L. + +=head2 Callbacks + +Callbacks enable actions triggered from the I of Text::CSV. + +While most of what this enables can easily be done in an unrolled loop as +described in the L callbacks can be used to meet special demands +or enhance the L function. + +=over 2 + +=item error + + $csv->callbacks (error => sub { $csv->SetDiag (0) }); + +the C callback is invoked when an error occurs, but I when +L is set to a true value. A callback is invoked with the values +returned by L: + + my ($c, $s); + + sub ignore3006 + { + my ($err, $msg, $pos, $recno, $fldno) = @_; + if ($err == 3006) { + # ignore this error + ($c, $s) = (undef, undef); + Text::CSV->SetDiag (0); + } + # Any other error + return; + } # ignore3006 + + $csv->callbacks (error => \&ignore3006); + $csv->bind_columns (\$c, \$s); + while ($csv->getline ($fh)) { + # Error 3006 will not stop the loop + } + +=item after_parse + + $csv->callbacks (after_parse => sub { push @{$_[1]}, "NEW" }); + while (my $row = $csv->getline ($fh)) { + $row->[-1] eq "NEW"; + } + +This callback is invoked after parsing with L only if no error +occurred. The callback is invoked with two arguments: the current C +parser object and an array reference to the fields parsed. + +The return code of the callback is ignored unless it is a reference to the +string "skip", in which case the record will be skipped in L. + + sub add_from_db + { + my ($csv, $row) = @_; + $sth->execute ($row->[4]); + push @$row, $sth->fetchrow_array; + } # add_from_db + + my $aoa = csv (in => "file.csv", callbacks => { + after_parse => \&add_from_db }); + +This hook can be used for validation: + +=over 2 + +=item FAIL + +Die if any of the records does not validate a rule: + + after_parse => sub { + $_[1][4] =~ m/^[0-9]{4}\s?[A-Z]{2}$/ or + die "5th field does not have a valid Dutch zipcode"; + } + +=item DEFAULT + +Replace invalid fields with a default value: + + after_parse => sub { $_[1][2] =~ m/^\d+$/ or $_[1][2] = 0 } + +=item SKIP + +Skip records that have invalid fields (only applies to L): + + after_parse => sub { $_[1][0] =~ m/^\d+$/ or return \"skip"; } + +=back + +=item before_print + + my $idx = 1; + $csv->callbacks (before_print => sub { $_[1][0] = $idx++ }); + $csv->print (*STDOUT, [ 0, $_ ]) for @members; + +This callback is invoked before printing with L only if no error +occurred. The callback is invoked with two arguments: the current C +parser object and an array reference to the fields passed. + +The return code of the callback is ignored. + + sub max_4_fields + { + my ($csv, $row) = @_; + @$row > 4 and splice @$row, 4; + } # max_4_fields + + csv (in => csv (in => "file.csv"), out => *STDOUT, + callbacks => { before print => \&max_4_fields }); + +This callback is not active for L. + +=back + +=head3 Callbacks for csv () + +The L allows for some callbacks that do not integrate in XS internals +but only feature the L function. + + csv (in => "file.csv", + callbacks => { + filter => { 6 => sub { $_ > 15 } }, # first + after_parse => sub { say "AFTER PARSE"; }, # first + after_in => sub { say "AFTER IN"; }, # second + on_in => sub { say "ON IN"; }, # third + }, + ); + + csv (in => $aoh, + out => "file.csv", + callbacks => { + on_in => sub { say "ON IN"; }, # first + before_out => sub { say "BEFORE OUT"; }, # second + before_print => sub { say "BEFORE PRINT"; }, # third + }, + ); + +=over 2 + +=item filter + +This callback can be used to filter records. It is called just after a new +record has been scanned. The callback accepts a hashref where the keys are +the index to the row (the field number, 1-based) and the values are subs to +return a true or false value. + + csv (in => "file.csv", filter => { + 3 => sub { m/a/ }, # third field should contain an "a" + 5 => sub { length > 4 }, # length of the 5th field minimal 5 + }); + + csv (in => "file.csv", filter => "not_blank"); + csv (in => "file.csv", filter => "not_empty"); + csv (in => "file.csv", filter => "filled"); + +If the keys to the filter hash contain any character that is not a digit it +will also implicitly set L to C<"auto"> unless L was +already passed as argument. When headers are active, returning an array of +hashes, the filter is not applicable to the header itself. + + csv (in => "file.csv", filter => { foo => sub { $_ > 4 }}); + +All sub results should match, as in AND. + +The context of the callback sets C<$_> localized to the field indicated by +the filter. The two arguments are as with all other callbacks, so the other +fields in the current row can be seen: + + filter => { 3 => sub { $_ > 100 ? $_[1][1] =~ m/A/ : $_[1][6] =~ m/B/ }} + +If the context is set to return a list of hashes (L is defined), +the current record will also be available in the localized C<%_>: + + filter => { 3 => sub { $_ > 100 && $_{foo} =~ m/A/ && $_{bar} < 1000 }} + +If the filter is used to I the content by changing C<$_>, make sure +that the sub returns true in order not to have that record skipped: + + filter => { 2 => sub { $_ = uc }} + +will upper-case the second field, and then skip it if the resulting content +evaluates to false. To always accept, end with truth: + + filter => { 2 => sub { $_ = uc; 1 }} + +B + +Given a file like (line numbers prefixed for doc purpose only): + + 1:1,2,3 + 2: + 3:, + 4:"" + 5:,, + 6:, , + 7:"", + 8:" " + 9:4,5,6 + +=over 2 + +=item not_blank + +Filter out the blank lines + +This filter is a shortcut for + + filter => { 0 => sub { @{$_[1]} > 1 or + defined $_[1][0] && $_[1][0] ne "" } } + +Due to the implementation, it is currently impossible to also filter lines +that consists only of a quoted empty field. These lines are also considered +blank lines. + +With the given example, lines 2 and 4 will be skipped. + +=item not_empty + +Filter out lines where all the fields are empty. + +This filter is a shortcut for + + filter => { 0 => sub { grep { defined && $_ ne "" } @{$_[1]} } } + +A space is not regarded being empty, so given the example data, lines 2, 3, +4, 5, and 7 are skipped. + +=item filled + +Filter out lines that have no visible data + +This filter is a shortcut for + + filter => { 0 => sub { grep { defined && m/\S/ } @{$_[1]} } } + +This filter rejects all lines that I have at least one field that does +not evaluate to the empty string. + +With the given example data, this filter would skip lines 2 through 8. + +=back + +=item after_in + +This callback is invoked for each record after all records have been parsed +but before returning the reference to the caller. The hook is invoked with +two arguments: the current C parser object and a reference to the +record. The reference can be a reference to a HASH or a reference to an +ARRAY as determined by the arguments. + +This callback can also be passed as an attribute without the C +wrapper. + +=item before_out + +This callback is invoked for each record before the record is printed. The +hook is invoked with two arguments: the current C parser object and a +reference to the record. The reference can be a reference to a HASH or a +reference to an ARRAY as determined by the arguments. + +This callback can also be passed as an attribute without the C +wrapper. + +This callback makes the row available in C<%_> if the row is a hashref. In +this case C<%_> is writable and will change the original row. + +=item on_in + +This callback acts exactly as the L or the L hooks. + +This callback can also be passed as an attribute without the C +wrapper. + +This callback makes the row available in C<%_> if the row is a hashref. In +this case C<%_> is writable and will change the original row. So e.g. with + + my $aoh = csv ( + in => \"foo\n1\n2\n", + headers => "auto", + on_in => sub { $_{bar} = 2; }, + ); + +C<$aoh> will be: + + [ { foo => 1, + bar => 2, + } + { foo => 2, + bar => 2, + } + ] + +=item csv + +The I L can also be called as a method or with an existing +Text::CSV object. This could help if the function is to be invoked a lot +of times and the overhead of creating the object internally over and over +again would be prevented by passing an existing instance. + + my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1 }); + + my $aoa = $csv->csv (in => $fh); + my $aoa = csv (in => $fh, csv => $csv); + +both act the same. Running this 20000 times on a 20 lines CSV file, showed +a 53% speedup. + +=back + +=head1 DIAGNOSTICS + +This section is also taken from Text::CSV_XS. + +If an error occurs, C<< $csv->error_diag >> can be used to get information +on the cause of the failure. Note that for speed reasons the internal value +is never cleared on success, so using the value returned by L +in normal cases - when no error occurred - may cause unexpected results. + +If the constructor failed, the cause can be found using L as a +class method, like C<< Text::CSV_PP->error_diag >>. + +The C<< $csv->error_diag >> method is automatically invoked upon error when +the contractor was called with L|/auto_diag> set to C<1> or +C<2>, or when L is in effect. When set to C<1>, this will cause a +C with the error message, when set to C<2>, it will C. C<2012 - +EOF> is excluded from L|/auto_diag> reports. + +Errors can be (individually) caught using the L callback. + +The errors as described below are available. I have tried to make the error +itself explanatory enough, but more descriptions will be added. For most of +these errors, the first three capitals describe the error category: + +=over 2 + +=item * +INI + +Initialization error or option conflict. + +=item * +ECR + +Carriage-Return related parse error. + +=item * +EOF + +End-Of-File related parse error. + +=item * +EIQ + +Parse error inside quotation. + +=item * +EIF + +Parse error inside field. + +=item * +ECB + +Combine error. + +=item * +EHR + +HashRef parse related error. + +=back + +And below should be the complete list of error codes that can be returned: + +=over 2 + +=item * +1001 "INI - sep_char is equal to quote_char or escape_char" +X<1001> + +The L cannot be equal to L or to L, as this +would invalidate all parsing rules. + +=item * +1002 "INI - allow_whitespace with escape_char or quote_char SP or TAB" +X<1002> + +Using the L|/allow_whitespace> attribute when either +L|/quote_char> or L|/escape_char> is equal to +C or C is too ambiguous to allow. + +=item * +1003 "INI - \r or \n in main attr not allowed" +X<1003> + +Using default L|/eol> characters in either L|/sep_char>, +L|/quote_char>, or L|/escape_char> is not +allowed. + +=item * +1004 "INI - callbacks should be undef or a hashref" +X<1004> + +The L|/Callbacks> attribute only allows one to be C or +a hash reference. + +=item * +1005 "INI - EOL too long" +X<1005> + +The value passed for EOL is exceeding its maximum length (16). + +=item * +1006 "INI - SEP too long" +X<1006> + +The value passed for SEP is exceeding its maximum length (16). + +=item * +1007 "INI - QUOTE too long" +X<1007> + +The value passed for QUOTE is exceeding its maximum length (16). + +=item * +1008 "INI - SEP undefined" +X<1008> + +The value passed for SEP should be defined and not empty. + +=item * +1010 "INI - the header is empty" +X<1010> + +The header line parsed in the L is empty. + +=item * +1011 "INI - the header contains more than one valid separator" +X<1011> + +The header line parsed in the L contains more than one (unique) +separator character out of the allowed set of separators. + +=item * +1012 "INI - the header contains an empty field" +X<1012> + +The header line parsed in the L is contains an empty field. + +=item * +1013 "INI - the header contains nun-unique fields" +X<1013> + +The header line parsed in the L contains at least two identical +fields. + +=item * +1014 "INI - header called on undefined stream" +X<1014> + +The header line cannot be parsed from an undefined sources. + +=item * +1500 "PRM - Invalid/unsupported argument(s)" +X<1500> + +Function or method called with invalid argument(s) or parameter(s). + +=item * +2010 "ECR - QUO char inside quotes followed by CR not part of EOL" +X<2010> + +When L|/eol> has been set to anything but the default, like +C<"\r\t\n">, and the C<"\r"> is following the B (closing) +L|/quote_char>, where the characters following the C<"\r"> do +not make up the L|/eol> sequence, this is an error. + +=item * +2011 "ECR - Characters after end of quoted field" +X<2011> + +Sequences like C<1,foo,"bar"baz,22,1> are not allowed. C<"bar"> is a quoted +field and after the closing double-quote, there should be either a new-line +sequence or a separation character. + +=item * +2012 "EOF - End of data in parsing input stream" +X<2012> + +Self-explaining. End-of-file while inside parsing a stream. Can happen only +when reading from streams with L, as using L is done on +strings that are not required to have a trailing L|/eol>. + +=item * +2013 "INI - Specification error for fragments RFC7111" +X<2013> + +Invalid specification for URI L specification. + +=item * +2021 "EIQ - NL char inside quotes, binary off" +X<2021> + +Sequences like C<1,"foo\nbar",22,1> are allowed only when the binary option +has been selected with the constructor. + +=item * +2022 "EIQ - CR char inside quotes, binary off" +X<2022> + +Sequences like C<1,"foo\rbar",22,1> are allowed only when the binary option +has been selected with the constructor. + +=item * +2023 "EIQ - QUO character not allowed" +X<2023> + +Sequences like C<"foo "bar" baz",qu> and C<2023,",2008-04-05,"Foo, Bar",\n> +will cause this error. + +=item * +2024 "EIQ - EOF cannot be escaped, not even inside quotes" +X<2024> + +The escape character is not allowed as last character in an input stream. + +=item * +2025 "EIQ - Loose unescaped escape" +X<2025> + +An escape character should escape only characters that need escaping. + +Allowing the escape for other characters is possible with the attribute +L. + +=item * +2026 "EIQ - Binary character inside quoted field, binary off" +X<2026> + +Binary characters are not allowed by default. Exceptions are fields that +contain valid UTF-8, that will automatically be upgraded if the content is +valid UTF-8. Set L|/binary> to C<1> to accept binary data. + +=item * +2027 "EIQ - Quoted field not terminated" +X<2027> + +When parsing a field that started with a quotation character, the field is +expected to be closed with a quotation character. When the parsed line is +exhausted before the quote is found, that field is not terminated. + +=item * +2030 "EIF - NL char inside unquoted verbatim, binary off" +X<2030> + +=item * +2031 "EIF - CR char is first char of field, not part of EOL" +X<2031> + +=item * +2032 "EIF - CR char inside unquoted, not part of EOL" +X<2032> + +=item * +2034 "EIF - Loose unescaped quote" +X<2034> + +=item * +2035 "EIF - Escaped EOF in unquoted field" +X<2035> + +=item * +2036 "EIF - ESC error" +X<2036> + +=item * +2037 "EIF - Binary character in unquoted field, binary off" +X<2037> + +=item * +2110 "ECB - Binary character in Combine, binary off" +X<2110> + +=item * +2200 "EIO - print to IO failed. See errno" +X<2200> + +=item * +3001 "EHR - Unsupported syntax for column_names ()" +X<3001> + +=item * +3002 "EHR - getline_hr () called before column_names ()" +X<3002> + +=item * +3003 "EHR - bind_columns () and column_names () fields count mismatch" +X<3003> + +=item * +3004 "EHR - bind_columns () only accepts refs to scalars" +X<3004> + +=item * +3006 "EHR - bind_columns () did not pass enough refs for parsed fields" +X<3006> + +=item * +3007 "EHR - bind_columns needs refs to writable scalars" +X<3007> + +=item * +3008 "EHR - unexpected error in bound fields" +X<3008> + +=item * +3009 "EHR - print_hr () called before column_names ()" +X<3009> + +=item * +3010 "EHR - print_hr () called with invalid arguments" +X<3010> + +=back + +=head1 SEE ALSO + +L, L and L. + + +=head1 AUTHORS and MAINTAINERS + +Alan Citterman Falan[at]mfgrtl.comE> wrote the original Perl +module. Please don't send mail concerning Text::CSV to Alan, as +he's not a present maintainer. + +Jochen Wiedmann Fjoe[at]ispsoft.deE> rewrote the encoding and +decoding in C by implementing a simple finite-state machine and added +the variable quote, escape and separator characters, the binary mode +and the print and getline methods. See ChangeLog releases 0.10 through +0.23. + +H.Merijn Brand Fh.m.brand[at]xs4all.nlE> cleaned up the code, +added the field flags methods, wrote the major part of the test suite, +completed the documentation, fixed some RT bugs. See ChangeLog releases +0.25 and on. + +Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE wrote Text::CSV_PP +which is the pure-Perl version of Text::CSV_XS. + +New Text::CSV (since 0.99) is maintained by Makamaka, and Kenichi Ishigaki +since 1.91. + + +=head1 COPYRIGHT AND LICENSE + +Text::CSV + +Copyright (C) 1997 Alan Citterman. All rights reserved. +Copyright (C) 2007-2015 Makamaka Hannyaharamitu. +Copyright (C) 2017- Kenichi Ishigaki +A large portion of the doc is taken from Text::CSV_XS. See below. + +Text::CSV_PP: + +Copyright (C) 2005-2015 Makamaka Hannyaharamitu. +Copyright (C) 2017- Kenichi Ishigaki +A large portion of the code/doc are also taken from Text::CSV_XS. See below. + +Text:CSV_XS: + +Copyright (C) 2007-2016 H.Merijn Brand for PROCURA B.V. +Copyright (C) 1998-2001 Jochen Wiedmann. All rights reserved. +Portions Copyright (C) 1997 Alan Citterman. All rights reserved. + + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/deployment-apps/TA-metricator-for-nmon/bin/lib/aix/Text/CSV_PP.pm b/deployment-apps/TA-metricator-for-nmon/bin/lib/aix/Text/CSV_PP.pm new file mode 100644 index 0000000..46430d4 --- /dev/null +++ b/deployment-apps/TA-metricator-for-nmon/bin/lib/aix/Text/CSV_PP.pm @@ -0,0 +1,4916 @@ +package Text::CSV_PP; + +################################################################################ +# +# Text::CSV_PP - Text::CSV_XS compatible pure-Perl module +# +################################################################################ +require 5.005; + +use strict; +use Exporter (); +use vars qw($VERSION @ISA @EXPORT_OK); +use Carp; + +$VERSION = '1.95'; +@ISA = qw(Exporter); +@EXPORT_OK = qw(csv); + +sub PV { 0 } +sub IV { 1 } +sub NV { 2 } + +sub IS_QUOTED () { 0x0001; } +sub IS_BINARY () { 0x0002; } +sub IS_ERROR () { 0x0004; } +sub IS_MISSING () { 0x0010; } + +sub HOOK_ERROR () { 0x0001; } +sub HOOK_AFTER_PARSE () { 0x0002; } +sub HOOK_BEFORE_PRINT () { 0x0004; } + +sub useIO_EOF () { 0x0010; } + +my $ERRORS = { + # Generic errors + 1000 => "INI - constructor failed", + 1001 => "INI - sep_char is equal to quote_char or escape_char", + 1002 => "INI - allow_whitespace with escape_char or quote_char SP or TAB", + 1003 => "INI - \\r or \\n in main attr not allowed", + 1004 => "INI - callbacks should be undef or a hashref", + 1005 => "INI - EOL too long", + 1006 => "INI - SEP too long", + 1007 => "INI - QUOTE too long", + 1008 => "INI - SEP undefined", + + 1010 => "INI - the header is empty", + 1011 => "INI - the header contains more than one valid separator", + 1012 => "INI - the header contains an empty field", + 1013 => "INI - the header contains nun-unique fields", + 1014 => "INI - header called on undefined stream", + + # Syntax errors + 1500 => "PRM - Invalid/unsupported arguments(s)", + + # Parse errors + 2010 => "ECR - QUO char inside quotes followed by CR not part of EOL", + 2011 => "ECR - Characters after end of quoted field", + 2012 => "EOF - End of data in parsing input stream", + 2013 => "ESP - Specification error for fragments RFC7111", + 2014 => "ENF - Inconsistent number of fields", + + # EIQ - Error Inside Quotes + 2021 => "EIQ - NL char inside quotes, binary off", + 2022 => "EIQ - CR char inside quotes, binary off", + 2023 => "EIQ - QUO character not allowed", + 2024 => "EIQ - EOF cannot be escaped, not even inside quotes", + 2025 => "EIQ - Loose unescaped escape", + 2026 => "EIQ - Binary character inside quoted field, binary off", + 2027 => "EIQ - Quoted field not terminated", + + # EIF - Error Inside Field + 2030 => "EIF - NL char inside unquoted verbatim, binary off", + 2031 => "EIF - CR char is first char of field, not part of EOL", + 2032 => "EIF - CR char inside unquoted, not part of EOL", + 2034 => "EIF - Loose unescaped quote", + 2035 => "EIF - Escaped EOF in unquoted field", + 2036 => "EIF - ESC error", + 2037 => "EIF - Binary character in unquoted field, binary off", + + # Combine errors + 2110 => "ECB - Binary character in Combine, binary off", + + # IO errors + 2200 => "EIO - print to IO failed. See errno", + + # Hash-Ref errors + 3001 => "EHR - Unsupported syntax for column_names ()", + 3002 => "EHR - getline_hr () called before column_names ()", + 3003 => "EHR - bind_columns () and column_names () fields count mismatch", + 3004 => "EHR - bind_columns () only accepts refs to scalars", + 3006 => "EHR - bind_columns () did not pass enough refs for parsed fields", + 3007 => "EHR - bind_columns needs refs to writable scalars", + 3008 => "EHR - unexpected error in bound fields", + 3009 => "EHR - print_hr () called before column_names ()", + 3010 => "EHR - print_hr () called with invalid arguments", + + # PP Only Error + 4002 => "EIQ - Unescaped ESC in quoted field", + 4003 => "EIF - ESC CR", + 4004 => "EUF - Field is terminated by the escape character (escape_char)", + + 0 => "", +}; + +BEGIN { + if ( $] < 5.006 ) { + $INC{'bytes.pm'} = 1 unless $INC{'bytes.pm'}; # dummy + no strict 'refs'; + *{"utf8::is_utf8"} = sub { 0; }; + *{"utf8::decode"} = sub { }; + } + elsif ( $] < 5.008 ) { + no strict 'refs'; + *{"utf8::is_utf8"} = sub { 0; }; + *{"utf8::decode"} = sub { }; + *{"utf8::encode"} = sub { }; + } + elsif ( !defined &utf8::is_utf8 ) { + require Encode; + *utf8::is_utf8 = *Encode::is_utf8; + } + + eval q| require Scalar::Util |; + if ( $@ ) { + eval q| require B |; + if ( $@ ) { + Carp::croak $@; + } + else { + my %tmap = qw( + B::NULL SCALAR + B::HV HASH + B::AV ARRAY + B::CV CODE + B::IO IO + B::GV GLOB + B::REGEXP REGEXP + ); + *Scalar::Util::reftype = sub (\$) { + my $r = shift; + return undef unless length(ref($r)); + my $t = ref(B::svref_2object($r)); + return + exists $tmap{$t} ? $tmap{$t} + : length(ref($$r)) ? 'REF' + : 'SCALAR'; + }; + *Scalar::Util::readonly = sub (\$) { + my $b = B::svref_2object( $_[0] ); + $b->FLAGS & 0x00800000; # SVf_READONLY? + }; + } + } +} + +################################################################################ +# +# Common pure perl methods, taken almost directly from Text::CSV_XS. +# (These should be moved into a common class eventually, so that +# both XS and PP don't need to apply the same changes.) +# +################################################################################ + +################################################################################ +# version +################################################################################ + +sub version { + return $VERSION; +} + +################################################################################ +# new +################################################################################ + +my %def_attr = ( + eol => '', + sep_char => ',', + quote_char => '"', + escape_char => '"', + binary => 0, + decode_utf8 => 1, + auto_diag => 0, + diag_verbose => 0, + strict => 0, + blank_is_undef => 0, + empty_is_undef => 0, + allow_whitespace => 0, + allow_loose_quotes => 0, + allow_loose_escapes => 0, + allow_unquoted_escape => 0, + always_quote => 0, + quote_empty => 0, + quote_space => 1, + quote_binary => 1, + escape_null => 1, + keep_meta_info => 0, + verbatim => 0, + types => undef, + callbacks => undef, + + _EOF => 0, + _RECNO => 0, + _STATUS => undef, + _FIELDS => undef, + _FFLAGS => undef, + _STRING => undef, + _ERROR_INPUT => undef, + _COLUMN_NAMES => undef, + _BOUND_COLUMNS => undef, + _AHEAD => undef, +); + +my %attr_alias = ( + quote_always => "always_quote", + verbose_diag => "diag_verbose", + quote_null => "escape_null", + ); + +my $last_new_error = Text::CSV_PP->SetDiag(0); +my $last_error; + +# NOT a method: is also used before bless +sub _unhealthy_whitespace { + my $self = shift; + $_[0] or return 0; # no checks needed without allow_whitespace + + my $quo = $self->{quote}; + defined $quo && length ($quo) or $quo = $self->{quote_char}; + my $esc = $self->{escape_char}; + + (defined $quo && $quo =~ m/^[ \t]/) || (defined $esc && $esc =~ m/^[ \t]/) and + return 1002; + + return 0; + } + +sub _check_sanity { + my $self = shift; + + my $eol = $self->{eol}; + my $sep = $self->{sep}; + defined $sep && length ($sep) or $sep = $self->{sep_char}; + my $quo = $self->{quote}; + defined $quo && length ($quo) or $quo = $self->{quote_char}; + my $esc = $self->{escape_char}; + +# use DP;::diag ("SEP: '", DPeek ($sep), +# "', QUO: '", DPeek ($quo), +# "', ESC: '", DPeek ($esc),"'"); + + # sep_char should not be undefined + if (defined $sep && $sep ne "") { + length ($sep) > 16 and return 1006; + $sep =~ m/[\r\n]/ and return 1003; + } + else { + return 1008; + } + if (defined $quo) { + defined $sep && $quo eq $sep and return 1001; + length ($quo) > 16 and return 1007; + $quo =~ m/[\r\n]/ and return 1003; + } + if (defined $esc) { + defined $sep && $esc eq $sep and return 1001; + $esc =~ m/[\r\n]/ and return 1003; + } + if (defined $eol) { + length ($eol) > 16 and return 1005; + } + + return _unhealthy_whitespace ($self, $self->{allow_whitespace}); + } + +sub known_attributes { + sort grep !m/^_/ => "sep", "quote", keys %def_attr; + } + +sub new { + $last_new_error = Text::CSV_PP->SetDiag(1000, + 'usage: my $csv = Text::CSV_PP->new ([{ option => value, ... }]);'); + + my $proto = shift; + my $class = ref ($proto) || $proto or return; + @_ > 0 && ref $_[0] ne "HASH" and return; + my $attr = shift || {}; + my %attr = map { + my $k = m/^[a-zA-Z]\w+$/ ? lc $_ : $_; + exists $attr_alias{$k} and $k = $attr_alias{$k}; + $k => $attr->{$_}; + } keys %$attr; + + my $sep_aliased = 0; + if (exists $attr{sep}) { + $attr{sep_char} = delete $attr{sep}; + $sep_aliased = 1; + } + my $quote_aliased = 0; + if (exists $attr{quote}) { + $attr{quote_char} = delete $attr{quote}; + $quote_aliased = 1; + } + for (keys %attr) { + if (m/^[a-z]/ && exists $def_attr{$_}) { + # uncoverable condition false + defined $attr{$_} && m/_char$/ and utf8::decode ($attr{$_}); + next; + } +# croak? + $last_new_error = Text::CSV_PP->SetDiag(1000, "INI - Unknown attribute '$_'"); + $attr{auto_diag} and error_diag (); + return; + } + if ($sep_aliased and defined $attr{sep_char}) { + my @b = unpack "U0C*", $attr{sep_char}; + if (@b > 1) { + $attr{sep} = $attr{sep_char}; + $attr{sep_char} = "\0"; + } + else { + $attr{sep} = undef; + } + } + if ($quote_aliased and defined $attr{quote_char}) { + my @b = unpack "U0C*", $attr{quote_char}; + if (@b > 1) { + $attr{quote} = $attr{quote_char}; + $attr{quote_char} = "\0"; + } + else { + $attr{quote} = undef; + } + } + + my $self = { %def_attr, %attr }; + if (my $ec = _check_sanity ($self)) { + $last_new_error = Text::CSV_PP->SetDiag($ec); + $attr{auto_diag} and error_diag (); + return; + } + if (defined $self->{callbacks} && ref $self->{callbacks} ne "HASH") { + Carp::carp "The 'callbacks' attribute is set but is not a hash: ignored\n"; + $self->{callbacks} = undef; + } + + $last_new_error = Text::CSV_PP->SetDiag(0); + defined $\ && !exists $attr{eol} and $self->{eol} = $\; + bless $self, $class; + defined $self->{types} and $self->types ($self->{types}); + $self; +} + +# Keep in sync with XS! +my %_cache_id = ( # Only expose what is accessed from within PM + quote_char => 0, + escape_char => 1, + sep_char => 2, + sep => 39, # 39 .. 55 + binary => 3, + keep_meta_info => 4, + always_quote => 5, + allow_loose_quotes => 6, + allow_loose_escapes => 7, + allow_unquoted_escape => 8, + allow_whitespace => 9, + blank_is_undef => 10, + eol => 11, + quote => 15, + verbatim => 22, + empty_is_undef => 23, + auto_diag => 24, + diag_verbose => 33, + quote_space => 25, + quote_empty => 37, + quote_binary => 32, + escape_null => 31, + decode_utf8 => 35, + _has_hooks => 36, + _is_bound => 26, # 26 .. 29 + strict => 58, + ); + +my %_hidden_cache_id = qw( + sep_len 38 + eol_len 12 + eol_is_cr 13 + quo_len 16 + _has_ahead 30 + has_error_input 34 +); + +my %_reverse_cache_id = ( + map({$_cache_id{$_} => $_} keys %_cache_id), + map({$_hidden_cache_id{$_} => $_} keys %_hidden_cache_id), +); + +# A `character' +sub _set_attr_C { + my ($self, $name, $val, $ec) = @_; + defined $val or $val = 0; + utf8::decode ($val); + $self->{$name} = $val; + $ec = _check_sanity ($self) and + croak ($self->SetDiag ($ec)); + $self->_cache_set ($_cache_id{$name}, $val); + } + +# A flag +sub _set_attr_X { + my ($self, $name, $val) = @_; + defined $val or $val = 0; + $self->{$name} = $val; + $self->_cache_set ($_cache_id{$name}, 0 + $val); + } + +# A number +sub _set_attr_N { + my ($self, $name, $val) = @_; + $self->{$name} = $val; + $self->_cache_set ($_cache_id{$name}, 0 + $val); + } + +# Accessor methods. +# It is unwise to change them halfway through a single file! +sub quote_char { + my $self = shift; + if (@_) { + $self->_set_attr_C ("quote_char", shift); + $self->_cache_set ($_cache_id{quote}, ""); + } + $self->{quote_char}; + } + +sub quote { + my $self = shift; + if (@_) { + my $quote = shift; + defined $quote or $quote = ""; + utf8::decode ($quote); + my @b = unpack "U0C*", $quote; + if (@b > 1) { + @b > 16 and croak ($self->SetDiag (1007)); + $self->quote_char ("\0"); + } + else { + $self->quote_char ($quote); + $quote = ""; + } + $self->{quote} = $quote; + + my $ec = _check_sanity ($self); + $ec and croak ($self->SetDiag ($ec)); + + $self->_cache_set ($_cache_id{quote}, $quote); + } + my $quote = $self->{quote}; + defined $quote && length ($quote) ? $quote : $self->{quote_char}; + } + +sub escape_char { + my $self = shift; + @_ and $self->_set_attr_C ("escape_char", shift); + $self->{escape_char}; + } + +sub sep_char { + my $self = shift; + if (@_) { + $self->_set_attr_C ("sep_char", shift); + $self->_cache_set ($_cache_id{sep}, ""); + } + $self->{sep_char}; +} + +sub sep { + my $self = shift; + if (@_) { + my $sep = shift; + defined $sep or $sep = ""; + utf8::decode ($sep); + my @b = unpack "U0C*", $sep; + if (@b > 1) { + @b > 16 and croak ($self->SetDiag (1006)); + $self->sep_char ("\0"); + } + else { + $self->sep_char ($sep); + $sep = ""; + } + $self->{sep} = $sep; + + my $ec = _check_sanity ($self); + $ec and croak ($self->SetDiag ($ec)); + + $self->_cache_set ($_cache_id{sep}, $sep); + } + my $sep = $self->{sep}; + defined $sep && length ($sep) ? $sep : $self->{sep_char}; + } + +sub eol { + my $self = shift; + if (@_) { + my $eol = shift; + defined $eol or $eol = ""; + length ($eol) > 16 and croak ($self->SetDiag (1005)); + $self->{eol} = $eol; + $self->_cache_set ($_cache_id{eol}, $eol); + } + $self->{eol}; + } + +sub always_quote { + my $self = shift; + @_ and $self->_set_attr_X ("always_quote", shift); + $self->{always_quote}; + } + +sub quote_space { + my $self = shift; + @_ and $self->_set_attr_X ("quote_space", shift); + $self->{quote_space}; + } + +sub quote_empty { + my $self = shift; + @_ and $self->_set_attr_X ("quote_empty", shift); + $self->{quote_empty}; + } + +sub escape_null { + my $self = shift; + @_ and $self->_set_attr_X ("escape_null", shift); + $self->{escape_null}; + } + +sub quote_null { goto &escape_null; } + +sub quote_binary { + my $self = shift; + @_ and $self->_set_attr_X ("quote_binary", shift); + $self->{quote_binary}; + } + +sub binary { + my $self = shift; + @_ and $self->_set_attr_X ("binary", shift); + $self->{binary}; + } + +sub strict { + my $self = shift; + @_ and $self->_set_attr_X ("strict", shift); + $self->{strict}; + } + +sub decode_utf8 { + my $self = shift; + @_ and $self->_set_attr_X ("decode_utf8", shift); + $self->{decode_utf8}; +} + +sub keep_meta_info { + my $self = shift; + if (@_) { + my $v = shift; + !defined $v || $v eq "" and $v = 0; + $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1 + $self->_set_attr_X ("keep_meta_info", $v); + } + $self->{keep_meta_info}; + } + +sub allow_loose_quotes { + my $self = shift; + @_ and $self->_set_attr_X ("allow_loose_quotes", shift); + $self->{allow_loose_quotes}; + } + +sub allow_loose_escapes { + my $self = shift; + @_ and $self->_set_attr_X ("allow_loose_escapes", shift); + $self->{allow_loose_escapes}; + } + +sub allow_whitespace { + my $self = shift; + if (@_) { + my $aw = shift; + _unhealthy_whitespace ($self, $aw) and + croak ($self->SetDiag (1002)); + $self->_set_attr_X ("allow_whitespace", $aw); + } + $self->{allow_whitespace}; + } + +sub allow_unquoted_escape { + my $self = shift; + @_ and $self->_set_attr_X ("allow_unquoted_escape", shift); + $self->{allow_unquoted_escape}; + } + +sub blank_is_undef { + my $self = shift; + @_ and $self->_set_attr_X ("blank_is_undef", shift); + $self->{blank_is_undef}; + } + +sub empty_is_undef { + my $self = shift; + @_ and $self->_set_attr_X ("empty_is_undef", shift); + $self->{empty_is_undef}; + } + +sub verbatim { + my $self = shift; + @_ and $self->_set_attr_X ("verbatim", shift); + $self->{verbatim}; + } + +sub auto_diag { + my $self = shift; + if (@_) { + my $v = shift; + !defined $v || $v eq "" and $v = 0; + $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1 + $self->_set_attr_X ("auto_diag", $v); + } + $self->{auto_diag}; + } + +sub diag_verbose { + my $self = shift; + if (@_) { + my $v = shift; + !defined $v || $v eq "" and $v = 0; + $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1 + $self->_set_attr_X ("diag_verbose", $v); + } + $self->{diag_verbose}; + } + +################################################################################ +# status +################################################################################ + +sub status { + $_[0]->{_STATUS}; +} + +sub eof { + $_[0]->{_EOF}; +} + +sub types { + my $self = shift; + + if (@_) { + if (my $types = shift) { + $self->{'_types'} = join("", map{ chr($_) } @$types); + $self->{'types'} = $types; + } + else { + delete $self->{'types'}; + delete $self->{'_types'}; + undef; + } + } + else { + $self->{'types'}; + } +} + +sub callbacks { + my $self = shift; + if (@_) { + my $cb; + my $hf = 0x00; + if (defined $_[0]) { + grep { !defined } @_ and croak ($self->SetDiag (1004)); + $cb = @_ == 1 && ref $_[0] eq "HASH" ? shift + : @_ % 2 == 0 ? { @_ } + : croak ($self->SetDiag (1004)); + foreach my $cbk (keys %$cb) { + (!ref $cbk && $cbk =~ m/^[\w.]+$/) && ref $cb->{$cbk} eq "CODE" or + croak ($self->SetDiag (1004)); + } + exists $cb->{error} and $hf |= 0x01; + exists $cb->{after_parse} and $hf |= 0x02; + exists $cb->{before_print} and $hf |= 0x04; + } + elsif (@_ > 1) { + # (undef, whatever) + croak ($self->SetDiag (1004)); + } + $self->_set_attr_X ("_has_hooks", $hf); + $self->{callbacks} = $cb; + } + $self->{callbacks}; + } + +################################################################################ +# error_diag +################################################################################ + +sub error_diag { + my $self = shift; + my @diag = (0 + $last_new_error, $last_new_error, 0, 0, 0); + + if ($self && ref $self && # Not a class method or direct call + $self->isa (__PACKAGE__) && defined $self->{_ERROR_DIAG}) { + $diag[0] = 0 + $self->{_ERROR_DIAG}; + $diag[1] = $self->{_ERROR_DIAG}; + $diag[2] = 1 + $self->{_ERROR_POS} if exists $self->{_ERROR_POS}; + $diag[3] = $self->{_RECNO}; + $diag[4] = $self->{_ERROR_FLD} if exists $self->{_ERROR_FLD}; + + $diag[0] && $self && $self->{callbacks} && $self->{callbacks}{error} and + return $self->{callbacks}{error}->(@diag); + } + + my $context = wantarray; + + unless (defined $context) { # Void context, auto-diag + if ($diag[0] && $diag[0] != 2012) { + my $msg = "# CSV_PP ERROR: $diag[0] - $diag[1] \@ rec $diag[3] pos $diag[2]\n"; + $diag[4] and $msg =~ s/$/ field $diag[4]/; + + unless ($self && ref $self) { # auto_diag + # called without args in void context + warn $msg; + return; + } + + if ($self->{diag_verbose} and $self->{_ERROR_INPUT}) { + $msg .= "$self->{_ERROR_INPUT}'\n"; + $msg .= " " x ($diag[2] - 1); + $msg .= "^\n"; + } + + my $lvl = $self->{auto_diag}; + if ($lvl < 2) { + my @c = caller (2); + if (@c >= 11 && $c[10] && ref $c[10] eq "HASH") { + my $hints = $c[10]; + (exists $hints->{autodie} && $hints->{autodie} or + exists $hints->{"guard Fatal"} && + !exists $hints->{"no Fatal"}) and + $lvl++; + # Future releases of autodie will probably set $^H{autodie} + # to "autodie @args", like "autodie :all" or "autodie open" + # so we can/should check for "open" or "new" + } + } + $lvl > 1 ? die $msg : warn $msg; + } + return; + } + + return $context ? @diag : $diag[1]; +} + +sub record_number { + return shift->{_RECNO}; +} + +################################################################################ +# string +################################################################################ + +*string = \&_string; +sub _string { + defined $_[0]->{_STRING} ? ${ $_[0]->{_STRING} } : undef; +} + +################################################################################ +# fields +################################################################################ + +*fields = \&_fields; +sub _fields { + ref($_[0]->{_FIELDS}) ? @{$_[0]->{_FIELDS}} : undef; +} + +################################################################################ +# meta_info +################################################################################ + +sub meta_info { + $_[0]->{_FFLAGS} ? @{ $_[0]->{_FFLAGS} } : undef; +} + +sub is_quoted { + return unless (defined $_[0]->{_FFLAGS}); + return if( $_[1] =~ /\D/ or $_[1] < 0 or $_[1] > $#{ $_[0]->{_FFLAGS} } ); + + $_[0]->{_FFLAGS}->[$_[1]] & IS_QUOTED ? 1 : 0; +} + +sub is_binary { + return unless (defined $_[0]->{_FFLAGS}); + return if( $_[1] =~ /\D/ or $_[1] < 0 or $_[1] > $#{ $_[0]->{_FFLAGS} } ); + $_[0]->{_FFLAGS}->[$_[1]] & IS_BINARY ? 1 : 0; +} + +sub is_missing { + my ($self, $idx, $val) = @_; + return unless $self->{keep_meta_info}; # FIXME + $idx < 0 || !ref $self->{_FFLAGS} and return; + $idx >= @{$self->{_FFLAGS}} and return 1; + $self->{_FFLAGS}[$idx] & IS_MISSING ? 1 : 0; +} + +################################################################################ +# combine +################################################################################ +*combine = \&_combine; +sub _combine { + my ($self, @fields) = @_; + my $str = ""; + $self->{_FIELDS} = \@fields; + $self->{_STATUS} = (@fields > 0) && $self->__combine(\$str, \@fields, 0); + $self->{_STRING} = \$str; + $self->{_STATUS}; + } + +################################################################################ +# parse +################################################################################ +*parse = \&_parse; +sub _parse { + my ($self, $str) = @_; + + ref $str and croak ($self->SetDiag (1500)); + + my $fields = []; + my $fflags = []; + $self->{_STRING} = \$str; + if (defined $str && $self->__parse ($fields, $fflags, $str, 0)) { + $self->{_FIELDS} = $fields; + $self->{_FFLAGS} = $fflags; + $self->{_STATUS} = 1; + } + else { + $self->{_FIELDS} = undef; + $self->{_FFLAGS} = undef; + $self->{_STATUS} = 0; + } + $self->{_STATUS}; + } + +sub column_names { + my ( $self, @columns ) = @_; + + @columns or return defined $self->{_COLUMN_NAMES} ? @{$self->{_COLUMN_NAMES}} : (); + @columns == 1 && ! defined $columns[0] and return $self->{_COLUMN_NAMES} = undef; + + if ( @columns == 1 && ref $columns[0] eq "ARRAY" ) { + @columns = @{ $columns[0] }; + } + elsif ( join "", map { defined $_ ? ref $_ : "" } @columns ) { + croak $self->SetDiag( 3001 ); + } + + if ( $self->{_BOUND_COLUMNS} && @columns != @{$self->{_BOUND_COLUMNS}} ) { + croak $self->SetDiag( 3003 ); + } + + $self->{_COLUMN_NAMES} = [ map { defined $_ ? $_ : "\cAUNDEF\cA" } @columns ]; + @{ $self->{_COLUMN_NAMES} }; +} + +sub header { + my ($self, $fh, @args) = @_; + + $fh or croak ($self->SetDiag (1014)); + + my (@seps, %args); + for (@args) { + if (ref $_ eq "ARRAY") { + push @seps, @$_; + next; + } + if (ref $_ eq "HASH") { + %args = %$_; + next; + } + croak (q{usage: $csv->header ($fh, [ seps ], { options })}); + } + + defined $args{detect_bom} or $args{detect_bom} = 1; + defined $args{munge_column_names} or $args{munge_column_names} = "lc"; + defined $args{set_column_names} or $args{set_column_names} = 1; + + defined $args{sep_set} && ref $args{sep_set} eq "ARRAY" and + @seps = @{$args{sep_set}}; + + my $hdr = <$fh>; + defined $hdr && $hdr ne "" or croak ($self->SetDiag (1010)); + + my %sep; + @seps or @seps = (",", ";"); + foreach my $sep (@seps) { + index ($hdr, $sep) >= 0 and $sep{$sep}++; + } + + keys %sep >= 2 and croak ($self->SetDiag (1011)); + + $self->sep (keys %sep); + my $enc = ""; + if ($args{detect_bom}) { # UTF-7 is not supported + if ($hdr =~ s/^\x00\x00\xfe\xff//) { $enc = "utf-32be" } + elsif ($hdr =~ s/^\xff\xfe\x00\x00//) { $enc = "utf-32le" } + elsif ($hdr =~ s/^\xfe\xff//) { $enc = "utf-16be" } + elsif ($hdr =~ s/^\xff\xfe//) { $enc = "utf-16le" } + elsif ($hdr =~ s/^\xef\xbb\xbf//) { $enc = "utf-8" } + elsif ($hdr =~ s/^\xf7\x64\x4c//) { $enc = "utf-1" } + elsif ($hdr =~ s/^\xdd\x73\x66\x73//) { $enc = "utf-ebcdic" } + elsif ($hdr =~ s/^\x0e\xfe\xff//) { $enc = "scsu" } + elsif ($hdr =~ s/^\xfb\xee\x28//) { $enc = "bocu-1" } + elsif ($hdr =~ s/^\x84\x31\x95\x33//) { $enc = "gb-18030" } + + if ($enc) { + if ($enc =~ m/([13]).le$/) { + my $l = 0 + $1; + my $x; + $hdr .= "\0" x $l; + read $fh, $x, $l; + } + $enc = ":encoding($enc)"; + binmode $fh, $enc; + } + } + + $args{munge_column_names} eq "lc" and $hdr = lc $hdr; + $args{munge_column_names} eq "uc" and $hdr = uc $hdr; + + my $hr = \$hdr; # Will cause croak on perl-5.6.x + open my $h, "<$enc", $hr; + my $row = $self->getline ($h) or croak; + close $h; + + my @hdr = @$row or croak ($self->SetDiag (1010)); + ref $args{munge_column_names} eq "CODE" and + @hdr = map { $args{munge_column_names}->($_) } @hdr; + my %hdr = map { $_ => 1 } @hdr; + exists $hdr{""} and croak ($self->SetDiag (1012)); + keys %hdr == @hdr or croak ($self->SetDiag (1013)); + $args{set_column_names} and $self->column_names (@hdr); + wantarray ? @hdr : $self; + } + +sub bind_columns { + my ( $self, @refs ) = @_; + + @refs or return defined $self->{_BOUND_COLUMNS} ? @{$self->{_BOUND_COLUMNS}} : undef; + @refs == 1 && ! defined $refs[0] and return $self->{_BOUND_COLUMNS} = undef; + + if ( $self->{_COLUMN_NAMES} && @refs != @{$self->{_COLUMN_NAMES}} ) { + croak $self->SetDiag( 3003 ); + } + + if ( grep { ref $_ ne "SCALAR" } @refs ) { # why don't use grep? + croak $self->SetDiag( 3004 ); + } + + $self->_set_attr_N("_is_bound", scalar @refs); + $self->{_BOUND_COLUMNS} = [ @refs ]; + @refs; +} + +sub getline_hr { + my ($self, @args, %hr) = @_; + $self->{_COLUMN_NAMES} or croak ($self->SetDiag (3002)); + my $fr = $self->getline (@args) or return; + if (ref $self->{_FFLAGS}) { # missing + $self->{_FFLAGS}[$_] = IS_MISSING + for (@$fr ? $#{$fr} + 1 : 0) .. $#{$self->{_COLUMN_NAMES}}; + @$fr == 1 && (!defined $fr->[0] || $fr->[0] eq "") and + $self->{_FFLAGS}[0] ||= IS_MISSING; + } + @hr{@{$self->{_COLUMN_NAMES}}} = @$fr; + \%hr; +} + +sub getline_hr_all { + my ( $self, $io, @args ) = @_; + my %hr; + + unless ( $self->{_COLUMN_NAMES} ) { + croak $self->SetDiag( 3002 ); + } + + my @cn = @{$self->{_COLUMN_NAMES}}; + + return [ map { my %h; @h{ @cn } = @$_; \%h } @{ $self->getline_all( $io, @args ) } ]; +} + +sub say { + my ($self, $io, @f) = @_; + my $eol = $self->eol; + defined $eol && $eol ne "" or $self->eol ($\ || $/); + my $state = $self->print ($io, @f); + $self->eol ($eol); + return $state; + } + +sub print_hr { + my ($self, $io, $hr) = @_; + $self->{_COLUMN_NAMES} or croak($self->SetDiag(3009)); + ref $hr eq "HASH" or croak($self->SetDiag(3010)); + $self->print ($io, [ map { $hr->{$_} } $self->column_names ]); +} + +sub fragment { + my ($self, $io, $spec) = @_; + + my $qd = qr{\s* [0-9]+ \s* }x; # digit + my $qs = qr{\s* (?: [0-9]+ | \* ) \s*}x; # digit or star + my $qr = qr{$qd (?: - $qs )?}x; # range + my $qc = qr{$qr (?: ; $qr )*}x; # list + defined $spec && $spec =~ m{^ \s* + \x23 ? \s* # optional leading # + ( row | col | cell ) \s* = + ( $qc # for row and col + | $qd , $qd (?: - $qs , $qs)? # for cell (ranges) + (?: ; $qd , $qd (?: - $qs , $qs)? )* # and cell (range) lists + ) \s* $}xi or croak ($self->SetDiag (2013)); + my ($type, $range) = (lc $1, $2); + + my @h = $self->column_names (); + + my @c; + if ($type eq "cell") { + my @spec; + my $min_row; + my $max_row = 0; + for (split m/\s*;\s*/ => $range) { + my ($tlr, $tlc, $brr, $brc) = (m{ + ^ \s* ([0-9]+ ) \s* , \s* ([0-9]+ ) \s* + (?: - \s* ([0-9]+ | \*) \s* , \s* ([0-9]+ | \*) \s* )? + $}x) or croak ($self->SetDiag (2013)); + defined $brr or ($brr, $brc) = ($tlr, $tlc); + $tlr == 0 || $tlc == 0 || + ($brr ne "*" && ($brr == 0 || $brr < $tlr)) || + ($brc ne "*" && ($brc == 0 || $brc < $tlc)) + and croak ($self->SetDiag (2013)); + $tlc--; + $brc-- unless $brc eq "*"; + defined $min_row or $min_row = $tlr; + $tlr < $min_row and $min_row = $tlr; + $brr eq "*" || $brr > $max_row and + $max_row = $brr; + push @spec, [ $tlr, $tlc, $brr, $brc ]; + } + my $r = 0; + while (my $row = $self->getline ($io)) { + ++$r < $min_row and next; + my %row; + my $lc; + foreach my $s (@spec) { + my ($tlr, $tlc, $brr, $brc) = @$s; + $r < $tlr || ($brr ne "*" && $r > $brr) and next; + !defined $lc || $tlc < $lc and $lc = $tlc; + my $rr = $brc eq "*" ? $#$row : $brc; + $row{$_} = $row->[$_] for $tlc .. $rr; + } + push @c, [ @row{sort { $a <=> $b } keys %row } ]; + if (@h) { + my %h; @h{@h} = @{$c[-1]}; + $c[-1] = \%h; + } + $max_row ne "*" && $r == $max_row and last; + } + return \@c; + } + + # row or col + my @r; + my $eod = 0; + for (split m/\s*;\s*/ => $range) { + my ($from, $to) = m/^\s* ([0-9]+) (?: \s* - \s* ([0-9]+ | \* ))? \s* $/x + or croak ($self->SetDiag (2013)); + $to ||= $from; + $to eq "*" and ($to, $eod) = ($from, 1); + $from <= 0 || $to <= 0 || $to < $from and croak ($self->SetDiag (2013)); + $r[$_] = 1 for $from .. $to; + } + + my $r = 0; + $type eq "col" and shift @r; + $_ ||= 0 for @r; + while (my $row = $self->getline ($io)) { + $r++; + if ($type eq "row") { + if (($r > $#r && $eod) || $r[$r]) { + push @c, $row; + if (@h) { + my %h; @h{@h} = @{$c[-1]}; + $c[-1] = \%h; + } + } + next; + } + push @c, [ map { ($_ > $#r && $eod) || $r[$_] ? $row->[$_] : () } 0..$#$row ]; + if (@h) { + my %h; @h{@h} = @{$c[-1]}; + $c[-1] = \%h; + } + } + + return \@c; + } + +my $csv_usage = q{usage: my $aoa = csv (in => $file);}; + +sub _csv_attr { + my %attr = (@_ == 1 && ref $_[0] eq "HASH" ? %{$_[0]} : @_) or croak; + + $attr{binary} = 1; + + my $enc = delete $attr{enc} || delete $attr{encoding} || ""; + $enc eq "auto" and ($attr{detect_bom}, $enc) = (1, ""); + $enc =~ m/^[-\w.]+$/ and $enc = ":encoding($enc)"; + + my $fh; + my $cls = 0; # If I open a file, I have to close it + my $in = delete $attr{in} || delete $attr{file} or croak $csv_usage; + my $out = delete $attr{out} || delete $attr{file}; + + ref $in eq "CODE" || ref $in eq "ARRAY" and $out ||= \*STDOUT; + + if ($out) { + $in or croak $csv_usage; # No out without in + if ((ref $out and ref $out ne "SCALAR") or "GLOB" eq ref \$out) { + $fh = $out; + } + else { + open $fh, ">", $out or croak "$out: $!"; + $cls = 1; + } + $enc and binmode $fh, $enc; + unless (defined $attr{eol}) { + my @layers = eval { PerlIO::get_layers ($fh) }; + $attr{eol} = (grep m/crlf/ => @layers) ? "\n" : "\r\n"; + } + } + + if ( ref $in eq "CODE" or ref $in eq "ARRAY") { + # All done + } + elsif (ref $in eq "SCALAR") { + # Strings with code points over 0xFF may not be mapped into in-memory file handles + # "<$enc" does not change that :( + open $fh, "<", $in or croak "Cannot open from SCALAR using PerlIO"; + $cls = 1; + } + elsif (ref $in or "GLOB" eq ref \$in) { + if (!ref $in && $] < 5.008005) { + $fh = \*$in; # uncoverable statement ancient perl version required + } + else { + $fh = $in; + } + } + else { + open $fh, "<$enc", $in or croak "$in: $!"; + $cls = 1; + } + $fh or croak qq{No valid source passed. "in" is required}; + + my $hdrs = delete $attr{headers}; + my $frag = delete $attr{fragment}; + my $key = delete $attr{key}; + + my $cbai = delete $attr{callbacks}{after_in} || + delete $attr{after_in} || + delete $attr{callbacks}{after_parse} || + delete $attr{after_parse}; + my $cbbo = delete $attr{callbacks}{before_out} || + delete $attr{before_out}; + my $cboi = delete $attr{callbacks}{on_in} || + delete $attr{on_in}; + + my $hd_s = delete $attr{sep_set} || + delete $attr{seps}; + my $hd_b = delete $attr{detect_bom} || + delete $attr{bom}; + my $hd_m = delete $attr{munge} || + delete $attr{munge_column_names}; + my $hd_c = delete $attr{set_column_names}; + + for ([ quo => "quote" ], + [ esc => "escape" ], + [ escape => "escape_char" ], + ) { + my ($f, $t) = @$_; + exists $attr{$f} and !exists $attr{$t} and $attr{$t} = delete $attr{$f}; + } + + my $fltr = delete $attr{filter}; + my %fltr = ( + not_blank => sub { @{$_[1]} > 1 or defined $_[1][0] && $_[1][0] ne "" }, + not_empty => sub { grep { defined && $_ ne "" } @{$_[1]} }, + filled => sub { grep { defined && m/\S/ } @{$_[1]} }, + ); + defined $fltr && !ref $fltr && exists $fltr{$fltr} and + $fltr = { 0 => $fltr{$fltr} }; + ref $fltr eq "HASH" or $fltr = undef; + + defined $attr{auto_diag} or $attr{auto_diag} = 1; + defined $attr{escape_null} or $attr{escape_null} = 0; + my $csv = delete $attr{csv} || Text::CSV_PP->new (\%attr) + or croak $last_new_error; + + return { + csv => $csv, + attr => { %attr }, + fh => $fh, + cls => $cls, + in => $in, + out => $out, + enc => $enc, + hdrs => $hdrs, + key => $key, + frag => $frag, + fltr => $fltr, + cbai => $cbai, + cbbo => $cbbo, + cboi => $cboi, + hd_s => $hd_s, + hd_b => $hd_b, + hd_m => $hd_m, + hd_c => $hd_c, + }; + } + +sub csv { + @_ && (ref $_[0] eq __PACKAGE__ or ref $_[0] eq 'Text::CSV') and splice @_, 0, 0, "csv"; + @_ or croak $csv_usage; + + my $c = _csv_attr (@_); + + my ($csv, $in, $fh, $hdrs) = @{$c}{"csv", "in", "fh", "hdrs"}; + my %hdr; + if (ref $hdrs eq "HASH") { + %hdr = %$hdrs; + $hdrs = "auto"; + } + + if ($c->{out}) { + if (ref $in eq "CODE") { + my $hdr = 1; + while (my $row = $in->($csv)) { + if (ref $row eq "ARRAY") { + $csv->print ($fh, $row); + next; + } + if (ref $row eq "HASH") { + if ($hdr) { + $hdrs ||= [ map { $hdr{$_} || $_ } keys %$row ]; + $csv->print ($fh, $hdrs); + $hdr = 0; + } + $csv->print ($fh, [ @{$row}{@$hdrs} ]); + } + } + } + elsif (ref $in->[0] eq "ARRAY") { # aoa + ref $hdrs and $csv->print ($fh, $hdrs); + for (@{$in}) { + $c->{cboi} and $c->{cboi}->($csv, $_); + $c->{cbbo} and $c->{cbbo}->($csv, $_); + $csv->print ($fh, $_); + } + } + else { # aoh + my @hdrs = ref $hdrs ? @{$hdrs} : keys %{$in->[0]}; + defined $hdrs or $hdrs = "auto"; + ref $hdrs || $hdrs eq "auto" and + $csv->print ($fh, [ map { $hdr{$_} || $_ } @hdrs ]); + for (@{$in}) { + local %_; + *_ = $_; + $c->{cboi} and $c->{cboi}->($csv, $_); + $c->{cbbo} and $c->{cbbo}->($csv, $_); + $csv->print ($fh, [ @{$_}{@hdrs} ]); + } + } + + $c->{cls} and close $fh; + return 1; + } + + if (defined $c->{hd_s} || defined $c->{hd_b} || defined $c->{hd_m} || defined $c->{hd_c}) { + my %harg; + defined $c->{hd_s} and $harg{set_set} = $c->{hd_s}; + defined $c->{hd_d} and $harg{detect_bom} = $c->{hd_b}; + defined $c->{hd_m} and $harg{munge_column_names} = $hdrs ? "none" : $c->{hd_m}; + defined $c->{hd_c} and $harg{set_column_names} = $hdrs ? 0 : $c->{hd_c}; + $csv->header ($fh, \%harg); + my @hdr = $csv->column_names; + @hdr and $hdrs ||= \@hdr; + } + + my $key = $c->{key} and $hdrs ||= "auto"; + $c->{fltr} && grep m/\D/ => keys %{$c->{fltr}} and $hdrs ||= "auto"; + if (defined $hdrs) { + if (!ref $hdrs) { + if ($hdrs eq "skip") { + $csv->getline ($fh); # discard; + } + elsif ($hdrs eq "auto") { + my $h = $csv->getline ($fh) or return; + $hdrs = [ map { $hdr{$_} || $_ } @$h ]; + } + elsif ($hdrs eq "lc") { + my $h = $csv->getline ($fh) or return; + $hdrs = [ map { lc ($hdr{$_} || $_) } @$h ]; + } + elsif ($hdrs eq "uc") { + my $h = $csv->getline ($fh) or return; + $hdrs = [ map { uc ($hdr{$_} || $_) } @$h ]; + } + } + elsif (ref $hdrs eq "CODE") { + my $h = $csv->getline ($fh) or return; + my $cr = $hdrs; + $hdrs = [ map { $cr->($hdr{$_} || $_) } @$h ]; + } + } + + if ($c->{fltr}) { + my %f = %{$c->{fltr}}; + # convert headers to index + my @hdr; + if (ref $hdrs) { + @hdr = @{$hdrs}; + for (0 .. $#hdr) { + exists $f{$hdr[$_]} and $f{$_ + 1} = delete $f{$hdr[$_]}; + } + } + $csv->callbacks (after_parse => sub { + my ($CSV, $ROW) = @_; # lexical sub-variables in caps + foreach my $FLD (sort keys %f) { + local $_ = $ROW->[$FLD - 1]; + local %_; + @hdr and @_{@hdr} = @$ROW; + $f{$FLD}->($CSV, $ROW) or return \"skip"; + $ROW->[$FLD - 1] = $_; + } + }); + } + + my $frag = $c->{frag}; + my $ref = ref $hdrs + ? # aoh + do { + $csv->column_names ($hdrs); + $frag ? $csv->fragment ($fh, $frag) : + $key ? { map { $_->{$key} => $_ } @{$csv->getline_hr_all ($fh)} } + : $csv->getline_hr_all ($fh); + } + : # aoa + $frag ? $csv->fragment ($fh, $frag) + : $csv->getline_all ($fh); + $ref or Text::CSV_PP->auto_diag; + $c->{cls} and close $fh; + if ($ref and $c->{cbai} || $c->{cboi}) { + foreach my $r (@{$ref}) { + local %_; + ref $r eq "HASH" and *_ = $r; + $c->{cbai} and $c->{cbai}->($csv, $r); + $c->{cboi} and $c->{cboi}->($csv, $r); + } + } + + defined wantarray or + return csv (%{$c->{attr}}, in => $ref, headers => $hdrs, %{$c->{attr}}); + + return $ref; + } + +# The end of the common pure perl part. + +################################################################################ +# +# The following are methods implemented in XS in Text::CSV_XS or +# helper methods for Text::CSV_PP only +# +################################################################################ + +sub _setup_ctx { + my $self = shift; + + $last_error = undef; + + my $ctx; + if ($self->{_CACHE}) { + $ctx = $self->{_CACHE}; + } else { + $ctx ||= {}; + # $ctx->{self} = $self; + $ctx->{pself} = ref $self || $self; + + $ctx->{sep} = ','; + if (defined $self->{sep_char}) { + $ctx->{sep} = $self->{sep_char}; + } + if (defined $self->{sep} and $self->{sep} ne '') { + use bytes; + $ctx->{sep} = $self->{sep}; + my $sep_len = length($ctx->{sep}); + $ctx->{sep_len} = $sep_len if $sep_len > 1; + } + + $ctx->{quo} = '"'; + if (exists $self->{quote_char}) { + my $quote_char = $self->{quote_char}; + if (defined $quote_char and length $quote_char) { + $ctx->{quo} = $quote_char; + } else { + $ctx->{quo} = "\0"; + } + } + if (defined $self->{quote} and $self->{quote} ne '') { + use bytes; + $ctx->{quo} = $self->{quote}; + my $quote_len = length($ctx->{quo}); + $ctx->{quo_len} = $quote_len if $quote_len > 1; + } + + $ctx->{escape_char} = '"'; + if (exists $self->{escape_char}) { + my $escape_char = $self->{escape_char}; + if (defined $escape_char and length $escape_char) { + $ctx->{escape_char} = $escape_char; + } else { + $ctx->{escape_char} = "\0"; + } + } + + if (defined $self->{eol}) { + my $eol = $self->{eol}; + my $eol_len = length($eol); + $ctx->{eol} = $eol; + $ctx->{eol_len} = $eol_len; + if ($eol_len == 1 and $eol eq "\015") { + $ctx->{eol_is_cr} = 1; + } + } + + if (defined $self->{_types}) { + $ctx->{types} = $self->{_types}; + $ctx->{types_len} = length($ctx->{types}); + } + + if (defined $self->{_is_bound}) { + $ctx->{is_bound} = $self->{_is_bound}; + } + + if (defined $self->{callbacks}) { + my $cb = $self->{callbacks}; + $ctx->{has_hooks} = 0; + if (defined $cb->{after_parse} and ref $cb->{after_parse} eq 'CODE') { + $ctx->{has_hooks} |= HOOK_AFTER_PARSE; + } + if (defined $cb->{before_print} and ref $cb->{before_print} eq 'CODE') { + $ctx->{has_hooks} |= HOOK_BEFORE_PRINT; + } + } + + for (qw/ + binary decode_utf8 always_quote strict quote_empty + allow_loose_quotes allow_loose_escapes + allow_unquoted_escape allow_whitespace blank_is_undef + empty_is_undef verbatim auto_diag diag_verbose + keep_meta_info + /) { + $ctx->{$_} = defined $self->{$_} ? $self->{$_} : 0; + } + for (qw/quote_space escape_null quote_binary/) { + $ctx->{$_} = defined $self->{$_} ? $self->{$_} : 1; + } + # FIXME: readonly + $self->{_CACHE} = $ctx; + } + + $ctx->{utf8} = 0; + $ctx->{size} = 0; + $ctx->{used} = 0; + + if ($ctx->{is_bound}) { + my $bound = $self->{_BOUND_COLUMNS}; + if ($bound and ref $bound eq 'ARRAY') { + $ctx->{bound} = $bound; + } else { + $ctx->{is_bound} = 0; + } + } + + $ctx->{eol_pos} = -1; + $ctx->{eolx} = $ctx->{eol_len} + ? $ctx->{verbatim} || $ctx->{eol_len} >= 2 + ? 1 + : $ctx->{eol} =~ /\A[\015|\012]/ ? 0 : 1 + : 0; + + if ($ctx->{sep_len} and _is_valid_utf8($ctx->{sep})) { + $ctx->{utf8} = 1; + } + if ($ctx->{quo_len} and _is_valid_utf8($ctx->{quo})) { + $ctx->{utf8} = 1; + } + + $ctx; +} + +sub _cache_set { + my ($self, $idx, $value) = @_; + return unless exists $self->{_CACHE}; + my $cache = $self->{_CACHE}; + + my $key = $_reverse_cache_id{$idx}; + if (!defined $key) { + warn (sprintf "Unknown cache index %d ignored\n", $idx); + } elsif ($key eq 'sep_char') { + $cache->{sep} = $value; + $cache->{sep_len} = 0; + } + elsif ($key eq 'quote_char') { + $cache->{quo} = $value; + $cache->{quo_len} = 0; + } + elsif ($key eq '_has_hooks') { + $cache->{has_hooks} = $value; + } + elsif ($key eq '_is_bound') { + $cache->{is_bound} = $value; + } + elsif ($key eq 'sep') { + use bytes; + my $len = bytes::length($value); + $cache->{sep} = $value if $len; + $cache->{sep_len} = $len == 1 ? 0 : $len; + } + elsif ($key eq 'quote') { + use bytes; + my $len = bytes::length($value); + $cache->{quo} = $value if $len; + $cache->{quo_len} = $len == 1 ? 0 : $len; + } + elsif ($key eq 'eol') { + $cache->{eol} = $value if length($value); + $cache->{eol_is_cr} = $value eq "\015" ? 1 : 0; + } + else { + $cache->{$key} = $value; + } + return 1; +} + +sub _cache_diag { + my $self = shift; + unless (exists $self->{_CACHE}) { + warn ("CACHE: invalid\n"); + return; + } + + my $cache = $self->{_CACHE}; + warn ("CACHE:\n"); + $self->__cache_show_char(quote_char => $cache->{quo}); + $self->__cache_show_char(escape_char => $cache->{escape_char}); + $self->__cache_show_char(sep_char => $cache->{sep}); + for (qw/ + binary decode_utf8 allow_loose_escapes allow_loose_quotes + allow_whitespace always_quote quote_empty quote_space + escape_null quote_binary auto_diag diag_verbose strict + has_error_input blank_is_undef empty_is_undef has_ahead + keep_meta_info verbatim has_hooks eol_is_cr eol_len + /) { + $self->__cache_show_byte($_ => $cache->{$_}); + } + $self->__cache_show_str(eol => $cache->{eol_len}, $cache->{eol}); + $self->__cache_show_byte(sep_len => $cache->{sep_len}); + if ($cache->{sep_len} and $cache->{sep_len} > 1) { + $self->__cache_show_str(sep => $cache->{sep_len}, $cache->{sep}); + } + $self->__cache_show_byte(quo_len => $cache->{quo_len}); + if ($cache->{quo_len} and $cache->{quo_len} > 1) { + $self->__cache_show_str(quote => $cache->{quo_len}, $cache->{quo}); + } +} + +sub __cache_show_byte { + my ($self, $key, $value) = @_; + warn (sprintf " %-21s %02x:%3d\n", $key, defined $value ? ord($value) : 0, defined $value ? $value : 0); +} + +sub __cache_show_char { + my ($self, $key, $value) = @_; + my $v = $value; + if (defined $value) { + my @b = unpack "U0C*", $value; + $v = pack "U*", $b[0]; + } + warn (sprintf " %-21s %02x:%s\n", $key, defined $v ? ord($v) : 0, $self->__pretty_str($v, 1)); +} + +sub __cache_show_str { + my ($self, $key, $len, $value) = @_; + warn (sprintf " %-21s %02d:%s\n", $key, $len, $self->__pretty_str($value, $len)); +} + +sub __pretty_str { # FIXME + my ($self, $str, $len) = @_; + return '' unless defined $str; + $str = substr($str, 0, $len); + $str =~ s/"/\\"/g; + $str =~ s/([^\x09\x20-\x7e])/sprintf '\\x{%x}', ord($1)/eg; + qq{"$str"}; +} + +sub _hook { + my ($self, $name, $fields) = @_; + return 0 unless $self->{callbacks}; + + my $cb = $self->{callbacks}{$name}; + return 0 unless $cb && ref $cb eq 'CODE'; + + my (@res) = $cb->($self, $fields); + if (@res) { + return 0 if ref $res[0] eq 'SCALAR' and ${$res[0]} eq "skip"; + } + scalar @res; +} + +################################################################################ +# methods for combine +################################################################################ + +sub __combine { + my ($self, $dst, $fields, $useIO) = @_; + + my $ctx = $self->_setup_ctx; + + my ($binary, $quot, $sep, $esc, $quote_space) = @{$ctx}{qw/binary quo sep escape_char quote_space/}; + + if(!defined $quot or $quot eq "\0"){ $quot = ''; } + + my $re_esc; + if ($quot ne '') { + $re_esc = $self->{_re_comb_escape}->{$quot}->{$esc} ||= qr/(\Q$quot\E|\Q$esc\E)/; + } else { + $re_esc = $self->{_re_comb_escape}->{$quot}->{$esc} ||= qr/(\Q$esc\E)/; + } + + my $re_sp = $self->{_re_comb_sp}->{$sep}->{$quote_space} ||= ( $quote_space ? qr/[\s\Q$sep\E]/ : qr/[\Q$sep\E]/ ); + + my $bound = 0; + my $n = @$fields - 1; + if ($n < 0 and $ctx->{is_bound}) { + $n = $ctx->{is_bound} - 1; + $bound = 1; + } + + my $check_meta = ($ctx->{keep_meta_info} >= 10 and @{$self->{_FFLAGS} || []} >= $n) ? 1 : 0; + + my $must_be_quoted; + my @results; + for(my $i = 0; $i <= $n; $i++) { + my $v_ref; + if ($bound) { + $v_ref = $self->__bound_field($ctx, $i, 1); + } else { + if (@$fields > $i) { + $v_ref = \($fields->[$i]); + } + } + next unless $v_ref; + + my $value = $$v_ref; + + unless (defined $value) { + push @results, ''; + next; + } + elsif ( !$binary ) { + $binary = 1 if utf8::is_utf8 $value; + } + + if (!$binary and $value =~ /[^\x09\x20-\x7E]/) { + # an argument contained an invalid character... + $self->{_ERROR_INPUT} = $value; + $self->SetDiag(2110); + return 0; + } + + $must_be_quoted = 0; + if ($value eq '') { + $must_be_quoted++ if $ctx->{quote_empty} or ($check_meta && $self->is_quoted($i)); + } + else { + if($value =~ s/$re_esc/$esc$1/g and $quot ne ''){ + $must_be_quoted++; + } + if($value =~ /$re_sp/){ + $must_be_quoted++; + } + + if( $binary and $ctx->{escape_null} ){ + use bytes; + $must_be_quoted++ if ( $value =~ s/\0/${esc}0/g || ($ctx->{quote_binary} && $value =~ /[\x00-\x1f\x7f-\xa0]/) ); + } + } + + if($ctx->{always_quote} or $must_be_quoted or ($check_meta && $self->is_quoted($i))){ + $value = $quot . $value . $quot; + } + push @results, $value; + } + + $$dst = join($sep, @results) . ( defined $ctx->{eol} ? $ctx->{eol} : '' ); + + return 1; +} + +sub print { + my ($self, $io, $fields) = @_; + + require IO::Handle; + + if (!defined $fields) { + $fields = []; + } elsif(ref($fields) ne 'ARRAY'){ + Carp::croak("Expected fields to be an array ref"); + } + + $self->_hook(before_print => $fields); + + my $str = ""; + $self->__combine(\$str, $fields, 1) or return ''; + + local $\ = ''; + + $io->print( $str ) or $self->_set_error_diag(2200); +} + +################################################################################ +# methods for parse +################################################################################ + + +sub __parse { # cx_xsParse + my ($self, $fields, $fflags, $src, $useIO) = @_; + + my $ctx = $self->_setup_ctx; + my $state = $self->___parse($ctx, $fields, $fflags, $src, $useIO); + if ($state and ($ctx->{has_hooks} || 0) & HOOK_AFTER_PARSE) { + $self->_hook(after_parse => $fields); + } + return $state || !$last_error; +} + +sub ___parse { # cx_c_xsParse + my ($self, $ctx, $fields, $fflags, $src, $useIO) = @_; + + local $/ = $ctx->{eol} if $ctx->{eolx} or $ctx->{eol_is_cr}; + + if ($ctx->{useIO} = $useIO) { + require IO::Handle; + + $ctx->{tmp} = undef; + if ($ctx->{has_ahead} and defined $self->{_AHEAD}) { + $ctx->{tmp} = $self->{_AHEAD}; + $ctx->{size} = length $ctx->{tmp}; + $ctx->{used} = 0; + } + } else { + $ctx->{tmp} = $src; + $ctx->{size} = length $src; + $ctx->{used} = 0; + $ctx->{utf8} = utf8::is_utf8($src); + } + if ($ctx->{has_error_input}) { + $self->{_ERROR_INPUT} = undef; + $ctx->{has_error_input} = 0; + } + + my $result = $self->____parse($ctx, $src, $fields, $fflags); + $self->{_RECNO} = ++($ctx->{recno}); + $self->{_EOF} = ''; + + if ($ctx->{strict}) { + $ctx->{strict_n} ||= $ctx->{fld_idx}; + if ($ctx->{strict_n} != $ctx->{fld_idx}) { + $self->__parse_error($ctx, 2014, $ctx->{used}); + return; + } + } + + if ($ctx->{useIO}) { + if (defined $ctx->{tmp} and $ctx->{used} < $ctx->{size} and $ctx->{has_ahead}) { + $self->{_AHEAD} = substr($ctx->{tmp}, $ctx->{used}, $ctx->{size} - $ctx->{used}); + } else { + $ctx->{has_ahead} = 0; + if ($ctx->{useIO} & useIO_EOF) { + $self->{_EOF} = 1; + } + } + + if ($fflags) { + if ($ctx->{keep_meta_info}) { + $self->{_FFLAGS} = $fflags; + } else { + undef $fflags; + } + } + } + + if ($result and $ctx->{types}) { + my $len = @$fields; + for(my $i = 0; $i <= $len && $i <= $ctx->{types_len}; $i++) { + my $value = $fields->[$i]; + next unless defined $value; + my $type = ord(substr($ctx->{types}, $i, 1)); + if ($type == IV) { + $fields->[$i] = int($value); + } elsif ($type == NV) { + $fields->[$i] = $value + 0.0; + } + } + } + + $result; +} + +sub ____parse { # cx_Parse + my ($self, $ctx, $src, $fields, $fflags) = @_; + + my ($quot, $sep, $esc, $eol) = @{$ctx}{qw/quo sep escape_char eol/}; + + utf8::encode($sep) if !$ctx->{utf8} and $ctx->{sep_len}; + utf8::encode($quot) if !$ctx->{utf8} and $ctx->{quo_len}; + utf8::encode($eol) if !$ctx->{utf8} and $ctx->{eol_len}; + + my $seenSomething = 0; + my $waitingForField = 1; + my ($value, $v_ref); + $ctx->{fld_idx} = my $fnum = 0; + $ctx->{flag} = 0; + + my $re_str = join '|', map({$_ eq "\0" ? '[\\0]' : quotemeta($_)} sort {length $b <=> length $a} grep {defined $_ and $_ ne ''} $sep, $quot, $esc, $eol), "\015", "\012", "\x09", " "; + $ctx->{_re} = qr/$re_str/; + my $re = qr/$re_str|[^\x09\x20-\x7E]|$/; + +LOOP: + while($self->__get_from_src($ctx, $src)) { + while($ctx->{tmp} =~ /\G(.*?)($re)/gs) { + my ($hit, $c) = ($1, $2); + $ctx->{used} = pos($ctx->{tmp}); + if (!$waitingForField and $c eq '' and $hit ne '' and $ctx->{useIO} and !($ctx->{useIO} & useIO_EOF)) { + $self->{_AHEAD} = $hit; + $ctx->{has_ahead} = 1; + $ctx->{has_leftover} = 1; + last; + } + last if $seenSomething and $hit eq '' and $c eq ''; # EOF + + # new field + if (!$v_ref) { + if ($ctx->{is_bound}) { + $v_ref = $self->__bound_field($ctx, $fnum++, 0); + } else { + $value = ''; + $v_ref = \$value; + } + return unless $v_ref; + $ctx->{flag} = 0; + $ctx->{fld_idx}++; + } + + $seenSomething = 1; + + if (defined $hit and $hit ne '') { + if ($waitingForField) { + $waitingForField = 0; + } + if ($hit =~ /[^\x09\x20-\x7E]/) { + $ctx->{flag} |= IS_BINARY; + } + $$v_ref .= $hit; + } + +RESTART: + if (defined $c and defined $sep and $c eq $sep) { + if ($waitingForField) { + # ,1,"foo, 3",,bar, + # ^ ^ + if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) { + $$v_ref = undef; + } else { + $$v_ref = ""; + } + unless ($ctx->{is_bound}) { + push @$fields, $$v_ref; + } + $v_ref = undef; + if ($ctx->{keep_meta_info} and $fflags) { + push @$fflags, $ctx->{flag}; + } + } elsif ($ctx->{flag} & IS_QUOTED) { + # ,1,"foo, 3",,bar, + # ^ + $$v_ref .= $c; + } else { + # ,1,"foo, 3",,bar, + # ^ ^ ^ + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + $v_ref = undef; + $waitingForField = 1; + } + } + elsif (defined $c and defined $quot and $quot ne "\0" and $c eq $quot) { + if ($waitingForField) { + # ,1,"foo, 3",,bar,\r\n + # ^ + $ctx->{flag} |= IS_QUOTED; + $waitingForField = 0; + next; + } + if ($ctx->{flag} & IS_QUOTED) { + # ,1,"foo, 3",,bar,\r\n + # ^ + my $quoesc = 0; + my $c2 = $self->__get($ctx); + + if ($ctx->{allow_whitespace}) { + # , 1 , "foo, 3" , , bar , \r\n + # ^ + while($self->__is_whitespace($ctx, $c2)) { + if ($ctx->{allow_loose_quotes} and !(defined $esc and $c2 eq $esc)) { + $$v_ref .= $c; + $c = $c2; + } + $c2 = $self->__get($ctx); + } + } + + if (!defined $c2) { # EOF + # ,1,"foo, 3" + # ^ + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + return 1; + } + + if (defined $c2 and defined $sep and $c2 eq $sep) { + # ,1,"foo, 3",,bar,\r\n + # ^ + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + $v_ref = undef; + $waitingForField = 1; + next; + } + if (defined $c2 and ($c2 eq "\012" or (defined $eol and $c2 eq $eol))) { # FIXME: EOLX + # ,1,"foo, 3",,"bar"\n + # ^ + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + return 1; + } + + if (defined $esc and $c eq $esc) { + $quoesc = 1; + if (defined $c2 and $c2 eq '0') { + # ,1,"foo, 3"056",,bar,\r\n + # ^ + $$v_ref .= "\0"; + next; + } + if (defined $c2 and defined $quot and $c2 eq $quot) { + # ,1,"foo, 3""56",,bar,\r\n + # ^ + if ($ctx->{utf8}) { + $ctx->{flag} |= IS_BINARY; + } + $$v_ref .= $c2; + next; + } + if ($ctx->{allow_loose_escapes} and defined $c2 and $c2 ne "\015") { + # ,1,"foo, 3"56",,bar,\r\n + # ^ + $$v_ref .= $c; + $c = $c2; + goto RESTART; + } + } + if (defined $c2 and $c2 eq "\015") { + if ($ctx->{eol_is_cr}) { + # ,1,"foo, 3"\r + # ^ + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + return 1; + } + + my $c3 = $self->__get($ctx); + if (defined $c3 and $c3 eq "\012") { + # ,1,"foo, 3"\r\n + # ^ + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + return 1; + } + + if ($ctx->{useIO} and !$ctx->{eol_len} and $c3 !~ /[^\x09\x20-\x7E]/) { + # ,1,"foo\n 3",,"bar"\r + # baz,4 + # ^ + $self->__set_eol_is_cr($ctx); + $ctx->{used}--; + $ctx->{has_ahead} = 1; + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + return 1; + } + + $self->__parse_error($ctx, $quoesc ? 2023 : 2010, $ctx->{used} - 2); + return; + } + + if ($ctx->{allow_loose_quotes} and !$quoesc) { + # ,1,"foo, 3"456",,bar,\r\n + # ^ + $$v_ref .= $c; + $c = $c2; + goto RESTART; + } + # 1,"foo" ",3 + # ^ + if ($quoesc) { + $ctx->{used}--; + $self->__error_inside_quotes($ctx, 2023); + return; + } + $self->__error_inside_quotes($ctx, 2011); + return; + } + # !waitingForField, !InsideQuotes + if ($ctx->{allow_loose_quotes}) { # 1,foo "boo" d'uh,1 + $ctx->{flag} |= IS_ERROR; + $$v_ref .= $c; + } else { + $self->__error_inside_field($ctx, 2034); + return; + } + } + elsif (defined $c and defined $esc and $esc ne "\0" and $c eq $esc) { + # This means quote_char != escape_char + if ($waitingForField) { + $waitingForField = 0; + if ($ctx->{allow_unquoted_escape}) { + # The escape character is the first character of an + # unquoted field + # ... get and store next character + my $c2 = $self->__get($ctx); + $$v_ref = ""; + + if (!defined $c2) { # EOF + $ctx->{used}--; + $self->__error_inside_field($ctx, 2035); + return; + } + if ($c2 eq '0') { + $$v_ref .= "\0"; + } + elsif ( + (defined $quot and $c2 eq $quot) or + (defined $sep and $c2 eq $sep) or + (defined $esc and $c2 eq $esc) or + $ctx->{allow_loose_escapes} + ) { + if ($ctx->{utf8}) { + $ctx->{flag} |= IS_BINARY; + } + $$v_ref .= $c2; + } else { + $self->__parse_inside_quotes($ctx, 2025); + return; + } + } + } + elsif ($ctx->{flag} & IS_QUOTED) { + my $c2 = $self->__get($ctx); + if (!defined $c2) { # EOF + $ctx->{used}--; + $self->__error_inside_quotes($ctx, 2024); + return; + } + if ($c2 eq '0') { + $$v_ref .= "\0"; + } + elsif ( + (defined $quot and $c2 eq $quot) or + (defined $sep and $c2 eq $sep) or + (defined $esc and $c2 eq $esc) or + $ctx->{allow_loose_escapes} + ) { + if ($ctx->{utf8}) { + $ctx->{flag} |= IS_BINARY; + } + $$v_ref .= $c2; + } else { + $ctx->{used}--; + $self->__error_inside_quotes($ctx, 2025); + return; + } + } + elsif ($v_ref) { + my $c2 = $self->__get($ctx); + if (!defined $c2) { # EOF + $ctx->{used}--; + $self->__error_inside_field($ctx, 2035); + return; + } + $$v_ref .= $c2; + } + else { + $self->__error_inside_field($ctx, 2036); + return; + } + } + elsif (defined $c and ($c eq "\012" or $c eq '' or (defined $eol and $c eq $eol and $eol ne "\015"))) { # EOL + EOLX: + if ($waitingForField) { + # ,1,"foo, 3",,bar, + # ^ + if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) { + $$v_ref = undef; + } else { + $$v_ref = ""; + } + unless ($ctx->{is_bound}) { + push @$fields, $$v_ref; + } + if ($ctx->{keep_meta_info} and $fflags) { + push @$fflags, $ctx->{flag}; + } + return 1; + } + if ($ctx->{flag} & IS_QUOTED) { + # ,1,"foo\n 3",,bar, + # ^ + $ctx->{flag} |= IS_BINARY; + unless ($ctx->{binary}) { + $self->__error_inside_quotes($ctx, 2021); + return; + } + $$v_ref .= $c; + } + elsif ($ctx->{verbatim}) { + # ,1,foo\n 3,,bar, + # This feature should be deprecated + $ctx->{flag} |= IS_BINARY; + unless ($ctx->{binary}) { + $self->__error_inside_field($ctx, 2030); + return; + } + $$v_ref .= $c unless $ctx->{eol} eq $c and $ctx->{useIO}; + } + else { + # sep=, + # ^ + if (!$ctx->{recno} and $ctx->{fld_idx} == 1 and $ctx->{useIO} and $hit =~ /^sep=(.{1,16})$/i) { + $ctx->{sep} = $1; + use bytes; + my $len = length $ctx->{sep}; + if ($len <= 16) { + $ctx->{sep_len} = $len == 1 ? 0 : $len; + return $self->____parse($ctx, $src, $fields, $fflags); + } + } + + # ,1,"foo\n 3",,bar + # ^ + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + return 1; + } + } + elsif (defined $c and $c eq "\015" and !$ctx->{verbatim}) { + if ($waitingForField) { + $waitingForField = 0; + if ($ctx->{eol_is_cr}) { + # ,1,"foo\n 3",,bar,\r + # ^ + $c = "\012"; + goto RESTART; + } + + my $c2 = $self->__get($ctx); + if (!defined $c2) { # EOF + # ,1,"foo\n 3",,bar,\r + # ^ + $c = undef; + goto RESTART; + } + if ($c2 eq "\012") { # \r is not optional before EOLX! + # ,1,"foo\n 3",,bar,\r\n + # ^ + $c = $c2; + goto RESTART; + } + + if ($ctx->{useIO} and !$ctx->{eol_len} and $c2 !~ /[^\x09\x20-\x7E]/) { + # ,1,"foo\n 3",,bar,\r + # baz,4 + # ^ + $self->__set_eol_is_cr($ctx); + $ctx->{used}--; + $ctx->{has_ahead} = 1; + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + return 1; + } + + # ,1,"foo\n 3",,bar,\r\t + # ^ + $ctx->{used}--; + $self->__error_inside_field($ctx, 2031); + return; + } + if ($ctx->{flag} & IS_QUOTED) { + # ,1,"foo\r 3",,bar,\r\t + # ^ + $ctx->{flag} |= IS_BINARY; + unless ($ctx->{binary}) { + $self->__error_inside_quotes($ctx, 2022); + return; + } + $$v_ref .= $c; + } + else { + if ($ctx->{eol_is_cr}) { + # ,1,"foo\n 3",,bar\r + # ^ + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + return 1; + } + + my $c2 = $self->__get($ctx); + if (defined $c2 and $c2 eq "\012") { # \r is not optional before EOLX! + # ,1,"foo\n 3",,bar\r\n + # ^ + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + return 1; + } + + if ($ctx->{useIO} and !$ctx->{eol_len} and $c2 !~ /[^\x09\x20-\x7E]/) { + # ,1,"foo\n 3",,bar\r + # baz,4 + # ^ + $self->__set_eol_is_cr($ctx); + $ctx->{used}--; + $ctx->{has_ahead} = 1; + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + return 1; + } + + # ,1,"foo\n 3",,bar\r\t + # ^ + $self->__error_inside_field($ctx, 2032); + return; + } + } + else { + if ($ctx->{eolx} and $c eq $eol) { + $c = ''; + goto EOLX; + } + + if ($waitingForField) { + if ($ctx->{allow_whitespace} and $self->__is_whitespace($ctx, $c)) { + do { + $c = $self->__get($ctx); + last if !defined $c; + } while $self->__is_whitespace($ctx, $c); + goto RESTART; + } + $waitingForField = 0; + goto RESTART; + } + if ($ctx->{flag} & IS_QUOTED) { + if (!defined $c or $c =~ /[^\x09\x20-\x7E]/) { + $ctx->{flag} |= IS_BINARY; + unless ($ctx->{binary} or $ctx->{utf8}) { + $self->__error_inside_quotes($ctx, 2026); + return; + } + } + $$v_ref .= $c; + } else { + if (!defined $c or $c =~ /[^\x09\x20-\x7E]/) { + $ctx->{flag} |= IS_BINARY; + unless ($ctx->{binary} or $ctx->{utf8}) { + $self->__error_inside_field($ctx, 2037); + return; + } + } + $$v_ref .= $c; + } + } + last LOOP if $ctx->{useIO} and $ctx->{verbatim} and $ctx->{used} == $ctx->{size}; + } + } + + if ($waitingForField) { + if ($seenSomething or !$ctx->{useIO}) { + # new field + if (!$v_ref) { + if ($ctx->{is_bound}) { + $v_ref = $self->__bound_field($ctx, $fnum++, 0); + } else { + $value = ''; + $v_ref = \$value; + } + return unless $v_ref; + $ctx->{flag} = 0; + $ctx->{fld_idx}++; + } + if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) { + $$v_ref = undef; + } else { + $$v_ref = ""; + } + unless ($ctx->{is_bound}) { + push @$fields, $$v_ref; + } + if ($ctx->{keep_meta_info} and $fflags) { + push @$fflags, $ctx->{flag}; + } + return 1; + } + $self->SetDiag(2012); + return; + } + + if ($ctx->{flag} & IS_QUOTED) { + $self->__error_inside_quotes($ctx, 2027); + return; + } + + if ($v_ref) { + $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}); + } + return 1; +} + +sub __get_from_src { + my ($self, $ctx, $src) = @_; + return 1 if defined $ctx->{tmp} and $ctx->{used} <= 0; + return 1 if $ctx->{used} < $ctx->{size}; + return unless $ctx->{useIO}; + my $res = $src->getline; + if (defined $res) { + if ($ctx->{has_ahead}) { + $ctx->{tmp} = $self->{_AHEAD}; + $ctx->{tmp} .= $ctx->{eol} if $ctx->{eol_len}; + $ctx->{tmp} .= $res; + $ctx->{has_ahead} = 0; + } else { + $ctx->{tmp} = $res; + } + if ($ctx->{size} = length $ctx->{tmp}) { + $ctx->{used} = -1; + $ctx->{utf8} = 1 if utf8::is_utf8($ctx->{tmp}); + pos($ctx->{tmp}) = 0; + return 1; + } + } elsif (delete $ctx->{has_leftover}) { + $ctx->{tmp} = $self->{_AHEAD}; + $ctx->{has_ahead} = 0; + $ctx->{useIO} |= useIO_EOF; + if ($ctx->{size} = length $ctx->{tmp}) { + $ctx->{used} = -1; + $ctx->{utf8} = 1 if utf8::is_utf8($ctx->{tmp}); + pos($ctx->{tmp}) = 0; + return 1; + } + } + $ctx->{tmp} = '' unless defined $ctx->{tmp}; + $ctx->{useIO} |= useIO_EOF; + return; +} + +sub __set_eol_is_cr { + my ($self, $ctx) = @_; + $ctx->{eol} = "\015"; + $ctx->{eol_is_cr} = 1; + $ctx->{eol_len} = 1; + + $self->{eol} = $ctx->{eol}; +} + +sub __bound_field { + my ($self, $ctx, $i, $keep) = @_; + if ($i >= $ctx->{is_bound}) { + $self->SetDiag(3006); + return; + } + if (ref $ctx->{bound} eq 'ARRAY') { + my $ref = $ctx->{bound}[$i]; + if (ref $ref) { + if ($keep) { + return $ref; + } + unless (Scalar::Util::readonly($$ref)) { + $$ref = ""; + return $ref; + } + } + } + $self->SetDiag(3008); + return; +} + +sub __get { + my ($self, $ctx) = @_; + return unless defined $ctx->{used}; + return if $ctx->{used} >= $ctx->{size}; + my $pos = pos($ctx->{tmp}); + if ($ctx->{tmp} =~ /\G($ctx->{_re}|.)/gs) { + my $c = $1; + if ($c =~ /[^\x09\x20-\x7e]/) { + $ctx->{flag} |= IS_BINARY; + } + $ctx->{used} = pos($ctx->{tmp}); + return $c; + } else { + pos($ctx->{tmp}) = $pos; + return; + } +} + +sub __error_inside_quotes { + my ($self, $ctx, $error) = @_; + $self->__parse_error($ctx, $error, $ctx->{used} - 1); +} + +sub __error_inside_field { + my ($self, $ctx, $error) = @_; + $self->__parse_error($ctx, $error, $ctx->{used} - 1); +} + +sub __parse_error { + my ($self, $ctx, $error, $pos) = @_; + $self->{_ERROR_POS} = $pos; + $self->{_ERROR_FLD} = $ctx->{fld_idx}; + $self->{_ERROR_INPUT} = $ctx->{tmp} if $ctx->{tmp}; + $self->SetDiag($error); + return; +} + +sub __is_whitespace { + my ($self, $ctx, $c) = @_; + return unless defined $c; + return ( + (!defined $ctx->{sep} or $c ne $ctx->{sep}) && + (!defined $ctx->{quo} or $c ne $ctx->{quo}) && + (!defined $ctx->{escape_char} or $c ne $ctx->{escape_char}) && + ($c eq " " or $c eq "\t") + ); +} + +sub __push_value { # AV_PUSH (part of) + my ($self, $ctx, $v_ref, $fields, $fflags, $flag) = @_; + utf8::encode($$v_ref) if $ctx->{utf8}; + if ( + (!defined $$v_ref or $$v_ref eq '') and + ($ctx->{empty_is_undef} or (!($flag & IS_QUOTED) and $ctx->{blank_is_undef})) + ) { + $$v_ref = undef; + } else { + if ($ctx->{allow_whitespace} && !($flag & IS_QUOTED)) { + $$v_ref =~ s/[ \t]+$//; + } + if ($flag & IS_BINARY and $ctx->{decode_utf8} and ($ctx->{utf8} || _is_valid_utf8($$v_ref))) { + utf8::decode($$v_ref); + } + } + unless ($ctx->{is_bound}) { + push @$fields, $$v_ref; + } + if ($ctx->{keep_meta_info} and $fflags) { + push @$fflags, $flag; + } +} + +sub getline { + my ($self, $io) = @_; + + my (@fields, @fflags); + my $res = $self->__parse(\@fields, \@fflags, $io, 1); + $res ? \@fields : undef; +} + +sub getline_all { + my ( $self, $io, $offset, $len ) = @_; + + my $ctx = $self->_setup_ctx; + + my $tail = 0; + my $n = 0; + $offset ||= 0; + + if ( $offset < 0 ) { + $tail = -$offset; + $offset = -1; + } + + my (@row, @list); + while ($self->___parse($ctx, \@row, undef, $io, 1)) { + $ctx = $self->_setup_ctx; + + if ($offset > 0) { + $offset--; + @row = (); + next; + } + if ($n++ >= $tail and $tail) { + shift @list; + $n--; + } + if (($ctx->{has_hooks} || 0) & HOOK_AFTER_PARSE) { + unless ($self->_hook(after_parse => \@row)) { + @row = (); + next; + } + } + push @list, [@row]; + @row = (); + + last if defined $len && $n >= $len and $offset >= 0; # exceeds limit size + } + + if ( defined $len && $n > $len ) { + @list = splice( @list, 0, $len); + } + + return \@list; +} + +sub _is_valid_utf8 { + return ( $_[0] =~ /^(?: + [\x00-\x7F] + |[\xC2-\xDF][\x80-\xBF] + |[\xE0][\xA0-\xBF][\x80-\xBF] + |[\xE1-\xEC][\x80-\xBF][\x80-\xBF] + |[\xED][\x80-\x9F][\x80-\xBF] + |[\xEE-\xEF][\x80-\xBF][\x80-\xBF] + |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF] + |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF] + |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF] + )+$/x ) ? 1 : 0; +} + +################################################################################ +# methods for errors +################################################################################ + +sub _set_error_diag { + my ( $self, $error, $pos ) = @_; + + $self->SetDiag($error); + + if (defined $pos) { + $_[0]->{_ERROR_POS} = $pos; + } + + return; +} + +sub error_input { + my $self = shift; + if ($self and ((Scalar::Util::reftype($self) || '') eq 'HASH' or (ref $self) =~ /^Text::CSV/)) { + return $self->{_ERROR_INPUT}; + } + return; +} + +sub _sv_diag { + my ($self, $error) = @_; + bless [$error, $ERRORS->{$error}], 'Text::CSV::ErrorDiag'; +} + +sub _set_diag { + my ($self, $ctx, $error) = @_; + + $last_error = $self->_sv_diag($error); + $self->{_ERROR_DIAG} = $last_error; + if ($error == 0) { + $self->{_ERROR_POS} = 0; + $self->{_ERROR_FLD} = 0; + $self->{_ERROR_INPUT} = undef; + $ctx->{has_error_input} = 0; + } + if ($error == 2012) { # EOF + $self->{_EOF} = 1; + } + if ($ctx->{auto_diag}) { + $self->error_diag; + } + return $last_error; +} + +sub SetDiag { + my ($self, $error, $errstr) = @_; + my $res; + if (ref $self) { + my $ctx = $self->_setup_ctx; + $res = $self->_set_diag($ctx, $error); + + } else { + $res = $self->_sv_diag($error); + } + if (defined $errstr) { + $res->[1] = $errstr; + } + $res; +} + +################################################################################ +package Text::CSV::ErrorDiag; + +use strict; +use overload ( + '""' => \&stringify, + '+' => \&numeric, + '-' => \&numeric, + '*' => \&numeric, + '/' => \&numeric, + fallback => 1, +); + + +sub numeric { + my ($left, $right) = @_; + return ref $left ? $left->[0] : $right->[0]; +} + + +sub stringify { + $_[0]->[1]; +} +################################################################################ +1; +__END__ + +=head1 NAME + +Text::CSV_PP - Text::CSV_XS compatible pure-Perl module + + +=head1 SYNOPSIS + + use Text::CSV_PP; + + $csv = Text::CSV_PP->new(); # create a new object + # If you want to handle non-ascii char. + $csv = Text::CSV_PP->new({binary => 1}); + + $status = $csv->combine(@columns); # combine columns into a string + $line = $csv->string(); # get the combined string + + $status = $csv->parse($line); # parse a CSV string into fields + @columns = $csv->fields(); # get the parsed fields + + $status = $csv->status (); # get the most recent status + $bad_argument = $csv->error_input (); # get the most recent bad argument + $diag = $csv->error_diag (); # if an error occurred, explains WHY + + $status = $csv->print ($io, $colref); # Write an array of fields + # immediately to a file $io + $colref = $csv->getline ($io); # Read a line from file $io, + # parse it and return an array + # ref of fields + $csv->column_names (@names); # Set column names for getline_hr () + $ref = $csv->getline_hr ($io); # getline (), but returns a hashref + $eof = $csv->eof (); # Indicate if last parse or + # getline () hit End Of File + + $csv->types(\@t_array); # Set column types + +=head1 DESCRIPTION + +Text::CSV_PP is a pure-perl module that provides facilities for the +composition and decomposition of comma-separated values. This is +(almost) compatible with much faster L, and mainly +used as its fallback module when you use L module without +having installed Text::CSV_XS. If you don't have any reason to use +this module directly, use Text::CSV for speed boost and portability +(or maybe Text::CSV_XS when you write an one-off script and don't need +to care about portability). + +The following caveats are taken from the doc of Text::CSV_XS. + +=head2 Embedded newlines + +B: The default behavior is to accept only ASCII characters +in the range from C<0x20> (space) to C<0x7E> (tilde). This means that the +fields can not contain newlines. If your data contains newlines embedded in +fields, or characters above C<0x7E> (tilde), or binary data, you B> +set C<< binary => 1 >> in the call to L. To cover the widest range of +parsing options, you will always want to set binary. + +But you still have the problem that you have to pass a correct line to the +L method, which is more complicated from the usual point of usage: + + my $csv = Text::CSV_PP->new ({ binary => 1, eol => $/ }); + while (<>) { # WRONG! + $csv->parse ($_); + my @fields = $csv->fields (); + } + +this will break, as the C might read broken lines: it does not care +about the quoting. If you need to support embedded newlines, the way to go +is to B pass L|/eol> in the parser (it accepts C<\n>, C<\r>, +B C<\r\n> by default) and then + + my $csv = Text::CSV_PP->new ({ binary => 1 }); + open my $io, "<", $file or die "$file: $!"; + while (my $row = $csv->getline ($io)) { + my @fields = @$row; + } + +The old(er) way of using global file handles is still supported + + while (my $row = $csv->getline (*ARGV)) { ... } + +=head2 Unicode + +Unicode is only tested to work with perl-5.8.2 and up. + +The simplest way to ensure the correct encoding is used for in- and output +is by either setting layers on the filehandles, or setting the L +argument for L. + + open my $fh, "<:encoding(UTF-8)", "in.csv" or die "in.csv: $!"; +or + my $aoa = csv (in => "in.csv", encoding => "UTF-8"); + + open my $fh, ">:encoding(UTF-8)", "out.csv" or die "out.csv: $!"; +or + csv (in => $aoa, out => "out.csv", encoding => "UTF-8"); + +On parsing (both for L and L), if the source is marked +being UTF8, then all fields that are marked binary will also be marked UTF8. + +On combining (L and L): if any of the combining fields +was marked UTF8, the resulting string will be marked as UTF8. Note however +that all fields I the first field marked UTF8 and contained 8-bit +characters that were not upgraded to UTF8, these will be C in the +resulting string too, possibly causing unexpected errors. If you pass data +of different encoding, or you don't know if there is different encoding, +force it to be upgraded before you pass them on: + + $csv->print ($fh, [ map { utf8::upgrade (my $x = $_); $x } @data ]); + +For complete control over encoding, please use L: + + use Text::CSV::Encoded; + my $csv = Text::CSV::Encoded->new ({ + encoding_in => "iso-8859-1", # the encoding comes into Perl + encoding_out => "cp1252", # the encoding comes out of Perl + }); + + $csv = Text::CSV::Encoded->new ({ encoding => "utf8" }); + # combine () and print () accept *literally* utf8 encoded data + # parse () and getline () return *literally* utf8 encoded data + + $csv = Text::CSV::Encoded->new ({ encoding => undef }); # default + # combine () and print () accept UTF8 marked data + # parse () and getline () return UTF8 marked data + +=head1 METHODS + +This whole section is also taken from Text::CSV_XS. + +=head2 version () + +(Class method) Returns the current module version. + +=head2 new (\%attr) + +(Class method) Returns a new instance of Text::CSV_PP. The attributes +are described by the (optional) hash ref C<\%attr>. + + my $csv = Text::CSV_PP->new ({ attributes ... }); + +The following attributes are available: + +=head3 eol + + my $csv = Text::CSV_PP->new ({ eol => $/ }); + $csv->eol (undef); + my $eol = $csv->eol; + +The end-of-line string to add to rows for L or the record separator +for L. + +When not passed in a B instance, the default behavior is to accept +C<\n>, C<\r>, and C<\r\n>, so it is probably safer to not specify C at +all. Passing C or the empty string behave the same. + +When not passed in a B instance, records are not terminated at +all, so it is probably wise to pass something you expect. A safe choice for +C on output is either C<$/> or C<\r\n>. + +Common values for C are C<"\012"> (C<\n> or Line Feed), C<"\015\012"> +(C<\r\n> or Carriage Return, Line Feed), and C<"\015"> (C<\r> or Carriage +Return). The L|/eol> attribute cannot exceed 7 (ASCII) characters. + +If both C<$/> and L|/eol> equal C<"\015">, parsing lines that end on +only a Carriage Return without Line Feed, will be Ld correct. + +=head3 sep_char + + my $csv = Text::CSV_PP->new ({ sep_char => ";" }); + $csv->sep_char (";"); + my $c = $csv->sep_char; + +The char used to separate fields, by default a comma. (C<,>). Limited to a +single-byte character, usually in the range from C<0x20> (space) to C<0x7E> +(tilde). When longer sequences are required, use L|/sep>. + +The separation character can not be equal to the quote character or to the +escape character. + +=head3 sep + + my $csv = Text::CSV_PP->new ({ sep => "\N{FULLWIDTH COMMA}" }); + $csv->sep (";"); + my $sep = $csv->sep; + +The chars used to separate fields, by default undefined. Limited to 8 bytes. + +When set, overrules L|/sep_char>. If its length is one byte it +acts as an alias to L|/sep_char>. + +=head3 quote_char + + my $csv = Text::CSV_PP->new ({ quote_char => "'" }); + $csv->quote_char (undef); + my $c = $csv->quote_char; + +The character to quote fields containing blanks or binary data, by default +the double quote character (C<">). A value of undef suppresses quote chars +(for simple cases only). Limited to a single-byte character, usually in the +range from C<0x20> (space) to C<0x7E> (tilde). When longer sequences are +required, use L|/quote>. + +C can not be equal to L|/sep_char>. + +=head3 quote + + my $csv = Text::CSV_PP->new ({ quote => "\N{FULLWIDTH QUOTATION MARK}" }); + $csv->quote ("'"); + my $quote = $csv->quote; + +The chars used to quote fields, by default undefined. Limited to 8 bytes. + +When set, overrules L|/quote_char>. If its length is one byte +it acts as an alias to L|/quote_char>. + +=head3 escape_char + + my $csv = Text::CSV_PP->new ({ escape_char => "\\" }); + $csv->escape_char (undef); + my $c = $csv->escape_char; + +The character to escape certain characters inside quoted fields. This is +limited to a single-byte character, usually in the range from C<0x20> +(space) to C<0x7E> (tilde). + +The C defaults to being the double-quote mark (C<">). In other +words the same as the default L|/quote_char>. This means that +doubling the quote mark in a field escapes it: + + "foo","bar","Escape ""quote mark"" with two ""quote marks""","baz" + +If you change the L|/quote_char> without changing the +C, the C will still be the double-quote (C<">). +If instead you want to escape the L|/quote_char> by doubling +it you will need to also change the C to be the same as what +you have changed the L|/quote_char> to. + +The escape character can not be equal to the separation character. + +=head3 binary + + my $csv = Text::CSV_PP->new ({ binary => 1 }); + $csv->binary (0); + my $f = $csv->binary; + +If this attribute is C<1>, you may use binary characters in quoted fields, +including line feeds, carriage returns and C bytes. (The latter could +be escaped as C<"0>.) By default this feature is off. + +If a string is marked UTF8, C will be turned on automatically when +binary characters other than C and C are encountered. Note that a +simple string like C<"\x{00a0}"> might still be binary, but not marked UTF8, +so setting C<< { binary => 1 } >> is still a wise option. + +=head3 strict + + my $csv = Text::CSV_PP->new ({ strict => 1 }); + $csv->strict (0); + my $f = $csv->strict; + +If this attribute is set to C<1>, any row that parses to a different number +of fields than the previous row will cause the parser to throw error 2014. + +=head3 decode_utf8 + + my $csv = Text::CSV_PP->new ({ decode_utf8 => 1 }); + $csv->decode_utf8 (0); + my $f = $csv->decode_utf8; + +This attributes defaults to TRUE. + +While I, fields that are valid UTF-8, are automatically set to be +UTF-8, so that + + $csv->parse ("\xC4\xA8\n"); + +results in + + PV("\304\250"\0) [UTF8 "\x{128}"] + +Sometimes it might not be a desired action. To prevent those upgrades, set +this attribute to false, and the result will be + + PV("\304\250"\0) + +=head3 auto_diag + + my $csv = Text::CSV_PP->new ({ auto_diag => 1 }); + $csv->auto_diag (2); + my $l = $csv->auto_diag; + +Set this attribute to a number between C<1> and C<9> causes L +to be automatically called in void context upon errors. + +In case of error C<2012 - EOF>, this call will be void. + +If C is set to a numeric value greater than C<1>, it will C +on errors instead of C. If set to anything unrecognized, it will be +silently ignored. + +Future extensions to this feature will include more reliable auto-detection +of C being active in the scope of which the error occurred which +will increment the value of C with C<1> the moment the error is +detected. + +=head3 diag_verbose + + my $csv = Text::CSV_PP->new ({ diag_verbose => 1 }); + $csv->diag_verbose (2); + my $l = $csv->diag_verbose; + +Set the verbosity of the output triggered by C. Currently only +adds the current input-record-number (if known) to the diagnostic output +with an indication of the position of the error. + +=head3 blank_is_undef + + my $csv = Text::CSV_PP->new ({ blank_is_undef => 1 }); + $csv->blank_is_undef (0); + my $f = $csv->blank_is_undef; + +Under normal circumstances, C data makes no distinction between quoted- +and unquoted empty fields. These both end up in an empty string field once +read, thus + + 1,"",," ",2 + +is read as + + ("1", "", "", " ", "2") + +When I C files with either L|/always_quote> +or L|/quote_empty> set, the unquoted I field is the +result of an undefined value. To enable this distinction when I +C data, the C attribute will cause unquoted empty +fields to be set to C, causing the above to be parsed as + + ("1", "", undef, " ", "2") + +note that this is specifically important when loading C fields into a +database that allows C values, as the perl equivalent for C is +C in L land. + +=head3 empty_is_undef + + my $csv = Text::CSV_PP->new ({ empty_is_undef => 1 }); + $csv->empty_is_undef (0); + my $f = $csv->empty_is_undef; + +Going one step further than L|/blank_is_undef>, this +attribute converts all empty fields to C, so + + 1,"",," ",2 + +is read as + + (1, undef, undef, " ", 2) + +Note that this effects only fields that are originally empty, not fields +that are empty after stripping allowed whitespace. YMMV. + +=head3 allow_whitespace + + my $csv = Text::CSV_PP->new ({ allow_whitespace => 1 }); + $csv->allow_whitespace (0); + my $f = $csv->allow_whitespace; + +When this option is set to true, the whitespace (C's and C's) +surrounding the separation character is removed when parsing. If either +C or C is one of the three characters L|/sep_char>, +L|/quote_char>, or L|/escape_char> it will not +be considered whitespace. + +Now lines like: + + 1 , "foo" , bar , 3 , zapp + +are parsed as valid C, even though it violates the C specs. + +Note that B whitespace is stripped from both start and end of each +field. That would make it I than a I to enable parsing bad +C lines, as + + 1, 2.0, 3, ape , monkey + +will now be parsed as + + ("1", "2.0", "3", "ape", "monkey") + +even if the original line was perfectly acceptable C. + +=head3 allow_loose_quotes + + my $csv = Text::CSV_PP->new ({ allow_loose_quotes => 1 }); + $csv->allow_loose_quotes (0); + my $f = $csv->allow_loose_quotes; + +By default, parsing unquoted fields containing L|/quote_char> +characters like + + 1,foo "bar" baz,42 + +would result in parse error 2034. Though it is still bad practice to allow +this format, we cannot help the fact that some vendors make their +applications spit out lines styled this way. + +If there is B bad C data, like + + 1,"foo "bar" baz",42 + +or + + 1,""foo bar baz"",42 + +there is a way to get this data-line parsed and leave the quotes inside the +quoted field as-is. This can be achieved by setting C +B making sure that the L|/escape_char> is I equal +to L|/quote_char>. + +=head3 allow_loose_escapes + + my $csv = Text::CSV_PP->new ({ allow_loose_escapes => 1 }); + $csv->allow_loose_escapes (0); + my $f = $csv->allow_loose_escapes; + +Parsing fields that have L|/escape_char> characters that +escape characters that do not need to be escaped, like: + + my $csv = Text::CSV_PP->new ({ escape_char => "\\" }); + $csv->parse (qq{1,"my bar\'s",baz,42}); + +would result in parse error 2025. Though it is bad practice to allow this +format, this attribute enables you to treat all escape character sequences +equal. + +=head3 allow_unquoted_escape + + my $csv = Text::CSV_PP->new ({ allow_unquoted_escape => 1 }); + $csv->allow_unquoted_escape (0); + my $f = $csv->allow_unquoted_escape; + +A backward compatibility issue where L|/escape_char> differs +from L|/quote_char> prevents L|/escape_char> +to be in the first position of a field. If L|/quote_char> is +equal to the default C<"> and L|/escape_char> is set to C<\>, +this would be illegal: + + 1,\0,2 + +Setting this attribute to C<1> might help to overcome issues with backward +compatibility and allow this style. + +=head3 always_quote + + my $csv = Text::CSV_PP->new ({ always_quote => 1 }); + $csv->always_quote (0); + my $f = $csv->always_quote; + +By default the generated fields are quoted only if they I to be. For +example, if they contain the separator character. If you set this attribute +to C<1> then I defined fields will be quoted. (C fields are not +quoted, see L). This makes it quite often easier to handle +exported data in external applications. + +=head3 quote_space + + my $csv = Text::CSV_PP->new ({ quote_space => 1 }); + $csv->quote_space (0); + my $f = $csv->quote_space; + +By default, a space in a field would trigger quotation. As no rule exists +this to be forced in C, nor any for the opposite, the default is true +for safety. You can exclude the space from this trigger by setting this +attribute to 0. + +=head3 quote_empty + + my $csv = Text::CSV_PP->new ({ quote_empty => 1 }); + $csv->quote_empty (0); + my $f = $csv->quote_empty; + +By default the generated fields are quoted only if they I to be. An +empty (defined) field does not need quotation. If you set this attribute to +C<1> then I defined fields will be quoted. (C fields are not +quoted, see L). See also L|/always_quote>. + +=head3 quote_binary + + my $csv = Text::CSV_PP->new ({ quote_binary => 1 }); + $csv->quote_binary (0); + my $f = $csv->quote_binary; + +By default, all "unsafe" bytes inside a string cause the combined field to +be quoted. By setting this attribute to C<0>, you can disable that trigger +for bytes >= C<0x7F>. + +=head3 escape_null or quote_null (deprecated) + + my $csv = Text::CSV_PP->new ({ escape_null => 1 }); + $csv->escape_null (0); + my $f = $csv->escape_null; + +By default, a C byte in a field would be escaped. This option enables +you to treat the C byte as a simple binary character in binary mode +(the C<< { binary => 1 } >> is set). The default is true. You can prevent +C escapes by setting this attribute to C<0>. + +The default when using the C function is C. + +=head3 keep_meta_info + + my $csv = Text::CSV_PP->new ({ keep_meta_info => 1 }); + $csv->keep_meta_info (0); + my $f = $csv->keep_meta_info; + +By default, the parsing of input records is as simple and fast as possible. +However, some parsing information - like quotation of the original field - +is lost in that process. Setting this flag to true enables retrieving that +information after parsing with the methods L, L, +and L described below. Default is false for performance. + +If you set this attribute to a value greater than 9, than you can control +output quotation style like it was used in the input of the the last parsed +record (unless quotation was added because of other reasons). + + my $csv = Text::CSV_PP->new ({ + binary => 1, + keep_meta_info => 1, + quote_space => 0, + }); + + my $row = $csv->parse (q{1,,"", ," ",f,"g","h""h",help,"help"}); + + $csv->print (*STDOUT, \@row); + # 1,,, , ,f,g,"h""h",help,help + $csv->keep_meta_info (11); + $csv->print (*STDOUT, \@row); + # 1,,"", ," ",f,"g","h""h",help,"help" + +=head3 verbatim + + my $csv = Text::CSV_PP->new ({ verbatim => 1 }); + $csv->verbatim (0); + my $f = $csv->verbatim; + +This is a quite controversial attribute to set, but makes some hard things +possible. + +The rationale behind this attribute is to tell the parser that the normally +special characters newline (C) and Carriage Return (C) will not be +special when this flag is set, and be dealt with as being ordinary binary +characters. This will ease working with data with embedded newlines. + +When C is used with L, L auto-C's +every line. + +Imagine a file format like + + M^^Hans^Janssen^Klas 2\n2A^Ja^11-06-2007#\r\n + +where, the line ending is a very specific C<"#\r\n">, and the sep_char is a +C<^> (caret). None of the fields is quoted, but embedded binary data is +likely to be present. With the specific line ending, this should not be too +hard to detect. + +By default, Text::CSV_PP' parse function is instructed to only know about +C<"\n"> and C<"\r"> to be legal line endings, and so has to deal with the +embedded newline as a real C, so it can scan the next line if +binary is true, and the newline is inside a quoted field. With this option, +we tell L to parse the line as if C<"\n"> is just nothing more than +a binary character. + +For L this means that the parser has no more idea about line ending +and L Cs line endings on reading. + +=head3 types + +A set of column types; the attribute is immediately passed to the L +method. + +=head3 callbacks + +See the L section below. + +=head3 accessors + +To sum it up, + + $csv = Text::CSV_PP->new (); + +is equivalent to + + $csv = Text::CSV_PP->new ({ + eol => undef, # \r, \n, or \r\n + sep_char => ',', + sep => undef, + quote_char => '"', + quote => undef, + escape_char => '"', + binary => 0, + decode_utf8 => 1, + auto_diag => 0, + diag_verbose => 0, + blank_is_undef => 0, + empty_is_undef => 0, + allow_whitespace => 0, + allow_loose_quotes => 0, + allow_loose_escapes => 0, + allow_unquoted_escape => 0, + always_quote => 0, + quote_empty => 0, + quote_space => 1, + escape_null => 1, + quote_binary => 1, + keep_meta_info => 0, + verbatim => 0, + types => undef, + callbacks => undef, + }); + +For all of the above mentioned flags, an accessor method is available where +you can inquire the current value, or change the value + + my $quote = $csv->quote_char; + $csv->binary (1); + +It is not wise to change these settings halfway through writing C data +to a stream. If however you want to create a new stream using the available +C object, there is no harm in changing them. + +If the L constructor call fails, it returns C, and makes the +fail reason available through the L method. + + $csv = Text::CSV_PP->new ({ ecs_char => 1 }) or + die "".Text::CSV_PP->error_diag (); + +L will return a string like + + "INI - Unknown attribute 'ecs_char'" + +=head2 known_attributes + + @attr = Text::CSV_PP->known_attributes; + @attr = Text::CSV_PP::known_attributes; + @attr = $csv->known_attributes; + +This method will return an ordered list of all the supported attributes as +described above. This can be useful for knowing what attributes are valid +in classes that use or extend Text::CSV_PP. + +=head2 print + + $status = $csv->print ($io, $colref); + +Similar to L + L
+ L, but much more efficient. +It expects an array ref as input (not an array!) and the resulting string +is not really created, but immediately written to the C<$io> object, +typically an IO handle or any other object that offers a L method. + +For performance reasons C does not create a result string, so all +L
, L, L, and L methods will return +undefined information after executing this method. + +If C<$colref> is C (explicit, not through a variable argument) and +L was used to specify fields to be printed, it is possible +to make performance improvements, as otherwise data would have to be copied +as arguments to the method call: + + $csv->bind_columns (\($foo, $bar)); + $status = $csv->print ($fh, undef); + +=head2 say + + $status = $csv->say ($io, $colref); + +Like L|/print>, but L|/eol> defaults to C<$\>. + +=head2 print_hr + + $csv->print_hr ($io, $ref); + +Provides an easy way to print a C<$ref> (as fetched with L) +provided the column names are set with L. + +It is just a wrapper method with basic parameter checks over + + $csv->print ($io, [ map { $ref->{$_} } $csv->column_names ]); + +=head2 combine + + $status = $csv->combine (@fields); + +This method constructs a C record from C<@fields>, returning success +or failure. Failure can result from lack of arguments or an argument that +contains an invalid character. Upon success, L
can be called to +retrieve the resultant C string. Upon failure, the value returned by +L
is undefined and L could be called to retrieve the +invalid argument. + +=head2 string + + $line = $csv->string (); + +This method returns the input to L or the resultant C string +of L, whichever was called more recently. + +=head2 getline + + $colref = $csv->getline ($io); + +This is the counterpart to L, as L is the counterpart to +L: it parses a row from the C<$io> handle using the L +method associated with C<$io> and parses this row into an array ref. This +array ref is returned by the function or C for failure. When C<$io> +does not support C, you are likely to hit errors. + +When fields are bound with L the return value is a reference +to an empty list. + +The L
, L, and L methods are meaningless again. + +=head2 getline_all + + $arrayref = $csv->getline_all ($io); + $arrayref = $csv->getline_all ($io, $offset); + $arrayref = $csv->getline_all ($io, $offset, $length); + +This will return a reference to a list of L results. +In this call, C is disabled. If C<$offset> is negative, as +with C, only the last C records of C<$io> are taken +into consideration. + +Given a CSV file with 10 lines: + + lines call + ----- --------------------------------------------------------- + 0..9 $csv->getline_all ($io) # all + 0..9 $csv->getline_all ($io, 0) # all + 8..9 $csv->getline_all ($io, 8) # start at 8 + - $csv->getline_all ($io, 0, 0) # start at 0 first 0 rows + 0..4 $csv->getline_all ($io, 0, 5) # start at 0 first 5 rows + 4..5 $csv->getline_all ($io, 4, 2) # start at 4 first 2 rows + 8..9 $csv->getline_all ($io, -2) # last 2 rows + 6..7 $csv->getline_all ($io, -4, 2) # first 2 of last 4 rows + +=head2 getline_hr + +The L and L methods work together to allow you +to have rows returned as hashrefs. You must call L first to +declare your column names. + + $csv->column_names (qw( code name price description )); + $hr = $csv->getline_hr ($io); + print "Price for $hr->{name} is $hr->{price} EUR\n"; + +L will croak if called before L. + +Note that L creates a hashref for every row and will be much +slower than the combined use of L and L but still +offering the same ease of use hashref inside the loop: + + my @cols = @{$csv->getline ($io)}; + $csv->column_names (@cols); + while (my $row = $csv->getline_hr ($io)) { + print $row->{price}; + } + +Could easily be rewritten to the much faster: + + my @cols = @{$csv->getline ($io)}; + my $row = {}; + $csv->bind_columns (\@{$row}{@cols}); + while ($csv->getline ($io)) { + print $row->{price}; + } + +Your mileage may vary for the size of the data and the number of rows. + +=head2 getline_hr_all + + $arrayref = $csv->getline_hr_all ($io); + $arrayref = $csv->getline_hr_all ($io, $offset); + $arrayref = $csv->getline_hr_all ($io, $offset, $length); + +This will return a reference to a list of L +results. In this call, L|/keep_meta_info> is disabled. + +=head2 parse + + $status = $csv->parse ($line); + +This method decomposes a C string into fields, returning success or +failure. Failure can result from a lack of argument or the given C +string is improperly formatted. Upon success, L can be called to +retrieve the decomposed fields. Upon failure calling L will return +undefined data and L can be called to retrieve the invalid +argument. + +You may use the L method for setting column types. See L' +description below. + +The C<$line> argument is supposed to be a simple scalar. Everything else is +supposed to croak and set error 1500. + +=head2 fragment + +This function tries to implement RFC7111 (URI Fragment Identifiers for the +text/csv Media Type) - http://tools.ietf.org/html/rfc7111 + + my $AoA = $csv->fragment ($io, $spec); + +In specifications, C<*> is used to specify the I item, a dash (C<->) +to indicate a range. All indices are C<1>-based: the first row or column +has index C<1>. Selections can be combined with the semi-colon (C<;>). + +When using this method in combination with L, the returned +reference will point to a list of hashes instead of a list of lists. A +disjointed cell-based combined selection might return rows with different +number of columns making the use of hashes unpredictable. + + $csv->column_names ("Name", "Age"); + my $AoH = $csv->fragment ($io, "col=3;8"); + +If the L callback is active, it is also called on every line +parsed and skipped before the fragment. + +=over 2 + +=item row + + row=4 + row=5-7 + row=6-* + row=1-2;4;6-* + +=item col + + col=2 + col=1-3 + col=4-* + col=1-2;4;7-* + +=item cell + +In cell-based selection, the comma (C<,>) is used to pair row and column + + cell=4,1 + +The range operator (C<->) using Cs can be used to define top-left and +bottom-right C location + + cell=3,1-4,6 + +The C<*> is only allowed in the second part of a pair + + cell=3,2-*,2 # row 3 till end, only column 2 + cell=3,2-3,* # column 2 till end, only row 3 + cell=3,2-*,* # strip row 1 and 2, and column 1 + +Cells and cell ranges may be combined with C<;>, possibly resulting in rows +with different number of columns + + cell=1,1-2,2;3,3-4,4;1,4;4,1 + +Disjointed selections will only return selected cells. The cells that are +not specified will not be included in the returned set, not even as +C. As an example given a C like + + 11,12,13,...19 + 21,22,...28,29 + : : + 91,...97,98,99 + +with C will return: + + 11,12,14 + 21,22 + 33,34 + 41,43,44 + +Overlapping cell-specs will return those cells only once, So +C will return: + + 11,12,13 + 21,22,23,24 + 31,32,33,34 + 42,43,44 + +=back + +L does B allow different +types of specs to be combined (either C I C I C). +Passing an invalid fragment specification will croak and set error 2013. + +=head2 column_names + +Set the "keys" that will be used in the L calls. If no keys +(column names) are passed, it will return the current setting as a list. + +L accepts a list of scalars (the column names) or a single +array_ref, so you can pass the return value from L too: + + $csv->column_names ($csv->getline ($io)); + +L does B checking on duplicates at all, which might lead +to unexpected results. Undefined entries will be replaced with the string +C<"\cAUNDEF\cA">, so + + $csv->column_names (undef, "", "name", "name"); + $hr = $csv->getline_hr ($io); + +Will set C<< $hr->{"\cAUNDEF\cA"} >> to the 1st field, C<< $hr->{""} >> to +the 2nd field, and C<< $hr->{name} >> to the 4th field, discarding the 3rd +field. + +L croaks on invalid arguments. + +=head2 header + +This method does NOT work in perl-5.6.x + +Parse the CSV header and set L|/sep>, column_names and encoding. + + my @hdr = $csv->header ($fh); + $csv->header ($fh, { sep_set => [ ";", ",", "|", "\t" ] }); + $csv->header ($fh, { detect_bom => 1, munge_column_names => "lc" }); + +The first argument should be a file handle. + +Assuming that the file opened for parsing has a header, and the header does +not contain problematic characters like embedded newlines, read the first +line from the open handle then auto-detect whether the header separates the +column names with a character from the allowed separator list. + +If any of the allowed separators matches, and none of the I allowed +separators match, set L|/sep> to that separator for the current +CSV_PP instance and use it to parse the first line, map those to lowercase, +and use that to set the instance L: + + my $csv = Text::CSV_PP->new ({ binary => 1, auto_diag => 1 }); + open my $fh, "<", "file.csv"; + binmode $fh; # for Windows + $csv->header ($fh); + while (my $row = $csv->getline_hr ($fh)) { + ... + } + +If the header is empty, contains more than one unique separator out of the +allowed set, contains empty fields, or contains identical fields (after +folding), it will croak with error 1010, 1011, 1012, or 1013 respectively. + +If the header contains embedded newlines or is not valid CSV in any other +way, this method will croak and leave the parse error untouched. + +A successful call to C
will always set the L|/sep> of the +C<$csv> object. This behavior can not be disabled. + +=head3 return value + +On error this method will croak. + +In list context, the headers will be returned whether they are used to set +L or not. + +In scalar context, the instance itself is returned. B: the values as +found in the header will effectively be B if C is +false. + +=head3 Options + +=over 2 + +=item sep_set + + $csv->header ($fh, { sep_set => [ ";", ",", "|", "\t" ] }); + +The list of legal separators defaults to C<[ ";", "," ]> and can be changed +by this option. As this is probably the most often used option, it can be +passed on its own as an unnamed argument: + + $csv->header ($fh, [ ";", ",", "|", "\t", "::", "\x{2063}" ]); + +Multi-byte sequences are allowed, both multi-character and Unicode. See +L|/sep>. + +=item detect_bom + + $csv->header ($fh, { detect_bom => 1 }); + +The default behavior is to detect if the header line starts with a BOM. If +the header has a BOM, use that to set the encoding of C<$fh>. This default +behavior can be disabled by passing a false value to C. + +Supported encodings from BOM are: UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, and +UTF-32LE. BOM's also support UTF-1, UTF-EBCDIC, SCSU, BOCU-1, and GB-18030 +but L does not (yet). UTF-7 is not supported. + +The encoding is set using C on C<$fh>. + +If the handle was opened in a (correct) encoding, this method will B +alter the encoding, as it checks the leading B of the first line. + +=item munge_column_names + +This option offers the means to modify the column names into something that +is most useful to the application. The default is to map all column names +to lower case. + + $csv->header ($fh, { munge_column_names => "lc" }); + +The following values are available: + + lc - lower case + uc - upper case + none - do not change + \&cb - supply a callback + + $csv->header ($fh, { munge_column_names => sub { fc } }); + $csv->header ($fh, { munge_column_names => sub { "column_".$col++ } }); + $csv->header ($fh, { munge_column_names => sub { lc (s/\W+/_/gr) } }); + +As this callback is called in a C, you can use C<$_> directly. + +=item set_column_names + + $csv->header ($fh, { set_column_names => 1 }); + +The default is to set the instances column names using L if +the method is successful, so subsequent calls to L can return +a hash. Disable setting the header can be forced by using a false value for +this option. + +=back + +=head3 Validation + +When receiving CSV files from external sources, this method can be used to +protect against changes in the layout by restricting to known headers (and +typos in the header fields). + + my %known = ( + "record key" => "c_rec", + "rec id" => "c_rec", + "id_rec" => "c_rec", + "kode" => "code", + "code" => "code", + "vaule" => "value", + "value" => "value", + ); + my $csv = Text::CSV_PP->new ({ binary => 1, auto_diag => 1 }); + open my $fh, "<", $source or die "$source: $!"; + $csv->header ($fh, { munge_column_names => sub { + s/\s+$//; + s/^\s+//; + $known{lc $_} or die "Unknown column '$_' in $source"; + }}); + while (my $row = $csv->getline_hr ($fh)) { + say join "\t", $row->{c_rec}, $row->{code}, $row->{value}; + } + +=head2 bind_columns + +Takes a list of scalar references to be used for output with L or +to store in the fields fetched by L. When you do not pass enough +references to store the fetched fields in, L will fail with error +C<3006>. If you pass more than there are fields to return, the content of +the remaining references is left untouched. + + $csv->bind_columns (\$code, \$name, \$price, \$description); + while ($csv->getline ($io)) { + print "The price of a $name is \x{20ac} $price\n"; + } + +To reset or clear all column binding, call L with the single +argument C. This will also clear column names. + + $csv->bind_columns (undef); + +If no arguments are passed at all, L will return the list of +current bindings or C if no binds are active. + +Note that in parsing with C, the fields are set on the fly. +That implies that if the third field of a row causes an error, the first +two fields already have been assigned the values of the current row, while +the rest of the fields will still hold the values of the previous row. +If you want the parser to fail in these cases, use the L|/strict> attribute. + +=head2 eof + + $eof = $csv->eof (); + +If L or L was used with an IO stream, this method will +return true (1) if the last call hit end of file, otherwise it will return +false (''). This is useful to see the difference between a failure and end +of file. + +Note that if the parsing of the last line caused an error, C is still +true. That means that if you are I using L, an idiom like + + while (my $row = $csv->getline ($fh)) { + # ... + } + $csv->eof or $csv->error_diag; + +will I report the error. You would have to change that to + + while (my $row = $csv->getline ($fh)) { + # ... + } + +$csv->error_diag and $csv->error_diag; + +=head2 types + + $csv->types (\@tref); + +This method is used to force that (all) columns are of a given type. For +example, if you have an integer column, two columns with doubles and a +string column, then you might do a + + $csv->types ([Text::CSV_PP::IV (), + Text::CSV_PP::NV (), + Text::CSV_PP::NV (), + Text::CSV_PP::PV ()]); + +Column types are used only for I columns while parsing, in other +words by the L and L methods. + +You can unset column types by doing a + + $csv->types (undef); + +or fetch the current type settings with + + $types = $csv->types (); + +=over 4 + +=item IV + +Set field type to integer. + +=item NV + +Set field type to numeric/float. + +=item PV + +Set field type to string. + +=back + +=head2 fields + + @columns = $csv->fields (); + +This method returns the input to L or the resultant decomposed +fields of a successful L, whichever was called more recently. + +Note that the return value is undefined after using L, which does +not fill the data structures returned by L. + +=head2 meta_info + + @flags = $csv->meta_info (); + +This method returns the "flags" of the input to L or the flags of +the resultant decomposed fields of L, whichever was called more +recently. + +For each field, a meta_info field will hold flags that inform something +about the field returned by the L method or passed to the +L method. The flags are bit-wise-C'd like: + +=over 2 + +=item C< >0x0001 + +The field was quoted. + +=item C< >0x0002 + +The field was binary. + +=back + +See the C methods below. + +=head2 is_quoted + + my $quoted = $csv->is_quoted ($column_idx); + +Where C<$column_idx> is the (zero-based) index of the column in the last +result of L. + +This returns a true value if the data in the indicated column was enclosed +in L|/quote_char> quotes. This might be important for fields +where content C<,20070108,> is to be treated as a numeric value, and where +C<,"20070108",> is explicitly marked as character string data. + +This method is only valid when L is set to a true value. + +=head2 is_binary + + my $binary = $csv->is_binary ($column_idx); + +Where C<$column_idx> is the (zero-based) index of the column in the last +result of L. + +This returns a true value if the data in the indicated column contained any +byte in the range C<[\x00-\x08,\x10-\x1F,\x7F-\xFF]>. + +This method is only valid when L is set to a true value. + +=head2 is_missing + + my $missing = $csv->is_missing ($column_idx); + +Where C<$column_idx> is the (zero-based) index of the column in the last +result of L. + + $csv->keep_meta_info (1); + while (my $hr = $csv->getline_hr ($fh)) { + $csv->is_missing (0) and next; # This was an empty line + } + +When using L, it is impossible to tell if the parsed fields +are C because they where not filled in the C stream or because +they were not read at all, as B the fields defined by L +are set in the hash-ref. If you still need to know if all fields in each +row are provided, you should enable L|/keep_meta_info> so +you can check the flags. + +If L|/keep_meta_info> is C, C will +always return C, regardless of C<$column_idx> being valid or not. If +this attribute is C it will return either C<0> (the field is present) +or C<1> (the field is missing). + +A special case is the empty line. If the line is completely empty - after +dealing with the flags - this is still a valid CSV line: it is a record of +just one single empty field. However, if C is set, invoking +C with index C<0> will now return true. + +=head2 status + + $status = $csv->status (); + +This method returns the status of the last invoked L or L +call. Status is success (true: C<1>) or failure (false: C or C<0>). + +=head2 error_input + + $bad_argument = $csv->error_input (); + +This method returns the erroneous argument (if it exists) of L or +L, whichever was called more recently. If the last invocation was +successful, C will return C. + +=head2 error_diag + + Text::CSV_PP->error_diag (); + $csv->error_diag (); + $error_code = 0 + $csv->error_diag (); + $error_str = "" . $csv->error_diag (); + ($cde, $str, $pos, $rec, $fld) = $csv->error_diag (); + +If (and only if) an error occurred, this function returns the diagnostics +of that error. + +If called in void context, this will print the internal error code and the +associated error message to STDERR. + +If called in list context, this will return the error code and the error +message in that order. If the last error was from parsing, the rest of the +values returned are a best guess at the location within the line that was +being parsed. Their values are 1-based. The position currently is index of +the byte at which the parsing failed in the current record. It might change +to be the index of the current character in a later release. The records is +the index of the record parsed by the csv instance. The field number is the +index of the field the parser thinks it is currently trying to parse. See +F for how this can be used. + +If called in scalar context, it will return the diagnostics in a single +scalar, a-la C<$!>. It will contain the error code in numeric context, and +the diagnostics message in string context. + +When called as a class method or a direct function call, the diagnostics +are that of the last L call. + +=head2 record_number + + $recno = $csv->record_number (); + +Returns the records parsed by this csv instance. This value should be more +accurate than C<$.> when embedded newlines come in play. Records written by +this instance are not counted. + +=head2 SetDiag + + $csv->SetDiag (0); + +Use to reset the diagnostics if you are dealing with errors. + +=head1 FUNCTIONS + +This whole section is also taken from Text::CSV_XS. + +=head2 csv + +This function is not exported by default and should be explicitly requested: + + use Text::CSV_PP qw( csv ); + +This is an high-level function that aims at simple (user) interfaces. This +can be used to read/parse a C file or stream (the default behavior) or +to produce a file or write to a stream (define the C attribute). It +returns an array- or hash-reference on parsing (or C on fail) or the +numeric value of L on writing. When this function fails you +can get to the error using the class call to L + + my $aoa = csv (in => "test.csv") or + die Text::CSV_PP->error_diag; + +This function takes the arguments as key-value pairs. This can be passed as +a list or as an anonymous hash: + + my $aoa = csv ( in => "test.csv", sep_char => ";"); + my $aoh = csv ({ in => $fh, headers => "auto" }); + +The arguments passed consist of two parts: the arguments to L itself +and the optional attributes to the C object used inside the function +as enumerated and explained in L. + +If not overridden, the default option used for CSV is + + auto_diag => 1 + escape_null => 0 + +The option that is always set and cannot be altered is + + binary => 1 + +As this function will likely be used in one-liners, it allows C to +be abbreviated as C, and C to be abbreviated as C +or C. + +Alternative invocations: + + my $aoa = Text::CSV_PP::csv (in => "file.csv"); + + my $csv = Text::CSV_PP->new (); + my $aoa = $csv->csv (in => "file.csv"); + +In the latter case, the object attributes are used from the existing object +and the attribute arguments in the function call are ignored: + + my $csv = Text::CSV_PP->new ({ sep_char => ";" }); + my $aoh = $csv->csv (in => "file.csv", bom => 1); + +will parse using C<;> as C, not C<,>. + +=head3 in + +Used to specify the source. C can be a file name (e.g. C<"file.csv">), +which will be opened for reading and closed when finished, a file handle +(e.g. C<$fh> or C), a reference to a glob (e.g. C<\*ARGV>), the glob +itself (e.g. C<*STDIN>), or a reference to a scalar (e.g. C<\q{1,2,"csv"}>). + +When used with L, C should be a reference to a CSV structure (AoA +or AoH) or a CODE-ref that returns an array-reference or a hash-reference. +The code-ref will be invoked with no arguments. + + my $aoa = csv (in => "file.csv"); + + open my $fh, "<", "file.csv"; + my $aoa = csv (in => $fh); + + my $csv = [ [qw( Foo Bar )], [ 1, 2 ], [ 2, 3 ]]; + my $err = csv (in => $csv, out => "file.csv"); + +If called in void context without the L attribute, the resulting ref +will be used as input to a subsequent call to csv: + + csv (in => "file.csv", filter => { 2 => sub { length > 2 }}) + +will be a shortcut to + + csv (in => csv (in => "file.csv", filter => { 2 => sub { length > 2 }})) + +where, in the absence of the C attribute, this is a shortcut to + + csv (in => csv (in => "file.csv", filter => { 2 => sub { length > 2 }}), + out => *STDOUT) + +=head3 out + +In output mode, the default CSV options when producing CSV are + + eol => "\r\n" + +The L attribute is ignored in output mode. + +C can be a file name (e.g. C<"file.csv">), which will be opened for +writing and closed when finished, a file handle (e.g. C<$fh> or C), a +reference to a glob (e.g. C<\*STDOUT>), or the glob itself (e.g. C<*STDOUT>). + + csv (in => sub { $sth->fetch }, out => "dump.csv"); + csv (in => sub { $sth->fetchrow_hashref }, out => "dump.csv", + headers => $sth->{NAME_lc}); + +When a code-ref is used for C, the output is generated per invocation, +so no buffering is involved. This implies that there is no size restriction +on the number of records. The C function ends when the coderef returns +a false value. + +=head3 encoding + +If passed, it should be an encoding accepted by the C<:encoding()> option +to C. There is no default value. This attribute does not work in perl +5.6.x. C can be abbreviated to C for ease of use in command +line invocations. + +If C is set to the literal value C<"auto">, the method L
+will be invoked on the opened stream to check if there is a BOM and set the +encoding accordingly. This is equal to passing a true value in the option +L|/detect_bom>. + +=head3 detect_bom + +If C is given, the method L will be invoked on the +opened stream to check if there is a BOM and set the encoding accordingly. + +C can be abbreviated to C. + +This is the same as setting L|/encoding> to C<"auto">. + +Note that as L is invoked, its default is to also set the headers. + +=head3 headers + +If this attribute is not given, the default behavior is to produce an array +of arrays. + +If C is supplied, it should be an anonymous list of column names, +an anonymous hashref, a coderef, or a literal flag: C, C, C, +or C. + +=over 2 + +=item skip + +When C is used, the header will not be included in the output. + + my $aoa = csv (in => $fh, headers => "skip"); + +=item auto + +If C is used, the first line of the C source will be read as the +list of field headers and used to produce an array of hashes. + + my $aoh = csv (in => $fh, headers => "auto"); + +=item lc + +If C is used, the first line of the C source will be read as the +list of field headers mapped to lower case and used to produce an array of +hashes. This is a variation of C. + + my $aoh = csv (in => $fh, headers => "lc"); + +=item uc + +If C is used, the first line of the C source will be read as the +list of field headers mapped to upper case and used to produce an array of +hashes. This is a variation of C. + + my $aoh = csv (in => $fh, headers => "uc"); + +=item CODE + +If a coderef is used, the first line of the C source will be read as +the list of mangled field headers in which each field is passed as the only +argument to the coderef. This list is used to produce an array of hashes. + + my $aoh = csv (in => $fh, + headers => sub { lc ($_[0]) =~ s/kode/code/gr }); + +this example is a variation of using C where all occurrences of C +are replaced with C. + +=item ARRAY + +If C is an anonymous list, the entries in the list will be used +as field names. The first line is considered data instead of headers. + + my $aoh = csv (in => $fh, headers => [qw( Foo Bar )]); + csv (in => $aoa, out => $fh, headers => [qw( code description price )]); + +=item HASH + +If C is an hash reference, this implies C, but header fields +for that exist as key in the hashref will be replaced by the value for that +key. Given a CSV file like + + post-kode,city,name,id number,fubble + 1234AA,Duckstad,Donald,13,"X313DF" + +using + + csv (headers => { "post-kode" => "pc", "id number" => "ID" }, ... + +will return an entry like + + { pc => "1234AA", + city => "Duckstad", + name => "Donald", + ID => "13", + fubble => "X313DF", + } + +=back + +See also L|/munge_column_names> and +L|/set_column_names>. + +=head3 munge_column_names + +If C is set, the method L is invoked on the +opened stream with all matching arguments to detect and set the headers. + +C can be abbreviated to C. + +=head3 key + +If passed, will default L|/headers> to C<"auto"> and return a +hashref instead of an array of hashes. + + my $ref = csv (in => "test.csv", key => "code"); + +with test.csv like + + code,product,price,color + 1,pc,850,gray + 2,keyboard,12,white + 3,mouse,5,black + +will return + + { 1 => { + code => 1, + color => 'gray', + price => 850, + product => 'pc' + }, + 2 => { + code => 2, + color => 'white', + price => 12, + product => 'keyboard' + }, + 3 => { + code => 3, + color => 'black', + price => 5, + product => 'mouse' + } + } + +=head3 fragment + +Only output the fragment as defined in the L method. This option +is ignored when I C. See L. + +Combining all of them could give something like + + use Text::CSV_PP qw( csv ); + my $aoh = csv ( + in => "test.txt", + encoding => "utf-8", + headers => "auto", + sep_char => "|", + fragment => "row=3;6-9;15-*", + ); + say $aoh->[15]{Foo}; + +=head3 sep_set + +If C is set, the method L is invoked on the opened stream +to detect and set L|/sep_char> with the given set. + +C can be abbreviated to C. + +Note that as L is invoked, its default is to also set the headers. + +=head3 set_column_names + +If C is passed, the method L is invoked on the +opened stream with all arguments meant for L. + +=head2 Callbacks + +Callbacks enable actions triggered from the I of Text::CSV_PP. + +While most of what this enables can easily be done in an unrolled loop as +described in the L callbacks can be used to meet special demands +or enhance the L function. + +=over 2 + +=item error + + $csv->callbacks (error => sub { $csv->SetDiag (0) }); + +the C callback is invoked when an error occurs, but I when +L is set to a true value. A callback is invoked with the values +returned by L: + + my ($c, $s); + + sub ignore3006 + { + my ($err, $msg, $pos, $recno, $fldno) = @_; + if ($err == 3006) { + # ignore this error + ($c, $s) = (undef, undef); + Text::CSV_PP->SetDiag (0); + } + # Any other error + return; + } # ignore3006 + + $csv->callbacks (error => \&ignore3006); + $csv->bind_columns (\$c, \$s); + while ($csv->getline ($fh)) { + # Error 3006 will not stop the loop + } + +=item after_parse + + $csv->callbacks (after_parse => sub { push @{$_[1]}, "NEW" }); + while (my $row = $csv->getline ($fh)) { + $row->[-1] eq "NEW"; + } + +This callback is invoked after parsing with L only if no error +occurred. The callback is invoked with two arguments: the current C +parser object and an array reference to the fields parsed. + +The return code of the callback is ignored unless it is a reference to the +string "skip", in which case the record will be skipped in L. + + sub add_from_db + { + my ($csv, $row) = @_; + $sth->execute ($row->[4]); + push @$row, $sth->fetchrow_array; + } # add_from_db + + my $aoa = csv (in => "file.csv", callbacks => { + after_parse => \&add_from_db }); + +This hook can be used for validation: + +=over 2 + +=item FAIL + +Die if any of the records does not validate a rule: + + after_parse => sub { + $_[1][4] =~ m/^[0-9]{4}\s?[A-Z]{2}$/ or + die "5th field does not have a valid Dutch zipcode"; + } + +=item DEFAULT + +Replace invalid fields with a default value: + + after_parse => sub { $_[1][2] =~ m/^\d+$/ or $_[1][2] = 0 } + +=item SKIP + +Skip records that have invalid fields (only applies to L): + + after_parse => sub { $_[1][0] =~ m/^\d+$/ or return \"skip"; } + +=back + +=item before_print + + my $idx = 1; + $csv->callbacks (before_print => sub { $_[1][0] = $idx++ }); + $csv->print (*STDOUT, [ 0, $_ ]) for @members; + +This callback is invoked before printing with L only if no error +occurred. The callback is invoked with two arguments: the current C +parser object and an array reference to the fields passed. + +The return code of the callback is ignored. + + sub max_4_fields + { + my ($csv, $row) = @_; + @$row > 4 and splice @$row, 4; + } # max_4_fields + + csv (in => csv (in => "file.csv"), out => *STDOUT, + callbacks => { before print => \&max_4_fields }); + +This callback is not active for L. + +=back + +=head3 Callbacks for csv () + +The L allows for some callbacks that do not integrate in XS internals +but only feature the L function. + + csv (in => "file.csv", + callbacks => { + filter => { 6 => sub { $_ > 15 } }, # first + after_parse => sub { say "AFTER PARSE"; }, # first + after_in => sub { say "AFTER IN"; }, # second + on_in => sub { say "ON IN"; }, # third + }, + ); + + csv (in => $aoh, + out => "file.csv", + callbacks => { + on_in => sub { say "ON IN"; }, # first + before_out => sub { say "BEFORE OUT"; }, # second + before_print => sub { say "BEFORE PRINT"; }, # third + }, + ); + +=over 2 + +=item filter + +This callback can be used to filter records. It is called just after a new +record has been scanned. The callback accepts a hashref where the keys are +the index to the row (the field number, 1-based) and the values are subs to +return a true or false value. + + csv (in => "file.csv", filter => { + 3 => sub { m/a/ }, # third field should contain an "a" + 5 => sub { length > 4 }, # length of the 5th field minimal 5 + }); + + csv (in => "file.csv", filter => "not_blank"); + csv (in => "file.csv", filter => "not_empty"); + csv (in => "file.csv", filter => "filled"); + +If the keys to the filter hash contain any character that is not a digit it +will also implicitly set L to C<"auto"> unless L was +already passed as argument. When headers are active, returning an array of +hashes, the filter is not applicable to the header itself. + + csv (in => "file.csv", filter => { foo => sub { $_ > 4 }}); + +All sub results should match, as in AND. + +The context of the callback sets C<$_> localized to the field indicated by +the filter. The two arguments are as with all other callbacks, so the other +fields in the current row can be seen: + + filter => { 3 => sub { $_ > 100 ? $_[1][1] =~ m/A/ : $_[1][6] =~ m/B/ }} + +If the context is set to return a list of hashes (L is defined), +the current record will also be available in the localized C<%_>: + + filter => { 3 => sub { $_ > 100 && $_{foo} =~ m/A/ && $_{bar} < 1000 }} + +If the filter is used to I the content by changing C<$_>, make sure +that the sub returns true in order not to have that record skipped: + + filter => { 2 => sub { $_ = uc }} + +will upper-case the second field, and then skip it if the resulting content +evaluates to false. To always accept, end with truth: + + filter => { 2 => sub { $_ = uc; 1 }} + +B + +Given a file like (line numbers prefixed for doc purpose only): + + 1:1,2,3 + 2: + 3:, + 4:"" + 5:,, + 6:, , + 7:"", + 8:" " + 9:4,5,6 + +=over 2 + +=item not_blank + +Filter out the blank lines + +This filter is a shortcut for + + filter => { 0 => sub { @{$_[1]} > 1 or + defined $_[1][0] && $_[1][0] ne "" } } + +Due to the implementation, it is currently impossible to also filter lines +that consists only of a quoted empty field. These lines are also considered +blank lines. + +With the given example, lines 2 and 4 will be skipped. + +=item not_empty + +Filter out lines where all the fields are empty. + +This filter is a shortcut for + + filter => { 0 => sub { grep { defined && $_ ne "" } @{$_[1]} } } + +A space is not regarded being empty, so given the example data, lines 2, 3, +4, 5, and 7 are skipped. + +=item filled + +Filter out lines that have no visible data + +This filter is a shortcut for + + filter => { 0 => sub { grep { defined && m/\S/ } @{$_[1]} } } + +This filter rejects all lines that I have at least one field that does +not evaluate to the empty string. + +With the given example data, this filter would skip lines 2 through 8. + +=back + +=item after_in + +This callback is invoked for each record after all records have been parsed +but before returning the reference to the caller. The hook is invoked with +two arguments: the current C parser object and a reference to the +record. The reference can be a reference to a HASH or a reference to an +ARRAY as determined by the arguments. + +This callback can also be passed as an attribute without the C +wrapper. + +=item before_out + +This callback is invoked for each record before the record is printed. The +hook is invoked with two arguments: the current C parser object and a +reference to the record. The reference can be a reference to a HASH or a +reference to an ARRAY as determined by the arguments. + +This callback can also be passed as an attribute without the C +wrapper. + +This callback makes the row available in C<%_> if the row is a hashref. In +this case C<%_> is writable and will change the original row. + +=item on_in + +This callback acts exactly as the L or the L hooks. + +This callback can also be passed as an attribute without the C +wrapper. + +This callback makes the row available in C<%_> if the row is a hashref. In +this case C<%_> is writable and will change the original row. So e.g. with + + my $aoh = csv ( + in => \"foo\n1\n2\n", + headers => "auto", + on_in => sub { $_{bar} = 2; }, + ); + +C<$aoh> will be: + + [ { foo => 1, + bar => 2, + } + { foo => 2, + bar => 2, + } + ] + +=item csv + +The I L can also be called as a method or with an existing +Text::CSV_PP object. This could help if the function is to be invoked a lot +of times and the overhead of creating the object internally over and over +again would be prevented by passing an existing instance. + + my $csv = Text::CSV_PP->new ({ binary => 1, auto_diag => 1 }); + + my $aoa = $csv->csv (in => $fh); + my $aoa = csv (in => $fh, csv => $csv); + +both act the same. Running this 20000 times on a 20 lines CSV file, showed +a 53% speedup. + +=back + +=head1 DIAGNOSTICS + +This section is also taken from Text::CSV_XS. + +If an error occurs, C<< $csv->error_diag >> can be used to get information +on the cause of the failure. Note that for speed reasons the internal value +is never cleared on success, so using the value returned by L +in normal cases - when no error occurred - may cause unexpected results. + +If the constructor failed, the cause can be found using L as a +class method, like C<< Text::CSV_PP->error_diag >>. + +The C<< $csv->error_diag >> method is automatically invoked upon error when +the contractor was called with L|/auto_diag> set to C<1> or +C<2>, or when L is in effect. When set to C<1>, this will cause a +C with the error message, when set to C<2>, it will C. C<2012 - +EOF> is excluded from L|/auto_diag> reports. + +Errors can be (individually) caught using the L callback. + +The errors as described below are available. I have tried to make the error +itself explanatory enough, but more descriptions will be added. For most of +these errors, the first three capitals describe the error category: + +=over 2 + +=item * +INI + +Initialization error or option conflict. + +=item * +ECR + +Carriage-Return related parse error. + +=item * +EOF + +End-Of-File related parse error. + +=item * +EIQ + +Parse error inside quotation. + +=item * +EIF + +Parse error inside field. + +=item * +ECB + +Combine error. + +=item * +EHR + +HashRef parse related error. + +=back + +And below should be the complete list of error codes that can be returned: + +=over 2 + +=item * +1001 "INI - sep_char is equal to quote_char or escape_char" +X<1001> + +The L cannot be equal to L or to L, as this +would invalidate all parsing rules. + +=item * +1002 "INI - allow_whitespace with escape_char or quote_char SP or TAB" +X<1002> + +Using the L|/allow_whitespace> attribute when either +L|/quote_char> or L|/escape_char> is equal to +C or C is too ambiguous to allow. + +=item * +1003 "INI - \r or \n in main attr not allowed" +X<1003> + +Using default L|/eol> characters in either L|/sep_char>, +L|/quote_char>, or L|/escape_char> is not +allowed. + +=item * +1004 "INI - callbacks should be undef or a hashref" +X<1004> + +The L|/Callbacks> attribute only allows one to be C or +a hash reference. + +=item * +1005 "INI - EOL too long" +X<1005> + +The value passed for EOL is exceeding its maximum length (16). + +=item * +1006 "INI - SEP too long" +X<1006> + +The value passed for SEP is exceeding its maximum length (16). + +=item * +1007 "INI - QUOTE too long" +X<1007> + +The value passed for QUOTE is exceeding its maximum length (16). + +=item * +1008 "INI - SEP undefined" +X<1008> + +The value passed for SEP should be defined and not empty. + +=item * +1010 "INI - the header is empty" +X<1010> + +The header line parsed in the L is empty. + +=item * +1011 "INI - the header contains more than one valid separator" +X<1011> + +The header line parsed in the L contains more than one (unique) +separator character out of the allowed set of separators. + +=item * +1012 "INI - the header contains an empty field" +X<1012> + +The header line parsed in the L is contains an empty field. + +=item * +1013 "INI - the header contains nun-unique fields" +X<1013> + +The header line parsed in the L contains at least two identical +fields. + +=item * +1014 "INI - header called on undefined stream" +X<1014> + +The header line cannot be parsed from an undefined sources. + +=item * +1500 "PRM - Invalid/unsupported argument(s)" +X<1500> + +Function or method called with invalid argument(s) or parameter(s). + +=item * +2010 "ECR - QUO char inside quotes followed by CR not part of EOL" +X<2010> + +When L|/eol> has been set to anything but the default, like +C<"\r\t\n">, and the C<"\r"> is following the B (closing) +L|/quote_char>, where the characters following the C<"\r"> do +not make up the L|/eol> sequence, this is an error. + +=item * +2011 "ECR - Characters after end of quoted field" +X<2011> + +Sequences like C<1,foo,"bar"baz,22,1> are not allowed. C<"bar"> is a quoted +field and after the closing double-quote, there should be either a new-line +sequence or a separation character. + +=item * +2012 "EOF - End of data in parsing input stream" +X<2012> + +Self-explaining. End-of-file while inside parsing a stream. Can happen only +when reading from streams with L, as using L is done on +strings that are not required to have a trailing L|/eol>. + +=item * +2013 "INI - Specification error for fragments RFC7111" +X<2013> + +Invalid specification for URI L specification. + +=item * +2014 "ENF - Inconsistent number of fields" +X<2014> + +Inconsistent number of fields under strict parsing. + +=item * +2021 "EIQ - NL char inside quotes, binary off" +X<2021> + +Sequences like C<1,"foo\nbar",22,1> are allowed only when the binary option +has been selected with the constructor. + +=item * +2022 "EIQ - CR char inside quotes, binary off" +X<2022> + +Sequences like C<1,"foo\rbar",22,1> are allowed only when the binary option +has been selected with the constructor. + +=item * +2023 "EIQ - QUO character not allowed" +X<2023> + +Sequences like C<"foo "bar" baz",qu> and C<2023,",2008-04-05,"Foo, Bar",\n> +will cause this error. + +=item * +2024 "EIQ - EOF cannot be escaped, not even inside quotes" +X<2024> + +The escape character is not allowed as last character in an input stream. + +=item * +2025 "EIQ - Loose unescaped escape" +X<2025> + +An escape character should escape only characters that need escaping. + +Allowing the escape for other characters is possible with the attribute +L. + +=item * +2026 "EIQ - Binary character inside quoted field, binary off" +X<2026> + +Binary characters are not allowed by default. Exceptions are fields that +contain valid UTF-8, that will automatically be upgraded if the content is +valid UTF-8. Set L|/binary> to C<1> to accept binary data. + +=item * +2027 "EIQ - Quoted field not terminated" +X<2027> + +When parsing a field that started with a quotation character, the field is +expected to be closed with a quotation character. When the parsed line is +exhausted before the quote is found, that field is not terminated. + +=item * +2030 "EIF - NL char inside unquoted verbatim, binary off" +X<2030> + +=item * +2031 "EIF - CR char is first char of field, not part of EOL" +X<2031> + +=item * +2032 "EIF - CR char inside unquoted, not part of EOL" +X<2032> + +=item * +2034 "EIF - Loose unescaped quote" +X<2034> + +=item * +2035 "EIF - Escaped EOF in unquoted field" +X<2035> + +=item * +2036 "EIF - ESC error" +X<2036> + +=item * +2037 "EIF - Binary character in unquoted field, binary off" +X<2037> + +=item * +2110 "ECB - Binary character in Combine, binary off" +X<2110> + +=item * +2200 "EIO - print to IO failed. See errno" +X<2200> + +=item * +3001 "EHR - Unsupported syntax for column_names ()" +X<3001> + +=item * +3002 "EHR - getline_hr () called before column_names ()" +X<3002> + +=item * +3003 "EHR - bind_columns () and column_names () fields count mismatch" +X<3003> + +=item * +3004 "EHR - bind_columns () only accepts refs to scalars" +X<3004> + +=item * +3006 "EHR - bind_columns () did not pass enough refs for parsed fields" +X<3006> + +=item * +3007 "EHR - bind_columns needs refs to writable scalars" +X<3007> + +=item * +3008 "EHR - unexpected error in bound fields" +X<3008> + +=item * +3009 "EHR - print_hr () called before column_names ()" +X<3009> + +=item * +3010 "EHR - print_hr () called with invalid arguments" +X<3010> + +=back + +=head1 SEE ALSO + +L, L + +Older versions took many regexp from L + +=head1 AUTHOR + +Kenichi Ishigaki, Eishigaki[at]cpan.orgE +Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE + +Text::CSV_XS was written by Ejoe[at]ispsoft.deE +and maintained by Eh.m.brand[at]xs4all.nlE. + +Text::CSV was written by Ealan[at]mfgrtl.comE. + +=head1 COPYRIGHT AND LICENSE + +Copyright 2017- by Kenichi Ishigaki, Eishigaki[at]cpan.orgE +Copyright 2005-2015 by Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE + +Most of the code and doc is directly taken from the pure perl part of +Text::CSV_XS. + +Copyright (C) 2007-2016 H.Merijn Brand. All rights reserved. +Copyright (C) 1998-2001 Jochen Wiedmann. All rights reserved. +Copyright (C) 1997 Alan Citterman. All rights reserved. + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/deployment-apps/TA-metricator-for-nmon/bin/lib/aix/Text/Diff.pm b/deployment-apps/TA-metricator-for-nmon/bin/lib/aix/Text/Diff.pm new file mode 100644 index 0000000..7f3a613 --- /dev/null +++ b/deployment-apps/TA-metricator-for-nmon/bin/lib/aix/Text/Diff.pm @@ -0,0 +1,745 @@ +package Text::Diff; + +use 5.006; +use strict; +use warnings; +use Carp qw/ croak confess /; +use Exporter (); +use Algorithm::Diff (); + +our $VERSION = '1.45'; +our @ISA = qw/ Exporter /; +our @EXPORT = qw/ diff /; + +## Hunks are made of ops. An op is the starting index for each +## sequence and the opcode: +use constant A => 0; # Array index before match/discard +use constant B => 1; +use constant OPCODE => 2; # "-", " ", "+" +use constant FLAG => 3; # What to display if not OPCODE "!" + +my %internal_styles = ( + Unified => undef, + Context => undef, + OldStyle => undef, + Table => undef, ## "internal", but in another module +); + +sub diff { + my @seqs = ( shift, shift ); + my $options = shift || {}; + + for my $i ( 0 .. 1 ) { + my $seq = $seqs[$i]; + my $type = ref $seq; + + while ( $type eq "CODE" ) { + $seqs[$i] = $seq = $seq->( $options ); + $type = ref $seq; + } + + my $AorB = !$i ? "A" : "B"; + + if ( $type eq "ARRAY" ) { + ## This is most efficient :) + $options->{"OFFSET_$AorB"} = 0 + unless defined $options->{"OFFSET_$AorB"}; + } + elsif ( $type eq "SCALAR" ) { + $seqs[$i] = [split( /^/m, $$seq )]; + $options->{"OFFSET_$AorB"} = 1 + unless defined $options->{"OFFSET_$AorB"}; + } + elsif ( ! $type ) { + $options->{"OFFSET_$AorB"} = 1 + unless defined $options->{"OFFSET_$AorB"}; + $options->{"FILENAME_$AorB"} = $seq + unless defined $options->{"FILENAME_$AorB"}; + $options->{"MTIME_$AorB"} = (stat($seq))[9] + unless defined $options->{"MTIME_$AorB"}; + + local $/ = "\n"; + open F, "<$seq" or croak "$!: $seq"; + $seqs[$i] = []; + close F; + + } + elsif ( $type eq "GLOB" || UNIVERSAL::isa( $seq, "IO::Handle" ) ) { + $options->{"OFFSET_$AorB"} = 1 + unless defined $options->{"OFFSET_$AorB"}; + local $/ = "\n"; + $seqs[$i] = [<$seq>]; + } + else { + confess "Can't handle input of type ", ref; + } + } + + ## Config vars + my $output; + my $output_handler = $options->{OUTPUT}; + my $type = ref $output_handler ; + if ( ! defined $output_handler ) { + $output = ""; + $output_handler = sub { $output .= shift }; + } + elsif ( $type eq "CODE" ) { + ## No problems, mate. + } + elsif ( $type eq "SCALAR" ) { + my $out_ref = $output_handler; + $output_handler = sub { $$out_ref .= shift }; + } + elsif ( $type eq "ARRAY" ) { + my $out_ref = $output_handler; + $output_handler = sub { push @$out_ref, shift }; + } + elsif ( $type eq "GLOB" || UNIVERSAL::isa $output_handler, "IO::Handle" ) { + my $output_handle = $output_handler; + $output_handler = sub { print $output_handle shift }; + } + else { + croak "Unrecognized output type: $type"; + } + + my $style = $options->{STYLE}; + $style = "Unified" unless defined $options->{STYLE}; + $style = "Text::Diff::$style" if exists $internal_styles{$style}; + + if ( ! $style->can( "hunk" ) ) { + eval "require $style; 1" or die $@; + } + + $style = $style->new if ! ref $style && $style->can( "new" ); + + my $ctx_lines = $options->{CONTEXT}; + $ctx_lines = 3 unless defined $ctx_lines; + $ctx_lines = 0 if $style->isa( "Text::Diff::OldStyle" ); + + my @keygen_args = $options->{KEYGEN_ARGS} + ? @{$options->{KEYGEN_ARGS}} + : (); + + ## State vars + my $diffs = 0; ## Number of discards this hunk + my $ctx = 0; ## Number of " " (ctx_lines) ops pushed after last diff. + my @ops; ## ops (" ", +, -) in this hunk + my $hunks = 0; ## Number of hunks + + my $emit_ops = sub { + $output_handler->( $style->file_header( @seqs, $options ) ) + unless $hunks++; + $output_handler->( $style->hunk_header( @seqs, @_, $options ) ); + $output_handler->( $style->hunk ( @seqs, @_, $options ) ); + $output_handler->( $style->hunk_footer( @seqs, @_, $options ) ); + }; + + ## We keep 2*ctx_lines so that if a diff occurs + ## at 2*ctx_lines we continue to grow the hunk instead + ## of emitting diffs and context as we go. We + ## need to know the total length of both of the two + ## subsequences so the line count can be printed in the + ## header. + my $dis_a = sub {push @ops, [@_[0,1],"-"]; ++$diffs ; $ctx = 0 }; + my $dis_b = sub {push @ops, [@_[0,1],"+"]; ++$diffs ; $ctx = 0 }; + + Algorithm::Diff::traverse_sequences( + @seqs, + { + MATCH => sub { + push @ops, [@_[0,1]," "]; + + if ( $diffs && ++$ctx > $ctx_lines * 2 ) { + $emit_ops->( [ splice @ops, 0, $#ops - $ctx_lines ] ); + $ctx = $diffs = 0; + } + + ## throw away context lines that aren't needed any more + shift @ops if ! $diffs && @ops > $ctx_lines; + }, + DISCARD_A => $dis_a, + DISCARD_B => $dis_b, + }, + $options->{KEYGEN}, # pass in user arguments for key gen function + @keygen_args, + ); + + if ( $diffs ) { + $#ops -= $ctx - $ctx_lines if $ctx > $ctx_lines; + $emit_ops->( \@ops ); + } + + $output_handler->( $style->file_footer( @seqs, $options ) ) if $hunks; + + return defined $output ? $output : $hunks; +} + +sub _header { + my ( $h ) = @_; + my ( $p1, $fn1, $t1, $p2, $fn2, $t2 ) = @{$h}{ + "FILENAME_PREFIX_A", + "FILENAME_A", + "MTIME_A", + "FILENAME_PREFIX_B", + "FILENAME_B", + "MTIME_B" + }; + + ## remember to change Text::Diff::Table if this logic is tweaked. + return "" unless defined $fn1 && defined $fn2; + + return join( "", + $p1, " ", $fn1, defined $t1 ? "\t" . localtime $t1 : (), "\n", + $p2, " ", $fn2, defined $t2 ? "\t" . localtime $t2 : (), "\n", + ); +} + +## _range encapsulates the building of, well, ranges. Turns out there are +## a few nuances. +sub _range { + my ( $ops, $a_or_b, $format ) = @_; + + my $start = $ops->[ 0]->[$a_or_b]; + my $after = $ops->[-1]->[$a_or_b]; + + ## The sequence indexes in the lines are from *before* the OPCODE is + ## executed, so we bump the last index up unless the OP indicates + ## it didn't change. + ++$after + unless $ops->[-1]->[OPCODE] eq ( $a_or_b == A ? "+" : "-" ); + + ## convert from 0..n index to 1..(n+1) line number. The unless modifier + ## handles diffs with no context, where only one file is affected. In this + ## case $start == $after indicates an empty range, and the $start must + ## not be incremented. + my $empty_range = $start == $after; + ++$start unless $empty_range; + + return + $start == $after + ? $format eq "unified" && $empty_range + ? "$start,0" + : $start + : $format eq "unified" + ? "$start,".($after-$start+1) + : "$start,$after"; +} + +sub _op_to_line { + my ( $seqs, $op, $a_or_b, $op_prefixes ) = @_; + + my $opcode = $op->[OPCODE]; + return () unless defined $op_prefixes->{$opcode}; + + my $op_sym = defined $op->[FLAG] ? $op->[FLAG] : $opcode; + $op_sym = $op_prefixes->{$op_sym}; + return () unless defined $op_sym; + + $a_or_b = $op->[OPCODE] ne "+" ? 0 : 1 unless defined $a_or_b; + my @line = ( $op_sym, $seqs->[$a_or_b][$op->[$a_or_b]] ); + unless ( $line[1] =~ /(?:\n|\r\n)$/ ) { + $line[1] .= "\n\\ No newline at end of file\n"; + } + return @line; +} + +SCOPE: { + package Text::Diff::Base; + + sub new { + my $proto = shift; + return bless { @_ }, ref $proto || $proto; + } + + sub file_header { return "" } + + sub hunk_header { return "" } + + sub hunk { return "" } + + sub hunk_footer { return "" } + + sub file_footer { return "" } +} + +@Text::Diff::Unified::ISA = qw( Text::Diff::Base ); + +sub Text::Diff::Unified::file_header { + shift; ## No instance data + my $options = pop ; + + _header( + { FILENAME_PREFIX_A => "---", FILENAME_PREFIX_B => "+++", %$options } + ); +} + +sub Text::Diff::Unified::hunk_header { + shift; ## No instance data + pop; ## Ignore options + my $ops = pop; + + return join( "", + "@@ -", + _range( $ops, A, "unified" ), + " +", + _range( $ops, B, "unified" ), + " @@\n", + ); +} + +sub Text::Diff::Unified::hunk { + shift; ## No instance data + pop; ## Ignore options + my $ops = pop; + + my $prefixes = { "+" => "+", " " => " ", "-" => "-" }; + + return join "", map _op_to_line( \@_, $_, undef, $prefixes ), @$ops +} + +@Text::Diff::Context::ISA = qw( Text::Diff::Base ); + +sub Text::Diff::Context::file_header { + _header { FILENAME_PREFIX_A=>"***", FILENAME_PREFIX_B=>"---", %{$_[-1]} }; +} + +sub Text::Diff::Context::hunk_header { + return "***************\n"; +} + +sub Text::Diff::Context::hunk { + shift; ## No instance data + pop; ## Ignore options + my $ops = pop; + ## Leave the sequences in @_[0,1] + + my $a_range = _range( $ops, A, "" ); + my $b_range = _range( $ops, B, "" ); + + ## Sigh. Gotta make sure that differences that aren't adds/deletions + ## get prefixed with "!", and that the old opcodes are removed. + my $after; + for ( my $start = 0; $start <= $#$ops ; $start = $after ) { + ## Scan until next difference + $after = $start + 1; + my $opcode = $ops->[$start]->[OPCODE]; + next if $opcode eq " "; + + my $bang_it; + while ( $after <= $#$ops && $ops->[$after]->[OPCODE] ne " " ) { + $bang_it ||= $ops->[$after]->[OPCODE] ne $opcode; + ++$after; + } + + if ( $bang_it ) { + for my $i ( $start..($after-1) ) { + $ops->[$i]->[FLAG] = "!"; + } + } + } + + my $b_prefixes = { "+" => "+ ", " " => " ", "-" => undef, "!" => "! " }; + my $a_prefixes = { "+" => undef, " " => " ", "-" => "- ", "!" => "! " }; + + return join( "", + "*** ", $a_range, " ****\n", + map( _op_to_line( \@_, $_, A, $a_prefixes ), @$ops ), + "--- ", $b_range, " ----\n", + map( _op_to_line( \@_, $_, B, $b_prefixes ), @$ops ), + ); +} + +@Text::Diff::OldStyle::ISA = qw( Text::Diff::Base ); + +sub _op { + my $ops = shift; + my $op = $ops->[0]->[OPCODE]; + $op = "c" if grep $_->[OPCODE] ne $op, @$ops; + $op = "a" if $op eq "+"; + $op = "d" if $op eq "-"; + return $op; +} + +sub Text::Diff::OldStyle::hunk_header { + shift; ## No instance data + pop; ## ignore options + my $ops = pop; + + my $op = _op $ops; + + return join "", _range( $ops, A, "" ), $op, _range( $ops, B, "" ), "\n"; +} + +sub Text::Diff::OldStyle::hunk { + shift; ## No instance data + pop; ## ignore options + my $ops = pop; + ## Leave the sequences in @_[0,1] + + my $a_prefixes = { "+" => undef, " " => undef, "-" => "< " }; + my $b_prefixes = { "+" => "> ", " " => undef, "-" => undef }; + + my $op = _op $ops; + + return join( "", + map( _op_to_line( \@_, $_, A, $a_prefixes ), @$ops ), + $op eq "c" ? "---\n" : (), + map( _op_to_line( \@_, $_, B, $b_prefixes ), @$ops ), + ); +} + +1; + +__END__ + +=head1 NAME + +Text::Diff - Perform diffs on files and record sets + +=head1 SYNOPSIS + + use Text::Diff; + + ## Mix and match filenames, strings, file handles, producer subs, + ## or arrays of records; returns diff in a string. + ## WARNING: can return B diffs for large files. + my $diff = diff "file1.txt", "file2.txt", { STYLE => "Context" }; + my $diff = diff \$string1, \$string2, \%options; + my $diff = diff \*FH1, \*FH2; + my $diff = diff \&reader1, \&reader2; + my $diff = diff \@records1, \@records2; + + ## May also mix input types: + my $diff = diff \@records1, "file_B.txt"; + +=head1 DESCRIPTION + +C provides a basic set of services akin to the GNU C utility. It +is not anywhere near as feature complete as GNU C, but it is better +integrated with Perl and available on all platforms. It is often faster than +shelling out to a system's C executable for small files, and generally +slower on larger files. + +Relies on L for, well, the algorithm. This may not produce +the same exact diff as a system's local C executable, but it will be a +valid diff and comprehensible by C. We haven't seen any differences +between L's logic and GNU C's, but we have not examined +them to make sure they are indeed identical. + +B: If you don't want to import the C function, do one of the +following: + + use Text::Diff (); + + require Text::Diff; + +That's a pretty rare occurrence, +so C is exported by default. + +If you pass a filename, but the file can't be read, +then C will C. + +=head1 OPTIONS + +C takes two parameters from which to draw input and a set of +options to control its output. The options are: + +=over + +=item FILENAME_A, MTIME_A, FILENAME_B, MTIME_B + +The name of the file and the modification time "files". + +These are filled in automatically for each file when C is passed a +filename, unless a defined value is passed in. + +If a filename is not passed in and FILENAME_A and FILENAME_B are not provided +or are C, the header will not be printed. + +Unused on C diffs. + +=item OFFSET_A, OFFSET_B + +The index of the first line / element. These default to 1 for all +parameter types except ARRAY references, for which the default is 0. This +is because ARRAY references are presumed to be data structures, while the +others are line-oriented text. + +=item STYLE + +"Unified", "Context", "OldStyle", or an object or class reference for a class +providing C, C, C, C and +C methods. The two footer() methods are provided for +overloading only; none of the formats provide them. + +Defaults to "Unified" (unlike standard C, but Unified is what's most +often used in submitting patches and is the most human readable of the three. + +If the package indicated by the STYLE has no C method, C will +load it automatically (lazy loading). Since all such packages should inherit +from C, this should be marvy. + +Styles may be specified as class names (C"; + string += new XMLSerializer().serializeToString(this.root.selectAll("svg")[0][0]); + string += new XMLSerializer().serializeToString(this.root.selectAll("svg")[0][1]); + string += ""; + + return string; + } +}; + +var DomainPosition = function() { + this.positions = d3.map(); +}; + +DomainPosition.prototype.getPosition = function(d) { + return this.positions.get(d); +}; + +DomainPosition.prototype.getPositionFromIndex = function(i) { + var domains = this.getKeys(); + return this.positions.get(domains[i]); +}; + +DomainPosition.prototype.getLast = function() { + var domains = this.getKeys(); + return this.positions.get(domains[domains.length-1]); +}; + +DomainPosition.prototype.setPosition = function(d, dim) { + this.positions.set(d, dim); +}; + +DomainPosition.prototype.shiftRightBy = function(exitingDomainDim) { + this.positions.forEach(function(key, value) { + this.set(key, value - exitingDomainDim); + }); + + var domains = this.getKeys(); + this.positions.remove(domains[0]); +}; + +DomainPosition.prototype.shiftLeftBy = function(enteringDomainDim) { + this.positions.forEach(function(key, value) { + this.set(key, value + enteringDomainDim); + }); + + var domains = this.getKeys(); + this.positions.remove(domains[domains.length-1]); +}; + +DomainPosition.prototype.getKeys = function() { + return this.positions.keys().sort(function(a, b) { + return parseInt(a, 10) - parseInt(b, 10); + }); +}; + +/** + * Sprintf like function + * @source http://stackoverflow.com/a/4795914/805649 + * @return String + */ +String.prototype.format = function () { + var formatted = this; + for (var prop in arguments[0]) { + var regexp = new RegExp("\\{" + prop + "\\}", "gi"); + formatted = formatted.replace(regexp, arguments[0][prop]); + } + return formatted; +}; + +/** + * #source http://stackoverflow.com/a/383245/805649 + */ +function mergeRecursive(obj1, obj2) { + + for (var p in obj2) { + try { + // Property in destination object set; update its value. + if (obj2[p].constructor === Object) { + obj1[p] = mergeRecursive(obj1[p], obj2[p]); + } else { + obj1[p] = obj2[p]; + } + } catch(e) { + // Property in destination object not set; create it and set its value. + obj1[p] = obj2[p]; + } + } + + return obj1; +} + +/// END LIBRARY CODE + +return CalHeatMap; + +}); \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/d3/LICENSE b/deployment-apps/metricator-for-nmon/appserver/static/components/d3/LICENSE new file mode 100644 index 0000000..9869c20 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/d3/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2013, Michael Bostock +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* The name Michael Bostock may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/d3/bower.json b/deployment-apps/metricator-for-nmon/appserver/static/components/d3/bower.json new file mode 100644 index 0000000..3b8552c --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/d3/bower.json @@ -0,0 +1,8 @@ +{ + "name": "d3", + "version": "3.3.5", + "main": "d3.js", + "ignore": [], + "dependencies": {}, + "devDependencies": {} +} \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/d3/d3.js b/deployment-apps/metricator-for-nmon/appserver/static/components/d3/d3.js new file mode 100644 index 0000000..5c1514c --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/d3/d3.js @@ -0,0 +1,8988 @@ +define(function(require, exports, module) { + +/// BEGIN LIBRARY CODE + +d3 = function() { + var d3 = { + version: "3.3.5" + }; + if (!Date.now) Date.now = function() { + return +new Date(); + }; + var d3_arraySlice = [].slice, d3_array = function(list) { + return d3_arraySlice.call(list); + }; + var d3_document = document, d3_documentElement = d3_document.documentElement, d3_window = window; + try { + d3_array(d3_documentElement.childNodes)[0].nodeType; + } catch (e) { + d3_array = function(list) { + var i = list.length, array = new Array(i); + while (i--) array[i] = list[i]; + return array; + }; + } + try { + d3_document.createElement("div").style.setProperty("opacity", 0, ""); + } catch (error) { + var d3_element_prototype = d3_window.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; + d3_element_prototype.setAttribute = function(name, value) { + d3_element_setAttribute.call(this, name, value + ""); + }; + d3_element_prototype.setAttributeNS = function(space, local, value) { + d3_element_setAttributeNS.call(this, space, local, value + ""); + }; + d3_style_prototype.setProperty = function(name, value, priority) { + d3_style_setProperty.call(this, name, value + "", priority); + }; + } + d3.ascending = function(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; + }; + d3.descending = function(a, b) { + return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; + }; + d3.min = function(array, f) { + var i = -1, n = array.length, a, b; + if (arguments.length === 1) { + while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; + while (++i < n) if ((b = array[i]) != null && a > b) a = b; + } else { + while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; + while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; + } + return a; + }; + d3.max = function(array, f) { + var i = -1, n = array.length, a, b; + if (arguments.length === 1) { + while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; + while (++i < n) if ((b = array[i]) != null && b > a) a = b; + } else { + while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; + while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; + } + return a; + }; + d3.extent = function(array, f) { + var i = -1, n = array.length, a, b, c; + if (arguments.length === 1) { + while (++i < n && !((a = c = array[i]) != null && a <= a)) a = c = undefined; + while (++i < n) if ((b = array[i]) != null) { + if (a > b) a = b; + if (c < b) c = b; + } + } else { + while (++i < n && !((a = c = f.call(array, array[i], i)) != null && a <= a)) a = undefined; + while (++i < n) if ((b = f.call(array, array[i], i)) != null) { + if (a > b) a = b; + if (c < b) c = b; + } + } + return [ a, c ]; + }; + d3.sum = function(array, f) { + var s = 0, n = array.length, a, i = -1; + if (arguments.length === 1) { + while (++i < n) if (!isNaN(a = +array[i])) s += a; + } else { + while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a; + } + return s; + }; + function d3_number(x) { + return x != null && !isNaN(x); + } + d3.mean = function(array, f) { + var n = array.length, a, m = 0, i = -1, j = 0; + if (arguments.length === 1) { + while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j; + } else { + while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j; + } + return j ? m : undefined; + }; + d3.quantile = function(values, p) { + var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; + return e ? v + e * (values[h] - v) : v; + }; + d3.median = function(array, f) { + if (arguments.length > 1) array = array.map(f); + array = array.filter(d3_number); + return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined; + }; + d3.bisector = function(f) { + return { + left: function(a, x, lo, hi) { + if (arguments.length < 3) lo = 0; + if (arguments.length < 4) hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (f.call(a, a[mid], mid) < x) lo = mid + 1; else hi = mid; + } + return lo; + }, + right: function(a, x, lo, hi) { + if (arguments.length < 3) lo = 0; + if (arguments.length < 4) hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (x < f.call(a, a[mid], mid)) hi = mid; else lo = mid + 1; + } + return lo; + } + }; + }; + var d3_bisector = d3.bisector(function(d) { + return d; + }); + d3.bisectLeft = d3_bisector.left; + d3.bisect = d3.bisectRight = d3_bisector.right; + d3.shuffle = function(array) { + var m = array.length, t, i; + while (m) { + i = Math.random() * m-- | 0; + t = array[m], array[m] = array[i], array[i] = t; + } + return array; + }; + d3.permute = function(array, indexes) { + var i = indexes.length, permutes = new Array(i); + while (i--) permutes[i] = array[indexes[i]]; + return permutes; + }; + d3.pairs = function(array) { + var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); + while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ]; + return pairs; + }; + d3.zip = function() { + if (!(n = arguments.length)) return []; + for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { + for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { + zip[j] = arguments[j][i]; + } + } + return zips; + }; + function d3_zipLength(d) { + return d.length; + } + d3.transpose = function(matrix) { + return d3.zip.apply(d3, matrix); + }; + d3.keys = function(map) { + var keys = []; + for (var key in map) keys.push(key); + return keys; + }; + d3.values = function(map) { + var values = []; + for (var key in map) values.push(map[key]); + return values; + }; + d3.entries = function(map) { + var entries = []; + for (var key in map) entries.push({ + key: key, + value: map[key] + }); + return entries; + }; + d3.merge = function(arrays) { + return Array.prototype.concat.apply([], arrays); + }; + d3.range = function(start, stop, step) { + if (arguments.length < 3) { + step = 1; + if (arguments.length < 2) { + stop = start; + start = 0; + } + } + if ((stop - start) / step === Infinity) throw new Error("infinite range"); + var range = [], k = d3_range_integerScale(Math.abs(step)), i = -1, j; + start *= k, stop *= k, step *= k; + if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); + return range; + }; + function d3_range_integerScale(x) { + var k = 1; + while (x * k % 1) k *= 10; + return k; + } + function d3_class(ctor, properties) { + try { + for (var key in properties) { + Object.defineProperty(ctor.prototype, key, { + value: properties[key], + enumerable: false + }); + } + } catch (e) { + ctor.prototype = properties; + } + } + d3.map = function(object) { + var map = new d3_Map(); + if (object instanceof d3_Map) object.forEach(function(key, value) { + map.set(key, value); + }); else for (var key in object) map.set(key, object[key]); + return map; + }; + function d3_Map() {} + d3_class(d3_Map, { + has: function(key) { + return d3_map_prefix + key in this; + }, + get: function(key) { + return this[d3_map_prefix + key]; + }, + set: function(key, value) { + return this[d3_map_prefix + key] = value; + }, + remove: function(key) { + key = d3_map_prefix + key; + return key in this && delete this[key]; + }, + keys: function() { + var keys = []; + this.forEach(function(key) { + keys.push(key); + }); + return keys; + }, + values: function() { + var values = []; + this.forEach(function(key, value) { + values.push(value); + }); + return values; + }, + entries: function() { + var entries = []; + this.forEach(function(key, value) { + entries.push({ + key: key, + value: value + }); + }); + return entries; + }, + forEach: function(f) { + for (var key in this) { + if (key.charCodeAt(0) === d3_map_prefixCode) { + f.call(this, key.substring(1), this[key]); + } + } + } + }); + var d3_map_prefix = "\0", d3_map_prefixCode = d3_map_prefix.charCodeAt(0); + d3.nest = function() { + var nest = {}, keys = [], sortKeys = [], sortValues, rollup; + function map(mapType, array, depth) { + if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; + var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; + while (++i < n) { + if (values = valuesByKey.get(keyValue = key(object = array[i]))) { + values.push(object); + } else { + valuesByKey.set(keyValue, [ object ]); + } + } + if (mapType) { + object = mapType(); + setter = function(keyValue, values) { + object.set(keyValue, map(mapType, values, depth)); + }; + } else { + object = {}; + setter = function(keyValue, values) { + object[keyValue] = map(mapType, values, depth); + }; + } + valuesByKey.forEach(setter); + return object; + } + function entries(map, depth) { + if (depth >= keys.length) return map; + var array = [], sortKey = sortKeys[depth++]; + map.forEach(function(key, keyMap) { + array.push({ + key: key, + values: entries(keyMap, depth) + }); + }); + return sortKey ? array.sort(function(a, b) { + return sortKey(a.key, b.key); + }) : array; + } + nest.map = function(array, mapType) { + return map(mapType, array, 0); + }; + nest.entries = function(array) { + return entries(map(d3.map, array, 0), 0); + }; + nest.key = function(d) { + keys.push(d); + return nest; + }; + nest.sortKeys = function(order) { + sortKeys[keys.length - 1] = order; + return nest; + }; + nest.sortValues = function(order) { + sortValues = order; + return nest; + }; + nest.rollup = function(f) { + rollup = f; + return nest; + }; + return nest; + }; + d3.set = function(array) { + var set = new d3_Set(); + if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); + return set; + }; + function d3_Set() {} + d3_class(d3_Set, { + has: function(value) { + return d3_map_prefix + value in this; + }, + add: function(value) { + this[d3_map_prefix + value] = true; + return value; + }, + remove: function(value) { + value = d3_map_prefix + value; + return value in this && delete this[value]; + }, + values: function() { + var values = []; + this.forEach(function(value) { + values.push(value); + }); + return values; + }, + forEach: function(f) { + for (var value in this) { + if (value.charCodeAt(0) === d3_map_prefixCode) { + f.call(this, value.substring(1)); + } + } + } + }); + d3.behavior = {}; + d3.rebind = function(target, source) { + var i = 1, n = arguments.length, method; + while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); + return target; + }; + function d3_rebind(target, source, method) { + return function() { + var value = method.apply(source, arguments); + return value === source ? target : value; + }; + } + function d3_vendorSymbol(object, name) { + if (name in object) return name; + name = name.charAt(0).toUpperCase() + name.substring(1); + for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { + var prefixName = d3_vendorPrefixes[i] + name; + if (prefixName in object) return prefixName; + } + } + var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ]; + function d3_noop() {} + d3.dispatch = function() { + var dispatch = new d3_dispatch(), i = -1, n = arguments.length; + while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); + return dispatch; + }; + function d3_dispatch() {} + d3_dispatch.prototype.on = function(type, listener) { + var i = type.indexOf("."), name = ""; + if (i >= 0) { + name = type.substring(i + 1); + type = type.substring(0, i); + } + if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); + if (arguments.length === 2) { + if (listener == null) for (type in this) { + if (this.hasOwnProperty(type)) this[type].on(name, null); + } + return this; + } + }; + function d3_dispatch_event(dispatch) { + var listeners = [], listenerByName = new d3_Map(); + function event() { + var z = listeners, i = -1, n = z.length, l; + while (++i < n) if (l = z[i].on) l.apply(this, arguments); + return dispatch; + } + event.on = function(name, listener) { + var l = listenerByName.get(name), i; + if (arguments.length < 2) return l && l.on; + if (l) { + l.on = null; + listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); + listenerByName.remove(name); + } + if (listener) listeners.push(listenerByName.set(name, { + on: listener + })); + return dispatch; + }; + return event; + } + d3.event = null; + function d3_eventPreventDefault() { + d3.event.preventDefault(); + } + function d3_eventSource() { + var e = d3.event, s; + while (s = e.sourceEvent) e = s; + return e; + } + function d3_eventDispatch(target) { + var dispatch = new d3_dispatch(), i = 0, n = arguments.length; + while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); + dispatch.of = function(thiz, argumentz) { + return function(e1) { + try { + var e0 = e1.sourceEvent = d3.event; + e1.target = target; + d3.event = e1; + dispatch[e1.type].apply(thiz, argumentz); + } finally { + d3.event = e0; + } + }; + }; + return dispatch; + } + d3.requote = function(s) { + return s.replace(d3_requote_re, "\\$&"); + }; + var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; + var d3_subclass = {}.__proto__ ? function(object, prototype) { + object.__proto__ = prototype; + } : function(object, prototype) { + for (var property in prototype) object[property] = prototype[property]; + }; + function d3_selection(groups) { + d3_subclass(groups, d3_selectionPrototype); + return groups; + } + var d3_select = function(s, n) { + return n.querySelector(s); + }, d3_selectAll = function(s, n) { + return n.querySelectorAll(s); + }, d3_selectMatcher = d3_documentElement[d3_vendorSymbol(d3_documentElement, "matchesSelector")], d3_selectMatches = function(n, s) { + return d3_selectMatcher.call(n, s); + }; + if (typeof Sizzle === "function") { + d3_select = function(s, n) { + return Sizzle(s, n)[0] || null; + }; + d3_selectAll = function(s, n) { + return Sizzle.uniqueSort(Sizzle(s, n)); + }; + d3_selectMatches = Sizzle.matchesSelector; + } + d3.selection = function() { + return d3_selectionRoot; + }; + var d3_selectionPrototype = d3.selection.prototype = []; + d3_selectionPrototype.select = function(selector) { + var subgroups = [], subgroup, subnode, group, node; + selector = d3_selection_selector(selector); + for (var j = -1, m = this.length; ++j < m; ) { + subgroups.push(subgroup = []); + subgroup.parentNode = (group = this[j]).parentNode; + for (var i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) { + subgroup.push(subnode = selector.call(node, node.__data__, i, j)); + if (subnode && "__data__" in node) subnode.__data__ = node.__data__; + } else { + subgroup.push(null); + } + } + } + return d3_selection(subgroups); + }; + function d3_selection_selector(selector) { + return typeof selector === "function" ? selector : function() { + return d3_select(selector, this); + }; + } + d3_selectionPrototype.selectAll = function(selector) { + var subgroups = [], subgroup, node; + selector = d3_selection_selectorAll(selector); + for (var j = -1, m = this.length; ++j < m; ) { + for (var group = this[j], i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) { + subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j))); + subgroup.parentNode = node; + } + } + } + return d3_selection(subgroups); + }; + function d3_selection_selectorAll(selector) { + return typeof selector === "function" ? selector : function() { + return d3_selectAll(selector, this); + }; + } + var d3_nsPrefix = { + svg: "http://www.w3.org/2000/svg", + xhtml: "http://www.w3.org/1999/xhtml", + xlink: "http://www.w3.org/1999/xlink", + xml: "http://www.w3.org/XML/1998/namespace", + xmlns: "http://www.w3.org/2000/xmlns/" + }; + d3.ns = { + prefix: d3_nsPrefix, + qualify: function(name) { + var i = name.indexOf(":"), prefix = name; + if (i >= 0) { + prefix = name.substring(0, i); + name = name.substring(i + 1); + } + return d3_nsPrefix.hasOwnProperty(prefix) ? { + space: d3_nsPrefix[prefix], + local: name + } : name; + } + }; + d3_selectionPrototype.attr = function(name, value) { + if (arguments.length < 2) { + if (typeof name === "string") { + var node = this.node(); + name = d3.ns.qualify(name); + return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); + } + for (value in name) this.each(d3_selection_attr(value, name[value])); + return this; + } + return this.each(d3_selection_attr(name, value)); + }; + function d3_selection_attr(name, value) { + name = d3.ns.qualify(name); + function attrNull() { + this.removeAttribute(name); + } + function attrNullNS() { + this.removeAttributeNS(name.space, name.local); + } + function attrConstant() { + this.setAttribute(name, value); + } + function attrConstantNS() { + this.setAttributeNS(name.space, name.local, value); + } + function attrFunction() { + var x = value.apply(this, arguments); + if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); + } + function attrFunctionNS() { + var x = value.apply(this, arguments); + if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); + } + return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; + } + function d3_collapse(s) { + return s.trim().replace(/\s+/g, " "); + } + d3_selectionPrototype.classed = function(name, value) { + if (arguments.length < 2) { + if (typeof name === "string") { + var node = this.node(), n = (name = name.trim().split(/^|\s+/g)).length, i = -1; + if (value = node.classList) { + while (++i < n) if (!value.contains(name[i])) return false; + } else { + value = node.getAttribute("class"); + while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; + } + return true; + } + for (value in name) this.each(d3_selection_classed(value, name[value])); + return this; + } + return this.each(d3_selection_classed(name, value)); + }; + function d3_selection_classedRe(name) { + return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); + } + function d3_selection_classed(name, value) { + name = name.trim().split(/\s+/).map(d3_selection_classedName); + var n = name.length; + function classedConstant() { + var i = -1; + while (++i < n) name[i](this, value); + } + function classedFunction() { + var i = -1, x = value.apply(this, arguments); + while (++i < n) name[i](this, x); + } + return typeof value === "function" ? classedFunction : classedConstant; + } + function d3_selection_classedName(name) { + var re = d3_selection_classedRe(name); + return function(node, value) { + if (c = node.classList) return value ? c.add(name) : c.remove(name); + var c = node.getAttribute("class") || ""; + if (value) { + re.lastIndex = 0; + if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); + } else { + node.setAttribute("class", d3_collapse(c.replace(re, " "))); + } + }; + } + d3_selectionPrototype.style = function(name, value, priority) { + var n = arguments.length; + if (n < 3) { + if (typeof name !== "string") { + if (n < 2) value = ""; + for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); + return this; + } + if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name); + priority = ""; + } + return this.each(d3_selection_style(name, value, priority)); + }; + function d3_selection_style(name, value, priority) { + function styleNull() { + this.style.removeProperty(name); + } + function styleConstant() { + this.style.setProperty(name, value, priority); + } + function styleFunction() { + var x = value.apply(this, arguments); + if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); + } + return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; + } + d3_selectionPrototype.property = function(name, value) { + if (arguments.length < 2) { + if (typeof name === "string") return this.node()[name]; + for (value in name) this.each(d3_selection_property(value, name[value])); + return this; + } + return this.each(d3_selection_property(name, value)); + }; + function d3_selection_property(name, value) { + function propertyNull() { + delete this[name]; + } + function propertyConstant() { + this[name] = value; + } + function propertyFunction() { + var x = value.apply(this, arguments); + if (x == null) delete this[name]; else this[name] = x; + } + return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; + } + d3_selectionPrototype.text = function(value) { + return arguments.length ? this.each(typeof value === "function" ? function() { + var v = value.apply(this, arguments); + this.textContent = v == null ? "" : v; + } : value == null ? function() { + this.textContent = ""; + } : function() { + this.textContent = value; + }) : this.node().textContent; + }; + d3_selectionPrototype.html = function(value) { + return arguments.length ? this.each(typeof value === "function" ? function() { + var v = value.apply(this, arguments); + this.innerHTML = v == null ? "" : v; + } : value == null ? function() { + this.innerHTML = ""; + } : function() { + this.innerHTML = value; + }) : this.node().innerHTML; + }; + d3_selectionPrototype.append = function(name) { + name = d3_selection_creator(name); + return this.select(function() { + return this.appendChild(name.apply(this, arguments)); + }); + }; + function d3_selection_creator(name) { + return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() { + return d3_document.createElementNS(name.space, name.local); + } : function() { + return d3_document.createElementNS(this.namespaceURI, name); + }; + } + d3_selectionPrototype.insert = function(name, before) { + name = d3_selection_creator(name); + before = d3_selection_selector(before); + return this.select(function() { + return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments)); + }); + }; + d3_selectionPrototype.remove = function() { + return this.each(function() { + var parent = this.parentNode; + if (parent) parent.removeChild(this); + }); + }; + d3_selectionPrototype.data = function(value, key) { + var i = -1, n = this.length, group, node; + if (!arguments.length) { + value = new Array(n = (group = this[0]).length); + while (++i < n) { + if (node = group[i]) { + value[i] = node.__data__; + } + } + return value; + } + function bind(group, groupData) { + var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData; + if (key) { + var nodeByKeyValue = new d3_Map(), dataByKeyValue = new d3_Map(), keyValues = [], keyValue; + for (i = -1; ++i < n; ) { + keyValue = key.call(node = group[i], node.__data__, i); + if (nodeByKeyValue.has(keyValue)) { + exitNodes[i] = node; + } else { + nodeByKeyValue.set(keyValue, node); + } + keyValues.push(keyValue); + } + for (i = -1; ++i < m; ) { + keyValue = key.call(groupData, nodeData = groupData[i], i); + if (node = nodeByKeyValue.get(keyValue)) { + updateNodes[i] = node; + node.__data__ = nodeData; + } else if (!dataByKeyValue.has(keyValue)) { + enterNodes[i] = d3_selection_dataNode(nodeData); + } + dataByKeyValue.set(keyValue, nodeData); + nodeByKeyValue.remove(keyValue); + } + for (i = -1; ++i < n; ) { + if (nodeByKeyValue.has(keyValues[i])) { + exitNodes[i] = group[i]; + } + } + } else { + for (i = -1; ++i < n0; ) { + node = group[i]; + nodeData = groupData[i]; + if (node) { + node.__data__ = nodeData; + updateNodes[i] = node; + } else { + enterNodes[i] = d3_selection_dataNode(nodeData); + } + } + for (;i < m; ++i) { + enterNodes[i] = d3_selection_dataNode(groupData[i]); + } + for (;i < n; ++i) { + exitNodes[i] = group[i]; + } + } + enterNodes.update = updateNodes; + enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; + enter.push(enterNodes); + update.push(updateNodes); + exit.push(exitNodes); + } + var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); + if (typeof value === "function") { + while (++i < n) { + bind(group = this[i], value.call(group, group.parentNode.__data__, i)); + } + } else { + while (++i < n) { + bind(group = this[i], value); + } + } + update.enter = function() { + return enter; + }; + update.exit = function() { + return exit; + }; + return update; + }; + function d3_selection_dataNode(data) { + return { + __data__: data + }; + } + d3_selectionPrototype.datum = function(value) { + return arguments.length ? this.property("__data__", value) : this.property("__data__"); + }; + d3_selectionPrototype.filter = function(filter) { + var subgroups = [], subgroup, group, node; + if (typeof filter !== "function") filter = d3_selection_filter(filter); + for (var j = 0, m = this.length; j < m; j++) { + subgroups.push(subgroup = []); + subgroup.parentNode = (group = this[j]).parentNode; + for (var i = 0, n = group.length; i < n; i++) { + if ((node = group[i]) && filter.call(node, node.__data__, i)) { + subgroup.push(node); + } + } + } + return d3_selection(subgroups); + }; + function d3_selection_filter(selector) { + return function() { + return d3_selectMatches(this, selector); + }; + } + d3_selectionPrototype.order = function() { + for (var j = -1, m = this.length; ++j < m; ) { + for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { + if (node = group[i]) { + if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); + next = node; + } + } + } + return this; + }; + d3_selectionPrototype.sort = function(comparator) { + comparator = d3_selection_sortComparator.apply(this, arguments); + for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); + return this.order(); + }; + function d3_selection_sortComparator(comparator) { + if (!arguments.length) comparator = d3.ascending; + return function(a, b) { + return a && b ? comparator(a.__data__, b.__data__) : !a - !b; + }; + } + d3_selectionPrototype.each = function(callback) { + return d3_selection_each(this, function(node, i, j) { + callback.call(node, node.__data__, i, j); + }); + }; + function d3_selection_each(groups, callback) { + for (var j = 0, m = groups.length; j < m; j++) { + for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { + if (node = group[i]) callback(node, i, j); + } + } + return groups; + } + d3_selectionPrototype.call = function(callback) { + var args = d3_array(arguments); + callback.apply(args[0] = this, args); + return this; + }; + d3_selectionPrototype.empty = function() { + return !this.node(); + }; + d3_selectionPrototype.node = function() { + for (var j = 0, m = this.length; j < m; j++) { + for (var group = this[j], i = 0, n = group.length; i < n; i++) { + var node = group[i]; + if (node) return node; + } + } + return null; + }; + d3_selectionPrototype.size = function() { + var n = 0; + this.each(function() { + ++n; + }); + return n; + }; + function d3_selection_enter(selection) { + d3_subclass(selection, d3_selection_enterPrototype); + return selection; + } + var d3_selection_enterPrototype = []; + d3.selection.enter = d3_selection_enter; + d3.selection.enter.prototype = d3_selection_enterPrototype; + d3_selection_enterPrototype.append = d3_selectionPrototype.append; + d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; + d3_selection_enterPrototype.node = d3_selectionPrototype.node; + d3_selection_enterPrototype.call = d3_selectionPrototype.call; + d3_selection_enterPrototype.size = d3_selectionPrototype.size; + d3_selection_enterPrototype.select = function(selector) { + var subgroups = [], subgroup, subnode, upgroup, group, node; + for (var j = -1, m = this.length; ++j < m; ) { + upgroup = (group = this[j]).update; + subgroups.push(subgroup = []); + subgroup.parentNode = group.parentNode; + for (var i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) { + subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j)); + subnode.__data__ = node.__data__; + } else { + subgroup.push(null); + } + } + } + return d3_selection(subgroups); + }; + d3_selection_enterPrototype.insert = function(name, before) { + if (arguments.length < 2) before = d3_selection_enterInsertBefore(this); + return d3_selectionPrototype.insert.call(this, name, before); + }; + function d3_selection_enterInsertBefore(enter) { + var i0, j0; + return function(d, i, j) { + var group = enter[j].update, n = group.length, node; + if (j != j0) j0 = j, i0 = 0; + if (i >= i0) i0 = i + 1; + while (!(node = group[i0]) && ++i0 < n) ; + return node; + }; + } + d3_selectionPrototype.transition = function() { + var id = d3_transitionInheritId || ++d3_transitionId, subgroups = [], subgroup, node, transition = d3_transitionInherit || { + time: Date.now(), + ease: d3_ease_cubicInOut, + delay: 0, + duration: 250 + }; + for (var j = -1, m = this.length; ++j < m; ) { + subgroups.push(subgroup = []); + for (var group = this[j], i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) d3_transitionNode(node, i, id, transition); + subgroup.push(node); + } + } + return d3_transition(subgroups, id); + }; + d3_selectionPrototype.interrupt = function() { + return this.each(d3_selection_interrupt); + }; + function d3_selection_interrupt() { + var lock = this.__transition__; + if (lock) ++lock.active; + } + d3.select = function(node) { + var group = [ typeof node === "string" ? d3_select(node, d3_document) : node ]; + group.parentNode = d3_documentElement; + return d3_selection([ group ]); + }; + d3.selectAll = function(nodes) { + var group = d3_array(typeof nodes === "string" ? d3_selectAll(nodes, d3_document) : nodes); + group.parentNode = d3_documentElement; + return d3_selection([ group ]); + }; + var d3_selectionRoot = d3.select(d3_documentElement); + d3_selectionPrototype.on = function(type, listener, capture) { + var n = arguments.length; + if (n < 3) { + if (typeof type !== "string") { + if (n < 2) listener = false; + for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); + return this; + } + if (n < 2) return (n = this.node()["__on" + type]) && n._; + capture = false; + } + return this.each(d3_selection_on(type, listener, capture)); + }; + function d3_selection_on(type, listener, capture) { + var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener; + if (i > 0) type = type.substring(0, i); + var filter = d3_selection_onFilters.get(type); + if (filter) type = filter, wrap = d3_selection_onFilter; + function onRemove() { + var l = this[name]; + if (l) { + this.removeEventListener(type, l, l.$); + delete this[name]; + } + } + function onAdd() { + var l = wrap(listener, d3_array(arguments)); + onRemove.call(this); + this.addEventListener(type, this[name] = l, l.$ = capture); + l._ = listener; + } + function removeAll() { + var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match; + for (var name in this) { + if (match = name.match(re)) { + var l = this[name]; + this.removeEventListener(match[1], l, l.$); + delete this[name]; + } + } + } + return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll; + } + var d3_selection_onFilters = d3.map({ + mouseenter: "mouseover", + mouseleave: "mouseout" + }); + d3_selection_onFilters.forEach(function(k) { + if ("on" + k in d3_document) d3_selection_onFilters.remove(k); + }); + function d3_selection_onListener(listener, argumentz) { + return function(e) { + var o = d3.event; + d3.event = e; + argumentz[0] = this.__data__; + try { + listener.apply(this, argumentz); + } finally { + d3.event = o; + } + }; + } + function d3_selection_onFilter(listener, argumentz) { + var l = d3_selection_onListener(listener, argumentz); + return function(e) { + var target = this, related = e.relatedTarget; + if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) { + l.call(target, e); + } + }; + } + var d3_event_dragSelect = d3_vendorSymbol(d3_documentElement.style, "userSelect"), d3_event_dragId = 0; + function d3_event_dragSuppress() { + var name = ".dragsuppress-" + ++d3_event_dragId, touchmove = "touchmove" + name, selectstart = "selectstart" + name, dragstart = "dragstart" + name, click = "click" + name, w = d3.select(d3_window).on(touchmove, d3_eventPreventDefault).on(selectstart, d3_eventPreventDefault).on(dragstart, d3_eventPreventDefault), style = d3_documentElement.style, select = style[d3_event_dragSelect]; + style[d3_event_dragSelect] = "none"; + return function(suppressClick) { + w.on(name, null); + style[d3_event_dragSelect] = select; + if (suppressClick) { + function off() { + w.on(click, null); + } + w.on(click, function() { + d3_eventPreventDefault(); + off(); + }, true); + setTimeout(off, 0); + } + }; + } + d3.mouse = function(container) { + return d3_mousePoint(container, d3_eventSource()); + }; + var d3_mouse_bug44083 = /WebKit/.test(d3_window.navigator.userAgent) ? -1 : 0; + function d3_mousePoint(container, e) { + if (e.changedTouches) e = e.changedTouches[0]; + var svg = container.ownerSVGElement || container; + if (svg.createSVGPoint) { + var point = svg.createSVGPoint(); + if (d3_mouse_bug44083 < 0 && (d3_window.scrollX || d3_window.scrollY)) { + svg = d3.select("body").append("svg").style({ + position: "absolute", + top: 0, + left: 0, + margin: 0, + padding: 0, + border: "none" + }, "important"); + var ctm = svg[0][0].getScreenCTM(); + d3_mouse_bug44083 = !(ctm.f || ctm.e); + svg.remove(); + } + if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, + point.y = e.clientY; + point = point.matrixTransform(container.getScreenCTM().inverse()); + return [ point.x, point.y ]; + } + var rect = container.getBoundingClientRect(); + return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; + } + d3.touches = function(container, touches) { + if (arguments.length < 2) touches = d3_eventSource().touches; + return touches ? d3_array(touches).map(function(touch) { + var point = d3_mousePoint(container, touch); + point.identifier = touch.identifier; + return point; + }) : []; + }; + d3.behavior.drag = function() { + var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, "mousemove", "mouseup"), touchstart = dragstart(touchid, touchposition, "touchmove", "touchend"); + function drag() { + this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart); + } + function touchid() { + return d3.event.changedTouches[0].identifier; + } + function touchposition(parent, id) { + return d3.touches(parent).filter(function(p) { + return p.identifier === id; + })[0]; + } + function dragstart(id, position, move, end) { + return function() { + var target = this, parent = target.parentNode, event_ = event.of(target, arguments), eventTarget = d3.event.target, eventId = id(), drag = eventId == null ? "drag" : "drag-" + eventId, origin_ = position(parent, eventId), dragged = 0, offset, w = d3.select(d3_window).on(move + "." + drag, moved).on(end + "." + drag, ended), dragRestore = d3_event_dragSuppress(); + if (origin) { + offset = origin.apply(target, arguments); + offset = [ offset.x - origin_[0], offset.y - origin_[1] ]; + } else { + offset = [ 0, 0 ]; + } + event_({ + type: "dragstart" + }); + function moved() { + var p = position(parent, eventId), dx = p[0] - origin_[0], dy = p[1] - origin_[1]; + dragged |= dx | dy; + origin_ = p; + event_({ + type: "drag", + x: p[0] + offset[0], + y: p[1] + offset[1], + dx: dx, + dy: dy + }); + } + function ended() { + w.on(move + "." + drag, null).on(end + "." + drag, null); + dragRestore(dragged && d3.event.target === eventTarget); + event_({ + type: "dragend" + }); + } + }; + } + drag.origin = function(x) { + if (!arguments.length) return origin; + origin = x; + return drag; + }; + return d3.rebind(drag, event, "on"); + }; + var π = Math.PI, ε = 1e-6, ε2 = ε * ε, d3_radians = π / 180, d3_degrees = 180 / π; + function d3_sgn(x) { + return x > 0 ? 1 : x < 0 ? -1 : 0; + } + function d3_acos(x) { + return x > 1 ? 0 : x < -1 ? π : Math.acos(x); + } + function d3_asin(x) { + return x > 1 ? π / 2 : x < -1 ? -π / 2 : Math.asin(x); + } + function d3_sinh(x) { + return (Math.exp(x) - Math.exp(-x)) / 2; + } + function d3_cosh(x) { + return (Math.exp(x) + Math.exp(-x)) / 2; + } + function d3_tanh(x) { + return d3_sinh(x) / d3_cosh(x); + } + function d3_haversin(x) { + return (x = Math.sin(x / 2)) * x; + } + var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4; + d3.interpolateZoom = function(p0, p1) { + var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2]; + var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / ρ; + function interpolate(t) { + var s = t * S; + if (dr) { + var coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0)); + return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ]; + } + return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * s) ]; + } + interpolate.duration = S * 1e3; + return interpolate; + }; + d3.behavior.zoom = function() { + var view = { + x: 0, + y: 0, + k: 1 + }, translate0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1; + function zoom(g) { + g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on(mousemove, mousewheelreset).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted); + } + zoom.event = function(g) { + g.each(function() { + var event_ = event.of(this, arguments), view1 = view; + if (d3_transitionInheritId) { + d3.select(this).transition().each("start.zoom", function() { + view = this.__chart__ || { + x: 0, + y: 0, + k: 1 + }; + zoomstarted(event_); + }).tween("zoom:zoom", function() { + var dx = size[0], dy = size[1], cx = dx / 2, cy = dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]); + return function(t) { + var l = i(t), k = dx / l[2]; + this.__chart__ = view = { + x: cx - l[0] * k, + y: cy - l[1] * k, + k: k + }; + zoomed(event_); + }; + }).each("end.zoom", function() { + zoomended(event_); + }); + } else { + this.__chart__ = view; + zoomstarted(event_); + zoomed(event_); + zoomended(event_); + } + }); + }; + zoom.translate = function(_) { + if (!arguments.length) return [ view.x, view.y ]; + view = { + x: +_[0], + y: +_[1], + k: view.k + }; + rescale(); + return zoom; + }; + zoom.scale = function(_) { + if (!arguments.length) return view.k; + view = { + x: view.x, + y: view.y, + k: +_ + }; + rescale(); + return zoom; + }; + zoom.scaleExtent = function(_) { + if (!arguments.length) return scaleExtent; + scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ]; + return zoom; + }; + zoom.center = function(_) { + if (!arguments.length) return center; + center = _ && [ +_[0], +_[1] ]; + return zoom; + }; + zoom.size = function(_) { + if (!arguments.length) return size; + size = _ && [ +_[0], +_[1] ]; + return zoom; + }; + zoom.x = function(z) { + if (!arguments.length) return x1; + x1 = z; + x0 = z.copy(); + view = { + x: 0, + y: 0, + k: 1 + }; + return zoom; + }; + zoom.y = function(z) { + if (!arguments.length) return y1; + y1 = z; + y0 = z.copy(); + view = { + x: 0, + y: 0, + k: 1 + }; + return zoom; + }; + function location(p) { + return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ]; + } + function point(l) { + return [ l[0] * view.k + view.x, l[1] * view.k + view.y ]; + } + function scaleTo(s) { + view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); + } + function translateTo(p, l) { + l = point(l); + view.x += p[0] - l[0]; + view.y += p[1] - l[1]; + } + function rescale() { + if (x1) x1.domain(x0.range().map(function(x) { + return (x - view.x) / view.k; + }).map(x0.invert)); + if (y1) y1.domain(y0.range().map(function(y) { + return (y - view.y) / view.k; + }).map(y0.invert)); + } + function zoomstarted(event) { + event({ + type: "zoomstart" + }); + } + function zoomed(event) { + rescale(); + event({ + type: "zoom", + scale: view.k, + translate: [ view.x, view.y ] + }); + } + function zoomended(event) { + event({ + type: "zoomend" + }); + } + function mousedowned() { + var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, dragged = 0, w = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended), l = location(d3.mouse(target)), dragRestore = d3_event_dragSuppress(); + d3_selection_interrupt.call(target); + zoomstarted(event_); + function moved() { + dragged = 1; + translateTo(d3.mouse(target), l); + zoomed(event_); + } + function ended() { + w.on(mousemove, d3_window === target ? mousewheelreset : null).on(mouseup, null); + dragRestore(dragged && d3.event.target === eventTarget); + zoomended(event_); + } + } + function touchstarted() { + var target = this, event_ = event.of(target, arguments), locations0 = {}, distance0 = 0, scale0, eventId = d3.event.changedTouches[0].identifier, touchmove = "touchmove.zoom-" + eventId, touchend = "touchend.zoom-" + eventId, w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended), t = d3.select(target).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress(); + d3_selection_interrupt.call(target); + started(); + zoomstarted(event_); + function relocate() { + var touches = d3.touches(target); + scale0 = view.k; + touches.forEach(function(t) { + if (t.identifier in locations0) locations0[t.identifier] = location(t); + }); + return touches; + } + function started() { + var changed = d3.event.changedTouches; + for (var i = 0, n = changed.length; i < n; ++i) { + locations0[changed[i].identifier] = null; + } + var touches = relocate(), now = Date.now(); + if (touches.length === 1) { + if (now - touchtime < 500) { + var p = touches[0], l = locations0[p.identifier]; + scaleTo(view.k * 2); + translateTo(p, l); + d3_eventPreventDefault(); + zoomed(event_); + } + touchtime = now; + } else if (touches.length > 1) { + var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1]; + distance0 = dx * dx + dy * dy; + } + } + function moved() { + var touches = d3.touches(target), p0, l0, p1, l1; + for (var i = 0, n = touches.length; i < n; ++i, l1 = null) { + p1 = touches[i]; + if (l1 = locations0[p1.identifier]) { + if (l0) break; + p0 = p1, l0 = l1; + } + } + if (l1) { + var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0); + p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; + l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; + scaleTo(scale1 * scale0); + } + touchtime = null; + translateTo(p0, l0); + zoomed(event_); + } + function ended() { + if (d3.event.touches.length) { + var changed = d3.event.changedTouches; + for (var i = 0, n = changed.length; i < n; ++i) { + delete locations0[changed[i].identifier]; + } + for (var identifier in locations0) { + return void relocate(); + } + } + w.on(touchmove, null).on(touchend, null); + t.on(mousedown, mousedowned).on(touchstart, touchstarted); + dragRestore(); + zoomended(event_); + } + } + function mousewheeled() { + var event_ = event.of(this, arguments); + if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), + zoomstarted(event_); + mousewheelTimer = setTimeout(function() { + mousewheelTimer = null; + zoomended(event_); + }, 50); + d3_eventPreventDefault(); + var point = center || d3.mouse(this); + if (!translate0) translate0 = location(point); + scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k); + translateTo(point, translate0); + zoomed(event_); + } + function mousewheelreset() { + translate0 = null; + } + function dblclicked() { + var event_ = event.of(this, arguments), p = d3.mouse(this), l = location(p), k = Math.log(view.k) / Math.LN2; + zoomstarted(event_); + scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1)); + translateTo(p, l); + zoomed(event_); + zoomended(event_); + } + return d3.rebind(zoom, event, "on"); + }; + var d3_behavior_zoomInfinity = [ 0, Infinity ]; + var d3_behavior_zoomDelta, d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { + return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); + }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { + return d3.event.wheelDelta; + }, "mousewheel") : (d3_behavior_zoomDelta = function() { + return -d3.event.detail; + }, "MozMousePixelScroll"); + function d3_Color() {} + d3_Color.prototype.toString = function() { + return this.rgb() + ""; + }; + d3.hsl = function(h, s, l) { + return arguments.length === 1 ? h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : d3_hsl(+h, +s, +l); + }; + function d3_hsl(h, s, l) { + return new d3_Hsl(h, s, l); + } + function d3_Hsl(h, s, l) { + this.h = h; + this.s = s; + this.l = l; + } + var d3_hslPrototype = d3_Hsl.prototype = new d3_Color(); + d3_hslPrototype.brighter = function(k) { + k = Math.pow(.7, arguments.length ? k : 1); + return d3_hsl(this.h, this.s, this.l / k); + }; + d3_hslPrototype.darker = function(k) { + k = Math.pow(.7, arguments.length ? k : 1); + return d3_hsl(this.h, this.s, k * this.l); + }; + d3_hslPrototype.rgb = function() { + return d3_hsl_rgb(this.h, this.s, this.l); + }; + function d3_hsl_rgb(h, s, l) { + var m1, m2; + h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; + s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; + l = l < 0 ? 0 : l > 1 ? 1 : l; + m2 = l <= .5 ? l * (1 + s) : l + s - l * s; + m1 = 2 * l - m2; + function v(h) { + if (h > 360) h -= 360; else if (h < 0) h += 360; + if (h < 60) return m1 + (m2 - m1) * h / 60; + if (h < 180) return m2; + if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; + return m1; + } + function vv(h) { + return Math.round(v(h) * 255); + } + return d3_rgb(vv(h + 120), vv(h), vv(h - 120)); + } + d3.hcl = function(h, c, l) { + return arguments.length === 1 ? h instanceof d3_Hcl ? d3_hcl(h.h, h.c, h.l) : h instanceof d3_Lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : d3_hcl(+h, +c, +l); + }; + function d3_hcl(h, c, l) { + return new d3_Hcl(h, c, l); + } + function d3_Hcl(h, c, l) { + this.h = h; + this.c = c; + this.l = l; + } + var d3_hclPrototype = d3_Hcl.prototype = new d3_Color(); + d3_hclPrototype.brighter = function(k) { + return d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); + }; + d3_hclPrototype.darker = function(k) { + return d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); + }; + d3_hclPrototype.rgb = function() { + return d3_hcl_lab(this.h, this.c, this.l).rgb(); + }; + function d3_hcl_lab(h, c, l) { + if (isNaN(h)) h = 0; + if (isNaN(c)) c = 0; + return d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); + } + d3.lab = function(l, a, b) { + return arguments.length === 1 ? l instanceof d3_Lab ? d3_lab(l.l, l.a, l.b) : l instanceof d3_Hcl ? d3_hcl_lab(l.l, l.c, l.h) : d3_rgb_lab((l = d3.rgb(l)).r, l.g, l.b) : d3_lab(+l, +a, +b); + }; + function d3_lab(l, a, b) { + return new d3_Lab(l, a, b); + } + function d3_Lab(l, a, b) { + this.l = l; + this.a = a; + this.b = b; + } + var d3_lab_K = 18; + var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; + var d3_labPrototype = d3_Lab.prototype = new d3_Color(); + d3_labPrototype.brighter = function(k) { + return d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); + }; + d3_labPrototype.darker = function(k) { + return d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); + }; + d3_labPrototype.rgb = function() { + return d3_lab_rgb(this.l, this.a, this.b); + }; + function d3_lab_rgb(l, a, b) { + var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; + x = d3_lab_xyz(x) * d3_lab_X; + y = d3_lab_xyz(y) * d3_lab_Y; + z = d3_lab_xyz(z) * d3_lab_Z; + return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); + } + function d3_lab_hcl(l, a, b) { + return l > 0 ? d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : d3_hcl(NaN, NaN, l); + } + function d3_lab_xyz(x) { + return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; + } + function d3_xyz_lab(x) { + return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; + } + function d3_xyz_rgb(r) { + return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); + } + d3.rgb = function(r, g, b) { + return arguments.length === 1 ? r instanceof d3_Rgb ? d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : d3_rgb(~~r, ~~g, ~~b); + }; + function d3_rgbNumber(value) { + return d3_rgb(value >> 16, value >> 8 & 255, value & 255); + } + function d3_rgbString(value) { + return d3_rgbNumber(value) + ""; + } + function d3_rgb(r, g, b) { + return new d3_Rgb(r, g, b); + } + function d3_Rgb(r, g, b) { + this.r = r; + this.g = g; + this.b = b; + } + var d3_rgbPrototype = d3_Rgb.prototype = new d3_Color(); + d3_rgbPrototype.brighter = function(k) { + k = Math.pow(.7, arguments.length ? k : 1); + var r = this.r, g = this.g, b = this.b, i = 30; + if (!r && !g && !b) return d3_rgb(i, i, i); + if (r && r < i) r = i; + if (g && g < i) g = i; + if (b && b < i) b = i; + return d3_rgb(Math.min(255, ~~(r / k)), Math.min(255, ~~(g / k)), Math.min(255, ~~(b / k))); + }; + d3_rgbPrototype.darker = function(k) { + k = Math.pow(.7, arguments.length ? k : 1); + return d3_rgb(~~(k * this.r), ~~(k * this.g), ~~(k * this.b)); + }; + d3_rgbPrototype.hsl = function() { + return d3_rgb_hsl(this.r, this.g, this.b); + }; + d3_rgbPrototype.toString = function() { + return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); + }; + function d3_rgb_hex(v) { + return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); + } + function d3_rgb_parse(format, rgb, hsl) { + var r = 0, g = 0, b = 0, m1, m2, name; + m1 = /([a-z]+)\((.*)\)/i.exec(format); + if (m1) { + m2 = m1[2].split(","); + switch (m1[1]) { + case "hsl": + { + return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); + } + + case "rgb": + { + return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); + } + } + } + if (name = d3_rgb_names.get(format)) return rgb(name.r, name.g, name.b); + if (format != null && format.charAt(0) === "#") { + if (format.length === 4) { + r = format.charAt(1); + r += r; + g = format.charAt(2); + g += g; + b = format.charAt(3); + b += b; + } else if (format.length === 7) { + r = format.substring(1, 3); + g = format.substring(3, 5); + b = format.substring(5, 7); + } + r = parseInt(r, 16); + g = parseInt(g, 16); + b = parseInt(b, 16); + } + return rgb(r, g, b); + } + function d3_rgb_hsl(r, g, b) { + var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; + if (d) { + s = l < .5 ? d / (max + min) : d / (2 - max - min); + if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; + h *= 60; + } else { + h = NaN; + s = l > 0 && l < 1 ? 0 : h; + } + return d3_hsl(h, s, l); + } + function d3_rgb_lab(r, g, b) { + r = d3_rgb_xyz(r); + g = d3_rgb_xyz(g); + b = d3_rgb_xyz(b); + var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); + return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); + } + function d3_rgb_xyz(r) { + return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); + } + function d3_rgb_parseNumber(c) { + var f = parseFloat(c); + return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; + } + var d3_rgb_names = d3.map({ + aliceblue: 15792383, + antiquewhite: 16444375, + aqua: 65535, + aquamarine: 8388564, + azure: 15794175, + beige: 16119260, + bisque: 16770244, + black: 0, + blanchedalmond: 16772045, + blue: 255, + blueviolet: 9055202, + brown: 10824234, + burlywood: 14596231, + cadetblue: 6266528, + chartreuse: 8388352, + chocolate: 13789470, + coral: 16744272, + cornflowerblue: 6591981, + cornsilk: 16775388, + crimson: 14423100, + cyan: 65535, + darkblue: 139, + darkcyan: 35723, + darkgoldenrod: 12092939, + darkgray: 11119017, + darkgreen: 25600, + darkgrey: 11119017, + darkkhaki: 12433259, + darkmagenta: 9109643, + darkolivegreen: 5597999, + darkorange: 16747520, + darkorchid: 10040012, + darkred: 9109504, + darksalmon: 15308410, + darkseagreen: 9419919, + darkslateblue: 4734347, + darkslategray: 3100495, + darkslategrey: 3100495, + darkturquoise: 52945, + darkviolet: 9699539, + deeppink: 16716947, + deepskyblue: 49151, + dimgray: 6908265, + dimgrey: 6908265, + dodgerblue: 2003199, + firebrick: 11674146, + floralwhite: 16775920, + forestgreen: 2263842, + fuchsia: 16711935, + gainsboro: 14474460, + ghostwhite: 16316671, + gold: 16766720, + goldenrod: 14329120, + gray: 8421504, + green: 32768, + greenyellow: 11403055, + grey: 8421504, + honeydew: 15794160, + hotpink: 16738740, + indianred: 13458524, + indigo: 4915330, + ivory: 16777200, + khaki: 15787660, + lavender: 15132410, + lavenderblush: 16773365, + lawngreen: 8190976, + lemonchiffon: 16775885, + lightblue: 11393254, + lightcoral: 15761536, + lightcyan: 14745599, + lightgoldenrodyellow: 16448210, + lightgray: 13882323, + lightgreen: 9498256, + lightgrey: 13882323, + lightpink: 16758465, + lightsalmon: 16752762, + lightseagreen: 2142890, + lightskyblue: 8900346, + lightslategray: 7833753, + lightslategrey: 7833753, + lightsteelblue: 11584734, + lightyellow: 16777184, + lime: 65280, + limegreen: 3329330, + linen: 16445670, + magenta: 16711935, + maroon: 8388608, + mediumaquamarine: 6737322, + mediumblue: 205, + mediumorchid: 12211667, + mediumpurple: 9662683, + mediumseagreen: 3978097, + mediumslateblue: 8087790, + mediumspringgreen: 64154, + mediumturquoise: 4772300, + mediumvioletred: 13047173, + midnightblue: 1644912, + mintcream: 16121850, + mistyrose: 16770273, + moccasin: 16770229, + navajowhite: 16768685, + navy: 128, + oldlace: 16643558, + olive: 8421376, + olivedrab: 7048739, + orange: 16753920, + orangered: 16729344, + orchid: 14315734, + palegoldenrod: 15657130, + palegreen: 10025880, + paleturquoise: 11529966, + palevioletred: 14381203, + papayawhip: 16773077, + peachpuff: 16767673, + peru: 13468991, + pink: 16761035, + plum: 14524637, + powderblue: 11591910, + purple: 8388736, + red: 16711680, + rosybrown: 12357519, + royalblue: 4286945, + saddlebrown: 9127187, + salmon: 16416882, + sandybrown: 16032864, + seagreen: 3050327, + seashell: 16774638, + sienna: 10506797, + silver: 12632256, + skyblue: 8900331, + slateblue: 6970061, + slategray: 7372944, + slategrey: 7372944, + snow: 16775930, + springgreen: 65407, + steelblue: 4620980, + tan: 13808780, + teal: 32896, + thistle: 14204888, + tomato: 16737095, + turquoise: 4251856, + violet: 15631086, + wheat: 16113331, + white: 16777215, + whitesmoke: 16119285, + yellow: 16776960, + yellowgreen: 10145074 + }); + d3_rgb_names.forEach(function(key, value) { + d3_rgb_names.set(key, d3_rgbNumber(value)); + }); + function d3_functor(v) { + return typeof v === "function" ? v : function() { + return v; + }; + } + d3.functor = d3_functor; + function d3_identity(d) { + return d; + } + d3.xhr = d3_xhrType(d3_identity); + function d3_xhrType(response) { + return function(url, mimeType, callback) { + if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, + mimeType = null; + return d3_xhr(url, mimeType, response, callback); + }; + } + function d3_xhr(url, mimeType, response, callback) { + var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null; + if (d3_window.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); + "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { + request.readyState > 3 && respond(); + }; + function respond() { + var status = request.status, result; + if (!status && request.responseText || status >= 200 && status < 300 || status === 304) { + try { + result = response.call(xhr, request); + } catch (e) { + dispatch.error.call(xhr, e); + return; + } + dispatch.load.call(xhr, result); + } else { + dispatch.error.call(xhr, request); + } + } + request.onprogress = function(event) { + var o = d3.event; + d3.event = event; + try { + dispatch.progress.call(xhr, request); + } finally { + d3.event = o; + } + }; + xhr.header = function(name, value) { + name = (name + "").toLowerCase(); + if (arguments.length < 2) return headers[name]; + if (value == null) delete headers[name]; else headers[name] = value + ""; + return xhr; + }; + xhr.mimeType = function(value) { + if (!arguments.length) return mimeType; + mimeType = value == null ? null : value + ""; + return xhr; + }; + xhr.responseType = function(value) { + if (!arguments.length) return responseType; + responseType = value; + return xhr; + }; + xhr.response = function(value) { + response = value; + return xhr; + }; + [ "get", "post" ].forEach(function(method) { + xhr[method] = function() { + return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); + }; + }); + xhr.send = function(method, data, callback) { + if (arguments.length === 2 && typeof data === "function") callback = data, data = null; + request.open(method, url, true); + if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; + if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); + if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); + if (responseType != null) request.responseType = responseType; + if (callback != null) xhr.on("error", callback).on("load", function(request) { + callback(null, request); + }); + dispatch.beforesend.call(xhr, request); + request.send(data == null ? null : data); + return xhr; + }; + xhr.abort = function() { + request.abort(); + return xhr; + }; + d3.rebind(xhr, dispatch, "on"); + return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); + } + function d3_xhr_fixCallback(callback) { + return callback.length === 1 ? function(error, request) { + callback(error == null ? request : null); + } : callback; + } + d3.dsv = function(delimiter, mimeType) { + var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); + function dsv(url, row, callback) { + if (arguments.length < 3) callback = row, row = null; + var xhr = d3.xhr(url, mimeType, callback); + xhr.row = function(_) { + return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row; + }; + return xhr.row(row); + } + function response(request) { + return dsv.parse(request.responseText); + } + function typedResponse(f) { + return function(request) { + return dsv.parse(request.responseText, f); + }; + } + dsv.parse = function(text, f) { + var o; + return dsv.parseRows(text, function(row, i) { + if (o) return o(row, i - 1); + var a = new Function("d", "return {" + row.map(function(name, i) { + return JSON.stringify(name) + ": d[" + i + "]"; + }).join(",") + "}"); + o = f ? function(row, i) { + return f(a(row), i); + } : a; + }); + }; + dsv.parseRows = function(text, f) { + var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; + function token() { + if (I >= N) return EOF; + if (eol) return eol = false, EOL; + var j = I; + if (text.charCodeAt(j) === 34) { + var i = j; + while (i++ < N) { + if (text.charCodeAt(i) === 34) { + if (text.charCodeAt(i + 1) !== 34) break; + ++i; + } + } + I = i + 2; + var c = text.charCodeAt(i + 1); + if (c === 13) { + eol = true; + if (text.charCodeAt(i + 2) === 10) ++I; + } else if (c === 10) { + eol = true; + } + return text.substring(j + 1, i).replace(/""/g, '"'); + } + while (I < N) { + var c = text.charCodeAt(I++), k = 1; + if (c === 10) eol = true; else if (c === 13) { + eol = true; + if (text.charCodeAt(I) === 10) ++I, ++k; + } else if (c !== delimiterCode) continue; + return text.substring(j, I - k); + } + return text.substring(j); + } + while ((t = token()) !== EOF) { + var a = []; + while (t !== EOL && t !== EOF) { + a.push(t); + t = token(); + } + if (f && !(a = f(a, n++))) continue; + rows.push(a); + } + return rows; + }; + dsv.format = function(rows) { + if (Array.isArray(rows[0])) return dsv.formatRows(rows); + var fieldSet = new d3_Set(), fields = []; + rows.forEach(function(row) { + for (var field in row) { + if (!fieldSet.has(field)) { + fields.push(fieldSet.add(field)); + } + } + }); + return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) { + return fields.map(function(field) { + return formatValue(row[field]); + }).join(delimiter); + })).join("\n"); + }; + dsv.formatRows = function(rows) { + return rows.map(formatRow).join("\n"); + }; + function formatRow(row) { + return row.map(formatValue).join(delimiter); + } + function formatValue(text) { + return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; + } + return dsv; + }; + d3.csv = d3.dsv(",", "text/csv"); + d3.tsv = d3.dsv(" ", "text/tab-separated-values"); + var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_active, d3_timer_frame = d3_window[d3_vendorSymbol(d3_window, "requestAnimationFrame")] || function(callback) { + setTimeout(callback, 17); + }; + d3.timer = function(callback, delay, then) { + var n = arguments.length; + if (n < 2) delay = 0; + if (n < 3) then = Date.now(); + var time = then + delay, timer = { + callback: callback, + time: time, + next: null + }; + if (d3_timer_queueTail) d3_timer_queueTail.next = timer; else d3_timer_queueHead = timer; + d3_timer_queueTail = timer; + if (!d3_timer_interval) { + d3_timer_timeout = clearTimeout(d3_timer_timeout); + d3_timer_interval = 1; + d3_timer_frame(d3_timer_step); + } + }; + function d3_timer_step() { + var now = d3_timer_mark(), delay = d3_timer_sweep() - now; + if (delay > 24) { + if (isFinite(delay)) { + clearTimeout(d3_timer_timeout); + d3_timer_timeout = setTimeout(d3_timer_step, delay); + } + d3_timer_interval = 0; + } else { + d3_timer_interval = 1; + d3_timer_frame(d3_timer_step); + } + } + d3.timer.flush = function() { + d3_timer_mark(); + d3_timer_sweep(); + }; + function d3_timer_replace(callback, delay, then) { + var n = arguments.length; + if (n < 2) delay = 0; + if (n < 3) then = Date.now(); + d3_timer_active.callback = callback; + d3_timer_active.time = then + delay; + } + function d3_timer_mark() { + var now = Date.now(); + d3_timer_active = d3_timer_queueHead; + while (d3_timer_active) { + if (now >= d3_timer_active.time) d3_timer_active.flush = d3_timer_active.callback(now - d3_timer_active.time); + d3_timer_active = d3_timer_active.next; + } + return now; + } + function d3_timer_sweep() { + var t0, t1 = d3_timer_queueHead, time = Infinity; + while (t1) { + if (t1.flush) { + t1 = t0 ? t0.next = t1.next : d3_timer_queueHead = t1.next; + } else { + if (t1.time < time) time = t1.time; + t1 = (t0 = t1).next; + } + } + d3_timer_queueTail = t0; + return time; + } + var d3_format_decimalPoint = ".", d3_format_thousandsSeparator = ",", d3_format_grouping = [ 3, 3 ], d3_format_currencySymbol = "$"; + var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); + d3.formatPrefix = function(value, precision) { + var i = 0; + if (value) { + if (value < 0) value *= -1; + if (precision) value = d3.round(value, d3_format_precision(value, precision)); + i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); + i = Math.max(-24, Math.min(24, Math.floor((i <= 0 ? i + 1 : i - 1) / 3) * 3)); + } + return d3_formatPrefixes[8 + i / 3]; + }; + function d3_formatPrefix(d, i) { + var k = Math.pow(10, Math.abs(8 - i) * 3); + return { + scale: i > 8 ? function(d) { + return d / k; + } : function(d) { + return d * k; + }, + symbol: d + }; + } + d3.round = function(x, n) { + return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); + }; + d3.format = function(specifier) { + var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, suffix = "", integer = false; + if (precision) precision = +precision.substring(1); + if (zfill || fill === "0" && align === "=") { + zfill = fill = "0"; + align = "="; + if (comma) width -= Math.floor((width - 1) / 4); + } + switch (type) { + case "n": + comma = true; + type = "g"; + break; + + case "%": + scale = 100; + suffix = "%"; + type = "f"; + break; + + case "p": + scale = 100; + suffix = "%"; + type = "r"; + break; + + case "b": + case "o": + case "x": + case "X": + if (symbol === "#") symbol = "0" + type.toLowerCase(); + + case "c": + case "d": + integer = true; + precision = 0; + break; + + case "s": + scale = -1; + type = "r"; + break; + } + if (symbol === "#") symbol = ""; else if (symbol === "$") symbol = d3_format_currencySymbol; + if (type == "r" && !precision) type = "g"; + if (precision != null) { + if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); + } + type = d3_format_types.get(type) || d3_format_typeDefault; + var zcomma = zfill && comma; + return function(value) { + if (integer && value % 1) return ""; + var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign; + if (scale < 0) { + var prefix = d3.formatPrefix(value, precision); + value = prefix.scale(value); + suffix = prefix.symbol; + } else { + value *= scale; + } + value = type(value, precision); + var i = value.lastIndexOf("."), before = i < 0 ? value : value.substring(0, i), after = i < 0 ? "" : d3_format_decimalPoint + value.substring(i + 1); + if (!zfill && comma) before = d3_format_group(before); + var length = symbol.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; + if (zcomma) before = d3_format_group(padding + before); + negative += symbol; + value = before + after; + return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + suffix; + }; + }; + var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; + var d3_format_types = d3.map({ + b: function(x) { + return x.toString(2); + }, + c: function(x) { + return String.fromCharCode(x); + }, + o: function(x) { + return x.toString(8); + }, + x: function(x) { + return x.toString(16); + }, + X: function(x) { + return x.toString(16).toUpperCase(); + }, + g: function(x, p) { + return x.toPrecision(p); + }, + e: function(x, p) { + return x.toExponential(p); + }, + f: function(x, p) { + return x.toFixed(p); + }, + r: function(x, p) { + return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); + } + }); + function d3_format_precision(x, p) { + return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); + } + function d3_format_typeDefault(x) { + return x + ""; + } + var d3_format_group = d3_identity; + if (d3_format_grouping) { + var d3_format_groupingLength = d3_format_grouping.length; + d3_format_group = function(value) { + var i = value.length, t = [], j = 0, g = d3_format_grouping[0]; + while (i > 0 && g > 0) { + t.push(value.substring(i -= g, i + g)); + g = d3_format_grouping[j = (j + 1) % d3_format_groupingLength]; + } + return t.reverse().join(d3_format_thousandsSeparator); + }; + } + d3.geo = {}; + function d3_adder() {} + d3_adder.prototype = { + s: 0, + t: 0, + add: function(y) { + d3_adderSum(y, this.t, d3_adderTemp); + d3_adderSum(d3_adderTemp.s, this.s, this); + if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t; + }, + reset: function() { + this.s = this.t = 0; + }, + valueOf: function() { + return this.s; + } + }; + var d3_adderTemp = new d3_adder(); + function d3_adderSum(a, b, o) { + var x = o.s = a + b, bv = x - a, av = x - bv; + o.t = a - av + (b - bv); + } + d3.geo.stream = function(object, listener) { + if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { + d3_geo_streamObjectType[object.type](object, listener); + } else { + d3_geo_streamGeometry(object, listener); + } + }; + function d3_geo_streamGeometry(geometry, listener) { + if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { + d3_geo_streamGeometryType[geometry.type](geometry, listener); + } + } + var d3_geo_streamObjectType = { + Feature: function(feature, listener) { + d3_geo_streamGeometry(feature.geometry, listener); + }, + FeatureCollection: function(object, listener) { + var features = object.features, i = -1, n = features.length; + while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); + } + }; + var d3_geo_streamGeometryType = { + Sphere: function(object, listener) { + listener.sphere(); + }, + Point: function(object, listener) { + object = object.coordinates; + listener.point(object[0], object[1], object[2]); + }, + MultiPoint: function(object, listener) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]); + }, + LineString: function(object, listener) { + d3_geo_streamLine(object.coordinates, listener, 0); + }, + MultiLineString: function(object, listener) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); + }, + Polygon: function(object, listener) { + d3_geo_streamPolygon(object.coordinates, listener); + }, + MultiPolygon: function(object, listener) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); + }, + GeometryCollection: function(object, listener) { + var geometries = object.geometries, i = -1, n = geometries.length; + while (++i < n) d3_geo_streamGeometry(geometries[i], listener); + } + }; + function d3_geo_streamLine(coordinates, listener, closed) { + var i = -1, n = coordinates.length - closed, coordinate; + listener.lineStart(); + while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]); + listener.lineEnd(); + } + function d3_geo_streamPolygon(coordinates, listener) { + var i = -1, n = coordinates.length; + listener.polygonStart(); + while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); + listener.polygonEnd(); + } + d3.geo.area = function(object) { + d3_geo_areaSum = 0; + d3.geo.stream(object, d3_geo_area); + return d3_geo_areaSum; + }; + var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder(); + var d3_geo_area = { + sphere: function() { + d3_geo_areaSum += 4 * π; + }, + point: d3_noop, + lineStart: d3_noop, + lineEnd: d3_noop, + polygonStart: function() { + d3_geo_areaRingSum.reset(); + d3_geo_area.lineStart = d3_geo_areaRingStart; + }, + polygonEnd: function() { + var area = 2 * d3_geo_areaRingSum; + d3_geo_areaSum += area < 0 ? 4 * π + area : area; + d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; + } + }; + function d3_geo_areaRingStart() { + var λ00, φ00, λ0, cosφ0, sinφ0; + d3_geo_area.point = function(λ, φ) { + d3_geo_area.point = nextPoint; + λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), + sinφ0 = Math.sin(φ); + }; + function nextPoint(λ, φ) { + λ *= d3_radians; + φ = φ * d3_radians / 2 + π / 4; + var dλ = λ - λ0, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(dλ), v = k * Math.sin(dλ); + d3_geo_areaRingSum.add(Math.atan2(v, u)); + λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; + } + d3_geo_area.lineEnd = function() { + nextPoint(λ00, φ00); + }; + } + function d3_geo_cartesian(spherical) { + var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); + return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; + } + function d3_geo_cartesianDot(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + } + function d3_geo_cartesianCross(a, b) { + return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; + } + function d3_geo_cartesianAdd(a, b) { + a[0] += b[0]; + a[1] += b[1]; + a[2] += b[2]; + } + function d3_geo_cartesianScale(vector, k) { + return [ vector[0] * k, vector[1] * k, vector[2] * k ]; + } + function d3_geo_cartesianNormalize(d) { + var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); + d[0] /= l; + d[1] /= l; + d[2] /= l; + } + function d3_geo_spherical(cartesian) { + return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ]; + } + function d3_geo_sphericalEqual(a, b) { + return Math.abs(a[0] - b[0]) < ε && Math.abs(a[1] - b[1]) < ε; + } + d3.geo.bounds = function() { + var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range; + var bound = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + bound.point = ringPoint; + bound.lineStart = ringStart; + bound.lineEnd = ringEnd; + dλSum = 0; + d3_geo_area.polygonStart(); + }, + polygonEnd: function() { + d3_geo_area.polygonEnd(); + bound.point = point; + bound.lineStart = lineStart; + bound.lineEnd = lineEnd; + if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90; + range[0] = λ0, range[1] = λ1; + } + }; + function point(λ, φ) { + ranges.push(range = [ λ0 = λ, λ1 = λ ]); + if (φ < φ0) φ0 = φ; + if (φ > φ1) φ1 = φ; + } + function linePoint(λ, φ) { + var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]); + if (p0) { + var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal); + d3_geo_cartesianNormalize(inflection); + inflection = d3_geo_spherical(inflection); + var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = Math.abs(dλ) > 180; + if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { + var φi = inflection[1] * d3_degrees; + if (φi > φ1) φ1 = φi; + } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { + var φi = -inflection[1] * d3_degrees; + if (φi < φ0) φ0 = φi; + } else { + if (φ < φ0) φ0 = φ; + if (φ > φ1) φ1 = φ; + } + if (antimeridian) { + if (λ < λ_) { + if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; + } else { + if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; + } + } else { + if (λ1 >= λ0) { + if (λ < λ0) λ0 = λ; + if (λ > λ1) λ1 = λ; + } else { + if (λ > λ_) { + if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; + } else { + if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; + } + } + } + } else { + point(λ, φ); + } + p0 = p, λ_ = λ; + } + function lineStart() { + bound.point = linePoint; + } + function lineEnd() { + range[0] = λ0, range[1] = λ1; + bound.point = point; + p0 = null; + } + function ringPoint(λ, φ) { + if (p0) { + var dλ = λ - λ_; + dλSum += Math.abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; + } else λ__ = λ, φ__ = φ; + d3_geo_area.point(λ, φ); + linePoint(λ, φ); + } + function ringStart() { + d3_geo_area.lineStart(); + } + function ringEnd() { + ringPoint(λ__, φ__); + d3_geo_area.lineEnd(); + if (Math.abs(dλSum) > ε) λ0 = -(λ1 = 180); + range[0] = λ0, range[1] = λ1; + p0 = null; + } + function angle(λ0, λ1) { + return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; + } + function compareRanges(a, b) { + return a[0] - b[0]; + } + function withinRange(x, range) { + return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; + } + return function(feature) { + φ1 = λ1 = -(λ0 = φ0 = Infinity); + ranges = []; + d3.geo.stream(feature, bound); + var n = ranges.length; + if (n) { + ranges.sort(compareRanges); + for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) { + b = ranges[i]; + if (withinRange(b[0], a) || withinRange(b[1], a)) { + if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; + if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; + } else { + merged.push(a = b); + } + } + var best = -Infinity, dλ; + for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { + b = merged[i]; + if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; + } + } + ranges = range = null; + return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ]; + }; + }(); + d3.geo.centroid = function(object) { + d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; + d3.geo.stream(object, d3_geo_centroid); + var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z; + if (m < ε2) { + x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1; + if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0; + m = x * x + y * y + z * z; + if (m < ε2) return [ NaN, NaN ]; + } + return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ]; + }; + var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2; + var d3_geo_centroid = { + sphere: d3_noop, + point: d3_geo_centroidPoint, + lineStart: d3_geo_centroidLineStart, + lineEnd: d3_geo_centroidLineEnd, + polygonStart: function() { + d3_geo_centroid.lineStart = d3_geo_centroidRingStart; + }, + polygonEnd: function() { + d3_geo_centroid.lineStart = d3_geo_centroidLineStart; + } + }; + function d3_geo_centroidPoint(λ, φ) { + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians); + d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ)); + } + function d3_geo_centroidPointXYZ(x, y, z) { + ++d3_geo_centroidW0; + d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0; + d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0; + d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0; + } + function d3_geo_centroidLineStart() { + var x0, y0, z0; + d3_geo_centroid.point = function(λ, φ) { + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians); + x0 = cosφ * Math.cos(λ); + y0 = cosφ * Math.sin(λ); + z0 = Math.sin(φ); + d3_geo_centroid.point = nextPoint; + d3_geo_centroidPointXYZ(x0, y0, z0); + }; + function nextPoint(λ, φ) { + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); + d3_geo_centroidW1 += w; + d3_geo_centroidX1 += w * (x0 + (x0 = x)); + d3_geo_centroidY1 += w * (y0 + (y0 = y)); + d3_geo_centroidZ1 += w * (z0 + (z0 = z)); + d3_geo_centroidPointXYZ(x0, y0, z0); + } + } + function d3_geo_centroidLineEnd() { + d3_geo_centroid.point = d3_geo_centroidPoint; + } + function d3_geo_centroidRingStart() { + var λ00, φ00, x0, y0, z0; + d3_geo_centroid.point = function(λ, φ) { + λ00 = λ, φ00 = φ; + d3_geo_centroid.point = nextPoint; + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians); + x0 = cosφ * Math.cos(λ); + y0 = cosφ * Math.sin(λ); + z0 = Math.sin(φ); + d3_geo_centroidPointXYZ(x0, y0, z0); + }; + d3_geo_centroid.lineEnd = function() { + nextPoint(λ00, φ00); + d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; + d3_geo_centroid.point = d3_geo_centroidPoint; + }; + function nextPoint(λ, φ) { + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u); + d3_geo_centroidX2 += v * cx; + d3_geo_centroidY2 += v * cy; + d3_geo_centroidZ2 += v * cz; + d3_geo_centroidW1 += w; + d3_geo_centroidX1 += w * (x0 + (x0 = x)); + d3_geo_centroidY1 += w * (y0 + (y0 = y)); + d3_geo_centroidZ1 += w * (z0 + (z0 = z)); + d3_geo_centroidPointXYZ(x0, y0, z0); + } + } + function d3_true() { + return true; + } + function d3_geo_clipPolygon(segments, compare, inside, interpolate, listener) { + var subject = [], clip = []; + segments.forEach(function(segment) { + if ((n = segment.length - 1) <= 0) return; + var n, p0 = segment[0], p1 = segment[n]; + if (d3_geo_sphericalEqual(p0, p1)) { + listener.lineStart(); + for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); + listener.lineEnd(); + return; + } + var a = { + point: p0, + points: segment, + other: null, + visited: false, + entry: true, + subject: true + }, b = { + point: p0, + points: [ p0 ], + other: a, + visited: false, + entry: false, + subject: false + }; + a.other = b; + subject.push(a); + clip.push(b); + a = { + point: p1, + points: [ p1 ], + other: null, + visited: false, + entry: false, + subject: true + }; + b = { + point: p1, + points: [ p1 ], + other: a, + visited: false, + entry: true, + subject: false + }; + a.other = b; + subject.push(a); + clip.push(b); + }); + clip.sort(compare); + d3_geo_clipPolygonLinkCircular(subject); + d3_geo_clipPolygonLinkCircular(clip); + if (!subject.length) return; + if (inside) for (var i = 1, e = !inside(clip[0].point), n = clip.length; i < n; ++i) { + clip[i].entry = e = !e; + } + var start = subject[0], current, points, point; + while (1) { + current = start; + while (current.visited) if ((current = current.next) === start) return; + points = current.points; + listener.lineStart(); + do { + current.visited = current.other.visited = true; + if (current.entry) { + if (current.subject) { + for (var i = 0; i < points.length; i++) listener.point((point = points[i])[0], point[1]); + } else { + interpolate(current.point, current.next.point, 1, listener); + } + current = current.next; + } else { + if (current.subject) { + points = current.prev.points; + for (var i = points.length; --i >= 0; ) listener.point((point = points[i])[0], point[1]); + } else { + interpolate(current.point, current.prev.point, -1, listener); + } + current = current.prev; + } + current = current.other; + points = current.points; + } while (!current.visited); + listener.lineEnd(); + } + } + function d3_geo_clipPolygonLinkCircular(array) { + if (!(n = array.length)) return; + var n, i = 0, a = array[0], b; + while (++i < n) { + a.next = b = array[i]; + b.prev = a; + a = b; + } + a.next = b = array[0]; + b.prev = a; + } + function d3_geo_clip(pointVisible, clipLine, interpolate, polygonContains) { + return function(listener) { + var line = clipLine(listener); + var clip = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + clip.point = pointRing; + clip.lineStart = ringStart; + clip.lineEnd = ringEnd; + segments = []; + polygon = []; + listener.polygonStart(); + }, + polygonEnd: function() { + clip.point = point; + clip.lineStart = lineStart; + clip.lineEnd = lineEnd; + segments = d3.merge(segments); + if (segments.length) { + d3_geo_clipPolygon(segments, d3_geo_clipSort, null, interpolate, listener); + } else if (polygonContains(polygon)) { + listener.lineStart(); + interpolate(null, null, 1, listener); + listener.lineEnd(); + } + listener.polygonEnd(); + segments = polygon = null; + }, + sphere: function() { + listener.polygonStart(); + listener.lineStart(); + interpolate(null, null, 1, listener); + listener.lineEnd(); + listener.polygonEnd(); + } + }; + function point(λ, φ) { + if (pointVisible(λ, φ)) listener.point(λ, φ); + } + function pointLine(λ, φ) { + line.point(λ, φ); + } + function lineStart() { + clip.point = pointLine; + line.lineStart(); + } + function lineEnd() { + clip.point = point; + line.lineEnd(); + } + var segments; + var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygon, ring; + function pointRing(λ, φ) { + ringListener.point(λ, φ); + ring.push([ λ, φ ]); + } + function ringStart() { + ringListener.lineStart(); + ring = []; + } + function ringEnd() { + pointRing(ring[0][0], ring[0][1]); + ringListener.lineEnd(); + var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; + ring.pop(); + polygon.push(ring); + ring = null; + if (!n) return; + if (clean & 1) { + segment = ringSegments[0]; + var n = segment.length - 1, i = -1, point; + listener.lineStart(); + while (++i < n) listener.point((point = segment[i])[0], point[1]); + listener.lineEnd(); + return; + } + if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); + segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); + } + return clip; + }; + } + function d3_geo_clipSegmentLength1(segment) { + return segment.length > 1; + } + function d3_geo_clipBufferListener() { + var lines = [], line; + return { + lineStart: function() { + lines.push(line = []); + }, + point: function(λ, φ) { + line.push([ λ, φ ]); + }, + lineEnd: d3_noop, + buffer: function() { + var buffer = lines; + lines = []; + line = null; + return buffer; + }, + rejoin: function() { + if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); + } + }; + } + function d3_geo_clipSort(a, b) { + return ((a = a.point)[0] < 0 ? a[1] - π / 2 - ε : π / 2 - a[1]) - ((b = b.point)[0] < 0 ? b[1] - π / 2 - ε : π / 2 - b[1]); + } + function d3_geo_pointInPolygon(point, polygon) { + var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0; + d3_geo_areaRingSum.reset(); + for (var i = 0, n = polygon.length; i < n; ++i) { + var ring = polygon[i], m = ring.length; + if (!m) continue; + var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1; + while (true) { + if (j === m) j = 0; + point = ring[j]; + var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, antimeridian = Math.abs(dλ) > π, k = sinφ0 * sinφ; + d3_geo_areaRingSum.add(Math.atan2(k * Math.sin(dλ), cosφ0 * cosφ + k * Math.cos(dλ))); + polarAngle += antimeridian ? dλ + (dλ >= 0 ? 2 : -2) * π : dλ; + if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) { + var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point)); + d3_geo_cartesianNormalize(arc); + var intersection = d3_geo_cartesianCross(meridianNormal, arc); + d3_geo_cartesianNormalize(intersection); + var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]); + if (parallel > φarc) { + winding += antimeridian ^ dλ >= 0 ? 1 : -1; + } + } + if (!j++) break; + λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point; + } + } + return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1; + } + var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, d3_geo_clipAntimeridianPolygonContains); + function d3_geo_clipAntimeridianLine(listener) { + var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; + return { + lineStart: function() { + listener.lineStart(); + clean = 1; + }, + point: function(λ1, φ1) { + var sλ1 = λ1 > 0 ? π : -π, dλ = Math.abs(λ1 - λ0); + if (Math.abs(dλ - π) < ε) { + listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? π / 2 : -π / 2); + listener.point(sλ0, φ0); + listener.lineEnd(); + listener.lineStart(); + listener.point(sλ1, φ0); + listener.point(λ1, φ0); + clean = 0; + } else if (sλ0 !== sλ1 && dλ >= π) { + if (Math.abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; + if (Math.abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; + φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); + listener.point(sλ0, φ0); + listener.lineEnd(); + listener.lineStart(); + listener.point(sλ1, φ0); + clean = 0; + } + listener.point(λ0 = λ1, φ0 = φ1); + sλ0 = sλ1; + }, + lineEnd: function() { + listener.lineEnd(); + λ0 = φ0 = NaN; + }, + clean: function() { + return 2 - clean; + } + }; + } + function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { + var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); + return Math.abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; + } + function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { + var φ; + if (from == null) { + φ = direction * π / 2; + listener.point(-π, φ); + listener.point(0, φ); + listener.point(π, φ); + listener.point(π, 0); + listener.point(π, -φ); + listener.point(0, -φ); + listener.point(-π, -φ); + listener.point(-π, 0); + listener.point(-π, φ); + } else if (Math.abs(from[0] - to[0]) > ε) { + var s = (from[0] < to[0] ? 1 : -1) * π; + φ = direction * s / 2; + listener.point(-s, φ); + listener.point(0, φ); + listener.point(s, φ); + } else { + listener.point(to[0], to[1]); + } + } + var d3_geo_clipAntimeridianPoint = [ -π, 0 ]; + function d3_geo_clipAntimeridianPolygonContains(polygon) { + return d3_geo_pointInPolygon(d3_geo_clipAntimeridianPoint, polygon); + } + function d3_geo_clipCircle(radius) { + var cr = Math.cos(radius), smallRadius = cr > 0, point = [ radius, 0 ], notHemisphere = Math.abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); + return d3_geo_clip(visible, clipLine, interpolate, polygonContains); + function visible(λ, φ) { + return Math.cos(λ) * Math.cos(φ) > cr; + } + function clipLine(listener) { + var point0, c0, v0, v00, clean; + return { + lineStart: function() { + v00 = v0 = false; + clean = 1; + }, + point: function(λ, φ) { + var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0; + if (!point0 && (v00 = v0 = v)) listener.lineStart(); + if (v !== v0) { + point2 = intersect(point0, point1); + if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { + point1[0] += ε; + point1[1] += ε; + v = visible(point1[0], point1[1]); + } + } + if (v !== v0) { + clean = 0; + if (v) { + listener.lineStart(); + point2 = intersect(point1, point0); + listener.point(point2[0], point2[1]); + } else { + point2 = intersect(point0, point1); + listener.point(point2[0], point2[1]); + listener.lineEnd(); + } + point0 = point2; + } else if (notHemisphere && point0 && smallRadius ^ v) { + var t; + if (!(c & c0) && (t = intersect(point1, point0, true))) { + clean = 0; + if (smallRadius) { + listener.lineStart(); + listener.point(t[0][0], t[0][1]); + listener.point(t[1][0], t[1][1]); + listener.lineEnd(); + } else { + listener.point(t[1][0], t[1][1]); + listener.lineEnd(); + listener.lineStart(); + listener.point(t[0][0], t[0][1]); + } + } + } + if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { + listener.point(point1[0], point1[1]); + } + point0 = point1, v0 = v, c0 = c; + }, + lineEnd: function() { + if (v0) listener.lineEnd(); + point0 = null; + }, + clean: function() { + return clean | (v00 && v0) << 1; + } + }; + } + function intersect(a, b, two) { + var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b); + var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; + if (!determinant) return !two && a; + var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); + d3_geo_cartesianAdd(A, B); + var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); + if (t2 < 0) return; + var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu); + d3_geo_cartesianAdd(q, A); + q = d3_geo_spherical(q); + if (!two) return q; + var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z; + if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; + var δλ = λ1 - λ0, polar = Math.abs(δλ - π) < ε, meridian = polar || δλ < ε; + if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; + if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (Math.abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) { + var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); + d3_geo_cartesianAdd(q1, A); + return [ q, d3_geo_spherical(q1) ]; + } + } + function code(λ, φ) { + var r = smallRadius ? radius : π - radius, code = 0; + if (λ < -r) code |= 1; else if (λ > r) code |= 2; + if (φ < -r) code |= 4; else if (φ > r) code |= 8; + return code; + } + function polygonContains(polygon) { + return d3_geo_pointInPolygon(point, polygon); + } + } + var d3_geo_clipExtentMAX = 1e9; + d3.geo.clipExtent = function() { + var x0, y0, x1, y1, stream, clip, clipExtent = { + stream: function(output) { + if (stream) stream.valid = false; + stream = clip(output); + stream.valid = true; + return stream; + }, + extent: function(_) { + if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; + clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]); + if (stream) stream.valid = false, stream = null; + return clipExtent; + } + }; + return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]); + }; + function d3_geo_clipExtent(x0, y0, x1, y1) { + return function(listener) { + var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), segments, polygon, ring; + var clip = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + listener = bufferListener; + segments = []; + polygon = []; + }, + polygonEnd: function() { + listener = listener_; + if ((segments = d3.merge(segments)).length) { + listener.polygonStart(); + d3_geo_clipPolygon(segments, compare, inside, interpolate, listener); + listener.polygonEnd(); + } else if (insidePolygon([ x0, y0 ])) { + listener.polygonStart(), listener.lineStart(); + interpolate(null, null, 1, listener); + listener.lineEnd(), listener.polygonEnd(); + } + segments = polygon = ring = null; + } + }; + function inside(point) { + var a = corner(point, -1), i = insidePolygon([ a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0 ]); + return i; + } + function insidePolygon(p) { + var wn = 0, n = polygon.length, y = p[1]; + for (var i = 0; i < n; ++i) { + for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { + b = v[j]; + if (a[1] <= y) { + if (b[1] > y && isLeft(a, b, p) > 0) ++wn; + } else { + if (b[1] <= y && isLeft(a, b, p) < 0) --wn; + } + a = b; + } + } + return wn !== 0; + } + function isLeft(a, b, c) { + return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]); + } + function interpolate(from, to, direction, listener) { + var a = 0, a1 = 0; + if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { + do { + listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); + } while ((a = (a + direction + 4) % 4) !== a1); + } else { + listener.point(to[0], to[1]); + } + } + function visible(x, y) { + return x0 <= x && x <= x1 && y0 <= y && y <= y1; + } + function point(x, y) { + if (visible(x, y)) listener.point(x, y); + } + var x__, y__, v__, x_, y_, v_, first; + function lineStart() { + clip.point = linePoint; + if (polygon) polygon.push(ring = []); + first = true; + v_ = false; + x_ = y_ = NaN; + } + function lineEnd() { + if (segments) { + linePoint(x__, y__); + if (v__ && v_) bufferListener.rejoin(); + segments.push(bufferListener.buffer()); + } + clip.point = point; + if (v_) listener.lineEnd(); + } + function linePoint(x, y) { + x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x)); + y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y)); + var v = visible(x, y); + if (polygon) ring.push([ x, y ]); + if (first) { + x__ = x, y__ = y, v__ = v; + first = false; + if (v) { + listener.lineStart(); + listener.point(x, y); + } + } else { + if (v && v_) listener.point(x, y); else { + var a = [ x_, y_ ], b = [ x, y ]; + if (clipLine(a, b)) { + if (!v_) { + listener.lineStart(); + listener.point(a[0], a[1]); + } + listener.point(b[0], b[1]); + if (!v) listener.lineEnd(); + } else if (v) { + listener.lineStart(); + listener.point(x, y); + } + } + } + x_ = x, y_ = y, v_ = v; + } + return clip; + }; + function corner(p, direction) { + return Math.abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : Math.abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : Math.abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; + } + function compare(a, b) { + return comparePoints(a.point, b.point); + } + function comparePoints(a, b) { + var ca = corner(a, 1), cb = corner(b, 1); + return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; + } + function clipLine(a, b) { + var dx = b[0] - a[0], dy = b[1] - a[1], t = [ 0, 1 ]; + if (Math.abs(dx) < ε && Math.abs(dy) < ε) return x0 <= a[0] && a[0] <= x1 && y0 <= a[1] && a[1] <= y1; + if (d3_geo_clipExtentT(x0 - a[0], dx, t) && d3_geo_clipExtentT(a[0] - x1, -dx, t) && d3_geo_clipExtentT(y0 - a[1], dy, t) && d3_geo_clipExtentT(a[1] - y1, -dy, t)) { + if (t[1] < 1) { + b[0] = a[0] + t[1] * dx; + b[1] = a[1] + t[1] * dy; + } + if (t[0] > 0) { + a[0] += t[0] * dx; + a[1] += t[0] * dy; + } + return true; + } + return false; + } + } + function d3_geo_clipExtentT(num, denominator, t) { + if (Math.abs(denominator) < ε) return num <= 0; + var u = num / denominator; + if (denominator > 0) { + if (u > t[1]) return false; + if (u > t[0]) t[0] = u; + } else { + if (u < t[0]) return false; + if (u < t[1]) t[1] = u; + } + return true; + } + function d3_geo_compose(a, b) { + function compose(x, y) { + return x = a(x, y), b(x[0], x[1]); + } + if (a.invert && b.invert) compose.invert = function(x, y) { + return x = b.invert(x, y), x && a.invert(x[0], x[1]); + }; + return compose; + } + function d3_geo_conic(projectAt) { + var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1); + p.parallels = function(_) { + if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ]; + return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180); + }; + return p; + } + function d3_geo_conicEqualArea(φ0, φ1) { + var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n; + function forward(λ, φ) { + var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; + return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ]; + } + forward.invert = function(x, y) { + var ρ0_y = ρ0 - y; + return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ]; + }; + return forward; + } + (d3.geo.conicEqualArea = function() { + return d3_geo_conic(d3_geo_conicEqualArea); + }).raw = d3_geo_conicEqualArea; + d3.geo.albers = function() { + return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070); + }; + d3.geo.albersUsa = function() { + var lower48 = d3.geo.albers(); + var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]); + var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]); + var point, pointStream = { + point: function(x, y) { + point = [ x, y ]; + } + }, lower48Point, alaskaPoint, hawaiiPoint; + function albersUsa(coordinates) { + var x = coordinates[0], y = coordinates[1]; + point = null; + (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y); + return point; + } + albersUsa.invert = function(coordinates) { + var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k; + return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates); + }; + albersUsa.stream = function(stream) { + var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream); + return { + point: function(x, y) { + lower48Stream.point(x, y); + alaskaStream.point(x, y); + hawaiiStream.point(x, y); + }, + sphere: function() { + lower48Stream.sphere(); + alaskaStream.sphere(); + hawaiiStream.sphere(); + }, + lineStart: function() { + lower48Stream.lineStart(); + alaskaStream.lineStart(); + hawaiiStream.lineStart(); + }, + lineEnd: function() { + lower48Stream.lineEnd(); + alaskaStream.lineEnd(); + hawaiiStream.lineEnd(); + }, + polygonStart: function() { + lower48Stream.polygonStart(); + alaskaStream.polygonStart(); + hawaiiStream.polygonStart(); + }, + polygonEnd: function() { + lower48Stream.polygonEnd(); + alaskaStream.polygonEnd(); + hawaiiStream.polygonEnd(); + } + }; + }; + albersUsa.precision = function(_) { + if (!arguments.length) return lower48.precision(); + lower48.precision(_); + alaska.precision(_); + hawaii.precision(_); + return albersUsa; + }; + albersUsa.scale = function(_) { + if (!arguments.length) return lower48.scale(); + lower48.scale(_); + alaska.scale(_ * .35); + hawaii.scale(_); + return albersUsa.translate(lower48.translate()); + }; + albersUsa.translate = function(_) { + if (!arguments.length) return lower48.translate(); + var k = lower48.scale(), x = +_[0], y = +_[1]; + lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point; + alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; + hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; + return albersUsa; + }; + return albersUsa.scale(1070); + }; + var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { + point: d3_noop, + lineStart: d3_noop, + lineEnd: d3_noop, + polygonStart: function() { + d3_geo_pathAreaPolygon = 0; + d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; + }, + polygonEnd: function() { + d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; + d3_geo_pathAreaSum += Math.abs(d3_geo_pathAreaPolygon / 2); + } + }; + function d3_geo_pathAreaRingStart() { + var x00, y00, x0, y0; + d3_geo_pathArea.point = function(x, y) { + d3_geo_pathArea.point = nextPoint; + x00 = x0 = x, y00 = y0 = y; + }; + function nextPoint(x, y) { + d3_geo_pathAreaPolygon += y0 * x - x0 * y; + x0 = x, y0 = y; + } + d3_geo_pathArea.lineEnd = function() { + nextPoint(x00, y00); + }; + } + var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1; + var d3_geo_pathBounds = { + point: d3_geo_pathBoundsPoint, + lineStart: d3_noop, + lineEnd: d3_noop, + polygonStart: d3_noop, + polygonEnd: d3_noop + }; + function d3_geo_pathBoundsPoint(x, y) { + if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; + if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; + if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; + if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; + } + function d3_geo_pathBuffer() { + var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = []; + var stream = { + point: point, + lineStart: function() { + stream.point = pointLineStart; + }, + lineEnd: lineEnd, + polygonStart: function() { + stream.lineEnd = lineEndPolygon; + }, + polygonEnd: function() { + stream.lineEnd = lineEnd; + stream.point = point; + }, + pointRadius: function(_) { + pointCircle = d3_geo_pathBufferCircle(_); + return stream; + }, + result: function() { + if (buffer.length) { + var result = buffer.join(""); + buffer = []; + return result; + } + } + }; + function point(x, y) { + buffer.push("M", x, ",", y, pointCircle); + } + function pointLineStart(x, y) { + buffer.push("M", x, ",", y); + stream.point = pointLine; + } + function pointLine(x, y) { + buffer.push("L", x, ",", y); + } + function lineEnd() { + stream.point = point; + } + function lineEndPolygon() { + buffer.push("Z"); + } + return stream; + } + function d3_geo_pathBufferCircle(radius) { + return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; + } + var d3_geo_pathCentroid = { + point: d3_geo_pathCentroidPoint, + lineStart: d3_geo_pathCentroidLineStart, + lineEnd: d3_geo_pathCentroidLineEnd, + polygonStart: function() { + d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; + }, + polygonEnd: function() { + d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; + d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; + d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; + } + }; + function d3_geo_pathCentroidPoint(x, y) { + d3_geo_centroidX0 += x; + d3_geo_centroidY0 += y; + ++d3_geo_centroidZ0; + } + function d3_geo_pathCentroidLineStart() { + var x0, y0; + d3_geo_pathCentroid.point = function(x, y) { + d3_geo_pathCentroid.point = nextPoint; + d3_geo_pathCentroidPoint(x0 = x, y0 = y); + }; + function nextPoint(x, y) { + var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); + d3_geo_centroidX1 += z * (x0 + x) / 2; + d3_geo_centroidY1 += z * (y0 + y) / 2; + d3_geo_centroidZ1 += z; + d3_geo_pathCentroidPoint(x0 = x, y0 = y); + } + } + function d3_geo_pathCentroidLineEnd() { + d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; + } + function d3_geo_pathCentroidRingStart() { + var x00, y00, x0, y0; + d3_geo_pathCentroid.point = function(x, y) { + d3_geo_pathCentroid.point = nextPoint; + d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y); + }; + function nextPoint(x, y) { + var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); + d3_geo_centroidX1 += z * (x0 + x) / 2; + d3_geo_centroidY1 += z * (y0 + y) / 2; + d3_geo_centroidZ1 += z; + z = y0 * x - x0 * y; + d3_geo_centroidX2 += z * (x0 + x); + d3_geo_centroidY2 += z * (y0 + y); + d3_geo_centroidZ2 += z * 3; + d3_geo_pathCentroidPoint(x0 = x, y0 = y); + } + d3_geo_pathCentroid.lineEnd = function() { + nextPoint(x00, y00); + }; + } + function d3_geo_pathContext(context) { + var pointRadius = 4.5; + var stream = { + point: point, + lineStart: function() { + stream.point = pointLineStart; + }, + lineEnd: lineEnd, + polygonStart: function() { + stream.lineEnd = lineEndPolygon; + }, + polygonEnd: function() { + stream.lineEnd = lineEnd; + stream.point = point; + }, + pointRadius: function(_) { + pointRadius = _; + return stream; + }, + result: d3_noop + }; + function point(x, y) { + context.moveTo(x, y); + context.arc(x, y, pointRadius, 0, 2 * π); + } + function pointLineStart(x, y) { + context.moveTo(x, y); + stream.point = pointLine; + } + function pointLine(x, y) { + context.lineTo(x, y); + } + function lineEnd() { + stream.point = point; + } + function lineEndPolygon() { + context.closePath(); + } + return stream; + } + function d3_geo_resample(project) { + var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16; + function resample(stream) { + var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0; + var resample = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + stream.polygonStart(); + resample.lineStart = ringStart; + }, + polygonEnd: function() { + stream.polygonEnd(); + resample.lineStart = lineStart; + } + }; + function point(x, y) { + x = project(x, y); + stream.point(x[0], x[1]); + } + function lineStart() { + x0 = NaN; + resample.point = linePoint; + stream.lineStart(); + } + function linePoint(λ, φ) { + var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); + resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); + stream.point(x0, y0); + } + function lineEnd() { + resample.point = point; + stream.lineEnd(); + } + function ringStart() { + lineStart(); + resample.point = ringPoint; + resample.lineEnd = ringEnd; + } + function ringPoint(λ, φ) { + linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; + resample.point = linePoint; + } + function ringEnd() { + resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); + resample.lineEnd = lineEnd; + lineEnd(); + } + return resample; + } + function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { + var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; + if (d2 > 4 * δ2 && depth--) { + var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; + if (dz * dz / d2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { + resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); + stream.point(x2, y2); + resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); + } + } + } + resample.precision = function(_) { + if (!arguments.length) return Math.sqrt(δ2); + maxDepth = (δ2 = _ * _) > 0 && 16; + return resample; + }; + return resample; + } + d3.geo.transform = function(methods) { + return { + stream: function(stream) { + var transform = new d3_geo_transform(stream); + for (var k in methods) transform[k] = methods[k]; + return transform; + } + }; + }; + function d3_geo_transform(stream) { + this.stream = stream; + } + d3_geo_transform.prototype = { + point: function(x, y) { + this.stream.point(x, y); + }, + sphere: function() { + this.stream.sphere(); + }, + lineStart: function() { + this.stream.lineStart(); + }, + lineEnd: function() { + this.stream.lineEnd(); + }, + polygonStart: function() { + this.stream.polygonStart(); + }, + polygonEnd: function() { + this.stream.polygonEnd(); + } + }; + d3.geo.path = function() { + var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream; + function path(object) { + if (object) { + if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); + if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream); + d3.geo.stream(object, cacheStream); + } + return contextStream.result(); + } + path.area = function(object) { + d3_geo_pathAreaSum = 0; + d3.geo.stream(object, projectStream(d3_geo_pathArea)); + return d3_geo_pathAreaSum; + }; + path.centroid = function(object) { + d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; + d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); + return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ]; + }; + path.bounds = function(object) { + d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); + d3.geo.stream(object, projectStream(d3_geo_pathBounds)); + return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ]; + }; + path.projection = function(_) { + if (!arguments.length) return projection; + projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; + return reset(); + }; + path.context = function(_) { + if (!arguments.length) return context; + contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); + if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); + return reset(); + }; + path.pointRadius = function(_) { + if (!arguments.length) return pointRadius; + pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); + return path; + }; + function reset() { + cacheStream = null; + return path; + } + return path.projection(d3.geo.albersUsa()).context(null); + }; + function d3_geo_pathProjectStream(project) { + var resample = d3_geo_resample(function(x, y) { + return project([ x * d3_degrees, y * d3_degrees ]); + }); + return function(stream) { + var transform = new d3_geo_transform(stream = resample(stream)); + transform.point = function(x, y) { + stream.point(x * d3_radians, y * d3_radians); + }; + return transform; + }; + } + d3.geo.projection = d3_geo_projection; + d3.geo.projectionMutator = d3_geo_projectionMutator; + function d3_geo_projection(project) { + return d3_geo_projectionMutator(function() { + return project; + })(); + } + function d3_geo_projectionMutator(projectAt) { + var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { + x = project(x, y); + return [ x[0] * k + δx, δy - x[1] * k ]; + }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream; + function projection(point) { + point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); + return [ point[0] * k + δx, δy - point[1] * k ]; + } + function invert(point) { + point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); + return point && [ point[0] * d3_degrees, point[1] * d3_degrees ]; + } + projection.stream = function(output) { + if (stream) stream.valid = false; + stream = d3_geo_projectionRadiansRotate(rotate, preclip(projectResample(postclip(output)))); + stream.valid = true; + return stream; + }; + projection.clipAngle = function(_) { + if (!arguments.length) return clipAngle; + preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); + return invalidate(); + }; + projection.clipExtent = function(_) { + if (!arguments.length) return clipExtent; + clipExtent = _; + postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity; + return invalidate(); + }; + projection.scale = function(_) { + if (!arguments.length) return k; + k = +_; + return reset(); + }; + projection.translate = function(_) { + if (!arguments.length) return [ x, y ]; + x = +_[0]; + y = +_[1]; + return reset(); + }; + projection.center = function(_) { + if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; + λ = _[0] % 360 * d3_radians; + φ = _[1] % 360 * d3_radians; + return reset(); + }; + projection.rotate = function(_) { + if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; + δλ = _[0] % 360 * d3_radians; + δφ = _[1] % 360 * d3_radians; + δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; + return reset(); + }; + d3.rebind(projection, projectResample, "precision"); + function reset() { + projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); + var center = project(λ, φ); + δx = x - center[0] * k; + δy = y + center[1] * k; + return invalidate(); + } + function invalidate() { + if (stream) stream.valid = false, stream = null; + return projection; + } + return function() { + project = projectAt.apply(this, arguments); + projection.invert = project.invert && invert; + return reset(); + }; + } + function d3_geo_projectionRadiansRotate(rotate, stream) { + var transform = new d3_geo_transform(stream); + transform.point = function(x, y) { + y = rotate(x * d3_radians, y * d3_radians), x = y[0]; + stream.point(x > π ? x - 2 * π : x < -π ? x + 2 * π : x, y[1]); + }; + return transform; + } + function d3_geo_equirectangular(λ, φ) { + return [ λ, φ ]; + } + (d3.geo.equirectangular = function() { + return d3_geo_projection(d3_geo_equirectangular); + }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; + d3.geo.rotation = function(rotate) { + rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); + function forward(coordinates) { + coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); + return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; + } + forward.invert = function(coordinates) { + coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); + return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; + }; + return forward; + }; + function d3_geo_rotation(δλ, δφ, δγ) { + return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_equirectangular; + } + function d3_geo_forwardRotationλ(δλ) { + return function(λ, φ) { + return λ += δλ, [ λ > π ? λ - 2 * π : λ < -π ? λ + 2 * π : λ, φ ]; + }; + } + function d3_geo_rotationλ(δλ) { + var rotation = d3_geo_forwardRotationλ(δλ); + rotation.invert = d3_geo_forwardRotationλ(-δλ); + return rotation; + } + function d3_geo_rotationφγ(δφ, δγ) { + var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); + function rotation(λ, φ) { + var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; + return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ]; + } + rotation.invert = function(λ, φ) { + var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; + return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ]; + }; + return rotation; + } + d3.geo.circle = function() { + var origin = [ 0, 0 ], angle, precision = 6, interpolate; + function circle() { + var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = []; + interpolate(null, null, 1, { + point: function(x, y) { + ring.push(x = rotate(x, y)); + x[0] *= d3_degrees, x[1] *= d3_degrees; + } + }); + return { + type: "Polygon", + coordinates: [ ring ] + }; + } + circle.origin = function(x) { + if (!arguments.length) return origin; + origin = x; + return circle; + }; + circle.angle = function(x) { + if (!arguments.length) return angle; + interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); + return circle; + }; + circle.precision = function(_) { + if (!arguments.length) return precision; + interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); + return circle; + }; + return circle.angle(90); + }; + function d3_geo_circleInterpolate(radius, precision) { + var cr = Math.cos(radius), sr = Math.sin(radius); + return function(from, to, direction, listener) { + var step = direction * precision; + if (from != null) { + from = d3_geo_circleAngle(cr, from); + to = d3_geo_circleAngle(cr, to); + if (direction > 0 ? from < to : from > to) from += direction * 2 * π; + } else { + from = radius + direction * 2 * π; + to = radius - .5 * step; + } + for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) { + listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); + } + }; + } + function d3_geo_circleAngle(cr, point) { + var a = d3_geo_cartesian(point); + a[0] -= cr; + d3_geo_cartesianNormalize(a); + var angle = d3_acos(-a[1]); + return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); + } + d3.geo.distance = function(a, b) { + var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t; + return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); + }; + d3.geo.graticule = function() { + var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5; + function graticule() { + return { + type: "MultiLineString", + coordinates: lines() + }; + } + function lines() { + return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { + return Math.abs(x % DX) > ε; + }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { + return Math.abs(y % DY) > ε; + }).map(y)); + } + graticule.lines = function() { + return lines().map(function(coordinates) { + return { + type: "LineString", + coordinates: coordinates + }; + }); + }; + graticule.outline = function() { + return { + type: "Polygon", + coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ] + }; + }; + graticule.extent = function(_) { + if (!arguments.length) return graticule.minorExtent(); + return graticule.majorExtent(_).minorExtent(_); + }; + graticule.majorExtent = function(_) { + if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ]; + X0 = +_[0][0], X1 = +_[1][0]; + Y0 = +_[0][1], Y1 = +_[1][1]; + if (X0 > X1) _ = X0, X0 = X1, X1 = _; + if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; + return graticule.precision(precision); + }; + graticule.minorExtent = function(_) { + if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; + x0 = +_[0][0], x1 = +_[1][0]; + y0 = +_[0][1], y1 = +_[1][1]; + if (x0 > x1) _ = x0, x0 = x1, x1 = _; + if (y0 > y1) _ = y0, y0 = y1, y1 = _; + return graticule.precision(precision); + }; + graticule.step = function(_) { + if (!arguments.length) return graticule.minorStep(); + return graticule.majorStep(_).minorStep(_); + }; + graticule.majorStep = function(_) { + if (!arguments.length) return [ DX, DY ]; + DX = +_[0], DY = +_[1]; + return graticule; + }; + graticule.minorStep = function(_) { + if (!arguments.length) return [ dx, dy ]; + dx = +_[0], dy = +_[1]; + return graticule; + }; + graticule.precision = function(_) { + if (!arguments.length) return precision; + precision = +_; + x = d3_geo_graticuleX(y0, y1, 90); + y = d3_geo_graticuleY(x0, x1, precision); + X = d3_geo_graticuleX(Y0, Y1, 90); + Y = d3_geo_graticuleY(X0, X1, precision); + return graticule; + }; + return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]); + }; + function d3_geo_graticuleX(y0, y1, dy) { + var y = d3.range(y0, y1 - ε, dy).concat(y1); + return function(x) { + return y.map(function(y) { + return [ x, y ]; + }); + }; + } + function d3_geo_graticuleY(x0, x1, dx) { + var x = d3.range(x0, x1 - ε, dx).concat(x1); + return function(y) { + return x.map(function(x) { + return [ x, y ]; + }); + }; + } + function d3_source(d) { + return d.source; + } + function d3_target(d) { + return d.target; + } + d3.geo.greatArc = function() { + var source = d3_source, source_, target = d3_target, target_; + function greatArc() { + return { + type: "LineString", + coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ] + }; + } + greatArc.distance = function() { + return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments)); + }; + greatArc.source = function(_) { + if (!arguments.length) return source; + source = _, source_ = typeof _ === "function" ? null : _; + return greatArc; + }; + greatArc.target = function(_) { + if (!arguments.length) return target; + target = _, target_ = typeof _ === "function" ? null : _; + return greatArc; + }; + greatArc.precision = function() { + return arguments.length ? greatArc : 0; + }; + return greatArc; + }; + d3.geo.interpolate = function(source, target) { + return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); + }; + function d3_geo_interpolate(x0, y0, x1, y1) { + var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d); + var interpolate = d ? function(t) { + var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; + return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ]; + } : function() { + return [ x0 * d3_degrees, y0 * d3_degrees ]; + }; + interpolate.distance = d; + return interpolate; + } + d3.geo.length = function(object) { + d3_geo_lengthSum = 0; + d3.geo.stream(object, d3_geo_length); + return d3_geo_lengthSum; + }; + var d3_geo_lengthSum; + var d3_geo_length = { + sphere: d3_noop, + point: d3_noop, + lineStart: d3_geo_lengthLineStart, + lineEnd: d3_noop, + polygonStart: d3_noop, + polygonEnd: d3_noop + }; + function d3_geo_lengthLineStart() { + var λ0, sinφ0, cosφ0; + d3_geo_length.point = function(λ, φ) { + λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); + d3_geo_length.point = nextPoint; + }; + d3_geo_length.lineEnd = function() { + d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; + }; + function nextPoint(λ, φ) { + var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = Math.abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t); + d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); + λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; + } + } + function d3_geo_azimuthal(scale, angle) { + function azimuthal(λ, φ) { + var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); + return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; + } + azimuthal.invert = function(x, y) { + var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c); + return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ]; + }; + return azimuthal; + } + var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { + return Math.sqrt(2 / (1 + cosλcosφ)); + }, function(ρ) { + return 2 * Math.asin(ρ / 2); + }); + (d3.geo.azimuthalEqualArea = function() { + return d3_geo_projection(d3_geo_azimuthalEqualArea); + }).raw = d3_geo_azimuthalEqualArea; + var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { + var c = Math.acos(cosλcosφ); + return c && c / Math.sin(c); + }, d3_identity); + (d3.geo.azimuthalEquidistant = function() { + return d3_geo_projection(d3_geo_azimuthalEquidistant); + }).raw = d3_geo_azimuthalEquidistant; + function d3_geo_conicConformal(φ0, φ1) { + var cosφ0 = Math.cos(φ0), t = function(φ) { + return Math.tan(π / 4 + φ / 2); + }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n; + if (!n) return d3_geo_mercator; + function forward(λ, φ) { + var ρ = Math.abs(Math.abs(φ) - π / 2) < ε ? 0 : F / Math.pow(t(φ), n); + return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ]; + } + forward.invert = function(x, y) { + var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y); + return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - π / 2 ]; + }; + return forward; + } + (d3.geo.conicConformal = function() { + return d3_geo_conic(d3_geo_conicConformal); + }).raw = d3_geo_conicConformal; + function d3_geo_conicEquidistant(φ0, φ1) { + var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0; + if (Math.abs(n) < ε) return d3_geo_equirectangular; + function forward(λ, φ) { + var ρ = G - φ; + return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ]; + } + forward.invert = function(x, y) { + var ρ0_y = G - y; + return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ]; + }; + return forward; + } + (d3.geo.conicEquidistant = function() { + return d3_geo_conic(d3_geo_conicEquidistant); + }).raw = d3_geo_conicEquidistant; + var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { + return 1 / cosλcosφ; + }, Math.atan); + (d3.geo.gnomonic = function() { + return d3_geo_projection(d3_geo_gnomonic); + }).raw = d3_geo_gnomonic; + function d3_geo_mercator(λ, φ) { + return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ]; + } + d3_geo_mercator.invert = function(x, y) { + return [ x, 2 * Math.atan(Math.exp(y)) - π / 2 ]; + }; + function d3_geo_mercatorProjection(project) { + var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto; + m.scale = function() { + var v = scale.apply(m, arguments); + return v === m ? clipAuto ? m.clipExtent(null) : m : v; + }; + m.translate = function() { + var v = translate.apply(m, arguments); + return v === m ? clipAuto ? m.clipExtent(null) : m : v; + }; + m.clipExtent = function(_) { + var v = clipExtent.apply(m, arguments); + if (v === m) { + if (clipAuto = _ == null) { + var k = π * scale(), t = translate(); + clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]); + } + } else if (clipAuto) { + v = null; + } + return v; + }; + return m.clipExtent(null); + } + (d3.geo.mercator = function() { + return d3_geo_mercatorProjection(d3_geo_mercator); + }).raw = d3_geo_mercator; + var d3_geo_orthographic = d3_geo_azimuthal(function() { + return 1; + }, Math.asin); + (d3.geo.orthographic = function() { + return d3_geo_projection(d3_geo_orthographic); + }).raw = d3_geo_orthographic; + var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { + return 1 / (1 + cosλcosφ); + }, function(ρ) { + return 2 * Math.atan(ρ); + }); + (d3.geo.stereographic = function() { + return d3_geo_projection(d3_geo_stereographic); + }).raw = d3_geo_stereographic; + function d3_geo_transverseMercator(λ, φ) { + var B = Math.cos(φ) * Math.sin(λ); + return [ Math.log((1 + B) / (1 - B)) / 2, Math.atan2(Math.tan(φ), Math.cos(λ)) ]; + } + d3_geo_transverseMercator.invert = function(x, y) { + return [ Math.atan2(d3_sinh(x), Math.cos(y)), d3_asin(Math.sin(y) / d3_cosh(x)) ]; + }; + (d3.geo.transverseMercator = function() { + return d3_geo_mercatorProjection(d3_geo_transverseMercator); + }).raw = d3_geo_transverseMercator; + d3.geom = {}; + d3.svg = {}; + function d3_svg_line(projection) { + var x = d3_svg_lineX, y = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; + function line(data) { + var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); + function segment() { + segments.push("M", interpolate(projection(points), tension)); + } + while (++i < n) { + if (defined.call(this, d = data[i], i)) { + points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); + } else if (points.length) { + segment(); + points = []; + } + } + if (points.length) segment(); + return segments.length ? segments.join("") : null; + } + line.x = function(_) { + if (!arguments.length) return x; + x = _; + return line; + }; + line.y = function(_) { + if (!arguments.length) return y; + y = _; + return line; + }; + line.defined = function(_) { + if (!arguments.length) return defined; + defined = _; + return line; + }; + line.interpolate = function(_) { + if (!arguments.length) return interpolateKey; + if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; + return line; + }; + line.tension = function(_) { + if (!arguments.length) return tension; + tension = _; + return line; + }; + return line; + } + d3.svg.line = function() { + return d3_svg_line(d3_identity); + }; + function d3_svg_lineX(d) { + return d[0]; + } + function d3_svg_lineY(d) { + return d[1]; + } + var d3_svg_lineInterpolators = d3.map({ + linear: d3_svg_lineLinear, + "linear-closed": d3_svg_lineLinearClosed, + step: d3_svg_lineStep, + "step-before": d3_svg_lineStepBefore, + "step-after": d3_svg_lineStepAfter, + basis: d3_svg_lineBasis, + "basis-open": d3_svg_lineBasisOpen, + "basis-closed": d3_svg_lineBasisClosed, + bundle: d3_svg_lineBundle, + cardinal: d3_svg_lineCardinal, + "cardinal-open": d3_svg_lineCardinalOpen, + "cardinal-closed": d3_svg_lineCardinalClosed, + monotone: d3_svg_lineMonotone + }); + d3_svg_lineInterpolators.forEach(function(key, value) { + value.key = key; + value.closed = /-closed$/.test(key); + }); + function d3_svg_lineLinear(points) { + return points.join("L"); + } + function d3_svg_lineLinearClosed(points) { + return d3_svg_lineLinear(points) + "Z"; + } + function d3_svg_lineStep(points) { + var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; + while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]); + if (n > 1) path.push("H", p[0]); + return path.join(""); + } + function d3_svg_lineStepBefore(points) { + var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; + while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); + return path.join(""); + } + function d3_svg_lineStepAfter(points) { + var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; + while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); + return path.join(""); + } + function d3_svg_lineCardinalOpen(points, tension) { + return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), d3_svg_lineCardinalTangents(points, tension)); + } + function d3_svg_lineCardinalClosed(points, tension) { + return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), + points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); + } + function d3_svg_lineCardinal(points, tension) { + return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); + } + function d3_svg_lineHermite(points, tangents) { + if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { + return d3_svg_lineLinear(points); + } + var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; + if (quad) { + path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; + p0 = points[1]; + pi = 2; + } + if (tangents.length > 1) { + t = tangents[1]; + p = points[pi]; + pi++; + path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; + for (var i = 2; i < tangents.length; i++, pi++) { + p = points[pi]; + t = tangents[i]; + path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; + } + } + if (quad) { + var lp = points[pi]; + path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; + } + return path; + } + function d3_svg_lineCardinalTangents(points, tension) { + var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; + while (++i < n) { + p0 = p1; + p1 = p2; + p2 = points[i]; + tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); + } + return tangents; + } + function d3_svg_lineBasis(points) { + if (points.length < 3) return d3_svg_lineLinear(points); + var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; + points.push(points[n - 1]); + while (++i <= n) { + pi = points[i]; + px.shift(); + px.push(pi[0]); + py.shift(); + py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + points.pop(); + path.push("L", pi); + return path.join(""); + } + function d3_svg_lineBasisOpen(points) { + if (points.length < 4) return d3_svg_lineLinear(points); + var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; + while (++i < 3) { + pi = points[i]; + px.push(pi[0]); + py.push(pi[1]); + } + path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); + --i; + while (++i < n) { + pi = points[i]; + px.shift(); + px.push(pi[0]); + py.shift(); + py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + return path.join(""); + } + function d3_svg_lineBasisClosed(points) { + var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; + while (++i < 4) { + pi = points[i % n]; + px.push(pi[0]); + py.push(pi[1]); + } + path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; + --i; + while (++i < m) { + pi = points[i % n]; + px.shift(); + px.push(pi[0]); + py.shift(); + py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + return path.join(""); + } + function d3_svg_lineBundle(points, tension) { + var n = points.length - 1; + if (n) { + var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; + while (++i <= n) { + p = points[i]; + t = i / n; + p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); + p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); + } + } + return d3_svg_lineBasis(points); + } + function d3_svg_lineDot4(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; + } + var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; + function d3_svg_lineBasisBezier(path, x, y) { + path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); + } + function d3_svg_lineSlope(p0, p1) { + return (p1[1] - p0[1]) / (p1[0] - p0[0]); + } + function d3_svg_lineFiniteDifferences(points) { + var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); + while (++i < j) { + m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; + } + m[i] = d; + return m; + } + function d3_svg_lineMonotoneTangents(points) { + var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; + while (++i < j) { + d = d3_svg_lineSlope(points[i], points[i + 1]); + if (Math.abs(d) < 1e-6) { + m[i] = m[i + 1] = 0; + } else { + a = m[i] / d; + b = m[i + 1] / d; + s = a * a + b * b; + if (s > 9) { + s = d * 3 / Math.sqrt(s); + m[i] = s * a; + m[i + 1] = s * b; + } + } + } + i = -1; + while (++i <= j) { + s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); + tangents.push([ s || 0, m[i] * s || 0 ]); + } + return tangents; + } + function d3_svg_lineMonotone(points) { + return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); + } + d3.geom.hull = function(vertices) { + var x = d3_svg_lineX, y = d3_svg_lineY; + if (arguments.length) return hull(vertices); + function hull(data) { + if (data.length < 3) return []; + var fx = d3_functor(x), fy = d3_functor(y), n = data.length, vertices, plen = n - 1, points = [], stack = [], d, i, j, h = 0, x1, y1, x2, y2, u, v, a, sp; + if (fx === d3_svg_lineX && y === d3_svg_lineY) vertices = data; else for (i = 0, + vertices = []; i < n; ++i) { + vertices.push([ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]); + } + for (i = 1; i < n; ++i) { + if (vertices[i][1] < vertices[h][1] || vertices[i][1] == vertices[h][1] && vertices[i][0] < vertices[h][0]) h = i; + } + for (i = 0; i < n; ++i) { + if (i === h) continue; + y1 = vertices[i][1] - vertices[h][1]; + x1 = vertices[i][0] - vertices[h][0]; + points.push({ + angle: Math.atan2(y1, x1), + index: i + }); + } + points.sort(function(a, b) { + return a.angle - b.angle; + }); + a = points[0].angle; + v = points[0].index; + u = 0; + for (i = 1; i < plen; ++i) { + j = points[i].index; + if (a == points[i].angle) { + x1 = vertices[v][0] - vertices[h][0]; + y1 = vertices[v][1] - vertices[h][1]; + x2 = vertices[j][0] - vertices[h][0]; + y2 = vertices[j][1] - vertices[h][1]; + if (x1 * x1 + y1 * y1 >= x2 * x2 + y2 * y2) { + points[i].index = -1; + continue; + } else { + points[u].index = -1; + } + } + a = points[i].angle; + u = i; + v = j; + } + stack.push(h); + for (i = 0, j = 0; i < 2; ++j) { + if (points[j].index > -1) { + stack.push(points[j].index); + i++; + } + } + sp = stack.length; + for (;j < plen; ++j) { + if (points[j].index < 0) continue; + while (!d3_geom_hullCCW(stack[sp - 2], stack[sp - 1], points[j].index, vertices)) { + --sp; + } + stack[sp++] = points[j].index; + } + var poly = []; + for (i = sp - 1; i >= 0; --i) poly.push(data[stack[i]]); + return poly; + } + hull.x = function(_) { + return arguments.length ? (x = _, hull) : x; + }; + hull.y = function(_) { + return arguments.length ? (y = _, hull) : y; + }; + return hull; + }; + function d3_geom_hullCCW(i1, i2, i3, v) { + var t, a, b, c, d, e, f; + t = v[i1]; + a = t[0]; + b = t[1]; + t = v[i2]; + c = t[0]; + d = t[1]; + t = v[i3]; + e = t[0]; + f = t[1]; + return (f - b) * (c - a) - (d - b) * (e - a) > 0; + } + d3.geom.polygon = function(coordinates) { + d3_subclass(coordinates, d3_geom_polygonPrototype); + return coordinates; + }; + var d3_geom_polygonPrototype = d3.geom.polygon.prototype = []; + d3_geom_polygonPrototype.area = function() { + var i = -1, n = this.length, a, b = this[n - 1], area = 0; + while (++i < n) { + a = b; + b = this[i]; + area += a[1] * b[0] - a[0] * b[1]; + } + return area * .5; + }; + d3_geom_polygonPrototype.centroid = function(k) { + var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c; + if (!arguments.length) k = -1 / (6 * this.area()); + while (++i < n) { + a = b; + b = this[i]; + c = a[0] * b[1] - b[0] * a[1]; + x += (a[0] + b[0]) * c; + y += (a[1] + b[1]) * c; + } + return [ x * k, y * k ]; + }; + d3_geom_polygonPrototype.clip = function(subject) { + var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d; + while (++i < n) { + input = subject.slice(); + subject.length = 0; + b = this[i]; + c = input[(m = input.length - closed) - 1]; + j = -1; + while (++j < m) { + d = input[j]; + if (d3_geom_polygonInside(d, a, b)) { + if (!d3_geom_polygonInside(c, a, b)) { + subject.push(d3_geom_polygonIntersect(c, d, a, b)); + } + subject.push(d); + } else if (d3_geom_polygonInside(c, a, b)) { + subject.push(d3_geom_polygonIntersect(c, d, a, b)); + } + c = d; + } + if (closed) subject.push(subject[0]); + a = b; + } + return subject; + }; + function d3_geom_polygonInside(p, a, b) { + return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); + } + function d3_geom_polygonIntersect(c, d, a, b) { + var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); + return [ x1 + ua * x21, y1 + ua * y21 ]; + } + function d3_geom_polygonClosed(coordinates) { + var a = coordinates[0], b = coordinates[coordinates.length - 1]; + return !(a[0] - b[0] || a[1] - b[1]); + } + d3.geom.delaunay = function(vertices) { + var edges = vertices.map(function() { + return []; + }), triangles = []; + d3_geom_voronoiTessellate(vertices, function(e) { + edges[e.region.l.index].push(vertices[e.region.r.index]); + }); + edges.forEach(function(edge, i) { + var v = vertices[i], cx = v[0], cy = v[1]; + edge.forEach(function(v) { + v.angle = Math.atan2(v[0] - cx, v[1] - cy); + }); + edge.sort(function(a, b) { + return a.angle - b.angle; + }); + for (var j = 0, m = edge.length - 1; j < m; j++) { + triangles.push([ v, edge[j], edge[j + 1] ]); + } + }); + return triangles; + }; + d3.geom.voronoi = function(points) { + var x = d3_svg_lineX, y = d3_svg_lineY, clipPolygon = null; + if (arguments.length) return voronoi(points); + function voronoi(data) { + var points, polygons = data.map(function() { + return []; + }), fx = d3_functor(x), fy = d3_functor(y), d, i, n = data.length, Z = 1e6; + if (fx === d3_svg_lineX && fy === d3_svg_lineY) points = data; else for (points = new Array(n), + i = 0; i < n; ++i) { + points[i] = [ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]; + } + d3_geom_voronoiTessellate(points, function(e) { + var s1, s2, x1, x2, y1, y2; + if (e.a === 1 && e.b >= 0) { + s1 = e.ep.r; + s2 = e.ep.l; + } else { + s1 = e.ep.l; + s2 = e.ep.r; + } + if (e.a === 1) { + y1 = s1 ? s1.y : -Z; + x1 = e.c - e.b * y1; + y2 = s2 ? s2.y : Z; + x2 = e.c - e.b * y2; + } else { + x1 = s1 ? s1.x : -Z; + y1 = e.c - e.a * x1; + x2 = s2 ? s2.x : Z; + y2 = e.c - e.a * x2; + } + var v1 = [ x1, y1 ], v2 = [ x2, y2 ]; + polygons[e.region.l.index].push(v1, v2); + polygons[e.region.r.index].push(v1, v2); + }); + polygons = polygons.map(function(polygon, i) { + var cx = points[i][0], cy = points[i][1], angle = polygon.map(function(v) { + return Math.atan2(v[0] - cx, v[1] - cy); + }), order = d3.range(polygon.length).sort(function(a, b) { + return angle[a] - angle[b]; + }); + return order.filter(function(d, i) { + return !i || angle[d] - angle[order[i - 1]] > ε; + }).map(function(d) { + return polygon[d]; + }); + }); + polygons.forEach(function(polygon, i) { + var n = polygon.length; + if (!n) return polygon.push([ -Z, -Z ], [ -Z, Z ], [ Z, Z ], [ Z, -Z ]); + if (n > 2) return; + var p0 = points[i], p1 = polygon[0], p2 = polygon[1], x0 = p0[0], y0 = p0[1], x1 = p1[0], y1 = p1[1], x2 = p2[0], y2 = p2[1], dx = Math.abs(x2 - x1), dy = y2 - y1; + if (Math.abs(dy) < ε) { + var y = y0 < y1 ? -Z : Z; + polygon.push([ -Z, y ], [ Z, y ]); + } else if (dx < ε) { + var x = x0 < x1 ? -Z : Z; + polygon.push([ x, -Z ], [ x, Z ]); + } else { + var y = (x2 - x1) * (y1 - y0) < (x1 - x0) * (y2 - y1) ? Z : -Z, z = Math.abs(dy) - dx; + if (Math.abs(z) < ε) { + polygon.push([ dy < 0 ? y : -y, y ]); + } else { + if (z > 0) y *= -1; + polygon.push([ -Z, y ], [ Z, y ]); + } + } + }); + if (clipPolygon) for (i = 0; i < n; ++i) clipPolygon.clip(polygons[i]); + for (i = 0; i < n; ++i) polygons[i].point = data[i]; + return polygons; + } + voronoi.x = function(_) { + return arguments.length ? (x = _, voronoi) : x; + }; + voronoi.y = function(_) { + return arguments.length ? (y = _, voronoi) : y; + }; + voronoi.clipExtent = function(_) { + if (!arguments.length) return clipPolygon && [ clipPolygon[0], clipPolygon[2] ]; + if (_ == null) clipPolygon = null; else { + var x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], y2 = +_[1][1]; + clipPolygon = d3.geom.polygon([ [ x1, y1 ], [ x1, y2 ], [ x2, y2 ], [ x2, y1 ] ]); + } + return voronoi; + }; + voronoi.size = function(_) { + if (!arguments.length) return clipPolygon && clipPolygon[2]; + return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]); + }; + voronoi.links = function(data) { + var points, graph = data.map(function() { + return []; + }), links = [], fx = d3_functor(x), fy = d3_functor(y), d, i, n = data.length; + if (fx === d3_svg_lineX && fy === d3_svg_lineY) points = data; else for (points = new Array(n), + i = 0; i < n; ++i) { + points[i] = [ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]; + } + d3_geom_voronoiTessellate(points, function(e) { + var l = e.region.l.index, r = e.region.r.index; + if (graph[l][r]) return; + graph[l][r] = graph[r][l] = true; + links.push({ + source: data[l], + target: data[r] + }); + }); + return links; + }; + voronoi.triangles = function(data) { + if (x === d3_svg_lineX && y === d3_svg_lineY) return d3.geom.delaunay(data); + var points = new Array(n), fx = d3_functor(x), fy = d3_functor(y), d, i = -1, n = data.length; + while (++i < n) { + (points[i] = [ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]).data = d; + } + return d3.geom.delaunay(points).map(function(triangle) { + return triangle.map(function(point) { + return point.data; + }); + }); + }; + return voronoi; + }; + var d3_geom_voronoiOpposite = { + l: "r", + r: "l" + }; + function d3_geom_voronoiTessellate(points, callback) { + var Sites = { + list: points.map(function(v, i) { + return { + index: i, + x: v[0], + y: v[1] + }; + }).sort(function(a, b) { + return a.y < b.y ? -1 : a.y > b.y ? 1 : a.x < b.x ? -1 : a.x > b.x ? 1 : 0; + }), + bottomSite: null + }; + var EdgeList = { + list: [], + leftEnd: null, + rightEnd: null, + init: function() { + EdgeList.leftEnd = EdgeList.createHalfEdge(null, "l"); + EdgeList.rightEnd = EdgeList.createHalfEdge(null, "l"); + EdgeList.leftEnd.r = EdgeList.rightEnd; + EdgeList.rightEnd.l = EdgeList.leftEnd; + EdgeList.list.unshift(EdgeList.leftEnd, EdgeList.rightEnd); + }, + createHalfEdge: function(edge, side) { + return { + edge: edge, + side: side, + vertex: null, + l: null, + r: null + }; + }, + insert: function(lb, he) { + he.l = lb; + he.r = lb.r; + lb.r.l = he; + lb.r = he; + }, + leftBound: function(p) { + var he = EdgeList.leftEnd; + do { + he = he.r; + } while (he != EdgeList.rightEnd && Geom.rightOf(he, p)); + he = he.l; + return he; + }, + del: function(he) { + he.l.r = he.r; + he.r.l = he.l; + he.edge = null; + }, + right: function(he) { + return he.r; + }, + left: function(he) { + return he.l; + }, + leftRegion: function(he) { + return he.edge == null ? Sites.bottomSite : he.edge.region[he.side]; + }, + rightRegion: function(he) { + return he.edge == null ? Sites.bottomSite : he.edge.region[d3_geom_voronoiOpposite[he.side]]; + } + }; + var Geom = { + bisect: function(s1, s2) { + var newEdge = { + region: { + l: s1, + r: s2 + }, + ep: { + l: null, + r: null + } + }; + var dx = s2.x - s1.x, dy = s2.y - s1.y, adx = dx > 0 ? dx : -dx, ady = dy > 0 ? dy : -dy; + newEdge.c = s1.x * dx + s1.y * dy + (dx * dx + dy * dy) * .5; + if (adx > ady) { + newEdge.a = 1; + newEdge.b = dy / dx; + newEdge.c /= dx; + } else { + newEdge.b = 1; + newEdge.a = dx / dy; + newEdge.c /= dy; + } + return newEdge; + }, + intersect: function(el1, el2) { + var e1 = el1.edge, e2 = el2.edge; + if (!e1 || !e2 || e1.region.r == e2.region.r) { + return null; + } + var d = e1.a * e2.b - e1.b * e2.a; + if (Math.abs(d) < 1e-10) { + return null; + } + var xint = (e1.c * e2.b - e2.c * e1.b) / d, yint = (e2.c * e1.a - e1.c * e2.a) / d, e1r = e1.region.r, e2r = e2.region.r, el, e; + if (e1r.y < e2r.y || e1r.y == e2r.y && e1r.x < e2r.x) { + el = el1; + e = e1; + } else { + el = el2; + e = e2; + } + var rightOfSite = xint >= e.region.r.x; + if (rightOfSite && el.side === "l" || !rightOfSite && el.side === "r") { + return null; + } + return { + x: xint, + y: yint + }; + }, + rightOf: function(he, p) { + var e = he.edge, topsite = e.region.r, rightOfSite = p.x > topsite.x; + if (rightOfSite && he.side === "l") { + return 1; + } + if (!rightOfSite && he.side === "r") { + return 0; + } + if (e.a === 1) { + var dyp = p.y - topsite.y, dxp = p.x - topsite.x, fast = 0, above = 0; + if (!rightOfSite && e.b < 0 || rightOfSite && e.b >= 0) { + above = fast = dyp >= e.b * dxp; + } else { + above = p.x + p.y * e.b > e.c; + if (e.b < 0) { + above = !above; + } + if (!above) { + fast = 1; + } + } + if (!fast) { + var dxs = topsite.x - e.region.l.x; + above = e.b * (dxp * dxp - dyp * dyp) < dxs * dyp * (1 + 2 * dxp / dxs + e.b * e.b); + if (e.b < 0) { + above = !above; + } + } + } else { + var yl = e.c - e.a * p.x, t1 = p.y - yl, t2 = p.x - topsite.x, t3 = yl - topsite.y; + above = t1 * t1 > t2 * t2 + t3 * t3; + } + return he.side === "l" ? above : !above; + }, + endPoint: function(edge, side, site) { + edge.ep[side] = site; + if (!edge.ep[d3_geom_voronoiOpposite[side]]) return; + callback(edge); + }, + distance: function(s, t) { + var dx = s.x - t.x, dy = s.y - t.y; + return Math.sqrt(dx * dx + dy * dy); + } + }; + var EventQueue = { + list: [], + insert: function(he, site, offset) { + he.vertex = site; + he.ystar = site.y + offset; + for (var i = 0, list = EventQueue.list, l = list.length; i < l; i++) { + var next = list[i]; + if (he.ystar > next.ystar || he.ystar == next.ystar && site.x > next.vertex.x) { + continue; + } else { + break; + } + } + list.splice(i, 0, he); + }, + del: function(he) { + for (var i = 0, ls = EventQueue.list, l = ls.length; i < l && ls[i] != he; ++i) {} + ls.splice(i, 1); + }, + empty: function() { + return EventQueue.list.length === 0; + }, + nextEvent: function(he) { + for (var i = 0, ls = EventQueue.list, l = ls.length; i < l; ++i) { + if (ls[i] == he) return ls[i + 1]; + } + return null; + }, + min: function() { + var elem = EventQueue.list[0]; + return { + x: elem.vertex.x, + y: elem.ystar + }; + }, + extractMin: function() { + return EventQueue.list.shift(); + } + }; + EdgeList.init(); + Sites.bottomSite = Sites.list.shift(); + var newSite = Sites.list.shift(), newIntStar; + var lbnd, rbnd, llbnd, rrbnd, bisector; + var bot, top, temp, p, v; + var e, pm; + while (true) { + if (!EventQueue.empty()) { + newIntStar = EventQueue.min(); + } + if (newSite && (EventQueue.empty() || newSite.y < newIntStar.y || newSite.y == newIntStar.y && newSite.x < newIntStar.x)) { + lbnd = EdgeList.leftBound(newSite); + rbnd = EdgeList.right(lbnd); + bot = EdgeList.rightRegion(lbnd); + e = Geom.bisect(bot, newSite); + bisector = EdgeList.createHalfEdge(e, "l"); + EdgeList.insert(lbnd, bisector); + p = Geom.intersect(lbnd, bisector); + if (p) { + EventQueue.del(lbnd); + EventQueue.insert(lbnd, p, Geom.distance(p, newSite)); + } + lbnd = bisector; + bisector = EdgeList.createHalfEdge(e, "r"); + EdgeList.insert(lbnd, bisector); + p = Geom.intersect(bisector, rbnd); + if (p) { + EventQueue.insert(bisector, p, Geom.distance(p, newSite)); + } + newSite = Sites.list.shift(); + } else if (!EventQueue.empty()) { + lbnd = EventQueue.extractMin(); + llbnd = EdgeList.left(lbnd); + rbnd = EdgeList.right(lbnd); + rrbnd = EdgeList.right(rbnd); + bot = EdgeList.leftRegion(lbnd); + top = EdgeList.rightRegion(rbnd); + v = lbnd.vertex; + Geom.endPoint(lbnd.edge, lbnd.side, v); + Geom.endPoint(rbnd.edge, rbnd.side, v); + EdgeList.del(lbnd); + EventQueue.del(rbnd); + EdgeList.del(rbnd); + pm = "l"; + if (bot.y > top.y) { + temp = bot; + bot = top; + top = temp; + pm = "r"; + } + e = Geom.bisect(bot, top); + bisector = EdgeList.createHalfEdge(e, pm); + EdgeList.insert(llbnd, bisector); + Geom.endPoint(e, d3_geom_voronoiOpposite[pm], v); + p = Geom.intersect(llbnd, bisector); + if (p) { + EventQueue.del(llbnd); + EventQueue.insert(llbnd, p, Geom.distance(p, bot)); + } + p = Geom.intersect(bisector, rrbnd); + if (p) { + EventQueue.insert(bisector, p, Geom.distance(p, bot)); + } + } else { + break; + } + } + for (lbnd = EdgeList.right(EdgeList.leftEnd); lbnd != EdgeList.rightEnd; lbnd = EdgeList.right(lbnd)) { + callback(lbnd.edge); + } + } + d3.geom.quadtree = function(points, x1, y1, x2, y2) { + var x = d3_svg_lineX, y = d3_svg_lineY, compat; + if (compat = arguments.length) { + x = d3_geom_quadtreeCompatX; + y = d3_geom_quadtreeCompatY; + if (compat === 3) { + y2 = y1; + x2 = x1; + y1 = x1 = 0; + } + return quadtree(points); + } + function quadtree(data) { + var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_; + if (x1 != null) { + x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; + } else { + x2_ = y2_ = -(x1_ = y1_ = Infinity); + xs = [], ys = []; + n = data.length; + if (compat) for (i = 0; i < n; ++i) { + d = data[i]; + if (d.x < x1_) x1_ = d.x; + if (d.y < y1_) y1_ = d.y; + if (d.x > x2_) x2_ = d.x; + if (d.y > y2_) y2_ = d.y; + xs.push(d.x); + ys.push(d.y); + } else for (i = 0; i < n; ++i) { + var x_ = +fx(d = data[i], i), y_ = +fy(d, i); + if (x_ < x1_) x1_ = x_; + if (y_ < y1_) y1_ = y_; + if (x_ > x2_) x2_ = x_; + if (y_ > y2_) y2_ = y_; + xs.push(x_); + ys.push(y_); + } + } + var dx = x2_ - x1_, dy = y2_ - y1_; + if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy; + function insert(n, d, x, y, x1, y1, x2, y2) { + if (isNaN(x) || isNaN(y)) return; + if (n.leaf) { + var nx = n.x, ny = n.y; + if (nx != null) { + if (Math.abs(nx - x) + Math.abs(ny - y) < .01) { + insertChild(n, d, x, y, x1, y1, x2, y2); + } else { + var nPoint = n.point; + n.x = n.y = n.point = null; + insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); + insertChild(n, d, x, y, x1, y1, x2, y2); + } + } else { + n.x = x, n.y = y, n.point = d; + } + } else { + insertChild(n, d, x, y, x1, y1, x2, y2); + } + } + function insertChild(n, d, x, y, x1, y1, x2, y2) { + var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, right = x >= sx, bottom = y >= sy, i = (bottom << 1) + right; + n.leaf = false; + n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); + if (right) x1 = sx; else x2 = sx; + if (bottom) y1 = sy; else y2 = sy; + insert(n, d, x, y, x1, y1, x2, y2); + } + var root = d3_geom_quadtreeNode(); + root.add = function(d) { + insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); + }; + root.visit = function(f) { + d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); + }; + i = -1; + if (x1 == null) { + while (++i < n) { + insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); + } + --i; + } else data.forEach(root.add); + xs = ys = data = d = null; + return root; + } + quadtree.x = function(_) { + return arguments.length ? (x = _, quadtree) : x; + }; + quadtree.y = function(_) { + return arguments.length ? (y = _, quadtree) : y; + }; + quadtree.extent = function(_) { + if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ]; + if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], + y2 = +_[1][1]; + return quadtree; + }; + quadtree.size = function(_) { + if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ]; + if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1]; + return quadtree; + }; + return quadtree; + }; + function d3_geom_quadtreeCompatX(d) { + return d.x; + } + function d3_geom_quadtreeCompatY(d) { + return d.y; + } + function d3_geom_quadtreeNode() { + return { + leaf: true, + nodes: [], + point: null, + x: null, + y: null + }; + } + function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { + if (!f(node, x1, y1, x2, y2)) { + var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; + if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); + if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); + if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); + if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); + } + } + d3.interpolateRgb = d3_interpolateRgb; + function d3_interpolateRgb(a, b) { + a = d3.rgb(a); + b = d3.rgb(b); + var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; + return function(t) { + return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t)); + }; + } + d3.interpolateObject = d3_interpolateObject; + function d3_interpolateObject(a, b) { + var i = {}, c = {}, k; + for (k in a) { + if (k in b) { + i[k] = d3_interpolate(a[k], b[k]); + } else { + c[k] = a[k]; + } + } + for (k in b) { + if (!(k in a)) { + c[k] = b[k]; + } + } + return function(t) { + for (k in i) c[k] = i[k](t); + return c; + }; + } + d3.interpolateNumber = d3_interpolateNumber; + function d3_interpolateNumber(a, b) { + b -= a = +a; + return function(t) { + return a + b * t; + }; + } + d3.interpolateString = d3_interpolateString; + function d3_interpolateString(a, b) { + var m, i, j, s0 = 0, s1 = 0, s = [], q = [], n, o; + a = a + "", b = b + ""; + d3_interpolate_number.lastIndex = 0; + for (i = 0; m = d3_interpolate_number.exec(b); ++i) { + if (m.index) s.push(b.substring(s0, s1 = m.index)); + q.push({ + i: s.length, + x: m[0] + }); + s.push(null); + s0 = d3_interpolate_number.lastIndex; + } + if (s0 < b.length) s.push(b.substring(s0)); + for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) { + o = q[i]; + if (o.x == m[0]) { + if (o.i) { + if (s[o.i + 1] == null) { + s[o.i - 1] += o.x; + s.splice(o.i, 1); + for (j = i + 1; j < n; ++j) q[j].i--; + } else { + s[o.i - 1] += o.x + s[o.i + 1]; + s.splice(o.i, 2); + for (j = i + 1; j < n; ++j) q[j].i -= 2; + } + } else { + if (s[o.i + 1] == null) { + s[o.i] = o.x; + } else { + s[o.i] = o.x + s[o.i + 1]; + s.splice(o.i + 1, 1); + for (j = i + 1; j < n; ++j) q[j].i--; + } + } + q.splice(i, 1); + n--; + i--; + } else { + o.x = d3_interpolateNumber(parseFloat(m[0]), parseFloat(o.x)); + } + } + while (i < n) { + o = q.pop(); + if (s[o.i + 1] == null) { + s[o.i] = o.x; + } else { + s[o.i] = o.x + s[o.i + 1]; + s.splice(o.i + 1, 1); + } + n--; + } + if (s.length === 1) { + return s[0] == null ? (o = q[0].x, function(t) { + return o(t) + ""; + }) : function() { + return b; + }; + } + return function(t) { + for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }; + } + var d3_interpolate_number = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; + d3.interpolate = d3_interpolate; + function d3_interpolate(a, b) { + var i = d3.interpolators.length, f; + while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; + return f; + } + d3.interpolators = [ function(a, b) { + var t = typeof b; + return (t === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_Color ? d3_interpolateRgb : t === "object" ? Array.isArray(b) ? d3_interpolateArray : d3_interpolateObject : d3_interpolateNumber)(a, b); + } ]; + d3.interpolateArray = d3_interpolateArray; + function d3_interpolateArray(a, b) { + var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; + for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); + for (;i < na; ++i) c[i] = a[i]; + for (;i < nb; ++i) c[i] = b[i]; + return function(t) { + for (i = 0; i < n0; ++i) c[i] = x[i](t); + return c; + }; + } + var d3_ease_default = function() { + return d3_identity; + }; + var d3_ease = d3.map({ + linear: d3_ease_default, + poly: d3_ease_poly, + quad: function() { + return d3_ease_quad; + }, + cubic: function() { + return d3_ease_cubic; + }, + sin: function() { + return d3_ease_sin; + }, + exp: function() { + return d3_ease_exp; + }, + circle: function() { + return d3_ease_circle; + }, + elastic: d3_ease_elastic, + back: d3_ease_back, + bounce: function() { + return d3_ease_bounce; + } + }); + var d3_ease_mode = d3.map({ + "in": d3_identity, + out: d3_ease_reverse, + "in-out": d3_ease_reflect, + "out-in": function(f) { + return d3_ease_reflect(d3_ease_reverse(f)); + } + }); + d3.ease = function(name) { + var i = name.indexOf("-"), t = i >= 0 ? name.substring(0, i) : name, m = i >= 0 ? name.substring(i + 1) : "in"; + t = d3_ease.get(t) || d3_ease_default; + m = d3_ease_mode.get(m) || d3_identity; + return d3_ease_clamp(m(t.apply(null, Array.prototype.slice.call(arguments, 1)))); + }; + function d3_ease_clamp(f) { + return function(t) { + return t <= 0 ? 0 : t >= 1 ? 1 : f(t); + }; + } + function d3_ease_reverse(f) { + return function(t) { + return 1 - f(1 - t); + }; + } + function d3_ease_reflect(f) { + return function(t) { + return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); + }; + } + function d3_ease_quad(t) { + return t * t; + } + function d3_ease_cubic(t) { + return t * t * t; + } + function d3_ease_cubicInOut(t) { + if (t <= 0) return 0; + if (t >= 1) return 1; + var t2 = t * t, t3 = t2 * t; + return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); + } + function d3_ease_poly(e) { + return function(t) { + return Math.pow(t, e); + }; + } + function d3_ease_sin(t) { + return 1 - Math.cos(t * π / 2); + } + function d3_ease_exp(t) { + return Math.pow(2, 10 * (t - 1)); + } + function d3_ease_circle(t) { + return 1 - Math.sqrt(1 - t * t); + } + function d3_ease_elastic(a, p) { + var s; + if (arguments.length < 2) p = .45; + if (arguments.length) s = p / (2 * π) * Math.asin(1 / a); else a = 1, s = p / 4; + return function(t) { + return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * π / p); + }; + } + function d3_ease_back(s) { + if (!s) s = 1.70158; + return function(t) { + return t * t * ((s + 1) * t - s); + }; + } + function d3_ease_bounce(t) { + return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; + } + d3.interpolateHcl = d3_interpolateHcl; + function d3_interpolateHcl(a, b) { + a = d3.hcl(a); + b = d3.hcl(b); + var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; + if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; + if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; + return function(t) { + return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; + }; + } + d3.interpolateHsl = d3_interpolateHsl; + function d3_interpolateHsl(a, b) { + a = d3.hsl(a); + b = d3.hsl(b); + var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al; + if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; + if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; + return function(t) { + return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + ""; + }; + } + d3.interpolateLab = d3_interpolateLab; + function d3_interpolateLab(a, b) { + a = d3.lab(a); + b = d3.lab(b); + var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; + return function(t) { + return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; + }; + } + d3.interpolateRound = d3_interpolateRound; + function d3_interpolateRound(a, b) { + b -= a; + return function(t) { + return Math.round(a + b * t); + }; + } + d3.transform = function(string) { + var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); + return (d3.transform = function(string) { + if (string != null) { + g.setAttribute("transform", string); + var t = g.transform.baseVal.consolidate(); + } + return new d3_transform(t ? t.matrix : d3_transformIdentity); + })(string); + }; + function d3_transform(m) { + var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; + if (r0[0] * r1[1] < r1[0] * r0[1]) { + r0[0] *= -1; + r0[1] *= -1; + kx *= -1; + kz *= -1; + } + this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; + this.translate = [ m.e, m.f ]; + this.scale = [ kx, ky ]; + this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; + } + d3_transform.prototype.toString = function() { + return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; + }; + function d3_transformDot(a, b) { + return a[0] * b[0] + a[1] * b[1]; + } + function d3_transformNormalize(a) { + var k = Math.sqrt(d3_transformDot(a, a)); + if (k) { + a[0] /= k; + a[1] /= k; + } + return k; + } + function d3_transformCombine(a, b, k) { + a[0] += k * b[0]; + a[1] += k * b[1]; + return a; + } + var d3_transformIdentity = { + a: 1, + b: 0, + c: 0, + d: 1, + e: 0, + f: 0 + }; + d3.interpolateTransform = d3_interpolateTransform; + function d3_interpolateTransform(a, b) { + var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; + if (ta[0] != tb[0] || ta[1] != tb[1]) { + s.push("translate(", null, ",", null, ")"); + q.push({ + i: 1, + x: d3_interpolateNumber(ta[0], tb[0]) + }, { + i: 3, + x: d3_interpolateNumber(ta[1], tb[1]) + }); + } else if (tb[0] || tb[1]) { + s.push("translate(" + tb + ")"); + } else { + s.push(""); + } + if (ra != rb) { + if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; + q.push({ + i: s.push(s.pop() + "rotate(", null, ")") - 2, + x: d3_interpolateNumber(ra, rb) + }); + } else if (rb) { + s.push(s.pop() + "rotate(" + rb + ")"); + } + if (wa != wb) { + q.push({ + i: s.push(s.pop() + "skewX(", null, ")") - 2, + x: d3_interpolateNumber(wa, wb) + }); + } else if (wb) { + s.push(s.pop() + "skewX(" + wb + ")"); + } + if (ka[0] != kb[0] || ka[1] != kb[1]) { + n = s.push(s.pop() + "scale(", null, ",", null, ")"); + q.push({ + i: n - 4, + x: d3_interpolateNumber(ka[0], kb[0]) + }, { + i: n - 2, + x: d3_interpolateNumber(ka[1], kb[1]) + }); + } else if (kb[0] != 1 || kb[1] != 1) { + s.push(s.pop() + "scale(" + kb + ")"); + } + n = q.length; + return function(t) { + var i = -1, o; + while (++i < n) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }; + } + function d3_uninterpolateNumber(a, b) { + b = b - (a = +a) ? 1 / (b - a) : 0; + return function(x) { + return (x - a) * b; + }; + } + function d3_uninterpolateClamp(a, b) { + b = b - (a = +a) ? 1 / (b - a) : 0; + return function(x) { + return Math.max(0, Math.min(1, (x - a) * b)); + }; + } + d3.layout = {}; + d3.layout.bundle = function() { + return function(links) { + var paths = [], i = -1, n = links.length; + while (++i < n) paths.push(d3_layout_bundlePath(links[i])); + return paths; + }; + }; + function d3_layout_bundlePath(link) { + var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; + while (start !== lca) { + start = start.parent; + points.push(start); + } + var k = points.length; + while (end !== lca) { + points.splice(k, 0, end); + end = end.parent; + } + return points; + } + function d3_layout_bundleAncestors(node) { + var ancestors = [], parent = node.parent; + while (parent != null) { + ancestors.push(node); + node = parent; + parent = parent.parent; + } + ancestors.push(node); + return ancestors; + } + function d3_layout_bundleLeastCommonAncestor(a, b) { + if (a === b) return a; + var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; + while (aNode === bNode) { + sharedNode = aNode; + aNode = aNodes.pop(); + bNode = bNodes.pop(); + } + return sharedNode; + } + d3.layout.chord = function() { + var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; + function relayout() { + var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; + chords = []; + groups = []; + k = 0, i = -1; + while (++i < n) { + x = 0, j = -1; + while (++j < n) { + x += matrix[i][j]; + } + groupSums.push(x); + subgroupIndex.push(d3.range(n)); + k += x; + } + if (sortGroups) { + groupIndex.sort(function(a, b) { + return sortGroups(groupSums[a], groupSums[b]); + }); + } + if (sortSubgroups) { + subgroupIndex.forEach(function(d, i) { + d.sort(function(a, b) { + return sortSubgroups(matrix[i][a], matrix[i][b]); + }); + }); + } + k = (2 * π - padding * n) / k; + x = 0, i = -1; + while (++i < n) { + x0 = x, j = -1; + while (++j < n) { + var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; + subgroups[di + "-" + dj] = { + index: di, + subindex: dj, + startAngle: a0, + endAngle: a1, + value: v + }; + } + groups[di] = { + index: di, + startAngle: x0, + endAngle: x, + value: (x - x0) / k + }; + x += padding; + } + i = -1; + while (++i < n) { + j = i - 1; + while (++j < n) { + var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; + if (source.value || target.value) { + chords.push(source.value < target.value ? { + source: target, + target: source + } : { + source: source, + target: target + }); + } + } + } + if (sortChords) resort(); + } + function resort() { + chords.sort(function(a, b) { + return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); + }); + } + chord.matrix = function(x) { + if (!arguments.length) return matrix; + n = (matrix = x) && matrix.length; + chords = groups = null; + return chord; + }; + chord.padding = function(x) { + if (!arguments.length) return padding; + padding = x; + chords = groups = null; + return chord; + }; + chord.sortGroups = function(x) { + if (!arguments.length) return sortGroups; + sortGroups = x; + chords = groups = null; + return chord; + }; + chord.sortSubgroups = function(x) { + if (!arguments.length) return sortSubgroups; + sortSubgroups = x; + chords = null; + return chord; + }; + chord.sortChords = function(x) { + if (!arguments.length) return sortChords; + sortChords = x; + if (chords) resort(); + return chord; + }; + chord.chords = function() { + if (!chords) relayout(); + return chords; + }; + chord.groups = function() { + if (!groups) relayout(); + return groups; + }; + return chord; + }; + d3.layout.force = function() { + var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, gravity = .1, theta = .8, nodes = [], links = [], distances, strengths, charges; + function repulse(node) { + return function(quad, x1, _, x2) { + if (quad.point !== node) { + var dx = quad.cx - node.x, dy = quad.cy - node.y, dn = 1 / Math.sqrt(dx * dx + dy * dy); + if ((x2 - x1) * dn < theta) { + var k = quad.charge * dn * dn; + node.px -= dx * k; + node.py -= dy * k; + return true; + } + if (quad.point && isFinite(dn)) { + var k = quad.pointCharge * dn * dn; + node.px -= dx * k; + node.py -= dy * k; + } + } + return !quad.charge; + }; + } + force.tick = function() { + if ((alpha *= .99) < .005) { + event.end({ + type: "end", + alpha: alpha = 0 + }); + return true; + } + var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; + for (i = 0; i < m; ++i) { + o = links[i]; + s = o.source; + t = o.target; + x = t.x - s.x; + y = t.y - s.y; + if (l = x * x + y * y) { + l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; + x *= l; + y *= l; + t.x -= x * (k = s.weight / (t.weight + s.weight)); + t.y -= y * k; + s.x += x * (k = 1 - k); + s.y += y * k; + } + } + if (k = alpha * gravity) { + x = size[0] / 2; + y = size[1] / 2; + i = -1; + if (k) while (++i < n) { + o = nodes[i]; + o.x += (x - o.x) * k; + o.y += (y - o.y) * k; + } + } + if (charge) { + d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); + i = -1; + while (++i < n) { + if (!(o = nodes[i]).fixed) { + q.visit(repulse(o)); + } + } + } + i = -1; + while (++i < n) { + o = nodes[i]; + if (o.fixed) { + o.x = o.px; + o.y = o.py; + } else { + o.x -= (o.px - (o.px = o.x)) * friction; + o.y -= (o.py - (o.py = o.y)) * friction; + } + } + event.tick({ + type: "tick", + alpha: alpha + }); + }; + force.nodes = function(x) { + if (!arguments.length) return nodes; + nodes = x; + return force; + }; + force.links = function(x) { + if (!arguments.length) return links; + links = x; + return force; + }; + force.size = function(x) { + if (!arguments.length) return size; + size = x; + return force; + }; + force.linkDistance = function(x) { + if (!arguments.length) return linkDistance; + linkDistance = typeof x === "function" ? x : +x; + return force; + }; + force.distance = force.linkDistance; + force.linkStrength = function(x) { + if (!arguments.length) return linkStrength; + linkStrength = typeof x === "function" ? x : +x; + return force; + }; + force.friction = function(x) { + if (!arguments.length) return friction; + friction = +x; + return force; + }; + force.charge = function(x) { + if (!arguments.length) return charge; + charge = typeof x === "function" ? x : +x; + return force; + }; + force.gravity = function(x) { + if (!arguments.length) return gravity; + gravity = +x; + return force; + }; + force.theta = function(x) { + if (!arguments.length) return theta; + theta = +x; + return force; + }; + force.alpha = function(x) { + if (!arguments.length) return alpha; + x = +x; + if (alpha) { + if (x > 0) alpha = x; else alpha = 0; + } else if (x > 0) { + event.start({ + type: "start", + alpha: alpha = x + }); + d3.timer(force.tick); + } + return force; + }; + force.start = function() { + var i, j, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; + for (i = 0; i < n; ++i) { + (o = nodes[i]).index = i; + o.weight = 0; + } + for (i = 0; i < m; ++i) { + o = links[i]; + if (typeof o.source == "number") o.source = nodes[o.source]; + if (typeof o.target == "number") o.target = nodes[o.target]; + ++o.source.weight; + ++o.target.weight; + } + for (i = 0; i < n; ++i) { + o = nodes[i]; + if (isNaN(o.x)) o.x = position("x", w); + if (isNaN(o.y)) o.y = position("y", h); + if (isNaN(o.px)) o.px = o.x; + if (isNaN(o.py)) o.py = o.y; + } + distances = []; + if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance; + strengths = []; + if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength; + charges = []; + if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge; + function position(dimension, size) { + var neighbors = neighbor(i), j = -1, m = neighbors.length, x; + while (++j < m) if (!isNaN(x = neighbors[j][dimension])) return x; + return Math.random() * size; + } + function neighbor() { + if (!neighbors) { + neighbors = []; + for (j = 0; j < n; ++j) { + neighbors[j] = []; + } + for (j = 0; j < m; ++j) { + var o = links[j]; + neighbors[o.source.index].push(o.target); + neighbors[o.target.index].push(o.source); + } + } + return neighbors[i]; + } + return force.resume(); + }; + force.resume = function() { + return force.alpha(.1); + }; + force.stop = function() { + return force.alpha(0); + }; + force.drag = function() { + if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend); + if (!arguments.length) return drag; + this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); + }; + function dragmove(d) { + d.px = d3.event.x, d.py = d3.event.y; + force.resume(); + } + return d3.rebind(force, event, "on"); + }; + function d3_layout_forceDragstart(d) { + d.fixed |= 2; + } + function d3_layout_forceDragend(d) { + d.fixed &= ~6; + } + function d3_layout_forceMouseover(d) { + d.fixed |= 4; + d.px = d.x, d.py = d.y; + } + function d3_layout_forceMouseout(d) { + d.fixed &= ~4; + } + function d3_layout_forceAccumulate(quad, alpha, charges) { + var cx = 0, cy = 0; + quad.charge = 0; + if (!quad.leaf) { + var nodes = quad.nodes, n = nodes.length, i = -1, c; + while (++i < n) { + c = nodes[i]; + if (c == null) continue; + d3_layout_forceAccumulate(c, alpha, charges); + quad.charge += c.charge; + cx += c.charge * c.cx; + cy += c.charge * c.cy; + } + } + if (quad.point) { + if (!quad.leaf) { + quad.point.x += Math.random() - .5; + quad.point.y += Math.random() - .5; + } + var k = alpha * charges[quad.point.index]; + quad.charge += quad.pointCharge = k; + cx += k * quad.point.x; + cy += k * quad.point.y; + } + quad.cx = cx / quad.charge; + quad.cy = cy / quad.charge; + } + var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1; + d3.layout.hierarchy = function() { + var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; + function recurse(node, depth, nodes) { + var childs = children.call(hierarchy, node, depth); + node.depth = depth; + nodes.push(node); + if (childs && (n = childs.length)) { + var i = -1, n, c = node.children = [], v = 0, j = depth + 1, d; + while (++i < n) { + d = recurse(childs[i], j, nodes); + d.parent = node; + c.push(d); + v += d.value; + } + if (sort) c.sort(sort); + if (value) node.value = v; + } else if (value) { + node.value = +value.call(hierarchy, node, depth) || 0; + } + return node; + } + function revalue(node, depth) { + var children = node.children, v = 0; + if (children && (n = children.length)) { + var i = -1, n, j = depth + 1; + while (++i < n) v += revalue(children[i], j); + } else if (value) { + v = +value.call(hierarchy, node, depth) || 0; + } + if (value) node.value = v; + return v; + } + function hierarchy(d) { + var nodes = []; + recurse(d, 0, nodes); + return nodes; + } + hierarchy.sort = function(x) { + if (!arguments.length) return sort; + sort = x; + return hierarchy; + }; + hierarchy.children = function(x) { + if (!arguments.length) return children; + children = x; + return hierarchy; + }; + hierarchy.value = function(x) { + if (!arguments.length) return value; + value = x; + return hierarchy; + }; + hierarchy.revalue = function(root) { + revalue(root, 0); + return root; + }; + return hierarchy; + }; + function d3_layout_hierarchyRebind(object, hierarchy) { + d3.rebind(object, hierarchy, "sort", "children", "value"); + object.nodes = object; + object.links = d3_layout_hierarchyLinks; + return object; + } + function d3_layout_hierarchyChildren(d) { + return d.children; + } + function d3_layout_hierarchyValue(d) { + return d.value; + } + function d3_layout_hierarchySort(a, b) { + return b.value - a.value; + } + function d3_layout_hierarchyLinks(nodes) { + return d3.merge(nodes.map(function(parent) { + return (parent.children || []).map(function(child) { + return { + source: parent, + target: child + }; + }); + })); + } + d3.layout.partition = function() { + var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; + function position(node, x, dx, dy) { + var children = node.children; + node.x = x; + node.y = node.depth * dy; + node.dx = dx; + node.dy = dy; + if (children && (n = children.length)) { + var i = -1, n, c, d; + dx = node.value ? dx / node.value : 0; + while (++i < n) { + position(c = children[i], x, d = c.value * dx, dy); + x += d; + } + } + } + function depth(node) { + var children = node.children, d = 0; + if (children && (n = children.length)) { + var i = -1, n; + while (++i < n) d = Math.max(d, depth(children[i])); + } + return 1 + d; + } + function partition(d, i) { + var nodes = hierarchy.call(this, d, i); + position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); + return nodes; + } + partition.size = function(x) { + if (!arguments.length) return size; + size = x; + return partition; + }; + return d3_layout_hierarchyRebind(partition, hierarchy); + }; + d3.layout.pie = function() { + var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = 2 * π; + function pie(data) { + var values = data.map(function(d, i) { + return +value.call(pie, d, i); + }); + var a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle); + var k = ((typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a) / d3.sum(values); + var index = d3.range(data.length); + if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { + return values[j] - values[i]; + } : function(i, j) { + return sort(data[i], data[j]); + }); + var arcs = []; + index.forEach(function(i) { + var d; + arcs[i] = { + data: data[i], + value: d = values[i], + startAngle: a, + endAngle: a += d * k + }; + }); + return arcs; + } + pie.value = function(x) { + if (!arguments.length) return value; + value = x; + return pie; + }; + pie.sort = function(x) { + if (!arguments.length) return sort; + sort = x; + return pie; + }; + pie.startAngle = function(x) { + if (!arguments.length) return startAngle; + startAngle = x; + return pie; + }; + pie.endAngle = function(x) { + if (!arguments.length) return endAngle; + endAngle = x; + return pie; + }; + return pie; + }; + var d3_layout_pieSortByValue = {}; + d3.layout.stack = function() { + var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; + function stack(data, index) { + var series = data.map(function(d, i) { + return values.call(stack, d, i); + }); + var points = series.map(function(d) { + return d.map(function(v, i) { + return [ x.call(stack, v, i), y.call(stack, v, i) ]; + }); + }); + var orders = order.call(stack, points, index); + series = d3.permute(series, orders); + points = d3.permute(points, orders); + var offsets = offset.call(stack, points, index); + var n = series.length, m = series[0].length, i, j, o; + for (j = 0; j < m; ++j) { + out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); + for (i = 1; i < n; ++i) { + out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); + } + } + return data; + } + stack.values = function(x) { + if (!arguments.length) return values; + values = x; + return stack; + }; + stack.order = function(x) { + if (!arguments.length) return order; + order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; + return stack; + }; + stack.offset = function(x) { + if (!arguments.length) return offset; + offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; + return stack; + }; + stack.x = function(z) { + if (!arguments.length) return x; + x = z; + return stack; + }; + stack.y = function(z) { + if (!arguments.length) return y; + y = z; + return stack; + }; + stack.out = function(z) { + if (!arguments.length) return out; + out = z; + return stack; + }; + return stack; + }; + function d3_layout_stackX(d) { + return d.x; + } + function d3_layout_stackY(d) { + return d.y; + } + function d3_layout_stackOut(d, y0, y) { + d.y0 = y0; + d.y = y; + } + var d3_layout_stackOrders = d3.map({ + "inside-out": function(data) { + var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { + return max[a] - max[b]; + }), top = 0, bottom = 0, tops = [], bottoms = []; + for (i = 0; i < n; ++i) { + j = index[i]; + if (top < bottom) { + top += sums[j]; + tops.push(j); + } else { + bottom += sums[j]; + bottoms.push(j); + } + } + return bottoms.reverse().concat(tops); + }, + reverse: function(data) { + return d3.range(data.length).reverse(); + }, + "default": d3_layout_stackOrderDefault + }); + var d3_layout_stackOffsets = d3.map({ + silhouette: function(data) { + var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; + for (j = 0; j < m; ++j) { + for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; + if (o > max) max = o; + sums.push(o); + } + for (j = 0; j < m; ++j) { + y0[j] = (max - sums[j]) / 2; + } + return y0; + }, + wiggle: function(data) { + var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; + y0[0] = o = o0 = 0; + for (j = 1; j < m; ++j) { + for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; + for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { + for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { + s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; + } + s2 += s3 * data[i][j][1]; + } + y0[j] = o -= s1 ? s2 / s1 * dx : 0; + if (o < o0) o0 = o; + } + for (j = 0; j < m; ++j) y0[j] -= o0; + return y0; + }, + expand: function(data) { + var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; + for (j = 0; j < m; ++j) { + for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; + if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; + } + for (j = 0; j < m; ++j) y0[j] = 0; + return y0; + }, + zero: d3_layout_stackOffsetZero + }); + function d3_layout_stackOrderDefault(data) { + return d3.range(data.length); + } + function d3_layout_stackOffsetZero(data) { + var j = -1, m = data[0].length, y0 = []; + while (++j < m) y0[j] = 0; + return y0; + } + function d3_layout_stackMaxIndex(array) { + var i = 1, j = 0, v = array[0][1], k, n = array.length; + for (;i < n; ++i) { + if ((k = array[i][1]) > v) { + j = i; + v = k; + } + } + return j; + } + function d3_layout_stackReduceSum(d) { + return d.reduce(d3_layout_stackSum, 0); + } + function d3_layout_stackSum(p, d) { + return p + d[1]; + } + d3.layout.histogram = function() { + var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; + function histogram(data, i) { + var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; + while (++i < m) { + bin = bins[i] = []; + bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); + bin.y = 0; + } + if (m > 0) { + i = -1; + while (++i < n) { + x = values[i]; + if (x >= range[0] && x <= range[1]) { + bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; + bin.y += k; + bin.push(data[i]); + } + } + } + return bins; + } + histogram.value = function(x) { + if (!arguments.length) return valuer; + valuer = x; + return histogram; + }; + histogram.range = function(x) { + if (!arguments.length) return ranger; + ranger = d3_functor(x); + return histogram; + }; + histogram.bins = function(x) { + if (!arguments.length) return binner; + binner = typeof x === "number" ? function(range) { + return d3_layout_histogramBinFixed(range, x); + } : d3_functor(x); + return histogram; + }; + histogram.frequency = function(x) { + if (!arguments.length) return frequency; + frequency = !!x; + return histogram; + }; + return histogram; + }; + function d3_layout_histogramBinSturges(range, values) { + return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); + } + function d3_layout_histogramBinFixed(range, n) { + var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; + while (++x <= n) f[x] = m * x + b; + return f; + } + function d3_layout_histogramRange(values) { + return [ d3.min(values), d3.max(values) ]; + } + d3.layout.tree = function() { + var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; + function tree(d, i) { + var nodes = hierarchy.call(this, d, i), root = nodes[0]; + function firstWalk(node, previousSibling) { + var children = node.children, layout = node._tree; + if (children && (n = children.length)) { + var n, firstChild = children[0], previousChild, ancestor = firstChild, child, i = -1; + while (++i < n) { + child = children[i]; + firstWalk(child, previousChild); + ancestor = apportion(child, previousChild, ancestor); + previousChild = child; + } + d3_layout_treeShift(node); + var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim); + if (previousSibling) { + layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); + layout.mod = layout.prelim - midpoint; + } else { + layout.prelim = midpoint; + } + } else { + if (previousSibling) { + layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); + } + } + } + function secondWalk(node, x) { + node.x = node._tree.prelim + x; + var children = node.children; + if (children && (n = children.length)) { + var i = -1, n; + x += node._tree.mod; + while (++i < n) { + secondWalk(children[i], x); + } + } + } + function apportion(node, previousSibling, ancestor) { + if (previousSibling) { + var vip = node, vop = node, vim = previousSibling, vom = node.parent.children[0], sip = vip._tree.mod, sop = vop._tree.mod, sim = vim._tree.mod, som = vom._tree.mod, shift; + while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { + vom = d3_layout_treeLeft(vom); + vop = d3_layout_treeRight(vop); + vop._tree.ancestor = node; + shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip); + if (shift > 0) { + d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift); + sip += shift; + sop += shift; + } + sim += vim._tree.mod; + sip += vip._tree.mod; + som += vom._tree.mod; + sop += vop._tree.mod; + } + if (vim && !d3_layout_treeRight(vop)) { + vop._tree.thread = vim; + vop._tree.mod += sim - sop; + } + if (vip && !d3_layout_treeLeft(vom)) { + vom._tree.thread = vip; + vom._tree.mod += sip - som; + ancestor = node; + } + } + return ancestor; + } + d3_layout_treeVisitAfter(root, function(node, previousSibling) { + node._tree = { + ancestor: node, + prelim: 0, + mod: 0, + change: 0, + shift: 0, + number: previousSibling ? previousSibling._tree.number + 1 : 0 + }; + }); + firstWalk(root); + secondWalk(root, -root._tree.prelim); + var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost), right = d3_layout_treeSearch(root, d3_layout_treeRightmost), deep = d3_layout_treeSearch(root, d3_layout_treeDeepest), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2, y1 = deep.depth || 1; + d3_layout_treeVisitAfter(root, nodeSize ? function(node) { + node.x *= size[0]; + node.y = node.depth * size[1]; + delete node._tree; + } : function(node) { + node.x = (node.x - x0) / (x1 - x0) * size[0]; + node.y = node.depth / y1 * size[1]; + delete node._tree; + }); + return nodes; + } + tree.separation = function(x) { + if (!arguments.length) return separation; + separation = x; + return tree; + }; + tree.size = function(x) { + if (!arguments.length) return nodeSize ? null : size; + nodeSize = (size = x) == null; + return tree; + }; + tree.nodeSize = function(x) { + if (!arguments.length) return nodeSize ? size : null; + nodeSize = (size = x) != null; + return tree; + }; + return d3_layout_hierarchyRebind(tree, hierarchy); + }; + function d3_layout_treeSeparation(a, b) { + return a.parent == b.parent ? 1 : 2; + } + function d3_layout_treeLeft(node) { + var children = node.children; + return children && children.length ? children[0] : node._tree.thread; + } + function d3_layout_treeRight(node) { + var children = node.children, n; + return children && (n = children.length) ? children[n - 1] : node._tree.thread; + } + function d3_layout_treeSearch(node, compare) { + var children = node.children; + if (children && (n = children.length)) { + var child, n, i = -1; + while (++i < n) { + if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) { + node = child; + } + } + } + return node; + } + function d3_layout_treeRightmost(a, b) { + return a.x - b.x; + } + function d3_layout_treeLeftmost(a, b) { + return b.x - a.x; + } + function d3_layout_treeDeepest(a, b) { + return a.depth - b.depth; + } + function d3_layout_treeVisitAfter(node, callback) { + function visit(node, previousSibling) { + var children = node.children; + if (children && (n = children.length)) { + var child, previousChild = null, i = -1, n; + while (++i < n) { + child = children[i]; + visit(child, previousChild); + previousChild = child; + } + } + callback(node, previousSibling); + } + visit(node, null); + } + function d3_layout_treeShift(node) { + var shift = 0, change = 0, children = node.children, i = children.length, child; + while (--i >= 0) { + child = children[i]._tree; + child.prelim += shift; + child.mod += shift; + shift += child.shift + (change += child.change); + } + } + function d3_layout_treeMove(ancestor, node, shift) { + ancestor = ancestor._tree; + node = node._tree; + var change = shift / (node.number - ancestor.number); + ancestor.change += change; + node.change -= change; + node.shift += shift; + node.prelim += shift; + node.mod += shift; + } + function d3_layout_treeAncestor(vim, node, ancestor) { + return vim._tree.ancestor.parent == node.parent ? vim._tree.ancestor : ancestor; + } + d3.layout.pack = function() { + var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius; + function pack(d, i) { + var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { + return radius; + }; + root.x = root.y = 0; + d3_layout_treeVisitAfter(root, function(d) { + d.r = +r(d.value); + }); + d3_layout_treeVisitAfter(root, d3_layout_packSiblings); + if (padding) { + var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2; + d3_layout_treeVisitAfter(root, function(d) { + d.r += dr; + }); + d3_layout_treeVisitAfter(root, d3_layout_packSiblings); + d3_layout_treeVisitAfter(root, function(d) { + d.r -= dr; + }); + } + d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h)); + return nodes; + } + pack.size = function(_) { + if (!arguments.length) return size; + size = _; + return pack; + }; + pack.radius = function(_) { + if (!arguments.length) return radius; + radius = _ == null || typeof _ === "function" ? _ : +_; + return pack; + }; + pack.padding = function(_) { + if (!arguments.length) return padding; + padding = +_; + return pack; + }; + return d3_layout_hierarchyRebind(pack, hierarchy); + }; + function d3_layout_packSort(a, b) { + return a.value - b.value; + } + function d3_layout_packInsert(a, b) { + var c = a._pack_next; + a._pack_next = b; + b._pack_prev = a; + b._pack_next = c; + c._pack_prev = b; + } + function d3_layout_packSplice(a, b) { + a._pack_next = b; + b._pack_prev = a; + } + function d3_layout_packIntersects(a, b) { + var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; + return .999 * dr * dr > dx * dx + dy * dy; + } + function d3_layout_packSiblings(node) { + if (!(nodes = node.children) || !(n = nodes.length)) return; + var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; + function bound(node) { + xMin = Math.min(node.x - node.r, xMin); + xMax = Math.max(node.x + node.r, xMax); + yMin = Math.min(node.y - node.r, yMin); + yMax = Math.max(node.y + node.r, yMax); + } + nodes.forEach(d3_layout_packLink); + a = nodes[0]; + a.x = -a.r; + a.y = 0; + bound(a); + if (n > 1) { + b = nodes[1]; + b.x = b.r; + b.y = 0; + bound(b); + if (n > 2) { + c = nodes[2]; + d3_layout_packPlace(a, b, c); + bound(c); + d3_layout_packInsert(a, c); + a._pack_prev = c; + d3_layout_packInsert(c, b); + b = a._pack_next; + for (i = 3; i < n; i++) { + d3_layout_packPlace(a, b, c = nodes[i]); + var isect = 0, s1 = 1, s2 = 1; + for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { + if (d3_layout_packIntersects(j, c)) { + isect = 1; + break; + } + } + if (isect == 1) { + for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { + if (d3_layout_packIntersects(k, c)) { + break; + } + } + } + if (isect) { + if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); + i--; + } else { + d3_layout_packInsert(a, c); + b = c; + bound(c); + } + } + } + } + var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; + for (i = 0; i < n; i++) { + c = nodes[i]; + c.x -= cx; + c.y -= cy; + cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); + } + node.r = cr; + nodes.forEach(d3_layout_packUnlink); + } + function d3_layout_packLink(node) { + node._pack_next = node._pack_prev = node; + } + function d3_layout_packUnlink(node) { + delete node._pack_next; + delete node._pack_prev; + } + function d3_layout_packTransform(node, x, y, k) { + var children = node.children; + node.x = x += k * node.x; + node.y = y += k * node.y; + node.r *= k; + if (children) { + var i = -1, n = children.length; + while (++i < n) d3_layout_packTransform(children[i], x, y, k); + } + } + function d3_layout_packPlace(a, b, c) { + var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; + if (db && (dx || dy)) { + var da = b.r + c.r, dc = dx * dx + dy * dy; + da *= da; + db *= db; + var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); + c.x = a.x + x * dx + y * dy; + c.y = a.y + x * dy - y * dx; + } else { + c.x = a.x + db; + c.y = a.y; + } + } + d3.layout.cluster = function() { + var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; + function cluster(d, i) { + var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; + d3_layout_treeVisitAfter(root, function(node) { + var children = node.children; + if (children && children.length) { + node.x = d3_layout_clusterX(children); + node.y = d3_layout_clusterY(children); + } else { + node.x = previousNode ? x += separation(node, previousNode) : 0; + node.y = 0; + previousNode = node; + } + }); + var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; + d3_layout_treeVisitAfter(root, nodeSize ? function(node) { + node.x = (node.x - root.x) * size[0]; + node.y = (root.y - node.y) * size[1]; + } : function(node) { + node.x = (node.x - x0) / (x1 - x0) * size[0]; + node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; + }); + return nodes; + } + cluster.separation = function(x) { + if (!arguments.length) return separation; + separation = x; + return cluster; + }; + cluster.size = function(x) { + if (!arguments.length) return nodeSize ? null : size; + nodeSize = (size = x) == null; + return cluster; + }; + cluster.nodeSize = function(x) { + if (!arguments.length) return nodeSize ? size : null; + nodeSize = (size = x) != null; + return cluster; + }; + return d3_layout_hierarchyRebind(cluster, hierarchy); + }; + function d3_layout_clusterY(children) { + return 1 + d3.max(children, function(child) { + return child.y; + }); + } + function d3_layout_clusterX(children) { + return children.reduce(function(x, child) { + return x + child.x; + }, 0) / children.length; + } + function d3_layout_clusterLeft(node) { + var children = node.children; + return children && children.length ? d3_layout_clusterLeft(children[0]) : node; + } + function d3_layout_clusterRight(node) { + var children = node.children, n; + return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; + } + d3.layout.treemap = function() { + var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); + function scale(children, k) { + var i = -1, n = children.length, child, area; + while (++i < n) { + area = (child = children[i]).value * (k < 0 ? 0 : k); + child.area = isNaN(area) || area <= 0 ? 0 : area; + } + } + function squarify(node) { + var children = node.children; + if (children && children.length) { + var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n; + scale(remaining, rect.dx * rect.dy / node.value); + row.area = 0; + while ((n = remaining.length) > 0) { + row.push(child = remaining[n - 1]); + row.area += child.area; + if (mode !== "squarify" || (score = worst(row, u)) <= best) { + remaining.pop(); + best = score; + } else { + row.area -= row.pop().area; + position(row, u, rect, false); + u = Math.min(rect.dx, rect.dy); + row.length = row.area = 0; + best = Infinity; + } + } + if (row.length) { + position(row, u, rect, true); + row.length = row.area = 0; + } + children.forEach(squarify); + } + } + function stickify(node) { + var children = node.children; + if (children && children.length) { + var rect = pad(node), remaining = children.slice(), child, row = []; + scale(remaining, rect.dx * rect.dy / node.value); + row.area = 0; + while (child = remaining.pop()) { + row.push(child); + row.area += child.area; + if (child.z != null) { + position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); + row.length = row.area = 0; + } + } + children.forEach(stickify); + } + } + function worst(row, u) { + var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; + while (++i < n) { + if (!(r = row[i].area)) continue; + if (r < rmin) rmin = r; + if (r > rmax) rmax = r; + } + s *= s; + u *= u; + return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; + } + function position(row, u, rect, flush) { + var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; + if (u == rect.dx) { + if (flush || v > rect.dy) v = rect.dy; + while (++i < n) { + o = row[i]; + o.x = x; + o.y = y; + o.dy = v; + x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); + } + o.z = true; + o.dx += rect.x + rect.dx - x; + rect.y += v; + rect.dy -= v; + } else { + if (flush || v > rect.dx) v = rect.dx; + while (++i < n) { + o = row[i]; + o.x = x; + o.y = y; + o.dx = v; + y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); + } + o.z = false; + o.dy += rect.y + rect.dy - y; + rect.x += v; + rect.dx -= v; + } + } + function treemap(d) { + var nodes = stickies || hierarchy(d), root = nodes[0]; + root.x = 0; + root.y = 0; + root.dx = size[0]; + root.dy = size[1]; + if (stickies) hierarchy.revalue(root); + scale([ root ], root.dx * root.dy / root.value); + (stickies ? stickify : squarify)(root); + if (sticky) stickies = nodes; + return nodes; + } + treemap.size = function(x) { + if (!arguments.length) return size; + size = x; + return treemap; + }; + treemap.padding = function(x) { + if (!arguments.length) return padding; + function padFunction(node) { + var p = x.call(treemap, node, node.depth); + return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); + } + function padConstant(node) { + return d3_layout_treemapPad(node, x); + } + var type; + pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], + padConstant) : padConstant; + return treemap; + }; + treemap.round = function(x) { + if (!arguments.length) return round != Number; + round = x ? Math.round : Number; + return treemap; + }; + treemap.sticky = function(x) { + if (!arguments.length) return sticky; + sticky = x; + stickies = null; + return treemap; + }; + treemap.ratio = function(x) { + if (!arguments.length) return ratio; + ratio = x; + return treemap; + }; + treemap.mode = function(x) { + if (!arguments.length) return mode; + mode = x + ""; + return treemap; + }; + return d3_layout_hierarchyRebind(treemap, hierarchy); + }; + function d3_layout_treemapPadNull(node) { + return { + x: node.x, + y: node.y, + dx: node.dx, + dy: node.dy + }; + } + function d3_layout_treemapPad(node, padding) { + var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; + if (dx < 0) { + x += dx / 2; + dx = 0; + } + if (dy < 0) { + y += dy / 2; + dy = 0; + } + return { + x: x, + y: y, + dx: dx, + dy: dy + }; + } + d3.random = { + normal: function(µ, σ) { + var n = arguments.length; + if (n < 2) σ = 1; + if (n < 1) µ = 0; + return function() { + var x, y, r; + do { + x = Math.random() * 2 - 1; + y = Math.random() * 2 - 1; + r = x * x + y * y; + } while (!r || r > 1); + return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); + }; + }, + logNormal: function() { + var random = d3.random.normal.apply(d3, arguments); + return function() { + return Math.exp(random()); + }; + }, + irwinHall: function(m) { + return function() { + for (var s = 0, j = 0; j < m; j++) s += Math.random(); + return s / m; + }; + } + }; + d3.scale = {}; + function d3_scaleExtent(domain) { + var start = domain[0], stop = domain[domain.length - 1]; + return start < stop ? [ start, stop ] : [ stop, start ]; + } + function d3_scaleRange(scale) { + return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); + } + function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { + var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); + return function(x) { + return i(u(x)); + }; + } + function d3_scale_nice(domain, nice) { + var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; + if (x1 < x0) { + dx = i0, i0 = i1, i1 = dx; + dx = x0, x0 = x1, x1 = dx; + } + domain[i0] = nice.floor(x0); + domain[i1] = nice.ceil(x1); + return domain; + } + function d3_scale_niceStep(step) { + return step ? { + floor: function(x) { + return Math.floor(x / step) * step; + }, + ceil: function(x) { + return Math.ceil(x / step) * step; + } + } : d3_scale_niceIdentity; + } + var d3_scale_niceIdentity = { + floor: d3_identity, + ceil: d3_identity + }; + function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { + var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; + if (domain[k] < domain[0]) { + domain = domain.slice().reverse(); + range = range.slice().reverse(); + } + while (++j <= k) { + u.push(uninterpolate(domain[j - 1], domain[j])); + i.push(interpolate(range[j - 1], range[j])); + } + return function(x) { + var j = d3.bisect(domain, x, 1, k) - 1; + return i[j](u[j](x)); + }; + } + d3.scale.linear = function() { + return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false); + }; + function d3_scale_linear(domain, range, interpolate, clamp) { + var output, input; + function rescale() { + var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; + output = linear(domain, range, uninterpolate, interpolate); + input = linear(range, domain, uninterpolate, d3_interpolate); + return scale; + } + function scale(x) { + return output(x); + } + scale.invert = function(y) { + return input(y); + }; + scale.domain = function(x) { + if (!arguments.length) return domain; + domain = x.map(Number); + return rescale(); + }; + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + return rescale(); + }; + scale.rangeRound = function(x) { + return scale.range(x).interpolate(d3_interpolateRound); + }; + scale.clamp = function(x) { + if (!arguments.length) return clamp; + clamp = x; + return rescale(); + }; + scale.interpolate = function(x) { + if (!arguments.length) return interpolate; + interpolate = x; + return rescale(); + }; + scale.ticks = function(m) { + return d3_scale_linearTicks(domain, m); + }; + scale.tickFormat = function(m, format) { + return d3_scale_linearTickFormat(domain, m, format); + }; + scale.nice = function(m) { + d3_scale_linearNice(domain, m); + return rescale(); + }; + scale.copy = function() { + return d3_scale_linear(domain, range, interpolate, clamp); + }; + return rescale(); + } + function d3_scale_linearRebind(scale, linear) { + return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); + } + function d3_scale_linearNice(domain, m) { + return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2])); + } + function d3_scale_linearTickRange(domain, m) { + if (m == null) m = 10; + var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; + if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; + extent[0] = Math.ceil(extent[0] / step) * step; + extent[1] = Math.floor(extent[1] / step) * step + step * .5; + extent[2] = step; + return extent; + } + function d3_scale_linearTicks(domain, m) { + return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); + } + function d3_scale_linearTickFormat(domain, m, format) { + var precision = -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01); + return d3.format(format ? format.replace(d3_format_re, function(a, b, c, d, e, f, g, h, i, j) { + return [ b, c, d, e, f, g, h, i || "." + (precision - (j === "%") * 2), j ].join(""); + }) : ",." + precision + "f"); + } + d3.scale.log = function() { + return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]); + }; + function d3_scale_log(linear, base, positive, domain) { + function log(x) { + return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base); + } + function pow(x) { + return positive ? Math.pow(base, x) : -Math.pow(base, -x); + } + function scale(x) { + return linear(log(x)); + } + scale.invert = function(x) { + return pow(linear.invert(x)); + }; + scale.domain = function(x) { + if (!arguments.length) return domain; + positive = x[0] >= 0; + linear.domain((domain = x.map(Number)).map(log)); + return scale; + }; + scale.base = function(_) { + if (!arguments.length) return base; + base = +_; + linear.domain(domain.map(log)); + return scale; + }; + scale.nice = function() { + var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative); + linear.domain(niced); + domain = niced.map(pow); + return scale; + }; + scale.ticks = function() { + var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base; + if (isFinite(j - i)) { + if (positive) { + for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k); + ticks.push(pow(i)); + } else { + ticks.push(pow(i)); + for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k); + } + for (i = 0; ticks[i] < u; i++) {} + for (j = ticks.length; ticks[j - 1] > v; j--) {} + ticks = ticks.slice(i, j); + } + return ticks; + }; + scale.tickFormat = function(n, format) { + if (!arguments.length) return d3_scale_logFormat; + if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format); + var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, + Math.floor), e; + return function(d) { + return d / pow(f(log(d) + e)) <= k ? format(d) : ""; + }; + }; + scale.copy = function() { + return d3_scale_log(linear.copy(), base, positive, domain); + }; + return d3_scale_linearRebind(scale, linear); + } + var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = { + floor: function(x) { + return -Math.ceil(-x); + }, + ceil: function(x) { + return -Math.floor(-x); + } + }; + d3.scale.pow = function() { + return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]); + }; + function d3_scale_pow(linear, exponent, domain) { + var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); + function scale(x) { + return linear(powp(x)); + } + scale.invert = function(x) { + return powb(linear.invert(x)); + }; + scale.domain = function(x) { + if (!arguments.length) return domain; + linear.domain((domain = x.map(Number)).map(powp)); + return scale; + }; + scale.ticks = function(m) { + return d3_scale_linearTicks(domain, m); + }; + scale.tickFormat = function(m, format) { + return d3_scale_linearTickFormat(domain, m, format); + }; + scale.nice = function(m) { + return scale.domain(d3_scale_linearNice(domain, m)); + }; + scale.exponent = function(x) { + if (!arguments.length) return exponent; + powp = d3_scale_powPow(exponent = x); + powb = d3_scale_powPow(1 / exponent); + linear.domain(domain.map(powp)); + return scale; + }; + scale.copy = function() { + return d3_scale_pow(linear.copy(), exponent, domain); + }; + return d3_scale_linearRebind(scale, linear); + } + function d3_scale_powPow(e) { + return function(x) { + return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); + }; + } + d3.scale.sqrt = function() { + return d3.scale.pow().exponent(.5); + }; + d3.scale.ordinal = function() { + return d3_scale_ordinal([], { + t: "range", + a: [ [] ] + }); + }; + function d3_scale_ordinal(domain, ranger) { + var index, range, rangeBand; + function scale(x) { + return range[((index.get(x) || ranger.t === "range" && index.set(x, domain.push(x))) - 1) % range.length]; + } + function steps(start, step) { + return d3.range(domain.length).map(function(i) { + return start + step * i; + }); + } + scale.domain = function(x) { + if (!arguments.length) return domain; + domain = []; + index = new d3_Map(); + var i = -1, n = x.length, xi; + while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); + return scale[ranger.t].apply(scale, ranger.a); + }; + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + rangeBand = 0; + ranger = { + t: "range", + a: arguments + }; + return scale; + }; + scale.rangePoints = function(x, padding) { + if (arguments.length < 2) padding = 0; + var start = x[0], stop = x[1], step = (stop - start) / (Math.max(1, domain.length - 1) + padding); + range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step); + rangeBand = 0; + ranger = { + t: "rangePoints", + a: arguments + }; + return scale; + }; + scale.rangeBands = function(x, padding, outerPadding) { + if (arguments.length < 2) padding = 0; + if (arguments.length < 3) outerPadding = padding; + var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); + range = steps(start + step * outerPadding, step); + if (reverse) range.reverse(); + rangeBand = step * (1 - padding); + ranger = { + t: "rangeBands", + a: arguments + }; + return scale; + }; + scale.rangeRoundBands = function(x, padding, outerPadding) { + if (arguments.length < 2) padding = 0; + if (arguments.length < 3) outerPadding = padding; + var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), error = stop - start - (domain.length - padding) * step; + range = steps(start + Math.round(error / 2), step); + if (reverse) range.reverse(); + rangeBand = Math.round(step * (1 - padding)); + ranger = { + t: "rangeRoundBands", + a: arguments + }; + return scale; + }; + scale.rangeBand = function() { + return rangeBand; + }; + scale.rangeExtent = function() { + return d3_scaleExtent(ranger.a[0]); + }; + scale.copy = function() { + return d3_scale_ordinal(domain, ranger); + }; + return scale.domain(domain); + } + d3.scale.category10 = function() { + return d3.scale.ordinal().range(d3_category10); + }; + d3.scale.category20 = function() { + return d3.scale.ordinal().range(d3_category20); + }; + d3.scale.category20b = function() { + return d3.scale.ordinal().range(d3_category20b); + }; + d3.scale.category20c = function() { + return d3.scale.ordinal().range(d3_category20c); + }; + var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString); + var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString); + var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString); + var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString); + d3.scale.quantile = function() { + return d3_scale_quantile([], []); + }; + function d3_scale_quantile(domain, range) { + var thresholds; + function rescale() { + var k = 0, q = range.length; + thresholds = []; + while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); + return scale; + } + function scale(x) { + if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)]; + } + scale.domain = function(x) { + if (!arguments.length) return domain; + domain = x.filter(function(d) { + return !isNaN(d); + }).sort(d3.ascending); + return rescale(); + }; + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + return rescale(); + }; + scale.quantiles = function() { + return thresholds; + }; + scale.invertExtent = function(y) { + y = range.indexOf(y); + return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ]; + }; + scale.copy = function() { + return d3_scale_quantile(domain, range); + }; + return rescale(); + } + d3.scale.quantize = function() { + return d3_scale_quantize(0, 1, [ 0, 1 ]); + }; + function d3_scale_quantize(x0, x1, range) { + var kx, i; + function scale(x) { + return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; + } + function rescale() { + kx = range.length / (x1 - x0); + i = range.length - 1; + return scale; + } + scale.domain = function(x) { + if (!arguments.length) return [ x0, x1 ]; + x0 = +x[0]; + x1 = +x[x.length - 1]; + return rescale(); + }; + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + return rescale(); + }; + scale.invertExtent = function(y) { + y = range.indexOf(y); + y = y < 0 ? NaN : y / kx + x0; + return [ y, y + 1 / kx ]; + }; + scale.copy = function() { + return d3_scale_quantize(x0, x1, range); + }; + return rescale(); + } + d3.scale.threshold = function() { + return d3_scale_threshold([ .5 ], [ 0, 1 ]); + }; + function d3_scale_threshold(domain, range) { + function scale(x) { + if (x <= x) return range[d3.bisect(domain, x)]; + } + scale.domain = function(_) { + if (!arguments.length) return domain; + domain = _; + return scale; + }; + scale.range = function(_) { + if (!arguments.length) return range; + range = _; + return scale; + }; + scale.invertExtent = function(y) { + y = range.indexOf(y); + return [ domain[y - 1], domain[y] ]; + }; + scale.copy = function() { + return d3_scale_threshold(domain, range); + }; + return scale; + } + d3.scale.identity = function() { + return d3_scale_identity([ 0, 1 ]); + }; + function d3_scale_identity(domain) { + function identity(x) { + return +x; + } + identity.invert = identity; + identity.domain = identity.range = function(x) { + if (!arguments.length) return domain; + domain = x.map(identity); + return identity; + }; + identity.ticks = function(m) { + return d3_scale_linearTicks(domain, m); + }; + identity.tickFormat = function(m, format) { + return d3_scale_linearTickFormat(domain, m, format); + }; + identity.copy = function() { + return d3_scale_identity(domain); + }; + return identity; + } + d3.svg.arc = function() { + var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; + function arc() { + var r0 = innerRadius.apply(this, arguments), r1 = outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset, a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset, da = (a1 < a0 && (da = a0, + a0 = a1, a1 = da), a1 - a0), df = da < π ? "0" : "1", c0 = Math.cos(a0), s0 = Math.sin(a0), c1 = Math.cos(a1), s1 = Math.sin(a1); + return da >= d3_svg_arcMax ? r0 ? "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "M0," + r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + -r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + r0 + "Z" : "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "Z" : r0 ? "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L" + r0 * c1 + "," + r0 * s1 + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0 + "Z" : "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L0,0" + "Z"; + } + arc.innerRadius = function(v) { + if (!arguments.length) return innerRadius; + innerRadius = d3_functor(v); + return arc; + }; + arc.outerRadius = function(v) { + if (!arguments.length) return outerRadius; + outerRadius = d3_functor(v); + return arc; + }; + arc.startAngle = function(v) { + if (!arguments.length) return startAngle; + startAngle = d3_functor(v); + return arc; + }; + arc.endAngle = function(v) { + if (!arguments.length) return endAngle; + endAngle = d3_functor(v); + return arc; + }; + arc.centroid = function() { + var r = (innerRadius.apply(this, arguments) + outerRadius.apply(this, arguments)) / 2, a = (startAngle.apply(this, arguments) + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset; + return [ Math.cos(a) * r, Math.sin(a) * r ]; + }; + return arc; + }; + var d3_svg_arcOffset = -π / 2, d3_svg_arcMax = 2 * π - 1e-6; + function d3_svg_arcInnerRadius(d) { + return d.innerRadius; + } + function d3_svg_arcOuterRadius(d) { + return d.outerRadius; + } + function d3_svg_arcStartAngle(d) { + return d.startAngle; + } + function d3_svg_arcEndAngle(d) { + return d.endAngle; + } + d3.svg.line.radial = function() { + var line = d3_svg_line(d3_svg_lineRadial); + line.radius = line.x, delete line.x; + line.angle = line.y, delete line.y; + return line; + }; + function d3_svg_lineRadial(points) { + var point, i = -1, n = points.length, r, a; + while (++i < n) { + point = points[i]; + r = point[0]; + a = point[1] + d3_svg_arcOffset; + point[0] = r * Math.cos(a); + point[1] = r * Math.sin(a); + } + return points; + } + function d3_svg_area(projection) { + var x0 = d3_svg_lineX, x1 = d3_svg_lineX, y0 = 0, y1 = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; + function area(data) { + var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { + return x; + } : d3_functor(x1), fy1 = y0 === y1 ? function() { + return y; + } : d3_functor(y1), x, y; + function segment() { + segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); + } + while (++i < n) { + if (defined.call(this, d = data[i], i)) { + points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); + points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); + } else if (points0.length) { + segment(); + points0 = []; + points1 = []; + } + } + if (points0.length) segment(); + return segments.length ? segments.join("") : null; + } + area.x = function(_) { + if (!arguments.length) return x1; + x0 = x1 = _; + return area; + }; + area.x0 = function(_) { + if (!arguments.length) return x0; + x0 = _; + return area; + }; + area.x1 = function(_) { + if (!arguments.length) return x1; + x1 = _; + return area; + }; + area.y = function(_) { + if (!arguments.length) return y1; + y0 = y1 = _; + return area; + }; + area.y0 = function(_) { + if (!arguments.length) return y0; + y0 = _; + return area; + }; + area.y1 = function(_) { + if (!arguments.length) return y1; + y1 = _; + return area; + }; + area.defined = function(_) { + if (!arguments.length) return defined; + defined = _; + return area; + }; + area.interpolate = function(_) { + if (!arguments.length) return interpolateKey; + if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; + interpolateReverse = interpolate.reverse || interpolate; + L = interpolate.closed ? "M" : "L"; + return area; + }; + area.tension = function(_) { + if (!arguments.length) return tension; + tension = _; + return area; + }; + return area; + } + d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; + d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; + d3.svg.area = function() { + return d3_svg_area(d3_identity); + }; + d3.svg.area.radial = function() { + var area = d3_svg_area(d3_svg_lineRadial); + area.radius = area.x, delete area.x; + area.innerRadius = area.x0, delete area.x0; + area.outerRadius = area.x1, delete area.x1; + area.angle = area.y, delete area.y; + area.startAngle = area.y0, delete area.y0; + area.endAngle = area.y1, delete area.y1; + return area; + }; + d3.svg.chord = function() { + var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; + function chord(d, i) { + var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); + return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; + } + function subgroup(self, f, d, i) { + var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset, a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset; + return { + r: r, + a0: a0, + a1: a1, + p0: [ r * Math.cos(a0), r * Math.sin(a0) ], + p1: [ r * Math.cos(a1), r * Math.sin(a1) ] + }; + } + function equals(a, b) { + return a.a0 == b.a0 && a.a1 == b.a1; + } + function arc(r, p, a) { + return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p; + } + function curve(r0, p0, r1, p1) { + return "Q 0,0 " + p1; + } + chord.radius = function(v) { + if (!arguments.length) return radius; + radius = d3_functor(v); + return chord; + }; + chord.source = function(v) { + if (!arguments.length) return source; + source = d3_functor(v); + return chord; + }; + chord.target = function(v) { + if (!arguments.length) return target; + target = d3_functor(v); + return chord; + }; + chord.startAngle = function(v) { + if (!arguments.length) return startAngle; + startAngle = d3_functor(v); + return chord; + }; + chord.endAngle = function(v) { + if (!arguments.length) return endAngle; + endAngle = d3_functor(v); + return chord; + }; + return chord; + }; + function d3_svg_chordRadius(d) { + return d.radius; + } + d3.svg.diagonal = function() { + var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; + function diagonal(d, i) { + var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { + x: p0.x, + y: m + }, { + x: p3.x, + y: m + }, p3 ]; + p = p.map(projection); + return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; + } + diagonal.source = function(x) { + if (!arguments.length) return source; + source = d3_functor(x); + return diagonal; + }; + diagonal.target = function(x) { + if (!arguments.length) return target; + target = d3_functor(x); + return diagonal; + }; + diagonal.projection = function(x) { + if (!arguments.length) return projection; + projection = x; + return diagonal; + }; + return diagonal; + }; + function d3_svg_diagonalProjection(d) { + return [ d.x, d.y ]; + } + d3.svg.diagonal.radial = function() { + var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; + diagonal.projection = function(x) { + return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; + }; + return diagonal; + }; + function d3_svg_diagonalRadialProjection(projection) { + return function() { + var d = projection.apply(this, arguments), r = d[0], a = d[1] + d3_svg_arcOffset; + return [ r * Math.cos(a), r * Math.sin(a) ]; + }; + } + d3.svg.symbol = function() { + var type = d3_svg_symbolType, size = d3_svg_symbolSize; + function symbol(d, i) { + return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); + } + symbol.type = function(x) { + if (!arguments.length) return type; + type = d3_functor(x); + return symbol; + }; + symbol.size = function(x) { + if (!arguments.length) return size; + size = d3_functor(x); + return symbol; + }; + return symbol; + }; + function d3_svg_symbolSize() { + return 64; + } + function d3_svg_symbolType() { + return "circle"; + } + function d3_svg_symbolCircle(size) { + var r = Math.sqrt(size / π); + return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; + } + var d3_svg_symbols = d3.map({ + circle: d3_svg_symbolCircle, + cross: function(size) { + var r = Math.sqrt(size / 5) / 2; + return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; + }, + diamond: function(size) { + var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; + return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; + }, + square: function(size) { + var r = Math.sqrt(size) / 2; + return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; + }, + "triangle-down": function(size) { + var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; + return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; + }, + "triangle-up": function(size) { + var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; + return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; + } + }); + d3.svg.symbolTypes = d3_svg_symbols.keys(); + var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); + function d3_transition(groups, id) { + d3_subclass(groups, d3_transitionPrototype); + groups.id = id; + return groups; + } + var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit; + d3_transitionPrototype.call = d3_selectionPrototype.call; + d3_transitionPrototype.empty = d3_selectionPrototype.empty; + d3_transitionPrototype.node = d3_selectionPrototype.node; + d3_transitionPrototype.size = d3_selectionPrototype.size; + d3.transition = function(selection) { + return arguments.length ? d3_transitionInheritId ? selection.transition() : selection : d3_selectionRoot.transition(); + }; + d3.transition.prototype = d3_transitionPrototype; + d3_transitionPrototype.select = function(selector) { + var id = this.id, subgroups = [], subgroup, subnode, node; + selector = d3_selection_selector(selector); + for (var j = -1, m = this.length; ++j < m; ) { + subgroups.push(subgroup = []); + for (var group = this[j], i = -1, n = group.length; ++i < n; ) { + if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) { + if ("__data__" in node) subnode.__data__ = node.__data__; + d3_transitionNode(subnode, i, id, node.__transition__[id]); + subgroup.push(subnode); + } else { + subgroup.push(null); + } + } + } + return d3_transition(subgroups, id); + }; + d3_transitionPrototype.selectAll = function(selector) { + var id = this.id, subgroups = [], subgroup, subnodes, node, subnode, transition; + selector = d3_selection_selectorAll(selector); + for (var j = -1, m = this.length; ++j < m; ) { + for (var group = this[j], i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) { + transition = node.__transition__[id]; + subnodes = selector.call(node, node.__data__, i, j); + subgroups.push(subgroup = []); + for (var k = -1, o = subnodes.length; ++k < o; ) { + if (subnode = subnodes[k]) d3_transitionNode(subnode, k, id, transition); + subgroup.push(subnode); + } + } + } + } + return d3_transition(subgroups, id); + }; + d3_transitionPrototype.filter = function(filter) { + var subgroups = [], subgroup, group, node; + if (typeof filter !== "function") filter = d3_selection_filter(filter); + for (var j = 0, m = this.length; j < m; j++) { + subgroups.push(subgroup = []); + for (var group = this[j], i = 0, n = group.length; i < n; i++) { + if ((node = group[i]) && filter.call(node, node.__data__, i)) { + subgroup.push(node); + } + } + } + return d3_transition(subgroups, this.id); + }; + d3_transitionPrototype.tween = function(name, tween) { + var id = this.id; + if (arguments.length < 2) return this.node().__transition__[id].tween.get(name); + return d3_selection_each(this, tween == null ? function(node) { + node.__transition__[id].tween.remove(name); + } : function(node) { + node.__transition__[id].tween.set(name, tween); + }); + }; + function d3_transition_tween(groups, name, value, tween) { + var id = groups.id; + return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { + node.__transition__[id].tween.set(name, tween(value.call(node, node.__data__, i, j))); + } : (value = tween(value), function(node) { + node.__transition__[id].tween.set(name, value); + })); + } + d3_transitionPrototype.attr = function(nameNS, value) { + if (arguments.length < 2) { + for (value in nameNS) this.attr(value, nameNS[value]); + return this; + } + var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS); + function attrNull() { + this.removeAttribute(name); + } + function attrNullNS() { + this.removeAttributeNS(name.space, name.local); + } + function attrTween(b) { + return b == null ? attrNull : (b += "", function() { + var a = this.getAttribute(name), i; + return a !== b && (i = interpolate(a, b), function(t) { + this.setAttribute(name, i(t)); + }); + }); + } + function attrTweenNS(b) { + return b == null ? attrNullNS : (b += "", function() { + var a = this.getAttributeNS(name.space, name.local), i; + return a !== b && (i = interpolate(a, b), function(t) { + this.setAttributeNS(name.space, name.local, i(t)); + }); + }); + } + return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); + }; + d3_transitionPrototype.attrTween = function(nameNS, tween) { + var name = d3.ns.qualify(nameNS); + function attrTween(d, i) { + var f = tween.call(this, d, i, this.getAttribute(name)); + return f && function(t) { + this.setAttribute(name, f(t)); + }; + } + function attrTweenNS(d, i) { + var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); + return f && function(t) { + this.setAttributeNS(name.space, name.local, f(t)); + }; + } + return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); + }; + d3_transitionPrototype.style = function(name, value, priority) { + var n = arguments.length; + if (n < 3) { + if (typeof name !== "string") { + if (n < 2) value = ""; + for (priority in name) this.style(priority, name[priority], value); + return this; + } + priority = ""; + } + function styleNull() { + this.style.removeProperty(name); + } + function styleString(b) { + return b == null ? styleNull : (b += "", function() { + var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i; + return a !== b && (i = d3_interpolate(a, b), function(t) { + this.style.setProperty(name, i(t), priority); + }); + }); + } + return d3_transition_tween(this, "style." + name, value, styleString); + }; + d3_transitionPrototype.styleTween = function(name, tween, priority) { + if (arguments.length < 3) priority = ""; + function styleTween(d, i) { + var f = tween.call(this, d, i, d3_window.getComputedStyle(this, null).getPropertyValue(name)); + return f && function(t) { + this.style.setProperty(name, f(t), priority); + }; + } + return this.tween("style." + name, styleTween); + }; + d3_transitionPrototype.text = function(value) { + return d3_transition_tween(this, "text", value, d3_transition_text); + }; + function d3_transition_text(b) { + if (b == null) b = ""; + return function() { + this.textContent = b; + }; + } + d3_transitionPrototype.remove = function() { + return this.each("end.transition", function() { + var p; + if (this.__transition__.count < 2 && (p = this.parentNode)) p.removeChild(this); + }); + }; + d3_transitionPrototype.ease = function(value) { + var id = this.id; + if (arguments.length < 1) return this.node().__transition__[id].ease; + if (typeof value !== "function") value = d3.ease.apply(d3, arguments); + return d3_selection_each(this, function(node) { + node.__transition__[id].ease = value; + }); + }; + d3_transitionPrototype.delay = function(value) { + var id = this.id; + return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { + node.__transition__[id].delay = +value.call(node, node.__data__, i, j); + } : (value = +value, function(node) { + node.__transition__[id].delay = value; + })); + }; + d3_transitionPrototype.duration = function(value) { + var id = this.id; + return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { + node.__transition__[id].duration = Math.max(1, value.call(node, node.__data__, i, j)); + } : (value = Math.max(1, value), function(node) { + node.__transition__[id].duration = value; + })); + }; + d3_transitionPrototype.each = function(type, listener) { + var id = this.id; + if (arguments.length < 2) { + var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; + d3_transitionInheritId = id; + d3_selection_each(this, function(node, i, j) { + d3_transitionInherit = node.__transition__[id]; + type.call(node, node.__data__, i, j); + }); + d3_transitionInherit = inherit; + d3_transitionInheritId = inheritId; + } else { + d3_selection_each(this, function(node) { + var transition = node.__transition__[id]; + (transition.event || (transition.event = d3.dispatch("start", "end"))).on(type, listener); + }); + } + return this; + }; + d3_transitionPrototype.transition = function() { + var id0 = this.id, id1 = ++d3_transitionId, subgroups = [], subgroup, group, node, transition; + for (var j = 0, m = this.length; j < m; j++) { + subgroups.push(subgroup = []); + for (var group = this[j], i = 0, n = group.length; i < n; i++) { + if (node = group[i]) { + transition = Object.create(node.__transition__[id0]); + transition.delay += transition.duration; + d3_transitionNode(node, i, id1, transition); + } + subgroup.push(node); + } + } + return d3_transition(subgroups, id1); + }; + function d3_transitionNode(node, i, id, inherit) { + var lock = node.__transition__ || (node.__transition__ = { + active: 0, + count: 0 + }), transition = lock[id]; + if (!transition) { + var time = inherit.time; + transition = lock[id] = { + tween: new d3_Map(), + time: time, + ease: inherit.ease, + delay: inherit.delay, + duration: inherit.duration + }; + ++lock.count; + d3.timer(function(elapsed) { + var d = node.__data__, ease = transition.ease, delay = transition.delay, duration = transition.duration, tweened = []; + if (delay <= elapsed) return start(elapsed); + d3_timer_replace(start, delay, time); + function start(elapsed) { + if (lock.active > id) return stop(); + lock.active = id; + transition.event && transition.event.start.call(node, d, i); + transition.tween.forEach(function(key, value) { + if (value = value.call(node, d, i)) { + tweened.push(value); + } + }); + if (tick(elapsed)) return 1; + d3_timer_replace(tick, 0, time); + } + function tick(elapsed) { + if (lock.active !== id) return stop(); + var t = (elapsed - delay) / duration, e = ease(t), n = tweened.length; + while (n > 0) { + tweened[--n].call(node, e); + } + if (t >= 1) { + transition.event && transition.event.end.call(node, d, i); + return stop(); + } + } + function stop() { + if (--lock.count) delete lock[id]; else delete node.__transition__; + return 1; + } + }, 0, time); + } + } + d3.svg.axis = function() { + var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_; + function axis(g) { + g.each(function() { + var g = d3.select(this); + var ticks = tickValues == null ? scale.ticks ? scale.ticks.apply(scale, tickArguments_) : scale.domain() : tickValues, tickFormat = tickFormat_ == null ? scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6), tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).remove(), tickUpdate = d3.transition(tick).style("opacity", 1), tickTransform; + var range = d3_scaleRange(scale), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), + d3.transition(path)); + var scale1 = scale.copy(), scale0 = this.__chart__ || scale1; + this.__chart__ = scale1; + tickEnter.append("line"); + tickEnter.append("text"); + var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"); + switch (orient) { + case "bottom": + { + tickTransform = d3_svg_axisX; + lineEnter.attr("y2", innerTickSize); + textEnter.attr("y", Math.max(innerTickSize, 0) + tickPadding); + lineUpdate.attr("x2", 0).attr("y2", innerTickSize); + textUpdate.attr("x", 0).attr("y", Math.max(innerTickSize, 0) + tickPadding); + text.attr("dy", ".71em").style("text-anchor", "middle"); + pathUpdate.attr("d", "M" + range[0] + "," + outerTickSize + "V0H" + range[1] + "V" + outerTickSize); + break; + } + + case "top": + { + tickTransform = d3_svg_axisX; + lineEnter.attr("y2", -innerTickSize); + textEnter.attr("y", -(Math.max(innerTickSize, 0) + tickPadding)); + lineUpdate.attr("x2", 0).attr("y2", -innerTickSize); + textUpdate.attr("x", 0).attr("y", -(Math.max(innerTickSize, 0) + tickPadding)); + text.attr("dy", "0em").style("text-anchor", "middle"); + pathUpdate.attr("d", "M" + range[0] + "," + -outerTickSize + "V0H" + range[1] + "V" + -outerTickSize); + break; + } + + case "left": + { + tickTransform = d3_svg_axisY; + lineEnter.attr("x2", -innerTickSize); + textEnter.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)); + lineUpdate.attr("x2", -innerTickSize).attr("y2", 0); + textUpdate.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)).attr("y", 0); + text.attr("dy", ".32em").style("text-anchor", "end"); + pathUpdate.attr("d", "M" + -outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + -outerTickSize); + break; + } + + case "right": + { + tickTransform = d3_svg_axisY; + lineEnter.attr("x2", innerTickSize); + textEnter.attr("x", Math.max(innerTickSize, 0) + tickPadding); + lineUpdate.attr("x2", innerTickSize).attr("y2", 0); + textUpdate.attr("x", Math.max(innerTickSize, 0) + tickPadding).attr("y", 0); + text.attr("dy", ".32em").style("text-anchor", "start"); + pathUpdate.attr("d", "M" + outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + outerTickSize); + break; + } + } + if (scale.rangeBand) { + var dx = scale1.rangeBand() / 2, x = function(d) { + return scale1(d) + dx; + }; + tickEnter.call(tickTransform, x); + tickUpdate.call(tickTransform, x); + } else { + tickEnter.call(tickTransform, scale0); + tickUpdate.call(tickTransform, scale1); + tickExit.call(tickTransform, scale1); + } + }); + } + axis.scale = function(x) { + if (!arguments.length) return scale; + scale = x; + return axis; + }; + axis.orient = function(x) { + if (!arguments.length) return orient; + orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; + return axis; + }; + axis.ticks = function() { + if (!arguments.length) return tickArguments_; + tickArguments_ = arguments; + return axis; + }; + axis.tickValues = function(x) { + if (!arguments.length) return tickValues; + tickValues = x; + return axis; + }; + axis.tickFormat = function(x) { + if (!arguments.length) return tickFormat_; + tickFormat_ = x; + return axis; + }; + axis.tickSize = function(x) { + var n = arguments.length; + if (!n) return innerTickSize; + innerTickSize = +x; + outerTickSize = +arguments[n - 1]; + return axis; + }; + axis.innerTickSize = function(x) { + if (!arguments.length) return innerTickSize; + innerTickSize = +x; + return axis; + }; + axis.outerTickSize = function(x) { + if (!arguments.length) return outerTickSize; + outerTickSize = +x; + return axis; + }; + axis.tickPadding = function(x) { + if (!arguments.length) return tickPadding; + tickPadding = +x; + return axis; + }; + axis.tickSubdivide = function() { + return arguments.length && axis; + }; + return axis; + }; + var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = { + top: 1, + right: 1, + bottom: 1, + left: 1 + }; + function d3_svg_axisX(selection, x) { + selection.attr("transform", function(d) { + return "translate(" + x(d) + ",0)"; + }); + } + function d3_svg_axisY(selection, y) { + selection.attr("transform", function(d) { + return "translate(0," + y(d) + ")"; + }); + } + d3.svg.brush = function() { + var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0]; + function brush(g) { + g.each(function() { + var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); + var background = g.selectAll(".background").data([ 0 ]); + background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); + g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move"); + var resize = g.selectAll(".resize").data(resizes, d3_identity); + resize.exit().remove(); + resize.enter().append("g").attr("class", function(d) { + return "resize " + d; + }).style("cursor", function(d) { + return d3_svg_brushCursor[d]; + }).append("rect").attr("x", function(d) { + return /[ew]$/.test(d) ? -3 : null; + }).attr("y", function(d) { + return /^[ns]/.test(d) ? -3 : null; + }).attr("width", 6).attr("height", 6).style("visibility", "hidden"); + resize.style("display", brush.empty() ? "none" : null); + var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range; + if (x) { + range = d3_scaleRange(x); + backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]); + redrawX(gUpdate); + } + if (y) { + range = d3_scaleRange(y); + backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]); + redrawY(gUpdate); + } + redraw(gUpdate); + }); + } + brush.event = function(g) { + g.each(function() { + var event_ = event.of(this, arguments), extent1 = { + x: xExtent, + y: yExtent, + i: xExtentDomain, + j: yExtentDomain + }, extent0 = this.__chart__ || extent1; + this.__chart__ = extent1; + if (d3_transitionInheritId) { + d3.select(this).transition().each("start.brush", function() { + xExtentDomain = extent0.i; + yExtentDomain = extent0.j; + xExtent = extent0.x; + yExtent = extent0.y; + event_({ + type: "brushstart" + }); + }).tween("brush:brush", function() { + var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y); + xExtentDomain = yExtentDomain = null; + return function(t) { + xExtent = extent1.x = xi(t); + yExtent = extent1.y = yi(t); + event_({ + type: "brush", + mode: "resize" + }); + }; + }).each("end.brush", function() { + xExtentDomain = extent1.i; + yExtentDomain = extent1.j; + event_({ + type: "brush", + mode: "resize" + }); + event_({ + type: "brushend" + }); + }); + } else { + event_({ + type: "brushstart" + }); + event_({ + type: "brush", + mode: "resize" + }); + event_({ + type: "brushend" + }); + } + }); + }; + function redraw(g) { + g.selectAll(".resize").attr("transform", function(d) { + return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")"; + }); + } + function redrawX(g) { + g.select(".extent").attr("x", xExtent[0]); + g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]); + } + function redrawY(g) { + g.select(".extent").attr("y", yExtent[0]); + g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]); + } + function brushstart() { + var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(), center, origin = d3.mouse(target), offset; + var w = d3.select(d3_window).on("keydown.brush", keydown).on("keyup.brush", keyup); + if (d3.event.changedTouches) { + w.on("touchmove.brush", brushmove).on("touchend.brush", brushend); + } else { + w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend); + } + g.interrupt().selectAll("*").interrupt(); + if (dragging) { + origin[0] = xExtent[0] - origin[0]; + origin[1] = yExtent[0] - origin[1]; + } else if (resizing) { + var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); + offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ]; + origin[0] = xExtent[ex]; + origin[1] = yExtent[ey]; + } else if (d3.event.altKey) center = origin.slice(); + g.style("pointer-events", "none").selectAll(".resize").style("display", null); + d3.select("body").style("cursor", eventTarget.style("cursor")); + event_({ + type: "brushstart" + }); + brushmove(); + function keydown() { + if (d3.event.keyCode == 32) { + if (!dragging) { + center = null; + origin[0] -= xExtent[1]; + origin[1] -= yExtent[1]; + dragging = 2; + } + d3_eventPreventDefault(); + } + } + function keyup() { + if (d3.event.keyCode == 32 && dragging == 2) { + origin[0] += xExtent[1]; + origin[1] += yExtent[1]; + dragging = 0; + d3_eventPreventDefault(); + } + } + function brushmove() { + var point = d3.mouse(target), moved = false; + if (offset) { + point[0] += offset[0]; + point[1] += offset[1]; + } + if (!dragging) { + if (d3.event.altKey) { + if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ]; + origin[0] = xExtent[+(point[0] < center[0])]; + origin[1] = yExtent[+(point[1] < center[1])]; + } else center = null; + } + if (resizingX && move1(point, x, 0)) { + redrawX(g); + moved = true; + } + if (resizingY && move1(point, y, 1)) { + redrawY(g); + moved = true; + } + if (moved) { + redraw(g); + event_({ + type: "brush", + mode: dragging ? "move" : "resize" + }); + } + } + function move1(point, scale, i) { + var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max; + if (dragging) { + r0 -= position; + r1 -= size + position; + } + min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i]; + if (dragging) { + max = (min += position) + size; + } else { + if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); + if (position < min) { + max = min; + min = position; + } else { + max = position; + } + } + if (extent[0] != min || extent[1] != max) { + if (i) yExtentDomain = null; else xExtentDomain = null; + extent[0] = min; + extent[1] = max; + return true; + } + } + function brushend() { + brushmove(); + g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); + d3.select("body").style("cursor", null); + w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); + dragRestore(); + event_({ + type: "brushend" + }); + } + } + brush.x = function(z) { + if (!arguments.length) return x; + x = z; + resizes = d3_svg_brushResizes[!x << 1 | !y]; + return brush; + }; + brush.y = function(z) { + if (!arguments.length) return y; + y = z; + resizes = d3_svg_brushResizes[!x << 1 | !y]; + return brush; + }; + brush.clamp = function(z) { + if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null; + if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z; + return brush; + }; + brush.extent = function(z) { + var x0, x1, y0, y1, t; + if (!arguments.length) { + if (x) { + if (xExtentDomain) { + x0 = xExtentDomain[0], x1 = xExtentDomain[1]; + } else { + x0 = xExtent[0], x1 = xExtent[1]; + if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); + if (x1 < x0) t = x0, x0 = x1, x1 = t; + } + } + if (y) { + if (yExtentDomain) { + y0 = yExtentDomain[0], y1 = yExtentDomain[1]; + } else { + y0 = yExtent[0], y1 = yExtent[1]; + if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); + if (y1 < y0) t = y0, y0 = y1, y1 = t; + } + } + return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; + } + if (x) { + x0 = z[0], x1 = z[1]; + if (y) x0 = x0[0], x1 = x1[0]; + xExtentDomain = [ x0, x1 ]; + if (x.invert) x0 = x(x0), x1 = x(x1); + if (x1 < x0) t = x0, x0 = x1, x1 = t; + if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ]; + } + if (y) { + y0 = z[0], y1 = z[1]; + if (x) y0 = y0[1], y1 = y1[1]; + yExtentDomain = [ y0, y1 ]; + if (y.invert) y0 = y(y0), y1 = y(y1); + if (y1 < y0) t = y0, y0 = y1, y1 = t; + if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ]; + } + return brush; + }; + brush.clear = function() { + if (!brush.empty()) { + xExtent = [ 0, 0 ], yExtent = [ 0, 0 ]; + xExtentDomain = yExtentDomain = null; + } + return brush; + }; + brush.empty = function() { + return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1]; + }; + return d3.rebind(brush, event, "on"); + }; + var d3_svg_brushCursor = { + n: "ns-resize", + e: "ew-resize", + s: "ns-resize", + w: "ew-resize", + nw: "nwse-resize", + ne: "nesw-resize", + se: "nwse-resize", + sw: "nesw-resize" + }; + var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; + var d3_time = d3.time = {}, d3_date = Date, d3_time_daySymbols = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ]; + function d3_date_utc() { + this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); + } + d3_date_utc.prototype = { + getDate: function() { + return this._.getUTCDate(); + }, + getDay: function() { + return this._.getUTCDay(); + }, + getFullYear: function() { + return this._.getUTCFullYear(); + }, + getHours: function() { + return this._.getUTCHours(); + }, + getMilliseconds: function() { + return this._.getUTCMilliseconds(); + }, + getMinutes: function() { + return this._.getUTCMinutes(); + }, + getMonth: function() { + return this._.getUTCMonth(); + }, + getSeconds: function() { + return this._.getUTCSeconds(); + }, + getTime: function() { + return this._.getTime(); + }, + getTimezoneOffset: function() { + return 0; + }, + valueOf: function() { + return this._.valueOf(); + }, + setDate: function() { + d3_time_prototype.setUTCDate.apply(this._, arguments); + }, + setDay: function() { + d3_time_prototype.setUTCDay.apply(this._, arguments); + }, + setFullYear: function() { + d3_time_prototype.setUTCFullYear.apply(this._, arguments); + }, + setHours: function() { + d3_time_prototype.setUTCHours.apply(this._, arguments); + }, + setMilliseconds: function() { + d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); + }, + setMinutes: function() { + d3_time_prototype.setUTCMinutes.apply(this._, arguments); + }, + setMonth: function() { + d3_time_prototype.setUTCMonth.apply(this._, arguments); + }, + setSeconds: function() { + d3_time_prototype.setUTCSeconds.apply(this._, arguments); + }, + setTime: function() { + d3_time_prototype.setTime.apply(this._, arguments); + } + }; + var d3_time_prototype = Date.prototype; + var d3_time_formatDateTime = "%a %b %e %X %Y", d3_time_formatDate = "%m/%d/%Y", d3_time_formatTime = "%H:%M:%S"; + var d3_time_days = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], d3_time_dayAbbreviations = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], d3_time_months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], d3_time_monthAbbreviations = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; + function d3_time_interval(local, step, number) { + function round(date) { + var d0 = local(date), d1 = offset(d0, 1); + return date - d0 < d1 - date ? d0 : d1; + } + function ceil(date) { + step(date = local(new d3_date(date - 1)), 1); + return date; + } + function offset(date, k) { + step(date = new d3_date(+date), k); + return date; + } + function range(t0, t1, dt) { + var time = ceil(t0), times = []; + if (dt > 1) { + while (time < t1) { + if (!(number(time) % dt)) times.push(new Date(+time)); + step(time, 1); + } + } else { + while (time < t1) times.push(new Date(+time)), step(time, 1); + } + return times; + } + function range_utc(t0, t1, dt) { + try { + d3_date = d3_date_utc; + var utc = new d3_date_utc(); + utc._ = t0; + return range(utc, t1, dt); + } finally { + d3_date = Date; + } + } + local.floor = local; + local.round = round; + local.ceil = ceil; + local.offset = offset; + local.range = range; + var utc = local.utc = d3_time_interval_utc(local); + utc.floor = utc; + utc.round = d3_time_interval_utc(round); + utc.ceil = d3_time_interval_utc(ceil); + utc.offset = d3_time_interval_utc(offset); + utc.range = range_utc; + return local; + } + function d3_time_interval_utc(method) { + return function(date, k) { + try { + d3_date = d3_date_utc; + var utc = new d3_date_utc(); + utc._ = date; + return method(utc, k)._; + } finally { + d3_date = Date; + } + }; + } + d3_time.year = d3_time_interval(function(date) { + date = d3_time.day(date); + date.setMonth(0, 1); + return date; + }, function(date, offset) { + date.setFullYear(date.getFullYear() + offset); + }, function(date) { + return date.getFullYear(); + }); + d3_time.years = d3_time.year.range; + d3_time.years.utc = d3_time.year.utc.range; + d3_time.day = d3_time_interval(function(date) { + var day = new d3_date(2e3, 0); + day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); + return day; + }, function(date, offset) { + date.setDate(date.getDate() + offset); + }, function(date) { + return date.getDate() - 1; + }); + d3_time.days = d3_time.day.range; + d3_time.days.utc = d3_time.day.utc.range; + d3_time.dayOfYear = function(date) { + var year = d3_time.year(date); + return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); + }; + d3_time_daySymbols.forEach(function(day, i) { + day = day.toLowerCase(); + i = 7 - i; + var interval = d3_time[day] = d3_time_interval(function(date) { + (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); + return date; + }, function(date, offset) { + date.setDate(date.getDate() + Math.floor(offset) * 7); + }, function(date) { + var day = d3_time.year(date).getDay(); + return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); + }); + d3_time[day + "s"] = interval.range; + d3_time[day + "s"].utc = interval.utc.range; + d3_time[day + "OfYear"] = function(date) { + var day = d3_time.year(date).getDay(); + return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7); + }; + }); + d3_time.week = d3_time.sunday; + d3_time.weeks = d3_time.sunday.range; + d3_time.weeks.utc = d3_time.sunday.utc.range; + d3_time.weekOfYear = d3_time.sundayOfYear; + d3_time.format = d3_time_format; + function d3_time_format(template) { + var n = template.length; + function format(date) { + var string = [], i = -1, j = 0, c, p, f; + while (++i < n) { + if (template.charCodeAt(i) === 37) { + string.push(template.substring(j, i)); + if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); + if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); + string.push(c); + j = i + 1; + } + } + string.push(template.substring(j, i)); + return string.join(""); + } + format.parse = function(string) { + var d = { + y: 1900, + m: 0, + d: 1, + H: 0, + M: 0, + S: 0, + L: 0, + Z: null + }, i = d3_time_parse(d, template, string, 0); + if (i != string.length) return null; + if ("p" in d) d.H = d.H % 12 + d.p * 12; + var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)(); + if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) { + date.setFullYear(d.y, 0, 1); + date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7); + } else date.setFullYear(d.y, d.m, d.d); + date.setHours(d.H + Math.floor(d.Z / 100), d.M + d.Z % 100, d.S, d.L); + return localZ ? date._ : date; + }; + format.toString = function() { + return template; + }; + return format; + } + function d3_time_parse(date, template, string, j) { + var c, p, t, i = 0, n = template.length, m = string.length; + while (i < n) { + if (j >= m) return -1; + c = template.charCodeAt(i++); + if (c === 37) { + t = template.charAt(i++); + p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t]; + if (!p || (j = p(date, string, j)) < 0) return -1; + } else if (c != string.charCodeAt(j++)) { + return -1; + } + } + return j; + } + function d3_time_formatRe(names) { + return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); + } + function d3_time_formatLookup(names) { + var map = new d3_Map(), i = -1, n = names.length; + while (++i < n) map.set(names[i].toLowerCase(), i); + return map; + } + function d3_time_formatPad(value, fill, width) { + var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length; + return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); + } + var d3_time_dayRe = d3_time_formatRe(d3_time_days), d3_time_dayLookup = d3_time_formatLookup(d3_time_days), d3_time_dayAbbrevRe = d3_time_formatRe(d3_time_dayAbbreviations), d3_time_dayAbbrevLookup = d3_time_formatLookup(d3_time_dayAbbreviations), d3_time_monthRe = d3_time_formatRe(d3_time_months), d3_time_monthLookup = d3_time_formatLookup(d3_time_months), d3_time_monthAbbrevRe = d3_time_formatRe(d3_time_monthAbbreviations), d3_time_monthAbbrevLookup = d3_time_formatLookup(d3_time_monthAbbreviations), d3_time_percentRe = /^%/; + var d3_time_formatPads = { + "-": "", + _: " ", + "0": "0" + }; + var d3_time_formats = { + a: function(d) { + return d3_time_dayAbbreviations[d.getDay()]; + }, + A: function(d) { + return d3_time_days[d.getDay()]; + }, + b: function(d) { + return d3_time_monthAbbreviations[d.getMonth()]; + }, + B: function(d) { + return d3_time_months[d.getMonth()]; + }, + c: d3_time_format(d3_time_formatDateTime), + d: function(d, p) { + return d3_time_formatPad(d.getDate(), p, 2); + }, + e: function(d, p) { + return d3_time_formatPad(d.getDate(), p, 2); + }, + H: function(d, p) { + return d3_time_formatPad(d.getHours(), p, 2); + }, + I: function(d, p) { + return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); + }, + j: function(d, p) { + return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3); + }, + L: function(d, p) { + return d3_time_formatPad(d.getMilliseconds(), p, 3); + }, + m: function(d, p) { + return d3_time_formatPad(d.getMonth() + 1, p, 2); + }, + M: function(d, p) { + return d3_time_formatPad(d.getMinutes(), p, 2); + }, + p: function(d) { + return d.getHours() >= 12 ? "PM" : "AM"; + }, + S: function(d, p) { + return d3_time_formatPad(d.getSeconds(), p, 2); + }, + U: function(d, p) { + return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2); + }, + w: function(d) { + return d.getDay(); + }, + W: function(d, p) { + return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2); + }, + x: d3_time_format(d3_time_formatDate), + X: d3_time_format(d3_time_formatTime), + y: function(d, p) { + return d3_time_formatPad(d.getFullYear() % 100, p, 2); + }, + Y: function(d, p) { + return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); + }, + Z: d3_time_zone, + "%": function() { + return "%"; + } + }; + var d3_time_parsers = { + a: d3_time_parseWeekdayAbbrev, + A: d3_time_parseWeekday, + b: d3_time_parseMonthAbbrev, + B: d3_time_parseMonth, + c: d3_time_parseLocaleFull, + d: d3_time_parseDay, + e: d3_time_parseDay, + H: d3_time_parseHour24, + I: d3_time_parseHour24, + j: d3_time_parseDayOfYear, + L: d3_time_parseMilliseconds, + m: d3_time_parseMonthNumber, + M: d3_time_parseMinutes, + p: d3_time_parseAmPm, + S: d3_time_parseSeconds, + U: d3_time_parseWeekNumberSunday, + w: d3_time_parseWeekdayNumber, + W: d3_time_parseWeekNumberMonday, + x: d3_time_parseLocaleDate, + X: d3_time_parseLocaleTime, + y: d3_time_parseYear, + Y: d3_time_parseFullYear, + Z: d3_time_parseZone, + "%": d3_time_parseLiteralPercent + }; + function d3_time_parseWeekdayAbbrev(date, string, i) { + d3_time_dayAbbrevRe.lastIndex = 0; + var n = d3_time_dayAbbrevRe.exec(string.substring(i)); + return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; + } + function d3_time_parseWeekday(date, string, i) { + d3_time_dayRe.lastIndex = 0; + var n = d3_time_dayRe.exec(string.substring(i)); + return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; + } + function d3_time_parseWeekdayNumber(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 1)); + return n ? (date.w = +n[0], i + n[0].length) : -1; + } + function d3_time_parseWeekNumberSunday(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i)); + return n ? (date.U = +n[0], i + n[0].length) : -1; + } + function d3_time_parseWeekNumberMonday(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i)); + return n ? (date.W = +n[0], i + n[0].length) : -1; + } + function d3_time_parseMonthAbbrev(date, string, i) { + d3_time_monthAbbrevRe.lastIndex = 0; + var n = d3_time_monthAbbrevRe.exec(string.substring(i)); + return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; + } + function d3_time_parseMonth(date, string, i) { + d3_time_monthRe.lastIndex = 0; + var n = d3_time_monthRe.exec(string.substring(i)); + return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; + } + function d3_time_parseLocaleFull(date, string, i) { + return d3_time_parse(date, d3_time_formats.c.toString(), string, i); + } + function d3_time_parseLocaleDate(date, string, i) { + return d3_time_parse(date, d3_time_formats.x.toString(), string, i); + } + function d3_time_parseLocaleTime(date, string, i) { + return d3_time_parse(date, d3_time_formats.X.toString(), string, i); + } + function d3_time_parseFullYear(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 4)); + return n ? (date.y = +n[0], i + n[0].length) : -1; + } + function d3_time_parseYear(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 2)); + return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1; + } + function d3_time_parseZone(date, string, i) { + return /^[+-]\d{4}$/.test(string = string.substring(i, i + 5)) ? (date.Z = +string, + i + 5) : -1; + } + function d3_time_expandYear(d) { + return d + (d > 68 ? 1900 : 2e3); + } + function d3_time_parseMonthNumber(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 2)); + return n ? (date.m = n[0] - 1, i + n[0].length) : -1; + } + function d3_time_parseDay(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 2)); + return n ? (date.d = +n[0], i + n[0].length) : -1; + } + function d3_time_parseDayOfYear(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 3)); + return n ? (date.j = +n[0], i + n[0].length) : -1; + } + function d3_time_parseHour24(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 2)); + return n ? (date.H = +n[0], i + n[0].length) : -1; + } + function d3_time_parseMinutes(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 2)); + return n ? (date.M = +n[0], i + n[0].length) : -1; + } + function d3_time_parseSeconds(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 2)); + return n ? (date.S = +n[0], i + n[0].length) : -1; + } + function d3_time_parseMilliseconds(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 3)); + return n ? (date.L = +n[0], i + n[0].length) : -1; + } + var d3_time_numberRe = /^\s*\d+/; + function d3_time_parseAmPm(date, string, i) { + var n = d3_time_amPmLookup.get(string.substring(i, i += 2).toLowerCase()); + return n == null ? -1 : (date.p = n, i); + } + var d3_time_amPmLookup = d3.map({ + am: 0, + pm: 1 + }); + function d3_time_zone(d) { + var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = ~~(Math.abs(z) / 60), zm = Math.abs(z) % 60; + return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); + } + function d3_time_parseLiteralPercent(date, string, i) { + d3_time_percentRe.lastIndex = 0; + var n = d3_time_percentRe.exec(string.substring(i, i + 1)); + return n ? i + n[0].length : -1; + } + d3_time_format.utc = d3_time_formatUtc; + function d3_time_formatUtc(template) { + var local = d3_time_format(template); + function format(date) { + try { + d3_date = d3_date_utc; + var utc = new d3_date(); + utc._ = date; + return local(utc); + } finally { + d3_date = Date; + } + } + format.parse = function(string) { + try { + d3_date = d3_date_utc; + var date = local.parse(string); + return date && date._; + } finally { + d3_date = Date; + } + }; + format.toString = local.toString; + return format; + } + var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ"); + d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso; + function d3_time_formatIsoNative(date) { + return date.toISOString(); + } + d3_time_formatIsoNative.parse = function(string) { + var date = new Date(string); + return isNaN(date) ? null : date; + }; + d3_time_formatIsoNative.toString = d3_time_formatIso.toString; + d3_time.second = d3_time_interval(function(date) { + return new d3_date(Math.floor(date / 1e3) * 1e3); + }, function(date, offset) { + date.setTime(date.getTime() + Math.floor(offset) * 1e3); + }, function(date) { + return date.getSeconds(); + }); + d3_time.seconds = d3_time.second.range; + d3_time.seconds.utc = d3_time.second.utc.range; + d3_time.minute = d3_time_interval(function(date) { + return new d3_date(Math.floor(date / 6e4) * 6e4); + }, function(date, offset) { + date.setTime(date.getTime() + Math.floor(offset) * 6e4); + }, function(date) { + return date.getMinutes(); + }); + d3_time.minutes = d3_time.minute.range; + d3_time.minutes.utc = d3_time.minute.utc.range; + d3_time.hour = d3_time_interval(function(date) { + var timezone = date.getTimezoneOffset() / 60; + return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); + }, function(date, offset) { + date.setTime(date.getTime() + Math.floor(offset) * 36e5); + }, function(date) { + return date.getHours(); + }); + d3_time.hours = d3_time.hour.range; + d3_time.hours.utc = d3_time.hour.utc.range; + d3_time.month = d3_time_interval(function(date) { + date = d3_time.day(date); + date.setDate(1); + return date; + }, function(date, offset) { + date.setMonth(date.getMonth() + offset); + }, function(date) { + return date.getMonth(); + }); + d3_time.months = d3_time.month.range; + d3_time.months.utc = d3_time.month.utc.range; + function d3_time_scale(linear, methods, format) { + function scale(x) { + return linear(x); + } + scale.invert = function(x) { + return d3_time_scaleDate(linear.invert(x)); + }; + scale.domain = function(x) { + if (!arguments.length) return linear.domain().map(d3_time_scaleDate); + linear.domain(x); + return scale; + }; + function tickMethod(extent, count) { + var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target); + return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) { + return d / 31536e6; + }), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i]; + } + scale.nice = function(interval, skip) { + var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval); + if (method) interval = method[0], skip = method[1]; + function skipped(date) { + return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length; + } + return scale.domain(d3_scale_nice(domain, skip > 1 ? { + floor: function(date) { + while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1); + return date; + }, + ceil: function(date) { + while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1); + return date; + } + } : interval)); + }; + scale.ticks = function(interval, skip) { + var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ { + range: interval + }, skip ]; + if (method) interval = method[0], skip = method[1]; + return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip); + }; + scale.tickFormat = function() { + return format; + }; + scale.copy = function() { + return d3_time_scale(linear.copy(), methods, format); + }; + return d3_scale_linearRebind(scale, linear); + } + function d3_time_scaleDate(t) { + return new Date(t); + } + function d3_time_scaleFormat(formats) { + return function(date) { + var i = formats.length - 1, f = formats[i]; + while (!f[1](date)) f = formats[--i]; + return f[0](date); + }; + } + var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; + var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ]; + var d3_time_scaleLocalFormats = [ [ d3_time_format("%Y"), d3_true ], [ d3_time_format("%B"), function(d) { + return d.getMonth(); + } ], [ d3_time_format("%b %d"), function(d) { + return d.getDate() != 1; + } ], [ d3_time_format("%a %d"), function(d) { + return d.getDay() && d.getDate() != 1; + } ], [ d3_time_format("%I %p"), function(d) { + return d.getHours(); + } ], [ d3_time_format("%I:%M"), function(d) { + return d.getMinutes(); + } ], [ d3_time_format(":%S"), function(d) { + return d.getSeconds(); + } ], [ d3_time_format(".%L"), function(d) { + return d.getMilliseconds(); + } ] ]; + var d3_time_scaleLocalFormat = d3_time_scaleFormat(d3_time_scaleLocalFormats); + d3_time_scaleLocalMethods.year = d3_time.year; + d3_time.scale = function() { + return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); + }; + var d3_time_scaleMilliseconds = { + range: function(start, stop, step) { + return d3.range(+start, +stop, step).map(d3_time_scaleDate); + } + }; + var d3_time_scaleUTCMethods = d3_time_scaleLocalMethods.map(function(m) { + return [ m[0].utc, m[1] ]; + }); + var d3_time_scaleUTCFormats = [ [ d3_time_formatUtc("%Y"), d3_true ], [ d3_time_formatUtc("%B"), function(d) { + return d.getUTCMonth(); + } ], [ d3_time_formatUtc("%b %d"), function(d) { + return d.getUTCDate() != 1; + } ], [ d3_time_formatUtc("%a %d"), function(d) { + return d.getUTCDay() && d.getUTCDate() != 1; + } ], [ d3_time_formatUtc("%I %p"), function(d) { + return d.getUTCHours(); + } ], [ d3_time_formatUtc("%I:%M"), function(d) { + return d.getUTCMinutes(); + } ], [ d3_time_formatUtc(":%S"), function(d) { + return d.getUTCSeconds(); + } ], [ d3_time_formatUtc(".%L"), function(d) { + return d.getUTCMilliseconds(); + } ] ]; + var d3_time_scaleUTCFormat = d3_time_scaleFormat(d3_time_scaleUTCFormats); + d3_time_scaleUTCMethods.year = d3_time.year.utc; + d3_time.scale.utc = function() { + return d3_time_scale(d3.scale.linear(), d3_time_scaleUTCMethods, d3_time_scaleUTCFormat); + }; + d3.text = d3_xhrType(function(request) { + return request.responseText; + }); + d3.json = function(url, callback) { + return d3_xhr(url, "application/json", d3_json, callback); + }; + function d3_json(request) { + return JSON.parse(request.responseText); + } + d3.html = function(url, callback) { + return d3_xhr(url, "text/html", d3_html, callback); + }; + function d3_html(request) { + var range = d3_document.createRange(); + range.selectNode(d3_document.body); + return range.createContextualFragment(request.responseText); + } + d3.xml = d3_xhrType(function(request) { + return request.responseXML; + }); + return d3; +}(); + +/// END LIBRARY CODE + +return d3; + +}); \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/d3/d3.layout.js b/deployment-apps/metricator-for-nmon/appserver/static/components/d3/d3.layout.js new file mode 100644 index 0000000..0cbd6fc --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/d3/d3.layout.js @@ -0,0 +1,1900 @@ +define(function(require, exports, module) { +var d3 = require("./d3"); + +/// BEGIN LIBRARY CODE + +d3.layout = {}; +// Implements hierarchical edge bundling using Holten's algorithm. For each +// input link, a path is computed that travels through the tree, up the parent +// hierarchy to the least common ancestor, and then back down to the destination +// node. Each path is simply an array of nodes. +d3.layout.bundle = function() { + return function(links) { + var paths = [], + i = -1, + n = links.length; + while (++i < n) paths.push(d3_layout_bundlePath(links[i])); + return paths; + }; +}; + +function d3_layout_bundlePath(link) { + var start = link.source, + end = link.target, + lca = d3_layout_bundleLeastCommonAncestor(start, end), + points = [start]; + while (start !== lca) { + start = start.parent; + points.push(start); + } + var k = points.length; + while (end !== lca) { + points.splice(k, 0, end); + end = end.parent; + } + return points; +} + +function d3_layout_bundleAncestors(node) { + var ancestors = [], + parent = node.parent; + while (parent != null) { + ancestors.push(node); + node = parent; + parent = parent.parent; + } + ancestors.push(node); + return ancestors; +} + +function d3_layout_bundleLeastCommonAncestor(a, b) { + if (a === b) return a; + var aNodes = d3_layout_bundleAncestors(a), + bNodes = d3_layout_bundleAncestors(b), + aNode = aNodes.pop(), + bNode = bNodes.pop(), + sharedNode = null; + while (aNode === bNode) { + sharedNode = aNode; + aNode = aNodes.pop(); + bNode = bNodes.pop(); + } + return sharedNode; +} +d3.layout.chord = function() { + var chord = {}, + chords, + groups, + matrix, + n, + padding = 0, + sortGroups, + sortSubgroups, + sortChords; + + function relayout() { + var subgroups = {}, + groupSums = [], + groupIndex = d3.range(n), + subgroupIndex = [], + k, + x, + x0, + i, + j; + + chords = []; + groups = []; + + // Compute the sum. + k = 0, i = -1; while (++i < n) { + x = 0, j = -1; while (++j < n) { + x += matrix[i][j]; + } + groupSums.push(x); + subgroupIndex.push(d3.range(n)); + k += x; + } + + // Sort groups… + if (sortGroups) { + groupIndex.sort(function(a, b) { + return sortGroups(groupSums[a], groupSums[b]); + }); + } + + // Sort subgroups… + if (sortSubgroups) { + subgroupIndex.forEach(function(d, i) { + d.sort(function(a, b) { + return sortSubgroups(matrix[i][a], matrix[i][b]); + }); + }); + } + + // Convert the sum to scaling factor for [0, 2pi]. + // TODO Allow start and end angle to be specified. + // TODO Allow padding to be specified as percentage? + k = (2 * Math.PI - padding * n) / k; + + // Compute the start and end angle for each group and subgroup. + x = 0, i = -1; while (++i < n) { + x0 = x, j = -1; while (++j < n) { + var di = groupIndex[i], + dj = subgroupIndex[i][j], + v = matrix[di][dj]; + subgroups[di + "-" + dj] = { + index: di, + subindex: dj, + startAngle: x, + endAngle: x += v * k, + value: v + }; + } + groups.push({ + index: di, + startAngle: x0, + endAngle: x, + value: (x - x0) / k + }); + x += padding; + } + + // Generate chords for each (non-empty) subgroup-subgroup link. + i = -1; while (++i < n) { + j = i - 1; while (++j < n) { + var source = subgroups[i + "-" + j], + target = subgroups[j + "-" + i]; + if (source.value || target.value) { + chords.push(source.value < target.value + ? {source: target, target: source} + : {source: source, target: target}); + } + } + } + + if (sortChords) resort(); + } + + function resort() { + chords.sort(function(a, b) { + return sortChords(a.target.value, b.target.value); + }); + } + + chord.matrix = function(x) { + if (!arguments.length) return matrix; + n = (matrix = x) && matrix.length; + chords = groups = null; + return chord; + }; + + chord.padding = function(x) { + if (!arguments.length) return padding; + padding = x; + chords = groups = null; + return chord; + }; + + chord.sortGroups = function(x) { + if (!arguments.length) return sortGroups; + sortGroups = x; + chords = groups = null; + return chord; + }; + + chord.sortSubgroups = function(x) { + if (!arguments.length) return sortSubgroups; + sortSubgroups = x; + chords = null; + return chord; + }; + + chord.sortChords = function(x) { + if (!arguments.length) return sortChords; + sortChords = x; + if (chords) resort(); + return chord; + }; + + chord.chords = function() { + if (!chords) relayout(); + return chords; + }; + + chord.groups = function() { + if (!groups) relayout(); + return groups; + }; + + return chord; +}; +// A rudimentary force layout using Gauss-Seidel. +d3.layout.force = function() { + var force = {}, + event = d3.dispatch("tick"), + size = [1, 1], + drag, + alpha, + friction = .9, + linkDistance = d3_layout_forceLinkDistance, + linkStrength = d3_layout_forceLinkStrength, + charge = -30, + gravity = .1, + theta = .8, + interval, + nodes = [], + links = [], + distances, + strengths, + charges; + + function repulse(node) { + return function(quad, x1, y1, x2, y2) { + if (quad.point !== node) { + var dx = quad.cx - node.x, + dy = quad.cy - node.y, + dn = 1 / Math.sqrt(dx * dx + dy * dy); + + /* Barnes-Hut criterion. */ + if ((x2 - x1) * dn < theta) { + var k = quad.charge * dn * dn; + node.px -= dx * k; + node.py -= dy * k; + return true; + } + + if (quad.point && isFinite(dn)) { + var k = quad.pointCharge * dn * dn; + node.px -= dx * k; + node.py -= dy * k; + } + } + return !quad.charge; + }; + } + + function tick() { + var n = nodes.length, + m = links.length, + q, + i, // current index + o, // current object + s, // current source + t, // current target + l, // current distance + k, // current force + x, // x-distance + y; // y-distance + + // gauss-seidel relaxation for links + for (i = 0; i < m; ++i) { + o = links[i]; + s = o.source; + t = o.target; + x = t.x - s.x; + y = t.y - s.y; + if (l = (x * x + y * y)) { + l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; + x *= l; + y *= l; + t.x -= x * (k = s.weight / (t.weight + s.weight)); + t.y -= y * k; + s.x += x * (k = 1 - k); + s.y += y * k; + } + } + + // apply gravity forces + if (k = alpha * gravity) { + x = size[0] / 2; + y = size[1] / 2; + i = -1; if (k) while (++i < n) { + o = nodes[i]; + o.x += (x - o.x) * k; + o.y += (y - o.y) * k; + } + } + + // compute quadtree center of mass and apply charge forces + if (charge) { + d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); + i = -1; while (++i < n) { + if (!(o = nodes[i]).fixed) { + q.visit(repulse(o)); + } + } + } + + // position verlet integration + i = -1; while (++i < n) { + o = nodes[i]; + if (o.fixed) { + o.x = o.px; + o.y = o.py; + } else { + o.x -= (o.px - (o.px = o.x)) * friction; + o.y -= (o.py - (o.py = o.y)) * friction; + } + } + + event.tick.dispatch({type: "tick", alpha: alpha}); + + // simulated annealing, basically + return (alpha *= .99) < .005; + } + + force.on = function(type, listener) { + event[type].add(listener); + return force; + }; + + force.nodes = function(x) { + if (!arguments.length) return nodes; + nodes = x; + return force; + }; + + force.links = function(x) { + if (!arguments.length) return links; + links = x; + return force; + }; + + force.size = function(x) { + if (!arguments.length) return size; + size = x; + return force; + }; + + force.linkDistance = function(x) { + if (!arguments.length) return linkDistance; + linkDistance = d3.functor(x); + return force; + }; + + // For backwards-compatibility. + force.distance = force.linkDistance; + + force.linkStrength = function(x) { + if (!arguments.length) return linkStrength; + linkStrength = d3.functor(x); + return force; + }; + + force.friction = function(x) { + if (!arguments.length) return friction; + friction = x; + return force; + }; + + force.charge = function(x) { + if (!arguments.length) return charge; + charge = typeof x === "function" ? x : +x; + return force; + }; + + force.gravity = function(x) { + if (!arguments.length) return gravity; + gravity = x; + return force; + }; + + force.theta = function(x) { + if (!arguments.length) return theta; + theta = x; + return force; + }; + + force.start = function() { + var i, + j, + n = nodes.length, + m = links.length, + w = size[0], + h = size[1], + neighbors, + o; + + for (i = 0; i < n; ++i) { + (o = nodes[i]).index = i; + o.weight = 0; + } + + distances = []; + strengths = []; + for (i = 0; i < m; ++i) { + o = links[i]; + if (typeof o.source == "number") o.source = nodes[o.source]; + if (typeof o.target == "number") o.target = nodes[o.target]; + distances[i] = linkDistance.call(this, o, i); + strengths[i] = linkStrength.call(this, o, i); + ++o.source.weight; + ++o.target.weight; + } + + for (i = 0; i < n; ++i) { + o = nodes[i]; + if (isNaN(o.x)) o.x = position("x", w); + if (isNaN(o.y)) o.y = position("y", h); + if (isNaN(o.px)) o.px = o.x; + if (isNaN(o.py)) o.py = o.y; + } + + charges = []; + if (typeof charge === "function") { + for (i = 0; i < n; ++i) { + charges[i] = +charge.call(this, nodes[i], i); + } + } else { + for (i = 0; i < n; ++i) { + charges[i] = charge; + } + } + + // initialize node position based on first neighbor + function position(dimension, size) { + var neighbors = neighbor(i), + j = -1, + m = neighbors.length, + x; + while (++j < m) if (!isNaN(x = neighbors[j][dimension])) return x; + return Math.random() * size; + } + + // initialize neighbors lazily + function neighbor() { + if (!neighbors) { + neighbors = []; + for (j = 0; j < n; ++j) { + neighbors[j] = []; + } + for (j = 0; j < m; ++j) { + var o = links[j]; + neighbors[o.source.index].push(o.target); + neighbors[o.target.index].push(o.source); + } + } + return neighbors[i]; + } + + return force.resume(); + }; + + force.resume = function() { + alpha = .1; + d3.timer(tick); + return force; + }; + + force.stop = function() { + alpha = 0; + return force; + }; + + // use `node.call(force.drag)` to make nodes draggable + force.drag = function() { + if (!drag) drag = d3.behavior.drag() + .on("dragstart", dragstart) + .on("drag", d3_layout_forceDrag) + .on("dragend", d3_layout_forceDragEnd); + + this.on("mouseover.force", d3_layout_forceDragOver) + .on("mouseout.force", d3_layout_forceDragOut) + .call(drag); + }; + + function dragstart(d) { + d3_layout_forceDragOver(d3_layout_forceDragNode = d); + d3_layout_forceDragForce = force; + } + + return force; +}; + +var d3_layout_forceDragForce, + d3_layout_forceDragNode; + +function d3_layout_forceDragOver(d) { + d.fixed |= 2; +} + +function d3_layout_forceDragOut(d) { + if (d !== d3_layout_forceDragNode) d.fixed &= 1; +} + +function d3_layout_forceDragEnd() { + d3_layout_forceDrag(); + d3_layout_forceDragNode.fixed &= 1; + d3_layout_forceDragForce = d3_layout_forceDragNode = null; +} + +function d3_layout_forceDrag() { + d3_layout_forceDragNode.px += d3.event.dx; + d3_layout_forceDragNode.py += d3.event.dy; + d3_layout_forceDragForce.resume(); // restart annealing +} + +function d3_layout_forceAccumulate(quad, alpha, charges) { + var cx = 0, + cy = 0; + quad.charge = 0; + if (!quad.leaf) { + var nodes = quad.nodes, + n = nodes.length, + i = -1, + c; + while (++i < n) { + c = nodes[i]; + if (c == null) continue; + d3_layout_forceAccumulate(c, alpha, charges); + quad.charge += c.charge; + cx += c.charge * c.cx; + cy += c.charge * c.cy; + } + } + if (quad.point) { + // jitter internal nodes that are coincident + if (!quad.leaf) { + quad.point.x += Math.random() - .5; + quad.point.y += Math.random() - .5; + } + var k = alpha * charges[quad.point.index]; + quad.charge += quad.pointCharge = k; + cx += k * quad.point.x; + cy += k * quad.point.y; + } + quad.cx = cx / quad.charge; + quad.cy = cy / quad.charge; +} + +function d3_layout_forceLinkDistance(link) { + return 20; +} + +function d3_layout_forceLinkStrength(link) { + return 1; +} +d3.layout.partition = function() { + var hierarchy = d3.layout.hierarchy(), + size = [1, 1]; // width, height + + function position(node, x, dx, dy) { + var children = node.children; + node.x = x; + node.y = node.depth * dy; + node.dx = dx; + node.dy = dy; + if (children && (n = children.length)) { + var i = -1, + n, + c, + d; + dx = node.value ? dx / node.value : 0; + while (++i < n) { + position(c = children[i], x, d = c.value * dx, dy); + x += d; + } + } + } + + function depth(node) { + var children = node.children, + d = 0; + if (children && (n = children.length)) { + var i = -1, + n; + while (++i < n) d = Math.max(d, depth(children[i])); + } + return 1 + d; + } + + function partition(d, i) { + var nodes = hierarchy.call(this, d, i); + position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); + return nodes; + } + + partition.size = function(x) { + if (!arguments.length) return size; + size = x; + return partition; + }; + + return d3_layout_hierarchyRebind(partition, hierarchy); +}; +d3.layout.pie = function() { + var value = Number, + sort = null, + startAngle = 0, + endAngle = 2 * Math.PI; + + function pie(data, i) { + + // Compute the start angle. + var a = +(typeof startAngle === "function" + ? startAngle.apply(this, arguments) + : startAngle); + + // Compute the angular range (end - start). + var k = (typeof endAngle === "function" + ? endAngle.apply(this, arguments) + : endAngle) - startAngle; + + // Optionally sort the data. + var index = d3.range(data.length); + if (sort != null) index.sort(function(i, j) { + return sort(data[i], data[j]); + }); + + // Compute the numeric values for each data element. + var values = data.map(value); + + // Convert k into a scale factor from value to angle, using the sum. + k /= values.reduce(function(p, d) { return p + d; }, 0); + + // Compute the arcs! + var arcs = index.map(function(i) { + return { + data: data[i], + value: d = values[i], + startAngle: a, + endAngle: a += d * k + }; + }); + + // Return the arcs in the original data's order. + return data.map(function(d, i) { + return arcs[index[i]]; + }); + } + + /** + * Specifies the value function *x*, which returns a nonnegative numeric value + * for each datum. The default value function is `Number`. The value function + * is passed two arguments: the current datum and the current index. + */ + pie.value = function(x) { + if (!arguments.length) return value; + value = x; + return pie; + }; + + /** + * Specifies a sort comparison operator *x*. The comparator is passed two data + * elements from the data array, a and b; it returns a negative value if a is + * less than b, a positive value if a is greater than b, and zero if a equals + * b. + */ + pie.sort = function(x) { + if (!arguments.length) return sort; + sort = x; + return pie; + }; + + /** + * Specifies the overall start angle of the pie chart. Defaults to 0. The + * start angle can be specified either as a constant or as a function; in the + * case of a function, it is evaluated once per array (as opposed to per + * element). + */ + pie.startAngle = function(x) { + if (!arguments.length) return startAngle; + startAngle = x; + return pie; + }; + + /** + * Specifies the overall end angle of the pie chart. Defaults to 2π. The + * end angle can be specified either as a constant or as a function; in the + * case of a function, it is evaluated once per array (as opposed to per + * element). + */ + pie.endAngle = function(x) { + if (!arguments.length) return endAngle; + endAngle = x; + return pie; + }; + + return pie; +}; +// data is two-dimensional array of x,y; we populate y0 +d3.layout.stack = function() { + var values = Object, + order = d3_layout_stackOrders["default"], + offset = d3_layout_stackOffsets["zero"], + out = d3_layout_stackOut, + x = d3_layout_stackX, + y = d3_layout_stackY; + + function stack(data, index) { + + // Convert series to canonical two-dimensional representation. + var series = data.map(function(d, i) { + return values.call(stack, d, i); + }); + + // Convert each series to canonical [[x,y]] representation. + var points = series.map(function(d, i) { + return d.map(function(v, i) { + return [x.call(stack, v, i), y.call(stack, v, i)]; + }); + }); + + // Compute the order of series, and permute them. + var orders = order.call(stack, points, index); + series = d3.permute(series, orders); + points = d3.permute(points, orders); + + // Compute the baseline… + var offsets = offset.call(stack, points, index); + + // And propagate it to other series. + var n = series.length, + m = series[0].length, + i, + j, + o; + for (j = 0; j < m; ++j) { + out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); + for (i = 1; i < n; ++i) { + out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); + } + } + + return data; + } + + stack.values = function(x) { + if (!arguments.length) return values; + values = x; + return stack; + }; + + stack.order = function(x) { + if (!arguments.length) return order; + order = typeof x === "function" ? x : d3_layout_stackOrders[x]; + return stack; + }; + + stack.offset = function(x) { + if (!arguments.length) return offset; + offset = typeof x === "function" ? x : d3_layout_stackOffsets[x]; + return stack; + }; + + stack.x = function(z) { + if (!arguments.length) return x; + x = z; + return stack; + }; + + stack.y = function(z) { + if (!arguments.length) return y; + y = z; + return stack; + }; + + stack.out = function(z) { + if (!arguments.length) return out; + out = z; + return stack; + }; + + return stack; +} + +function d3_layout_stackX(d) { + return d.x; +} + +function d3_layout_stackY(d) { + return d.y; +} + +function d3_layout_stackOut(d, y0, y) { + d.y0 = y0; + d.y = y; +} + +var d3_layout_stackOrders = { + + "inside-out": function(data) { + var n = data.length, + i, + j, + max = data.map(d3_layout_stackMaxIndex), + sums = data.map(d3_layout_stackReduceSum), + index = d3.range(n).sort(function(a, b) { return max[a] - max[b]; }), + top = 0, + bottom = 0, + tops = [], + bottoms = []; + for (i = 0; i < n; ++i) { + j = index[i]; + if (top < bottom) { + top += sums[j]; + tops.push(j); + } else { + bottom += sums[j]; + bottoms.push(j); + } + } + return bottoms.reverse().concat(tops); + }, + + "reverse": function(data) { + return d3.range(data.length).reverse(); + }, + + "default": function(data) { + return d3.range(data.length); + } + +}; + +var d3_layout_stackOffsets = { + + "silhouette": function(data) { + var n = data.length, + m = data[0].length, + sums = [], + max = 0, + i, + j, + o, + y0 = []; + for (j = 0; j < m; ++j) { + for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; + if (o > max) max = o; + sums.push(o); + } + for (j = 0; j < m; ++j) { + y0[j] = (max - sums[j]) / 2; + } + return y0; + }, + + "wiggle": function(data) { + var n = data.length, + x = data[0], + m = x.length, + max = 0, + i, + j, + k, + s1, + s2, + s3, + dx, + o, + o0, + y0 = []; + y0[0] = o = o0 = 0; + for (j = 1; j < m; ++j) { + for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; + for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { + for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { + s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; + } + s2 += s3 * data[i][j][1]; + } + y0[j] = o -= s1 ? s2 / s1 * dx : 0; + if (o < o0) o0 = o; + } + for (j = 0; j < m; ++j) y0[j] -= o0; + return y0; + }, + + "expand": function(data) { + var n = data.length, + m = data[0].length, + k = 1 / n, + i, + j, + o, + y0 = []; + for (j = 0; j < m; ++j) { + for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; + if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; + else for (i = 0; i < n; i++) data[i][j][1] = k; + } + for (j = 0; j < m; ++j) y0[j] = 0; + return y0; + }, + + "zero": function(data) { + var j = -1, + m = data[0].length, + y0 = []; + while (++j < m) y0[j] = 0; + return y0; + } + +}; + +function d3_layout_stackMaxIndex(array) { + var i = 1, + j = 0, + v = array[0][1], + k, + n = array.length; + for (; i < n; ++i) { + if ((k = array[i][1]) > v) { + j = i; + v = k; + } + } + return j; +} + +function d3_layout_stackReduceSum(d) { + return d.reduce(d3_layout_stackSum, 0); +} + +function d3_layout_stackSum(p, d) { + return p + d[1]; +} +d3.layout.histogram = function() { + var frequency = true, + valuer = Number, + ranger = d3_layout_histogramRange, + binner = d3_layout_histogramBinSturges; + + function histogram(data, i) { + var bins = [], + values = data.map(valuer, this), + range = ranger.call(this, values, i), + thresholds = binner.call(this, range, values, i), + bin, + i = -1, + n = values.length, + m = thresholds.length - 1, + k = frequency ? 1 : 1 / n, + x; + + // Initialize the bins. + while (++i < m) { + bin = bins[i] = []; + bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); + bin.y = 0; + } + + // Fill the bins, ignoring values outside the range. + i = -1; while(++i < n) { + x = values[i]; + if ((x >= range[0]) && (x <= range[1])) { + bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; + bin.y += k; + bin.push(data[i]); + } + } + + return bins; + } + + // Specifies how to extract a value from the associated data. The default + // value function is `Number`, which is equivalent to the identity function. + histogram.value = function(x) { + if (!arguments.length) return valuer; + valuer = x; + return histogram; + }; + + // Specifies the range of the histogram. Values outside the specified range + // will be ignored. The argument `x` may be specified either as a two-element + // array representing the minimum and maximum value of the range, or as a + // function that returns the range given the array of values and the current + // index `i`. The default range is the extent (minimum and maximum) of the + // values. + histogram.range = function(x) { + if (!arguments.length) return ranger; + ranger = d3.functor(x); + return histogram; + }; + + // Specifies how to bin values in the histogram. The argument `x` may be + // specified as a number, in which case the range of values will be split + // uniformly into the given number of bins. Or, `x` may be an array of + // threshold values, defining the bins; the specified array must contain the + // rightmost (upper) value, thus specifying n + 1 values for n bins. Or, `x` + // may be a function which is evaluated, being passed the range, the array of + // values, and the current index `i`, returning an array of thresholds. The + // default bin function will divide the values into uniform bins using + // Sturges' formula. + histogram.bins = function(x) { + if (!arguments.length) return binner; + binner = typeof x === "number" + ? function(range) { return d3_layout_histogramBinFixed(range, x); } + : d3.functor(x); + return histogram; + }; + + // Specifies whether the histogram's `y` value is a count (frequency) or a + // probability (density). The default value is true. + histogram.frequency = function(x) { + if (!arguments.length) return frequency; + frequency = !!x; + return histogram; + }; + + return histogram; +}; + +function d3_layout_histogramBinSturges(range, values) { + return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); +} + +function d3_layout_histogramBinFixed(range, n) { + var x = -1, + b = +range[0], + m = (range[1] - b) / n, + f = []; + while (++x <= n) f[x] = m * x + b; + return f; +} + +function d3_layout_histogramRange(values) { + return [d3.min(values), d3.max(values)]; +} +d3.layout.hierarchy = function() { + var sort = d3_layout_hierarchySort, + children = d3_layout_hierarchyChildren, + value = d3_layout_hierarchyValue; + + // Recursively compute the node depth and value. + // Also converts the data representation into a standard hierarchy structure. + function recurse(data, depth, nodes) { + var childs = children.call(hierarchy, data, depth), + node = d3_layout_hierarchyInline ? data : {data: data}; + node.depth = depth; + nodes.push(node); + if (childs && (n = childs.length)) { + var i = -1, + n, + c = node.children = [], + v = 0, + j = depth + 1; + while (++i < n) { + d = recurse(childs[i], j, nodes); + d.parent = node; + c.push(d); + v += d.value; + } + if (sort) c.sort(sort); + if (value) node.value = v; + } else if (value) { + node.value = +value.call(hierarchy, data, depth) || 0; + } + return node; + } + + // Recursively re-evaluates the node value. + function revalue(node, depth) { + var children = node.children, + v = 0; + if (children && (n = children.length)) { + var i = -1, + n, + j = depth + 1; + while (++i < n) v += revalue(children[i], j); + } else if (value) { + v = +value.call(hierarchy, d3_layout_hierarchyInline ? node : node.data, depth) || 0; + } + if (value) node.value = v; + return v; + } + + function hierarchy(d) { + var nodes = []; + recurse(d, 0, nodes); + return nodes; + } + + hierarchy.sort = function(x) { + if (!arguments.length) return sort; + sort = x; + return hierarchy; + }; + + hierarchy.children = function(x) { + if (!arguments.length) return children; + children = x; + return hierarchy; + }; + + hierarchy.value = function(x) { + if (!arguments.length) return value; + value = x; + return hierarchy; + }; + + // Re-evaluates the `value` property for the specified hierarchy. + hierarchy.revalue = function(root) { + revalue(root, 0); + return root; + }; + + return hierarchy; +}; + +// A method assignment helper for hierarchy subclasses. +function d3_layout_hierarchyRebind(object, hierarchy) { + object.sort = d3.rebind(object, hierarchy.sort); + object.children = d3.rebind(object, hierarchy.children); + object.links = d3_layout_hierarchyLinks; + object.value = d3.rebind(object, hierarchy.value); + + // If the new API is used, enabling inlining. + object.nodes = function(d) { + d3_layout_hierarchyInline = true; + return (object.nodes = object)(d); + }; + + return object; +} + +function d3_layout_hierarchyChildren(d) { + return d.children; +} + +function d3_layout_hierarchyValue(d) { + return d.value; +} + +function d3_layout_hierarchySort(a, b) { + return b.value - a.value; +} + +// Returns an array source+target objects for the specified nodes. +function d3_layout_hierarchyLinks(nodes) { + return d3.merge(nodes.map(function(parent) { + return (parent.children || []).map(function(child) { + return {source: parent, target: child}; + }); + })); +} + +// For backwards-compatibility, don't enable inlining by default. +var d3_layout_hierarchyInline = false; +d3.layout.pack = function() { + var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), + size = [1, 1]; + + function pack(d, i) { + var nodes = hierarchy.call(this, d, i), + root = nodes[0]; + + // Recursively compute the layout. + root.x = 0; + root.y = 0; + d3_layout_packTree(root); + + // Scale the layout to fit the requested size. + var w = size[0], + h = size[1], + k = 1 / Math.max(2 * root.r / w, 2 * root.r / h); + d3_layout_packTransform(root, w / 2, h / 2, k); + + return nodes; + } + + pack.size = function(x) { + if (!arguments.length) return size; + size = x; + return pack; + }; + + return d3_layout_hierarchyRebind(pack, hierarchy); +}; + +function d3_layout_packSort(a, b) { + return a.value - b.value; +} + +function d3_layout_packInsert(a, b) { + var c = a._pack_next; + a._pack_next = b; + b._pack_prev = a; + b._pack_next = c; + c._pack_prev = b; +} + +function d3_layout_packSplice(a, b) { + a._pack_next = b; + b._pack_prev = a; +} + +function d3_layout_packIntersects(a, b) { + var dx = b.x - a.x, + dy = b.y - a.y, + dr = a.r + b.r; + return (dr * dr - dx * dx - dy * dy) > .001; // within epsilon +} + +function d3_layout_packCircle(nodes) { + var xMin = Infinity, + xMax = -Infinity, + yMin = Infinity, + yMax = -Infinity, + n = nodes.length, + a, b, c, j, k; + + function bound(node) { + xMin = Math.min(node.x - node.r, xMin); + xMax = Math.max(node.x + node.r, xMax); + yMin = Math.min(node.y - node.r, yMin); + yMax = Math.max(node.y + node.r, yMax); + } + + // Create node links. + nodes.forEach(d3_layout_packLink); + + // Create first node. + a = nodes[0]; + a.x = -a.r; + a.y = 0; + bound(a); + + // Create second node. + if (n > 1) { + b = nodes[1]; + b.x = b.r; + b.y = 0; + bound(b); + + // Create third node and build chain. + if (n > 2) { + c = nodes[2]; + d3_layout_packPlace(a, b, c); + bound(c); + d3_layout_packInsert(a, c); + a._pack_prev = c; + d3_layout_packInsert(c, b); + b = a._pack_next; + + // Now iterate through the rest. + for (var i = 3; i < n; i++) { + d3_layout_packPlace(a, b, c = nodes[i]); + + // Search for the closest intersection. + var isect = 0, s1 = 1, s2 = 1; + for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { + if (d3_layout_packIntersects(j, c)) { + isect = 1; + break; + } + } + if (isect == 1) { + for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { + if (d3_layout_packIntersects(k, c)) { + if (s2 < s1) { + isect = -1; + j = k; + } + break; + } + } + } + + // Update node chain. + if (isect == 0) { + d3_layout_packInsert(a, c); + b = c; + bound(c); + } else if (isect > 0) { + d3_layout_packSplice(a, j); + b = j; + i--; + } else { // isect < 0 + d3_layout_packSplice(j, b); + a = j; + i--; + } + } + } + } + + // Re-center the circles and return the encompassing radius. + var cx = (xMin + xMax) / 2, + cy = (yMin + yMax) / 2, + cr = 0; + for (var i = 0; i < n; i++) { + var node = nodes[i]; + node.x -= cx; + node.y -= cy; + cr = Math.max(cr, node.r + Math.sqrt(node.x * node.x + node.y * node.y)); + } + + // Remove node links. + nodes.forEach(d3_layout_packUnlink); + + return cr; +} + +function d3_layout_packLink(node) { + node._pack_next = node._pack_prev = node; +} + +function d3_layout_packUnlink(node) { + delete node._pack_next; + delete node._pack_prev; +} + +function d3_layout_packTree(node) { + var children = node.children; + if (children && children.length) { + children.forEach(d3_layout_packTree); + node.r = d3_layout_packCircle(children); + } else { + node.r = Math.sqrt(node.value); + } +} + +function d3_layout_packTransform(node, x, y, k) { + var children = node.children; + node.x = (x += k * node.x); + node.y = (y += k * node.y); + node.r *= k; + if (children) { + var i = -1, n = children.length; + while (++i < n) d3_layout_packTransform(children[i], x, y, k); + } +} + +function d3_layout_packPlace(a, b, c) { + var db = a.r + c.r, + dx = b.x - a.x, + dy = b.y - a.y; + if (db && (dx || dy)) { + var da = b.r + c.r, + dc = Math.sqrt(dx * dx + dy * dy), + cos = Math.max(-1, Math.min(1, (db * db + dc * dc - da * da) / (2 * db * dc))), + theta = Math.acos(cos), + x = cos * (db /= dc), + y = Math.sin(theta) * db; + c.x = a.x + x * dx + y * dy; + c.y = a.y + x * dy - y * dx; + } else { + c.x = a.x + db; + c.y = a.y; + } +} +// Implements a hierarchical layout using the cluster (or dendogram) algorithm. +d3.layout.cluster = function() { + var hierarchy = d3.layout.hierarchy().sort(null).value(null), + separation = d3_layout_treeSeparation, + size = [1, 1]; // width, height + + function cluster(d, i) { + var nodes = hierarchy.call(this, d, i), + root = nodes[0], + previousNode, + x = 0, + kx, + ky; + + // First walk, computing the initial x & y values. + d3_layout_treeVisitAfter(root, function(node) { + var children = node.children; + if (children && children.length) { + node.x = d3_layout_clusterX(children); + node.y = d3_layout_clusterY(children); + } else { + node.x = previousNode ? x += separation(node, previousNode) : 0; + node.y = 0; + previousNode = node; + } + }); + + // Compute the left-most, right-most, and depth-most nodes for extents. + var left = d3_layout_clusterLeft(root), + right = d3_layout_clusterRight(root), + x0 = left.x - separation(left, right) / 2, + x1 = right.x + separation(right, left) / 2; + + // Second walk, normalizing x & y to the desired size. + d3_layout_treeVisitAfter(root, function(node) { + node.x = (node.x - x0) / (x1 - x0) * size[0]; + node.y = (1 - node.y / root.y) * size[1]; + }); + + return nodes; + } + + cluster.separation = function(x) { + if (!arguments.length) return separation; + separation = x; + return cluster; + }; + + cluster.size = function(x) { + if (!arguments.length) return size; + size = x; + return cluster; + }; + + return d3_layout_hierarchyRebind(cluster, hierarchy); +}; + +function d3_layout_clusterY(children) { + return 1 + d3.max(children, function(child) { + return child.y; + }); +} + +function d3_layout_clusterX(children) { + return children.reduce(function(x, child) { + return x + child.x; + }, 0) / children.length; +} + +function d3_layout_clusterLeft(node) { + var children = node.children; + return children && children.length ? d3_layout_clusterLeft(children[0]) : node; +} + +function d3_layout_clusterRight(node) { + var children = node.children, n; + return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; +} +// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm +d3.layout.tree = function() { + var hierarchy = d3.layout.hierarchy().sort(null).value(null), + separation = d3_layout_treeSeparation, + size = [1, 1]; // width, height + + function tree(d, i) { + var nodes = hierarchy.call(this, d, i), + root = nodes[0]; + + function firstWalk(node, previousSibling) { + var children = node.children, + layout = node._tree; + if (children && (n = children.length)) { + var n, + firstChild = children[0], + previousChild, + ancestor = firstChild, + child, + i = -1; + while (++i < n) { + child = children[i]; + firstWalk(child, previousChild); + ancestor = apportion(child, previousChild, ancestor); + previousChild = child; + } + d3_layout_treeShift(node); + var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim); + if (previousSibling) { + layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); + layout.mod = layout.prelim - midpoint; + } else { + layout.prelim = midpoint; + } + } else { + if (previousSibling) { + layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); + } + } + } + + function secondWalk(node, x) { + node.x = node._tree.prelim + x; + var children = node.children; + if (children && (n = children.length)) { + var i = -1, + n; + x += node._tree.mod; + while (++i < n) { + secondWalk(children[i], x); + } + } + } + + function apportion(node, previousSibling, ancestor) { + if (previousSibling) { + var vip = node, + vop = node, + vim = previousSibling, + vom = node.parent.children[0], + sip = vip._tree.mod, + sop = vop._tree.mod, + sim = vim._tree.mod, + som = vom._tree.mod, + shift; + while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { + vom = d3_layout_treeLeft(vom); + vop = d3_layout_treeRight(vop); + vop._tree.ancestor = node; + shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip); + if (shift > 0) { + d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift); + sip += shift; + sop += shift; + } + sim += vim._tree.mod; + sip += vip._tree.mod; + som += vom._tree.mod; + sop += vop._tree.mod; + } + if (vim && !d3_layout_treeRight(vop)) { + vop._tree.thread = vim; + vop._tree.mod += sim - sop; + } + if (vip && !d3_layout_treeLeft(vom)) { + vom._tree.thread = vip; + vom._tree.mod += sip - som; + ancestor = node; + } + } + return ancestor; + } + + // Initialize temporary layout variables. + d3_layout_treeVisitAfter(root, function(node, previousSibling) { + node._tree = { + ancestor: node, + prelim: 0, + mod: 0, + change: 0, + shift: 0, + number: previousSibling ? previousSibling._tree.number + 1 : 0 + }; + }); + + // Compute the layout using Buchheim et al.'s algorithm. + firstWalk(root); + secondWalk(root, -root._tree.prelim); + + // Compute the left-most, right-most, and depth-most nodes for extents. + var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost), + right = d3_layout_treeSearch(root, d3_layout_treeRightmost), + deep = d3_layout_treeSearch(root, d3_layout_treeDeepest), + x0 = left.x - separation(left, right) / 2, + x1 = right.x + separation(right, left) / 2, + y1 = deep.depth || 1; + + // Clear temporary layout variables; transform x and y. + d3_layout_treeVisitAfter(root, function(node) { + node.x = (node.x - x0) / (x1 - x0) * size[0]; + node.y = node.depth / y1 * size[1]; + delete node._tree; + }); + + return nodes; + } + + tree.separation = function(x) { + if (!arguments.length) return separation; + separation = x; + return tree; + }; + + tree.size = function(x) { + if (!arguments.length) return size; + size = x; + return tree; + }; + + return d3_layout_hierarchyRebind(tree, hierarchy); +}; + +function d3_layout_treeSeparation(a, b) { + return a.parent == b.parent ? 1 : 2; +} + +// function d3_layout_treeSeparationRadial(a, b) { +// return (a.parent == b.parent ? 1 : 2) / a.depth; +// } + +function d3_layout_treeLeft(node) { + var children = node.children; + return children && children.length ? children[0] : node._tree.thread; +} + +function d3_layout_treeRight(node) { + var children = node.children, + n; + return children && (n = children.length) ? children[n - 1] : node._tree.thread; +} + +function d3_layout_treeSearch(node, compare) { + var children = node.children; + if (children && (n = children.length)) { + var child, + n, + i = -1; + while (++i < n) { + if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) { + node = child; + } + } + } + return node; +} + +function d3_layout_treeRightmost(a, b) { + return a.x - b.x; +} + +function d3_layout_treeLeftmost(a, b) { + return b.x - a.x; +} + +function d3_layout_treeDeepest(a, b) { + return a.depth - b.depth; +} + +function d3_layout_treeVisitAfter(node, callback) { + function visit(node, previousSibling) { + var children = node.children; + if (children && (n = children.length)) { + var child, + previousChild = null, + i = -1, + n; + while (++i < n) { + child = children[i]; + visit(child, previousChild); + previousChild = child; + } + } + callback(node, previousSibling); + } + visit(node, null); +} + +function d3_layout_treeShift(node) { + var shift = 0, + change = 0, + children = node.children, + i = children.length, + child; + while (--i >= 0) { + child = children[i]._tree; + child.prelim += shift; + child.mod += shift; + shift += child.shift + (change += child.change); + } +} + +function d3_layout_treeMove(ancestor, node, shift) { + ancestor = ancestor._tree; + node = node._tree; + var change = shift / (node.number - ancestor.number); + ancestor.change += change; + node.change -= change; + node.shift += shift; + node.prelim += shift; + node.mod += shift; +} + +function d3_layout_treeAncestor(vim, node, ancestor) { + return vim._tree.ancestor.parent == node.parent + ? vim._tree.ancestor + : ancestor; +} +// Squarified Treemaps by Mark Bruls, Kees Huizing, and Jarke J. van Wijk +// Modified to support a target aspect ratio by Jeff Heer +d3.layout.treemap = function() { + var hierarchy = d3.layout.hierarchy(), + round = Math.round, + size = [1, 1], // width, height + padding = null, + pad = d3_layout_treemapPadNull, + sticky = false, + stickies, + ratio = 0.5 * (1 + Math.sqrt(5)); // golden ratio + + // Compute the area for each child based on value & scale. + function scale(children, k) { + var i = -1, + n = children.length, + child, + area; + while (++i < n) { + area = (child = children[i]).value * (k < 0 ? 0 : k); + child.area = isNaN(area) || area <= 0 ? 0 : area; + } + } + + // Recursively arranges the specified node's children into squarified rows. + function squarify(node) { + var children = node.children; + if (children && children.length) { + var rect = pad(node), + row = [], + remaining = children.slice(), // copy-on-write + child, + best = Infinity, // the best row score so far + score, // the current row score + u = Math.min(rect.dx, rect.dy), // initial orientation + n; + scale(remaining, rect.dx * rect.dy / node.value); + row.area = 0; + while ((n = remaining.length) > 0) { + row.push(child = remaining[n - 1]); + row.area += child.area; + if ((score = worst(row, u)) <= best) { // continue with this orientation + remaining.pop(); + best = score; + } else { // abort, and try a different orientation + row.area -= row.pop().area; + position(row, u, rect, false); + u = Math.min(rect.dx, rect.dy); + row.length = row.area = 0; + best = Infinity; + } + } + if (row.length) { + position(row, u, rect, true); + row.length = row.area = 0; + } + children.forEach(squarify); + } + } + + // Recursively resizes the specified node's children into existing rows. + // Preserves the existing layout! + function stickify(node) { + var children = node.children; + if (children && children.length) { + var rect = pad(node), + remaining = children.slice(), // copy-on-write + child, + row = []; + scale(remaining, rect.dx * rect.dy / node.value); + row.area = 0; + while (child = remaining.pop()) { + row.push(child); + row.area += child.area; + if (child.z != null) { + position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); + row.length = row.area = 0; + } + } + children.forEach(stickify); + } + } + + // Computes the score for the specified row, as the worst aspect ratio. + function worst(row, u) { + var s = row.area, + r, + rmax = 0, + rmin = Infinity, + i = -1, + n = row.length; + while (++i < n) { + if (!(r = row[i].area)) continue; + if (r < rmin) rmin = r; + if (r > rmax) rmax = r; + } + s *= s; + u *= u; + return s + ? Math.max((u * rmax * ratio) / s, s / (u * rmin * ratio)) + : Infinity; + } + + // Positions the specified row of nodes. Modifies `rect`. + function position(row, u, rect, flush) { + var i = -1, + n = row.length, + x = rect.x, + y = rect.y, + v = u ? round(row.area / u) : 0, + o; + if (u == rect.dx) { // horizontal subdivision + if (flush || v > rect.dy) v = v ? rect.dy : 0; // over+underflow + while (++i < n) { + o = row[i]; + o.x = x; + o.y = y; + o.dy = v; + x += o.dx = v ? round(o.area / v) : 0; + } + o.z = true; + o.dx += rect.x + rect.dx - x; // rounding error + rect.y += v; + rect.dy -= v; + } else { // vertical subdivision + if (flush || v > rect.dx) v = v ? rect.dx : 0; // over+underflow + while (++i < n) { + o = row[i]; + o.x = x; + o.y = y; + o.dx = v; + y += o.dy = v ? round(o.area / v) : 0; + } + o.z = false; + o.dy += rect.y + rect.dy - y; // rounding error + rect.x += v; + rect.dx -= v; + } + } + + function treemap(d) { + var nodes = stickies || hierarchy(d), + root = nodes[0]; + root.x = 0; + root.y = 0; + root.dx = size[0]; + root.dy = size[1]; + if (stickies) hierarchy.revalue(root); + scale([root], root.dx * root.dy / root.value); + (stickies ? stickify : squarify)(root); + if (sticky) stickies = nodes; + return nodes; + } + + treemap.size = function(x) { + if (!arguments.length) return size; + size = x; + return treemap; + }; + + treemap.padding = function(x) { + if (!arguments.length) return padding; + + function padFunction(node) { + var p = x.call(treemap, node, node.depth); + return p == null + ? d3_layout_treemapPadNull(node) + : d3_layout_treemapPad(node, typeof p === "number" ? [p, p, p, p] : p); + } + + function padConstant(node) { + return d3_layout_treemapPad(node, x); + } + + var type; + pad = (padding = x) == null ? d3_layout_treemapPadNull + : (type = typeof x) === "function" ? padFunction + : type === "number" ? (x = [x, x, x, x], padConstant) + : padConstant; + return treemap; + }; + + treemap.round = function(x) { + if (!arguments.length) return round != Number; + round = x ? Math.round : Number; + return treemap; + }; + + treemap.sticky = function(x) { + if (!arguments.length) return sticky; + sticky = x; + stickies = null; + return treemap; + }; + + treemap.ratio = function(x) { + if (!arguments.length) return ratio; + ratio = x; + return treemap; + }; + + return d3_layout_hierarchyRebind(treemap, hierarchy); +}; + +function d3_layout_treemapPadNull(node) { + return {x: node.x, y: node.y, dx: node.dx, dy: node.dy}; +} + +function d3_layout_treemapPad(node, padding) { + var x = node.x + padding[3], + y = node.y + padding[0], + dx = node.dx - padding[1] - padding[3], + dy = node.dy - padding[0] - padding[2]; + if (dx < 0) { x += dx / 2; dx = 0; } + if (dy < 0) { y += dy / 2; dy = 0; } + return {x: x, y: y, dx: dx, dy: dy}; +} + +/// END LIBRARY CODE + +return d3; + +}); diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/dendrogram/dendrogram.css b/deployment-apps/metricator-for-nmon/appserver/static/components/dendrogram/dendrogram.css new file mode 100644 index 0000000..6048684 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/dendrogram/dendrogram.css @@ -0,0 +1,13 @@ +.node circle { + stroke-width: 1.5px; +} + +.node text { + font-size: 12px; +} + +path.link { + fill: none; + stroke: #ccc; + stroke-width: 1.5px; +} diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/dendrogram/dendrogram.js b/deployment-apps/metricator-for-nmon/appserver/static/components/dendrogram/dendrogram.js new file mode 100644 index 0000000..6842793 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/dendrogram/dendrogram.js @@ -0,0 +1,361 @@ +// Cluster Dendrogram D3.js code taken and modified from http://bl.ocks.org/mbostock/4063570 by Mike Bostock + +define(function (require, exports, module) { + var d3 = require("../d3/d3.layout"); + var SimpleSplunkView = require("splunkjs/mvc/simplesplunkview"); + var _ = require("underscore"); + require("css!./dendrogram.css"); + + var Dendrogram = SimpleSplunkView.extend({ + className: "splunk-toolkit-dendrogram", + options: { + managerid: null, + data: "preview", + root_label: "root_label not set", + height: "auto", + node_outline_color: "#509DDD", + node_close_color: "#e7969c", + node_open_color: "#ffffff", + label_size_color: "#509DDD", + label_count_color: "#1f77b4", + has_size: true, + initial_open_level: 1, + margin_left: 100, + margin_right: 400, + }, + output_mode: "json_rows", + initialize: function () { + _(this.options).extend({ + height_px: 500, + width_px: 2000, + }); + + SimpleSplunkView.prototype.initialize.apply(this, arguments); + + this.settings.on("change:order", this.render, this); + + $(window).resize(this, _.debounce(this._handleResize, 20)); + }, + _handleResize: function (e) { + // e.data is the this pointer passed to the callback. + // here it refers to this object and we call render() + e.data.render(); + }, + createView: function () { + return true; + }, + // Making the data look how we want it to for updateView to do its job + formatData: function (data) { + var height = this.settings.get("height"); + var height_px = this.settings.get("height_px"); + var width = this.settings.get("width"); + var width_px = this.settings.get("width_px"); + var root_label = this.settings.get("root_label"); + var has_size = this.settings.get("has_size"); + + this.settings.set( + "height_px", + height === "auto" ? Math.max(data.length * 30, height_px) : height + ); + + data = _(data).map(function (row) { + return _(row).map(function (item, i) { + // Convert the string value to number + return has_size && i + 1 === row.length ? parseFloat(item) : item; + }); + }); + + var get_sum = function (list) { + return _(list) + .pluck(list[0].length - 1) + .reduce(function (memo, num) { + return memo + num; + }, 0); + }; + + var nest = function (list) { + var groups = _(list).groupBy(0); + + return _(groups).map(function (value, key) { + var children = _(value) + .chain() + .map(function (v) { + return _(v).rest(); + }) + .compact() + .value(); + + if (has_size) { + var sum = get_sum(children); + var count = children.length; + + return children.length == 1 && children[0].length === 1 + ? { name: key, size: children[0][0] } + : { name: key, sum: sum, count: count, children: nest(children) }; + } else { + return children.length == 1 && children[0].length === 0 + ? { name: key } + : { name: key, children: nest(children) }; + } + }); + }; + + var formatted_data = { + name: root_label, + children: nest(data), + }; + + if (has_size) { + _(formatted_data).extend({ + sum: get_sum(data), + count: data.length, + }); + } + + return formatted_data; + }, + updateView: function (viz, data) { + this.$el.html(""); + + //this.$el.append(''); + //this.$el.append(''); + + //$("#open_all").on("click", function() { + // $("g.node_close").click(); + //}); + + //$("#close_all").on("click", function() { + // $("g.node_open").click(); + //}); + + var has_size = this.settings.get("has_size"); + + var node_outline_color = this.settings.get("node_outline_color"); + var node_close_color = this.settings.get("node_close_color"); + var node_open_color = this.settings.get("node_open_color"); + var label_size_color = this.settings.get("label_size_color"); + var label_count_color = this.settings.get("label_count_color"); + + var width = this.settings.get("width_px"); + var height = this.settings.get("height_px"); + + var m = [ + 20, + this.settings.get("margin_right"), + 20, + this.settings.get("margin_left"), + ], + w = width - m[1] - m[3], + h = height - m[0] - m[2], + i = 0; + + var tree = d3.layout.tree().size([h, w]); + + var diagonal = d3.svg.diagonal().projection(function (d) { + return [d.y, d.x]; + }); + + var vis = d3 + .select(this.el) + .append("svg:svg") + .attr("width", w + m[1] + m[3]) + .attr("height", h + m[0] + m[2]) + .append("svg:g") + .attr("transform", "translate(" + m[3] + "," + m[0] + ")"); + + data.x0 = h / 2; + data.y0 = 0; + + function toggle_children(tree, level) { + if (tree.children) { + _(tree.children).each(function (child) { + toggle_children(child, level + 1); + }); + + if (level >= initial_open_level) { + toggle(tree); + } + } + } + + var initial_open_level = this.settings.get("initial_open_level"); + + if (initial_open_level >= 0) { + toggle_children(data, 0); + } + + var duration = 0; + update(data); + duration = d3.event && d3.event.altKey ? 5000 : 500; + + function update(source) { + // Compute the new tree layout. + var nodes = tree.nodes(data).reverse(); + + // Normalize for fixed-depth. + nodes.forEach(function (d) { + d.y = d.depth * 180; + }); + + // Update the nodes… + var node = vis.selectAll("g.node").data(nodes, function (d) { + return d.id || (d.id = ++i); + }); + + // Enter any new nodes at the parent's previous position. + var nodeEnter = node + .enter() + .append("svg:g") + //.attr("class", "node") + .attr("class", function (d) { + return d._children ? "node node_close" : "node node_open"; + }) + .attr("transform", function (d) { + return "translate(" + source.y0 + "," + source.x0 + ")"; + }) + .on("click", function (d) { + toggle(d); + update(d); + }); + + nodeEnter + .append("svg:circle") + .attr("r", 1e-6) + .style("fill", function (d) { + return d._children ? node_close_color : node_open_color; + }) + .style("cursor", function (d) { + return d.children || d._children ? "pointer" : "default"; + }) + .style("stroke", node_outline_color); + + nodeEnter + .append("svg:text") + .attr("x", function (d) { + return d.children || d._children ? -10 : 10; + }) + .attr("dy", ".35em") + .attr("text-anchor", function (d) { + return d.children || d._children ? "end" : "start"; + }) + .style("cursor", function (d) { + return d.children || d._children ? "pointer" : "default"; + }) + .style("fill-opacity", 1e-6) + .html(function (d) { + if (has_size) { + var sum = Number(d.sum).toLocaleString("en"); + var size = Number(d.size).toLocaleString("en"); + + var long_label = + d.name + + ' - ' + + sum + + ' - ' + + d.count + + ""; + var short_label = + d.name + + ' - ' + + size + + ""; + + return d.children || d._children ? long_label : short_label; + } else { + return d.name; + } + }); + + // Transition nodes to their new position. + var nodeUpdate = node + .transition() + .duration(duration) + .attr("transform", function (d) { + return "translate(" + d.y + "," + d.x + ")"; + }); + + nodeUpdate + .select("circle") + .attr("r", 4.5) + .style("fill", function (d) { + return d._children ? node_close_color : node_open_color; + }); + + nodeUpdate.select("text").style("fill-opacity", 1); + nodeUpdate.select("text").style("fill", "white"); + + // Transition exiting nodes to the parent's new position. + var nodeExit = node + .exit() + .transition() + .duration(duration) + .attr("transform", function (d) { + return "translate(" + source.y + "," + source.x + ")"; + }) + .remove(); + + nodeExit.select("circle").attr("r", 1e-6); + + nodeExit.select("text").style("fill-opacity", 1e-6); + + // Update the links… + var link = vis + .selectAll("path.link") + .data(tree.links(nodes), function (d) { + return d.target.id; + }); + + // Enter any new links at the parent's previous position. + link + .enter() + .insert("svg:path", "g") + .attr("class", "link") + .attr("d", function (d) { + var o = { x: source.x0, y: source.y0 }; + return diagonal({ source: o, target: o }); + }) + .transition() + .duration(duration) + .attr("d", diagonal); + + // Transition links to their new position. + link.transition().duration(duration).attr("d", diagonal); + + // Transition exiting nodes to the parent's new position. + link + .exit() + .transition() + .duration(duration) + .attr("d", function (d) { + var o = { x: source.x, y: source.y }; + return diagonal({ source: o, target: o }); + }) + .remove(); + + // Stash the old positions for transition. + nodes.forEach(function (d) { + d.x0 = d.x; + d.y0 = d.y; + }); + } + + // Toggle children. + function toggle(d) { + if (d.children) { + d._children = d.children; + d.children = null; + } else { + d.children = d._children; + d._children = null; + } + } + }, + }); + return Dendrogram; +}); diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/forcedirected/bower.json b/deployment-apps/metricator-for-nmon/appserver/static/components/forcedirected/bower.json new file mode 100644 index 0000000..b40be47 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/forcedirected/bower.json @@ -0,0 +1,10 @@ +{ + "name": "forcedirected", + "version": "1.0.0", + "main": "forcedirected.js", + "ignore": [], + "dependencies": { + "d3": "3.3.x" + }, + "devDependencies": {} +} \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/forcedirected/forcedirected.css b/deployment-apps/metricator-for-nmon/appserver/static/components/forcedirected/forcedirected.css new file mode 100644 index 0000000..b49d0b0 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/forcedirected/forcedirected.css @@ -0,0 +1,86 @@ +.splunk-toolkit-force-directed { + overflow: hidden; + font-family: arial; +} + +.splunk-toolkit-force-directed circle.node { + stroke: #fff; + stroke-width: 1.5px; +} + +.splunk-toolkit-force-directed .link, .splunk-toolkit-force-directed #arrowEnd { + stroke: #999; + stroke-opacity: .6; + fill: none; +} +.splunk-toolkit-force-directed #arrowEnd { + fill: #999; +} + +.splunk-toolkit-force-directed circle.node { + stroke: #fff; + stroke-width: 1.5px; +} + +.splunk-toolkit-force-directed circle.nodeHighlight, +.splunk-toolkit-force-directed circle.highlight { + stroke-width: 2px; + stroke: #E89595; +} + +.linkHighlight { + stroke: red !important; +} + +.splunk-toolkit-force-directed circle.nodeHighlight.highlight { + stroke-width: 3px; +} + + +.splunk-toolkit-force-directed line.link { + stroke: #999; + stroke-opacity: .6; +} + +.splunk-toolkit-force-directed #chart { + width: 100%; + height: 100%; +} + +.splunk-toolkit-force-directed #tooltipContainer { + border: 1px solid hsl(0, 0%, 80%); + position: absolute; + min-width: 200px; + min-height: 50px; + border-radius:3px; + z-index:100; + background: #3A3A3A; + padding: 10px; + color: white; + top:50px; +} + +.splunk-toolkit-force-directed .group-swatch { + width:20px; + height:20px; + float:left; + margin:2px; + margin-right: 10px +} + +.splunk-toolkit-force-directed .group-name { + padding-top: 5px; +} + +.splunk-toolkit-force-directed .tooltipLabel { + font-weight:bold; + padding-right:5px; +} + +.splunk-toolkit-force-directed .tooltipRow { + margin-bottom:10px; +} + +.splunk-toolkit-force-directed .panCursor { + cursor: move; +} \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/forcedirected/forcedirected.js b/deployment-apps/metricator-for-nmon/appserver/static/components/forcedirected/forcedirected.js new file mode 100644 index 0000000..1b694ef --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/forcedirected/forcedirected.js @@ -0,0 +1,546 @@ +// Force Directed Graphs! +// these require an input of (at least) 3 fields in the format +// 'stats count by field1 field2 field3' + +// ---- settings ---- +// height, width +// panAndZoom: the ability to zoom (true, false) +// directional: true, false +// valueField: what field to count by +// charges, gravity: change the look of the graph, play around with these! +// linkDistance: the distance between each node + +// ---- expected data format ---- +// a splunk search like this: source=*somedata* | stats count by artist_name track_name device +// each group is an artist/song pairing +// { +// "nodes":[ +// { +// "source":"Bruno Mars", +// "group":0 +// }, +// { +// "source":"It Will Rain", +// "group":0 +// }, +// { +// "source":"Cobra Starship", +// "group":1 +// }, +// { +// "source":"You Make Me Feel", +// "group":1 +// }, +// { +// "source":"Gym Class Heroes", +// "group":2 +// }, +// { +// "source":"Stereo Hearts", +// "group":2 +// }, +// ], +// "links":[ +// { +// "source":0, +// "target":1, +// "value":null +// }, +// { +// "source":2, +// "target":3, +// "value":null +// }, +// { +// "source":4, +// "target":5, +// "value":null +// }, +// ], + +// - we add this part - + +// "groupNames":{ +// "iphone":49, +// "android":53, +// "blackberry":48, +// "ipad":52, +// "ipod":50 +// }, +// "groupLookup":[ +// "iphone", +// "android", +// "blackberry", +// "ipad", +// "ipod" +// ] +// } + +define(function(require, exports, module) { + + var _ = require('underscore'); + var d3 = require("../d3/d3"); + var SimpleSplunkView = require("splunkjs/mvc/simplesplunkview"); + + var ForceDirected = SimpleSplunkView.extend({ + moduleId: module.id, + + className: "splunk-toolkit-force-directed", + + options: { + managerid: null, + data: 'preview', + panAndZoom: true, + directional: true, + valueField: 'count', + charges: -500, + gravity: 0.2, + linkDistance: 15, + swoop: false, + isStatic: true + }, + + output_mode: "json_rows", + + initialize: function() { + SimpleSplunkView.prototype.initialize.apply(this, arguments); + + // in the case that any options are changed, it will dynamically update + // without having to refresh. + this.settings.on("change:charges", this.render, this); + this.settings.on("change:gravity", this.render, this); + this.settings.on("change:linkDistance", this.render, this); + this.settings.on("change:directional", this.render, this); + this.settings.on("change:panAndZoom", this.render, this); + this.settings.on("change:swoop", this.render, this); + this.settings.on("change:isStatic", this.render, this); + }, + + createView: function() { + var margin = {top: 10, right: 10, bottom: 10, left: 10}; + var availableWidth = parseInt(this.settings.get("width") || this.$el.width(), 10); + var availableHeight = parseInt(this.settings.get("height") || this.$el.height(), 10); + + this.$el.html(""); + + var svg = d3.select(this.el) + .append("svg") + .attr("width", availableWidth) + .attr("height", availableHeight) + .attr("pointer-events", "all"); + + return { container: this.$el, svg: svg, margin: margin }; + }, + + // making the data look how we want it to for updateView to do its job + formatData: function(data) { + var nodes = {}; + var links = []; + data.forEach(function(link) { + var sourceName = link[0]; + var targetName = link[1]; + var groupName = link[2]; + var newLink = {}; + newLink.source = nodes[sourceName] || + (nodes[sourceName] = {name: sourceName, group: groupName, value: 0}); + newLink.target = nodes[targetName] || + (nodes[targetName] = {name: targetName, group: groupName, value: 0}); + newLink.value = +link[3]; + newLink.source.value += newLink.value; + newLink.target.value += newLink.value; + links.push(newLink); + }); + + return {nodes: d3.values(nodes), links: links}; + }, + + updateView: function(viz, data) { + var that = this; + var containerHeight = this.$el.height(); + var containerWidth = this.$el.width(); + + // Clear svg + var svg = $(viz.svg[0]); + svg.empty(); + svg.height(containerHeight); + svg.width(containerWidth); + + // Add the graph group as a child of the main svg + var graphWidth = containerWidth - viz.margin.left - viz.margin.right; + var graphHeight = containerHeight - viz.margin.top - viz.margin.bottom; + var graph = viz.svg + .append("g") + .attr("width", graphWidth) + .attr("height", graphHeight) + .attr("transform", "translate(" + viz.margin.left + "," + viz.margin.top + ")"); + + // Get settings + this.charge = this.settings.get('charges'); + this.gravity = this.settings.get('gravity'); + this.linkDistance = this.settings.get('linkDistance'); + this.zoomable = this.settings.get('panAndZoom'); + this.swoop = this.settings.get('swoop'); + this.isStatic = this.settings.get('isStatic'); + this.isDirectional = this.settings.get('directional'); + this.zoomFactor = 0.5; + + this.groupNameLookup = data.groupLookup; + + // Set up graph + var r = 6; + var height = graphHeight; + var width = graphWidth; + var force = d3.layout.force() + .gravity(this.gravity) + .charge(this.charge) + .linkDistance(this.linkDistance) + .size([width, height]); + + this.color = d3.scale.category20(); + + this.tooltips = new Tooltips(graph); + + if (this.zoomable) { + initPanZoom.call(this, viz.svg); + } + + graph.style("opacity", 1e-6) + .transition() + .duration(1000) + .style("opacity", 1); + + graph.append("svg:defs").selectAll("marker") + .data(["arrowEnd"]) + .enter().append("svg:marker") + .attr("id", String) + .attr("viewBox", "0 -5 10 10") + .attr("refX", 0) + .attr("refY", 0) + .attr("markerWidth", 6) + .attr("markerHeight", 6) + .attr("markerUnits", "userSpaceOnUse") + .attr("orient", "auto") + .append("svg:path") + .attr("d", "M0,-5L10,0L0,5"); + + var link = graph.selectAll("line.link") + .data(data.links) + .enter().append('path') + .attr("class", "link") + .attr("marker-end", function(d) { + if (that.isDirectional) { + return "url(#" + "arrowEnd" + ")"; + } + }) + .style("stroke-width", function(d) { + var num = Math.max(Math.round(Math.log(d.value)), 1); + return _.isNaN(num) ? 1 : num; + }); + + link + .on('click', function(d) { + that.trigger('click:link', { + source: d.source.name, + sourceGroup: d.source.group, + target: d.target.name, + targetGroup: d.target.group, + value: d.value + }); + }) + .on('mouseover', function(d) { + d3.select(this).classed('linkHighlight', true); + openLinkTooltip(d, this); + }) + .on('mouseout', function(d) { + d3.select(this).classed('linkHighlight', false); + that.tooltips.close(this); + }); + + var node = graph.selectAll("circle.node") + .data(data.nodes) + .enter().append("svg:circle") + .attr("class", "node") + .attr("r", r - 1) + .style("fill", function(d) { + return that.color(d.group); + }) + .call(force.drag); + + node.append("title") + .text(function(d) { return d.name; }); + + node + .on('click', function(d) { + that.trigger('click:node', { + name: d.name, + group: d.group, + value: d.value + }); + }) + .on('mouseover', function(d) { + d3.select(this).classed('nodeHighlight', true); + openNodeTooltip(d, this); + }) + .on('mouseout', function(d) { + d3.select(this).classed('nodeHighlight', false); + that.tooltips.close(this); + }); + + force.nodes(data.nodes) + .links(data.links) + .on("tick", function() { + link.attr("d", function(d) { + var diffX = d.target.x - d.source.x; + var diffY = d.target.y - d.source.y; + + // Length of path from center of source node to center of target node + var pathLength = Math.sqrt((diffX * diffX) + (diffY * diffY)); + + // x and y distances from center to outside edge of target node + var offsetX = (diffX * (r * 2)) / pathLength; + var offsetY = (diffY * (r * 2)) / pathLength; + + if (!that.swoop) { + pathLength = 0; + } + + return "M" + d.source.x + "," + d.source.y + "A" + pathLength + "," + pathLength + " 0 0,1 " + (d.target.x - offsetX) + "," + (d.target.y - offsetY); + }); + + node.attr("cx", function(d) { + d.x = Math.max(r, Math.min(width - r, d.x)); + return d.x; + }) + .attr("cy", function(d) { + d.y = Math.max(r, Math.min(height - r, d.y)); + return d.y; + }); + + }).start(); + + if (this.isStatic) { + forwardAlpha(force, 0.005, 1000); + } + + function forwardAlpha(layout, alpha, max) { + alpha = alpha || 0; + max = max || 1000; + var i = 0; + while (layout.alpha() > alpha && i++ < max) { + layout.tick(); + } + } + + // draggin' + function initPanZoom(svg) { + var that = this; + svg.on('mousedown.drag', function() { + if (that.zoomable) { + svg.classed('panCursor', true); + } + // console.log('drag start'); + }); + + svg.on('mouseup.drag', function() { + svg.classed('panCursor', false); + // console.log('drag stop'); + }); + + svg.call(d3.behavior.zoom().on("zoom", function() { + panZoom(); + })); + } + + // zoomin' + function panZoom() { + graph.attr("transform", + "translate(" + d3.event.translate + ")" + + " scale(" + d3.event.scale + ")"); + } + + function openNodeTooltip(d, node) { + var groupName; + + if (that.groupNameLookup !== undefined) { + groupName = that.groupNameLookup[d.group]; + } else { + groupName = d.group; + } + + that.tooltips.open('nodes', { + slots: { + val: d.name, + group: groupName + }, + swatch: that.color(d.group) + }, node); + } + + function openLinkTooltip(d, node) { + that.tooltips.open('links', { + slots: { + source: d.source.name, + target: d.target.name + } + }, node); + } + + //TODO: This doesn't seem to be used in this file + function getSafeVal(getobj, name) { + var retVal; + if (getobj.hasOwnProperty(name) && getobj[name] !== null) { + retVal = getobj[name]; + } else { + retVal = name; + } + return retVal; + } + + function highlightNodes(val) { + var self = this, groupName; + if (val !== ' ' && val !== '') { + graph.selectAll('circle') + .filter(function(d, i) { + groupName = self.groupNameLookup[d.group]; + if (d.source.indexOf(val) >= 0 || groupName.indexOf(val) >= 0) { + d3.select(this).classed('highlight', true); + } else { + d3.select(this).classed('highlight', false); + } + }); + } else { + graph.selectAll('circle').classed('highlight', false); + } + } + + /////////////////////// formerly known as tooltips.js ///////////////////////////// + + function Tooltips(svg) { + var tooltipTimer = null, + tooltipOpenCoords = {}, + tooltipIsOpen = false, + tooltipContents, + $tooltipContainer, + isReady = false, + layouts; + + setup(svg, viz.container); + + function setup(svg, $container) { + var self = this, + data = [0], + $nodeVal, $nodeGroup, $nodeContainer, + $linkSource, $linkTarget, $linkContainer; + + $tooltipContainer = $("
"); + + $nodeContainer = $("
"); + $nodeVal = $("
Value:
"); + $nodeGroup = $("
Group:
"); + $nodeContainer.append($nodeVal); + $nodeContainer.append($nodeGroup); + $tooltipContainer.append($nodeContainer); + + $linkContainer = $(""); + $linkSource = $("
Source:
"); + $linkTarget = $("
Target:
"); + $linkContainer.append($linkSource); + $linkContainer.append($linkTarget); + $tooltipContainer.append($linkContainer); + + $tooltipContainer.find('.group-swatch').hide(); + + $container.prepend($tooltipContainer); + $tooltipContainer.hide(); + + layouts = { + 'nodes': { + "container": $nodeContainer, + "slots": { + "val": $nodeVal.find('.field1-val'), + "group": $nodeGroup.find('.group-val') + }, + "swatch": $nodeContainer.find('.group-swatch') + }, + 'links': { + "container": $linkContainer, + "slots": { + "source": $linkSource.find('.source-val'), + "target": $linkTarget.find('.target-val') + } + } + }; + + isReady = true; + } + + function clearTooltips() { + if (isReady) { + $.each(layouts, function(k, layout) { + $.each(layout.slots, function(k, v) { + // this isnt really neccesary because it's either hidden or shown with newly-replaced content + v.empty(); + }); + layout.container.hide(); + if (layout.swatch !== undefined) { + layout.swatch.hide(); + } + }); + } + } + + this.close = function(node) { + // return false; + var self = this, + dx, dy; + + var mouseCoords = d3.mouse(node); + + if (tooltipTimer !== null) { + window.clearTimeout(tooltipTimer); + } + + dx = Math.abs(tooltipOpenCoords.x - mouseCoords[0]); + dy = Math.abs(tooltipOpenCoords.y - mouseCoords[1]); + + /* + only close the tooltip when the user has moved a certain distance away + this helps when an element is very small and the user might have + difficulty keeping their mouse directly over it + */ + if (dy > 10 || dx > 10) { + tooltipIsOpen = false; + tooltipTimer = window.setTimeout(function() { + $tooltipContainer.fadeOut(400); + }, 500); + } + }; + + this.open = function(layout, data, node) { + var mouseCoords = d3.mouse(node); + tooltipIsOpen = true; + tooltipOpenCoords = { + x: mouseCoords[0] + 6 * 2, + y: mouseCoords[1] + 6 * 3 + }; + + clearTooltips(); + $.each(data.slots, function(k, v) { + layouts[layout]['slots'][k].append(v); + }); + layouts[layout]['container'].show(); + if (layouts[layout]['swatch'] !== undefined) { + layouts[layout]['swatch'].show().css('background-color', data.swatch); + } + + $tooltipContainer + .css("left", tooltipOpenCoords.x) + .css("top", tooltipOpenCoords.y); + $tooltipContainer.fadeIn(400); + }; + } + } + + }); + return ForceDirected; +}); \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/lib/options.js b/deployment-apps/metricator-for-nmon/appserver/static/components/lib/options.js new file mode 100644 index 0000000..8009289 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/lib/options.js @@ -0,0 +1,53 @@ +// This code has been imported from the following nice work: https://splunkbase.splunk.com/app/3171/ + +// Author: Ryan Thibodeaux +// +// +// Options module for passing +// parameters between modules/functions. + +(function() { + define([ + "module", + ], function(module) { + + var appOptions; + var options = {}; + var config = module.config(); + + if (typeof config !== 'undefined' && config !== null) { + options = config.options; + } + + return appOptions = (function() { + function appOptions() {} // empty constructor + + // check if appOptions contains parameter 'name' + appOptions.hasOption = function(name) { + if (typeof options === 'undefined' || + typeof name === 'undefined' || + options.hasOwnProperty(name) !== true) { + return false; + } + return true; + }; + + // return value stored in parameter 'name' + appOptions.getOptionValue = function(name) { + return (appOptions.hasOption(name) ? options[name] : undefined); + }; + + // set parameter 'name' to value + appOptions.setOptionValue = function(name, value) { + if (!appOptions.hasOption(name)) { + return false; + } + + options[name] = value; + return true; + }; + + return appOptions; + })(); + }); +}).call(this); diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/lib/utils.js b/deployment-apps/metricator-for-nmon/appserver/static/components/lib/utils.js new file mode 100644 index 0000000..50e61d5 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/lib/utils.js @@ -0,0 +1,740 @@ +// This code has been imported from the following nice work: https://splunkbase.splunk.com/app/3171/ + +// Author: Ryan Thibodeaux +// +// +// Utility functions used throughout +// other modules and funcitons in the app. + + +(function() { + define([ + "jquery", + "underscore", + "appOptions", + "splunkjs/mvc", + "splunkjs/mvc/simplexml/ready!", + ], function($, _, appOptions, mvc) { + + var appUtils; + var footerRemovalTimerOn = 0; + + var submittedTokenModel = mvc.Components.get('submitted'); + var defaultTokenModel = mvc.Components.get('default'); + + if (typeof mvc === 'undefined' || !submittedTokenModel || !defaultTokenModel) { + var str = "Failed to load Splunk components. " + + "This is probably a symptom of a bigger problem."; + alert(str); + console.error(str); + } + + return appUtils = (function() { + + function appUtils() {} // empty constructor + + + // Initializes app tokens and set footer removal timer + appUtils.initiliazeApp = function(submit) { + + // make sure appName and pageName are set, and set + // the 'my_app' and 'my_view' tokens accordingly + var myApp = appOptions.getOptionValue('appName'); + var myView = appOptions.getOptionValue('pageName'); + if (typeof myApp === 'undefined' || myApp.toString().trim().length < 1 || + typeof myView === 'undefined' || myView.toString().trim().length < 1) { + + var comps = (location.pathname.split('?')[0]).split('/'); + var idx = comps.indexOf('app'); + myApp = comps[idx + 1]; + myView = comps[idx + 2]; + + appOptions.setOptionValue('appName', myApp); + appOptions.setOptionValue('pageName', myView); + } + + appUtils.setToken('my_app', myApp); + appUtils.setToken('my_view', myView); + + if (!!submit) { //!!undefined is false + appUtils.submitTokens(); + } + + // make sure pageStartTime is set + var startTime = appOptions.getOptionValue('pageStartTime'); + if (typeof startTime === 'undefined' || startTime <= 0) { + startTime = new Date().valueOf(); + appOptions.setOptionValue('pageStartTime', startTime); + } + + // set timer to remove footer instead of relying on + // page 'load' event (that was unreliable) + appUtils.setFooterEditTimer(200); + }; + + + // return token model objects + appUtils.getTokenModels = function() { + return ([defaultTokenModel, submittedTokenModel]); + } + + + // set generic wildcard tooltip on passed element name(s) where + // inputs can be an array or a comma-delimited list + appUtils.setWildCardTooltip = function(inputElements) { + + if (typeof inputElements === 'undefined' || inputElements.length < 1) { + return; + } + + var newArray = inputElements; + + // test if not an Array - turn it into one if it is not + if (Object.prototype.toString.call(inputElements) !== '[object Array]') { + newArray = inputElements.replace(/^,+|,+$/gm, '').split(","); + } + + var len = newArray.length; + + for (var i = 0; i < len; i++) { + appUtils.setTooltip(newArray[i], 'Use \"*\" as a wildcard'); + } + }; + + + // set the 'tip' string as the tooltip for element 'name' + appUtils.setTooltip = function(name, tip) { + + if (typeof name === 'undefined' || name.length < 1 || typeof tip === 'undefined') { + return; + } + + var eleID = (name[0] === '#' ? name : '#' + name); + var e = $(eleID); + + // element exists, so add tooltips + if (e.length) { + + // add tooltips to text inputs + var textChild = e.children('div.splunk-textinput'); + if (textChild.length) { + textChild.attr('title', tip); + var textChildInputs = textChild.find('input'); + if (textChildInputs.length) { + textChildInputs.attr('placeholder', tip); + } + } + + // add tooltips to multiselect and dropdown inputs + var msChild = e.children('div.splunk-choice-input'); + if (msChild.length) { + msChild.attr('title', tip); + } + } + }; + + + // remove links from Splunk footer + appUtils.hideFooterLinks = function() { + + footerRemovalTimerOn = 0; + + var footer = $('#footer'); + + if (footer.length > 0) { + links = footer.find('a'); + if (links.length > 0) { + links.hide(); + + // hide the "Hide Filters" link on top of the + // dashboard if it is present + var hideLink = $('.hide-global-filters'); + if (hideLink.length > 0) { + hideLink.hide(); + } + + } else { + appUtils.setFooterEditTimer(); + } + } + }; + + + // setup timer to remove links from Splunk footer, where + // the footer is checked 'delayMS' milliseconds from now + appUtils.setFooterEditTimer = function(delayMS) { + + // set default delay for when to check for footer + // if delayMS was not set + if (Math.floor(delayMS) > 1) {} else { + delayMS = 1000; + } + + // don't allow setting this timer after page has been loaded + // for more than 60 seconds + if (appUtils.getPageLoadedSecs() > 60) { + return; + } + + // only allow assessing the footer if the footer is on + // the dashboard, i.e., hideFooter is not true + if ($('#footer').length > 0) { + if (!footerRemovalTimerOn) { + setTimeout(appUtils.hideFooterLinks, delayMS); + footerRemovalTimerOn = 1; + } + } + }; + + + // number of seconds the page has been loaded + appUtils.getPageLoadedSecs = function() { + return ((new Date().valueOf() - appOptions.getOptionValue('pageStartTime')) / 1000); + }; + + + // Sets token 'name' to 'value' in submittedTokenModel and + // defaultTokenModel unless excludeDefault is set to true + appUtils.setSubmittedToken = function(name, value, excludeDefault) { + if (typeof name === 'undefined' || !submittedTokenModel) { + return; + } + if (!excludeDefault) { + appUtils.setDefaulToken(name, value); + } + submittedTokenModel.set(name, value); + }; + + // Sets token 'name' to 'value' in defaultTokenModel. + appUtils.setDefaulToken = function(name, value) { + if (typeof name === 'undefined' || !defaultTokenModel) { + return; + } + defaultTokenModel.set(name, value); + }; + + // Sets token 'name' to 'value' in defaultTokenModel and + // submit all tokens if set + appUtils.setToken = function(name, value, submit) { + appUtils.setDefaulToken(name, value); + + if (!!submit) { + appUtils.submitTokens(); + } + }; + + // Returns value of token 'name' in defaultTokenModel and + appUtils.getDefaultToken = function(name) { + if (typeof name === 'undefined' || !defaultTokenModel) { + return undefined; + } + return defaultTokenModel.get(name); + }; + + // Returns value of token 'name' in submittedTokenModel and + appUtils.getSubmittedToken = function(name) { + if (typeof name === 'undefined' || !submittedTokenModel) { + return undefined; + } + return submittedTokenModel.get(name); + }; + + // Returns value of token 'name' in token model 'model' + appUtils.getToken = function(name, model) { + var tokens = (typeof model === 'undefined') ? defaultTokenModel : model; + + if (typeof name === 'undefined' || !tokens) { + return undefined; + } + + return tokens.get(name); + }; + + + // Copy defaultTokenModel values into submittedTokenModels + appUtils.submitTokens = function() { + if (submittedTokenModel && defaultTokenModel) { + submittedTokenModel.set(defaultTokenModel.toJSON()); + } + }; + + // Return boolean answer to if 'checkval' matches 'newval' + appUtils.checkTokenValue = function(checkval, newval) { + return (newval === checkval ? true : false); + }; + + + // Jumps to div element eleID + appUtils.scrollIntoView = function(eleID, setting) { + var e = document.getElementById(eleID); + if (!!e && e.scrollIntoView) { + e.scrollIntoView(setting); + } + }; + + + // return if a token is set or not, where "lax" determines + // if the token is checked if it is an empty value as well + appUtils.checkEmptyValue = function(value, lax) { + if (!!lax) { + return (typeof value === 'undefined') + } else { + return (typeof value === 'undefined' || value.length < 1) + } + }; + + // Toggles visibility of HTML elements of a dashboard + appUtils.hideHtmlElement = function(eleID, hide) { + if (appUtils.checkEmptyValue(eleID)) { + return; + } + + var e = (eleID[0] === '#' ? eleID : '#' + eleID); + if ($(e).length) { + if (!!hide) { + $(e).hide(); + } else { + $(e).show(); + } + } + }; + + // loop through input elements and evaluate each one for focus + appUtils.checkEmptyTokenFocusForDashboard = function(inputs) { + if (typeof inputs === 'undefined') { + return; + } + + var len = inputs.length; + var currentValue = undefined; + + for (var i = 0; i < len; i++) { + currentValue = (defaultTokenModel.attributes.hasOwnProperty('form.' + inputs[i]) ? appUtils.getToken('form.' + inputs[i]) : appUtils.getToken(inputs[i])); + appUtils.checkEmptyTokenFocus(inputs[i], currentValue); + } + }; + + + // set border style based on state of 'value' + appUtils.checkEmptyTokenFocus = function(name, value) { + var id = (name[0] === '#' ? name : '#' + name); + var p = $(id); + if (p.length) { + if (typeof value === 'undefined' || value.length < 1) { + appUtils.setInputFocus(p); + return true; + } else { + appUtils.clearInputFocus(p); + return false; + } + } + return false; + }; + + // set the focus effects on the based element + appUtils.setInputFocus = function(el) { + if (el.hasClass('input-text') || el.hasClass('splunk-textinput')) { + el.find('input[type="text"]').css("border-color", "red").css("box-shadow", "0px 1px 1px rgba(0, 0, 0, 0.075) inset, 0px 0px 8px rgba(222, 79, 79, 0.6"); + } else if (el.hasClass('input-dropdown')) { + el.find('.select2-choice').css("border-color", "red").css("box-shadow", "0px 1px 1px rgba(0, 0, 0, 0.075) inset, 0px 0px 8px rgba(222, 79, 79, 0.6"); + } else if (el.hasClass('input-multiselect')) { + el.find('.select2-choices').css("border-color", "red").css("box-shadow", "0px 1px 1px rgba(0, 0, 0, 0.075) inset, 0px 0px 8px rgba(222, 79, 79, 0.6"); + } else { + el.css("border-style", "double"); + } + }; + + // clear the focus effects on the based element + appUtils.clearInputFocus = function(el) { + if (el.hasClass('input-text') || el.hasClass('splunk-textinput')) { + el.find('input[type="text"]').css("border-color", "").css("box-shadow", ""); + } else if (el.hasClass('input-dropdown')) { + el.find('.select2-choice').css("border-color", "").css("box-shadow", ""); + } else if (el.hasClass('input-multiselect')) { + el.find('.select2-choices').css("border-color", "").css("box-shadow", ""); + } else { + el.css("border-style", "none"); + } + }; + + + // add event listener of type to object using the assigned callback + appUtils.addEvent = function(object, type, callback) { + if (typeof object === 'undefined') { + return; + } + if (object.addEventListener) { + object.addEventListener(type, callback, false); + } else if (object.attachEvent) { + object.attachEvent("on" + type, callback); + } else { + object["on" + type] = callback; + } + }; + + // redirects to a new page in the current app where urlSegment + // starts with the new page to go to and newTab indicates if + // we want to open a new tab or not + appUtils.drilldownRedirect = function(urlSegment, newTab) { + + if (typeof urlSegment === 'undefined' || urlSegment.toString().trim().length < 1) { + return; + } + + // make sure the new segment starts with a '/' + var segment = urlSegment.toString().trim(); + segment = (segment[0] === '/' ? segment : '/' + segment); + + // get strip everything in the current URL and strip it down + // to what comes before the current page, including the last '/' + var uri = window.location.toString(); + var currentPage = appUtils.getToken('my_view'); + var path = uri.substr(0, uri.indexOf(currentPage)).replace(/\/+$/i, ''); + + // go to new URL + if (!!newTab) { + window.open(path + segment, "_blank"); + } else { + window.location = path + segment; + } + }; + + // generate html button in parent element + // id: id and name to use on the html button + // label: label/span to apply to the button + // parent: id of parent html element in which to place the button + // append?: should append or prepend in parent list of children + // submit?: should it be a submit button type or not + // vertical?: is the button used in a vertical list of items + appUtils.generateButton = function(id, label, parent, append, submit, vertical) { + + var btn = document.createElement('button'); + var span; + + // apply id field + if (typeof id !== 'undefined' && id.length > 0) { + btn.id = id; + btn.name = id; + } + + // apply label + if (typeof label !== 'undefined' && label.length > 0) { + span = document.createElement('span'); + span.innerHTML = label; + btn.appendChild(span); + } + + // assign styling and insert if parent is set + if (typeof parent !== 'undefined' && parent.length > 0) { + var parentID = (parent[0] === '#' ? parent : '#' + parent); + var p = $(parentID); + + if (p.length) { + + // set button in its place of the parent + var t = p.find('.fieldset'); + if (t.length) { + t = $(t[0]); + if (!!append) { + t.append(btn); + } else { + t.prepend(btn); + } + } + } + } + + // set button type classes and CSS + if (!!submit) { + btn.className = 'btn btn-primary'; + } else { + btn.className = 'btn-info btn-app-info'; + } + + // set button CSS based on it being in a + // vertical stack of items or not + if (!!vertical) { + btn.style.verticalAlign = 'middle'; + btn.style.margin = "5px 10px 5px 0px"; + } else { + btn.style.verticalAlign = 'top'; + btn.style.marginTop = "21px"; + btn.style.marginRight = " 10px"; + } + + return $(btn); + }; + + // strip value of dangerous characters in Splunk and trim the result + appUtils.cleanTxtString = function(value) { + if (typeof value === 'undefined' || value.length < 1) { + return ""; + } + return value.replace(/%|\||\=|\[|\]|\(|\)/g, "").trim(); + }; + + // clean raw input text elements + // value: current value to clean + // defaultVal: default value to return if cleaned version is empty/undefined + // post: function to use to clean passed value + appUtils.cleanTextInputElement = function(value, defaultVal, post) { + + var cleanedValue = defaultVal; + + if (typeof value !== 'undefined') { + + if (!!post) { + cleanedValue = post(value.toString()); + } else { + cleanedValue = appUtils.cleanTxtString(value.toString()); + } + + if (cleanedValue.length < 1) { + cleanedValue = defaultVal; + } + } + + return cleanedValue; + }; + + + // Forces the strict ordering of the values in the token of a checkbox + // group identified by the argument "name". The ordering is determined + // by the order of the individual checkboxes in the group. The current + // values of the token is passed via the "value" argument. + appUtils.enforceCheckboxOrdering = function(name, value) { + var cb = mvc.Components.getInstance(name); + if (typeof cb !== 'undefined') { + var preferred_values_order = []; + var new_field_list = []; + var matched = []; + var choices = cb.options.choices; + + // set list of preferred order based on value ordering in checkbox + for (var i = 0; i < choices.length; i++) { + preferred_values_order.push(choices[i]['value']); + } + + // values that do match entries in ordered_preference + matched = value.filter(function(x) { return preferred_values_order.indexOf(x) >= 0 }); + + // loop through preferred_values_order and add them if they are present in matched + for (var j = 0; j < preferred_values_order.length; j++) { + if (matched.indexOf(preferred_values_order[j]) >= 0) { + new_field_list.push(preferred_values_order[j]); + } + } + + appUtils.setToken("form." + name, new_field_list); + } + }; + + + // Setup the modal search tool button and event listeners + // for the passed instance in "modalObject" + appUtils.setupModalSearchTool = function(modalObject) { + + if (typeof modalObject !== 'undefined') { + + // Create a button on the top fieldset that will open the modal window + var modalButton = appUtils.generateButton('btn_modal_open', 'Open Search Tool'); + modalButton.click(function() { + appUtils.setToken('dd_modal_search_time.earliest', appUtils.getToken('earliest')); + appUtils.setToken('dd_modal_search_time.latest', appUtils.getToken('latest')); + modalObject.show(); + }); + + // add modal button to end of top fieldset after the last input / submit button + var topFieldset = $('.dashboard-body').find('.fieldset').first(); + if (topFieldset.length > 0) { + var topFieldsetChildren = topFieldset.children(); + if (topFieldsetChildren.length > 0) { + var i = topFieldsetChildren.length - 1; + for(i; i >= 0 ; i--) { + var lastChild = $(topFieldsetChildren[i]); + if (!lastChild.hasClass('form-submit') && !lastChild.hasClass('input')) { + // continue, go to next previous child + } else { + lastChild.after(modalButton); + break; + } + } + if (i < 0) { + topFieldset.append(modalButton); + } + } else { + topFieldset.append(modalButton); + } + } + + defaultTokenModel.on("change:dd_modal_search_value", function(model, value, options) { + appUtils.checkEmptyTokenFocus("dd_modal_search_value", value); + }); + + submittedTokenModel.on("change:dd_modal_search_value", function(model, value, options) { + appUtils.setToken("dd_modal_search_value_internal", appUtils.parseModalSearchTerm("dd_modal_search_value", value), true); + }); + } + }; + + + // Parse and clean the search input string from modal + // window search tool. + // Returns the cleaned value. + // name: name of the token used for the search input text box + // value: value obtained from the text box + appUtils.parseModalSearchTerm = function(name, value) { + + if (typeof value === 'undefined') { + return undefined; + } else if (value.toString().trim() === "") { + appUtils.setToken(name, undefined, true); + return undefined; + } + + var valueCleaned = value.toString().replace(/\'|\"|\||%|\[|\]|\(|\)|\=/g, ''); + + if (valueCleaned !== value) { + alert('Search string contained disallowed characters (\'\"%|[]()=). They have been stripped in the applied search value.'); + } + + value = valueCleaned.trim(); + + if (value === "") { + alert("Applied search string is empty. Please enter a valid search string."); + appUtils.setToken(name, undefined, true); + return undefined; + } + + return value; + }; + + + // Parse and clean selected host. Valid inputs values + // will be separated into a domain and user token. + // Returns boolean value indicating if the tokens have changed. + // name: name of the token used for the input text box + // value: value obtained from the text box + appUtils.parseDashboardHostTokens = function(name, value) { + + var newHostValue = undefined; + var currentHostValue = appUtils.getSubmittedToken('dd_target_host_internal'); + var submit = false; + + if (typeof value !== 'undefined') { + + // trim whitespace + var cleanedValue = value.trim(); + + // reset initial value if nothing is left after cleaning, + // but don't call submit + if (cleanedValue.length < 1) { + appUtils.setToken(name, undefined); + } else { + + // alert the host if there are disallowed characters + if (typeof cleanedValue !== 'undefined') { + var cleanedUser = cleanedValue.replace(/\*|\'|\"|\||%|\[|\]|\(|\)|\=/g, ''); + if (cleanedUser !== cleanedValue) { + alert("The passed Host value contained disallowed characters (*\'\"%|[]()=). They have been stripped from the applied search."); + } + newHostValue = cleanedUser.trim(); + } + + // set user value to undefined if an empty string + if (typeof newHostValue === 'undefined' || newHostValue.length < 1) { + alert("The passed Host value is incomplete. Use the Search Tool to choose a Host."); + newHostValue = undefined; + } + } + } + + // set host token value if different than the current value + if (newHostValue !== currentHostValue) { + appUtils.setToken('dd_target_host_internal', newHostValue); + submit = true; + } + + return submit; + }; + + // Parse and clean selected user. Valid inputs values + // will be separated into a domain and user token. + // Returns boolean value indicating if the tokens have changed. + // name: name of the token used for the input text box + // value: value obtained from the text box + appUtils.parseDashboardUserTokens = function(name, value) { + + var newUserValue = undefined; + var currentUserValue = appUtils.getSubmittedToken('dd_target_user_internal'); + var newDomainValue = undefined; + var currentDomainValue = appUtils.getSubmittedToken('dd_target_domain_internal'); + var submit = false; + + if (typeof value !== 'undefined') { + + // trim whitespace + var cleanedValue = value.trim(); + + // reset initial value if nothing is left after cleaning, + // but don't call submit + if (cleanedValue.length < 1) { + appUtils.setToken(name, undefined); + } else { + + // inspect the data for validity + var regex = /([^\x5c]*)(?:\x5c+)?([^\x5c]*)?/g; + var match = regex.exec(cleanedValue); + var dom = match.length > 1 ? match[1] : undefined; + var user = match.length > 2 ? match[2] : undefined; + + // alert the user if there are disallowed characters + if (typeof user !== 'undefined') { + var cleanedUser = user.replace(/\*|\'|\"|\||%|\[|\]|\(|\)|\=/g, ''); + if (cleanedUser !== user) { + alert("The passed User value contained disallowed characters (*\'\"%|[]()=). They have been stripped from the applied search."); + } + newUserValue = cleanedUser.trim(); + } + + // alert the user if there are disallowed characters + if (typeof dom !== 'undefined') { + var cleanedDomain = dom.replace(/\*|\'|\"|\||%|\[|\]|\(|\)|\=/g, ''); + if (cleanedDomain !== dom) { + alert("The passed Domain value contained disallowed characters (*\'\"%|[]()=). They have been stripped from the applied search."); + } + newDomainValue = cleanedDomain.trim(); + } + + // set user value to undefined if an empty string + if (typeof newUserValue === 'undefined' || newUserValue.length < 1) { + alert("The passed User value is incomplete. Use the Search Tool to choose a User."); + newUserValue = undefined; + } + + // set domain value to undefined if an empty string + if (typeof newDomainValue === 'undefined' || newDomainValue.length < 1) { + alert("The passed Domain value is incomplete. Use the Search Tool to choose a Domain."); + newDomainValue = undefined; + } + } + } + + // set user token value if different than the current value + if (newUserValue !== currentUserValue) { + appUtils.setToken('dd_target_user_internal', newUserValue); + submit = true; + } + + // set domain token value if different than the current value + if (newDomainValue !== currentDomainValue) { + appUtils.setToken('dd_target_domain_internal', newDomainValue); + submit = true; + } + return submit; + }; + + return appUtils; + })(); + }); +}).call(this); diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/modaltextmsg/LICENSE b/deployment-apps/metricator-for-nmon/appserver/static/components/modaltextmsg/LICENSE new file mode 100644 index 0000000..d7fe390 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/modaltextmsg/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2017, Ryan Thibodeaux +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/modaltextmsg/modaltextmsg.css b/deployment-apps/metricator-for-nmon/appserver/static/components/modaltextmsg/modaltextmsg.css new file mode 100644 index 0000000..7d8019e --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/modaltextmsg/modaltextmsg.css @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2017, Ryan Thibodeaux. All Rights Reserved + * see included LICENSE file (BSD 3-clause) + */ + +/* top-level entity */ +.modal-text-msg { + position: fixed; + top: 40%; + left: 50%; + width: 450px; + margin-left: -225px; + z-index: 200000; +} + +.modal-text-msg-unactivated { + display: none !important; +} +.modal-text-msg-activated {} + +.modal-text-msg > .modal-body { + padding: 15px 20px 10px 20px; + max-height: 800px; +} + +/* background */ +.modal-text-msg-backdrop { + opacity: 0.5; + background-color: black; + z-index: 100000; + cursor: pointer; +} + +.modal-text-msg-backdrop-clear { + opacity: 0.0 !important; +} + +/* header items */ +.modal-text-msg > .modal-header { + padding: 7px 0px 7px 20px +} + +.modal-text-msg > .modal-header { + background: #90b5ea; + -webkit-border-top-left-radius: 5px; + -moz-border-radius-topleft: 5px; + border-top-left-radius: 5px; + -webkit-border-top-right-radius: 5px; + -moz-border-radius-topright: 5px; + border-top-right-radius: 5px; + border-radius: 5px 5px 0 0; +} +.modal-text-msg > .info { + background: #90b5ea; +} +.modal-text-msg > .debug { + background: #f5f5f5; +} +.modal-text-msg > .warn { + background: #dd9754; +} +.modal-text-msg > .error { + background: indianred; +} +.modal-text-msg > .modal-header > .modal-title { + line-height: 22px; + overflow-wrap: break-word; + padding-right: 30px; + font-size: 20px; + font-weight: bold; + margin: 0; +} + +/* Text content elements */ +.modal-text-msg p { + font-size:14px; + line-height: 20px; +} + +/* footer items */ +.modal-text-msg > .modal-footer { + padding: 5px 10px 5px 10px; + background-color: #f5f5f5; + border-radius: 0 0 5px 5px; + -webkit-border-bottom-left-radius: 5px; + -moz-border-radius-bottomleft: 5px; + border-bottom-left-radius: 5px; + -webkit-border-bottom-right-radius: 5px; + -moz-border-radius-bottomright: 5px; + border-bottom-right-radius: 5px; +} + +.modal-text-msg-close:before { + color: #000000; + font-size: 18px; + font-weight: bold; +} + +.modal-text-msg-close:hover:before { + color: #000000; +} diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/modaltextmsg/modaltextmsg.js b/deployment-apps/metricator-for-nmon/appserver/static/components/modaltextmsg/modaltextmsg.js new file mode 100644 index 0000000..7c8eb30 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/modaltextmsg/modaltextmsg.js @@ -0,0 +1,157 @@ +/** + * @fileoverview Class definition for Modal Text Message + * @author Ryan Thibodeaux + * @version 1.0.1 + */ + +/* + * Copyright (c) 2017, Ryan Thibodeaux. All Rights Reserved + * see included LICENSE file (BSD 3-clause) + */ + +define(function(require, exports, module) { + + "use strict"; + + var _ = require('underscore'); + var $ = require('jquery'); + var Backbone = require('backbone'); + + require("css!/static/app/metricator-for-nmon/components/modaltextmsg/modaltextmsg.css"); + + // escapes any HTML passed into string + function escapeHTML(str) { + var div = document.createElement('div'); + div.appendChild(document.createTextNode(str)); + return div.innerHTML; + } + +/** + * Creates a new ModalTextMsg object. + * @class + * @classdesc Modal Text Message class that displays messages as a modal box. + * @param {Object} options + * @param {String} options.type Type of text message to show + * @param {String} options.title Title for the text message + * @param {String} options.message Message content string + * @param {String} options.id HTML ID to use + */ + var ModalTextMsg = Backbone.View.extend({ + + className: 'ModalTextMsg', + content: undefined, + + defaults: { + title: "", // title to show on top of the modal window + type: "info", // the type of modal message [info, debug, warn, error] + message: "", // the message to display in the modal window + id: "ModalTextMsgID", // the html ID to use for the modal text message + }, + + // initialize ModalTextMsg object + initialize: function(options) { + this.options = options; + this.options.title = (typeof this.options.title === 'undefined' ? this.defaults.title : escapeHTML(this.options.title).trim()); + this.options.type = (typeof this.options.type === 'undefined' ? this.defaults.type : escapeHTML(this.options.type).trim().toLowerCase()); + this.options.message = (typeof this.options.message === 'undefined' ? this.defaults.message : escapeHTML(this.options.message).trim()); + this.options.id = (typeof this.options.id === 'undefined' ? this.defaults.id : escapeHTML(this.options.id).trim()); + this.template = _.template(this.template); + + // enforce the type to be of a specific value + switch(this.options.type) { + case "error": + this.options.title = (this.options.title === "" ? "Error" : this.options.title); + break; + case "warn": + this.options.title = (this.options.title === "" ? "Warning" : this.options.title); + break; + case "debug": + this.options.title = (this.options.title === "" ? "Debug" : this.options.title); + break; + case "info": + default: + this.options.type = "info"; + this.options.title = (this.options.title === "" ? "Info" : this.options.title); + break; + } + + // setup content div by breaking up message into + // paragraphs for every
tag found + var c = document.createElement('div'); + c.id = "modal-text-msg-content"; + var msgParts = this.options.message.split("<br/>"); + msgParts.forEach( function(str) { + var para = document.createElement("p"); + var t = document.createTextNode(str.trim()); + para.appendChild(t); + c.appendChild(para); + }); + this.content = c; + + // render the content and add it to the HTML body but don't show it + (this.render()).$el.addClass('modal-text-msg-unactivated'); + $(document.body).append(this.el); + }, + + // click listeners + events: { + 'click .modal-text-msg-close' : 'close', + 'click .modal-text-msg-backdrop' : 'close' + }, + + // render the content based on the template + render: function() { + this.$el.html(this.template({ + id : this.options.id, + title : this.options.title, + type : this.options.type + })); + this.$el.find(".modal-body").append(this.content); + return this; + }, + + // show the modal text message window + show: function() { + if (this.$el.hasClass('modal-text-msg-unactivated')) { + this.$el.removeClass('modal-text-msg-unactivated').addClass('modal-text-msg-activated'); + } + this.updateVisibility(); + return this; + }, + + // close the modal window and destroy the content + close: function() { + this.unbind(); + this.remove(); + this.updateVisibility(); + return this; + }, + + // update visibility of modal windows that + // have been activated + updateVisibility: function() { + // make the last window visible and all others invisible + var modals = $(".modal-text-msg-activated"); + if (modals.length > 0) { + modals.each(function(i,m) { + if (i == modals.length - 1) { + $(m).show() + } else { + $(m).hide(); + } + }); + } + }, + + // html template + template: '' + + '' + }); + return ModalTextMsg; +}); diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/modaltextmsg/wrapper.js b/deployment-apps/metricator-for-nmon/appserver/static/components/modaltextmsg/wrapper.js new file mode 100644 index 0000000..b7db9c7 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/modaltextmsg/wrapper.js @@ -0,0 +1,138 @@ +/** + * @fileoverview Controlling logic for the Modal Text Message feature + * @author Ryan Thibodeaux + * @version 1.0.1 + */ + +/* + * Copyright (c) 2017, Ryan Thibodeaux. All Rights Reserved + * see included LICENSE file (BSD 3-clause) + */ + +(function() { + require([ + "jquery", + "ModalTextMsg", + "splunkjs/mvc", + "splunkjs/ready!", + "splunkjs/mvc/simplexml/ready!" + ], function($, ModalTextMsg, mvc) { + + "use strict"; + + // get token models and setup modifier functions + var defaultTokenModel = mvc.Components.get('default'); + var submittedTokenModel = mvc.Components.get('submitted'); + var urlTokenModel = mvc.Components.get('url'); + + function setToken(name, value, submit) { + defaultTokenModel.set(name, value); + if (!!submit) { + submitTokens(); + } + } + function submitTokens() { + if (submittedTokenModel && defaultTokenModel) { + submittedTokenModel.set(defaultTokenModel.toJSON()); + } + } + + + // parse passed modal text message title + function parseMessageTitle(token, title) { + var value = title; + if (typeof value !== 'undefined') { + if (Object.prototype.toString.call(title) === '[object Array]') { + value = title[0]; + } + value = value.trim() + if (value.length > 0) { + next_title = value; + } + } + } + + // parse passed modal text message content and trigger the display + function parseMessageToken(token, msg) { + var value = msg; + if (typeof value !== 'undefined') { + if (Object.prototype.toString.call(msg) === '[object Array]') { + value = msg[0]; + } + value = value.trim(); + if (value.length > 0) { + next_msg = value; + next_msg_type = token.split("_").pop(); + triggerMsgDisplay(); + } + } + } + + // show the modal text message + function triggerMsgDisplay() { + var k = new ModalTextMsg({ + title : next_title, + type : next_msg_type, + message : next_msg + }); + k.show(); + + next_title = undefined; + next_msg = undefined; + next_msg_type = undefined; + } + + ///////////////////////////////////////// + /// Start Main Code Here + ///////////////////////////////////////// + + // array of message tokens in increasing order of priority + const MESSAGE_TOKENS = ["modal_msg_title", "modal_msg_debug", "modal_msg_info", "modal_msg_warn", "modal_msg_error"]; + const MESSAGE_URL_TOKENS = ["modal_msg_url_title", "modal_msg_url_debug", "modal_msg_url_info", "modal_msg_url_warn", "modal_msg_url_error"]; + var next_title = undefined; + var next_msg = undefined; + var next_msg_type = undefined; + + // parse and display messages passed via URL tokens + var urlTokensSet = urlTokenModel.keys(); + for (var i = 0; i < MESSAGE_URL_TOKENS.length; i++) { + if (urlTokensSet.indexOf(MESSAGE_URL_TOKENS[i]) >= 0) { + if (MESSAGE_URL_TOKENS[i] === "modal_msg_url_title") { + parseMessageTitle(MESSAGE_URL_TOKENS[i], urlTokenModel.get(MESSAGE_URL_TOKENS[i])); + } else { + parseMessageToken(MESSAGE_URL_TOKENS[i], urlTokenModel.get(MESSAGE_URL_TOKENS[i])); + } + } + } + + // listen for changes to the message type tokens + MESSAGE_TOKENS.forEach(function(str) { + submittedTokenModel.on("change:" + str, function(model, value, options) { + if (str === "modal_msg_title") { + parseMessageTitle(str, value); + } else { + parseMessageToken(str, value); + } + if (typeof value !== 'undefined') { + setToken(str, undefined, true); + } + }); + + // see if the value was already set at page load via quick changes that + // may not be registered in the code block above since it isn't loaded + // quickly enough in 6.5+ + var currentValue = submittedTokenModel.get(str); + var urlValue = urlTokenModel.get(str); + if (typeof currentValue !== "undefined" && currentValue.length > 0) { + if (typeof urlValue === "undefined" || urlValue.length < 1) { + setToken(str, currentValue + " ", true); + } + } + }); + },function(err) { + // error callback + // the error has a list of modules that failed + var failedId = err.requireModules && err.requireModules[0]; + console.error("Error when loading dependencies in Modal Text Message wrapper: ", err); + }); +}).call(this); diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/bower.json b/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/bower.json new file mode 100644 index 0000000..c54fce1 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/bower.json @@ -0,0 +1,10 @@ +{ + "name": "parallelcoords", + "version": "1.0.0", + "main": "parallelcoords.js", + "ignore": [], + "dependencies": { + "d3": "3.3.x" + }, + "devDependencies": {} +} \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/contrib/LICENSE b/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/contrib/LICENSE new file mode 100644 index 0000000..6c6d355 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/contrib/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2012, Kai Chang +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* The name Kai Chang may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/contrib/d3-parcoords.css b/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/contrib/d3-parcoords.css new file mode 100644 index 0000000..89d4311 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/contrib/d3-parcoords.css @@ -0,0 +1,34 @@ +.parcoords > svg, .parcoords > canvas { + font: 14px sans-serif; + position: absolute; +} +.parcoords > canvas { + pointer-events: none; +} +.parcoords rect.background { + fill: transparent; +} +.parcoords rect.background:hover { + fill: rgba(120,120,120,0.2); +} +.parcoords .resize rect { + fill: rgba(0,0,0,0.1); +} +.parcoords rect.extent { + fill: rgba(255,255,255,0.25); + stroke: rgba(0,0,0,0.6); +} +.parcoords .axis line, .parcoords .axis path { + fill: none; + stroke: #222; + shape-rendering: crispEdges; +} +.parcoords canvas { + opacity: 1; + -moz-transition: opacity 0.3s; + -webkit-transition: opacity 0.3s; + -o-transition: opacity 0.3s; +} +.parcoords canvas.faded { + opacity: 0.25; +} diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/contrib/d3-parcoords.js b/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/contrib/d3-parcoords.js new file mode 100644 index 0000000..9fcb56b --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/contrib/d3-parcoords.js @@ -0,0 +1,598 @@ +define(function(require, exports, module) { + +var d3 = require("../../d3/d3"); +require("css!./d3-parcoords.css"); + +/// BEGIN LIBRARY CODE +// +d3.parcoords = function(config) { + var __ = { + data: [], + dimensions: [], + dimensionTitles: {}, + types: {}, + brushed: false, + mode: "default", + rate: 20, + width: 600, + height: 300, + margin: { top: 24, right: 0, bottom: 12, left: 0 }, + color: "#069", + composite: "source-over", + alpha: 0.7 + }; + + extend(__, config); +var pc = function(selection) { + selection = pc.selection = d3.select(selection); + + __.width = selection[0][0].clientWidth; + __.height = selection[0][0].clientHeight; + + // canvas data layers + ["shadows", "marks", "foreground", "highlight"].forEach(function(layer) { + canvas[layer] = selection + .append("canvas") + .attr("class", layer)[0][0]; + ctx[layer] = canvas[layer].getContext("2d"); + }); + + // svg tick and brush layers + pc.svg = selection + .append("svg") + .attr("width", __.width) + .attr("height", __.height) + .append("svg:g") + .attr("transform", "translate(" + __.margin.left + "," + __.margin.top + ")"); + + return pc; +}; +var events = d3.dispatch.apply(this,["render", "resize", "highlight", "brush"].concat(d3.keys(__))), + w = function() { return __.width - __.margin.right - __.margin.left; }, + h = function() { return __.height - __.margin.top - __.margin.bottom }, + flags = { + brushable: false, + reorderable: false, + axes: false, + interactive: false, + shadows: false, + debug: false + }, + xscale = d3.scale.ordinal(), + yscale = {}, + dragging = {}, + line = d3.svg.line(), + axis = d3.svg.axis().orient("left").ticks(5), + g, // groups for axes, brushes + ctx = {}, + canvas = {}; + +// side effects for setters +var side_effects = d3.dispatch.apply(this,d3.keys(__)) + .on("composite", function(d) { ctx.foreground.globalCompositeOperation = d.value; }) + .on("alpha", function(d) { ctx.foreground.globalAlpha = d.value; }) + .on("width", function(d) { pc.resize(); }) + .on("height", function(d) { pc.resize(); }) + .on("margin", function(d) { pc.resize(); }) + .on("rate", function(d) { rqueue.rate(d.value); }) + .on("data", function(d) { + if (flags.shadows) paths(__.data, ctx.shadows); + }) + .on("dimensions", function(d) { + xscale.domain(__.dimensions); + if (flags.interactive) pc.render().updateAxes(); + }); + +// expose the state of the chart +pc.state = __; +pc.flags = flags; + +// create getter/setters +getset(pc, __, events); + +// expose events +d3.rebind(pc, events, "on"); + +// tick formatting +d3.rebind(pc, axis, "ticks", "orient", "tickValues", "tickSubdivide", "tickSize", "tickPadding", "tickFormat"); + +// getter/setter with event firing +function getset(obj,state,events) { + d3.keys(state).forEach(function(key) { + obj[key] = function(x) { + if (!arguments.length) return state[key]; + var old = state[key]; + state[key] = x; + side_effects[key].call(pc,{"value": x, "previous": old}); + events[key].call(pc,{"value": x, "previous": old}); + return obj; + }; + }); +}; + +function extend(target, source) { + for (key in source) { + target[key] = source[key]; + } + return target; +}; +pc.autoscale = function() { + // yscale + var defaultScales = { + "date": function(k) { + return d3.time.scale() + .domain(d3.extent(__.data, function(d) { + return d[k] ? d[k].getTime() : null; + })) + .range([h()+1, 1]) + }, + "number": function(k) { + return d3.scale.linear() + .domain(d3.extent(__.data, function(d) { return +d[k]; })) + .range([h()+1, 1]) + }, + "string": function(k) { + return d3.scale.ordinal() + .domain(__.data.map(function(p) { return p[k]; })) + .rangePoints([h()+1, 1]) + } + }; + + __.dimensions.forEach(function(k) { + yscale[k] = defaultScales[__.types[k]](k); + }); + + // hack to remove ordinal dimensions with many values + pc.dimensions(pc.dimensions().filter(function(p,i) { + var uniques = yscale[p].domain().length; + if (__.types[p] == "string" && (uniques > 60 || uniques < 2)) { + return false; + } + return true; + })); + + // xscale + xscale.rangePoints([0, w()], 1); + + // canvas sizes + pc.selection.selectAll("canvas") + .style("margin-top", __.margin.top + "px") + .style("margin-left", __.margin.left + "px") + .attr("width", w()+2) + .attr("height", h()+2) + + // default styles, needs to be set when canvas width changes + ctx.foreground.strokeStyle = __.color; + ctx.foreground.lineWidth = 1.4; + ctx.foreground.globalCompositeOperation = __.composite; + ctx.foreground.globalAlpha = __.alpha; + ctx.highlight.lineWidth = 3; + ctx.shadows.strokeStyle = "#dadada"; + + return this; +}; +pc.detectDimensions = function() { + pc.types(pc.detectDimensionTypes(__.data)); + pc.dimensions(d3.keys(pc.types())); + return this; +}; + +// a better "typeof" from this post: http://stackoverflow.com/questions/7390426/better-way-to-get-type-of-a-javascript-variable +pc.toType = function(v) { + return ({}).toString.call(v).match(/\s([a-zA-Z]+)/)[1].toLowerCase() +}; + +// try to coerce to number before returning type +pc.toTypeCoerceNumbers = function(v) { + if ((parseFloat(v) == v) && (v != null)) return "number"; + return pc.toType(v); +}; + +// attempt to determine types of each dimension based on first row of data +pc.detectDimensionTypes = function(data) { + var types = {} + d3.keys(data[0]) + .forEach(function(col) { + types[col] = pc.toTypeCoerceNumbers(data[0][col]); + }); + return types; +}; +pc.render = function() { + // try to autodetect dimensions and create scales + if (!__.dimensions.length) pc.detectDimensions(); + if (!(__.dimensions[0] in yscale)) pc.autoscale(); + + pc.render[__.mode](); + + events.render.call(this); + return this; +}; + +pc.render.default = function() { + pc.clear('foreground'); + if (__.brushed) { + __.brushed.forEach(path_foreground); + } else { + __.data.forEach(path_foreground); + } +}; + +var rqueue = d3.renderQueue(path_foreground) + .rate(50) + .clear(function() { pc.clear('foreground'); }); + +pc.render.queue = function() { + if (__.brushed) { + rqueue(__.brushed); + } else { + rqueue(__.data); + } +}; +pc.shadows = function() { + flags.shadows = true; + if (__.data.length > 0) paths(__.data, ctx.shadows); + return this; +}; + +// draw little dots on the axis line where data intersects +pc.axisDots = function() { + var ctx = pc.ctx.marks; + ctx.globalAlpha = d3.min([1/Math.pow(data.length, 1/2), 1]); + __.data.forEach(function(d) { + __.dimensions.map(function(p,i) { + ctx.fillRect(position(p)-0.75,yscale[p](d[p])-0.75,1.5,1.5); + }); + }); + return this; +}; + +// draw single polyline +function color_path(d, ctx) { + ctx.strokeStyle = d3.functor(__.color)(d); + ctx.beginPath(); + __.dimensions.map(function(p,i) { + if (i == 0) { + ctx.moveTo(position(p),yscale[p](d[p])); + } else { + ctx.lineTo(position(p),yscale[p](d[p])); + } + }); + ctx.stroke(); +}; + +// draw many polylines of the same color +function paths(data, ctx) { + ctx.clearRect(-1,-1,w()+2,h()+2); + ctx.beginPath(); + data.forEach(function(d) { + __.dimensions.map(function(p,i) { + if (i == 0) { + ctx.moveTo(position(p),yscale[p](d[p])); + } else { + ctx.lineTo(position(p),yscale[p](d[p])); + } + }); + }); + ctx.stroke(); +}; + +function path_foreground(d) { + return color_path(d, ctx.foreground); +}; + +function path_highlight(d) { + return color_path(d, ctx.highlight); +}; +pc.clear = function(layer) { + ctx[layer].clearRect(0,0,w()+2,h()+2); + return this; +}; +pc.createAxes = function() { + if (g) pc.removeAxes(); + + // Add a group element for each dimension. + g = pc.svg.selectAll(".dimension") + .data(__.dimensions, function(d) { return d; }) + .enter().append("svg:g") + .attr("class", "dimension") + .attr("transform", function(d) { return "translate(" + xscale(d) + ")"; }) + + // Add an axis and title. + g.append("svg:g") + .attr("class", "axis") + .attr("transform", "translate(0,0)") + .each(function(d) { d3.select(this).call(axis.scale(yscale[d])); }) + .append("svg:text") + .attr({ + "text-anchor": "middle", + "y": 0, + "transform": "translate(0,-12)", + "x": 0, + "class": "label" + }) + .text(function(d) { + return d in __.dimensionTitles ? __.dimensionTitles[d] : d; // dimension display names + }) + + flags.axes= true; + return this; +}; + +pc.removeAxes = function() { + g.remove(); + return this; +}; + +pc.updateAxes = function() { + var g_data = pc.svg.selectAll(".dimension") + .data(__.dimensions, function(d) { return d; }) + + g_data.enter().append("svg:g") + .attr("class", "dimension") + .attr("transform", function(p) { return "translate(" + position(p) + ")"; }) + .style("opacity", 0) + .append("svg:g") + .attr("class", "axis") + .attr("transform", "translate(0,0)") + .each(function(d) { d3.select(this).call(axis.scale(yscale[d])); }) + .append("svg:text") + .attr({ + "text-anchor": "middle", + "y": 0, + "transform": "translate(0,-12)", + "x": 0, + "class": "label" + }) + .text(String); + + g_data.exit().remove(); + + g = pc.svg.selectAll(".dimension"); + + g.transition().duration(1100) + .attr("transform", function(p) { return "translate(" + position(p) + ")"; }) + .style("opacity", 1) + if (flags.shadows) paths(__.data, ctx.shadows); + return this; +}; + +pc.brushable = function() { + if (!g) pc.createAxes(); + + // Add and store a brush for each axis. + g.append("svg:g") + .attr("class", "brush") + .each(function(d) { + d3.select(this).call( + yscale[d].brush = d3.svg.brush() + .y(yscale[d]) + .on("brushstart", function() { + d3.event.sourceEvent.stopPropagation(); + }) + .on("brush", pc.brush) + ); + }) + .selectAll("rect") + .style("visibility", null) + .attr("x", -15) + .attr("width", 30) + flags.brushable = true; + return this; +}; + +// Jason Davies, http://bl.ocks.org/1341281 +pc.reorderable = function() { + if (!g) pc.createAxes(); + + g.style("cursor", "move") + .call(d3.behavior.drag() + .on("dragstart", function(d) { + dragging[d] = this.__origin__ = xscale(d); + }) + .on("drag", function(d) { + dragging[d] = Math.min(w(), Math.max(0, this.__origin__ += d3.event.dx)); + __.dimensions.sort(function(a, b) { return position(a) - position(b); }); + xscale.domain(__.dimensions); + pc.render(); + g.attr("transform", function(d) { return "translate(" + position(d) + ")"; }) + }) + .on("dragend", function(d) { + delete this.__origin__; + delete dragging[d]; + d3.select(this).transition().attr("transform", "translate(" + xscale(d) + ")"); + pc.render(); + })); + flags.reorderable = true; + return this; +}; + +// pairs of adjacent dimensions +pc.adjacent_pairs = function(arr) { + var ret = []; + for (var i = 0; i < arr.length-1; i++) { + ret.push([arr[i],arr[i+1]]); + }; + return ret; +}; +pc.interactive = function() { + flags.interactive = true; + return this; +}; + +// Get data within brushes +pc.brush = function() { + __.brushed = selected(); + events.brush.call(pc,__.brushed); + pc.render(); +}; + +// expose a few objects +pc.xscale = xscale; +pc.yscale = yscale; +pc.ctx = ctx; +pc.canvas = canvas; +pc.g = function() { return g; }; + +pc.brushReset = function(dimension) { + if (g) { + g.selectAll('.brush') + .each(function(d) { + d3.select(this).call( + yscale[d].brush.clear() + ); + }) + pc.brush(); + } + return this; +}; + +// rescale for height, width and margins +// TODO currently assumes chart is brushable, and destroys old brushes +pc.resize = function() { + // selection size + pc.selection.select("svg") + .attr("width", __.width) + .attr("height", __.height) + pc.svg.attr("transform", "translate(" + __.margin.left + "," + __.margin.top + ")"); + + // scales + pc.autoscale(); + + // axes, destroys old brushes. the current brush state should pass through in the future + if (g) pc.createAxes().brushable(); + + events.resize.call(this, {width: __.width, height: __.height, margin: __.margin}); + return this; +}; + +// highlight an array of data +pc.highlight = function(data) { + pc.clear("highlight"); + d3.select(canvas.foreground).classed("faded", true); + data.forEach(path_highlight); + events.highlight.call(this,data); + return this; +}; + +// clear highlighting +pc.unhighlight = function(data) { + pc.clear("highlight"); + d3.select(canvas.foreground).classed("faded", false); + return this; +}; + +// calculate 2d intersection of line a->b with line c->d +// points are objects with x and y properties +pc.intersection = function(a, b, c, d) { + return { + x: ((a.x * b.y - a.y * b.x) * (c.x - d.x) - (a.x - b.x) * (c.x * d.y - c.y * d.x)) / ((a.x - b.x) * (c.y - d.y) - (a.y - b.y) * (c.x - d.x)), + y: ((a.x * b.y - a.y * b.x) * (c.y - d.y) - (a.y - b.y) * (c.x * d.y - c.y * d.x)) / ((a.x - b.x) * (c.y - d.y) - (a.y - b.y) * (c.x - d.x)) + }; +}; + +function is_brushed(p) { + return !yscale[p].brush.empty(); +}; + +// data within extents +function selected() { + var actives = __.dimensions.filter(is_brushed), + extents = actives.map(function(p) { return yscale[p].brush.extent(); }); + + // test if within range + var within = { + "date": function(d,p,dimension) { + return extents[dimension][0] <= d[p] && d[p] <= extents[dimension][1] + }, + "number": function(d,p,dimension) { + return extents[dimension][0] <= d[p] && d[p] <= extents[dimension][1] + }, + "string": function(d,p,dimension) { + return extents[dimension][0] <= yscale[p](d[p]) && yscale[p](d[p]) <= extents[dimension][1] + } + }; + + return __.data + .filter(function(d) { + return actives.every(function(p, dimension) { + return within[__.types[p]](d,p,dimension); + }); + }); +}; + +function position(d) { + var v = dragging[d]; + return v == null ? xscale(d) : v; +} + pc.toString = function() { return "Parallel Coordinates: " + __.dimensions.length + " dimensions (" + d3.keys(__.data[0]).length + " total) , " + __.data.length + " rows"; }; + + pc.version = "0.2.2"; + + return pc; +}; + +d3.renderQueue = (function(func) { + var _queue = [], // data to be rendered + _rate = 10, // number of calls per frame + _clear = function() {}, // clearing function + _i = 0; // current iteration + + var rq = function(data) { + if (data) rq.data(data); + rq.invalidate(); + _clear(); + rq.render(); + }; + + rq.render = function() { + _i = 0; + var valid = true; + rq.invalidate = function() { valid = false; }; + + function doFrame() { + if (!valid) return true; + if (_i > _queue.length) return true; + var chunk = _queue.slice(_i,_i+_rate); + _i += _rate; + chunk.map(func); + } + + d3.timer(doFrame); + }; + + rq.data = function(data) { + rq.invalidate(); + _queue = data.slice(0); + return rq; + }; + + rq.rate = function(value) { + if (!arguments.length) return _rate; + _rate = value; + return rq; + }; + + rq.remaining = function() { + return _queue.length - _i; + }; + + // clear the canvas + rq.clear = function(func) { + if (!arguments.length) { + _clear(); + return rq; + } + _clear = func; + return rq; + }; + + rq.invalidate = function() {}; + + return rq; +}); + +/// END LIBRARY CODE + +return d3.parcoords; + +}); \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/parallelcoords.js b/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/parallelcoords.js new file mode 100644 index 0000000..bd8f4b8 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/parallelcoords/parallelcoords.js @@ -0,0 +1,117 @@ +// parallel coords! +// a visualisation technique for multidimensional categorical data +// you can drag the vertical axis for each section to filter things (try it out for yourself) + +// --- settings --- +// none for the time being. +// TODO: add settings to choose which data goes where + +// --- expected data format --- +// a splunk search like this: index=_internal sourcetype=splunkd_access | table method status + +define(function(require, exports, module) { + + var _ = require('underscore'); + var d3 = require("../d3/d3"); + var parcoords = require("./contrib/d3-parcoords"); + var SimpleSplunkView = require("splunkjs/mvc/simplesplunkview"); + + var ParCoords = SimpleSplunkView.extend({ + + className: "splunk-toolkit-parcoords", + + options: { + managerid: null, // your MANAGER ID + data: "preview", // Results type + }, + + output_mode: "json_rows", + + initialize: function() { + SimpleSplunkView.prototype.initialize.apply(this, arguments); + + this.settings.enablePush("value"); + + // Set up resize callback. The first argument is a this + // pointer which gets passed into the callback event + $(window).resize(this, _.debounce(this._handleResize, 20)); + }, + + _handleResize: function(e){ + + // e.data is the this pointer passed to the callback. + // here it refers to this object and we call render() + e.data.render(); + }, + + createView: function() { + this.$el.html(''); // clearing all prior junk from the view (eg. 'waiting for data...') + return true; + }, + + // making the data look how we want it to for updateView to do its job + formatData: function(data) { + + // Decide what fields we want + // TODO: this should be specifialbe + var fields = _.filter(this.resultsModel.data().fields, function(d){return d[0] !== "_" }); + var objects = _.map(data, function(row) { + var obj = {}; + _.each(fields, function(field, idx) { + if (row[idx] !== null) { + obj[field] = row[idx]; + } + else { + obj[field] = ""; + } + }); + + return obj; + }); + + data = { + 'results': objects, + 'fields': fields + } + + return data; + }, + + updateView: function(viz, data) { + var that = this; + var availableHeight = parseInt(this.settings.get("height") || this.$el.height()); + + this.$el.html(''); + var fields = data.fields; + viz = $("
").appendTo(this.el) + .css("height", availableHeight) + var colorgen = d3.scale.category20(); + var colors = {}; + _(data.results).chain() + .pluck(fields[0]) + .uniq() + .each(function(d,i) { + colors[d] = colorgen(i); + }); + + var color = function(d) {return colors[d[fields[0]]]; }; + + var pc_progressive = d3.parcoords()('#' + this.id + '_parallelcoords') + .data(data.results) + .color(color) + .alpha(0.4) + .margin({ top: 24, left: 150, bottom: 12, right: 0 }) + .mode("queue") + .render() + .brushable() // enable brushing + .interactive() // command line mode + .on("brush", function(selected) { + that.trigger("select", {selected: selected}); + }); + + pc_progressive.svg.selectAll("text") + .style("font", "10px sans-serif"); + } + }); + return ParCoords; +}); diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/bower.json b/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/bower.json new file mode 100644 index 0000000..61bd319 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/bower.json @@ -0,0 +1,10 @@ +{ + "name": "sankey", + "version": "1.0.0", + "main": "sankey.js", + "ignore": [], + "dependencies": { + "d3": "3.3.x" + }, + "devDependencies": {} +} \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/contrib/LICENSE b/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/contrib/LICENSE new file mode 100644 index 0000000..9869c20 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/contrib/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2013, Michael Bostock +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* The name Michael Bostock may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/contrib/d3-sankey.js b/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/contrib/d3-sankey.js new file mode 100644 index 0000000..ed208fd --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/contrib/d3-sankey.js @@ -0,0 +1,585 @@ +define(function(require, exports, module) { + +var d3 = require('../../d3/d3'); + +/// BEGIN LIBRARY CODE + +// A modified d3 sankey plugin +// This is taken verbatim from: +// https://github.com/kunalb/d3-plugins/blob/sankey/sankey/sankey.js +// Referenced from pull request: +// https://github.com/d3/d3-plugins/pull/39 + +d3.sankey = function() { + var sankey = {}, + nodeWidth = 24, + nodePadding = 8, + size = [1, 1], + nodes = [], + links = [], + components = []; + + sankey.nodeWidth = function(_) { + if (!arguments.length) return nodeWidth; + nodeWidth = +_; + return sankey; + }; + + sankey.nodePadding = function(_) { + if (!arguments.length) return nodePadding; + nodePadding = +_; + return sankey; + }; + + sankey.nodes = function(_) { + if (!arguments.length) return nodes; + nodes = _; + return sankey; + }; + + sankey.links = function(_) { + if (!arguments.length) return links; + links = _; + return sankey; + }; + + sankey.size = function(_) { + if (!arguments.length) return size; + size = _; + return sankey; + }; + + sankey.layout = function(iterations) { + computeNodeLinks(); + computeNodeValues(); + + computeNodeStructure(); + computeNodeBreadths(); + + computeNodeDepths(iterations); + computeLinkDepths(); + + return sankey; + }; + + sankey.relayout = function() { + computeLinkDepths(); + return sankey; + }; + + // A more involved path generator that requires 3 elements to render -- + // It draws a starting element, intermediate and end element that are useful + // while drawing reverse links to get an appropriate fill. + // + // Each link is now an area and not a basic spline and no longer guarantees + // fixed width throughout. + // + // Sample usage: + // + // linkNodes = this._svg.append("g").selectAll(".link") + // .data(this.links) + // .enter().append("g") + // .attr("fill", "none") + // .attr("class", ".link") + // .sort(function(a, b) { return b.dy - a.dy; }); + // + // linkNodePieces = []; + // for (var i = 0; i < 3; i++) { + // linkNodePieces[i] = linkNodes.append("path") + // .attr("class", ".linkPiece") + // .attr("d", path(i)) + // .attr("fill", ...) + // } + sankey.reversibleLink = function() { + var curvature = .5; + + // Used when source is behind target, the first and last paths are simple + // lines at the start and end node while the second path is the spline + function forwardLink(part, d) { + var x0 = d.source.x + d.source.dx, + x1 = d.target.x, + xi = d3.interpolateNumber(x0, x1), + x2 = xi(curvature), + x3 = xi(1 - curvature), + y0 = d.source.y + d.sy, + y1 = d.target.y + d.ty, + y2 = d.source.y + d.sy + d.dy, + y3 = d.target.y + d.ty + d.dy; + + switch (part) { + case 0: + return "M" + x0 + "," + y0 + "L" + x0 + "," + (y0 + d.dy); + + case 1: + return "M" + x0 + "," + y0 + + "C" + x2 + "," + y0 + " " + x3 + "," + y1 + " " + x1 + "," + y1 + + "L" + x1 + "," + y3 + + "C" + x3 + "," + y3 + " " + x2 + "," + y2 + " " + x0 + "," + y2 + + "Z"; + + case 2: + return "M" + x1 + "," + y1 + "L" + x1 + "," + (y1 + d.dy); + } + } + + // Used for self loops and when the source is actually in front of the + // target; the first element is a turning path from the source to the + // destination, the second element connects the two twists and the last + // twists into the target element. + // + // + // /--Target + // \----------------------\ + // Source--/ + // + function backwardLink(part, d) { + var curveExtension = 30; + var curveDepth = 15; + + function getDir(d) { + return d.source.y + d.sy > d.target.y + d.ty ? -1 : 1; + } + + function p(x, y) { + return x + "," + y + " "; + } + + var dt = getDir(d) * curveDepth, + x0 = d.source.x + d.source.dx, + y0 = d.source.y + d.sy, + x1 = d.target.x, + y1 = d.target.y + d.ty; + + switch (part) { + case 0: + return "M" + p(x0, y0) + + "C" + p(x0, y0) + + p(x0 + curveExtension, y0) + + p(x0 + curveExtension, y0 + dt) + + "L" + p(x0 + curveExtension, y0 + dt + d.dy) + + "C" + p(x0 + curveExtension, y0 + d.dy) + + p(x0, y0 + d.dy) + + p(x0, y0 + d.dy) + + "Z"; + case 1: + return "M" + p(x0 + curveExtension, y0 + dt) + + "C" + p(x0 + curveExtension, y0 + 3 * dt) + + p(x1 - curveExtension, y1 - 3 * dt) + + p(x1 - curveExtension, y1 - dt) + + "L" + p(x1 - curveExtension, y1 - dt + d.dy) + + "C" + p(x1 - curveExtension, y1 - 3 * dt + d.dy) + + p(x0 + curveExtension, y0 + 3 * dt + d.dy) + + p(x0 + curveExtension, y0 + dt + d.dy) + + "Z"; + + case 2: + return "M" + p(x1 - curveExtension, y1 - dt) + + "C" + p(x1 - curveExtension, y1) + + p(x1, y1) + + p(x1, y1) + + "L" + p(x1, y1 + d.dy) + + "C" + p(x1, y1 + d.dy) + + p(x1 - curveExtension, y1 + d.dy) + + p(x1 - curveExtension, y1 + d.dy - dt) + + "Z"; + } + } + + return function(part) { + return function(d) { + if (d.source.x < d.target.x) { + return forwardLink(part, d); + } else { + return backwardLink(part, d); + } + } + } + }; + + // The standard link path using a constant width spline that needs a + // single path element. + sankey.link = function() { + var curvature = .5; + + function link(d) { + var x0 = d.source.x + d.source.dx, + x1 = d.target.x, + xi = d3.interpolateNumber(x0, x1), + x2 = xi(curvature), + x3 = xi(1 - curvature), + y0 = d.source.y + d.sy + d.dy / 2, + y1 = d.target.y + d.ty + d.dy / 2; + return "M" + x0 + "," + y0 + + "C" + x2 + "," + y0 + + " " + x3 + "," + y1 + + " " + x1 + "," + y1; + } + + link.curvature = function(_) { + if (!arguments.length) return curvature; + curvature = +_; + return link; + }; + + return link; + }; + + // Populate the sourceLinks and targetLinks for each node. + // Also, if the source and target are not objects, assume they are indices. + function computeNodeLinks() { + nodes.forEach(function(node) { + node.sourceLinks = []; + node.targetLinks = []; + }); + + links.forEach(function(link) { + var source = link.source, + target = link.target; + if (typeof source === "number") source = link.source = nodes[link.source]; + if (typeof target === "number") target = link.target = nodes[link.target]; + source.sourceLinks.push(link); + target.targetLinks.push(link); + }); + } + + // Compute the value (size) of each node by summing the associated links. + function computeNodeValues() { + nodes.forEach(function(node) { + node.value = Math.max( + d3.sum(node.sourceLinks, value), + d3.sum(node.targetLinks, value) + ); + }); + } + + // Take the list of nodes and create a DAG of supervertices, each consisting + // of a strongly connected component of the graph + // + // Based off: + // http://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm + function computeNodeStructure() { + var nodeStack = [], + index = 0; + + nodes.forEach(function(node) { + if (!node.index) { + connect(node); + } + }); + + function connect(node) { + node.index = index++; + node.lowIndex = node.index; + node.onStack = true; + nodeStack.push(node); + + if (node.sourceLinks) { + node.sourceLinks.forEach(function(sourceLink){ + var target = sourceLink.target; + if (!target.hasOwnProperty('index')) { + connect(target); + node.lowIndex = Math.min(node.lowIndex, target.lowIndex); + } else if (target.onStack) { + node.lowIndex = Math.min(node.lowIndex, target.index); + } + }); + + if (node.lowIndex === node.index) { + var component = [], currentNode; + do { + currentNode = nodeStack.pop() + currentNode.onStack = false; + component.push(currentNode); + } while (currentNode != node); + components.push({ + root: node, + scc: component + }); + } + } + } + + components.forEach(function(component, i){ + component.index = i; + component.scc.forEach(function(node) { + node.component = i; + }); + }); + } + + // Assign the breadth (x-position) for each strongly connected component, + // followed by assigning breadth within the component. + function computeNodeBreadths() { + + layerComponents(); + + components.forEach(function(component, i){ + bfs(component.root, function(node){ + var result = node.sourceLinks + .filter(function(sourceLink){ + return sourceLink.target.component == i; + }) + .map(function(sourceLink){ + return sourceLink.target; + }); + return result; + }); + }); + + var max = 0; + var componentsByBreadth = d3.nest() + .key(function(d) { return d.x; }) + .sortKeys(d3.ascending) + .entries(components) + .map(function(d) { return d.values; }); + + var max = -1, nextMax = -1; + componentsByBreadth.forEach(function(c){ + c.forEach(function(component){ + component.x = max + 1; + component.scc.forEach(function(node){ + node.x = component.x + node.x; + nextMax = Math.max(nextMax, node.x); + }); + }); + max = nextMax; + }); + + + nodes + .filter(function(node) { + var outLinks = node.sourceLinks.filter(function(link){ return link.source.name != link.target.name; }); + return (outLinks.length == 0); + }) + .forEach(function(node) { node.x = max; }) + + scaleNodeBreadths((size[0] - nodeWidth) / Math.max(max, 1)); + + function flatten(a) { + return [].concat.apply([], a); + } + + function layerComponents() { + var remainingComponents = components, + nextComponents, + visitedIndex, + x = 0; + + while (remainingComponents.length) { + nextComponents = []; + visitedIndex = {}; + + remainingComponents.forEach(function(component) { + component.x = x; + + component.scc.forEach(function(n) { + n.sourceLinks.forEach(function(l) { + if (!visitedIndex.hasOwnProperty(l.target.component) && + l.target.component != component.index) { + nextComponents.push(components[l.target.component]); + visitedIndex[l.target.component] = true; + } + }) + }); + }); + + remainingComponents = nextComponents; + ++x; + } + } + + function bfs(node, extractTargets) { + var queue = [node], currentCount = 1, nextCount = 0; + var x = 0; + + while(currentCount > 0) { + var currentNode = queue.shift(); + currentCount--; + + if (!currentNode.hasOwnProperty('x')) { + currentNode.x = x; + currentNode.dx = nodeWidth; + + var targets = extractTargets(currentNode); + + queue = queue.concat(targets); + nextCount += targets.length; + } + + + if (currentCount == 0) { // level change + x++; + currentCount = nextCount; + nextCount = 0; + } + + } + } + } + + function moveSourcesRight() { + nodes.forEach(function(node) { + if (!node.targetLinks.length) { + node.x = d3.min(node.sourceLinks, function(d) { return d.target.x; }) - 1; + } + }); + } + + function moveSinksRight(x) { + nodes.forEach(function(node) { + if (!node.sourceLinks.length) { + node.x = x - 1; + } + }); + } + + function scaleNodeBreadths(kx) { + nodes.forEach(function(node) { + node.x *= kx; + }); + } + + function computeNodeDepths(iterations) { + var nodesByBreadth = d3.nest() + .key(function(d) { return d.x; }) + .sortKeys(d3.ascending) + .entries(nodes) + .map(function(d) { return d.values; }); + + // + initializeNodeDepth(); + resolveCollisions(); + for (var alpha = 1; iterations > 0; --iterations) { + relaxRightToLeft(alpha *= .99); + resolveCollisions(); + relaxLeftToRight(alpha); + resolveCollisions(); + } + + function initializeNodeDepth() { + var ky = d3.min(nodesByBreadth, function(nodes) { + return (size[1] - (nodes.length - 1) * nodePadding) / d3.sum(nodes, value); + }); + + nodesByBreadth.forEach(function(nodes) { + nodes.forEach(function(node, i) { + node.y = i; + node.dy = node.value * ky; + }); + }); + + links.forEach(function(link) { + link.dy = link.value * ky; + }); + } + + function relaxLeftToRight(alpha) { + nodesByBreadth.forEach(function(nodes, breadth) { + nodes.forEach(function(node) { + if (node.targetLinks.length) { + var y = d3.sum(node.targetLinks, weightedSource) / d3.sum(node.targetLinks, value); + node.y += (y - center(node)) * alpha; + } + }); + }); + + function weightedSource(link) { + return center(link.source) * link.value; + } + } + + function relaxRightToLeft(alpha) { + nodesByBreadth.slice().reverse().forEach(function(nodes) { + nodes.forEach(function(node) { + if (node.sourceLinks.length) { + var y = d3.sum(node.sourceLinks, weightedTarget) / d3.sum(node.sourceLinks, value); + node.y += (y - center(node)) * alpha; + } + }); + }); + + function weightedTarget(link) { + return center(link.target) * link.value; + } + } + + function resolveCollisions() { + nodesByBreadth.forEach(function(nodes) { + var node, + dy, + y0 = 0, + n = nodes.length, + i; + + // Push any overlapping nodes down. + nodes.sort(ascendingDepth); + for (i = 0; i < n; ++i) { + node = nodes[i]; + dy = y0 - node.y; + if (dy > 0) node.y += dy; + y0 = node.y + node.dy + nodePadding; + } + + // If the bottommost node goes outside the bounds, push it back up. + dy = y0 - nodePadding - size[1]; + if (dy > 0) { + y0 = node.y -= dy; + + // Push any overlapping nodes back up. + for (i = n - 2; i >= 0; --i) { + node = nodes[i]; + dy = node.y + node.dy + nodePadding - y0; + if (dy > 0) node.y -= dy; + y0 = node.y; + } + } + }); + } + + function ascendingDepth(a, b) { + return a.y - b.y; + } + } + + function computeLinkDepths() { + nodes.forEach(function(node) { + node.sourceLinks.sort(ascendingTargetDepth); + node.targetLinks.sort(ascendingSourceDepth); + }); + nodes.forEach(function(node) { + var sy = 0, ty = 0; + node.sourceLinks.forEach(function(link) { + link.sy = sy; + sy += link.dy; + }); + node.targetLinks.forEach(function(link) { + link.ty = ty; + ty += link.dy; + }); + }); + + function ascendingSourceDepth(a, b) { + return a.source.y - b.source.y; + } + + function ascendingTargetDepth(a, b) { + return a.target.y - b.target.y; + } + } + + function center(node) { + return node.y + node.dy / 2; + } + + function value(link) { + return link.value; + } + + return sankey; +}; + +/// END LIBRARY CODE + +return d3.sankey; + +}); \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/sankey.css b/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/sankey.css new file mode 100644 index 0000000..c2ccc86 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/sankey.css @@ -0,0 +1,28 @@ +.sankey-diagram .node rect { + cursor: move; + fill-opacity: 0.9; + shape-rendering: crispEdges; +} + +.sankey-diagram .node text { + pointer-events: none; + text-shadow: 0 1px 0 white; +} + +.sankey-diagram .link { + fill: none; + stroke: black; + stroke-opacity: 0.2; +} + +.sankey-diagram .link:hover, .sankey-diagram .link.hovering { + stroke-opacity: 0.5; +} + +.sankey-diagram .link.my-selected { + stroke: yellow; +} + +.sankey-diagram scrollable { + overflow-y: auto; +} diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/sankey.js b/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/sankey.js new file mode 100644 index 0000000..cc3760f --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/sankey/sankey.js @@ -0,0 +1,277 @@ +// AppFramework Sankey Plug-In +// --------------------------- +// +// Provide an easy-to-use plug-in that takes data that relates a +// many-to-many relationship with scores into a Sankey display, a form +// of flow display. Any relationship between two fields can be +// illustrated, although the most common is +// "stats count by field1, field2" + +define(function(require, exports, module) { + var _ = require("underscore"); + var $ = require("jquery"); + var SimpleSplunkView = require("splunkjs/mvc/simplesplunkview"); + var d3 = require("../d3/d3"); + // Load D3 Sankey plugin + require("./contrib/d3-sankey"); + + // Import CSS for the sankey chart. + require("css!./sankey.css"); + + var SankeyChart = SimpleSplunkView.extend({ + moduleId: module.id, + + className: "sankey-diagram", + + options: { + managerid: null, + data: "preview", + formatLabel: _.identity, + height: 300, + formatTooltip: function(d) { + return (d.source.name + ' -> ' + d.target.name + ': ' + d.value); + } + }, + + // This is how we extend the SimpleSplunkView's options value for + // this object, so that these values are available when + // SimpleSplunkView initializes. + initialize: function() { + SimpleSplunkView.prototype.initialize.apply(this, arguments); + + this.settings.on("change:formatLabel change:formatTooltip", this.render, this); + + + // Set up resize callback. + $(window).resize(_.debounce(_.bind(this._handleResize, this), 20)); + }, + + _handleResize: function() { + this.render(); + }, + + // The object this method returns will be passed to the + // updateView() method as the first argument, to be + // manipulated according to the data and the visualization's + // needs. + createView: function() { + var margin = {top: 10, right: 10, bottom: 10, left: 10}; + var availableWidth = parseInt(this.settings.get("width") || this.$el.width()); + var availableHeight = parseInt(this.settings.get("height") || this.$el.height()); + + this.$el.html(""); + + var svg = d3.select(this.el) + .append("svg") + .attr("width", availableWidth) + .attr("height", availableHeight) + .attr("pointer-events", "all"); + + return { svg: svg, margin: margin}; + }, + + // Where the data and the visualization meet. Both 'viz' and + // 'data' are the data structures returned from their + // respective construction methods, createView() above and + // onData(), below. + updateView: function(viz, data) { + var that = this; + var containerHeight = this.$el.height(); + var containerWidth = this.$el.width(); + + // Clear svg + var svg = $(viz.svg[0]); + svg.empty(); + svg.height(containerHeight); + svg.width(containerWidth); + + // Add the graph group as a child of the main svg + var graphWidth = containerWidth - viz.margin.left - viz.margin.right; + var graphHeight = containerHeight - viz.margin.top - viz.margin.bottom; + var graph = viz.svg + .append("g") + .attr("width", graphWidth) + .attr("height", graphHeight) + .attr("transform", "translate(" + viz.margin.left + "," + viz.margin.top + ")"); + + var formatLabel = this.settings.get('formatLabel') || _.identity; + var formatTooltip = this.settings.get('formatTooltip'); + + var sankey = d3.sankey() + .nodeWidth(15) + .nodePadding(10) + .size([graphWidth, graphHeight]); + + var path = sankey.link(); + + sankey.nodes(data.nodes) + .links(data.links) + .layout(1); + + var link = graph.append("g").selectAll(".link") + .data(data.links) + .enter().append("path") + .attr("class", "link") + .attr("d", path) + .style("stroke-width", function(d) { + return Math.max(1, d.dy); + }) + .sort(function(a, b) { + return b.dy - a.dy; + }); + + link.append("title") + .text(function(d) { + return formatTooltip(d); + }); + + var node = graph.append("g").selectAll(".node") + .data(data.nodes) + .enter() + .append("g") + .attr("class", "node") + .attr("transform", function(d) { + return "translate(" + d.x + "," + d.y + ")"; + }); + + var color = d3.scale.category20(); + + // Draw the rectangles at each end of the link that + // correspond to a given node, and then decorate the chart + // with the names for each node. + node.append("rect") + .attr("height", function(d) { + return d.dy; + }) + .attr("width", sankey.nodeWidth()) + .style("fill", function(d) { + d.color = color(d.name.replace(/ .*/, "")); + return d.color; + }) + .style("stroke", function(d) { + return d3.rgb(d.color).darker(2); + }) + .on("mouseover", function(node) { + var linksToHighlight = link.filter(function(d) { + return d.source.name === node.name || d.target.name === node.name; + }); + linksToHighlight.classed('hovering', true); + }) + .on("mouseout", function(node) { + var linksToHighlight = link.filter(function(d) { + return d.source.name === node.name || d.target.name === node.name; + }); + linksToHighlight.classed('hovering', false); + }) + .append("title") + .text(function(d) { + return formatLabel(d.name) + "\n" + d.value; + }); + + node.attr("transform", function(d) { + return "translate(" + d.x + "," + d.y + ")"; + }) + .call(d3.behavior.drag() + .origin(function(d) { + return d; + }) + .on("dragstart", function() { + this.parentNode.appendChild(this); + }) + .on("drag", dragmove)); + + node.append("text") + .attr("x", -6) + .attr("y", function(d) { + return d.dy / 2; + }) + .attr("dy", ".35em") + .attr("text-anchor", "end") + .attr("transform", null) + .text(function(d) { + return formatLabel(d.name); + }) + .filter(function(d) { + return d.x < graphWidth / 2; + }) + .attr("x", 6 + sankey.nodeWidth()) + .attr("text-anchor", "start"); + + // This view publishes the 'click:link' event that + // other Splunk views can then use to drill down + // further into the data. We return the source and target + // names as values to be used in further Splunk searches. + // This allows us to accept events from the visualization + // library and provide them consistently to other Splunk + // views. + var format_event_data = function(e) { + return { + source: e.source.name, + target: e.target.name, + value: e.value + }; + }; + + function dragmove(d) { + d3.select(this).attr("transform", "translate(" + d.x + "," + (d.y = Math.max(0, Math.min(graphHeight - d.dy, d3.event.y))) + ")"); + sankey.relayout(); + link.attr("d", path); + } + + link.on('click', function(e) { + that.trigger('click:link', format_event_data(e)); + }); + + node.on('mousedown', function(e) { + var linksToNodes = function(links, type) { + return _.map(links, function(link) { + return { + name: link[type].name, + value: link[type].value + }; + }); + }; + + var clickEvent = { + name: e.name, + value: e.value, + incomingLinks: linksToNodes(e.targetLinks, "source"), + outgoingLinks: linksToNodes(e.sourceLinks, "target") + }; + that.trigger('click:node', clickEvent); + }); + }, + + // This function turns the three expected data items into data + // structures Sankey understands, and then calls + // updateView(). This is the function that is called when + // new data is available, and triggers the actual rendering of + // the visualization above. The data passed here corresponds + // to the basic format requested by the view. + formatData: function(data) { + var nodeList = _.uniq(_.pluck(data, 0).concat(_.pluck(data, 1))); + + var links = _.map(data, function(item) { + return { + source: nodeList.indexOf(item[0]), + target: nodeList.indexOf(item[1]), + value: parseInt(item[2], 10) + }; + }); + + var nodes = _.map(nodeList, function(node) { + return { + name: node + }; + }); + + return { nodes: nodes, links: links }; + }, + render: function() { + this.$el.height(this.settings.get('height')); + return SimpleSplunkView.prototype.render.apply(this, arguments); + } + }); + + return SankeyChart; +}); diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/scc_takethetour/scc_takethetour.css b/deployment-apps/metricator-for-nmon/appserver/static/components/scc_takethetour/scc_takethetour.css new file mode 100644 index 0000000..75b60f2 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/scc_takethetour/scc_takethetour.css @@ -0,0 +1,70 @@ +/* + -------------- + SccTakeTheTour + -------------- +*/ + +/* Navigation*/ +.scc-takethetour-nav { + margin-bottom: 2em; +} + +.scc-takethetour-nav button, +.scc-takethetour-nav div { + display: inline-block; +} + +.scc-takethetour-nav div button{ + border-radius: 0; + border-right: none; +} + +.scc-takethetour-nav button.prev{ + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-right: none; +} + +.scc-takethetour-nav button.next{ + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.scc-takethetour-nav button.prev .caret { + transform: rotate(90deg); + padding: 0; +} + +.scc-takethetour-nav button.next .caret { + transform: rotate(270deg); + padding: 0; +} + +/* Slides */ +.scc-takethetour-slides { + margin: 0; +} + +.scc-takethetour-slides li{ + list-style-type: none; +} + +/* Various */ +.scc-takethetour .credits { + font-size: 9px; + text-align: center; +} + +.scc-takethetour.modal .modal-footer { + padding-left: 20px; + padding-right: 20px; +} + +.scc-takethetour .never-show-again { + float: left; +} + +.scc-takethetour .never-show-again input { + margin-top: 0; + margin-right: 0.5em; +} \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/scc_takethetour/scc_takethetour.js b/deployment-apps/metricator-for-nmon/appserver/static/components/scc_takethetour/scc_takethetour.js new file mode 100644 index 0000000..a235d9d --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/scc_takethetour/scc_takethetour.js @@ -0,0 +1,226 @@ +/* + -------------- + SccTakeTheTour + -------------- +*/ + +define(function(require, exports, module) { + var $ = require('jquery'); + var SimpleSplunkView = require('splunkjs/mvc/simplesplunkview'); + var SplunkUtils = require('splunkjs/mvc/utils'); + require("css!./scc_takethetour.css"); + + var SccTakeTheTour = SimpleSplunkView.extend({ + className: "scc-takethetour", + options: { + title: "Take the tour", + width: 60, + close_btn_label: "Close", + no_more_label: "Do not show this tour again", + hide_container: false, + show_credits: false, + cookie_name_suffix: "", + backdrop_close: true, + keyboard_close: true + }, + + initialize: function() { + SimpleSplunkView.prototype.initialize.apply(this, arguments); + + // Treat "hide_container" setting + if(this.settings.get('hide_container') == true){ + this.$el.parent().css({ + 'padding':0, + 'margin':0, + 'height':'0px', + 'width':'0px' + }) + } + + return this; + }, + + render: function() { + this.$el.html(''); + + // Cookie stuff + var cookie_name_suffix = this.settings.get('cookie_name_suffix') == "" ? "" : '_' + this.settings.get('cookie_name_suffix'); + var ck_name = 'scc_takethetour_' + SplunkUtils.getCurrentApp() + cookie_name_suffix; + + // set expiration for 1 year + var d = new Date(); + d.setTime(d.getTime() + (365*24*60*60*1000)); + var ck_expires = "expires="+d.toUTCString(); + + function getCookie(ck_name) { + var oRegex = new RegExp("(?:; )?" + ck_name + "=([^;]*);?"); + return oRegex.test(document.cookie) ? decodeURIComponent(RegExp["$1"]) : null; + } + + function setCookie(ck_name) { + document.cookie = ck_name + "= scc-takethetour" + ";" + ck_expires; + } + + // GENERATE BOOTSTRAP MODAL + // ------------------------ + if(typeof this.settings.get('user_slides') !== 'undefined' + && $('#'+this.settings.get('user_slides')).length == 1 + && getCookie(ck_name) == null){ + + var html_tpl = ''; + this.$el.html(html_tpl); + + var $user_slides = $('#'+this.settings.get('user_slides')+' li'); + + var $modal = this.$el.find('#scc-takethetour-modal'); + $modal.css({width:this.settings.get('width') + "%", "margin-left": "-" + this.settings.get('width')/2 + "%"}); + + var $modal_body = this.$el.find('#scc-takethetour-modal .modal-body'); + var $slides = this.$el.find('.scc-takethetour-slides'); + var $slides_nav = this.$el.find('.scc-takethetour-nav'); + var $slides_nav_prev = $slides_nav.find('.prev'); + var $slides_nav_next = $slides_nav.find('.next'); + var $slides_nav_links = $slides_nav.find('div'); + var $checkbox = this.$el.find('.never-show-again input'); + + var active_slide_id = 0; + var max_slide_id = $user_slides.length - 1; + + // Treat "show_credits" setting + if(this.settings.get('show_credits') === true){ + var html_credits = '
' + + 'Powered by Splunk and Scc' + + '
'; + $modal.find('.modal-footer').append(html_credits); + } + + $user_slides.each(function(idx){ + $slides_nav_links.append(''); + $slides.append($user_slides.eq(idx)); + + idx == 0 ? $slides_nav_links.find('button').eq(idx).addClass('btn-primary') : $slides.find('li').eq(idx).addClass('hide'); + }); + $('#'+this.settings.get('user_slides')).remove(); + + + // EVENTS + // ------ + $slides_nav_prev.on('click', function(){ + if(!$(this).hasClass('disabled')){ + slidesManagr(active_slide_id - 1); + } + }); + $slides_nav_next.on('click', function(){ + if(!$(this).hasClass('disabled')){ + slidesManagr(active_slide_id + 1); + } + }); + $slides_nav_links.on('click', function(e){ + slidesManagr($(e.target).attr('data-slide-id')); + }); + + // Add / remove vertical scrollbar on page resize + function isScrollNeeded(){ + var overflow_y = $slides_nav.outerHeight(true) + $slides.outerHeight() > $modal_body.height() ? 'scroll' : 'none'; + $modal_body.css('overflow-y', overflow_y); + }; + + // Hide / show slides and slides navigation + function slidesManagr(slide_id){ + slide_id = parseInt(slide_id); + + // Manage slides + $slides.find('li').eq(active_slide_id).addClass('hide'); + $slides_nav_links.find('button').eq(active_slide_id).removeClass('btn-primary') + + $slides.find('li').eq(slide_id).removeClass('hide'); + $slides_nav_links.find('button').eq(slide_id).addClass('btn-primary'); + + // Manage nav + if(slide_id == 0){ + if(!$slides_nav_prev.hasClass('disabled')){ + $slides_nav_prev.addClass('disabled'); + } + if($slides_nav_next.hasClass('disabled')){ + $slides_nav_next.removeClass('disabled'); + } + } + + else if(slide_id == max_slide_id){ + if(!$slides_nav_next.hasClass('disabled')){ + $slides_nav_next.addClass('disabled'); + } + if($slides_nav_prev.hasClass('disabled')){ + $slides_nav_prev.removeClass('disabled'); + } + } + + else{ + if($slides_nav_prev.hasClass('disabled')){ + $slides_nav_prev.removeClass('disabled'); + } + if($slides_nav_next.hasClass('disabled')){ + $slides_nav_next.removeClass('disabled'); + } + } + + active_slide_id = slide_id; + isScrollNeeded(); + } + + $(window).resize(function(){ + isScrollNeeded(); + }); + + // Treat "backdrop_close" and "keyboard_close" settings + var modal_backdrop = this.settings.get('backdrop_close') === true ? true : 'static'; + var modal_keyboard = this.settings.get('keyboard_close') === true ? true : false; + + $modal + .on('shown.bs.modal', function(e){ + // Prevents page body scrolling if modal content is scrollable + $('body').css({overflow:"hidden", position:"fixed", width: "100%"}); + isScrollNeeded(); + }) + .on('hide.bs.modal', function(e){ + // Give back inherited overflow attributes to the body + $('body').css({overflow:"inherit", position:"inherit", width: "inherit"}); + + // Never show the tour again until navigator cookie is not deleted by user + if($checkbox.is(':checked')){ + setCookie(ck_name); + } + }) + .modal({ + backdrop: modal_backdrop, + keyboard: modal_keyboard + }); + } + + return this; + } + }); + + return SccTakeTheTour; +}); diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/srcviewer/codeview.js b/deployment-apps/metricator-for-nmon/appserver/static/components/srcviewer/codeview.js new file mode 100644 index 0000000..878d2b6 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/srcviewer/codeview.js @@ -0,0 +1,61 @@ +require.config({ + paths: { + prettify: '../app/simple_xml_examples/components/srcviewer/contrib/prettify' + } +}) +define([ + 'underscore', + 'jquery', + 'backbone', + 'prettify', + 'css!contrib/google-code-prettify/prettify.css' +], function(_, $, Backbone, prettify) { + + var CodeView = Backbone.View.extend({ + options: { + stripI18n: true + }, + initialize: function() { + this.listenTo(this.model, 'change:content', this.render, this); + }, + getContent: function() { + var content = this.model.get('content'); + if (content && this.options.stripI18n) { + content = this.stripInjectedI18n(content); + } + return content; + }, + stripInjectedI18n: function(source) { + var lines = source.split(/\r\n|\r|\n/); + var i = 0, start = 0; + while (i < lines.length) { + if (lines[i].indexOf('i18n_register') === 0) { + i++; + while (!lines[i]) { + i++; + } + start = i; + break; + } + i++; + } + return lines.slice(start).join('\n'); + }, + render: function() { + this.$el.html(this.template({ + content: this.getContent(), + lang: this.model.get('lang') + })); + this.$el.attr({ "class": "tab-pane", id: this.model.get("id") }); + prettify(function(){}, this.el); + return this; + }, + template: _.template( + '
' +
+                        '<%- content %>' +
+                    '
' + ) + }); + + return CodeView; +}); \ No newline at end of file diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/srcviewer/contrib/prettify.js b/deployment-apps/metricator-for-nmon/appserver/static/components/srcviewer/contrib/prettify.js new file mode 100644 index 0000000..7b3a360 --- /dev/null +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/srcviewer/contrib/prettify.js @@ -0,0 +1,1655 @@ +// Copyright (C) 2006 Google Inc. +// +// Licensed 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. + + +/** + * @fileoverview + * some functions for browser-side pretty printing of code contained in html. + * + *

+ * For a fairly comprehensive set of languages see the + * README + * file that came with this source. At a minimum, the lexer should work on a + * number of languages including C and friends, Java, Python, Bash, SQL, HTML, + * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk + * and a subset of Perl, but, because of commenting conventions, doesn't work on + * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. + *

+ * Usage:

    + *
  1. include this source file in an html page via + * {@code } + *
  2. define style rules. See the example page for examples. + *
  3. mark the {@code
    } and {@code } tags in your source with
    + *    {@code class=prettyprint.}
    + *    You can also use the (html deprecated) {@code } tag, but the pretty
    + *    printer needs to do more substantial DOM manipulations to support that, so
    + *    some css styles may not be preserved.
    + * </ol>
    + * That's it.  I wanted to keep the API as simple as possible, so there's no
    + * need to specify which language the code is in, but if you wish, you can add
    + * another class to the {@code <pre>} or {@code <code>} element to specify the
    + * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
    + * starts with "lang-" followed by a file extension, specifies the file type.
    + * See the "lang-*.js" files in this directory for code that implements
    + * per-language file handlers.
    + * <p>
    + * Change log:<br>
    + * cbeust, 2006/08/22
    + * <blockquote>
    + *   Java annotations (start with "@") are now captured as literals ("lit")
    + * </blockquote>
    + * @requires console
    + */
    +
    +// JSLint declarations
    +/*global console, document, navigator, setTimeout, window, define */
    +
    +/** @define {boolean} */
    +var IN_GLOBAL_SCOPE = true;
    +
    +/**
    + * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
    + * UI events.
    + * If set to {@code false}, {@code prettyPrint()} is synchronous.
    + */
    +window['PR_SHOULD_USE_CONTINUATION'] = true;
    +
    +/**
    + * Pretty print a chunk of code.
    + * @param {string} sourceCodeHtml The HTML to pretty print.
    + * @param {string} opt_langExtension The language name to use.
    + *     Typically, a filename extension like 'cpp' or 'java'.
    + * @param {number|boolean} opt_numberLines True to number lines,
    + *     or the 1-indexed number of the first line in sourceCodeHtml.
    + * @return {string} code as html, but prettier
    + */
    +var prettyPrintOne;
    +/**
    + * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    + * {@code class=prettyprint} and prettify them.
    + *
    + * @param {Function} opt_whenDone called when prettifying is done.
    + * @param {HTMLElement|HTMLDocument} opt_root an element or document
    + *   containing all the elements to pretty print.
    + *   Defaults to {@code document.body}.
    + */
    +var prettyPrint;
    +
    +
    +(function () {
    +  var win = window;
    +  // Keyword lists for various languages.
    +  // We use things that coerce to strings to make them compact when minified
    +  // and to defeat aggressive optimizers that fold large string constants.
    +  var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
    +  var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
    +      "double,enum,extern,float,goto,inline,int,long,register,short,signed," +
    +      "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
    +  var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
    +      "new,operator,private,protected,public,this,throw,true,try,typeof"];
    +  var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
    +      "concept,concept_map,const_cast,constexpr,decltype,delegate," +
    +      "dynamic_cast,explicit,export,friend,generic,late_check," +
    +      "mutable,namespace,nullptr,property,reinterpret_cast,static_assert," +
    +      "static_cast,template,typeid,typename,using,virtual,where"];
    +  var JAVA_KEYWORDS = [COMMON_KEYWORDS,
    +      "abstract,assert,boolean,byte,extends,final,finally,implements,import," +
    +      "instanceof,interface,null,native,package,strictfp,super,synchronized," +
    +      "throws,transient"];
    +  var CSHARP_KEYWORDS = [COMMON_KEYWORDS,
    +      "abstract,as,base,bool,by,byte,checked,decimal,delegate,descending," +
    +      "dynamic,event,finally,fixed,foreach,from,group,implicit,in,interface," +
    +      "internal,into,is,let,lock,null,object,out,override,orderby,params," +
    +      "partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong," +
    +      "unchecked,unsafe,ushort,var,virtual,where"];
    +  var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
    +      "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
    +      "throw,true,try,unless,until,when,while,yes";
    +  var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
    +      "debugger,eval,export,function,get,null,set,undefined,var,with," +
    +      "Infinity,NaN"];
    +  var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
    +      "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
    +      "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
    +  var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
    +      "elif,except,exec,finally,from,global,import,in,is,lambda," +
    +      "nonlocal,not,or,pass,print,raise,try,with,yield," +
    +      "False,True,None"];
    +  var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
    +      "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
    +      "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
    +      "BEGIN,END"];
    +   var RUST_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "as,assert,const,copy,drop," +
    +      "enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv," +
    +      "pub,pure,ref,self,static,struct,true,trait,type,unsafe,use"];
    +  var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
    +      "function,in,local,set,then,until"];
    +  var ALL_KEYWORDS = [
    +      CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS,
    +      PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
    +  var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
    +
    +  // token style names.  correspond to css classes
    +  /**
    +   * token style for a string literal
    +   * @const
    +   */
    +  var PR_STRING = 'str';
    +  /**
    +   * token style for a keyword
    +   * @const
    +   */
    +  var PR_KEYWORD = 'kwd';
    +  /**
    +   * token style for a comment
    +   * @const
    +   */
    +  var PR_COMMENT = 'com';
    +  /**
    +   * token style for a type
    +   * @const
    +   */
    +  var PR_TYPE = 'typ';
    +  /**
    +   * token style for a literal value.  e.g. 1, null, true.
    +   * @const
    +   */
    +  var PR_LITERAL = 'lit';
    +  /**
    +   * token style for a punctuation string.
    +   * @const
    +   */
    +  var PR_PUNCTUATION = 'pun';
    +  /**
    +   * token style for plain text.
    +   * @const
    +   */
    +  var PR_PLAIN = 'pln';
    +
    +  /**
    +   * token style for an sgml tag.
    +   * @const
    +   */
    +  var PR_TAG = 'tag';
    +  /**
    +   * token style for a markup declaration such as a DOCTYPE.
    +   * @const
    +   */
    +  var PR_DECLARATION = 'dec';
    +  /**
    +   * token style for embedded source.
    +   * @const
    +   */
    +  var PR_SOURCE = 'src';
    +  /**
    +   * token style for an sgml attribute name.
    +   * @const
    +   */
    +  var PR_ATTRIB_NAME = 'atn';
    +  /**
    +   * token style for an sgml attribute value.
    +   * @const
    +   */
    +  var PR_ATTRIB_VALUE = 'atv';
    +
    +  /**
    +   * A class that indicates a section of markup that is not code, e.g. to allow
    +   * embedding of line numbers within code listings.
    +   * @const
    +   */
    +  var PR_NOCODE = 'nocode';
    +
    +
    +
    +  /**
    +   * A set of tokens that can precede a regular expression literal in
    +   * javascript
    +   * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
    +   * has the full list, but I've removed ones that might be problematic when
    +   * seen in languages that don't support regular expression literals.
    +   *
    +   * <p>Specifically, I've removed any keywords that can't precede a regexp
    +   * literal in a syntactically legal javascript program, and I've removed the
    +   * "in" keyword since it's not a keyword in many languages, and might be used
    +   * as a count of inches.
    +   *
    +   * <p>The link above does not accurately describe EcmaScript rules since
    +   * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
    +   * very well in practice.
    +   *
    +   * @private
    +   * @const
    +   */
    +  var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
    +
    +  // CAVEAT: this does not properly handle the case where a regular
    +  // expression immediately follows another since a regular expression may
    +  // have flags for case-sensitivity and the like.  Having regexp tokens
    +  // adjacent is not valid in any language I'm aware of, so I'm punting.
    +  // TODO: maybe style special characters inside a regexp as punctuation.
    +
    +  /**
    +   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
    +   * matches the union of the sets of strings matched by the input RegExp.
    +   * Since it matches globally, if the input strings have a start-of-input
    +   * anchor (/^.../), it is ignored for the purposes of unioning.
    +   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
    +   * @return {RegExp} a global regex.
    +   */
    +  function combinePrefixPatterns(regexs) {
    +    var capturedGroupIndex = 0;
    +
    +    var needToFoldCase = false;
    +    var ignoreCase = false;
    +    for (var i = 0, n = regexs.length; i < n; ++i) {
    +      var regex = regexs[i];
    +      if (regex.ignoreCase) {
    +        ignoreCase = true;
    +      } else if (/[a-z]/i.test(regex.source.replace(
    +                     /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
    +        needToFoldCase = true;
    +        ignoreCase = false;
    +        break;
    +      }
    +    }
    +
    +    var escapeCharToCodeUnit = {
    +      'b': 8,
    +      't': 9,
    +      'n': 0xa,
    +      'v': 0xb,
    +      'f': 0xc,
    +      'r': 0xd
    +    };
    +
    +    function decodeEscape(charsetPart) {
    +      var cc0 = charsetPart.charCodeAt(0);
    +      if (cc0 !== 92 /* \\ */) {
    +        return cc0;
    +      }
    +      var c1 = charsetPart.charAt(1);
    +      cc0 = escapeCharToCodeUnit[c1];
    +      if (cc0) {
    +        return cc0;
    +      } else if ('0' <= c1 && c1 <= '7') {
    +        return parseInt(charsetPart.substring(1), 8);
    +      } else if (c1 === 'u' || c1 === 'x') {
    +        return parseInt(charsetPart.substring(2), 16);
    +      } else {
    +        return charsetPart.charCodeAt(1);
    +      }
    +    }
    +
    +    function encodeEscape(charCode) {
    +      if (charCode < 0x20) {
    +        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
    +      }
    +      var ch = String.fromCharCode(charCode);
    +      return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
    +          ? "\\" + ch : ch;
    +    }
    +
    +    function caseFoldCharset(charSet) {
    +      var charsetParts = charSet.substring(1, charSet.length - 1).match(
    +          new RegExp(
    +              '\\\\u[0-9A-Fa-f]{4}'
    +              + '|\\\\x[0-9A-Fa-f]{2}'
    +              + '|\\\\[0-3][0-7]{0,2}'
    +              + '|\\\\[0-7]{1,2}'
    +              + '|\\\\[\\s\\S]'
    +              + '|-'
    +              + '|[^-\\\\]',
    +              'g'));
    +      var ranges = [];
    +      var inverse = charsetParts[0] === '^';
    +
    +      var out = ['['];
    +      if (inverse) { out.push('^'); }
    +
    +      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
    +        var p = charsetParts[i];
    +        if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
    +          out.push(p);
    +        } else {
    +          var start = decodeEscape(p);
    +          var end;
    +          if (i + 2 < n && '-' === charsetParts[i + 1]) {
    +            end = decodeEscape(charsetParts[i + 2]);
    +            i += 2;
    +          } else {
    +            end = start;
    +          }
    +          ranges.push([start, end]);
    +          // If the range might intersect letters, then expand it.
    +          // This case handling is too simplistic.
    +          // It does not deal with non-latin case folding.
    +          // It works for latin source code identifiers though.
    +          if (!(end < 65 || start > 122)) {
    +            if (!(end < 65 || start > 90)) {
    +              ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
    +            }
    +            if (!(end < 97 || start > 122)) {
    +              ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
    +            }
    +          }
    +        }
    +      }
    +
    +      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
    +      // -> [[1, 12], [14, 14], [16, 17]]
    +      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
    +      var consolidatedRanges = [];
    +      var lastRange = [];
    +      for (var i = 0; i < ranges.length; ++i) {
    +        var range = ranges[i];
    +        if (range[0] <= lastRange[1] + 1) {
    +          lastRange[1] = Math.max(lastRange[1], range[1]);
    +        } else {
    +          consolidatedRanges.push(lastRange = range);
    +        }
    +      }
    +
    +      for (var i = 0; i < consolidatedRanges.length; ++i) {
    +        var range = consolidatedRanges[i];
    +        out.push(encodeEscape(range[0]));
    +        if (range[1] > range[0]) {
    +          if (range[1] + 1 > range[0]) { out.push('-'); }
    +          out.push(encodeEscape(range[1]));
    +        }
    +      }
    +      out.push(']');
    +      return out.join('');
    +    }
    +
    +    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
    +      // Split into character sets, escape sequences, punctuation strings
    +      // like ('(', '(?:', ')', '^'), and runs of characters that do not
    +      // include any of the above.
    +      var parts = regex.source.match(
    +          new RegExp(
    +              '(?:'
    +              + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
    +              + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
    +              + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
    +              + '|\\\\[0-9]+'  // a back-reference or octal escape
    +              + '|\\\\[^ux0-9]'  // other escape sequence
    +              + '|\\(\\?[:!=]'  // start of a non-capturing group
    +              + '|[\\(\\)\\^]'  // start/end of a group, or line start
    +              + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
    +              + ')',
    +              'g'));
    +      var n = parts.length;
    +
    +      // Maps captured group numbers to the number they will occupy in
    +      // the output or to -1 if that has not been determined, or to
    +      // undefined if they need not be capturing in the output.
    +      var capturedGroups = [];
    +
    +      // Walk over and identify back references to build the capturedGroups
    +      // mapping.
    +      for (var i = 0, groupIndex = 0; i < n; ++i) {
    +        var p = parts[i];
    +        if (p === '(') {
    +          // groups are 1-indexed, so max group index is count of '('
    +          ++groupIndex;
    +        } else if ('\\' === p.charAt(0)) {
    +          var decimalValue = +p.substring(1);
    +          if (decimalValue) {
    +            if (decimalValue <= groupIndex) {
    +              capturedGroups[decimalValue] = -1;
    +            } else {
    +              // Replace with an unambiguous escape sequence so that
    +              // an octal escape sequence does not turn into a backreference
    +              // to a capturing group from an earlier regex.
    +              parts[i] = encodeEscape(decimalValue);
    +            }
    +          }
    +        }
    +      }
    +
    +      // Renumber groups and reduce capturing groups to non-capturing groups
    +      // where possible.
    +      for (var i = 1; i < capturedGroups.length; ++i) {
    +        if (-1 === capturedGroups[i]) {
    +          capturedGroups[i] = ++capturedGroupIndex;
    +        }
    +      }
    +      for (var i = 0, groupIndex = 0; i < n; ++i) {
    +        var p = parts[i];
    +        if (p === '(') {
    +          ++groupIndex;
    +          if (!capturedGroups[groupIndex]) {
    +            parts[i] = '(?:';
    +          }
    +        } else if ('\\' === p.charAt(0)) {
    +          var decimalValue = +p.substring(1);
    +          if (decimalValue && decimalValue <= groupIndex) {
    +            parts[i] = '\\' + capturedGroups[decimalValue];
    +          }
    +        }
    +      }
    +
    +      // Remove any prefix anchors so that the output will match anywhere.
    +      // ^^ really does mean an anchored match though.
    +      for (var i = 0; i < n; ++i) {
    +        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
    +      }
    +
    +      // Expand letters to groups to handle mixing of case-sensitive and
    +      // case-insensitive patterns if necessary.
    +      if (regex.ignoreCase && needToFoldCase) {
    +        for (var i = 0; i < n; ++i) {
    +          var p = parts[i];
    +          var ch0 = p.charAt(0);
    +          if (p.length >= 2 && ch0 === '[') {
    +            parts[i] = caseFoldCharset(p);
    +          } else if (ch0 !== '\\') {
    +            // TODO: handle letters in numeric escapes.
    +            parts[i] = p.replace(
    +                /[a-zA-Z]/g,
    +                function (ch) {
    +                  var cc = ch.charCodeAt(0);
    +                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
    +                });
    +          }
    +        }
    +      }
    +
    +      return parts.join('');
    +    }
    +
    +    var rewritten = [];
    +    for (var i = 0, n = regexs.length; i < n; ++i) {
    +      var regex = regexs[i];
    +      if (regex.global || regex.multiline) { throw new Error('' + regex); }
    +      rewritten.push(
    +          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
    +    }
    +
    +    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
    +  }
    +
    +  /**
    +   * Split markup into a string of source code and an array mapping ranges in
    +   * that string to the text nodes in which they appear.
    +   *
    +   * <p>
    +   * The HTML DOM structure:</p>
    +   * <pre>
    +   * (Element   "p"
    +   *   (Element "b"
    +   *     (Text  "print "))       ; #1
    +   *   (Text    "'Hello '")      ; #2
    +   *   (Element "br")            ; #3
    +   *   (Text    "  + 'World';")) ; #4
    +   * </pre>
    +   * <p>
    +   * corresponds to the HTML
    +   * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
    +   *
    +   * <p>
    +   * It will produce the output:</p>
    +   * <pre>
    +   * {
    +   *   sourceCode: "print 'Hello '\n  + 'World';",
    +   *   //                     1          2
    +   *   //           012345678901234 5678901234567
    +   *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
    +   * }
    +   * </pre>
    +   * <p>
    +   * where #1 is a reference to the {@code "print "} text node above, and so
    +   * on for the other text nodes.
    +   * </p>
    +   *
    +   * <p>
    +   * The {@code} spans array is an array of pairs.  Even elements are the start
    +   * indices of substrings, and odd elements are the text nodes (or BR elements)
    +   * that contain the text for those substrings.
    +   * Substrings continue until the next index or the end of the source.
    +   * </p>
    +   *
    +   * @param {Node} node an HTML DOM subtree containing source-code.
    +   * @param {boolean} isPreformatted true if white-space in text nodes should
    +   *    be considered significant.
    +   * @return {Object} source code and the text nodes in which they occur.
    +   */
    +  function extractSourceSpans(node, isPreformatted) {
    +    var nocode = /(?:^|\s)nocode(?:\s|$)/;
    +
    +    var chunks = [];
    +    var length = 0;
    +    var spans = [];
    +    var k = 0;
    +
    +    function walk(node) {
    +      var type = node.nodeType;
    +      if (type == 1) {  // Element
    +        if (nocode.test(node.className)) { return; }
    +        for (var child = node.firstChild; child; child = child.nextSibling) {
    +          walk(child);
    +        }
    +        var nodeName = node.nodeName.toLowerCase();
    +        if ('br' === nodeName || 'li' === nodeName) {
    +          chunks[k] = '\n';
    +          spans[k << 1] = length++;
    +          spans[(k++ << 1) | 1] = node;
    +        }
    +      } else if (type == 3 || type == 4) {  // Text
    +        var text = node.nodeValue;
    +        if (text.length) {
    +          if (!isPreformatted) {
    +            text = text.replace(/[ \t\r\n]+/g, ' ');
    +          } else {
    +            text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
    +          }
    +          // TODO: handle tabs here?
    +          chunks[k] = text;
    +          spans[k << 1] = length;
    +          length += text.length;
    +          spans[(k++ << 1) | 1] = node;
    +        }
    +      }
    +    }
    +
    +    walk(node);
    +
    +    return {
    +      sourceCode: chunks.join('').replace(/\n$/, ''),
    +      spans: spans
    +    };
    +  }
    +
    +  /**
    +   * Apply the given language handler to sourceCode and add the resulting
    +   * decorations to out.
    +   * @param {number} basePos the index of sourceCode within the chunk of source
    +   *    whose decorations are already present on out.
    +   */
    +  function appendDecorations(basePos, sourceCode, langHandler, out) {
    +    if (!sourceCode) { return; }
    +    var job = {
    +      sourceCode: sourceCode,
    +      basePos: basePos
    +    };
    +    langHandler(job);
    +    out.push.apply(out, job.decorations);
    +  }
    +
    +  var notWs = /\S/;
    +
    +  /**
    +   * Given an element, if it contains only one child element and any text nodes
    +   * it contains contain only space characters, return the sole child element.
    +   * Otherwise returns undefined.
    +   * <p>
    +   * This is meant to return the CODE element in {@code <pre><code ...>} when
    +   * there is a single child element that contains all the non-space textual
    +   * content, but not to return anything where there are multiple child elements
    +   * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
    +   * is textual content.
    +   */
    +  function childContentWrapper(element) {
    +    var wrapper = undefined;
    +    for (var c = element.firstChild; c; c = c.nextSibling) {
    +      var type = c.nodeType;
    +      wrapper = (type === 1)  // Element Node
    +          ? (wrapper ? element : c)
    +          : (type === 3)  // Text Node
    +          ? (notWs.test(c.nodeValue) ? element : wrapper)
    +          : wrapper;
    +    }
    +    return wrapper === element ? undefined : wrapper;
    +  }
    +
    +  /** Given triples of [style, pattern, context] returns a lexing function,
    +    * The lexing function interprets the patterns to find token boundaries and
    +    * returns a decoration list of the form
    +    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
    +    * where index_n is an index into the sourceCode, and style_n is a style
    +    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
    +    * all characters in sourceCode[index_n-1:index_n].
    +    *
    +    * The stylePatterns is a list whose elements have the form
    +    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
    +    *
    +    * Style is a style constant like PR_PLAIN, or can be a string of the
    +    * form 'lang-FOO', where FOO is a language extension describing the
    +    * language of the portion of the token in $1 after pattern executes.
    +    * E.g., if style is 'lang-lisp', and group 1 contains the text
    +    * '(hello (world))', then that portion of the token will be passed to the
    +    * registered lisp handler for formatting.
    +    * The text before and after group 1 will be restyled using this decorator
    +    * so decorators should take care that this doesn't result in infinite
    +    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
    +    * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
    +    * '<script>foo()<\/script>', which would cause the current decorator to
    +    * be called with '<script>' which would not match the same rule since
    +    * group 1 must not be empty, so it would be instead styled as PR_TAG by
    +    * the generic tag rule.  The handler registered for the 'js' extension would
    +    * then be called with 'foo()', and finally, the current decorator would
    +    * be called with '<\/script>' which would not match the original rule and
    +    * so the generic tag rule would identify it as a tag.
    +    *
    +    * Pattern must only match prefixes, and if it matches a prefix, then that
    +    * match is considered a token with the same style.
    +    *
    +    * Context is applied to the last non-whitespace, non-comment token
    +    * recognized.
    +    *
    +    * Shortcut is an optional string of characters, any of which, if the first
    +    * character, gurantee that this pattern and only this pattern matches.
    +    *
    +    * @param {Array} shortcutStylePatterns patterns that always start with
    +    *   a known character.  Must have a shortcut string.
    +    * @param {Array} fallthroughStylePatterns patterns that will be tried in
    +    *   order if the shortcut ones fail.  May have shortcuts.
    +    *
    +    * @return {function (Object)} a
    +    *   function that takes source code and returns a list of decorations.
    +    */
    +  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
    +    var shortcuts = {};
    +    var tokenizer;
    +    (function () {
    +      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
    +      var allRegexs = [];
    +      var regexKeys = {};
    +      for (var i = 0, n = allPatterns.length; i < n; ++i) {
    +        var patternParts = allPatterns[i];
    +        var shortcutChars = patternParts[3];
    +        if (shortcutChars) {
    +          for (var c = shortcutChars.length; --c >= 0;) {
    +            shortcuts[shortcutChars.charAt(c)] = patternParts;
    +          }
    +        }
    +        var regex = patternParts[1];
    +        var k = '' + regex;
    +        if (!regexKeys.hasOwnProperty(k)) {
    +          allRegexs.push(regex);
    +          regexKeys[k] = null;
    +        }
    +      }
    +      allRegexs.push(/[\0-\uffff]/);
    +      tokenizer = combinePrefixPatterns(allRegexs);
    +    })();
    +
    +    var nPatterns = fallthroughStylePatterns.length;
    +
    +    /**
    +     * Lexes job.sourceCode and produces an output array job.decorations of
    +     * style classes preceded by the position at which they start in
    +     * job.sourceCode in order.
    +     *
    +     * @param {Object} job an object like <pre>{
    +     *    sourceCode: {string} sourceText plain text,
    +     *    basePos: {int} position of job.sourceCode in the larger chunk of
    +     *        sourceCode.
    +     * }</pre>
    +     */
    +    var decorate = function (job) {
    +      var sourceCode = job.sourceCode, basePos = job.basePos;
    +      /** Even entries are positions in source in ascending order.  Odd enties
    +        * are style markers (e.g., PR_COMMENT) that run from that position until
    +        * the end.
    +        * @type {Array.<number|string>}
    +        */
    +      var decorations = [basePos, PR_PLAIN];
    +      var pos = 0;  // index into sourceCode
    +      var tokens = sourceCode.match(tokenizer) || [];
    +      var styleCache = {};
    +
    +      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
    +        var token = tokens[ti];
    +        var style = styleCache[token];
    +        var match = void 0;
    +
    +        var isEmbedded;
    +        if (typeof style === 'string') {
    +          isEmbedded = false;
    +        } else {
    +          var patternParts = shortcuts[token.charAt(0)];
    +          if (patternParts) {
    +            match = token.match(patternParts[1]);
    +            style = patternParts[0];
    +          } else {
    +            for (var i = 0; i < nPatterns; ++i) {
    +              patternParts = fallthroughStylePatterns[i];
    +              match = token.match(patternParts[1]);
    +              if (match) {
    +                style = patternParts[0];
    +                break;
    +              }
    +            }
    +
    +            if (!match) {  // make sure that we make progress
    +              style = PR_PLAIN;
    +            }
    +          }
    +
    +          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
    +          if (isEmbedded && !(match && typeof match[1] === 'string')) {
    +            isEmbedded = false;
    +            style = PR_SOURCE;
    +          }
    +
    +          if (!isEmbedded) { styleCache[token] = style; }
    +        }
    +
    +        var tokenStart = pos;
    +        pos += token.length;
    +
    +        if (!isEmbedded) {
    +          decorations.push(basePos + tokenStart, style);
    +        } else {  // Treat group 1 as an embedded block of source code.
    +          var embeddedSource = match[1];
    +          var embeddedSourceStart = token.indexOf(embeddedSource);
    +          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
    +          if (match[2]) {
    +            // If embeddedSource can be blank, then it would match at the
    +            // beginning which would cause us to infinitely recurse on the
    +            // entire token, so we catch the right context in match[2].
    +            embeddedSourceEnd = token.length - match[2].length;
    +            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
    +          }
    +          var lang = style.substring(5);
    +          // Decorate the left of the embedded source
    +          appendDecorations(
    +              basePos + tokenStart,
    +              token.substring(0, embeddedSourceStart),
    +              decorate, decorations);
    +          // Decorate the embedded source
    +          appendDecorations(
    +              basePos + tokenStart + embeddedSourceStart,
    +              embeddedSource,
    +              langHandlerForExtension(lang, embeddedSource),
    +              decorations);
    +          // Decorate the right of the embedded section
    +          appendDecorations(
    +              basePos + tokenStart + embeddedSourceEnd,
    +              token.substring(embeddedSourceEnd),
    +              decorate, decorations);
    +        }
    +      }
    +      job.decorations = decorations;
    +    };
    +    return decorate;
    +  }
    +
    +  /** returns a function that produces a list of decorations from source text.
    +    *
    +    * This code treats ", ', and ` as string delimiters, and \ as a string
    +    * escape.  It does not recognize perl's qq() style strings.
    +    * It has no special handling for double delimiter escapes as in basic, or
    +    * the tripled delimiters used in python, but should work on those regardless
    +    * although in those cases a single string literal may be broken up into
    +    * multiple adjacent string literals.
    +    *
    +    * It recognizes C, C++, and shell style comments.
    +    *
    +    * @param {Object} options a set of optional parameters.
    +    * @return {function (Object)} a function that examines the source code
    +    *     in the input job and builds the decoration list.
    +    */
    +  function sourceDecorator(options) {
    +    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
    +    if (options['tripleQuotedStrings']) {
    +      // '''multi-line-string''', 'single-line-string', and double-quoted
    +      shortcutStylePatterns.push(
    +          [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
    +           null, '\'"']);
    +    } else if (options['multiLineStrings']) {
    +      // 'multi-line-string', "multi-line-string"
    +      shortcutStylePatterns.push(
    +          [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
    +           null, '\'"`']);
    +    } else {
    +      // 'single-line-string', "single-line-string"
    +      shortcutStylePatterns.push(
    +          [PR_STRING,
    +           /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
    +           null, '"\'']);
    +    }
    +    if (options['verbatimStrings']) {
    +      // verbatim-string-literal production from the C# grammar.  See issue 93.
    +      fallthroughStylePatterns.push(
    +          [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
    +    }
    +    var hc = options['hashComments'];
    +    if (hc) {
    +      if (options['cStyleComments']) {
    +        if (hc > 1) {  // multiline hash comments
    +          shortcutStylePatterns.push(
    +              [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
    +        } else {
    +          // Stop C preprocessor declarations at an unclosed open comment
    +          shortcutStylePatterns.push(
    +              [PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
    +               null, '#']);
    +        }
    +        // #include <stdio.h>
    +        fallthroughStylePatterns.push(
    +            [PR_STRING,
    +             /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
    +             null]);
    +      } else {
    +        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
    +      }
    +    }
    +    if (options['cStyleComments']) {
    +      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
    +      fallthroughStylePatterns.push(
    +          [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
    +    }
    +    var regexLiterals = options['regexLiterals'];
    +    if (regexLiterals) {
    +      /**
    +       * @const
    +       */
    +      var regexExcls = regexLiterals > 1
    +        ? ''  // Multiline regex literals
    +        : '\n\r';
    +      /**
    +       * @const
    +       */
    +      var regexAny = regexExcls ? '.' : '[\\S\\s]';
    +      /**
    +       * @const
    +       */
    +      var REGEX_LITERAL = (
    +          // A regular expression literal starts with a slash that is
    +          // not followed by * or / so that it is not confused with
    +          // comments.
    +          '/(?=[^/*' + regexExcls + '])'
    +          // and then contains any number of raw characters,
    +          + '(?:[^/\\x5B\\x5C' + regexExcls + ']'
    +          // escape sequences (\x5C),
    +          +    '|\\x5C' + regexAny
    +          // or non-nesting character sets (\x5B\x5D);
    +          +    '|\\x5B(?:[^\\x5C\\x5D' + regexExcls + ']'
    +          +             '|\\x5C' + regexAny + ')*(?:\\x5D|$))+'
    +          // finally closed by a /.
    +          + '/');
    +      fallthroughStylePatterns.push(
    +          ['lang-regex',
    +           RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
    +           ]);
    +    }
    +
    +    var types = options['types'];
    +    if (types) {
    +      fallthroughStylePatterns.push([PR_TYPE, types]);
    +    }
    +
    +    var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
    +    if (keywords.length) {
    +      fallthroughStylePatterns.push(
    +          [PR_KEYWORD,
    +           new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
    +           null]);
    +    }
    +
    +    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
    +
    +    var punctuation =
    +      // The Bash man page says
    +
    +      // A word is a sequence of characters considered as a single
    +      // unit by GRUB. Words are separated by metacharacters,
    +      // which are the following plus space, tab, and newline: { }
    +      // | & $ ; < >
    +      // ...
    +
    +      // A word beginning with # causes that word and all remaining
    +      // characters on that line to be ignored.
    +
    +      // which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
    +      // comment but empirically
    +      // $ echo {#}
    +      // {#}
    +      // $ echo \$#
    +      // $#
    +      // $ echo }#
    +      // }#
    +
    +      // so /(?:^|[|&;<>\s])/ is more appropriate.
    +
    +      // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
    +      // suggests that this definition is compatible with a
    +      // default mode that tries to use a single token definition
    +      // to recognize both bash/python style comments and C
    +      // preprocessor directives.
    +
    +      // This definition of punctuation does not include # in the list of
    +      // follow-on exclusions, so # will not be broken before if preceeded
    +      // by a punctuation character.  We could try to exclude # after
    +      // [|&;<>] but that doesn't seem to cause many major problems.
    +      // If that does turn out to be a problem, we should change the below
    +      // when hc is truthy to include # in the run of punctuation characters
    +      // only when not followint [|&;<>].
    +      '^.[^\\s\\w.$@\'"`/\\\\]*';
    +    if (options['regexLiterals']) {
    +      punctuation += '(?!\s*\/)';
    +    }
    +
    +    fallthroughStylePatterns.push(
    +        // TODO(mikesamuel): recognize non-latin letters and numerals in idents
    +        [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
    +        [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
    +        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
    +        [PR_LITERAL,
    +         new RegExp(
    +             '^(?:'
    +             // A hex number
    +             + '0x[a-f0-9]+'
    +             // or an octal or decimal number,
    +             + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
    +             // possibly in scientific notation
    +             + '(?:e[+\\-]?\\d+)?'
    +             + ')'
    +             // with an optional modifier like UL for unsigned long
    +             + '[a-z]*', 'i'),
    +         null, '0123456789'],
    +        // Don't treat escaped quotes in bash as starting strings.
    +        // See issue 144.
    +        [PR_PLAIN,       /^\\[\s\S]?/, null],
    +        [PR_PUNCTUATION, new RegExp(punctuation), null]);
    +
    +    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
    +  }
    +
    +  var decorateSource = sourceDecorator({
    +        'keywords': ALL_KEYWORDS,
    +        'hashComments': true,
    +        'cStyleComments': true,
    +        'multiLineStrings': true,
    +        'regexLiterals': true
    +      });
    +
    +  /**
    +   * Given a DOM subtree, wraps it in a list, and puts each line into its own
    +   * list item.
    +   *
    +   * @param {Node} node modified in place.  Its content is pulled into an
    +   *     HTMLOListElement, and each line is moved into a separate list item.
    +   *     This requires cloning elements, so the input might not have unique
    +   *     IDs after numbering.
    +   * @param {boolean} isPreformatted true iff white-space in text nodes should
    +   *     be treated as significant.
    +   */
    +  function numberLines(node, opt_startLineNum, isPreformatted) {
    +    var nocode = /(?:^|\s)nocode(?:\s|$)/;
    +    var lineBreak = /\r\n?|\n/;
    +
    +    var document = node.ownerDocument;
    +
    +    var li = document.createElement('li');
    +    while (node.firstChild) {
    +      li.appendChild(node.firstChild);
    +    }
    +    // An array of lines.  We split below, so this is initialized to one
    +    // un-split line.
    +    var listItems = [li];
    +
    +    function walk(node) {
    +      var type = node.nodeType;
    +      if (type == 1 && !nocode.test(node.className)) {  // Element
    +        if ('br' === node.nodeName) {
    +          breakAfter(node);
    +          // Discard the <BR> since it is now flush against a </LI>.
    +          if (node.parentNode) {
    +            node.parentNode.removeChild(node);
    +          }
    +        } else {
    +          for (var child = node.firstChild; child; child = child.nextSibling) {
    +            walk(child);
    +          }
    +        }
    +      } else if ((type == 3 || type == 4) && isPreformatted) {  // Text
    +        var text = node.nodeValue;
    +        var match = text.match(lineBreak);
    +        if (match) {
    +          var firstLine = text.substring(0, match.index);
    +          node.nodeValue = firstLine;
    +          var tail = text.substring(match.index + match[0].length);
    +          if (tail) {
    +            var parent = node.parentNode;
    +            parent.insertBefore(
    +              document.createTextNode(tail), node.nextSibling);
    +          }
    +          breakAfter(node);
    +          if (!firstLine) {
    +            // Don't leave blank text nodes in the DOM.
    +            node.parentNode.removeChild(node);
    +          }
    +        }
    +      }
    +    }
    +
    +    // Split a line after the given node.
    +    function breakAfter(lineEndNode) {
    +      // If there's nothing to the right, then we can skip ending the line
    +      // here, and move root-wards since splitting just before an end-tag
    +      // would require us to create a bunch of empty copies.
    +      while (!lineEndNode.nextSibling) {
    +        lineEndNode = lineEndNode.parentNode;
    +        if (!lineEndNode) { return; }
    +      }
    +
    +      function breakLeftOf(limit, copy) {
    +        // Clone shallowly if this node needs to be on both sides of the break.
    +        var rightSide = copy ? limit.cloneNode(false) : limit;
    +        var parent = limit.parentNode;
    +        if (parent) {
    +          // We clone the parent chain.
    +          // This helps us resurrect important styling elements that cross lines.
    +          // E.g. in <i>Foo<br>Bar</i>
    +          // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
    +          var parentClone = breakLeftOf(parent, 1);
    +          // Move the clone and everything to the right of the original
    +          // onto the cloned parent.
    +          var next = limit.nextSibling;
    +          parentClone.appendChild(rightSide);
    +          for (var sibling = next; sibling; sibling = next) {
    +            next = sibling.nextSibling;
    +            parentClone.appendChild(sibling);
    +          }
    +        }
    +        return rightSide;
    +      }
    +
    +      var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
    +
    +      // Walk the parent chain until we reach an unattached LI.
    +      for (var parent;
    +           // Check nodeType since IE invents document fragments.
    +           (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
    +        copiedListItem = parent;
    +      }
    +      // Put it on the list of lines for later processing.
    +      listItems.push(copiedListItem);
    +    }
    +
    +    // Split lines while there are lines left to split.
    +    for (var i = 0;  // Number of lines that have been split so far.
    +         i < listItems.length;  // length updated by breakAfter calls.
    +         ++i) {
    +      walk(listItems[i]);
    +    }
    +
    +    // Make sure numeric indices show correctly.
    +    if (opt_startLineNum === (opt_startLineNum|0)) {
    +      listItems[0].setAttribute('value', opt_startLineNum);
    +    }
    +
    +    var ol = document.createElement('ol');
    +    ol.className = 'linenums';
    +    var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
    +    for (var i = 0, n = listItems.length; i < n; ++i) {
    +      li = listItems[i];
    +      // Stick a class on the LIs so that stylesheets can
    +      // color odd/even rows, or any other row pattern that
    +      // is co-prime with 10.
    +      li.className = 'L' + ((i + offset) % 10);
    +      if (!li.firstChild) {
    +        li.appendChild(document.createTextNode('\xA0'));
    +      }
    +      ol.appendChild(li);
    +    }
    +
    +    node.appendChild(ol);
    +  }
    +  /**
    +   * Breaks {@code job.sourceCode} around style boundaries in
    +   * {@code job.decorations} and modifies {@code job.sourceNode} in place.
    +   * @param {Object} job like <pre>{
    +   *    sourceCode: {string} source as plain text,
    +   *    sourceNode: {HTMLElement} the element containing the source,
    +   *    spans: {Array.<number|Node>} alternating span start indices into source
    +   *       and the text node or element (e.g. {@code <BR>}) corresponding to that
    +   *       span.
    +   *    decorations: {Array.<number|string} an array of style classes preceded
    +   *       by the position at which they start in job.sourceCode in order
    +   * }</pre>
    +   * @private
    +   */
    +  function recombineTagsAndDecorations(job) {
    +    var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
    +    isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
    +    var newlineRe = /\n/g;
    +
    +    var source = job.sourceCode;
    +    var sourceLength = source.length;
    +    // Index into source after the last code-unit recombined.
    +    var sourceIndex = 0;
    +
    +    var spans = job.spans;
    +    var nSpans = spans.length;
    +    // Index into spans after the last span which ends at or before sourceIndex.
    +    var spanIndex = 0;
    +
    +    var decorations = job.decorations;
    +    var nDecorations = decorations.length;
    +    // Index into decorations after the last decoration which ends at or before
    +    // sourceIndex.
    +    var decorationIndex = 0;
    +
    +    // Remove all zero-length decorations.
    +    decorations[nDecorations] = sourceLength;
    +    var decPos, i;
    +    for (i = decPos = 0; i < nDecorations;) {
    +      if (decorations[i] !== decorations[i + 2]) {
    +        decorations[decPos++] = decorations[i++];
    +        decorations[decPos++] = decorations[i++];
    +      } else {
    +        i += 2;
    +      }
    +    }
    +    nDecorations = decPos;
    +
    +    // Simplify decorations.
    +    for (i = decPos = 0; i < nDecorations;) {
    +      var startPos = decorations[i];
    +      // Conflate all adjacent decorations that use the same style.
    +      var startDec = decorations[i + 1];
    +      var end = i + 2;
    +      while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
    +        end += 2;
    +      }
    +      decorations[decPos++] = startPos;
    +      decorations[decPos++] = startDec;
    +      i = end;
    +    }
    +
    +    nDecorations = decorations.length = decPos;
    +
    +    var sourceNode = job.sourceNode;
    +    var oldDisplay;
    +    if (sourceNode) {
    +      oldDisplay = sourceNode.style.display;
    +      sourceNode.style.display = 'none';
    +    }
    +    try {
    +      var decoration = null;
    +      while (spanIndex < nSpans) {
    +        var spanStart = spans[spanIndex];
    +        var spanEnd = spans[spanIndex + 2] || sourceLength;
    +
    +        var decEnd = decorations[decorationIndex + 2] || sourceLength;
    +
    +        var end = Math.min(spanEnd, decEnd);
    +
    +        var textNode = spans[spanIndex + 1];
    +        var styledText;
    +        if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
    +            // Don't introduce spans around empty text nodes.
    +            && (styledText = source.substring(sourceIndex, end))) {
    +          // This may seem bizarre, and it is.  Emitting LF on IE causes the
    +          // code to display with spaces instead of line breaks.
    +          // Emitting Windows standard issue linebreaks (CRLF) causes a blank
    +          // space to appear at the beginning of every line but the first.
    +          // Emitting an old Mac OS 9 line separator makes everything spiffy.
    +          if (isIE8OrEarlier) {
    +            styledText = styledText.replace(newlineRe, '\r');
    +          }
    +          textNode.nodeValue = styledText;
    +          var document = textNode.ownerDocument;
    +          var span = document.createElement('span');
    +          span.className = decorations[decorationIndex + 1];
    +          var parentNode = textNode.parentNode;
    +          parentNode.replaceChild(span, textNode);
    +          span.appendChild(textNode);
    +          if (sourceIndex < spanEnd) {  // Split off a text node.
    +            spans[spanIndex + 1] = textNode
    +                // TODO: Possibly optimize by using '' if there's no flicker.
    +                = document.createTextNode(source.substring(end, spanEnd));
    +            parentNode.insertBefore(textNode, span.nextSibling);
    +          }
    +        }
    +
    +        sourceIndex = end;
    +
    +        if (sourceIndex >= spanEnd) {
    +          spanIndex += 2;
    +        }
    +        if (sourceIndex >= decEnd) {
    +          decorationIndex += 2;
    +        }
    +      }
    +    } finally {
    +      if (sourceNode) {
    +        sourceNode.style.display = oldDisplay;
    +      }
    +    }
    +  }
    +
    +  /** Maps language-specific file extensions to handlers. */
    +  var langHandlerRegistry = {};
    +  /** Register a language handler for the given file extensions.
    +    * @param {function (Object)} handler a function from source code to a list
    +    *      of decorations.  Takes a single argument job which describes the
    +    *      state of the computation.   The single parameter has the form
    +    *      {@code {
    +    *        sourceCode: {string} as plain text.
    +    *        decorations: {Array.<number|string>} an array of style classes
    +    *                     preceded by the position at which they start in
    +    *                     job.sourceCode in order.
    +    *                     The language handler should assigned this field.
    +    *        basePos: {int} the position of source in the larger source chunk.
    +    *                 All positions in the output decorations array are relative
    +    *                 to the larger source chunk.
    +    *      } }
    +    * @param {Array.<string>} fileExtensions
    +    */
    +  function registerLangHandler(handler, fileExtensions) {
    +    for (var i = fileExtensions.length; --i >= 0;) {
    +      var ext = fileExtensions[i];
    +      if (!langHandlerRegistry.hasOwnProperty(ext)) {
    +        langHandlerRegistry[ext] = handler;
    +      } else if (win['console']) {
    +        console['warn']('cannot override language handler %s', ext);
    +      }
    +    }
    +  }
    +  function langHandlerForExtension(extension, source) {
    +    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
    +      // Treat it as markup if the first non whitespace character is a < and
    +      // the last non-whitespace character is a >.
    +      extension = /^\s*</.test(source)
    +          ? 'default-markup'
    +          : 'default-code';
    +    }
    +    return langHandlerRegistry[extension];
    +  }
    +  registerLangHandler(decorateSource, ['default-code']);
    +  registerLangHandler(
    +      createSimpleLexer(
    +          [],
    +          [
    +           [PR_PLAIN,       /^[^<?]+/],
    +           [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
    +           [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
    +           // Unescaped content in an unknown language
    +           ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
    +           ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
    +           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
    +           ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
    +           // Unescaped content in javascript.  (Or possibly vbscript).
    +           ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
    +           // Contains unescaped stylesheet content
    +           ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
    +           ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
    +          ]),
    +      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
    +  registerLangHandler(
    +      createSimpleLexer(
    +          [
    +           [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
    +           [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
    +           ],
    +          [
    +           [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
    +           [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
    +           ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
    +           [PR_PUNCTUATION,  /^[=<>\/]+/],
    +           ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
    +           ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
    +           ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
    +           ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
    +           ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
    +           ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
    +           ]),
    +      ['in.tag']);
    +  registerLangHandler(
    +      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': CPP_KEYWORDS,
    +          'hashComments': true,
    +          'cStyleComments': true,
    +          'types': C_TYPES
    +        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': 'null,true,false'
    +        }), ['json']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': CSHARP_KEYWORDS,
    +          'hashComments': true,
    +          'cStyleComments': true,
    +          'verbatimStrings': true,
    +          'types': C_TYPES
    +        }), ['cs']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': JAVA_KEYWORDS,
    +          'cStyleComments': true
    +        }), ['java']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': SH_KEYWORDS,
    +          'hashComments': true,
    +          'multiLineStrings': true
    +        }), ['bash', 'bsh', 'csh', 'sh']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': PYTHON_KEYWORDS,
    +          'hashComments': true,
    +          'multiLineStrings': true,
    +          'tripleQuotedStrings': true
    +        }), ['cv', 'py', 'python']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': PERL_KEYWORDS,
    +          'hashComments': true,
    +          'multiLineStrings': true,
    +          'regexLiterals': 2  // multiline regex literals
    +        }), ['perl', 'pl', 'pm']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': RUBY_KEYWORDS,
    +          'hashComments': true,
    +          'multiLineStrings': true,
    +          'regexLiterals': true
    +        }), ['rb', 'ruby']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': JSCRIPT_KEYWORDS,
    +          'cStyleComments': true,
    +          'regexLiterals': true
    +        }), ['javascript', 'js']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': COFFEE_KEYWORDS,
    +          'hashComments': 3,  // ### style block comments
    +          'cStyleComments': true,
    +          'multilineStrings': true,
    +          'tripleQuotedStrings': true,
    +          'regexLiterals': true
    +        }), ['coffee']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': RUST_KEYWORDS,
    +          'cStyleComments': true,
    +          'multilineStrings': true
    +        }), ['rc', 'rs', 'rust']);
    +  registerLangHandler(
    +      createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
    +
    +  function applyDecorator(job) {
    +    var opt_langExtension = job.langExtension;
    +
    +    try {
    +      // Extract tags, and convert the source code to plain text.
    +      var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
    +      /** Plain text. @type {string} */
    +      var source = sourceAndSpans.sourceCode;
    +      job.sourceCode = source;
    +      job.spans = sourceAndSpans.spans;
    +      job.basePos = 0;
    +
    +      // Apply the appropriate language handler
    +      langHandlerForExtension(opt_langExtension, source)(job);
    +
    +      // Integrate the decorations and tags back into the source code,
    +      // modifying the sourceNode in place.
    +      recombineTagsAndDecorations(job);
    +    } catch (e) {
    +      if (win['console']) {
    +        console['log'](e && e['stack'] || e);
    +      }
    +    }
    +  }
    +
    +  /**
    +   * Pretty print a chunk of code.
    +   * @param sourceCodeHtml {string} The HTML to pretty print.
    +   * @param opt_langExtension {string} The language name to use.
    +   *     Typically, a filename extension like 'cpp' or 'java'.
    +   * @param opt_numberLines {number|boolean} True to number lines,
    +   *     or the 1-indexed number of the first line in sourceCodeHtml.
    +   */
    +  function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
    +    var container = document.createElement('div');
    +    // This could cause images to load and onload listeners to fire.
    +    // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
    +    // We assume that the inner HTML is from a trusted source.
    +    // The pre-tag is required for IE8 which strips newlines from innerHTML
    +    // when it is injected into a <pre> tag.
    +    // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
    +    // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
    +    container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';
    +    container = container.firstChild;
    +    if (opt_numberLines) {
    +      numberLines(container, opt_numberLines, true);
    +    }
    +
    +    var job = {
    +      langExtension: opt_langExtension,
    +      numberLines: opt_numberLines,
    +      sourceNode: container,
    +      pre: 1
    +    };
    +    applyDecorator(job);
    +    return container.innerHTML;
    +  }
    +
    +   /**
    +    * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    +    * {@code class=prettyprint} and prettify them.
    +    *
    +    * @param {Function} opt_whenDone called when prettifying is done.
    +    * @param {HTMLElement|HTMLDocument} opt_root an element or document
    +    *   containing all the elements to pretty print.
    +    *   Defaults to {@code document.body}.
    +    */
    +  function $prettyPrint(opt_whenDone, opt_root) {
    +    var root = opt_root || document.body;
    +    var doc = root.ownerDocument || document;
    +    function byTagName(tn) { return root.getElementsByTagName(tn); }
    +    // fetch a list of nodes to rewrite
    +    var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
    +    var elements = [];
    +    for (var i = 0; i < codeSegments.length; ++i) {
    +      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
    +        elements.push(codeSegments[i][j]);
    +      }
    +    }
    +    codeSegments = null;
    +
    +    var clock = Date;
    +    if (!clock['now']) {
    +      clock = { 'now': function () { return +(new Date); } };
    +    }
    +
    +    // The loop is broken into a series of continuations to make sure that we
    +    // don't make the browser unresponsive when rewriting a large page.
    +    var k = 0;
    +    var prettyPrintingJob;
    +
    +    var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
    +    var prettyPrintRe = /\bprettyprint\b/;
    +    var prettyPrintedRe = /\bprettyprinted\b/;
    +    var preformattedTagNameRe = /pre|xmp/i;
    +    var codeRe = /^code$/i;
    +    var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
    +    var EMPTY = {};
    +
    +    function doWork() {
    +      var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
    +                     clock['now']() + 250 /* ms */ :
    +                     Infinity);
    +      for (; k < elements.length && clock['now']() < endTime; k++) {
    +        var cs = elements[k];
    +
    +        // Look for a preceding comment like
    +        // <?prettify lang="..." linenums="..."?>
    +        var attrs = EMPTY;
    +        {
    +          for (var preceder = cs; (preceder = preceder.previousSibling);) {
    +            var nt = preceder.nodeType;
    +            // <?foo?> is parsed by HTML 5 to a comment node (8)
    +            // like <!--?foo?-->, but in XML is a processing instruction
    +            var value = (nt === 7 || nt === 8) && preceder.nodeValue;
    +            if (value
    +                ? !/^\??prettify\b/.test(value)
    +                : (nt !== 3 || /\S/.test(preceder.nodeValue))) {
    +              // Skip over white-space text nodes but not others.
    +              break;
    +            }
    +            if (value) {
    +              attrs = {};
    +              value.replace(
    +                  /\b(\w+)=([\w:.%+-]+)/g,
    +                function (_, name, value) { attrs[name] = value; });
    +              break;
    +            }
    +          }
    +        }
    +
    +        var className = cs.className;
    +        if ((attrs !== EMPTY || prettyPrintRe.test(className))
    +            // Don't redo this if we've already done it.
    +            // This allows recalling pretty print to just prettyprint elements
    +            // that have been added to the page since last call.
    +            && !prettyPrintedRe.test(className)) {
    +
    +          // make sure this is not nested in an already prettified element
    +          var nested = false;
    +          for (var p = cs.parentNode; p; p = p.parentNode) {
    +            var tn = p.tagName;
    +            if (preCodeXmpRe.test(tn)
    +                && p.className && prettyPrintRe.test(p.className)) {
    +              nested = true;
    +              break;
    +            }
    +          }
    +          if (!nested) {
    +            // Mark done.  If we fail to prettyprint for whatever reason,
    +            // we shouldn't try again.
    +            cs.className += ' prettyprinted';
    +
    +            // If the classes includes a language extensions, use it.
    +            // Language extensions can be specified like
    +            //     <pre class="prettyprint lang-cpp">
    +            // the language extension "cpp" is used to find a language handler
    +            // as passed to PR.registerLangHandler.
    +            // HTML5 recommends that a language be specified using "language-"
    +            // as the prefix instead.  Google Code Prettify supports both.
    +            // http://dev.w3.org/html5/spec-author-view/the-code-element.html
    +            var langExtension = attrs['lang'];
    +            if (!langExtension) {
    +              langExtension = className.match(langExtensionRe);
    +              // Support <pre class="prettyprint"><code class="language-c">
    +              var wrapper;
    +              if (!langExtension && (wrapper = childContentWrapper(cs))
    +                  && codeRe.test(wrapper.tagName)) {
    +                langExtension = wrapper.className.match(langExtensionRe);
    +              }
    +
    +              if (langExtension) { langExtension = langExtension[1]; }
    +            }
    +
    +            var preformatted;
    +            if (preformattedTagNameRe.test(cs.tagName)) {
    +              preformatted = 1;
    +            } else {
    +              var currentStyle = cs['currentStyle'];
    +              var defaultView = doc.defaultView;
    +              var whitespace = (
    +                  currentStyle
    +                  ? currentStyle['whiteSpace']
    +                  : (defaultView
    +                     && defaultView.getComputedStyle)
    +                  ? defaultView.getComputedStyle(cs, null)
    +                  .getPropertyValue('white-space')
    +                  : 0);
    +              preformatted = whitespace
    +                  && 'pre' === whitespace.substring(0, 3);
    +            }
    +
    +            // Look for a class like linenums or linenums:<n> where <n> is the
    +            // 1-indexed number of the first line.
    +            var lineNums = attrs['linenums'];
    +            if (!(lineNums = lineNums === 'true' || +lineNums)) {
    +              lineNums = className.match(/\blinenums\b(?::(\d+))?/);
    +              lineNums =
    +                lineNums
    +                ? lineNums[1] && lineNums[1].length
    +                  ? +lineNums[1] : true
    +                : false;
    +            }
    +            if (lineNums) { numberLines(cs, lineNums, preformatted); }
    +
    +            // do the pretty printing
    +            prettyPrintingJob = {
    +              langExtension: langExtension,
    +              sourceNode: cs,
    +              numberLines: lineNums,
    +              pre: preformatted
    +            };
    +            applyDecorator(prettyPrintingJob);
    +          }
    +        }
    +      }
    +      if (k < elements.length) {
    +        // finish up in a continuation
    +        setTimeout(doWork, 250);
    +      } else if ('function' === typeof opt_whenDone) {
    +        opt_whenDone();
    +      }
    +    }
    +
    +    doWork();
    +  }
    +
    +  /**
    +   * Contains functions for creating and registering new language handlers.
    +   * @type {Object}
    +   */
    +  var PR = win['PR'] = {
    +        'createSimpleLexer': createSimpleLexer,
    +        'registerLangHandler': registerLangHandler,
    +        'sourceDecorator': sourceDecorator,
    +        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
    +        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
    +        'PR_COMMENT': PR_COMMENT,
    +        'PR_DECLARATION': PR_DECLARATION,
    +        'PR_KEYWORD': PR_KEYWORD,
    +        'PR_LITERAL': PR_LITERAL,
    +        'PR_NOCODE': PR_NOCODE,
    +        'PR_PLAIN': PR_PLAIN,
    +        'PR_PUNCTUATION': PR_PUNCTUATION,
    +        'PR_SOURCE': PR_SOURCE,
    +        'PR_STRING': PR_STRING,
    +        'PR_TAG': PR_TAG,
    +        'PR_TYPE': PR_TYPE,
    +        'prettyPrintOne':
    +           IN_GLOBAL_SCOPE
    +             ? (win['prettyPrintOne'] = $prettyPrintOne)
    +             : (prettyPrintOne = $prettyPrintOne),
    +        'prettyPrint': prettyPrint =
    +           IN_GLOBAL_SCOPE
    +             ? (win['prettyPrint'] = $prettyPrint)
    +             : (prettyPrint = $prettyPrint)
    +      };
    +
    +  // Make PR available via the Asynchronous Module Definition (AMD) API.
    +  // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
    +  // The Asynchronous Module Definition (AMD) API specifies a
    +  // mechanism for defining modules such that the module and its
    +  // dependencies can be asynchronously loaded.
    +  // ...
    +  // To allow a clear indicator that a global define function (as
    +  // needed for script src browser loading) conforms to the AMD API,
    +  // any global define function SHOULD have a property called "amd"
    +  // whose value is an object. This helps avoid conflict with any
    +  // other existing JavaScript code that could have defined a define()
    +  // function that does not conform to the AMD API.
    +  if (typeof define === "function" && define['amd']) {
    +    define("google-code-prettify", [], function () {
    +      return PR;
    +    });
    +  }
    +})();
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/srcviewer/contrib/showdown.js b/deployment-apps/metricator-for-nmon/appserver/static/components/srcviewer/contrib/showdown.js
    new file mode 100644
    index 0000000..a2ca6ed
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/srcviewer/contrib/showdown.js
    @@ -0,0 +1,1454 @@
    +//
    +// showdown.js -- A javascript port of Markdown.
    +//
    +// Copyright (c) 2007 John Fraser.
    +//
    +// Original Markdown Copyright (c) 2004-2005 John Gruber
    +//   <http://daringfireball.net/projects/markdown/>
    +//
    +// Redistributable under a BSD-style open source license.
    +// See license.txt for more information.
    +//
    +// The full source distribution is at:
    +//
    +//				A A L
    +//				T C A
    +//				T K B
    +//
    +//   <http://www.attacklab.net/>
    +//
    +
    +//
    +// Wherever possible, Showdown is a straight, line-by-line port
    +// of the Perl version of Markdown.
    +//
    +// This is not a normal parser design; it's basically just a
    +// series of string substitutions.  It's hard to read and
    +// maintain this way,  but keeping Showdown close to the original
    +// design makes it easier to port new features.
    +//
    +// More importantly, Showdown behaves like markdown.pl in most
    +// edge cases.  So web applications can do client-side preview
    +// in Javascript, and then build identical HTML on the server.
    +//
    +// This port needs the new RegExp functionality of ECMA 262,
    +// 3rd Edition (i.e. Javascript 1.5).  Most modern web browsers
    +// should do fine.  Even with the new regular expression features,
    +// We do a lot of work to emulate Perl's regex functionality.
    +// The tricky changes in this file mostly have the "attacklab:"
    +// label.  Major or self-explanatory changes don't.
    +//
    +// Smart diff tools like Araxis Merge will be able to match up
    +// this file with markdown.pl in a useful way.  A little tweaking
    +// helps: in a copy of markdown.pl, replace "#" with "//" and
    +// replace "$text" with "text".  Be sure to ignore whitespace
    +// and line endings.
    +//
    +
    +
    +//
    +// Showdown usage:
    +//
    +//   var text = "Markdown *rocks*.";
    +//
    +//   var converter = new Showdown.converter();
    +//   var html = converter.makeHtml(text);
    +//
    +//   alert(html);
    +//
    +// Note: move the sample code to the bottom of this
    +// file before uncommenting it.
    +//
    +
    +
    +//
    +// Showdown namespace
    +//
    +var Showdown = { extensions: {} };
    +
    +//
    +// forEach
    +//
    +var forEach = Showdown.forEach = function(obj, callback) {
    +	if (typeof obj.forEach === 'function') {
    +		obj.forEach(callback);
    +	} else {
    +		var i, len = obj.length;
    +		for (i = 0; i < len; i++) {
    +			callback(obj[i], i, obj);
    +		}
    +	}
    +};
    +
    +//
    +// Standard extension naming
    +//
    +var stdExtName = function(s) {
    +	return s.replace(/[_-]||\s/g, '').toLowerCase();
    +};
    +
    +//
    +// converter
    +//
    +// Wraps all "globals" so that the only thing
    +// exposed is makeHtml().
    +//
    +Showdown.converter = function(converter_options) {
    +
    +//
    +// Globals:
    +//
    +
    +// Global hashes, used by various utility routines
    +var g_urls;
    +var g_titles;
    +var g_html_blocks;
    +
    +// Used to track when we're inside an ordered or unordered list
    +// (see _ProcessListItems() for details):
    +var g_list_level = 0;
    +
    +// Global extensions
    +var g_lang_extensions = [];
    +var g_output_modifiers = [];
    +
    +
    +//
    +// Automatic Extension Loading (node only):
    +//
    +
    +if (typeof module !== 'undefind' && typeof exports !== 'undefined' && typeof require !== 'undefind') {
    +	var fs = require('fs');
    +
    +	if (fs) {
    +		// Search extensions folder
    +		var extensions = fs.readdirSync((__dirname || '.')+'/extensions').filter(function(file){
    +			return ~file.indexOf('.js');
    +		}).map(function(file){
    +			return file.replace(/\.js$/, '');
    +		});
    +		// Load extensions into Showdown namespace
    +		Showdown.forEach(extensions, function(ext){
    +			var name = stdExtName(ext);
    +			Showdown.extensions[name] = require('./extensions/' + ext);
    +		});
    +	}
    +}
    +
    +this.makeHtml = function(text) {
    +//
    +// Main function. The order in which other subs are called here is
    +// essential. Link and image substitutions need to happen before
    +// _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the <a>
    +// and <img> tags get encoded.
    +//
    +
    +	// Clear the global hashes. If we don't clear these, you get conflicts
    +	// from other articles when generating a page which contains more than
    +	// one article (e.g. an index page that shows the N most recent
    +	// articles):
    +	g_urls = {};
    +	g_titles = {};
    +	g_html_blocks = [];
    +
    +	// attacklab: Replace ~ with ~T
    +	// This lets us use tilde as an escape char to avoid md5 hashes
    +	// The choice of character is arbitray; anything that isn't
    +	// magic in Markdown will work.
    +	text = text.replace(/~/g,"~T");
    +
    +	// attacklab: Replace $ with ~D
    +	// RegExp interprets $ as a special character
    +	// when it's in a replacement string
    +	text = text.replace(/\$/g,"~D");
    +
    +	// Standardize line endings
    +	text = text.replace(/\r\n/g,"\n"); // DOS to Unix
    +	text = text.replace(/\r/g,"\n"); // Mac to Unix
    +
    +	// Make sure text begins and ends with a couple of newlines:
    +	text = "\n\n" + text + "\n\n";
    +
    +	// Convert all tabs to spaces.
    +	text = _Detab(text);
    +
    +	// Strip any lines consisting only of spaces and tabs.
    +	// This makes subsequent regexen easier to write, because we can
    +	// match consecutive blank lines with /\n+/ instead of something
    +	// contorted like /[ \t]*\n+/ .
    +	text = text.replace(/^[ \t]+$/mg,"");
    +
    +	// Run language extensions
    +	Showdown.forEach(g_lang_extensions, function(x){
    +		text = _ExecuteExtension(x, text);
    +	});
    +
    +	// Handle github codeblocks prior to running HashHTML so that
    +	// HTML contained within the codeblock gets escaped propertly
    +	text = _DoGithubCodeBlocks(text);
    +
    +	// Turn block-level HTML blocks into hash entries
    +	text = _HashHTMLBlocks(text);
    +
    +	// Strip link definitions, store in hashes.
    +	text = _StripLinkDefinitions(text);
    +
    +	text = _RunBlockGamut(text);
    +
    +	text = _UnescapeSpecialChars(text);
    +
    +	// attacklab: Restore dollar signs
    +	text = text.replace(/~D/g,"$$");
    +
    +	// attacklab: Restore tildes
    +	text = text.replace(/~T/g,"~");
    +
    +	// Run output modifiers
    +	Showdown.forEach(g_output_modifiers, function(x){
    +		text = _ExecuteExtension(x, text);
    +	});
    +
    +	return text;
    +};
    +//
    +// Options:
    +//
    +
    +// Parse extensions options into separate arrays
    +if (converter_options && converter_options.extensions) {
    +
    +  var self = this;
    +
    +	// Iterate over each plugin
    +	Showdown.forEach(converter_options.extensions, function(plugin){
    +
    +		// Assume it's a bundled plugin if a string is given
    +		if (typeof plugin === 'string') {
    +			plugin = Showdown.extensions[stdExtName(plugin)];
    +		}
    +
    +		if (typeof plugin === 'function') {
    +			// Iterate over each extension within that plugin
    +			Showdown.forEach(plugin(self), function(ext){
    +				// Sort extensions by type
    +				if (ext.type) {
    +					if (ext.type === 'language' || ext.type === 'lang') {
    +						g_lang_extensions.push(ext);
    +					} else if (ext.type === 'output' || ext.type === 'html') {
    +						g_output_modifiers.push(ext);
    +					}
    +				} else {
    +					// Assume language extension
    +					g_output_modifiers.push(ext);
    +				}
    +			});
    +		} else {
    +			throw "Extension '" + plugin + "' could not be loaded.  It was either not found or is not a valid extension.";
    +		}
    +	});
    +}
    +
    +
    +var _ExecuteExtension = function(ext, text) {
    +	if (ext.regex) {
    +		var re = new RegExp(ext.regex, 'g');
    +		return text.replace(re, ext.replace);
    +	} else if (ext.filter) {
    +		return ext.filter(text);
    +	}
    +};
    +
    +var _StripLinkDefinitions = function(text) {
    +//
    +// Strips link definitions from text, stores the URLs and titles in
    +// hash references.
    +//
    +
    +	// Link defs are in the form: ^[id]: url "optional title"
    +
    +	/*
    +		var text = text.replace(/
    +				^[ ]{0,3}\[(.+)\]:  // id = $1  attacklab: g_tab_width - 1
    +				  [ \t]*
    +				  \n?				// maybe *one* newline
    +				  [ \t]*
    +				<?(\S+?)>?			// url = $2
    +				  [ \t]*
    +				  \n?				// maybe one newline
    +				  [ \t]*
    +				(?:
    +				  (\n*)				// any lines skipped = $3 attacklab: lookbehind removed
    +				  ["(]
    +				  (.+?)				// title = $4
    +				  [")]
    +				  [ \t]*
    +				)?					// title is optional
    +				(?:\n+|$)
    +			  /gm,
    +			  function(){...});
    +	*/
    +
    +	// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
    +	text += "~0";
    +
    +	text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|(?=~0))/gm,
    +		function (wholeMatch,m1,m2,m3,m4) {
    +			m1 = m1.toLowerCase();
    +			g_urls[m1] = _EncodeAmpsAndAngles(m2);  // Link IDs are case-insensitive
    +			if (m3) {
    +				// Oops, found blank lines, so it's not a title.
    +				// Put back the parenthetical statement we stole.
    +				return m3+m4;
    +			} else if (m4) {
    +				g_titles[m1] = m4.replace(/"/g,"&quot;");
    +			}
    +
    +			// Completely remove the definition from the text
    +			return "";
    +		}
    +	);
    +
    +	// attacklab: strip sentinel
    +	text = text.replace(/~0/,"");
    +
    +	return text;
    +}
    +
    +
    +var _HashHTMLBlocks = function(text) {
    +	// attacklab: Double up blank lines to reduce lookaround
    +	text = text.replace(/\n/g,"\n\n");
    +
    +	// Hashify HTML blocks:
    +	// We only want to do this for block-level HTML tags, such as headers,
    +	// lists, and tables. That's because we still want to wrap <p>s around
    +	// "paragraphs" that are wrapped in non-block-level tags, such as anchors,
    +	// phrase emphasis, and spans. The list of tags we're looking for is
    +	// hard-coded:
    +	var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del|style|section|header|footer|nav|article|aside";
    +	var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside";
    +
    +	// First, look for nested blocks, e.g.:
    +	//   <div>
    +	//     <div>
    +	//     tags for inner block must be indented.
    +	//     </div>
    +	//   </div>
    +	//
    +	// The outermost tags must start at the left margin for this to match, and
    +	// the inner nested divs must be indented.
    +	// We need to do this before the next, more liberal match, because the next
    +	// match will start at the first `<div>` and stop at the first `</div>`.
    +
    +	// attacklab: This regex can be expensive when it fails.
    +	/*
    +		var text = text.replace(/
    +		(						// save in $1
    +			^					// start of line  (with /m)
    +			<($block_tags_a)	// start tag = $2
    +			\b					// word break
    +								// attacklab: hack around khtml/pcre bug...
    +			[^\r]*?\n			// any number of lines, minimally matching
    +			</\2>				// the matching end tag
    +			[ \t]*				// trailing spaces/tabs
    +			(?=\n+)				// followed by a newline
    +		)						// attacklab: there are sentinel newlines at end of document
    +		/gm,function(){...}};
    +	*/
    +	text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,hashElement);
    +
    +	//
    +	// Now match more liberally, simply from `\n<tag>` to `</tag>\n`
    +	//
    +
    +	/*
    +		var text = text.replace(/
    +		(						// save in $1
    +			^					// start of line  (with /m)
    +			<($block_tags_b)	// start tag = $2
    +			\b					// word break
    +								// attacklab: hack around khtml/pcre bug...
    +			[^\r]*?				// any number of lines, minimally matching
    +			</\2>				// the matching end tag
    +			[ \t]*				// trailing spaces/tabs
    +			(?=\n+)				// followed by a newline
    +		)						// attacklab: there are sentinel newlines at end of document
    +		/gm,function(){...}};
    +	*/
    +	text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside)\b[^\r]*?<\/\2>[ \t]*(?=\n+)\n)/gm,hashElement);
    +
    +	// Special case just for <hr />. It was easier to make a special case than
    +	// to make the other regex more complicated.
    +
    +	/*
    +		text = text.replace(/
    +		(						// save in $1
    +			\n\n				// Starting after a blank line
    +			[ ]{0,3}
    +			(<(hr)				// start tag = $2
    +			\b					// word break
    +			([^<>])*?			//
    +			\/?>)				// the matching end tag
    +			[ \t]*
    +			(?=\n{2,})			// followed by a blank line
    +		)
    +		/g,hashElement);
    +	*/
    +	text = text.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,hashElement);
    +
    +	// Special case for standalone HTML comments:
    +
    +	/*
    +		text = text.replace(/
    +		(						// save in $1
    +			\n\n				// Starting after a blank line
    +			[ ]{0,3}			// attacklab: g_tab_width - 1
    +			<!
    +			(--[^\r]*?--\s*)+
    +			>
    +			[ \t]*
    +			(?=\n{2,})			// followed by a blank line
    +		)
    +		/g,hashElement);
    +	*/
    +	text = text.replace(/(\n\n[ ]{0,3}<!(--[^\r]*?--\s*)+>[ \t]*(?=\n{2,}))/g,hashElement);
    +
    +	// PHP and ASP-style processor instructions (<?...?> and <%...%>)
    +
    +	/*
    +		text = text.replace(/
    +		(?:
    +			\n\n				// Starting after a blank line
    +		)
    +		(						// save in $1
    +			[ ]{0,3}			// attacklab: g_tab_width - 1
    +			(?:
    +				<([?%])			// $2
    +				[^\r]*?
    +				\2>
    +			)
    +			[ \t]*
    +			(?=\n{2,})			// followed by a blank line
    +		)
    +		/g,hashElement);
    +	*/
    +	text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,hashElement);
    +
    +	// attacklab: Undo double lines (see comment at top of this function)
    +	text = text.replace(/\n\n/g,"\n");
    +	return text;
    +}
    +
    +var hashElement = function(wholeMatch,m1) {
    +	var blockText = m1;
    +
    +	// Undo double lines
    +	blockText = blockText.replace(/\n\n/g,"\n");
    +	blockText = blockText.replace(/^\n/,"");
    +
    +	// strip trailing blank lines
    +	blockText = blockText.replace(/\n+$/g,"");
    +
    +	// Replace the element text with a marker ("~KxK" where x is its key)
    +	blockText = "\n\n~K" + (g_html_blocks.push(blockText)-1) + "K\n\n";
    +
    +	return blockText;
    +};
    +
    +var _RunBlockGamut = function(text) {
    +//
    +// These are all the transformations that form block-level
    +// tags like paragraphs, headers, and list items.
    +//
    +	text = _DoHeaders(text);
    +
    +	// Do Horizontal Rules:
    +	var key = hashBlock("<hr />");
    +	text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,key);
    +	text = text.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm,key);
    +	text = text.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm,key);
    +
    +	text = _DoLists(text);
    +	text = _DoCodeBlocks(text);
    +	text = _DoBlockQuotes(text);
    +
    +	// We already ran _HashHTMLBlocks() before, in Markdown(), but that
    +	// was to escape raw HTML in the original Markdown source. This time,
    +	// we're escaping the markup we've just created, so that we don't wrap
    +	// <p> tags around block-level tags.
    +	text = _HashHTMLBlocks(text);
    +	text = _FormParagraphs(text);
    +
    +	return text;
    +};
    +
    +
    +var _RunSpanGamut = function(text) {
    +//
    +// These are all the transformations that occur *within* block-level
    +// tags like paragraphs, headers, and list items.
    +//
    +
    +	text = _DoCodeSpans(text);
    +	text = _EscapeSpecialCharsWithinTagAttributes(text);
    +	text = _EncodeBackslashEscapes(text);
    +
    +	// Process anchor and image tags. Images must come first,
    +	// because ![foo][f] looks like an anchor.
    +	text = _DoImages(text);
    +	text = _DoAnchors(text);
    +
    +	// Make links out of things like `<http://example.com/>`
    +	// Must come after _DoAnchors(), because you can use < and >
    +	// delimiters in inline links like [this](<url>).
    +	text = _DoAutoLinks(text);
    +	text = _EncodeAmpsAndAngles(text);
    +	text = _DoItalicsAndBold(text);
    +
    +	// Do hard breaks:
    +	text = text.replace(/  +\n/g," <br />\n");
    +
    +	return text;
    +}
    +
    +var _EscapeSpecialCharsWithinTagAttributes = function(text) {
    +//
    +// Within tags -- meaning between < and > -- encode [\ ` * _] so they
    +// don't conflict with their use in Markdown for code, italics and strong.
    +//
    +
    +	// Build a regex to find HTML tags and comments.  See Friedl's
    +	// "Mastering Regular Expressions", 2nd Ed., pp. 200-201.
    +	var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)/gi;
    +
    +	text = text.replace(regex, function(wholeMatch) {
    +		var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g,"$1`");
    +		tag = escapeCharacters(tag,"\\`*_");
    +		return tag;
    +	});
    +
    +	return text;
    +}
    +
    +var _DoAnchors = function(text) {
    +//
    +// Turn Markdown link shortcuts into XHTML <a> tags.
    +//
    +	//
    +	// First, handle reference-style links: [link text] [id]
    +	//
    +
    +	/*
    +		text = text.replace(/
    +		(							// wrap whole match in $1
    +			\[
    +			(
    +				(?:
    +					\[[^\]]*\]		// allow brackets nested one level
    +					|
    +					[^\[]			// or anything else
    +				)*
    +			)
    +			\]
    +
    +			[ ]?					// one optional space
    +			(?:\n[ ]*)?				// one optional newline followed by spaces
    +
    +			\[
    +			(.*?)					// id = $3
    +			\]
    +		)()()()()					// pad remaining backreferences
    +		/g,_DoAnchors_callback);
    +	*/
    +	text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeAnchorTag);
    +
    +	//
    +	// Next, inline-style links: [link text](url "optional title")
    +	//
    +
    +	/*
    +		text = text.replace(/
    +			(						// wrap whole match in $1
    +				\[
    +				(
    +					(?:
    +						\[[^\]]*\]	// allow brackets nested one level
    +					|
    +					[^\[\]]			// or anything else
    +				)
    +			)
    +			\]
    +			\(						// literal paren
    +			[ \t]*
    +			()						// no id, so leave $3 empty
    +			<?(.*?)>?				// href = $4
    +			[ \t]*
    +			(						// $5
    +				(['"])				// quote char = $6
    +				(.*?)				// Title = $7
    +				\6					// matching quote
    +				[ \t]*				// ignore any spaces/tabs between closing quote and )
    +			)?						// title is optional
    +			\)
    +		)
    +		/g,writeAnchorTag);
    +	*/
    +	text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?(?:\(.*?\).*?)?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeAnchorTag);
    +
    +	//
    +	// Last, handle reference-style shortcuts: [link text]
    +	// These must come last in case you've also got [link test][1]
    +	// or [link test](/foo)
    +	//
    +
    +	/*
    +		text = text.replace(/
    +		(		 					// wrap whole match in $1
    +			\[
    +			([^\[\]]+)				// link text = $2; can't contain '[' or ']'
    +			\]
    +		)()()()()()					// pad rest of backreferences
    +		/g, writeAnchorTag);
    +	*/
    +	text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag);
    +
    +	return text;
    +}
    +
    +var writeAnchorTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
    +	if (m7 == undefined) m7 = "";
    +	var whole_match = m1;
    +	var link_text   = m2;
    +	var link_id	 = m3.toLowerCase();
    +	var url		= m4;
    +	var title	= m7;
    +
    +	if (url == "") {
    +		if (link_id == "") {
    +			// lower-case and turn embedded newlines into spaces
    +			link_id = link_text.toLowerCase().replace(/ ?\n/g," ");
    +		}
    +		url = "#"+link_id;
    +
    +		if (g_urls[link_id] != undefined) {
    +			url = g_urls[link_id];
    +			if (g_titles[link_id] != undefined) {
    +				title = g_titles[link_id];
    +			}
    +		}
    +		else {
    +			if (whole_match.search(/\(\s*\)$/m)>-1) {
    +				// Special case for explicit empty url
    +				url = "";
    +			} else {
    +				return whole_match;
    +			}
    +		}
    +	}
    +
    +	url = escapeCharacters(url,"*_");
    +	var result = "<a href=\"" + url + "\"";
    +
    +	if (title != "") {
    +		title = title.replace(/"/g,"&quot;");
    +		title = escapeCharacters(title,"*_");
    +		result +=  " title=\"" + title + "\"";
    +	}
    +
    +	result += ">" + link_text + "</a>";
    +
    +	return result;
    +}
    +
    +
    +var _DoImages = function(text) {
    +//
    +// Turn Markdown image shortcuts into <img> tags.
    +//
    +
    +	//
    +	// First, handle reference-style labeled images: ![alt text][id]
    +	//
    +
    +	/*
    +		text = text.replace(/
    +		(						// wrap whole match in $1
    +			!\[
    +			(.*?)				// alt text = $2
    +			\]
    +
    +			[ ]?				// one optional space
    +			(?:\n[ ]*)?			// one optional newline followed by spaces
    +
    +			\[
    +			(.*?)				// id = $3
    +			\]
    +		)()()()()				// pad rest of backreferences
    +		/g,writeImageTag);
    +	*/
    +	text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeImageTag);
    +
    +	//
    +	// Next, handle inline images:  ![alt text](url "optional title")
    +	// Don't forget: encode * and _
    +
    +	/*
    +		text = text.replace(/
    +		(						// wrap whole match in $1
    +			!\[
    +			(.*?)				// alt text = $2
    +			\]
    +			\s?					// One optional whitespace character
    +			\(					// literal paren
    +			[ \t]*
    +			()					// no id, so leave $3 empty
    +			<?(\S+?)>?			// src url = $4
    +			[ \t]*
    +			(					// $5
    +				(['"])			// quote char = $6
    +				(.*?)			// title = $7
    +				\6				// matching quote
    +				[ \t]*
    +			)?					// title is optional
    +		\)
    +		)
    +		/g,writeImageTag);
    +	*/
    +	text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeImageTag);
    +
    +	return text;
    +}
    +
    +var writeImageTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
    +	var whole_match = m1;
    +	var alt_text   = m2;
    +	var link_id	 = m3.toLowerCase();
    +	var url		= m4;
    +	var title	= m7;
    +
    +	if (!title) title = "";
    +
    +	if (url == "") {
    +		if (link_id == "") {
    +			// lower-case and turn embedded newlines into spaces
    +			link_id = alt_text.toLowerCase().replace(/ ?\n/g," ");
    +		}
    +		url = "#"+link_id;
    +
    +		if (g_urls[link_id] != undefined) {
    +			url = g_urls[link_id];
    +			if (g_titles[link_id] != undefined) {
    +				title = g_titles[link_id];
    +			}
    +		}
    +		else {
    +			return whole_match;
    +		}
    +	}
    +
    +	alt_text = alt_text.replace(/"/g,"&quot;");
    +	url = escapeCharacters(url,"*_");
    +	var result = "<img src=\"" + url + "\" alt=\"" + alt_text + "\"";
    +
    +	// attacklab: Markdown.pl adds empty title attributes to images.
    +	// Replicate this bug.
    +
    +	//if (title != "") {
    +		title = title.replace(/"/g,"&quot;");
    +		title = escapeCharacters(title,"*_");
    +		result +=  " title=\"" + title + "\"";
    +	//}
    +
    +	result += " />";
    +
    +	return result;
    +}
    +
    +
    +var _DoHeaders = function(text) {
    +
    +	// Setext-style headers:
    +	//	Header 1
    +	//	========
    +	//
    +	//	Header 2
    +	//	--------
    +	//
    +	text = text.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,
    +		function(wholeMatch,m1){return hashBlock('<h1 id="' + headerId(m1) + '">' + _RunSpanGamut(m1) + "</h1>");});
    +
    +	text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,
    +		function(matchFound,m1){return hashBlock('<h2 id="' + headerId(m1) + '">' + _RunSpanGamut(m1) + "</h2>");});
    +
    +	// atx-style headers:
    +	//  # Header 1
    +	//  ## Header 2
    +	//  ## Header 2 with closing hashes ##
    +	//  ...
    +	//  ###### Header 6
    +	//
    +
    +	/*
    +		text = text.replace(/
    +			^(\#{1,6})				// $1 = string of #'s
    +			[ \t]*
    +			(.+?)					// $2 = Header text
    +			[ \t]*
    +			\#*						// optional closing #'s (not counted)
    +			\n+
    +		/gm, function() {...});
    +	*/
    +
    +	text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,
    +		function(wholeMatch,m1,m2) {
    +			var h_level = m1.length;
    +			return hashBlock("<h" + h_level + ' id="' + headerId(m2) + '">' + _RunSpanGamut(m2) + "</h" + h_level + ">");
    +		});
    +
    +	function headerId(m) {
    +		return m.replace(/[^\w]/g, '').toLowerCase();
    +	}
    +	return text;
    +}
    +
    +// This declaration keeps Dojo compressor from outputting garbage:
    +var _ProcessListItems;
    +
    +var _DoLists = function(text) {
    +//
    +// Form HTML ordered (numbered) and unordered (bulleted) lists.
    +//
    +
    +	// attacklab: add sentinel to hack around khtml/safari bug:
    +	// http://bugs.webkit.org/show_bug.cgi?id=11231
    +	text += "~0";
    +
    +	// Re-usable pattern to match any entirel ul or ol list:
    +
    +	/*
    +		var whole_list = /
    +		(									// $1 = whole list
    +			(								// $2
    +				[ ]{0,3}					// attacklab: g_tab_width - 1
    +				([*+-]|\d+[.])				// $3 = first list item marker
    +				[ \t]+
    +			)
    +			[^\r]+?
    +			(								// $4
    +				~0							// sentinel for workaround; should be $
    +			|
    +				\n{2,}
    +				(?=\S)
    +				(?!							// Negative lookahead for another list item marker
    +					[ \t]*
    +					(?:[*+-]|\d+[.])[ \t]+
    +				)
    +			)
    +		)/g
    +	*/
    +	var whole_list = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
    +
    +	if (g_list_level) {
    +		text = text.replace(whole_list,function(wholeMatch,m1,m2) {
    +			var list = m1;
    +			var list_type = (m2.search(/[*+-]/g)>-1) ? "ul" : "ol";
    +
    +			// Turn double returns into triple returns, so that we can make a
    +			// paragraph for the last item in a list, if necessary:
    +			list = list.replace(/\n{2,}/g,"\n\n\n");;
    +			var result = _ProcessListItems(list);
    +
    +			// Trim any trailing whitespace, to put the closing `</$list_type>`
    +			// up on the preceding line, to get it past the current stupid
    +			// HTML block parser. This is a hack to work around the terrible
    +			// hack that is the HTML block parser.
    +			result = result.replace(/\s+$/,"");
    +			result = "<"+list_type+">" + result + "</"+list_type+">\n";
    +			return result;
    +		});
    +	} else {
    +		whole_list = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g;
    +		text = text.replace(whole_list,function(wholeMatch,m1,m2,m3) {
    +			var runup = m1;
    +			var list = m2;
    +
    +			var list_type = (m3.search(/[*+-]/g)>-1) ? "ul" : "ol";
    +			// Turn double returns into triple returns, so that we can make a
    +			// paragraph for the last item in a list, if necessary:
    +			var list = list.replace(/\n{2,}/g,"\n\n\n");;
    +			var result = _ProcessListItems(list);
    +			result = runup + "<"+list_type+">\n" + result + "</"+list_type+">\n";
    +			return result;
    +		});
    +	}
    +
    +	// attacklab: strip sentinel
    +	text = text.replace(/~0/,"");
    +
    +	return text;
    +}
    +
    +_ProcessListItems = function(list_str) {
    +//
    +//  Process the contents of a single ordered or unordered list, splitting it
    +//  into individual list items.
    +//
    +	// The $g_list_level global keeps track of when we're inside a list.
    +	// Each time we enter a list, we increment it; when we leave a list,
    +	// we decrement. If it's zero, we're not in a list anymore.
    +	//
    +	// We do this because when we're not inside a list, we want to treat
    +	// something like this:
    +	//
    +	//    I recommend upgrading to version
    +	//    8. Oops, now this line is treated
    +	//    as a sub-list.
    +	//
    +	// As a single paragraph, despite the fact that the second line starts
    +	// with a digit-period-space sequence.
    +	//
    +	// Whereas when we're inside a list (or sub-list), that line will be
    +	// treated as the start of a sub-list. What a kludge, huh? This is
    +	// an aspect of Markdown's syntax that's hard to parse perfectly
    +	// without resorting to mind-reading. Perhaps the solution is to
    +	// change the syntax rules such that sub-lists must start with a
    +	// starting cardinal number; e.g. "1." or "a.".
    +
    +	g_list_level++;
    +
    +	// trim trailing blank lines:
    +	list_str = list_str.replace(/\n{2,}$/,"\n");
    +
    +	// attacklab: add sentinel to emulate \z
    +	list_str += "~0";
    +
    +	/*
    +		list_str = list_str.replace(/
    +			(\n)?							// leading line = $1
    +			(^[ \t]*)						// leading whitespace = $2
    +			([*+-]|\d+[.]) [ \t]+			// list marker = $3
    +			([^\r]+?						// list item text   = $4
    +			(\n{1,2}))
    +			(?= \n* (~0 | \2 ([*+-]|\d+[.]) [ \t]+))
    +		/gm, function(){...});
    +	*/
    +	list_str = list_str.replace(/(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+([^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,
    +		function(wholeMatch,m1,m2,m3,m4){
    +			var item = m4;
    +			var leading_line = m1;
    +			var leading_space = m2;
    +
    +			if (leading_line || (item.search(/\n{2,}/)>-1)) {
    +				item = _RunBlockGamut(_Outdent(item));
    +			}
    +			else {
    +				// Recursion for sub-lists:
    +				item = _DoLists(_Outdent(item));
    +				item = item.replace(/\n$/,""); // chomp(item)
    +				item = _RunSpanGamut(item);
    +			}
    +
    +			return  "<li>" + item + "</li>\n";
    +		}
    +	);
    +
    +	// attacklab: strip sentinel
    +	list_str = list_str.replace(/~0/g,"");
    +
    +	g_list_level--;
    +	return list_str;
    +}
    +
    +
    +var _DoCodeBlocks = function(text) {
    +//
    +//  Process Markdown `<pre><code>` blocks.
    +//
    +
    +	/*
    +		text = text.replace(text,
    +			/(?:\n\n|^)
    +			(								// $1 = the code block -- one or more lines, starting with a space/tab
    +				(?:
    +					(?:[ ]{4}|\t)			// Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
    +					.*\n+
    +				)+
    +			)
    +			(\n*[ ]{0,3}[^ \t\n]|(?=~0))	// attacklab: g_tab_width
    +		/g,function(){...});
    +	*/
    +
    +	// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
    +	text += "~0";
    +
    +	text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
    +		function(wholeMatch,m1,m2) {
    +			var codeblock = m1;
    +			var nextChar = m2;
    +
    +			codeblock = _EncodeCode( _Outdent(codeblock));
    +			codeblock = _Detab(codeblock);
    +			codeblock = codeblock.replace(/^\n+/g,""); // trim leading newlines
    +			codeblock = codeblock.replace(/\n+$/g,""); // trim trailing whitespace
    +
    +			codeblock = "<pre><code>" + codeblock + "\n</code></pre>";
    +
    +			return hashBlock(codeblock) + nextChar;
    +		}
    +	);
    +
    +	// attacklab: strip sentinel
    +	text = text.replace(/~0/,"");
    +
    +	return text;
    +};
    +
    +var _DoGithubCodeBlocks = function(text) {
    +//
    +//  Process Github-style code blocks
    +//  Example:
    +//  ```ruby
    +//  def hello_world(x)
    +//    puts "Hello, #{x}"
    +//  end
    +//  ```
    +//
    +
    +
    +	// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
    +	text += "~0";
    +
    +	text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g,
    +		function(wholeMatch,m1,m2) {
    +			var language = m1;
    +			var codeblock = m2;
    +
    +			codeblock = _EncodeCode(codeblock);
    +			codeblock = _Detab(codeblock);
    +			codeblock = codeblock.replace(/^\n+/g,""); // trim leading newlines
    +			codeblock = codeblock.replace(/\n+$/g,""); // trim trailing whitespace
    +
    +			codeblock = "<pre><code" + (language ? " class=\"" + language + '"' : "") + ">" + codeblock + "\n</code></pre>";
    +
    +			return hashBlock(codeblock);
    +		}
    +	);
    +
    +	// attacklab: strip sentinel
    +	text = text.replace(/~0/,"");
    +
    +	return text;
    +}
    +
    +var hashBlock = function(text) {
    +	text = text.replace(/(^\n+|\n+$)/g,"");
    +	return "\n\n~K" + (g_html_blocks.push(text)-1) + "K\n\n";
    +}
    +
    +var _DoCodeSpans = function(text) {
    +//
    +//   *  Backtick quotes are used for <code></code> spans.
    +//
    +//   *  You can use multiple backticks as the delimiters if you want to
    +//	 include literal backticks in the code span. So, this input:
    +//
    +//		 Just type ``foo `bar` baz`` at the prompt.
    +//
    +//	   Will translate to:
    +//
    +//		 <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
    +//
    +//	There's no arbitrary limit to the number of backticks you
    +//	can use as delimters. If you need three consecutive backticks
    +//	in your code, use four for delimiters, etc.
    +//
    +//  *  You can use spaces to get literal backticks at the edges:
    +//
    +//		 ... type `` `bar` `` ...
    +//
    +//	   Turns to:
    +//
    +//		 ... type <code>`bar`</code> ...
    +//
    +
    +	/*
    +		text = text.replace(/
    +			(^|[^\\])					// Character before opening ` can't be a backslash
    +			(`+)						// $2 = Opening run of `
    +			(							// $3 = The code block
    +				[^\r]*?
    +				[^`]					// attacklab: work around lack of lookbehind
    +			)
    +			\2							// Matching closer
    +			(?!`)
    +		/gm, function(){...});
    +	*/
    +
    +	text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
    +		function(wholeMatch,m1,m2,m3,m4) {
    +			var c = m3;
    +			c = c.replace(/^([ \t]*)/g,"");	// leading whitespace
    +			c = c.replace(/[ \t]*$/g,"");	// trailing whitespace
    +			c = _EncodeCode(c);
    +			return m1+"<code>"+c+"</code>";
    +		});
    +
    +	return text;
    +}
    +
    +var _EncodeCode = function(text) {
    +//
    +// Encode/escape certain characters inside Markdown code runs.
    +// The point is that in code, these characters are literals,
    +// and lose their special Markdown meanings.
    +//
    +	// Encode all ampersands; HTML entities are not
    +	// entities within a Markdown code span.
    +	text = text.replace(/&/g,"&amp;");
    +
    +	// Do the angle bracket song and dance:
    +	text = text.replace(/</g,"&lt;");
    +	text = text.replace(/>/g,"&gt;");
    +
    +	// Now, escape characters that are magic in Markdown:
    +	text = escapeCharacters(text,"\*_{}[]\\",false);
    +
    +// jj the line above breaks this:
    +//---
    +
    +//* Item
    +
    +//   1. Subitem
    +
    +//            special char: *
    +//---
    +
    +	return text;
    +}
    +
    +
    +var _DoItalicsAndBold = function(text) {
    +
    +	// <strong> must go first:
    +	text = text.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,
    +		"<strong>$2</strong>");
    +
    +	text = text.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g,
    +		"<em>$2</em>");
    +
    +	return text;
    +}
    +
    +
    +var _DoBlockQuotes = function(text) {
    +
    +	/*
    +		text = text.replace(/
    +		(								// Wrap whole match in $1
    +			(
    +				^[ \t]*>[ \t]?			// '>' at the start of a line
    +				.+\n					// rest of the first line
    +				(.+\n)*					// subsequent consecutive lines
    +				\n*						// blanks
    +			)+
    +		)
    +		/gm, function(){...});
    +	*/
    +
    +	text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,
    +		function(wholeMatch,m1) {
    +			var bq = m1;
    +
    +			// attacklab: hack around Konqueror 3.5.4 bug:
    +			// "----------bug".replace(/^-/g,"") == "bug"
    +
    +			bq = bq.replace(/^[ \t]*>[ \t]?/gm,"~0");	// trim one level of quoting
    +
    +			// attacklab: clean up hack
    +			bq = bq.replace(/~0/g,"");
    +
    +			bq = bq.replace(/^[ \t]+$/gm,"");		// trim whitespace-only lines
    +			bq = _RunBlockGamut(bq);				// recurse
    +
    +			bq = bq.replace(/(^|\n)/g,"$1  ");
    +			// These leading spaces screw with <pre> content, so we need to fix that:
    +			bq = bq.replace(
    +					/(\s*<pre>[^\r]+?<\/pre>)/gm,
    +				function(wholeMatch,m1) {
    +					var pre = m1;
    +					// attacklab: hack around Konqueror 3.5.4 bug:
    +					pre = pre.replace(/^  /mg,"~0");
    +					pre = pre.replace(/~0/g,"");
    +					return pre;
    +				});
    +
    +			return hashBlock("<blockquote>\n" + bq + "\n</blockquote>");
    +		});
    +	return text;
    +}
    +
    +
    +var _FormParagraphs = function(text) {
    +//
    +//  Params:
    +//    $text - string to process with html <p> tags
    +//
    +
    +	// Strip leading and trailing lines:
    +	text = text.replace(/^\n+/g,"");
    +	text = text.replace(/\n+$/g,"");
    +
    +	var grafs = text.split(/\n{2,}/g);
    +	var grafsOut = [];
    +
    +	//
    +	// Wrap <p> tags.
    +	//
    +	var end = grafs.length;
    +	for (var i=0; i<end; i++) {
    +		var str = grafs[i];
    +
    +		// if this is an HTML marker, copy it
    +		if (str.search(/~K(\d+)K/g) >= 0) {
    +			grafsOut.push(str);
    +		}
    +		else if (str.search(/\S/) >= 0) {
    +			str = _RunSpanGamut(str);
    +			str = str.replace(/^([ \t]*)/g,"<p>");
    +			str += "</p>"
    +			grafsOut.push(str);
    +		}
    +
    +	}
    +
    +	//
    +	// Unhashify HTML blocks
    +	//
    +	end = grafsOut.length;
    +	for (var i=0; i<end; i++) {
    +		// if this is a marker for an html block...
    +		while (grafsOut[i].search(/~K(\d+)K/) >= 0) {
    +			var blockText = g_html_blocks[RegExp.$1];
    +			blockText = blockText.replace(/\$/g,"$$$$"); // Escape any dollar signs
    +			grafsOut[i] = grafsOut[i].replace(/~K\d+K/,blockText);
    +		}
    +	}
    +
    +	return grafsOut.join("\n\n");
    +}
    +
    +
    +var _EncodeAmpsAndAngles = function(text) {
    +// Smart processing for ampersands and angle brackets that need to be encoded.
    +
    +	// Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
    +	//   http://bumppo.net/projects/amputator/
    +	text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&amp;");
    +
    +	// Encode naked <'s
    +	text = text.replace(/<(?![a-z\/?\$!])/gi,"&lt;");
    +
    +	return text;
    +}
    +
    +
    +var _EncodeBackslashEscapes = function(text) {
    +//
    +//   Parameter:  String.
    +//   Returns:	The string, with after processing the following backslash
    +//			   escape sequences.
    +//
    +
    +	// attacklab: The polite way to do this is with the new
    +	// escapeCharacters() function:
    +	//
    +	// 	text = escapeCharacters(text,"\\",true);
    +	// 	text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
    +	//
    +	// ...but we're sidestepping its use of the (slow) RegExp constructor
    +	// as an optimization for Firefox.  This function gets called a LOT.
    +
    +	text = text.replace(/\\(\\)/g,escapeCharacters_callback);
    +	text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g,escapeCharacters_callback);
    +	return text;
    +}
    +
    +
    +var _DoAutoLinks = function(text) {
    +
    +	text = text.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"<a href=\"$1\">$1</a>");
    +
    +	// Email addresses: <address@domain.foo>
    +
    +	/*
    +		text = text.replace(/
    +			<
    +			(?:mailto:)?
    +			(
    +				[-.\w]+
    +				\@
    +				[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
    +			)
    +			>
    +		/gi, _DoAutoLinks_callback());
    +	*/
    +	text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
    +		function(wholeMatch,m1) {
    +			return _EncodeEmailAddress( _UnescapeSpecialChars(m1) );
    +		}
    +	);
    +
    +	return text;
    +}
    +
    +
    +var _EncodeEmailAddress = function(addr) {
    +//
    +//  Input: an email address, e.g. "foo@example.com"
    +//
    +//  Output: the email address as a mailto link, with each character
    +//	of the address encoded as either a decimal or hex entity, in
    +//	the hopes of foiling most address harvesting spam bots. E.g.:
    +//
    +//	<a href="&#x6D;&#97;&#105;&#108;&#x74;&#111;:&#102;&#111;&#111;&#64;&#101;
    +//	   x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;">&#102;&#111;&#111;
    +//	   &#64;&#101;x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;</a>
    +//
    +//  Based on a filter by Matthew Wickline, posted to the BBEdit-Talk
    +//  mailing list: <http://tinyurl.com/yu7ue>
    +//
    +
    +	var encode = [
    +		function(ch){return "&#"+ch.charCodeAt(0)+";";},
    +		function(ch){return "&#x"+ch.charCodeAt(0).toString(16)+";";},
    +		function(ch){return ch;}
    +	];
    +
    +	addr = "mailto:" + addr;
    +
    +	addr = addr.replace(/./g, function(ch) {
    +		if (ch == "@") {
    +		   	// this *must* be encoded. I insist.
    +			ch = encode[Math.floor(Math.random()*2)](ch);
    +		} else if (ch !=":") {
    +			// leave ':' alone (to spot mailto: later)
    +			var r = Math.random();
    +			// roughly 10% raw, 45% hex, 45% dec
    +			ch =  (
    +					r > .9  ?	encode[2](ch)   :
    +					r > .45 ?	encode[1](ch)   :
    +								encode[0](ch)
    +				);
    +		}
    +		return ch;
    +	});
    +
    +	addr = "<a href=\"" + addr + "\">" + addr + "</a>";
    +	addr = addr.replace(/">.+:/g,"\">"); // strip the mailto: from the visible part
    +
    +	return addr;
    +}
    +
    +
    +var _UnescapeSpecialChars = function(text) {
    +//
    +// Swap back in all the special characters we've hidden.
    +//
    +	text = text.replace(/~E(\d+)E/g,
    +		function(wholeMatch,m1) {
    +			var charCodeToReplace = parseInt(m1);
    +			return String.fromCharCode(charCodeToReplace);
    +		}
    +	);
    +	return text;
    +}
    +
    +
    +var _Outdent = function(text) {
    +//
    +// Remove one level of line-leading tabs or spaces
    +//
    +
    +	// attacklab: hack around Konqueror 3.5.4 bug:
    +	// "----------bug".replace(/^-/g,"") == "bug"
    +
    +	text = text.replace(/^(\t|[ ]{1,4})/gm,"~0"); // attacklab: g_tab_width
    +
    +	// attacklab: clean up hack
    +	text = text.replace(/~0/g,"")
    +
    +	return text;
    +}
    +
    +var _Detab = function(text) {
    +// attacklab: Detab's completely rewritten for speed.
    +// In perl we could fix it by anchoring the regexp with \G.
    +// In javascript we're less fortunate.
    +
    +	// expand first n-1 tabs
    +	text = text.replace(/\t(?=\t)/g,"    "); // attacklab: g_tab_width
    +
    +	// replace the nth with two sentinels
    +	text = text.replace(/\t/g,"~A~B");
    +
    +	// use the sentinel to anchor our regex so it doesn't explode
    +	text = text.replace(/~B(.+?)~A/g,
    +		function(wholeMatch,m1,m2) {
    +			var leadingText = m1;
    +			var numSpaces = 4 - leadingText.length % 4;  // attacklab: g_tab_width
    +
    +			// there *must* be a better way to do this:
    +			for (var i=0; i<numSpaces; i++) leadingText+=" ";
    +
    +			return leadingText;
    +		}
    +	);
    +
    +	// clean up sentinels
    +	text = text.replace(/~A/g,"    ");  // attacklab: g_tab_width
    +	text = text.replace(/~B/g,"");
    +
    +	return text;
    +}
    +
    +
    +//
    +//  attacklab: Utility functions
    +//
    +
    +
    +var escapeCharacters = function(text, charsToEscape, afterBackslash) {
    +	// First we have to escape the escape characters so that
    +	// we can build a character class out of them
    +	var regexString = "([" + charsToEscape.replace(/([\[\]\\])/g,"\\$1") + "])";
    +
    +	if (afterBackslash) {
    +		regexString = "\\\\" + regexString;
    +	}
    +
    +	var regex = new RegExp(regexString,"g");
    +	text = text.replace(regex,escapeCharacters_callback);
    +
    +	return text;
    +}
    +
    +
    +var escapeCharacters_callback = function(wholeMatch,m1) {
    +	var charCodeToEscape = m1.charCodeAt(0);
    +	return "~E"+charCodeToEscape+"E";
    +}
    +
    +} // end of Showdown.converter
    +
    +
    +// export
    +if (typeof module !== 'undefined') module.exports = Showdown;
    +
    +// stolen from AMD branch of underscore
    +// AMD define happens at the end for compatibility with AMD loaders
    +// that don't enforce next-turn semantics on modules.
    +if (typeof define === 'function' && define.amd) {
    +    define('showdown', function() {
    +        return Showdown;
    +    });
    +}
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/srcviewer/srcviewer.js b/deployment-apps/metricator-for-nmon/appserver/static/components/srcviewer/srcviewer.js
    new file mode 100644
    index 0000000..6169ab5
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/srcviewer/srcviewer.js
    @@ -0,0 +1,106 @@
    +require.config({
    +    paths: {
    +        showdown: '../app/simple_xml_examples/components/srcviewer/contrib/showdown'
    +    }
    +});
    +
    +define([
    +    'underscore',
    +    'jquery',
    +    'backbone',
    +    './codeview',
    +    'showdown',
    +    'bootstrap.tab'
    +], function(_, $, Backbone, CodeView, Showdown) {
    +
    +    var markdown = new Showdown.converter();
    +
    +    var SourceCodeViewer = Backbone.View.extend({
    +        className: 'sourcecode-viewer',
    +        options: {
    +            title: 'Dashboard Source Code'
    +        },
    +        initialize: function(){
    +            this.items = [];
    +            this.listenTo(this.collection, 'reset remove', this.render, this);
    +            this.listenTo(this.collection, 'add', this.addItem, this);
    +            this.listenTo(this.model, 'change', this.render, this);
    +        },
    +        events: {
    +            'click .nav>li>a': function(e){
    +                e.preventDefault();
    +                $(e.currentTarget).tab('show');
    +            }
    +        },
    +        addItem: function(model){
    +            if(!model.has('id')) {
    +                model.set('id', _.uniqueId('tab_'));
    +            }
    +            var id = model.get('id');
    +            var filename = model.get('name');
    +            var fileUrl = model.get('url') || '';
    +            var link = $('<a class="tab-title-text"></a>').text(filename).attr('href', fileUrl + '#' + id)
    +            var li = $('<li></li>').append(link);
    +            this.$('.nav-tabs').append(li);
    +
    +            var item = new CodeView({
    +                model: model,
    +                el: $('<div></div>').appendTo(this.$('.tab-content'))
    +            });
    +            item.render();
    +
    +            if(this.items.length == 0) {
    +                // Activate the tab, if it's the first item
    +                li.find('a').click();
    +            }
    +
    +            this.items.push(item);
    +            return item;
    +        },
    +        render: function(){
    +            _(this.items).invoke('remove');
    +            this.items.length = 0; // Clear items array
    +
    +            var model = _.extend({
    +                _: _,
    +                description: '',
    +                shortDescription: '',
    +                related_links: null
    +            }, this.model.toJSON(), this.options);
    +
    +            if(model.description) {
    +                model.description = markdown.makeHtml(model.description);
    +            }
    +
    +            this.$el.addClass(this.className);
    +            this.$el.html(this.template(model));
    +            this.collection.map(_(this.addItem).bind(this));
    +
    +            return this;
    +        },
    +        template: _.template(
    +            '<div class="dashboard-description">' +
    +                '<div class="description-title"><h3><%= _("Description").t() %></h3></div>' +
    +                '<div class="example-info">' +
    +                    '<p class="description"><%= description %></p>' +
    +                    '<% if(related_links && related_links.length) { %>' +
    +                    '<h5><%= _("Related examples:").t() %></h5>' +
    +                        '<ul class="related-links">' +
    +                            '<% _.each(related_links, function(link) { %>' +
    +                                '<li><a href="<%- link.href %>"><%- link.label %></a></li>' +
    +                            '<% }); %>' +
    +                        '</ul>' +
    +                    '<% } %>' +
    +                '</div>' +
    +            '</div>' +
    +            '<div class="showsource-container">' +
    +                '<ul class="nav nav-tabs">' +
    +                '<li class="nav-title">Source Code</li>' +
    +                '</ul>' +
    +                '<div class="tab-content source-content"></div>' +
    +            '</div>'
    +        )
    +    });
    +
    +    return SourceCodeViewer;
    +});
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/tagcloud/tagcloud.css b/deployment-apps/metricator-for-nmon/appserver/static/components/tagcloud/tagcloud.css
    new file mode 100644
    index 0000000..b30fba4
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/tagcloud/tagcloud.css
    @@ -0,0 +1,12 @@
    +.tagcloud-viz {
    +	text-align: center;
    +	margin: 20px auto;
    +	max-width: 60%;
    +	line-height: 18px;
    +}
    +
    +.tagcloud-viz .link {
    +	padding: 2px 3px;
    +    display: inline-block;
    +    vertical-align: middle;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/tagcloud/tagcloud.js b/deployment-apps/metricator-for-nmon/appserver/static/components/tagcloud/tagcloud.js
    new file mode 100644
    index 0000000..bd69ee7
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/tagcloud/tagcloud.js
    @@ -0,0 +1,72 @@
    +/*
    + * Simple TagCloud visualization
    + * This view is an example for a simple visualization based on search results
    + */
    +define(function(require, module) {
    +    var _ = require('underscore'), $ = require('jquery');
    +    var SimpleSplunkView = require('splunkjs/mvc/simplesplunkview');
    +    var Drilldown = require('splunkjs/mvc/drilldown');
    +    require('css!./tagcloud.css');
    +
    +    var TagCloud = SimpleSplunkView.extend({
    +        moduleId: module.id,
    +        className: 'tagcloud-viz',
    +        options: {
    +            labelField: 'label',
    +            valueField: 'count',
    +            minFontSize: 8,
    +            maxFontSize: 36,
    +            data: 'preview'
    +        },
    +        output_mode: 'json',
    +        events: {
    +            'click a': function(e) {
    +                e.preventDefault();
    +                // Perform automatic drilldown on click on a tag
    +                Drilldown.handleDrilldown({
    +                    name: this.settings.get('labelField'),
    +                    value: $.trim($(e.target).text())
    +                }, 'row', this.manager);
    +            }
    +        },
    +        initialize: function() {
    +            SimpleSplunkView.prototype.initialize.apply(this, arguments);
    +            // Make sure we re-render the visualization when our settings change
    +            this.listenTo(this.settings, 'change:labelField change:valueField change:minFontSize change:maxFontSize', this._updateView);
    +        },
    +        createView: function() {
    +            return true;
    +        },
    +        updateView: function(viz, data) {
    +            var labelField = this.settings.get('labelField');
    +            var valueField = this.settings.get('valueField');
    +            var minFontSize = parseFloat(this.settings.get('minFontSize'));
    +            var maxFontSize = parseFloat(this.settings.get('maxFontSize'));
    +
    +            // Clear the current view
    +            var el = this.$el.empty().css('line-height', Math.ceil(maxFontSize * 0.55) + 'px');
    +            var minMagnitude = Infinity, maxMagnitude = -Infinity;
    +
    +            _(data).chain().map(function(result) {
    +                // Extract and convert the magnitude field value
    +                var magnitude = parseFloat(result[valueField]);
    +                // Find the maximum and minimum of the magnitude field values
    +                minMagnitude = magnitude < minMagnitude ? magnitude : minMagnitude;
    +                maxMagnitude = magnitude > maxMagnitude ? magnitude : maxMagnitude;
    +                return {
    +                    label: result[labelField],
    +                    magnitude: magnitude
    +                };
    +            }).each(function(result) {
    +                        // Calculate relative size of each tag
    +                        var size = minFontSize + ((result.magnitude - minMagnitude) / maxMagnitude * (maxFontSize - minFontSize));
    +                        // Render the tag
    +                        $('<a class="link" href="#" /> ').text(result.label + ' ').css({
    +                            'font-size': size
    +                        }).appendTo(el);
    +                    });
    +        }
    +    });
    +
    +    return TagCloud;
    +});
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/togglepanel/LICENSE b/deployment-apps/metricator-for-nmon/appserver/static/components/togglepanel/LICENSE
    new file mode 100644
    index 0000000..83441df
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/togglepanel/LICENSE
    @@ -0,0 +1,29 @@
    +BSD 3-Clause License
    +
    +Copyright (c) 2016-2017, OctoInsight Inc., All rights reserved.
    +All rights reserved.
    +
    +Redistribution and use in source and binary forms, with or without
    +modification, are permitted provided that the following conditions are met:
    +
    +* Redistributions of source code must retain the above copyright notice, this
    +  list of conditions and the following disclaimer.
    +
    +* Redistributions in binary form must reproduce the above copyright notice,
    +  this list of conditions and the following disclaimer in the documentation
    +  and/or other materials provided with the distribution.
    +
    +* Neither the name of the copyright holder nor the names of its
    +  contributors may be used to endorse or promote products derived from
    +  this software without specific prior written permission.
    +
    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/togglepanel/togglepanel.css b/deployment-apps/metricator-for-nmon/appserver/static/components/togglepanel/togglepanel.css
    new file mode 100644
    index 0000000..46067e7
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/togglepanel/togglepanel.css
    @@ -0,0 +1,45 @@
    +/*
    + * Copyright (c) 2016-2017, OctoInsight Inc., All rights reserved.
    + * Authored by Ryan Thibodeaux
    + * see included LICENSE file (BSD 3-clause)
    + */
    +
    +.toggledopen {
    +  font-family: Arial, Helvetica, Arial, sans-serif;
    +  padding: 9px 6px 6px 6px;
    +  cursor: pointer;
    +  display: inline;
    +  float: left;
    +  font-size: 20px;
    +  font-weight: bolder;
    +  -webkit-border-radius: 1px;
    +  -moz-border-radius: 1px;
    +  border-radius: 1px;
    +}
    +
    +.toggledopen:before {
    +  color: #d3d3d3;
    +  content: "\25B2";
    +}
    +
    +.toggledclosed {
    +  font-family: Arial, Helvetica, Arial, sans-serif;
    +  padding: 9px 6px 6px 6px;
    +  cursor: pointer;
    +  display: inline;
    +  float: left;
    +  font-size: 20px;
    +  font-weight: bolder;
    +  -webkit-border-radius: 1px;
    +  -moz-border-radius: 1px;
    +  border-radius: 1px;
    +}
    +
    +.toggledclosed:before {
    +  color: #d3d3d3;
    +  content: "\25Bc";
    +}
    +
    +.togglepanel-hidden {
    +  display: none !important;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/togglepanel/togglepanel.js b/deployment-apps/metricator-for-nmon/appserver/static/components/togglepanel/togglepanel.js
    new file mode 100644
    index 0000000..c345d96
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/togglepanel/togglepanel.js
    @@ -0,0 +1,263 @@
    +/**
    + * @fileoverview Class definition for TogglePanel or Accordion panel feature
    + * @author Ryan Thibodeaux
    + * @version 1.0.0
    + */
    +
    +/*
    + * Copyright (c) 2016-2017, OctoInsight Inc., All rights reserved.
    + * Authored by Ryan Thibodeaux
    + * see included LICENSE file (BSD 3-clause)
    + */
    +
    +/*
    + * Definition of custom TogglePanel class.
    + * This turns a Splunk "panel" element into
    + * an Accordion panel or toggle-able panel.
    + *
    + * NOTE: this is not an extension of the panel
    + * base class; instead, it allows one to retroactively
    + * turn an existing panel into a toggle-able one. This
    + * makes managing panels easier in Simple XML dashboards
    + * because the Simple XML dashboards don't have to know
    + * about this class, i.e., it is done in JS for the
    + * dashboard
    + */
    +
    +define(function(require, exports, module) {
    +
    +  var $ = require('jquery');
    +  var mvc = require("splunkjs/mvc");
    +
    +  // The require-css plugin is inconsistent at determining the path
    +  // for loading CSS files. We have to hardcode for now,
    +  require('css!/static/app/metricator-for-nmon/components/togglepanel/togglepanel.css');
    +
    +
    +  // default settings for TogglePanel object
    +  var defaults = {
    +    openWidth   : undefined,   // width of toggle panel when open
    +    closeWidth  : undefined,   // width of toggle panel when closed
    +    toggleSpeed : 500,         // toggle animation duration in milliseconds
    +  };
    +
    +  // constructor of TogglePanel object
    +  // parent can be an HTML id or jquery selector
    +  function TogglePanel(parent, openWidth, closeWidth, toggleSpeed) {
    +    if (!(this instanceof TogglePanel)) {
    +      throw new TypeError("TogglePanel constructor cannot be called as a function.");
    +    }
    +
    +    // handle parent parameter passed in as HTML id or jquery selector.
    +    // this.parent should point to jquery selector of TogglePanel object
    +    // this.parentId should contain the parent's HTML id
    +    if (typeof parent === 'undefined') {
    +      throw new TypeError("TogglePanel constructor cannot be called without a parent.");
    +    } else if (typeof parent === 'string' || parent instanceof String) {
    +      this.parentId = parent.replace(/^\#+/g, '');
    +      this.parent = $('#' + parent);
    +      if (!this.parentId.length) {
    +        throw new TypeError("TogglePanel constructor cannot find specified parent.");
    +      }
    +    } else {
    +      this.parentId = $(parent).attr('id');
    +      this.parent = $(parent);
    +    }
    +
    +    // set TogglePanel parameters
    +    this.openWidth = (typeof openWidth !== 'undefined' ? openWidth : defaults.openWidth);
    +    this.closeWidth = (typeof closeWidth !== 'undefined' ? closeWidth : defaults.closeWidth);
    +    this.toggleSpeed = (typeof toggleSpeed !== 'undefined' ? toggleSpeed : defaults.toggleSpeed);
    +    this.fieldset = undefined;
    +    this.childrenMvc = undefined;
    +  }
    +
    +  // create() wrapper for Toggle Panel constructor
    +  TogglePanel.create = function(parent, openWidth, closeWidth, toggleSpeed) {
    +    return (new TogglePanel(parent, openWidth, closeWidth, toggleSpeed));
    +  };
    +
    +  // static CSS class names to use for the open and close
    +  // state of the TogglePanel
    +  TogglePanel.OPENED_CLASS = 'toggledopen';
    +  TogglePanel.CLOSED_CLASS = 'toggledclosed';
    +
    +
    +  // define the TogglePanel class, which is a wholly new class
    +  // and not an extension of another
    +  TogglePanel.prototype = {
    +    constructor: TogglePanel,
    +
    +    // toggle child state
    +    toggleChild: function(el, wait) {
    +      if (!!wait) {
    +        el.slideToggle(this.toggleSpeed, function(){return;});
    +      } else {
    +        el.slideToggle(this.toggleSpeed);
    +      }
    +      el.resize();
    +    },
    +
    +    // animate hiding of child
    +    slideUpChild: function(el, wait) {
    +      if (!!wait) {
    +        el.slideUp(this.toggleSpeed, function(){return;});
    +      } else {
    +        el.slideUp(this.toggleSpeed);
    +      }
    +    },
    +
    +    // animate showing of child
    +    slideDownChild: function(el, wait) {
    +      if (!!wait) {
    +        el.slideDown(this.toggleSpeed, function(){return;});
    +      } else {
    +        el.slideDown(this.toggleSpeed);
    +      }
    +    },
    +
    +    // resize Splunk MVC element
    +    resizeChild: function(el) {
    +      el.resize();
    +    },
    +
    +    // call toggleChild for all known child elements
    +    toggleAllChildren: function() {
    +      var self = this;
    +      this.childrenMvc.forEach(function(child) {
    +        self.toggleChild(child.$el);
    +      });
    +      return this;
    +    },
    +
    +    // call slideUp for all known child elements
    +    hideAllChildren: function() {
    +      var self = this;
    +      this.childrenMvc.forEach(function(child) {
    +        self.slideUpChild(child.$el);
    +      });
    +      return this;
    +    },
    +
    +    // call slideDown for all known child elements
    +    // where we let the animation complete before moving
    +    // to the next and then we resize after all done
    +    showAllChildren: function() {
    +      var self = this;
    +      this.childrenMvc.forEach(function(child) {
    +        self.slideDownChild(child.$el, true);
    +      });
    +      this.childrenMvc.forEach(function(child) {
    +        self.resizeChild(child.$el);
    +      });
    +      return this;
    +    },
    +
    +    // high-level function to start the toggle process on,
    +    // element el which should toggle all dashboard elements inside
    +    // of the toggle panel (el) and its fieldset element
    +    toggle: function(el) {
    +
    +      if (!el.data('parent')) {
    +        return;
    +      }
    +
    +      // set the toggled state on the contained fieldset element
    +      // and set the appropriate width of the TogglePanel object el
    +      var parent = $('#' + el.data('parent'));
    +      if (parent.length) {
    +
    +        var fieldset = this.fieldset;
    +
    +        // if toggling open, set width, toggle the fieldset,
    +        // and then toggle the elements
    +        if (el.attr("class") === TogglePanel.CLOSED_CLASS) {
    +          if (typeof this.openWidth !== 'undefined') {
    +            parent.css('width', this.openWidth);
    +          }
    +
    +          // toggle the fieldset
    +          if (fieldset.length > 0) {
    +            fieldset.removeClass("togglepanel-hidden");
    +            fieldset.slideDown(this.toggleSpeed);
    +          }
    +
    +          // call toggle open on all children
    +          this.showAllChildren();
    +
    +          // set new toggle icon
    +          el.attr('class', TogglePanel.OPENED_CLASS);
    +        } else {
    +          // if toggling closed, toggle elements,
    +          // and then toggle the fieldset
    +
    +          // call slideUp on all children
    +          this.hideAllChildren();
    +
    +          // hide the fieldset, where we use slideUp but
    +          // we also add a class after the animation is complete
    +          // where this class will force it to be hidden
    +          if (fieldset.length > 0) {
    +            fieldset.slideUp(this.toggleSpeed, function() {
    +              fieldset.addClass("togglepanel-hidden");
    +            });
    +          }
    +
    +          // set the close width
    +          if (typeof this.closeWidth !== 'undefined') {
    +            parent.css('width', this.closeWidth);
    +          }
    +
    +          // set new toggle icon
    +          el.attr('class', TogglePanel.CLOSED_CLASS);
    +        }
    +      }
    +      return this;
    +    },
    +
    +    // initial function to setup the TogglePanel object
    +    // by inserting the toggle element at the beginning
    +    // of the panel title and setting the appropriate state
    +    // of the TogglePanel based on the hide parameter
    +    setup: function(hide) {
    +
    +      // setup html element and its attributes for the toggle icon
    +      var title = this.parent.find('.panel-title')
    +      var toggleDiv = $('<div> &nbsp; </div>');
    +      toggleDiv.attr('class', TogglePanel.OPENED_CLASS);
    +      toggleDiv.attr('id', "toggle_panel_div_" + this.parentId);
    +      this.parent.children('.dashboard-panel').prepend(toggleDiv);
    +      toggleDiv.attr('alt', '#' + this.parentId).data('parent', this.parentId);
    +      this.$el = toggleDiv
    +
    +      // save fieldset selector if the panel has one
    +      this.fieldset = this.parent.find('.fieldset');
    +
    +      // find all MVC elements and save them in childrenMvc
    +      var children = [];
    +      this.parent.find('.dashboard-element').each(function() {
    +        var k = mvc.Components.get(this.id);
    +        if (typeof k !== 'undefined') {
    +          children.push(k);
    +        }
    +      });
    +      this.childrenMvc = children;
    +
    +
    +      // hide all children if "hide" is true
    +      if (!!hide) {
    +        this.toggle(this.$el);
    +      }
    +
    +      // setup click listener on toggle switch and panel title
    +      toggleDiv.on("click", $.proxy(this.toggle, this, this.$el));
    +      if (title.length > 0) {
    +        title.first().on("click", $.proxy(this.toggle, this, this.$el));
    +        title.first().css("cursor", "pointer");
    +      }
    +      return this;
    +    },
    +  };
    +
    +  return TogglePanel;
    +});
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/components/togglepanel/wrapper.js b/deployment-apps/metricator-for-nmon/appserver/static/components/togglepanel/wrapper.js
    new file mode 100644
    index 0000000..ef05159
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/components/togglepanel/wrapper.js
    @@ -0,0 +1,41 @@
    +/*
    + * Copyright (c) 2016-2017, OctoInsight Inc., All rights reserved.
    + * Authored by Ryan Thibodeaux
    + * see included LICENSE file (BSD 3-clause)
    + */
    +
    +/*
    + * This file implements the autodiscover function
    + * that finds panels in SimpleXML that should
    + * be turned into Toggle Panels based on their
    + * HTML IDs matching a specific pattern.
    + */
    +
    +(function() {
    +  require([
    +    "underscore",
    +    "jquery",
    +    "splunkjs/mvc",
    +    "TogglePanel",
    +], function(_, $, mvc, TogglePanel) {
    +
    +    const regex = /_togglepanel/i;
    +    const regexHide = /_togglepanel_true/i;
    +
    +    _(mvc.Components.toJSON())
    +      .chain()
    +      .filter(function(el) {
    +        var id = $(el).attr("id");
    +        var dom = $(el).attr("$el");
    +        if (typeof id !== "undefined" && typeof dom !== "undefined") {
    +          if (id.match(regex) !== null && dom.hasClass('dashboard-cell')) {
    +            return el;
    +          }
    +        }
    +      }).each(function(el) {
    +        var id = $(el).attr("id");
    +        var hide = (id.match(regexHide) !== null ? true : false);
    +        new TogglePanel(id).setup(hide);
    +      });
    +  });
    +}).call(this);
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/custom_layout.js b/deployment-apps/metricator-for-nmon/appserver/static/custom_layout.js
    new file mode 100644
    index 0000000..4061001
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/custom_layout.js
    @@ -0,0 +1,10 @@
    + require(['jquery', 'splunkjs/mvc/simplexml/ready!'], function($) {
    +     $("[id*=setWidth]").each(function() {
    +         var match = /setWidth_(\d+(?:_\d+)?)/.exec($(this).attr('id'));
    +         if (match[1]) {
    +             $(this).closest(".dashboard-cell").css('width', match[1].replace("_", ".") + '%');
    +         }
    +     });
    +     // Force visualizations (esp. charts) to be redrawn with their new size
    +     $(window).trigger('resize');
    + });
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/dark.css b/deployment-apps/metricator-for-nmon/appserver/static/dark.css
    new file mode 100644
    index 0000000..572b394
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/dark.css
    @@ -0,0 +1,31 @@
    +
    +
    +/* darks css theme from: http://www.brainfold.net/2016/04/splunk-dashboards-looks-more-beautiful.html */
    +
    +body,.dashboard-body,.footer,.header,.dashboard-cell {
    +    background: #1C1E23 !important;
    +}
    +
    +.dashboard-panel {
    +    background: #292C33 !important;
    +}
    +
    +svg text {
    +    fill: #fff !important;
    +}
    +.single-value .single-result {
    +    color: #fff;
    +}
    +
    +.dashboard-header h2, p.description, .nav-footer>li>a {
    +    color: #ddd;
    +    text-shadow: none;
    +}
    +
    +.dashboard-row .dashboard-panel h2.panel-title {
    +    color: #fff;
    +}
    +
    +button, input, label, select, textarea {
    +    color: #808080 !important;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/dashboard.css b/deployment-apps/metricator-for-nmon/appserver/static/dashboard.css
    new file mode 100644
    index 0000000..bb3bb91
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/dashboard.css
    @@ -0,0 +1,10 @@
    +/*
    + *
    + * This is the default CSS for all
    + * pages in the app.
    + *
    + * This file will automatically be loaded
    + * for all dashboards.
    + *
    + */
    +
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/dashboard.js b/deployment-apps/metricator-for-nmon/appserver/static/dashboard.js
    new file mode 100644
    index 0000000..b10a363
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/dashboard.js
    @@ -0,0 +1,77 @@
    +/////////////////////////////////////////////////
    +//
    +// This is the default entry point for all
    +// pages in the app.
    +//
    +// This file will automatically be loaded
    +// for all dashboards.
    +//
    +/////////////////////////////////////////////////
    +
    +(function() {
    +  var appName, appPath;
    +  var pageOptions, pageName;
    +  var urlAppComponents, requireRoot;
    +
    +  // anonymous function to breakdown the URL into app name and page name
    +  urlAppComponents = (function() {
    +    var comps = (location.pathname.split('?')[0]).split('/');
    +    var idx   = comps.indexOf('app');
    +    var app   = comps[idx + 1];
    +    var page  = comps[idx + 2];
    +    return [app, page];
    +  })();
    +
    +  // obtain values from previous anonymous function
    +  appName  = urlAppComponents[0];
    +  pageName = urlAppComponents[1];
    +
    +  // save global entities
    +  pageOptions = {
    +    "pageStartTime": new Date().valueOf(), // save time of when page is loaded
    +    "appName"  : appName, // app name
    +    "pageName" : pageName, // dashboard page name
    +  };
    +
    +  // setup paths for rest of the configuration
    +  requireRoot = "../app";
    +  appPath     = requireRoot + "/" + appName;
    +
    +  // configure RequrieJS Paths and Options
    +  require.config({
    +    paths: {
    +      "app"                : requireRoot,
    +      "appOptions"         : appPath + "/components/lib/options",
    +      "appUtils"           : appPath + "/components/lib/utils",
    +    },
    +    config: {
    +      "appOptions": {
    +        "options": pageOptions
    +      }
    +    }
    +  });
    +
    +  // load the important modules for the dashboards, where we load CSS first
    +  // and than everything else
    +  require([], function() {
    +    require([
    +      "appOptions",
    +      "appUtils",
    +    ], function(ignored, appUtils) {
    +      // call initialization routine
    +      appUtils.initiliazeApp(true);
    +    }, function(err) {
    +      // error callback
    +      // the error has a list of modules that failed
    +      var failedId = err.requireModules && err.requireModules[0];
    +      requirejs.undef(failedId);
    +      console.error("Error when loading dependency", err);
    +    });
    +  }, function(err) {
    +    // error callback
    +    // the error has a list of modules that failed
    +    var failedId = err.requireModules && err.requireModules[0];
    +    requirejs.undef(failedId);
    +    console.error("Error when loading CSS dependency", err);
    +  });
    +}).call(this);
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/diagrams/frameID_mapping.png b/deployment-apps/metricator-for-nmon/appserver/static/diagrams/frameID_mapping.png
    new file mode 100644
    index 0000000..d0085cb
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/diagrams/frameID_mapping.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/diagrams/threshold_management.png b/deployment-apps/metricator-for-nmon/appserver/static/diagrams/threshold_management.png
    new file mode 100644
    index 0000000..b4d728a
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/diagrams/threshold_management.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/hide_dashboardtitle.css b/deployment-apps/metricator-for-nmon/appserver/static/hide_dashboardtitle.css
    new file mode 100644
    index 0000000..1fe261a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/hide_dashboardtitle.css
    @@ -0,0 +1,3 @@
    +.dashboard-header h2 {
    +visibility: hidden !important;
    +}
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/hide_footer.css b/deployment-apps/metricator-for-nmon/appserver/static/hide_footer.css
    new file mode 100644
    index 0000000..d827c68
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/hide_footer.css
    @@ -0,0 +1,5 @@
    +/* completely hide panel footers */
    +
    +.dashboard-row .dashboard-panel .dashboard-element .panel-footer {
    +    display: none;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/hide_timeindicator.css b/deployment-apps/metricator-for-nmon/appserver/static/hide_timeindicator.css
    new file mode 100644
    index 0000000..e7c67da
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/hide_timeindicator.css
    @@ -0,0 +1,7 @@
    +.dashboard-row .dashboard-panel .refresh-time-indicator {
    +font-size: 11px;
    +color: #555555;
    +cursor: default;
    +padding: 10px 10px 6px 10px;
    +visibility: hidden !important;
    +}
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/hover.css b/deployment-apps/metricator-for-nmon/appserver/static/hover.css
    new file mode 100644
    index 0000000..ac7ce43
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/hover.css
    @@ -0,0 +1,2093 @@
    +/*!
    + * Hover.css (http://ianlunn.co.uk/)
    + * Version: 1.0.8
    + * Author: Ian Lunn @IanLunn
    + * Author URL: http://ianlunn.co.uk/
    + * Github: https://github.com/IanLunn/Hover
    +
    + * Made available under a MIT License:
    + * http://www.opensource.org/licenses/mit-license.php
    +
    + * Hover.css Copyright Ian Lunn 2014.
    + */
    +/* Default styles for the demo buttons */
    +.button {
    +  display: inline-block;
    +  /*margin: .4em;*/
    +  text-align: center;
    +  min-width: 150px;
    +  max-width: 300px;
    +  padding: 10px 20px;
    +  cursor: pointer;
    +  background: #8aa3c8;
    +  text-decoration: none !important;
    +  color: #FFF;
    +  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    +  margin-bottom: 3px;
    +  margin-top: 3px;
    +}
    +
    +.button2 {
    +  display: inline-block;
    +  /*margin: .4em;*/
    +  text-align: center;
    +  min-width: 150px;
    +  max-width: 300px;
    +  padding: 10px 20px;
    +  cursor: pointer;
    +  background: #778899;
    +  text-decoration: none !important;
    +  color: #FFF;
    +  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    +  margin-bottom: 3px;
    +  margin-top: 3px;
    +}
    +
    +.button_pastelgreen {
    +  display: inline-block;
    +  /*margin: .4em;*/
    +  text-align: center;
    +  min-width: 150px;
    +  max-width: 300px;
    +  padding: 10px 20px;
    +  cursor: pointer;
    +  background: #a7c59b;
    +  text-decoration: none !important;
    +  color: #FFF;
    +  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    +  margin-bottom: 3px;
    +  margin-top: 3px;
    +}
    +
    +.button_lightblue {
    +  display: inline-block;
    +  /*margin: .4em;*/
    +  text-align: center;
    +  min-width: 150px;
    +  max-width: 300px;
    +  padding: 10px 20px;
    +  cursor: pointer;
    +  background: #BBDAF6;
    +  text-decoration: none !important;
    +  color: #FFF;
    +  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    +  margin-bottom: 3px;
    +  margin-top: 3px;
    +}
    +
    +.button_lowpadding {
    +  display: inline-block;
    +  /*margin: .4em;*/
    +  text-align: center;
    +  min-width: 200px;
    +  max-width: 400px;
    +  padding: 5px 20px;
    +  cursor: pointer;
    +  background: #8aa3c8;
    +  text-decoration: none !important;
    +  color: #FFF;
    +  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    +  margin-bottom: 3px;
    +  margin-top: 3px;
    +}
    +
    +.button2_lowpadding {
    +  display: inline-block;
    +  /*margin: .4em;*/
    +  text-align: center;
    +  min-width: 200px;
    +  max-width: 400px;
    +  padding: 5px 20px;
    +  cursor: pointer;
    +  background: #778899;
    +  text-decoration: none !important;
    +  color: #FFF;
    +  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    +  margin-bottom: 3px;
    +  margin-top: 3px;
    +}
    +
    +.button_pastelgreen_lowpadding {
    +  display: inline-block;
    +  /*margin: .4em;*/
    +  text-align: center;
    +  min-width: 200px;
    +  max-width: 400px;
    +  padding: 5px 20px;
    +  cursor: pointer;
    +  background: #a7c59b;
    +  text-decoration: none !important;
    +  color: #FFF;
    +  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    +  margin-bottom: 3px;
    +  margin-top: 3px;
    +}
    +
    +.button_pastelred_lowpadding {
    +  display: inline-block;
    +  /*margin: .4em;*/
    +  text-align: center;
    +  min-width: 200px;
    +  max-width: 400px;
    +  padding: 5px 20px;
    +  cursor: pointer;
    +  background: #ff817b;
    +  text-decoration: none !important;
    +  color: #FFF;
    +  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    +  margin-bottom: 3px;
    +  margin-top: 3px;
    +}
    +
    +.button_lightblue_lowpadding {
    +  display: inline-block;
    +  /*margin: .4em;*/
    +  text-align: center;
    +  min-width: 200px;
    +  max-width: 400px;
    +  padding: 5px 20px;
    +  cursor: pointer;
    +  background: #BBDAF6;
    +  text-decoration: none !important;
    +  color: #FFF;
    +  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    +  margin-bottom: 3px;
    +  margin-top: 3px;
    +}
    +
    +/* 2D TRANSITIONS */
    +/* Grow */
    +.grow {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.grow:hover, .grow:focus, .grow:active {
    +  -webkit-transform: scale(1.1);
    +  transform: scale(1.1);
    +}
    +
    +/* Shrink */
    +.shrink {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.shrink:hover, .shrink:focus, .shrink:active {
    +  -webkit-transform: scale(0.9);
    +  transform: scale(0.9);
    +}
    +
    +/* Pulse */
    +@-webkit-keyframes pulse {
    +  25% {
    +    -webkit-transform: scale(1.1);
    +    transform: scale(1.1);
    +  }
    +
    +  75% {
    +    -webkit-transform: scale(0.9);
    +    transform: scale(0.9);
    +  }
    +}
    +
    +@keyframes pulse {
    +  25% {
    +    -webkit-transform: scale(1.1);
    +    transform: scale(1.1);
    +  }
    +
    +  75% {
    +    -webkit-transform: scale(0.9);
    +    transform: scale(0.9);
    +  }
    +}
    +
    +.pulse {
    +  display: inline-block;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.pulse:hover, .pulse:focus, .pulse:active {
    +  -webkit-animation-name: pulse;
    +  animation-name: pulse;
    +  -webkit-animation-duration: 1s;
    +  animation-duration: 1s;
    +  -webkit-animation-timing-function: linear;
    +  animation-timing-function: linear;
    +  -webkit-animation-iteration-count: infinite;
    +  animation-iteration-count: infinite;
    +}
    +
    +/* Pulse Grow */
    +@-webkit-keyframes pulse-grow {
    +  to {
    +    -webkit-transform: scale(1.1);
    +    transform: scale(1.1);
    +  }
    +}
    +
    +@keyframes pulse-grow {
    +  to {
    +    -webkit-transform: scale(1.1);
    +    transform: scale(1.1);
    +  }
    +}
    +
    +.pulse-grow {
    +  display: inline-block;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.pulse-grow:hover, .pulse-grow:focus, .pulse-grow:active {
    +  -webkit-animation-name: pulse-grow;
    +  animation-name: pulse-grow;
    +  -webkit-animation-duration: 0.3s;
    +  animation-duration: 0.3s;
    +  -webkit-animation-timing-function: linear;
    +  animation-timing-function: linear;
    +  -webkit-animation-iteration-count: infinite;
    +  animation-iteration-count: infinite;
    +  -webkit-animation-direction: alternate;
    +  animation-direction: alternate;
    +}
    +
    +/* Pulse Shrink */
    +@-webkit-keyframes pulse-shrink {
    +  to {
    +    -webkit-transform: scale(0.9);
    +    transform: scale(0.9);
    +  }
    +}
    +
    +@keyframes pulse-shrink {
    +  to {
    +    -webkit-transform: scale(0.9);
    +    transform: scale(0.9);
    +  }
    +}
    +
    +.pulse-shrink {
    +  display: inline-block;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.pulse-shrink:hover, .pulse-shrink:focus, .pulse-shrink:active {
    +  -webkit-animation-name: pulse-shrink;
    +  animation-name: pulse-shrink;
    +  -webkit-animation-duration: 0.3s;
    +  animation-duration: 0.3s;
    +  -webkit-animation-timing-function: linear;
    +  animation-timing-function: linear;
    +  -webkit-animation-iteration-count: infinite;
    +  animation-iteration-count: infinite;
    +  -webkit-animation-direction: alternate;
    +  animation-direction: alternate;
    +}
    +
    +/* Push */
    +@-webkit-keyframes push {
    +  50% {
    +    -webkit-transform: scale(0.8);
    +    transform: scale(0.8);
    +  }
    +
    +  100% {
    +    -webkit-transform: scale(1);
    +    transform: scale(1);
    +  }
    +}
    +
    +@keyframes push {
    +  50% {
    +    -webkit-transform: scale(0.8);
    +    transform: scale(0.8);
    +  }
    +
    +  100% {
    +    -webkit-transform: scale(1);
    +    transform: scale(1);
    +  }
    +}
    +
    +.push {
    +  display: inline-block;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.push:hover, .push:focus, .push:active {
    +  -webkit-animation-name: push;
    +  animation-name: push;
    +  -webkit-animation-duration: 0.3s;
    +  animation-duration: 0.3s;
    +  -webkit-animation-timing-function: linear;
    +  animation-timing-function: linear;
    +  -webkit-animation-iteration-count: 1;
    +  animation-iteration-count: 1;
    +}
    +
    +/* Pop */
    +@-webkit-keyframes pop {
    +  50% {
    +    -webkit-transform: scale(1.2);
    +    transform: scale(1.2);
    +  }
    +
    +  100% {
    +    -webkit-transform: scale(1);
    +    transform: scale(1);
    +  }
    +}
    +
    +@keyframes pop {
    +  50% {
    +    -webkit-transform: scale(1.2);
    +    transform: scale(1.2);
    +  }
    +
    +  100% {
    +    -webkit-transform: scale(1);
    +    transform: scale(1);
    +  }
    +}
    +
    +.pop {
    +  display: inline-block;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.pop:hover, .pop:focus, .pop:active {
    +  -webkit-animation-name: pop;
    +  animation-name: pop;
    +  -webkit-animation-duration: 0.3s;
    +  animation-duration: 0.3s;
    +  -webkit-animation-timing-function: linear;
    +  animation-timing-function: linear;
    +  -webkit-animation-iteration-count: 1;
    +  animation-iteration-count: 1;
    +}
    +
    +/* Rotate */
    +.rotate {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.rotate:hover, .rotate:focus, .rotate:active {
    +  -webkit-transform: rotate(4deg);
    +  transform: rotate(4deg);
    +}
    +
    +/* Grow Rotate */
    +.grow-rotate {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.grow-rotate:hover, .grow-rotate:focus, .grow-rotate:active {
    +  -webkit-transform: scale(1.1) rotate(4deg);
    +  transform: scale(1.1) rotate(4deg);
    +}
    +
    +/* Float */
    +.float {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.float:hover, .float:focus, .float:active {
    +  -webkit-transform: translateY(-5px);
    +  transform: translateY(-5px);
    +}
    +
    +/* Sink */
    +.sink {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.sink:hover, .sink:focus, .sink:active {
    +  -webkit-transform: translateY(5px);
    +  transform: translateY(5px);
    +}
    +
    +/* Hover */
    +@-webkit-keyframes hover {
    +  50% {
    +    -webkit-transform: translateY(-3px);
    +    transform: translateY(-3px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateY(-6px);
    +    transform: translateY(-6px);
    +  }
    +}
    +
    +@keyframes hover {
    +  50% {
    +    -webkit-transform: translateY(-3px);
    +    transform: translateY(-3px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateY(-6px);
    +    transform: translateY(-6px);
    +  }
    +}
    +
    +.hover {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.5s;
    +  transition-duration: 0.5s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.hover:hover, .hover:focus, .hover:active {
    +  -webkit-transform: translateY(-6px);
    +  transform: translateY(-6px);
    +  -webkit-animation-name: hover;
    +  animation-name: hover;
    +  -webkit-animation-duration: 1.5s;
    +  animation-duration: 1.5s;
    +  -webkit-animation-delay: 0.3s;
    +  animation-delay: 0.3s;
    +  -webkit-animation-timing-function: linear;
    +  animation-timing-function: linear;
    +  -webkit-animation-iteration-count: infinite;
    +  animation-iteration-count: infinite;
    +  -webkit-animation-direction: alternate;
    +  animation-direction: alternate;
    +}
    +
    +/* Hang */
    +@-webkit-keyframes hang {
    +  50% {
    +    -webkit-transform: translateY(3px);
    +    transform: translateY(3px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateY(6px);
    +    transform: translateY(6px);
    +  }
    +}
    +
    +@keyframes hang {
    +  50% {
    +    -webkit-transform: translateY(3px);
    +    transform: translateY(3px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateY(6px);
    +    transform: translateY(6px);
    +  }
    +}
    +
    +.hang {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.5s;
    +  transition-duration: 0.5s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.hang:hover, .hang:focus, .hang:active {
    +  -webkit-transform: translateY(6px);
    +  transform: translateY(6px);
    +  -webkit-animation-name: hang;
    +  animation-name: hang;
    +  -webkit-animation-duration: 1.5s;
    +  animation-duration: 1.5s;
    +  -webkit-animation-delay: 0.3s;
    +  animation-delay: 0.3s;
    +  -webkit-animation-timing-function: linear;
    +  animation-timing-function: linear;
    +  -webkit-animation-iteration-count: infinite;
    +  animation-iteration-count: infinite;
    +  -webkit-animation-direction: alternate;
    +  animation-direction: alternate;
    +}
    +
    +/* Skew */
    +.skew {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.skew:hover, .skew:focus, .skew:active {
    +  -webkit-transform: skew(-10deg);
    +  transform: skew(-10deg);
    +}
    +
    +/* Skew Forward */
    +.skew-forward {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform-origin: 0 100%;
    +  transform-origin: 0 100%;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.skew-forward:hover, .skew-forward:focus, .skew-forward:active {
    +  -webkit-transform: skew(-10deg);
    +  transform: skew(-10deg);
    +}
    +
    +/* Skew Backward */
    +.skew-backward {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform-origin: 0 100%;
    +  transform-origin: 0 100%;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.skew-backward:hover, .skew-backward:focus, .skew-backward:active {
    +  -webkit-transform: skew(10deg);
    +  transform: skew(10deg);
    +}
    +
    +/* Wobble Vertical */
    +@-webkit-keyframes wobble-vertical {
    +  16.65% {
    +    -webkit-transform: translateY(8px);
    +    transform: translateY(8px);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: translateY(-6px);
    +    transform: translateY(-6px);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: translateY(4px);
    +    transform: translateY(4px);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: translateY(-2px);
    +    transform: translateY(-2px);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: translateY(1px);
    +    transform: translateY(1px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateY(0);
    +    transform: translateY(0);
    +  }
    +}
    +
    +@keyframes wobble-vertical {
    +  16.65% {
    +    -webkit-transform: translateY(8px);
    +    transform: translateY(8px);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: translateY(-6px);
    +    transform: translateY(-6px);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: translateY(4px);
    +    transform: translateY(4px);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: translateY(-2px);
    +    transform: translateY(-2px);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: translateY(1px);
    +    transform: translateY(1px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateY(0);
    +    transform: translateY(0);
    +  }
    +}
    +
    +.wobble-vertical {
    +  display: inline-block;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.wobble-vertical:hover, .wobble-vertical:focus, .wobble-vertical:active {
    +  -webkit-animation-name: wobble-vertical;
    +  animation-name: wobble-vertical;
    +  -webkit-animation-duration: 1s;
    +  animation-duration: 1s;
    +  -webkit-animation-timing-function: ease-in-out;
    +  animation-timing-function: ease-in-out;
    +  -webkit-animation-iteration-count: 1;
    +  animation-iteration-count: 1;
    +}
    +
    +/* Wobble Horizontal */
    +@-webkit-keyframes wobble-horizontal {
    +  16.65% {
    +    -webkit-transform: translateX(8px);
    +    transform: translateX(8px);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: translateX(-6px);
    +    transform: translateX(-6px);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: translateX(4px);
    +    transform: translateX(4px);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: translateX(-2px);
    +    transform: translateX(-2px);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: translateX(1px);
    +    transform: translateX(1px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateX(0);
    +    transform: translateX(0);
    +  }
    +}
    +
    +@keyframes wobble-horizontal {
    +  16.65% {
    +    -webkit-transform: translateX(8px);
    +    transform: translateX(8px);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: translateX(-6px);
    +    transform: translateX(-6px);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: translateX(4px);
    +    transform: translateX(4px);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: translateX(-2px);
    +    transform: translateX(-2px);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: translateX(1px);
    +    transform: translateX(1px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateX(0);
    +    transform: translateX(0);
    +  }
    +}
    +
    +.wobble-horizontal {
    +  display: inline-block;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.wobble-horizontal:hover, .wobble-horizontal:focus, .wobble-horizontal:active {
    +  -webkit-animation-name: wobble-horizontal;
    +  animation-name: wobble-horizontal;
    +  -webkit-animation-duration: 1s;
    +  animation-duration: 1s;
    +  -webkit-animation-timing-function: ease-in-out;
    +  animation-timing-function: ease-in-out;
    +  -webkit-animation-iteration-count: 1;
    +  animation-iteration-count: 1;
    +}
    +
    +/* Wobble To Bottom Right */
    +@-webkit-keyframes wobble-to-bottom-right {
    +  16.65% {
    +    -webkit-transform: translate(8px, 8px);
    +    transform: translate(8px, 8px);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: translate(-6px, -6px);
    +    transform: translate(-6px, -6px);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: translate(4px, 4px);
    +    transform: translate(4px, 4px);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: translate(-2px, -2px);
    +    transform: translate(-2px, -2px);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: translate(1px, 1px);
    +    transform: translate(1px, 1px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translate(0, 0);
    +    transform: translate(0, 0);
    +  }
    +}
    +
    +@keyframes wobble-to-bottom-right {
    +  16.65% {
    +    -webkit-transform: translate(8px, 8px);
    +    transform: translate(8px, 8px);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: translate(-6px, -6px);
    +    transform: translate(-6px, -6px);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: translate(4px, 4px);
    +    transform: translate(4px, 4px);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: translate(-2px, -2px);
    +    transform: translate(-2px, -2px);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: translate(1px, 1px);
    +    transform: translate(1px, 1px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translate(0, 0);
    +    transform: translate(0, 0);
    +  }
    +}
    +
    +.wobble-to-bottom-right {
    +  display: inline-block;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.wobble-to-bottom-right:hover, .wobble-to-bottom-right:focus, .wobble-to-bottom-right:active {
    +  -webkit-animation-name: wobble-to-bottom-right;
    +  animation-name: wobble-to-bottom-right;
    +  -webkit-animation-duration: 1s;
    +  animation-duration: 1s;
    +  -webkit-animation-timing-function: ease-in-out;
    +  animation-timing-function: ease-in-out;
    +  -webkit-animation-iteration-count: 1;
    +  animation-iteration-count: 1;
    +}
    +
    +/* Wobble To Top Right */
    +@-webkit-keyframes wobble-to-top-right {
    +  16.65% {
    +    -webkit-transform: translate(8px, -8px);
    +    transform: translate(8px, -8px);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: translate(-6px, 6px);
    +    transform: translate(-6px, 6px);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: translate(4px, -4px);
    +    transform: translate(4px, -4px);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: translate(-2px, 2px);
    +    transform: translate(-2px, 2px);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: translate(1px, -1px);
    +    transform: translate(1px, -1px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translate(0, 0);
    +    transform: translate(0, 0);
    +  }
    +}
    +
    +@keyframes wobble-to-top-right {
    +  16.65% {
    +    -webkit-transform: translate(8px, -8px);
    +    transform: translate(8px, -8px);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: translate(-6px, 6px);
    +    transform: translate(-6px, 6px);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: translate(4px, -4px);
    +    transform: translate(4px, -4px);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: translate(-2px, 2px);
    +    transform: translate(-2px, 2px);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: translate(1px, -1px);
    +    transform: translate(1px, -1px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translate(0, 0);
    +    transform: translate(0, 0);
    +  }
    +}
    +
    +.wobble-to-top-right {
    +  display: inline-block;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.wobble-to-top-right:hover, .wobble-to-top-right:focus, .wobble-to-top-right:active {
    +  -webkit-animation-name: wobble-to-top-right;
    +  animation-name: wobble-to-top-right;
    +  -webkit-animation-duration: 1s;
    +  animation-duration: 1s;
    +  -webkit-animation-timing-function: ease-in-out;
    +  animation-timing-function: ease-in-out;
    +  -webkit-animation-iteration-count: 1;
    +  animation-iteration-count: 1;
    +}
    +
    +/* Wobble Top */
    +@-webkit-keyframes wobble-top {
    +  16.65% {
    +    -webkit-transform: skew(-12deg);
    +    transform: skew(-12deg);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: skew(10deg);
    +    transform: skew(10deg);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: skew(-6deg);
    +    transform: skew(-6deg);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: skew(4deg);
    +    transform: skew(4deg);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: skew(-2deg);
    +    transform: skew(-2deg);
    +  }
    +
    +  100% {
    +    -webkit-transform: skew(0);
    +    transform: skew(0);
    +  }
    +}
    +
    +@keyframes wobble-top {
    +  16.65% {
    +    -webkit-transform: skew(-12deg);
    +    transform: skew(-12deg);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: skew(10deg);
    +    transform: skew(10deg);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: skew(-6deg);
    +    transform: skew(-6deg);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: skew(4deg);
    +    transform: skew(4deg);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: skew(-2deg);
    +    transform: skew(-2deg);
    +  }
    +
    +  100% {
    +    -webkit-transform: skew(0);
    +    transform: skew(0);
    +  }
    +}
    +
    +.wobble-top {
    +  display: inline-block;
    +  -webkit-transform-origin: 0 100%;
    +  transform-origin: 0 100%;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.wobble-top:hover, .wobble-top:focus, .wobble-top:active {
    +  -webkit-animation-name: wobble-top;
    +  animation-name: wobble-top;
    +  -webkit-animation-duration: 1s;
    +  animation-duration: 1s;
    +  -webkit-animation-timing-function: ease-in-out;
    +  animation-timing-function: ease-in-out;
    +  -webkit-animation-iteration-count: 1;
    +  animation-iteration-count: 1;
    +}
    +
    +/* Wobble Bottom */
    +@-webkit-keyframes wobble-bottom {
    +  16.65% {
    +    -webkit-transform: skew(-12deg);
    +    transform: skew(-12deg);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: skew(10deg);
    +    transform: skew(10deg);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: skew(-6deg);
    +    transform: skew(-6deg);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: skew(4deg);
    +    transform: skew(4deg);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: skew(-2deg);
    +    transform: skew(-2deg);
    +  }
    +
    +  100% {
    +    -webkit-transform: skew(0);
    +    transform: skew(0);
    +  }
    +}
    +
    +@keyframes wobble-bottom {
    +  16.65% {
    +    -webkit-transform: skew(-12deg);
    +    transform: skew(-12deg);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: skew(10deg);
    +    transform: skew(10deg);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: skew(-6deg);
    +    transform: skew(-6deg);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: skew(4deg);
    +    transform: skew(4deg);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: skew(-2deg);
    +    transform: skew(-2deg);
    +  }
    +
    +  100% {
    +    -webkit-transform: skew(0);
    +    transform: skew(0);
    +  }
    +}
    +
    +.wobble-bottom {
    +  display: inline-block;
    +  -webkit-transform-origin: 100% 0;
    +  transform-origin: 100% 0;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.wobble-bottom:hover, .wobble-bottom:focus, .wobble-bottom:active {
    +  -webkit-animation-name: wobble-bottom;
    +  animation-name: wobble-bottom;
    +  -webkit-animation-duration: 1s;
    +  animation-duration: 1s;
    +  -webkit-animation-timing-function: ease-in-out;
    +  animation-timing-function: ease-in-out;
    +  -webkit-animation-iteration-count: 1;
    +  animation-iteration-count: 1;
    +}
    +
    +/* Wobble Skew */
    +@-webkit-keyframes wobble-skew {
    +  16.65% {
    +    -webkit-transform: skew(-12deg);
    +    transform: skew(-12deg);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: skew(10deg);
    +    transform: skew(10deg);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: skew(-6deg);
    +    transform: skew(-6deg);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: skew(4deg);
    +    transform: skew(4deg);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: skew(-2deg);
    +    transform: skew(-2deg);
    +  }
    +
    +  100% {
    +    -webkit-transform: skew(0);
    +    transform: skew(0);
    +  }
    +}
    +
    +@keyframes wobble-skew {
    +  16.65% {
    +    -webkit-transform: skew(-12deg);
    +    transform: skew(-12deg);
    +  }
    +
    +  33.3% {
    +    -webkit-transform: skew(10deg);
    +    transform: skew(10deg);
    +  }
    +
    +  49.95% {
    +    -webkit-transform: skew(-6deg);
    +    transform: skew(-6deg);
    +  }
    +
    +  66.6% {
    +    -webkit-transform: skew(4deg);
    +    transform: skew(4deg);
    +  }
    +
    +  83.25% {
    +    -webkit-transform: skew(-2deg);
    +    transform: skew(-2deg);
    +  }
    +
    +  100% {
    +    -webkit-transform: skew(0);
    +    transform: skew(0);
    +  }
    +}
    +
    +.wobble-skew {
    +  display: inline-block;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.wobble-skew:hover, .wobble-skew:focus, .wobble-skew:active {
    +  -webkit-animation-name: wobble-skew;
    +  animation-name: wobble-skew;
    +  -webkit-animation-duration: 1s;
    +  animation-duration: 1s;
    +  -webkit-animation-timing-function: ease-in-out;
    +  animation-timing-function: ease-in-out;
    +  -webkit-animation-iteration-count: 1;
    +  animation-iteration-count: 1;
    +}
    +
    +/* Buzz */
    +@-webkit-keyframes buzz {
    +  50% {
    +    -webkit-transform: translateX(3px) rotate(2deg);
    +    transform: translateX(3px) rotate(2deg);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateX(-3px) rotate(-2deg);
    +    transform: translateX(-3px) rotate(-2deg);
    +  }
    +}
    +
    +@keyframes buzz {
    +  50% {
    +    -webkit-transform: translateX(3px) rotate(2deg);
    +    transform: translateX(3px) rotate(2deg);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateX(-3px) rotate(-2deg);
    +    transform: translateX(-3px) rotate(-2deg);
    +  }
    +}
    +
    +.buzz {
    +  display: inline-block;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.buzz:hover, .buzz:focus, .buzz:active {
    +  -webkit-animation-name: buzz;
    +  animation-name: buzz;
    +  -webkit-animation-duration: 0.15s;
    +  animation-duration: 0.15s;
    +  -webkit-animation-timing-function: linear;
    +  animation-timing-function: linear;
    +  -webkit-animation-iteration-count: infinite;
    +  animation-iteration-count: infinite;
    +}
    +
    +/* Buzz Out */
    +@-webkit-keyframes buzz-out {
    +  10% {
    +    -webkit-transform: translateX(3px) rotate(2deg);
    +    transform: translateX(3px) rotate(2deg);
    +  }
    +
    +  20% {
    +    -webkit-transform: translateX(-3px) rotate(-2deg);
    +    transform: translateX(-3px) rotate(-2deg);
    +  }
    +
    +  30% {
    +    -webkit-transform: translateX(3px) rotate(2deg);
    +    transform: translateX(3px) rotate(2deg);
    +  }
    +
    +  40% {
    +    -webkit-transform: translateX(-3px) rotate(-2deg);
    +    transform: translateX(-3px) rotate(-2deg);
    +  }
    +
    +  50% {
    +    -webkit-transform: translateX(2px) rotate(1deg);
    +    transform: translateX(2px) rotate(1deg);
    +  }
    +
    +  60% {
    +    -webkit-transform: translateX(-2px) rotate(-1deg);
    +    transform: translateX(-2px) rotate(-1deg);
    +  }
    +
    +  70% {
    +    -webkit-transform: translateX(2px) rotate(1deg);
    +    transform: translateX(2px) rotate(1deg);
    +  }
    +
    +  80% {
    +    -webkit-transform: translateX(-2px) rotate(-1deg);
    +    transform: translateX(-2px) rotate(-1deg);
    +  }
    +
    +  90% {
    +    -webkit-transform: translateX(1px) rotate(0);
    +    transform: translateX(1px) rotate(0);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateX(-1px) rotate(0);
    +    transform: translateX(-1px) rotate(0);
    +  }
    +}
    +
    +@keyframes buzz-out {
    +  10% {
    +    -webkit-transform: translateX(3px) rotate(2deg);
    +    transform: translateX(3px) rotate(2deg);
    +  }
    +
    +  20% {
    +    -webkit-transform: translateX(-3px) rotate(-2deg);
    +    transform: translateX(-3px) rotate(-2deg);
    +  }
    +
    +  30% {
    +    -webkit-transform: translateX(3px) rotate(2deg);
    +    transform: translateX(3px) rotate(2deg);
    +  }
    +
    +  40% {
    +    -webkit-transform: translateX(-3px) rotate(-2deg);
    +    transform: translateX(-3px) rotate(-2deg);
    +  }
    +
    +  50% {
    +    -webkit-transform: translateX(2px) rotate(1deg);
    +    transform: translateX(2px) rotate(1deg);
    +  }
    +
    +  60% {
    +    -webkit-transform: translateX(-2px) rotate(-1deg);
    +    transform: translateX(-2px) rotate(-1deg);
    +  }
    +
    +  70% {
    +    -webkit-transform: translateX(2px) rotate(1deg);
    +    transform: translateX(2px) rotate(1deg);
    +  }
    +
    +  80% {
    +    -webkit-transform: translateX(-2px) rotate(-1deg);
    +    transform: translateX(-2px) rotate(-1deg);
    +  }
    +
    +  90% {
    +    -webkit-transform: translateX(1px) rotate(0);
    +    transform: translateX(1px) rotate(0);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateX(-1px) rotate(0);
    +    transform: translateX(-1px) rotate(0);
    +  }
    +}
    +
    +.buzz-out {
    +  display: inline-block;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.buzz-out:hover, .buzz-out:focus, .buzz-out:active {
    +  -webkit-animation-name: buzz-out;
    +  animation-name: buzz-out;
    +  -webkit-animation-duration: 0.75s;
    +  animation-duration: 0.75s;
    +  -webkit-animation-timing-function: linear;
    +  animation-timing-function: linear;
    +  -webkit-animation-iteration-count: 1;
    +  animation-iteration-count: 1;
    +}
    +
    +/* BORDER TRANSITIONS */
    +/* Border Fade */
    +.border-fade {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: box-shadow;
    +  transition-property: box-shadow;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: inset 0 0 0 4px #e1e1e1, 0 0 1px rgba(0, 0, 0, 0);
    +  /* Hack to improve aliasing on mobile/tablet devices */
    +}
    +.border-fade:hover, .border-fade:focus, .border-fade:active {
    +  box-shadow: inset 0 0 0 4px #666666, 0 0 1px rgba(0, 0, 0, 0);
    +  /* Hack to improve aliasing on mobile/tablet devices */
    +}
    +
    +/* Hollow */
    +.hollow {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: background;
    +  transition-property: background;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: inset 0 0 0 4px #e1e1e1, 0 0 1px rgba(0, 0, 0, 0);
    +  /* Hack to improve aliasing on mobile/tablet devices */
    +}
    +.hollow:hover, .hollow:focus, .hollow:active {
    +  background: none;
    +}
    +
    +/* Trim */
    +.trim {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.trim:before {
    +  content: '';
    +  position: absolute;
    +  border: white solid 4px;
    +  top: 4px;
    +  left: 4px;
    +  right: 4px;
    +  bottom: 4px;
    +  opacity: 0;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: opacity;
    +  transition-property: opacity;
    +}
    +.trim:hover:before, .trim:focus:before, .trim:active:before {
    +  opacity: 1;
    +}
    +
    +/* Outline Outward */
    +.outline-outward {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.outline-outward:before {
    +  content: '';
    +  position: absolute;
    +  border: #e1e1e1 solid 4px;
    +  top: 0;
    +  right: 0;
    +  bottom: 0;
    +  left: 0;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: top, right, bottom, left;
    +  transition-property: top, right, bottom, left;
    +}
    +.outline-outward:hover:before, .outline-outward:focus:before, .outline-outward:active:before {
    +  top: -8px;
    +  right: -8px;
    +  bottom: -8px;
    +  left: -8px;
    +}
    +
    +/* Outline Inward */
    +.outline-inward {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.outline-inward:before {
    +  pointer-events: none;
    +  content: '';
    +  position: absolute;
    +  border: #e1e1e1 solid 4px;
    +  top: -16px;
    +  right: -16px;
    +  bottom: -16px;
    +  left: -16px;
    +  opacity: 0;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: top, right, bottom, left;
    +  transition-property: top, right, bottom, left;
    +}
    +.outline-inward:hover:before, .outline-inward:focus:before, .outline-inward:active:before {
    +  top: -8px;
    +  right: -8px;
    +  bottom: -8px;
    +  left: -8px;
    +  opacity: 1;
    +}
    +
    +/* Round Corners */
    +.round-corners {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: border-radius;
    +  transition-property: border-radius;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.round-corners:hover, .round-corners:focus, .round-corners:active {
    +  border-radius: 1em;
    +}
    +
    +/* SHADOW/GLOW TRANSITIONS */
    +/* Glow */
    +.glow {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: box-shadow;
    +  transition-property: box-shadow;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.glow:hover, .glow:focus, .glow:active {
    +  box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
    +}
    +
    +/* Box Shadow Outset */
    +.box-shadow-outset {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: box-shadow;
    +  transition-property: box-shadow;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.box-shadow-outset:hover, .box-shadow-outset:focus, .box-shadow-outset:active {
    +  box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6);
    +}
    +
    +/* Box Shadow Inset */
    +.box-shadow-inset {
    +  display: inline-block;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: box-shadow;
    +  transition-property: box-shadow;
    +  box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.6), 0 0 1px rgba(0, 0, 0, 0);
    +  /* Hack to improve aliasing on mobile/tablet devices */
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +}
    +.box-shadow-inset:hover, .box-shadow-inset:focus, .box-shadow-inset:active {
    +  box-shadow: inset 2px 2px 2px rgba(0, 0, 0, 0.6), 0 0 1px rgba(0, 0, 0, 0);
    +  /* Hack to improve aliasing on mobile/tablet devices */
    +}
    +
    +/* Float Shadow */
    +.float-shadow {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.float-shadow:before {
    +  pointer-events: none;
    +  position: absolute;
    +  z-index: -1;
    +  content: '';
    +  top: 100%;
    +  left: 5%;
    +  height: 10px;
    +  width: 90%;
    +  opacity: 0;
    +  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0) 80%);
    +  /* W3C */
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform, opacity;
    +  transition-property: transform, opacity;
    +}
    +.float-shadow:hover, .float-shadow:focus, .float-shadow:active {
    +  -webkit-transform: translateY(-5px);
    +  transform: translateY(-5px);
    +  /* move the element up by 5px */
    +}
    +.float-shadow:hover:before, .float-shadow:focus:before, .float-shadow:active:before {
    +  opacity: 1;
    +  -webkit-transform: translateY(5px);
    +  transform: translateY(5px);
    +  /* move the element down by 5px (it will stay in place because it's attached to the element that also moves up 5px) */
    +}
    +
    +/* Hover Shadow */
    +@-webkit-keyframes hover {
    +  50% {
    +    -webkit-transform: translateY(-3px);
    +    transform: translateY(-3px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateY(-6px);
    +    transform: translateY(-6px);
    +  }
    +}
    +
    +@keyframes hover {
    +  50% {
    +    -webkit-transform: translateY(-3px);
    +    transform: translateY(-3px);
    +  }
    +
    +  100% {
    +    -webkit-transform: translateY(-6px);
    +    transform: translateY(-6px);
    +  }
    +}
    +
    +@-webkit-keyframes hover-shadow {
    +  0% {
    +    -webkit-transform: translateY(6px);
    +    transform: translateY(6px);
    +    opacity: .4;
    +  }
    +
    +  50% {
    +    -webkit-transform: translateY(3px);
    +    transform: translateY(3px);
    +    opacity: 1;
    +  }
    +
    +  100% {
    +    -webkit-transform: translateY(6px);
    +    transform: translateY(6px);
    +    opacity: .4;
    +  }
    +}
    +
    +@keyframes hover-shadow {
    +  0% {
    +    -webkit-transform: translateY(6px);
    +    transform: translateY(6px);
    +    opacity: .4;
    +  }
    +
    +  50% {
    +    -webkit-transform: translateY(3px);
    +    transform: translateY(3px);
    +    opacity: 1;
    +  }
    +
    +  100% {
    +    -webkit-transform: translateY(6px);
    +    transform: translateY(6px);
    +    opacity: .4;
    +  }
    +}
    +
    +.hover-shadow {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.hover-shadow:before {
    +  pointer-events: none;
    +  position: absolute;
    +  z-index: -1;
    +  content: '';
    +  top: 100%;
    +  left: 5%;
    +  height: 10px;
    +  width: 90%;
    +  opacity: 0;
    +  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0) 80%);
    +  /* W3C */
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform, opacity;
    +  transition-property: transform, opacity;
    +}
    +.hover-shadow:hover, .hover-shadow:focus, .hover-shadow:active {
    +  -webkit-transform: translateY(-6px);
    +  transform: translateY(-6px);
    +  animation-name: hover;
    +  animation-duration: 1.5s;
    +  animation-delay: 0.3s;
    +  animation-timing-function: linear;
    +  animation-iteration-count: infinite;
    +  animation-direction: alternate;
    +}
    +.hover-shadow:hover:before, .hover-shadow:focus:before, .hover-shadow:active:before {
    +  opacity: .4;
    +  -webkit-transform: translateY(6px);
    +  transform: translateY(6px);
    +  -webkit-animation-name: hover-shadow;
    +  animation-name: hover-shadow;
    +  -webkit-animation-duration: 1.5s;
    +  animation-duration: 1.5s;
    +  -webkit-animation-delay: 0.3s;
    +  animation-delay: 0.3s;
    +  -webkit-animation-timing-function: linear;
    +  animation-timing-function: linear;
    +  -webkit-animation-iteration-count: infinite;
    +  animation-iteration-count: infinite;
    +  -webkit-animation-direction: alternate;
    +  animation-direction: alternate;
    +}
    +
    +/* Shadow Radial */
    +.shadow-radial {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.shadow-radial:before, .shadow-radial:after {
    +  pointer-events: none;
    +  position: absolute;
    +  content: '';
    +  left: 0;
    +  width: 100%;
    +  box-sizing: border-box;
    +  background-repeat: no-repeat;
    +  height: 5px;
    +  opacity: 0;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: opacity;
    +  transition-property: opacity;
    +}
    +.shadow-radial:before {
    +  bottom: 100%;
    +  background: radial-gradient(ellipse at 50% 150%, rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0) 80%);
    +}
    +.shadow-radial:after {
    +  top: 100%;
    +  background: radial-gradient(ellipse at 50% -50%, rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0) 80%);
    +}
    +.shadow-radial:hover:before, .shadow-radial:focus:before, .shadow-radial:active:before, .shadow-radial:hover:after, .shadow-radial:focus:after, .shadow-radial:active:after {
    +  opacity: 1;
    +}
    +
    +/* SPEECH BUBBLES */
    +/* Bubble Top */
    +.bubble-top {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.bubble-top:before {
    +  pointer-events: none;
    +  position: absolute;
    +  z-index: -1;
    +  content: '';
    +  border-style: solid;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: top;
    +  transition-property: top;
    +  left: calc(50% - 10px);
    +  top: 0;
    +  border-width: 0 10px 10px 10px;
    +  border-color: transparent transparent #e1e1e1 transparent;
    +}
    +.bubble-top:hover:before, .bubble-top:focus:before, .bubble-top:active:before {
    +  top: -10px;
    +}
    +
    +/* Bubble Right */
    +.bubble-right {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.bubble-right:before {
    +  pointer-events: none;
    +  position: absolute;
    +  z-index: -1;
    +  content: '';
    +  border-style: solid;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: right;
    +  transition-property: right;
    +  top: calc(50% - 10px);
    +  right: 0;
    +  border-width: 10px 0 10px 10px;
    +  border-color: transparent transparent transparent #e1e1e1;
    +}
    +.bubble-right:hover:before, .bubble-right:focus:before, .bubble-right:active:before {
    +  right: -10px;
    +}
    +
    +/* Bubble Bottom */
    +.bubble-bottom {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.bubble-bottom:before {
    +  pointer-events: none;
    +  position: absolute;
    +  z-index: -1;
    +  content: '';
    +  border-style: solid;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: bottom;
    +  transition-property: bottom;
    +  left: calc(50% - 10px);
    +  bottom: 0;
    +  border-width: 10px 10px 0 10px;
    +  border-color: #e1e1e1 transparent transparent transparent;
    +}
    +.bubble-bottom:hover:before, .bubble-bottom:focus:before, .bubble-bottom:active:before {
    +  bottom: -10px;
    +}
    +
    +/* Bubble Left */
    +.bubble-left {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.bubble-left:before {
    +  pointer-events: none;
    +  position: absolute;
    +  z-index: -1;
    +  content: '';
    +  border-style: solid;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: left;
    +  transition-property: left;
    +  top: calc(50% - 10px);
    +  left: 0;
    +  border-width: 10px 10px 10px 0;
    +  border-color: transparent #e1e1e1 transparent transparent;
    +}
    +.bubble-left:hover:before, .bubble-left:focus:before, .bubble-left:active:before {
    +  left: -10px;
    +}
    +
    +/* Bubble Float Top */
    +.bubble-float-top {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.bubble-float-top:before {
    +  position: absolute;
    +  z-index: -1;
    +  content: '';
    +  left: calc(50% - 10px);
    +  top: 0;
    +  border-style: solid;
    +  border-width: 0 10px 10px 10px;
    +  border-color: transparent transparent #e1e1e1 transparent;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: top;
    +  transition-property: top;
    +}
    +.bubble-float-top:hover, .bubble-float-top:focus, .bubble-float-top:active {
    +  -webkit-transform: translateY(5px) translateZ(0);
    +  transform: translateY(5px) translateZ(0);
    +}
    +.bubble-float-top:hover:before, .bubble-float-top:focus:before, .bubble-float-top:active:before {
    +  top: -10px;
    +}
    +
    +/* Bubble Float Right */
    +.bubble-float-right {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.bubble-float-right:before {
    +  position: absolute;
    +  z-index: -1;
    +  top: calc(50% - 10px);
    +  right: 0;
    +  content: '';
    +  border-style: solid;
    +  border-width: 10px 0 10px 10px;
    +  border-color: transparent transparent transparent #e1e1e1;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: right;
    +  transition-property: right;
    +}
    +.bubble-float-right:hover, .bubble-float-right:focus, .bubble-float-right:active {
    +  -webkit-transform: translateX(-5px);
    +  transform: translateX(-5px);
    +}
    +.bubble-float-right:hover:before, .bubble-float-right:focus:before, .bubble-float-right:active:before {
    +  right: -10px;
    +}
    +
    +/* Bubble Float Bottom */
    +.bubble-float-bottom {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.bubble-float-bottom:before {
    +  position: absolute;
    +  z-index: -1;
    +  content: '';
    +  left: calc(50% - 10px);
    +  bottom: 0;
    +  border-style: solid;
    +  border-width: 10px 10px 0 10px;
    +  border-color: #e1e1e1 transparent transparent transparent;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: bottom;
    +  transition-property: bottom;
    +}
    +.bubble-float-bottom:hover, .bubble-float-bottom:focus, .bubble-float-bottom:active {
    +  -webkit-transform: translateY(-5px) translateZ(0);
    +  transform: translateY(-5px) translateZ(0);
    +}
    +.bubble-float-bottom:hover:before, .bubble-float-bottom:focus:before, .bubble-float-bottom:active:before {
    +  bottom: -10px;
    +}
    +
    +/* Bubble Float Left */
    +.bubble-float-left {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: transform;
    +  transition-property: transform;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.bubble-float-left:before {
    +  position: absolute;
    +  z-index: -1;
    +  content: '';
    +  top: calc(50% - 10px);
    +  left: 0;
    +  border-style: solid;
    +  border-width: 10px 10px 10px 0;
    +  border-color: transparent #e1e1e1 transparent transparent;
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: left;
    +  transition-property: left;
    +}
    +.bubble-float-left:hover, .bubble-float-left:focus, .bubble-float-left:active {
    +  -webkit-transform: translateX(5px);
    +  transform: translateX(5px);
    +}
    +.bubble-float-left:hover:before, .bubble-float-left:focus:before, .bubble-float-left:active:before {
    +  left: -10px;
    +}
    +
    +/* CURLS */
    +/* Curl Top Left */
    +.curl-top-left {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.curl-top-left:before {
    +  pointer-events: none;
    +  position: absolute;
    +  content: '';
    +  height: 0;
    +  width: 0;
    +  top: 0;
    +  left: 0;
    +  background: white;
    +  /* IE9 */
    +  background: linear-gradient(135deg, white 45%, #aaaaaa 50%, #cccccc 56%, white 80%);
    +  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#ffffff', endColorstr='#000000');
    +  /*For IE7-8-9*/
    +  z-index: 1000;
    +  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.4);
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: width, height;
    +  transition-property: width, height;
    +}
    +.curl-top-left:hover:before, .curl-top-left:focus:before, .curl-top-left:active:before {
    +  width: 25px;
    +  height: 25px;
    +}
    +
    +/* Curl Top Right */
    +.curl-top-right {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.curl-top-right:before {
    +  pointer-events: none;
    +  position: absolute;
    +  content: '';
    +  height: 0;
    +  width: 0;
    +  top: 0;
    +  right: 0;
    +  background: white;
    +  /* IE9 */
    +  background: linear-gradient(225deg, white 45%, #aaaaaa 50%, #cccccc 56%, white 80%);
    +  box-shadow: -1px 1px 1px rgba(0, 0, 0, 0.4);
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: width, height;
    +  transition-property: width, height;
    +}
    +.curl-top-right:hover:before, .curl-top-right:focus:before, .curl-top-right:active:before {
    +  width: 25px;
    +  height: 25px;
    +}
    +
    +/* Curl Bottom Right */
    +.curl-bottom-right {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.curl-bottom-right:before {
    +  pointer-events: none;
    +  position: absolute;
    +  content: '';
    +  height: 0;
    +  width: 0;
    +  bottom: 0;
    +  right: 0;
    +  background: white;
    +  /* IE9 */
    +  background: linear-gradient(315deg, white 45%, #aaaaaa 50%, #cccccc 56%, white 80%);
    +  box-shadow: -1px -1px 1px rgba(0, 0, 0, 0.4);
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: width, height;
    +  transition-property: width, height;
    +}
    +.curl-bottom-right:hover:before, .curl-bottom-right:focus:before, .curl-bottom-right:active:before {
    +  width: 25px;
    +  height: 25px;
    +}
    +
    +/* Curl Bottom Left */
    +.curl-bottom-left {
    +  display: inline-block;
    +  position: relative;
    +  -webkit-transform: translateZ(0);
    +  transform: translateZ(0);
    +  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    +}
    +.curl-bottom-left:before {
    +  pointer-events: none;
    +  position: absolute;
    +  content: '';
    +  height: 0;
    +  width: 0;
    +  bottom: 0;
    +  left: 0;
    +  background: white;
    +  /* IE9 */
    +  background: linear-gradient(45deg, white 45%, #aaaaaa 50%, #cccccc 56%, white 80%);
    +  box-shadow: 1px -1px 1px rgba(0, 0, 0, 0.4);
    +  -webkit-transition-duration: 0.3s;
    +  transition-duration: 0.3s;
    +  -webkit-transition-property: width, height;
    +  transition-property: width, height;
    +}
    +.curl-bottom-left:hover:before, .curl-bottom-left:focus:before, .curl-bottom-left:active:before {
    +  width: 25px;
    +  height: 25px;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/howto.css b/deployment-apps/metricator-for-nmon/appserver/static/howto.css
    new file mode 100644
    index 0000000..9922f89
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/howto.css
    @@ -0,0 +1,66 @@
    +.html h2 {
    +  color: #adbacd !important;
    +}
    +
    +a.tryitbtn-blue,
    +a.tryitbtn-blue:link,
    +a.tryitbtn-blue:visited,
    +a.tryitbtn-blue,
    +a.tryitbtn-blue:link,
    +a.tryitbtn-blue:visited {
    +  display: inline-block;
    +  color: #71b1c1;
    +  background-color: #1f1f1f;
    +  font-weight: bold;
    +  font-size: 12px;
    +  text-align: center;
    +  padding-left: 10px;
    +  padding-right: 10px;
    +  padding-top: 3px;
    +  padding-bottom: 4px;
    +  text-decoration: none;
    +  margin-left: 0;
    +  /* margin-left: 5px; */
    +  margin-right: 10px;
    +  margin-top: 0px;
    +  margin-bottom: 5px;
    +  border: 1px solid #aaaaaa;
    +  border: 1px solid #71b1c1;
    +  border-radius: 5px;
    +  white-space: nowrap;
    +}
    +
    +a.tryitbtn-blue:hover,
    +a.tryitbtn-blue:active,
    +a.tryitbtn-blue:hover,
    +a.tryitbtn-blue:active {
    +  background-color: #71b1c1;
    +  color: #1f1f1f;
    +}
    +
    +/* main category icons and titles */
    +
    +.imgheader img {
    +  float: left;
    +  width: 48px;
    +  height: 48px;
    +}
    +
    +.imgheader h1 {
    +  color: #adbacd;
    +  text-align: left;
    +  position: relative;
    +  top: 9px;
    +  left: 10px;
    +}
    +
    +.imgheader h2 {
    +  position: relative;
    +  top: 18px;
    +  left: 10px;
    +}
    +
    +.imgminiheader img {
    +  position: relative;
    +  top: -4px;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/arrow_green_decrease_48px.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/arrow_green_decrease_48px.png
    new file mode 100644
    index 0000000..62de5d6
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/arrow_green_decrease_48px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/arrow_green_increase_48px.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/arrow_green_increase_48px.png
    new file mode 100644
    index 0000000..1780ab3
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/arrow_green_increase_48px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/arrow_red_decrease_48px.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/arrow_red_decrease_48px.png
    new file mode 100644
    index 0000000..c1a9e32
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/arrow_red_decrease_48px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/arrow_red_increase_48px.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/arrow_red_increase_48px.png
    new file mode 100644
    index 0000000..086a1c6
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/arrow_red_increase_48px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/calendar.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/calendar.png
    new file mode 100644
    index 0000000..55539aa
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/calendar.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/compare.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/compare.png
    new file mode 100644
    index 0000000..54bc6fd
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/compare.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/cpu.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/cpu.png
    new file mode 100644
    index 0000000..ecc2bec
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/cpu.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/dashboard.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/dashboard.png
    new file mode 100644
    index 0000000..e7db0eb
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/dashboard.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/drive.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/drive.png
    new file mode 100644
    index 0000000..fc7e6f5
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/drive.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/equal-sign-48px.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/equal-sign-48px.png
    new file mode 100644
    index 0000000..8b18bb3
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/equal-sign-48px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/executive-search.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/executive-search.png
    new file mode 100644
    index 0000000..ae69572
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/executive-search.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/info.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/info.png
    new file mode 100644
    index 0000000..7ce5285
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/info.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/info2.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/info2.png
    new file mode 100644
    index 0000000..626350f
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/info2.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/memory.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/memory.png
    new file mode 100644
    index 0000000..996c819
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/memory.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/predict.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/predict.png
    new file mode 100644
    index 0000000..e099e18
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/predict.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/process.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/process.png
    new file mode 100644
    index 0000000..6751c28
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/process.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/redcross.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/redcross.png
    new file mode 100644
    index 0000000..f420e27
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/redcross.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/warning.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/warning.png
    new file mode 100644
    index 0000000..0c48d09
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/color_theme/warning.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/bug.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/bug.png
    new file mode 100644
    index 0000000..a2dd478
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/bug.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/calendar.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/calendar.png
    new file mode 100644
    index 0000000..1115613
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/calendar.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/compare.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/compare.png
    new file mode 100644
    index 0000000..910fd33
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/compare.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/cpu.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/cpu.png
    new file mode 100644
    index 0000000..a38f556
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/cpu.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/dashboard.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/dashboard.png
    new file mode 100644
    index 0000000..55566ba
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/dashboard.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/dictionary.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/dictionary.png
    new file mode 100644
    index 0000000..fa251dd
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/dictionary.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/dollar.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/dollar.png
    new file mode 100644
    index 0000000..ff788a1
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/dollar.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/drive.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/drive.png
    new file mode 100644
    index 0000000..2b30777
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/drive.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/filesystem.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/filesystem.png
    new file mode 100644
    index 0000000..8900353
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/filesystem.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/info.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/info.png
    new file mode 100644
    index 0000000..e36354c
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/info.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/inventory.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/inventory.png
    new file mode 100644
    index 0000000..3645edc
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/inventory.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/link.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/link.png
    new file mode 100644
    index 0000000..ae0ec89
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/link.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/memory.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/memory.png
    new file mode 100644
    index 0000000..8213260
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/memory.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/minidatabase.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/minidatabase.png
    new file mode 100644
    index 0000000..b2c541b
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/minidatabase.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/minihelp.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/minihelp.png
    new file mode 100644
    index 0000000..d683e45
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/minihelp.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/network.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/network.png
    new file mode 100644
    index 0000000..ed47e45
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/network.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/people.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/people.png
    new file mode 100644
    index 0000000..9fb8c87
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/people.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/predict.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/predict.png
    new file mode 100644
    index 0000000..980d30b
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/predict.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/process.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/process.png
    new file mode 100644
    index 0000000..4b106d9
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/process.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/server_info.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/server_info.png
    new file mode 100644
    index 0000000..cfbb53f
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/server_info.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/settings.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/settings.png
    new file mode 100644
    index 0000000..922f5f8
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/dark_theme/settings.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/bug.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/bug.png
    new file mode 100644
    index 0000000..e26c210
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/bug.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/calendar.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/calendar.png
    new file mode 100644
    index 0000000..9e7cdce
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/calendar.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/compare.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/compare.png
    new file mode 100644
    index 0000000..a00873a
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/compare.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/cpu.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/cpu.png
    new file mode 100644
    index 0000000..c18f983
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/cpu.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/dashboard.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/dashboard.png
    new file mode 100644
    index 0000000..aa20531
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/dashboard.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/dictionary.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/dictionary.png
    new file mode 100644
    index 0000000..fda1893
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/dictionary.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/dollar.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/dollar.png
    new file mode 100644
    index 0000000..0eb0e18
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/dollar.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/drive.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/drive.png
    new file mode 100644
    index 0000000..10c124d
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/drive.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/filesystem.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/filesystem.png
    new file mode 100644
    index 0000000..7cf800e
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/filesystem.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/info.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/info.png
    new file mode 100644
    index 0000000..f33dac5
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/info.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/inventory.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/inventory.png
    new file mode 100644
    index 0000000..1b174f7
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/inventory.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/link.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/link.png
    new file mode 100644
    index 0000000..12837c2
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/link.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/memory.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/memory.png
    new file mode 100644
    index 0000000..d15bb14
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/memory.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/minidatabase.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/minidatabase.png
    new file mode 100644
    index 0000000..204b195
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/minidatabase.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/minihelp.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/minihelp.png
    new file mode 100644
    index 0000000..9bfd8be
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/minihelp.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/network.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/network.png
    new file mode 100644
    index 0000000..990d13b
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/network.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/people.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/people.png
    new file mode 100644
    index 0000000..8fefd40
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/people.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/predict.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/predict.png
    new file mode 100644
    index 0000000..a3ce1a9
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/predict.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/process.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/process.png
    new file mode 100644
    index 0000000..c77e50d
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/process.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/server_info.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/server_info.png
    new file mode 100644
    index 0000000..75cc4bf
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/server_info.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/settings.png b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/settings.png
    new file mode 100644
    index 0000000..1de478e
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/icons/grey_theme/settings.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/js/build/309.js b/deployment-apps/metricator-for-nmon/appserver/static/js/build/309.js
    new file mode 100644
    index 0000000..ecfc1e9
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/js/build/309.js
    @@ -0,0 +1,2 @@
    +/*! For license information please see 309.js.LICENSE.txt */
    +(self.webpackChunk_splunk_ucc_ui_lib=self.webpackChunk_splunk_ucc_ui_lib||[]).push([[309],{746:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=40)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},2:function(e,t){e.exports=n(2472)},40:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Check")},e),o.a.createElement("path",{d:"M536.3 1278.364L1500 121.514 1354.11.283 513.7 1010.212l-391.44-319.52L0 837.61"}))}}})},272:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=41)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},2:function(e,t){e.exports=n(2472)},41:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Chevron Down"),viewBox:"0 0 1500 885"},e),o.a.createElement("path",{d:"M1500 134.59l-750 750L0 133.56 134.59 0 750 615.41 1365.41 0"}))}}})},720:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=42)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},2:function(e,t){e.exports=n(2472)},42:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Chevron Left"),viewBox:"0 0 885 1500"},e),o.a.createElement("path",{d:"M751.027 1500L0 750 750 0l134.59 134.59L269.177 750l615.41 615.41"}))}}})},4345:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=43)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},2:function(e,t){e.exports=n(2472)},43:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Chevron Right"),viewBox:"0 0 885 1500"},e),o.a.createElement("path",{d:"M134.59 0l750 750-751.028 750L0 1365.41 615.41 750 0 134.59"}))}}})},4193:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=53)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},2:function(e,t){e.exports=n(2472)},53:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Clone")},e),o.a.createElement("path",{d:"M189.04 1310.96H1125V1500H0V375h189.04v935.96zM375 0h1125v1125H375V0zm935.96 935.96V189.04H564.04v746.92h746.92z"}))}}})},8808:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=87)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},2:function(e,t){e.exports=n(2472)},87:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Info"),viewBox:"0 0 750 1500"},e),o.a.createElement("path",{d:"M187.5 562.5h375v750H750V1500H0v-187.5h187.5V750H0V562.5h187.5z"}),o.a.createElement("circle",{cx:"375",cy:"187.5",r:"187.5"}))}}})},2666:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=112)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},112:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("More"),viewBox:"0 0 32 32"},e),o.a.createElement("path",{d:"M9,16c0,1.7-1.3,3-3,3s-3-1.3-3-3s1.3-3,3-3S9,14.3,9,16z M16,13c-1.7,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S17.7,13,16,13zM26,13c-1.7,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S27.7,13,26,13z"}))}},2:function(e,t){e.exports=n(2472)}})},6261:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=113)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},113:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("More"),viewBox:"0 0 32 32"},e),o.a.createElement("path",{d:"M16,3c1.7,0,3,1.3,3,3s-1.3,3-3,3s-3-1.3-3-3S14.3,3,16,3z M16,13c1.7,0,3,1.3,3,3s-1.3,3-3,3s-3-1.3-3-3S14.3,13,16,13zM16,23c1.7,0,3,1.3,3,3s-1.3,3-3,3s-3-1.3-3-3S14.3,23,16,23z"}))}},2:function(e,t){e.exports=n(2472)}})},1:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=121)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},121:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Pencil")},e),o.a.createElement("path",{d:"M1403.425 105.822C1478.425 179.795 1500 300 1500 375L450 1425 0 1500l75-450L1125 0c75 0 184.932 9.247 278.425 105.822zM225 1374.658h188.014c-6.165-79.11-32.877-128.425-94.52-193.15-61.645-56.508-111.987-84.248-193.152-94.522L124.315 1275c42.123 23.63 75 58.562 100.685 99.658z"}))}},2:function(e,t){e.exports=n(2472)}})},8044:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=143)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},143:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Search")},e),o.a.createElement("path",{d:"M1476.69 1268.412l-340.795-340.795c56.048-92.285 88.43-200.177 88.43-314.948C1224.324 277.195 947.634.506 612.16.506S0 277.197 0 612.67c0 335.472 276.69 612.16 612.162 612.16 114.77 0 222.663-32.385 314.948-88.43l340.795 340.796c30.406 30.405 75 30.405 105.406 0l103.38-103.378c30.405-30.406 30.405-75 0-105.406zM156.08 612.67c0-248.312 207.77-456.082 456.082-456.082 248.31 0 456.08 207.77 456.08 456.08 0 248.312-207.77 456.082-456.08 456.082-248.31 0-456.08-207.77-456.08-456.08z"}))}},2:function(e,t){e.exports=n(2472)}})},7631:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=149)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},149:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Sort"),viewBox:"0 0 900 1500"},e),o.a.createElement("path",{d:"M0 900h900l-450 450L0 900zm0-300l450-450 450 450H0z"}))}},2:function(e,t){e.exports=n(2472)}})},5336:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=150)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},150:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Sorted Down"),viewBox:"0 0 900 1500"},e),o.a.createElement("path",{stroke:"#979797",d:"M1.207 900.5L450 1349.293 898.793 900.5H1.207z"}))}},2:function(e,t){e.exports=n(2472)}})},1022:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=151)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},151:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Sorted Up"),viewBox:"0 0 900 1500"},e),o.a.createElement("path",{stroke:"#979797",d:"M1.207 599.5h897.586L450 150.707 1.207 599.5z"}))}},2:function(e,t){e.exports=n(2472)}})},8442:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=165)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},165:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Trash"),viewBox:"0 0 1350 1500"},e),o.a.createElement("path",{d:"M1273.973 150H900V76.027C900 31.85 868.15 0 823.973 0H526.027C481.85 0 450 31.85 450 76.027V150H76.027C31.85 150 0 181.85 0 225v150h1350V226.027c0-44.178-31.85-76.027-76.027-76.027zM150 523.973v900c0 44.178 31.85 76.027 76.027 76.027h897.946c44.178 0 76.027-31.85 76.027-76.027v-900H150z"}))}},2:function(e,t){e.exports=n(2472)}})},9135:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=172)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},172:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),a=n(1),i=n(2),l=n.n(i);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e){return o.a.createElement(l.a,c({screenReaderText:Object(a._)("Triangle Right Small"),viewBox:"0 0 677 1062"},e),o.a.createElement("path",{d:"M175 1001l458-397c17.333-18 29-31.833 35-41.5 6-9.667 9-20.167 9-31.5 0-13.333-3-24.833-9-34.5-6-9.667-17.667-22.5-35-38.5L167 43C132.333 14.333 101 0 73 0 51.667 0 34.167 6.5 20.5 19.5 6.833 32.5 0 49.667 0 71v918c0 21.333 6.833 38.833 20.5 52.5 13.667 13.667 31.167 20.5 52.5 20.5 13.333 0 27.333-4.833 42-14.5 14.667-9.667 34.667-25.167 60-46.5z"}))}},2:function(e,t){e.exports=n(2472)}})},1946:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=22)}([function(e,t){e.exports=n(3262)},function(e,t,n){"use strict";n.r(t),n.d(t,"TOAST_TYPES",(function(){return r})),n.d(t,"TOAST_POSITIONS",(function(){return o}));var r={INFO:"info",WARNING:"warning",SUCCESS:"success",ERROR:"error"},o={TOP_LEFT:"top-left",TOP_CENTER:"top-center",TOP_RIGHT:"top-right",BOTTOM_LEFT:"bottom-left",BOTTOM_CENTER:"bottom-center",BOTTOM_RIGHT:"bottom-right"}},function(e,t){e.exports=n(7294)},function(e,t){e.exports=n(1581)},function(e,t){e.exports=n(2788)},function(e,t,n){"use strict";n.d(t,"h",(function(){return A})),n.d(t,"a",(function(){return M})),n.d(t,"g",(function(){return I})),n.d(t,"e",(function(){return R})),n.d(t,"c",(function(){return L})),n.d(t,"d",(function(){return q})),n.d(t,"b",(function(){return B})),n.d(t,"f",(function(){return W}));var r,o,a,i=n(4),l=n.n(i),c=n(13),s=n.n(c),u=n(0),p=n(1);function f(){var e=T(["\n            font-size: 14px;\n            line-height: 20px;\n            color: ",";\n            margin-left: 12px;\n            margin-right: 12px;\n        "]);return f=function(){return e},e}function d(){var e=T(["\n    ","\n    ","\n    box-sizing: content-box;\n"]);return d=function(){return e},e}function b(){var e=T(["\n    ","\n    position: fixed;\n    z-index: ",";\n    ",";\n"]);return b=function(){return e},e}function h(){var e=T(["\n    bottom: 16px;\n    left: 50%;\n    margin-left: calc(-1 * "," / 2);\n"]);return h=function(){return e},e}function v(){var e=T(["\n    bottom: 16px;\n    right: 16px;\n"]);return v=function(){return e},e}function y(){var e=T(["\n    bottom: 16px;\n    left: 16px;\n"]);return y=function(){return e},e}function m(){var e=T(["\n    top: 16px;\n    left: 16px;\n"]);return m=function(){return e},e}function g(){var e=T(["\n    top: 16px;\n    right: 16px;\n"]);return g=function(){return e},e}function O(){var e=T(["\n    top: 16px;\n    left: 50%;\n    margin-left: calc(-1 * "," / 2);\n"]);return O=function(){return e},e}function x(){var e=T(["\n    width: ",";\n\n    & > div:not(:nth-last-child(1)) {\n        margin-bottom: 16px;\n    }\n"]);return x=function(){return e},e}function j(){var e=T(["\n    display: block;\n    position: relative;\n    float: right;\n    margin: 3px 12px 12px 0;\n    overflow: hidden;\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    width: auto;\n    color: ",";\n    padding: 1px 0 2px;\n    border: none;\n    font-size: 14px;\n    line-height: 20px;\n    cursor: pointer;\n    max-width: calc(100% - 24px);\n    background-color: ",";\n    box-sizing: content-box;\n"]);return j=function(){return e},e}function w(){var e=T(["\n    overflow-y: auto;\n    overflow-x: hidden;\n    margin-left: 47px;\n    width: 453px;\n    padding-top: 8px;\n    box-sizing: content-box;\n"]);return w=function(){return e},e}function C(){var e=T(["\n            border-radius: "," 0 0 ",";\n        "]);return C=function(){return e},e}function S(){var e=T(["\n    width: 36px;\n    height: 100%;\n    display: flex;\n    position: absolute;\n    align-items: center;\n    padding-left: 11px;\n    background: ",";\n    color: ",";\n    ","\n    box-sizing: content-box;\n"]);return S=function(){return e},e}function k(){var e=T(["\n    display: inline-block;\n    height: 100%;\n    padding-top: 5px;\n    margin-left: 12px;\n    margin-right: 12px;\n    max-width: 404px;\n    hyphens: auto;\n    text-overflow: ellipsis;\n    padding-bottom: ",";\n    box-sizing: content-box;\n"]);return k=function(){return e},e}function P(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function E(){var e=T(["\n            border: 1px solid\n                ",";\n        "]);return E=function(){return e},e}function _(){var e=T(["\n    width: ",";\n    min-height: 46px;\n    position: relative;\n    background-color: ",";\n    box-shadow: ",";\n    ",";\n    border-radius: ",";\n    box-sizing: content-box;\n"]);return _=function(){return e},e}function T(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}var D="500px",I=l.a.div(_(),D,Object(u.pick)({enterprise:u.variables.backgroundColor,prisma:u.variables.backgroundColorPopup}),Object(u.pick)({enterprise:u.variables.overlayShadow,prisma:u.variables.embossShadow}),Object(u.pick)({enterprise:Object(i.css)(E(),Object(u.pickVariant)("$type",(r={},P(r,p.TOAST_TYPES.INFO,u.variables.cat1Color),P(r,p.TOAST_TYPES.WARNING,u.variables.warningColor),P(r,p.TOAST_TYPES.SUCCESS,u.variables.successColor),P(r,p.TOAST_TYPES.ERROR,u.variables.errorColor),r)))}),u.variables.borderRadius),R=l.a.div(k(),(function(e){return e.action?null:"13px"})),L=l.a.div(S(),Object(u.pick)({enterprise:Object(u.pickVariant)("$type",(o={},P(o,p.TOAST_TYPES.INFO,u.variables.cat1Color),P(o,p.TOAST_TYPES.WARNING,u.variables.warningColor),P(o,p.TOAST_TYPES.SUCCESS,u.variables.successColor),P(o,p.TOAST_TYPES.ERROR,u.variables.errorColor),o)),prisma:Object(u.pickVariant)("$type",(a={},P(a,p.TOAST_TYPES.INFO,u.variables.contentColorActive),P(a,p.TOAST_TYPES.WARNING,u.variables.accentColorWarning),P(a,p.TOAST_TYPES.SUCCESS,u.variables.accentColorPositive),P(a,p.TOAST_TYPES.ERROR,u.variables.accentColorNegative),a))}),Object(u.pick)({enterprise:u.variables.white,prisma:u.variables.contentColorInverted}),Object(u.pick)({prisma:Object(i.css)(C(),u.variables.borderRadius,u.variables.borderRadius)})),A=l.a.div(w()),M=l.a.button(j(),u.variables.linkColor,Object(u.pick)({enterprise:u.variables.backgroundColor,prisma:"transparent"})),B=l()(s.a)(x(),D),N=Object(i.css)(O(),D),z=Object(i.css)(g()),F=Object(i.css)(m()),$=Object(i.css)(y()),H=Object(i.css)(v()),V=Object(i.css)(h(),D),q=l.a.div(b(),u.mixins.reset("block"),u.variables.zindexToastMessages,(function(e){switch(e.position){case p.TOAST_POSITIONS.TOP_LEFT:return F;case p.TOAST_POSITIONS.TOP_CENTER:return N;case p.TOAST_POSITIONS.TOP_RIGHT:return z;case p.TOAST_POSITIONS.BOTTOM_LEFT:return $;case p.TOAST_POSITIONS.BOTTOM_CENTER:return V;case p.TOAST_POSITIONS.BOTTOM_RIGHT:return H;default:return N}})),W=l.a.p(d(),u.mixins.reset("block"),Object(u.pick)({prisma:Object(i.css)(f(),Object(u.pickVariant)("$type",{info:u.variables.contentColorActive,warning:u.variables.accentColorWarning,error:u.variables.accentColorNegative,success:u.variables.accentColorPositive}))}))},function(e,t){e.exports=n(1476)},function(e,t){e.exports=n(2916)},function(e,t){e.exports=n(2708)},function(e,t){e.exports=n(3940)},function(e,t){e.exports=n(6054)},function(e,t){e.exports=n(4003)},function(e,t){e.exports=n(3849)},function(e,t){e.exports=n(7794)},function(e,t,n){"use strict";n.r(t);var r=n(2),o=n.n(r),a=n(3),i=n.n(a),l=n(6),c=n.n(l),s=n(7),u=n(8),p=n.n(u),f=n(9),d=n.n(f),b=n(10),h=n.n(b),v=n(11),y=n.n(v),m=n(12),g=n.n(m),O=n(1),x=n(5),j="24px",w=function(e){var t=e.children;return o.a.createElement("svg",{viewBox:"0 0 24 24",width:j,height:j,xmlns:"http://www.w3.org/2000/svg"},t)};w.propTypes={children:i.a.node.isRequired};var C=function(e){var t=e.type,n="prisma"===g()().family?function(e){switch(e){case O.TOAST_TYPES.SUCCESS:return o.a.createElement(w,null,o.a.createElement("path",{fillRule:"evenodd",d:"M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM16.8738 8.62627C17.2643 9.01679 17.2643 9.64996 16.8738 10.0405L11.5853 15.329C10.9996 15.9147 10.0499 15.9148 9.46414 15.3291L7.12637 12.9921C6.73579 12.6016 6.7357 11.9684 7.12616 11.5779C7.51663 11.1873 8.1498 11.1872 8.54038 11.5776L10.5246 13.5613L15.4596 8.62627C15.8501 8.23574 16.4833 8.23574 16.8738 8.62627Z",fill:"currentColor"}));case O.TOAST_TYPES.INFO:return o.a.createElement(w,null,o.a.createElement("path",{fillRule:"evenodd",d:"M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM11.0001 16.0094V11.9999C11.0001 11.4476 11.4478 10.9999 12.0001 10.9999C12.5524 10.9999 13.0001 11.4476 13.0001 11.9999V16.0094C13.0001 16.5617 12.5524 17.0094 12.0001 17.0094C11.4478 17.0094 11.0001 16.5617 11.0001 16.0094ZM12 6.9999C12.6628 6.9999 13.2 7.53716 13.2 8.1999C13.2 8.86264 12.6628 9.3999 12 9.3999C11.3373 9.3999 10.8 8.86264 10.8 8.1999C10.8 7.53716 11.3373 6.9999 12 6.9999Z",fill:"currentColor"}));case O.TOAST_TYPES.ERROR:return o.a.createElement(w,null,o.a.createElement("path",{fillRule:"evenodd",d:"M22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12ZM11.0001 7.9906V12.0001C11.0001 12.5524 11.4478 13.0001 12.0001 13.0001C12.5524 13.0001 13.0001 12.5524 13.0001 12.0001V7.9906C13.0001 7.43832 12.5524 6.9906 12.0001 6.9906C11.4478 6.9906 11.0001 7.43832 11.0001 7.9906ZM12.0001 17.0001C12.6628 17.0001 13.2001 16.4628 13.2001 15.8001C13.2001 15.1374 12.6628 14.6001 12.0001 14.6001C11.3373 14.6001 10.8001 15.1374 10.8001 15.8001C10.8001 16.4628 11.3373 17.0001 12.0001 17.0001Z",fill:"currentColor"}));case O.TOAST_TYPES.WARNING:return o.a.createElement(w,null,o.a.createElement("path",{fillRule:"evenodd",d:"M10.6827 2.82369C11.2341 1.72544 12.7659 1.72544 13.3173 2.82369L21.8338 19.7867C22.3412 20.7973 21.6254 22 20.5165 22H3.48349C2.37462 22 1.65878 20.7973 2.16616 19.7867L10.6827 2.82369ZM11.0002 13.6618V11.0133C11.0002 10.461 11.4479 10.0133 12.0002 10.0133C12.5525 10.0133 13.0002 10.461 13.0002 11.0133V13.6618C13.0002 14.2141 12.5525 14.6618 12.0002 14.6618C11.4479 14.6618 11.0002 14.2141 11.0002 13.6618ZM13.2002 16.9347C13.2002 17.5975 12.6629 18.1347 12.0002 18.1347C11.3374 18.1347 10.8002 17.5975 10.8002 16.9347C10.8002 16.272 11.3374 15.7347 12.0002 15.7347C12.6629 15.7347 13.2002 16.272 13.2002 16.9347Z",fill:"currentColor"}));default:return o.a.createElement(w,null,o.a.createElement("path",{fillRule:"evenodd",d:"M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM11.0001 16.0094V11.9999C11.0001 11.4476 11.4478 10.9999 12.0001 10.9999C12.5524 10.9999 13.0001 11.4476 13.0001 11.9999V16.0094C13.0001 16.5617 12.5524 17.0094 12.0001 17.0094C11.4478 17.0094 11.0001 16.5617 11.0001 16.0094ZM12 6.9999C12.6628 6.9999 13.2 7.53716 13.2 8.1999C13.2 8.86264 12.6628 9.3999 12 9.3999C11.3373 9.3999 10.8 8.86264 10.8 8.1999C10.8 7.53716 11.3373 6.9999 12 6.9999Z",fill:"currentColor"}))}}(t):function(e){switch(e){case O.TOAST_TYPES.SUCCESS:return o.a.createElement(d.a,{size:j});case O.TOAST_TYPES.INFO:return o.a.createElement(p.a,{size:j});case O.TOAST_TYPES.ERROR:return o.a.createElement(h.a,{size:"26px"});case O.TOAST_TYPES.WARNING:return o.a.createElement(y.a,{size:j});default:return o.a.createElement(p.a,{size:j})}}(t);return o.a.createElement(x.c,{role:"img","data-test":t,"aria-label":"".concat(t," toast icon"),$type:t},n)};C.propTypes={type:i.a.string.isRequired};var S=C;function k(e){return k="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},k(e)}function P(){return P=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},P.apply(this,arguments)}function E(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function T(e,t){return T=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},T(e,t)}function D(e,t){return!t||"object"!==k(t)&&"function"!=typeof t?I(e):t}function I(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function R(e){return R=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},R(e)}function L(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var A=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&T(e,t)}(l,e);var t,n,r,a,i=(r=l,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=R(r);if(a){var n=R(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return D(this,e)});function l(){var e;E(this,l);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return L(I(e=i.call.apply(i,[this].concat(n))),"onMouseEnter",(function(){e.props.autoDismiss&&e.pause()})),L(I(e),"onMouseLeave",(function(){e.props.autoDismiss&&e.resume()})),L(I(e),"onActionClick",(function(t){e.fulfillActionCallback(t)})),L(I(e),"handleCloseKeyDown",(function(t){t.keyCode===Object(s.keycode)("enter")&&e.requestHide()})),L(I(e),"handleActionButtonKeyDown",(function(t){t.keyCode===Object(s.keycode)("enter")&&e.fulfillActionCallback(t)})),L(I(e),"isValidToastType",(function(e){switch(e){case O.TOAST_TYPES.SUCCESS:case O.TOAST_TYPES.INFO:case O.TOAST_TYPES.ERROR:case O.TOAST_TYPES.WARNING:return!0;default:return!1}})),L(I(e),"Timer",(function(t,n){var r=n,o=n;return e.pause=function(){window.clearTimeout(e.timerId),o-=new Date-r},e.resume=function(){return r=new Date,window.setTimeout((function(){t()}),o)},e.resume()})),L(I(e),"requestHide",(function(){(0,e.props.onRequestHide)()})),e}return t=l,(n=[{key:"componentDidMount",value:function(){if(this.props.autoDismiss){var e=this.props.timeout||5e3;this.timerId=this.Timer(this.requestHide,e)}}},{key:"componentWillUnmount",value:function(){this.props.autoDismiss&&this.timerId&&window.clearTimeout(this.timerId)}},{key:"fulfillActionCallback",value:function(e){var t=this.props,n=t.dismissOnActionClick;t.action.callback(e),n&&this.requestHide()}},{key:"render",value:function(){var e=this.props,t=e.title,n=e.type,r=e.action,a=e.message,i=e.onFocus,l=e.onBlur,s=(e.onRequestHide,function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["title","type","action","message","onFocus","onBlur","onRequestHide"])),u=o.a.createElement(S,{type:n}),p=o.a.createElement(x.e,{"data-test":"toast-message","aria-label":a,lang:navigator.language||navigator.userLanguage,title:a},a),f=r?o.a.createElement(x.a,P({"data-test":"toast-action",tabIndex:0,onClick:this.onActionClick,onFocus:i,onBlur:l,onKeyDown:this.handleActionButtonKeyDown,type:"button"},r.props),r.label):null,d=o.a.createElement("div",{role:"button","data-test":"toast-dismiss",style:{position:"absolute",top:"13px",right:"12px",color:"#818d99",cursor:"pointer"},tabIndex:0,focusable:"true",onClick:this.requestHide,onFocus:i,onBlur:l,onKeyDown:this.handleCloseKeyDown},o.a.createElement(c.a,{size:"12px"})),b=o.a.createElement("div",{style:t?{position:"absolute",top:"13px",right:"12px",color:"#818d99",cursor:"pointer"}:{display:"inline-block",marginTop:"5px",marginRight:"12px",float:"right",color:"#818d99",cursor:"pointer"}},o.a.createElement(c.a,{size:"12px"})),h=o.a.createElement(x.h,{role:"group","aria-label":"Toast content"},t&&o.a.createElement(x.f,{"data-test":"toast-message-title",$type:n},t),p," ",b," ",f," ",d);return o.a.createElement(x.g,P({role:"group","data-test":"toast","aria-label":"Toast container",onMouseEnter:this.onMouseEnter,onMouseLeave:this.onMouseLeave,$type:n},s),u,h)}}])&&_(t.prototype,n),l}(o.a.Component);A.propTypes={message:i.a.string.isRequired,type:i.a.string.isRequired,autoDismiss:i.a.bool,dismissOnActionClick:i.a.bool,action:i.a.shape({label:i.a.oneOfType([i.a.string,i.a.node]).isRequired,callback:i.a.func.isRequired,props:i.a.object}),title:i.a.string,timeout:i.a.number,onRequestHide:i.a.func,onFocus:i.a.func,onBlur:i.a.func},A.defaultProps={title:"",autoDismiss:!0,dismissOnActionClick:!0,onRequestHide:function(){},onFocus:function(){},onBlur:function(){}},t.default=A},function(e,t){e.exports=n(5220)},function(e,t){e.exports=n(2034)},function(e,t){e.exports=n(8568)},function(e,t){e.exports=n(5451)},,,,function(e,t,n){"use strict";n.r(t);var r=n(2),o=n.n(r),a=n(3),i=n.n(a),l=n(15),c=n(18),s=n.n(c),u=n(16),p=n.n(u),f=n(17),d=n(14),b=n(5),h=n(1);function v(e){return v="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},v(e)}function y(){return y=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},y.apply(this,arguments)}function m(e){return function(e){if(Array.isArray(e))return g(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return g(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?g(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function g(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function O(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function x(e,t){return x=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},x(e,t)}function j(e,t){return!t||"object"!==v(t)&&"function"!=typeof t?w(e):t}function w(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function C(e){return C=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},C(e)}function S(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var k={from:{transform:"translateY(-100%)",opacity:"0"},to:{transform:"translateY(0)",opacity:""}},P={from:{transform:"translateY(100%)",opacity:"0"},to:{transform:"translateY(0)",opacity:""}},E=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&x(e,t)}(c,e);var t,n,r,a,i=(r=c,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=C(r);if(a){var n=C(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return j(this,e)});function c(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,c),S(w(t=i.call(this,e)),"handleModalMount",(function(e){t.el=e,e&&Object(l.defer)(f.takeFocus,e,"container")})),S(w(t),"handleModalKeyDown",(function(e){Object(f.handleTab)(t.el,e)})),S(w(t),"handleToastCreate",(function(e){var n=-1!==t.props.position.indexOf("top");t.setState((function(t){return n?{toasts:[e].concat(m(t.toasts))}:{toasts:[].concat(m(t.toasts),[e])}}))})),S(w(t),"handleToastFocus",(function(e){t.setState((function(t){var n=t.toasts.filter((function(t){return t.id===e}));return n.length>0&&t.focusedToast!==n[0]?{focusedToast:n[0]}:null}))})),S(w(t),"handleRequestHide",(function(e){t.setState((function(t){var n=t.focusedToast||e;return{toasts:t.toasts.filter((function(e){return n.id!==e.id})),focusedToast:null}}))})),S(w(t),"renderLayer",(function(){var e=t.props,n=e.position,r=e.animationDuration,a=-1!==n.indexOf("top"),i=a?k:P;return o.a.createElement(b.d,{ref:t.handleModalMount,position:n,"data-test":"toast-messages",role:"group","aria-label":"Toast messages container",tabIndex:-1,onKeyDown:t.handleModalKeyDown},o.a.createElement(b.b,{enterAnimation:i,appearAnimation:i,leaveAnimation:"fade",duration:Object(l.isNil)(r)?200:r,easing:"cubic-bezier(0.25, 0.46, 0.45, 0.94)",verticalAlignment:a?"top":"bottom"},t.state.toasts.map((function(e){var n=e.id,r=e.title,a=e.message,i=e.type,l=e.autoDismiss,c=e.dismissOnActionClick,s=e.action,u=e.timeOut,p=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["id","title","message","type","autoDismiss","dismissOnActionClick","action","timeOut"]);return o.a.createElement(d.default,y({key:n,title:r,message:a,type:i,autoDismiss:l,dismissOnActionClick:c,action:s,timeout:u,onRequestHide:function(){return t.handleRequestHide(e)},onFocus:function(){return t.handleToastFocus(n)},onBlur:function(){return t.handleToastBlur()}},p))}))))})),t.state={toasts:e.toasts||[],focusedToast:null},t}return t=c,(n=[{key:"componentDidMount",value:function(){p.a.addCreateListener(this.handleToastCreate)}},{key:"componentWillUnmount",value:function(){this.setState({toasts:[],focusedToast:null}),p.a.removeCreateListener(this.handleToastCreate)}},{key:"handleToastBlur",value:function(){this.state.focusedToast&&this.setState({focusedToast:null})}},{key:"render",value:function(){var e=this,t=-1!==this.props.position.indexOf("top")?0:Math.max(this.state.toasts.length-1,0),n=this.state.toasts.length>0;return this.props.escapeToCloseToasts?o.a.createElement(s.a,{closeReasons:["escapeKey"],render:this.renderLayer,onRequestClose:function(){return e.handleRequestHide(e.state.toasts[t])},open:n},n&&this.renderLayer()):this.renderLayer()}}])&&O(t.prototype,n),c}(o.a.Component);E.propTypes={position:i.a.oneOf(Object(l.values)(h.TOAST_POSITIONS)).isRequired,animationDuration:i.a.number,toasts:i.a.arrayOf(i.a.object),escapeToCloseToasts:i.a.bool},E.defaultProps={escapeToCloseToasts:!0};var _=E,T=function(e){return o.a.createElement(_,{position:e.position})};T.propTypes={position:i.a.oneOf(["top-left","top-center","top-right","bottom-left","bottom-center","bottom-right"])},T.defaultProps={position:"top-center"},t.default=T}])},2130:(e,t,n)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=e.family,n=e.colorScheme,r=e.density,i=e.additionalThemeProperties,c=e.customizeTheme,u=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["family","colorScheme","density","additionalThemeProperties","customizeTheme"]),p=((0,o.useContext)(a.ThemeContext)||{}).splunkThemeV1,f=void 0===p?{}:p,d=s(s({},i),{},{splunkThemeV1:{family:t||f.family||"prisma",colorScheme:n||f.colorScheme||"dark",density:r||f.density||"comfortable",customizer:c||f.customizer}});return o.default.createElement(a.ThemeProvider,l({theme:d},u))};var o=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var t=i();if(t&&t.has(e))return t.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if(Object.prototype.hasOwnProperty.call(e,a)){var l=o?Object.getOwnPropertyDescriptor(e,a):null;l&&(l.get||l.set)?Object.defineProperty(n,a,l):n[a]=e[a]}return n.default=e,t&&t.set(e,n),n}(n(7294)),a=n(2788);function i(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return i=function(){return e},e}function l(){return l=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l.apply(this,arguments)}function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){u(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},3030:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={spacingQuarter:"5px",spacingHalf:"10px",spacing:"20px",fontSizeSmall:"12px",fontSize:"14px",fontSizeLarge:"16px",fontSizeXLarge:"18px",fontSizeXXLarge:"24px",lineHeight:"20px",inputHeight:"32px",borderRadius:"3px"}},2998:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={spacingQuarter:"5px",spacingHalf:"10px",spacing:"20px",fontSizeSmall:"12px",fontSize:"12px",fontSizeLarge:"16px",fontSizeXLarge:"18px",fontSizeXXLarge:"24px",lineHeight:"20px",inputHeight:"28px",borderRadius:"3px"}},257:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r,o=(r=n(6707))&&r.__esModule?r:{default:r};function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){l(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var c={backgroundColor:o.default.gray20,backgroundColorHover:o.default.gray30,borderColor:o.default.gray22,borderDarkColor:o.default.black,borderLightColor:o.default.gray60,textColor:o.default.white,textGray:o.default.gray92,textDisabledColor:o.default.gray45,linkColor:o.default.accentColorL10,linkColorHover:o.default.accentColorL20,border:"1px solid ".concat(o.default.gray22),borderDark:"1px solid ".concat(o.default.black),borderLight:"1px solid ".concat(o.default.gray60),focusShadowInset:"inset 0 0 1px 1px ".concat(o.default.gray25,", inset 0 0 0 3px ").concat(o.default.focusColor),draggableBackground:"url('data:image/png;base64,".concat("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAA1SURBVHgB7dKhEQAgDAPAhHmwSKZHYtmHVtZVVNTkXS53UeG57yPYazLmrB8o6h8QgPqBOAOboRAPJUGIOAAAAABJRU5ErkJggg==","') 0 0 / 8px 8px repeat")},s=i(i({},o.default),c);t.default=s},7872:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=c(n(6707)),o=c(n(257)),a=c(n(2998)),i=c(n(3030)),l=c(n(9918));function c(e){return e&&e.__esModule?e:{default:e}}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function u(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){p(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function p(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}t.default=function(e){var t=e.colorScheme,n=e.density,c={light:r.default,dark:o.default}[t],s={compact:a.default,comfortable:i.default}[n],p=(0,l.default)({colorScheme:t,density:n});return u(u(u({},c),s),p)}},6707:(e,t)=>{"use strict";function n(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function r(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var a={white:"#ffffff",gray98:"#f7f8fa",gray96:"#f2f4f5",gray92:"#e1e6eb",gray80:"#c3cbd4",gray60:"#818d99",gray45:"#5c6773",gray30:"#3c444d",gray25:"#31373e",gray22:"#2b3033",gray20:"#171d21",black:"#000000"},i={accentColorL50:"#ecf8ff",accentColorL40:"#bfe9ff",accentColorL30:"#7ed2ff",accentColorL20:"#3ebcff",accentColorL10:"#00a4fd",accentColor:"#007abd",accentColorD10:"#006eaa",accentColorD20:"#006297",accentColorD30:"#005684",accentColorD40:"#004a71",accentColorD50:"#003d5e"},l={textColor:a.gray30,textGray:"#6b7785",textDisabledColor:a.gray80,linkColor:i.accentColorD10,linkColorHover:i.accentColor,borderLightColor:a.gray92,borderColor:a.gray80,focusColor:i.accentColorD10,backgroundColorHover:a.gray96,backgroundColor:a.white,transparent:"transparent"},c={focusShadow:"0 0 1px 3px ".concat(l.focusColor),focusShadowInset:"inset 0 0 1px 1px ".concat(a.white,", inset 0 0 0 3px ").concat(l.focusColor),overlayShadow:"0 4px 8px rgba(0, 0, 0, 0.2)"},s={draggableBackground:"url('data:image/png;base64,".concat("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAA2SURBVHgB7dKhEQAgDAPAhDnxDMAcDIBnT1pZV1FRk3e53EWFc+2P4N3DmLN+oKh/QADqB+IMUKEQD/CeueAAAAAASUVORK5CYII=","') 0 0 / 8px 8px repeat")},u={borderRadius:"3px",border:"1px solid ".concat(l.borderColor)},p="'Splunk Platform Sans', 'Proxima Nova', Roboto, Droid, 'Helvetica Neue', Helvetica, Arial, sans-serif",f={sansFontFamily:p,serifFontFamily:"Georgia, 'Times New Roman', Times, serif",monoFontFamily:"'Splunk Platform Mono', Inconsolata, Consolas, 'Droid Sans Mono', Monaco, 'Courier New', Courier, monospace",fontFamily:p,fontWeightBold:"700",fontWeightSemiBold:"500"},d=r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r({},{brandColorL50:"#f5fbf5",brandColorL40:"#dff2df",brandColorL30:"#bee6be",brandColorL20:"#9ed99e",brandColorL10:"#7ecd7e",brandColor:"#5cc05c",brandColorD10:"#49b849",brandColorD20:"#40a540",brandColorD30:"#389038",brandColorD40:"#307b30",brandColorD50:"#286728"}),a),i),{errorColorL50:"#fcedec",errorColorL40:"#f8dcd9",errorColorL30:"#f1b9b3",errorColorL20:"#ea958d",errorColorL10:"#e37267",errorColor:"#dc4e41",errorColorD10:"#c84535",errorColorD20:"#b23d30",errorColorD30:"#9c3529",errorColorD40:"#852d24",errorColorD50:"#6f261d"}),{alertColorL50:"#fef3ec",alertColorL40:"#fde6d9",alertColorL30:"#facdb3",alertColorL20:"#f7b48c",alertColorL10:"#f49b66",alertColor:"#f1813f",alertColorD10:"#da742e",alertColorD20:"#c2672a",alertColorD30:"#aa5a25",alertColorD40:"#914d1f",alertColorD50:"#79401a"}),{warningColorL50:"#fff9eb",warningColorL40:"#fef2d7",warningColorL30:"#fde5ae",warningColorL20:"#fbd886",warningColorL10:"#facb5d",warningColor:"#f8be34",warningColorD10:"#e0ac16",warningColorD20:"#c79915",warningColorD30:"#ae8613",warningColorD40:"#957312",warningColorD50:"#7d600f"}),{successColorL50:"#eef6ee",successColorL40:"#ddecdd",successColorL30:"#bbd9ba",successColorL20:"#98c697",successColorL10:"#76b374",successColor:"#53a051",successColorD10:"#479144",successColorD20:"#40813d",successColorD30:"#387135",successColorD40:"#2f612e",successColorD50:"#275126"}),{infoColorL50:"#e5f0f5",infoColorL40:"#cce2eb",infoColorL30:"#99c5d7",infoColorL20:"#66a7c4",infoColorL10:"#338ab0",infoColor:"#006d9c",infoColorD10:"#00577c",infoColorD20:"#004c6c",infoColorD30:"#00415d",infoColorD40:"#00364d",infoColorD50:"#002b3e"}),{cat1Color:"#297ba5",cat1ColorL:"#78b9d6",cat2Color:"#4fa484",cat2ColorL:"#74d5c2",cat3Color:"#b6c75a",cat3ColorL:"#dce6a5",cat4Color:"#3c6188",cat4ColorL:"#a0b2ca",cat5Color:"#ec9960",cat5ColorL:"#fac9a7",cat6Color:"#a65c7d",cat6ColorL:"#d3a7ba",cat7Color:"#708794",cat7ColorL:"#b2c0c8",cat8Color:"#38b8bf",cat8ColorL:"#92dde2",cat9Color:"#ffde63",cat9ColorL:"#ffeeae",cat10Color:"#c19975",cat10ColorL:"#d7bfab",cat11Color:"#5a4575",cat11ColorL:"#b7acca",cat12Color:"#7ea77b",cat12ColorL:"#b2cab0",cat13Color:"#576d83",cat13ColorL:"#a5b2bf",cat14Color:"#d7c6b7",cat14ColorL:"#e9ddd4",cat15Color:"#339bb2",cat15ColorL:"#66c3d0",cat16Color:"#236d9b",cat16ColorL:"#66a7c2",cat17Color:"#e5dc80",cat17ColorL:"#f1eab7",cat18Color:"#96907f",cat18ColorL:"#c1bcb3",cat19Color:"#87bc65",cat19ColorL:"#b6d7a3",cat20Color:"#cf7e60",cat20ColorL:"#e1b2a1",cat21Color:"#7b5547",cat21ColorL:"#dec4ba",cat22Color:"#77d6d8",cat22ColorL:"#abe6e8",cat23Color:"#4a7f2c",cat23ColorL:"#91b282",cat24Color:"#f589ad",cat24ColorL:"#f8b7ce",cat25Color:"#6a2c5d",cat25ColorL:"#cba3c2",cat26Color:"#aaabae",cat26ColorL:"#cccdce",cat27Color:"#9a7438",cat27ColorL:"#c3ab89",cat28Color:"#a4d563",cat28ColorL:"#c7e6a3",cat29Color:"#7672a4",cat29ColorL:"#ada9c8",cat30Color:"#184b81",cat30ColorL:"#a4bbe0"}),{diverging1ColorA:"#006d9c",diverging1ColorB:"#ec9960",diverging2ColorA:"#af575a",diverging2ColorB:"#62b3b2",diverging3ColorA:"#4fa484",diverging3ColorB:"#f8be34",diverging4ColorA:"#5a4575",diverging4ColorB:"#708794",diverging5ColorA:"#294e70",diverging5ColorB:"#b6c75a"}),{syntaxBlue:"#2662fc",syntaxBlueLight:"#006d9c",syntaxBrown:"#a67f59",syntaxGray:"#8293a7",syntaxGreen:"#5ca300",syntaxGreenLight:"#5ba383",syntaxOrange:"#f58220",syntaxPink:"#cf00cf",syntaxPurple:"#7738ff",syntaxPurpleLight:"#b19cd9",syntaxRed:"#d90700",syntaxRedLight:"#af575a",syntaxTeal:"#00a8ab"}),f),l),s),c),u),{zindexFixedNavbar:1030,zindexModalBackdrop:1040,zindexModal:1050,zindexPopover:1060,zindexToastMessages:2e3});t.default=d},9918:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=c(n(7621)),o=c(n(6707)),a=c(n(257)),i=c(n(2998)),l=c(n(3030));function c(e){return e&&e.__esModule?e:{default:e}}t.default=function(e){var t=e.colorScheme,n=e.density,c={light:o.default,dark:a.default}[t],s={compact:i.default,comfortable:l.default}[n];return{accentColorPositive:c.successColor,accentColorWarning:c.warningColor,accentColorAlert:c.alertColor,accentColorNegative:c.errorColor,statusColorInfo:c.infoColorL10,statusColorNormal:c.successColorL10,statusColorLow:c.warningColorL10,statusColorMedium:c.alertColorL10,statusColorHigh:c.errorColorL10,statusColorCritical:c.errorColorD20,embossShadow:c.overlayShadow,dragShadow:c.overlayShadow,modalShadow:c.overlayShadow,backgroundColorPopup:c.backgroundColor,backgroundColorSection:c.backgroundColor,backgroundColorSidebar:c.backgroundColor,backgroundColorPage:c.backgroundColor,backgroundColorNavigation:c.backgroundColor,backgroundColorFloating:c.backgroundColor,backgroundColorDialog:c.backgroundColor,backgroundColorScrim:(0,r.default)(c.gray30).setAlpha(.8).toRgbString(),contentColorActive:c.textColor,contentColorDefault:c.textColor,contentColorMuted:c.textGray,contentColorDisabled:c.textDisabledColor,contentColorInverted:c.gray30,neutral100:"dark"===t?c.gray25:c.gray98,neutral200:"dark"===t?c.gray30:c.gray96,neutral300:"dark"===t?c.gray45:c.gray92,neutral400:"dark"===t?c.gray60:r.default.mix(c.gray92,c.gray80).toRgbString(),neutral500:c.gray80,interactiveColorPrimary:c.brandColor,interactiveColorBorder:c.borderColor,spacingXSmall:s.spacingQuarter,spacingSmall:s.spacingHalf,spacingMedium:"calc(".concat(s.spacing," * 0.75)"),spacingLarge:s.spacing,spacingXLarge:"calc(".concat(s.spacing," * 1.5)"),spacingXXLarge:"calc(".concat(s.spacing," * 2)"),spacingXXXLarge:"calc(".concat(s.spacing," * 2.5)")}}},3077:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=n(4150);t.default=function(e){var t,n=(null===(t=e.theme)||void 0===t?void 0:t.splunkThemeV1)||{},o=n.family,a=n.colorScheme,i=n.density;return(0,r.addThemeDefaults)({family:o,colorScheme:a,density:i})}},2843:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.clearGetThemeCache=t.default=void 0;var r=l(n(9776)),o=l(n(7872)),a=l(n(3286)),i=n(4150);function l(e){return e&&e.__esModule?e:{default:e}}function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){u(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var p=(0,r.default)((function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=(0,i.addThemeDefaults)(e),n=t.family,r=t.colorScheme,l=t.density,c="prisma"===n,u="enterprise"===n,p="comfortable"===l,f="compact"===l,d="dark"===r,b="light"===r;return Object.freeze(s({colorScheme:r,density:l,family:n,isPrisma:c,isEnterprise:u,isComfortable:p,isCompact:f,isDark:d,isLight:b},"enterprise"===n?(0,o.default)({colorScheme:r,density:l}):(0,a.default)({colorScheme:r,density:l})))}),(function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.family,n=e.colorScheme,r=e.density;return"".concat(t).concat(n).concat(r)}));t.clearGetThemeCache=function(){var e,t;return null===(e=(t=p.cache).clear)||void 0===e?void 0:e.call(t)};var f=p;t.default=f},3262:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r={getSettingsFromThemedProps:!0,getTheme:!0,mixins:!0,pick:!0,pickVariant:!0,SplunkThemeProvider:!0,useSplunkTheme:!0,withSplunkTheme:!0,variables:!0};Object.defineProperty(t,"getSettingsFromThemedProps",{enumerable:!0,get:function(){return o.default}}),Object.defineProperty(t,"getTheme",{enumerable:!0,get:function(){return a.default}}),Object.defineProperty(t,"mixins",{enumerable:!0,get:function(){return i.default}}),Object.defineProperty(t,"pick",{enumerable:!0,get:function(){return l.default}}),Object.defineProperty(t,"pickVariant",{enumerable:!0,get:function(){return c.default}}),Object.defineProperty(t,"SplunkThemeProvider",{enumerable:!0,get:function(){return s.default}}),Object.defineProperty(t,"useSplunkTheme",{enumerable:!0,get:function(){return u.default}}),Object.defineProperty(t,"withSplunkTheme",{enumerable:!0,get:function(){return p.default}}),Object.defineProperty(t,"variables",{enumerable:!0,get:function(){return f.default}});var o=b(n(3077)),a=b(n(2843)),i=b(n(5779)),l=b(n(317)),c=b(n(3560)),s=b(n(2130)),u=b(n(3849)),p=b(n(2930)),f=b(n(321)),d=n(2609);function b(e){return e&&e.__esModule?e:{default:e}}Object.keys(d).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||Object.defineProperty(t,e,{enumerable:!0,get:function(){return d[e]}}))}))},5779:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.clearfix=p,t.ellipsis=f,t.printWidth100Percent=d,t.printHide=b,t.printNoBackground=h,t.printWrapAll=v,t.screenReaderContent=y,t.overlayColors=m,t.colorWithAlpha=g,t.default=t.reset=void 0;var r=c(n(7621)),o=n(2788),a=n(691),i=c(n(321)),l=c(n(317));function c(e){return e&&e.__esModule?e:{default:e}}function s(){var e,t,n=(e=["\n        /* Generic resets */\n        animation: none 0s ease 0s 1 normal none running;\n        backface-visibility: visible;\n        background: transparent none repeat 0 0 / auto auto padding-box border-box scroll;\n        border: medium none currentColor;\n        border-collapse: separate;\n        border-image: none;\n        border-radius: 0;\n        border-spacing: 0;\n        bottom: auto;\n        box-shadow: none;\n        caption-side: top;\n        clear: none;\n        clip: auto;\n        columns: auto;\n        column-count: auto;\n        column-fill: balance;\n        column-gap: normal;\n        column-rule: medium none currentColor;\n        column-span: 1;\n        column-width: auto;\n        content: normal;\n        counter-increment: none;\n        counter-reset: none;\n        empty-cells: show;\n        float: none;\n        font-style: normal;\n        font-variant: normal;\n        font-weight: normal;\n        font-stretch: normal;\n        height: auto;\n        hyphens: none;\n        left: auto;\n        letter-spacing: normal;\n        list-style: disc outside none;\n        margin: 0;\n        max-height: none;\n        max-width: none;\n        min-height: 0;\n        min-width: 0;\n        opacity: 1;\n        orphans: 2;\n        overflow: visible;\n        overflow-x: visible;\n        overflow-y: visible;\n        padding: 0;\n        page-break-after: auto;\n        page-break-before: auto;\n        page-break-inside: auto;\n        perspective: none;\n        perspective-origin: 50% 50%;\n        pointer-events: auto;\n        position: static;\n        right: auto;\n        tab-size: 8;\n        table-layout: auto;\n        text-align: left;\n        text-align-last: auto;\n        text-decoration: none;\n        text-indent: 0;\n        text-shadow: none;\n        text-transform: none;\n        top: auto;\n        transform: none;\n        transform-origin: 50% 50% 0;\n        transform-style: flat;\n        transition: none 0s ease 0s;\n        user-select: auto;\n        vertical-align: baseline;\n        white-space: normal;\n        widows: 2;\n        width: auto;\n        word-spacing: normal;\n        z-index: auto;\n        /* Splunk-specific resets */\n        border-width: 1px;\n        box-sizing: border-box;\n        color: ",";\n        cursor: inherit;\n        display: ",";\n        font-family: ",";\n        font-size: ",";\n        line-height: ",";\n        outline: medium none ",";\n        visibility: inherit;\n    "],t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}})));return s=function(){return n},n}var u=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"inline";return function(){return(0,o.css)(s(),(0,l.default)({enterprise:i.default.textColor,prisma:i.default.contentColorDefault}),e,i.default.fontFamily,i.default.fontSize,i.default.lineHeight,i.default.focusColor)}};function p(){return{"&::after":{display:"table",content:'""',clear:"both"}}}function f(){return{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}function d(){return{maxWidth:"100% !important",width:"100% !important",overflow:"hidden !important"}}function b(){return{display:"none !important"}}function h(){return{background:"none !important"}}function v(){return{wordBreak:"break-all !important",wordWrap:"break-word !important",overflowWrap:"break-word !important",whiteSpace:"normal !important"}}function y(){return{position:"absolute",overflow:"hidden",clip:"rect(0 0 0 0)",height:"1px",width:"1px",margin:"-1px",padding:0,border:0}}function m(e,t){return function(n){var o="function"==typeof e?e(n):e,i="function"==typeof t?t(n):t,l=(0,a.normal)((0,r.default)(o).toRgb(),(0,r.default)(i).toRgb());return(0,r.default)(l).toRgbString()}}function g(e,t){return function(n){var o="function"==typeof e?e(n):e;return(0,r.default)(o).setAlpha(t).toRgbString()}}t.reset=u;var O={reset:u,clearfix:p,ellipsis:f,printWidth100Percent:d,printHide:b,printNoBackground:h,printWrapAll:v,screenReaderContent:y,colorWithAlpha:g,overlayColors:m};t.default=O},317:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isInterpolationResult=i,t.default=t.getThemeVariant=void 0;var r=n(4150);function o(e){return o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o(e)}var a={enterprise:"family",prisma:"family",light:"colorScheme",dark:"colorScheme",compact:"density",comfortable:"density"};function i(e){return"object"!==o(e)||Array.isArray(e)||null===e}var l=function e(t,n){var r=Object.keys(t).shift();if(!r)throw new Error("A pick tree cannot be empty.");var o=a[r];if(!o)throw new Error("Invalid pick tree key: ".concat(r));var l=t[n[o]];return i(l)?l:e(l,n)};t.getThemeVariant=l;t.default=function(e){return function(t){var n=t.theme,o=(0,r.addThemeDefaults)(null==n?void 0:n.splunkThemeV1);return l(e,o)}}},3560:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=n(317),o=n(4150);t.default=function(e,t){return function(n){var a,i=n[e],l=t[i];if((0,r.isInterpolationResult)(l))return l;var c=(0,o.addThemeDefaults)(null===(a=n.theme)||void 0===a?void 0:a.splunkThemeV1);return(0,r.getThemeVariant)(l,c)}}},7865:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=l(n(7621)),o=l(n(3929)),a=l(n(5042)),i=l(n(4189));function l(e){return e&&e.__esModule?e:{default:e}}function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){u(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}t.default=function(e){var t=e.colorScheme,n={light:a.default,dark:i.default}[t],l={focusColor:(0,r.default)(n.interactiveColorPrimary).setAlpha(.7).toRgbString(),transparent:"transparent",linkColor:n.interactiveColorPrimary},c={hoverShadow:"0 0 0 2px ".concat(n.backgroundColorPage,", 0 0 0 5px ").concat(n.interactiveColorOverlayHover),focusShadow:"0 0 0 2px ".concat(n.backgroundColorPage,", 0 0 0 5px ").concat(l.focusColor),focusShadowInset:"inset 0 0 0 3px ".concat(l.focusColor)},u={draggableBackground:"radial-gradient(circle at 1px 1px, ".concat(n.contentColorMuted,", ").concat(n.contentColorMuted," 1px, transparent 1px) 0 0 / 4px 6px")},p="'Splunk Platform Sans', 'Splunk Data Sans', Roboto, Droid, 'Helvetica Neue', Helvetica, Arial, sans-serif";return s(s(s(s(s(s({},{sansFontFamily:p,serifFontFamily:"Georgia, 'Times New Roman', Times, serif",monoFontFamily:"'Splunk Platform Mono', 'Roboto Mono', Consolas, 'Droid Sans Mono', Monaco, 'Courier New', Courier, monospace",fontFamily:p,fontWeightBold:"700",fontWeightSemiBold:"500"}),l),o.default),c),u),{zindexFixedNavbar:1030,zindexModalBackdrop:1040,zindexModal:1050,zindexPopover:1060,zindexToastMessages:2e3})}},5069:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={spacingXSmall:"4px",spacingSmall:"8px",spacingMedium:"12px",spacingLarge:"16px",spacingXLarge:"24px",spacingXXLarge:"32px",spacingXXXLarge:"40px",fontSizeSmall:"12px",fontSize:"14px",fontSizeLarge:"16px",fontSizeXLarge:"18px",fontSizeXXLarge:"24px",lineHeight:"20px",inputHeight:"40px",borderRadius:"4px"}},1808:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={spacingXSmall:"4px",spacingSmall:"8px",spacingMedium:"12px",spacingLarge:"16px",spacingXLarge:"24px",spacingXXLarge:"32px",spacingXXXLarge:"40px",fontSizeSmall:"12px",fontSize:"14px",fontSizeLarge:"16px",fontSizeXLarge:"18px",fontSizeXXLarge:"24px",lineHeight:"20px",inputHeight:"32px",borderRadius:"4px"}},4189:(e,t)=>{"use strict";function n(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function r(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var a=r(r(r(r(r(r(r(r({},{accentColorPositive:"#27f561",accentColorWarning:"#ffd442",accentColorAlert:"#ff9750",accentColorNegative:"#ff5c5c"}),{statusColorInfo:"#61cafa",statusColorNormal:"#85eb48",statusColorLow:"#fae75f",statusColorMedium:"#f5b53f",statusColorHigh:"#ec4B43",statusColorCritical:"#a81916"}),{embossShadow:"0px 1px 5px rgba(0, 0, 0, 0.35), 0px 0px 1px rgba(0, 0, 0, 0.35)",overlayShadow:"0px 26px 103px rgba(0, 0, 0, 0.64), 0px 11px 18px rgba(0, 0, 0, 0.32), 0px 3px 6px rgba(0, 0, 0, 0.3)",dragShadow:"0px 26px 103px rgba(0, 0, 0, 0.64), 0px 11px 18px rgba(0, 0, 0, 0.32), 0px 3px 6px rgba(0, 0, 0, 0.3)",modalShadow:"0px 50px 200px #000000, 0px 29px 66px rgba(0, 0, 0, 0.41), 0px 14px 47px rgba(0, 0, 0, 0.17), 0px 5px 10px rgba(0, 0, 0, 0.15)"}),{backgroundColorPopup:"#27292e",backgroundColorSection:"#1a1c20",backgroundColorSidebar:"#0b0c0e",backgroundColorPage:"#111215",backgroundColorNavigation:"#08090a",backgroundColorFloating:"#ffffff",backgroundColorDialog:"#1e2024",backgroundColorScrim:"rgba(0, 0, 0, 0.8)"}),{contentColorActive:"#fafafa",contentColorDefault:"#b5b5b5",contentColorDisabled:"#6b6b6b",contentColorInverted:"#000000",contentColorMuted:"#909090"}),{black:"#000000",neutral100:"#33343b",neutral200:"#43454b",neutral300:"#505158",neutral400:"#818285",neutral500:"#acacad",white:"#ffffff"}),{interactiveColorPrimary:"#3993FF",interactiveColorBorder:"rgba(255, 255, 255, 0.5)",interactiveColorBorderHover:"rgba(255, 255, 255, 0.7)",interactiveColorBorderDisabled:"rgba(255, 255, 255, 0.30)",interactiveColorOverlaySelected:"rgba(255, 255, 255, 0.1)",interactiveColorOverlayHover:"rgba(255, 255, 255, 0.05)",interactiveColorOverlayActive:"rgba(0, 0, 0, 0.2)",interactiveColorOverlayDrag:"rgba(57, 147, 255, 0.16)",interactiveColorBackground:"#272a2f",interactiveColorBackgroundDisabled:"rgba(255, 255, 255, 0.15)"}),{syntaxBlue:"#6cd0f0",syntaxBrown:"#fccf87",syntaxGray:"#7d7d7d",syntaxGreen:"#cef06c",syntaxOrange:"#f7933f",syntaxPink:"#f494e5",syntaxPurple:"#a870ef",syntaxRed:"#e85b79",syntaxTeal:"#45d4ba"});t.default=a},3929:(e,t)=>{"use strict";function n(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function r(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.highLow=t.sequential=t.divergent=t.categorical=t.staticColors=void 0;var a={static1:"#7B56DB",static2:"#009CEB",static3:"#00CDAF",static4:"#DD9900",static5:"#FF677B",static6:"#CB2196",static7:"#813193",static8:"#0051B5",static9:"#008C80",static10:"#99B100",static11:"#FFA476",static12:"#FF6ACE",static13:"#AE8CFF",static14:"#00689D",static15:"#00490A",static16:"#465D00",static17:"#9D6300",static18:"#F6540B",static19:"#FF969E",static20:"#E47BFE"};t.staticColors=a;var i=r(r(r(r({},{categorical1D1:"#5C33FF",categorical1D2:"#207865",categorical1D3:"#AD3F20",categorical1D4:"#003E80",categorical1D5:"#78062A",categorical1D6:"#2F8811",categorical1D7:"#555555"}),{categorical1L1:"#9980FF",categorical1L2:"#45D4BA",categorical1L3:"#FB865C",categorical1L4:"#66AAF9",categorical1L5:"#E85B79",categorical1L6:"#88EE66",categorical1L7:"#F0B000"}),{categorical2D1:"#1F4D5B",categorical2D2:"#CC0AD6",categorical2D3:"#017FA2",categorical2D4:"#D81E5B",categorical2D5:"#621FFF",categorical2D6:"#348350",categorical2D7:"#555555"}),{categorical2L1:"#5599BE",categorical2L2:"#FB9DFB",categorical2L3:"#00BBEE",categorical2L4:"#EE3399",categorical2L5:"#9980FF",categorical2L6:"#5FBF7F",categorical2L7:"#F58B00"});t.categorical=i;var l=r(r(r(r(r(r(r(r({},{divergent1D1:"#118832",divergent1D2:"#1C6B2D",divergent1D3:"#284D27",divergent1D4:"#333022",divergent1D5:"#692A21",divergent1D6:"#9E2520",divergent1D7:"#D41F1F"}),{divergent1L1:"#08AE37",divergent1L2:"#55C169",divergent1L3:"#A1D59C",divergent1L4:"#EEE8CE",divergent1L5:"#F4BAA9",divergent1L6:"#F98C83",divergent1L7:"#FF5E5E"}),{divergent2D1:"#0070F3",divergent2D2:"#115BAD",divergent2D3:"#224468",divergent2D4:"#333022",divergent2D5:"#692A21",divergent2D6:"#9E2520",divergent2D7:"#D41F1F"}),{divergent2L1:"#2A99FF",divergent2L2:"#6BB3EE",divergent2L3:"#ADCCDD",divergent2L4:"#EEE8CE",divergent2L5:"#F4BAA9",divergent2L6:"#F98C83",divergent2L7:"#FF5E5E"}),{divergent3D1:"#299986",divergent3D2:"#277C52",divergent3D3:"#24551F",divergent3D4:"#333022",divergent3D5:"#422879",divergent3D6:"#602CA1",divergent3D7:"#8747DA"}),{divergent3L1:"#14846C",divergent3L2:"#45D4BA",divergent3L3:"#9ADEC4",divergent3L4:"#EEE8CE",divergent3L5:"#D7BEE4",divergent3L6:"#C093F9",divergent3L7:"#9156DD"}),{divergent4D1:"#0D8387",divergent4D2:"#1A6765",divergent4D3:"#264C44",divergent4D4:"#333022",divergent4D5:"#693623",divergent4D6:"#9F3B23",divergent4D7:"#D54124"}),{divergent4L1:"#008287",divergent4L2:"#2EA39B",divergent4L3:"#5CC3AF",divergent4L4:"#EEE8CE",divergent4L5:"#ECA14E",divergent4L6:"#E3723A",divergent4L7:"#DA4325"});t.divergent=l;var c=r(r(r(r(r(r(r(r(r(r(r(r({},{sequential1D1:"#118832",sequential1D2:"#669922",sequential1D3:"#9D9F0D",sequential1D4:"#CBA700",sequential1D5:"#D97A0D",sequential1D6:"#D94E17",sequential1D7:"#D41F1F"}),{sequential1L1:"#088F44",sequential1L2:"#2EB82E",sequential1L3:"#C3CC33",sequential1L4:"#FFD442",sequential1L5:"#FFA857",sequential1L6:"#FF7149",sequential1L7:"#FE3A3A"}),{sequential2D1:"#333022",sequential2D2:"#3D2830",sequential2D3:"#562E4C",sequential2D4:"#6F3468",sequential2D5:"#873A83",sequential2D6:"#A0409F",sequential2D7:"#B846BB"}),{sequential2L1:"#EEE8CE",sequential2L2:"#E8C7CE",sequential2L3:"#E1A6CD",sequential2L4:"#DB86CD",sequential2L5:"#D465CD",sequential2L6:"#CE44CC",sequential2L7:"#C723CC"}),{sequential3D1:"#333022",sequential3D2:"#253223",sequential3D3:"#244333",sequential3D4:"#245442",sequential3D5:"#246451",sequential3D6:"#237561",sequential3D7:"#238570"}),{sequential3L1:"#EEE8CE",sequential3L2:"#B6ECD4",sequential3L3:"#7EEFDA",sequential3L4:"#45D4BA",sequential3L5:"#35B9A0",sequential3L6:"#249F86",sequential3L7:"#14846C"}),{sequential4D1:"#333022",sequential4D2:"#442519",sequential4D3:"#64271F",sequential4D4:"#832A24",sequential4D5:"#A0312E",sequential4D6:"#BD3737",sequential4D7:"#DA3B30"}),{sequential4L1:"#EEE8CE",sequential4L2:"#F5CEBF",sequential4L3:"#FCB4B0",sequential4L4:"#F99C96",sequential4L5:"#F6847C",sequential4L6:"#DF564D",sequential4L7:"#DD2E2E"}),{sequential5D1:"#2E2E55",sequential5D2:"#4B1773",sequential5D3:"#77136A",sequential5D4:"#A81A45",sequential5D5:"#D24620",sequential5D6:"#D97A0D",sequential5D7:"#CBA700"}),{sequential5L1:"#EEE8CE",sequential5L2:"#F2DD88",sequential5L3:"#FFC355",sequential5L4:"#FF9D66",sequential5L5:"#FF7777",sequential5L6:"#EE4477",sequential5L7:"#DD22BB"}),{sequential6D1:"#1C3355",sequential6D2:"#005580",sequential6D3:"#007575",sequential6D4:"#118832",sequential6D5:"#669922",sequential6D6:"#9D9F0D",sequential6D7:"#CBA700"}),{sequential6L1:"#EEE8CE",sequential6L2:"#E7E755",sequential6L3:"#A3E052",sequential6L4:"#0AD647",sequential6L5:"#00BBBB",sequential6L6:"#1182F3",sequential6L7:"#6666DD"});t.sequential=c;var s=r(r(r(r(r(r(r(r({},{highLow1DHigh:"#1C6B2D",highLow1DLow:"#9E2520"}),{highLow1LHigh:"#55C169",highLow1LLow:"#F98C83"}),{highLow2DHigh:"#115BAD",highLow2DLow:"#9E2520"}),{highLow2LHigh:"#6BB3EE",highLow2LLow:"#F98C83"}),{highLow3DHigh:"#277C52",highLow3DLow:"#602CA1"}),{highLow3LHigh:"#45D4BA",highLow3LLow:"#C093F9"}),{highLow4DHigh:"#1A6765",highLow4DLow:"#9F3B23"}),{highLow4LHigh:"#2EA39B",highLow4LLow:"#E3723A"});t.highLow=s;var u=r(r(r(r(r({},a),i),l),c),s);t.default=u},3286:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=c(n(5042)),o=c(n(4189)),a=c(n(1808)),i=c(n(5069)),l=c(n(7865));function c(e){return e&&e.__esModule?e:{default:e}}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function u(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){p(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function p(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}t.default=function(e){var t=e.colorScheme,n=e.density,c={light:r.default,dark:o.default}[t],s={compact:a.default,comfortable:i.default}[n];return u(u(u({},(0,l.default)({colorScheme:t})),c),s)}},5042:(e,t)=>{"use strict";function n(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function r(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var a=r(r(r(r(r(r(r(r({},{accentColorPositive:"#118832",accentColorWarning:"#cca700",accentColorAlert:"#cf750c",accentColorNegative:"#d41f1f"}),{statusColorInfo:"#61cafa",statusColorNormal:"#85eb48",statusColorLow:"#fae75f",statusColorMedium:"#f5b53f",statusColorHigh:"#ec4B43",statusColorCritical:"#9c0300"}),{embossShadow:" 0px 1px 5px rgba(0, 0, 0, 0.07), 0px 0px 1px rgba(0, 0, 0, 0.07)",overlayShadow:"0px 26px 103px rgba(0, 0, 0, 0.13), 0px 11px 18px rgba(0, 0, 0, 0.06), 0px 3px 6px rgba(0, 0, 0, 0.06)",dragShadow:"0px 26px 103px rgba(0, 0, 0, 0.13), 0px 11px 18px rgba(0, 0, 0, 0.06), 0px 3px 6px rgba(0, 0, 0, 0.06)",modalShadow:"0px 50px 200px rgba(0, 0, 0, 0.3), 0px 29px 66px rgba(0, 0, 0, 0.08), 0px 29px 47px rgba(0, 0, 0, 0.08), 0px 5px 10px rgba(0, 0, 0, 0.03)"}),{backgroundColorPopup:"#ffffff",backgroundColorSection:"#ffffff",backgroundColorSidebar:"#f8f8f8",backgroundColorPage:"#f9f9f9",backgroundColorNavigation:"#f7f7f7",backgroundColorFloating:"#000000",backgroundColorDialog:"#ffffff",backgroundColorScrim:"rgba(255, 255, 255, 0.75)"}),{contentColorActive:"#2c2c2c",contentColorDefault:"#4d4d4d",contentColorDisabled:"#878787",contentColorInverted:"#ffffff",contentColorMuted:"#6b6b6b"}),{white:"#ffffff",neutral100:"#f0f0f0",neutral200:"#e6e6e6",neutral300:"#dddddd",neutral400:"#cacaca",neutral500:"#b8b8b8",black:"#000000"}),{interactiveColorPrimary:"#0264d7",interactiveColorBorder:"rgba(0, 0, 0, 0.4)",interactiveColorBorderHover:"rgba(0, 0, 0, 0.6)",interactiveColorBorderDisabled:"rgba(0, 0, 0, 0.3)",interactiveColorOverlaySelected:"rgba(0, 0, 0, 0.04)",interactiveColorOverlayHover:"rgba(0, 0, 0, 0.03)",interactiveColorOverlayActive:"rgba(0, 0, 0, 0.07)",interactiveColorOverlayDrag:"rgba(2, 100, 215, 0.16)",interactiveColorBackground:"#eeeeee",interactiveColorBackgroundDisabled:"rgba(0, 0, 0, 0.1)"}),{syntaxBlue:"#107d9f",syntaxBrown:"#a26604",syntaxGray:"#737373",syntaxGreen:"#607d0d",syntaxOrange:"#b75808",syntaxPink:"#d015b2",syntaxPurple:"#7f52f5",syntaxRed:"#df1f48",syntaxTeal:"#1e816f"});t.default=a},2609:()=>{},3849:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=n(7294),o=n(2788),a=n(4150);function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){c(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}t.default=function(){var e=(0,r.useContext)(o.ThemeContext)||{},t=e.splunkThemeV1,n=void 0===t?{}:t,i=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["splunkThemeV1"]),c=n.family,s=n.colorScheme,u=n.density,p=n.customizer;return l(l({},i),(0,a.getCustomizedTheme)({family:c,colorScheme:s,density:u},p))}},4150:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getCustomizedTheme=t.addThemeDefaults=void 0;var r,o=n(5220),a=(r=n(2843))&&r.__esModule?r:{default:r};t.addThemeDefaults=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.family,n=void 0===t?"prisma":t,r=e.colorScheme,o=void 0===r?"dark":r,a=e.density,i=void 0===a?"comfortable":a,l=e.isPrisma,c=void 0===l||l,s=e.isEnterprise,u=void 0!==s&&s,p=e.isComfortable,f=void 0===p||p,d=e.isCompact,b=void 0!==d&&d,h=e.isDark,v=void 0===h||h,y=e.isLight,m=void 0!==y&&y;return{family:n,colorScheme:o,density:i,isPrisma:c,isEnterprise:u,isComfortable:f,isCompact:b,isDark:v,isLight:m}};var i=(0,o.memoize)((function(e,t){var n=(0,a.default)(e);return t?t(n):n}),(function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.family,n=e.colorScheme,r=e.density,o=arguments.length>1?arguments[1]:void 0;return"".concat(t,"-").concat(n,"-").concat(r,"-").concat(!!o)}));t.getCustomizedTheme=i},321:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.clearVariablesCache=t.default=void 0;var r=i(n(9776)),o=i(n(2843)),a=n(4150);function i(e){return e&&e.__esModule?e:{default:e}}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var u=(0,r.default)((function(e,t,n){return(0,a.getCustomizedTheme)(t,n)[e]}),(function(e,t,n){var r=t.family,o=t.colorScheme,a=t.density;return"".concat(e,"-").concat(r,"-").concat(o,"-").concat(a,"-").concat(!!n)}));t.clearVariablesCache=function(){var e,t;return null===(e=(t=u.cache).clear)||void 0===e?void 0:e.call(t)};var p=Object.keys(c(c({},(0,o.default)({family:"prisma"})),(0,o.default)({family:"enterprise"}))).reduce((function(e,t){var n;return Object.defineProperty(e,t,{value:(n=t,function(e){var t=e.theme,r=(t=void 0===t?{}:t).splunkThemeV1||{},o=r.family,a=r.colorScheme,i=r.density,l=r.customizer;return u(n,{family:o,colorScheme:a,density:i},l)})}),e}),{});t.default=p},2930:(e,t,n)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var t=l();if(t&&t.has(e))return t.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if(Object.prototype.hasOwnProperty.call(e,a)){var i=o?Object.getOwnPropertyDescriptor(e,a):null;i&&(i.get||i.set)?Object.defineProperty(n,a,i):n[a]=e[a]}return n.default=e,t&&t.set(e,n),n}(n(7294)),a=n(2788),i=n(4150);function l(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return l=function(){return e},e}function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function u(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){p(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function p(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}t.default=function(e){var t=o.default.forwardRef((function(t,n){var r=(0,o.useContext)(a.ThemeContext)||{},l=r.splunkThemeV1,s=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(r,["splunkThemeV1"]),p=l||{},f=p.family,d=p.colorScheme,b=p.density,h=p.customizer,v=(0,i.addThemeDefaults)({family:f,colorScheme:d,density:b}),y=u(u({},s),(0,i.getCustomizedTheme)(v,h));return o.default.createElement(e,c({},t,{ref:n,splunkTheme:y}))})),n=e.displayName||e.name||"Component";return t.displayName="withSplunkTheme(".concat(n,")"),t}},308:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=153)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},153:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return b}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(3),c=n.n(l),s=n(0),u=c.a.a.withConfig({displayName:"AnchorStyles__StyledAnchor",componentId:"sc-1m9yzet-0"})(["",";color:inherit;font-size:inherit;font-family:inherit;font-weight:inherit;line-height:inherit;text-decoration:inherit;text-rendering:inherit;text-transform:inherit;cursor:pointer;margin:1px;&:hover::after{content:' #';opacity:0.5;}&:focus,&:active{box-shadow:",";&::after{content:' #';opacity:0.5;}}"],s.mixins.reset("inline"),s.variables.focusShadow);function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},p.apply(this,arguments)}var f={children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),name:i.a.string.isRequired};function d(e){var t=e.children,n=e.elementRef,r=e.name,a=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","elementRef","name"]);return o.a.createElement(u,p({"data-test":"anchor",ref:n},a,{name:r,href:"#".concat(r)}),t)}d.propTypes=f;var b=d},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)}})},5864:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=155)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},155:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return v}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(3),c=n.n(l),s=n(8),u=n.n(s),p=n(0),f=c()(u.a).withConfig({displayName:"ButtonGroupStyles__StyledBox",componentId:"sc-14fs2xs-0"})(["position:relative;[data-inline] + &{margin-left:",";}"],Object(p.pick)({enterprise:p.variables.spacingHalf,prisma:p.variables.spacingSmall}));function d(){return d=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},d.apply(this,arguments)}var b={children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),flex:i.a.bool};function h(e){var t=e.children,n=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children"]),a=r.Children.toArray(t).filter(r.isValidElement).map((function(e,t,n){var o=n.length;return Object(r.cloneElement)(e,{prepend:t>0,append:t<o-1,inline:!1,role:e.props&&e.props.role||"menuitem"})}));return o.a.createElement(f,d({inline:!0,flex:!0,"data-test":"button-group",role:"menubar"},n),a)}h.propTypes=b;var v=h},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)},8:function(e,t){e.exports=n(6493)}})},2978:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=121)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},12:function(e,t){e.exports=n(5917)},121:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return se})),n.d(t,"Header",(function(){return F})),n.d(t,"Body",(function(){return v})),n.d(t,"Footer",(function(){return x}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(3),c=n.n(l),s=n(8),u=n.n(s),p=n(0),f=c()(u.a).withConfig({displayName:"BodyStyles__StyledBox",componentId:"sc-1130udp-0"})(["flex:1 1 auto;overflow:auto;height:100%;",";",""],(function(e){return e.$inset?Object(l.css)(["",""],Object(p.pick)({enterprise:Object(l.css)(["padding:",";&:not(:first-child){padding-top:0;}"],p.variables.spacing),prisma:{comfortable:Object(l.css)(["padding:12px 24px;&:first-child{padding-top:28px;}&:last-child{padding-bottom:28px;}"]),compact:Object(l.css)(["padding:8px 24px;&:first-child{padding-top:20px;}&:last-child{padding-bottom:20px;}"])}})):Object(l.css)(["padding:0;"])}),Object(p.pick)({prisma:{comfortable:Object(l.css)(["border-radius:",";color:",";"],p.variables.borderRadius,p.variables.contentColorMuted),compact:Object(l.css)(["border-radius:",";color:",";"],p.variables.borderRadius,p.variables.contentColorMuted)}}));function d(){return d=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},d.apply(this,arguments)}var b={children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),inset:i.a.bool};function h(e){var t=e.children,n=e.inset,r=void 0===n||n,a=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","inset"]);return o.a.createElement(f,d({"data-test":"body",$inset:r},a),t)}h.propTypes=b;var v=h,y=c()(u.a).withConfig({displayName:"FooterStyles__StyledBox",componentId:"sc-1yu3r4s-0"})(["",";text-align:right;color:",";",""],Object(p.pick)({enterprise:Object(l.css)(["padding:",";&:first-child{border-top:none;}"],p.variables.spacing),prisma:{comfortable:Object(l.css)(["padding:24px;"]),compact:"padding: 18px 24px"}}),p.variables.contentColorMuted,(function(e){return e.$showTopBorder&&Object(p.pick)({enterprise:Object(l.css)(["border-top:1px solid ",";"],p.variables.gray92)})}));function m(){return m=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},m.apply(this,arguments)}var g={children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),showBorder:i.a.bool};function O(e){var t=e.children,n=e.showBorder,r=void 0===n||n,a=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","showBorder"]);return o.a.createElement(y,m({"data-test":"footer",$showTopBorder:r},a),t)}O.propTypes=g;var x=O,j=n(5),w=n(64),C=n.n(w),S=n(16),k=n.n(S),P=n(20),E=n.n(P),_=n(42),T=n.n(_),D=n(65),I=c.a.div.withConfig({displayName:"HeaderStyles__StyledTitle",componentId:"eqi6uk-0"})([""," "," margin:0;overflow-wrap:break-word;padding:0;"],p.mixins.reset("block"),Object(p.pick)({enterprise:Object(l.css)(["font-weight:",";font-size:",";line-height:1.2;"],p.variables.fontWeightSemiBold,p.variables.fontSizeLarge),prisma:Object(l.css)(["font-weight:",";color:",";"],p.variables.fontWeightBold,p.variables.contentColorActive)})),R=c.a.div.withConfig({displayName:"HeaderStyles__StyledSubtitle",componentId:"eqi6uk-1"})([""," "," margin:0;overflow-wrap:break-word;padding:0;font-weight:normal;"],p.mixins.reset("block"),Object(p.pick)({enterprise:Object(l.css)(["font-size:",";color:",";"],p.variables.fontSizeSmall,p.variables.textGray),prisma:Object(l.css)(["color:",";"],p.variables.contentColorDefault)})),L=c.a.div.withConfig({displayName:"HeaderStyles__StyledTitleContainer",componentId:"eqi6uk-2"})([""," flex:0 1 auto;"," &:not(:last-child){margin-right:",";}"],p.mixins.reset("block"),(function(e){return e.$truncateTitle&&Object(l.css)(["overflow:hidden;& > ",",& > ","{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}"],I,R)}),Object(p.pick)({enterprise:p.variables.spacingHalf,prisma:p.variables.spacingSmall})),A=c.a.div.withConfig({displayName:"HeaderStyles__StyledActionContainer",componentId:"eqi6uk-3"})([""," align-items:center;display:flex;flex:0 0 auto;justify-content:space-between;",";"],p.mixins.reset("block"),Object(p.pick)({prisma:{comfortable:Object(l.css)(["margin-right:-12px;margin-top:-4px;"]),compact:Object(l.css)(["margin-right:-12px;margin-top:0;"])}})),M=c()(u.a).withConfig({displayName:"HeaderStyles__StyledBox",componentId:"eqi6uk-4"})(["align-items:start;display:flex;flex:0 0 auto;justify-content:space-between;position:relative;min-height:30px;"," "," >:not(","):not(","){flex:1 0 auto;}"],Object(p.pick)({enterprise:Object(l.css)(["padding:",";"],p.variables.spacing),prisma:{comfortable:Object(l.css)(["padding:16px 24px;&:last-child{padding-bottom:32px;}"]),compact:Object(l.css)(["padding:12px 24px;&:last-child{padding-bottom:24px;}"])}}),Object(p.pick)({prisma:Object(l.css)(["border-top-left-radius:",";border-top-right-radius:",";"],p.variables.borderRadius,p.variables.borderRadius)}),L,A);function B(){return B=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},B.apply(this,arguments)}var N={actionPrimary:i.a.node,actionsSecondary:i.a.node,anchor:i.a.string,children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),subtitle:i.a.node,title:i.a.node,truncateTitle:i.a.bool};function z(e){var t=e.actionPrimary,n=e.actionsSecondary,r=e.anchor,a=e.children,i=e.subtitle,l=e.title,c=e.truncateTitle,s=void 0===c||c,u=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["actionPrimary","actionsSecondary","anchor","children","subtitle","title","truncateTitle"]),p=T()().family,f=o.a.createElement(k.a,{appearance:"secondary","data-test":"actions-secondary-toggle",icon:o.a.createElement(D.a,{screenReaderText:t?Object(j._)("More Actions"):Object(j._)("Actions")}),style:{marginLeft:10}}),d="prisma"===p?"right":"below";return o.a.createElement(M,B({"data-test":"header"},u),(l||i)&&o.a.createElement(L,{$truncateTitle:s},l&&o.a.createElement(I,null,r?o.a.createElement(C.a,{name:r},l):l),i&&o.a.createElement(R,null,i)),a,(t||n)&&o.a.createElement(A,null,t,n&&o.a.createElement(E.a,{defaultPlacement:d,toggle:f},n)))}z.propTypes=N;var F=z,$=n(12),H=n.n($),V="0.2s",q=c.a.div.withConfig({displayName:"CardStyles__Styled",componentId:"ola3x0-0"})(["",";flex-direction:column;align-items:stretch;min-width:100px;flex:1;vertical-align:top;"," transition:height ",",width ",",min-width ",",max-width ",",margin ",",box-shadow ",",border-color ",";"," &[data-clickable='true']{cursor:pointer;"," &:hover{","}&:focus{","}}"],p.mixins.reset("inline-flex"),Object(p.pick)({enterprise:Object(l.css)(["background-color:",";border:1px solid transparent;"],p.variables.backgroundColor),prisma:Object(l.css)(["background-color:",";border-radius:",";box-shadow:",";"],p.variables.backgroundColorSection,p.variables.borderRadius,p.variables.embossShadow)}),V,V,V,V,V,V,V,(function(e){return e.$cardHasBorder&&Object(p.pick)({enterprise:Object(l.css)(["border-color:",";"],p.variables.borderLightColor)})}),(function(e){return e.$selected&&Object(p.pick)({enterprise:Object(l.css)(["border-color:",";"],p.variables.focusColor),prisma:Object(l.css)(["background-color:",";"],p.mixins.overlayColors(p.variables.backgroundColorSection,p.variables.interactiveColorOverlaySelected))})}),Object(p.pick)({enterprise:Object(l.css)(["box-shadow:",";"],p.variables.overlayShadow),prisma:Object(l.css)(["box-shadow:",";background-color:",";"],p.variables.embossShadow,p.mixins.overlayColors(p.variables.backgroundColorSection,p.variables.interactiveColorOverlayHover))}),Object(p.pick)({enterprise:Object(l.css)(["box-shadow:",";"],p.variables.focusShadow),prisma:Object(l.css)(["box-shadow:",";background-color:",";"],p.variables.embossShadow,p.mixins.overlayColors(p.variables.backgroundColorSection,p.variables.interactiveColorOverlayHover))})),W=q.withComponent(H.a),K=c.a.div.withConfig({displayName:"CardStyles__StyledFirefoxFlexHack",componentId:"ola3x0-1"})(["display:flex;flex:1 1 auto;flex-direction:column;align-items:stretch;justify-content:stretch;height:100%;",""],Object(p.pick)({prisma:Object(l.css)(["border-radius:",";"],p.variables.borderRadius)}));function U(e){return U="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},U(e)}function Z(){return Z=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Z.apply(this,arguments)}function G(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,a=void 0;try{for(var i,l=e[Symbol.iterator]();!(r=(i=l.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){o=!0,a=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw a}}return n}}(e,t)||function(e,t){if(e){if("string"==typeof e)return X(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?X(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function X(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Y(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function Q(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function J(e,t){return J=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},J(e,t)}function ee(e,t){return!t||"object"!==U(t)&&"function"!=typeof t?te(e):t}function te(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function ne(e){return ne=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},ne(e)}function re(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function oe(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ae(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var ie={children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),margin:i.a.number,maxWidth:i.a.oneOfType([i.a.number,i.a.string]),minWidth:i.a.oneOfType([i.a.number,i.a.string]),onClick:i.a.func,openInNewContext:i.a.bool,selected:i.a.bool,showBorder:i.a.bool,to:i.a.string,value:i.a.any};function le(e){var t=e.margin,n=e.maxWidth,r=e.minWidth,o=e.selected,a=e.showBorder,i=e.style,l=ae(e,["margin","maxWidth","minWidth","selected","showBorder","style"]),c=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?re(Object(n),!0).forEach((function(t){oe(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):re(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({minWidth:r,maxWidth:n,margin:t},i);return[{showBorder:a,selected:o,"data-test":"card",style:c},l]}var ce=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&J(e,t)}(l,e);var t,n,r,a,i=(r=l,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=ne(r);if(a){var n=ne(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return ee(this,e)});function l(){var e;Y(this,l);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return oe(te(e=i.call.apply(i,[this].concat(n))),"handleCardClick",(function(t){var n,r,o=e.props,a=o.selected,i=o.value;null===(n=(r=e.props).onClick)||void 0===n||n.call(r,t,{selected:a,value:i})})),e}return t=l,(n=[{key:"render",value:function(){if((f=this.props).onClick||f.to){var e=G(le(this.props),2),t=e[0],n=e[1],r=t.selected,a=t.showBorder,i=n.children,l=n.elementRef,c=n.onClick,s=n.openInNewContext,u=n.to,p=ae(n,["children","elementRef","onClick","openInNewContext","to"]);return o.a.createElement(W,Z({"data-clickable":!0,$selected:r,$cardHasBorder:a,elementRef:l},t,p,{onClick:c?this.handleCardClick:void 0,openInNewContext:s,to:u||void 0}),o.a.createElement(K,null,i))}var f,d=G(le(this.props),2),b=d[0],h=d[1],v=b.selected,y=b.showBorder,m=h.children,g=h.elementRef,O=ae(h,["children","elementRef"]);return o.a.createElement(q,Z({$selected:v,$cardHasBorder:y,ref:g},b,O),m)}}])&&Q(t.prototype,n),l}(r.Component);oe(ce,"propTypes",ie),oe(ce,"defaultProps",{openInNewContext:!1,selected:!1,showBorder:!0}),oe(ce,"Header",F),oe(ce,"Body",v),oe(ce,"Footer",x);var se=ce},16:function(e,t){e.exports=n(6416)},2:function(e,t){e.exports=n(7294)},20:function(e,t){e.exports=n(6635)},3:function(e,t){e.exports=n(2788)},42:function(e,t){e.exports=n(1093)},5:function(e,t){e.exports=n(6219)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var r=n(2),o=n.n(r),a=n(3);function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n.n(a).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function c(e){return o.a.createElement(l,i({xmlns:"http://www.w3.org/2000/svg"},e))}},64:function(e,t){e.exports=n(308)},65:function(e,t,n){"use strict";n.d(t,"a",(function(){return p}));var r=n(2),o=n.n(r),a=n(66),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M12.0167 6.27273C12.9205 6.27273 13.6531 5.5401 13.6531 4.63636C13.6531 3.73263 12.9205 3 12.0167 3C11.113 3 10.3804 3.73263 10.3804 4.63636C10.3804 5.5401 11.113 6.27273 12.0167 6.27273ZM13.6531 12C13.6531 12.9038 12.9205 13.6364 12.0167 13.6364C11.113 13.6364 10.3804 12.9038 10.3804 12C10.3804 11.0963 11.113 10.3636 12.0167 10.3636C12.9205 10.3636 13.6531 11.0963 13.6531 12ZM13.6531 19.3637C13.6531 20.2674 12.9205 21 12.0167 21C11.113 21 10.3804 20.2674 10.3804 19.3637C10.3804 18.4599 11.113 17.7273 12.0167 17.7273C12.9205 17.7273 13.6531 18.4599 13.6531 19.3637Z",fill:"currentColor"}))}function p(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma24:u},e))}},66:function(e,t){e.exports=n(6261)},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(0);function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}var p={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},f={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:i.a.func,enterpriseSize:i.a.oneOfType([i.a.number,i.a.string]),enterpriseWidth:i.a.oneOfType([i.a.number,i.a.string]),enterpriseHeight:i.a.oneOfType([i.a.number,i.a.string]),Prisma24:i.a.func.isRequired,Prisma20:i.a.func,Prisma16:i.a.func,prismaSize:i.a.oneOf(["medium","small"]),inline:i.a.bool,screenReaderText:i.a.string};function b(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,a=e.Prisma16,i=e.prismaSize,d=e.inline,b=e.enterpriseSize,h=e.enterpriseWidth,v=e.enterpriseHeight,y=e.screenReaderText,m=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),g=Object(l.useSplunkTheme)(),O=g.family,x=g.density;if("enterprise"===O)return o.a.createElement(t,u({size:b,width:h,height:v,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},m));var j=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?p:f},m);if("small"===i){var w=a||n;return o.a.createElement(w,u({width:"16",height:"16"},j))}if("compact"===x){var C=r||n;return o.a.createElement(C,u({width:"20",height:"20"},j))}return o.a.createElement(n,u({width:"24",height:"24"},j))}b.propTypes=d,b.defaultProps={inline:!0,prismaSize:"medium"}},8:function(e,t){e.exports=n(6493)}})},1008:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=157)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},12:function(e,t){e.exports=n(5917)},157:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return R}));var r=n(2),o=n.n(r),a=n(37),i=n(5),l=n(47),c=n.n(l),s=n(1),u=n.n(s),p=n(22),f=n(3),d=n.n(f),b=n(12),h=n.n(b),v=n(0),y=d.a.div.withConfig({displayName:"ChipStyles__StyledBasic",componentId:"sc-1sd3tsh-0"})(["",";background-color:",";border:1px solid transparent;flex:0 1 auto;max-width:calc(100% - 3px);border-radius:2px;",";"," "," ",""],v.mixins.reset("inline-flex"),Object(v.pickVariant)("$appearance",{default:{enterprise:{dark:v.variables.gray45,light:v.variables.gray92},prisma:v.variables.neutral100},info:{enterprise:v.variables.infoColorL10},success:{enterprise:v.variables.successColorL10},warning:{enterprise:v.variables.warningColorL10},error:{enterprise:v.variables.errorColorL10,prisma:v.variables.accentColorNegative},outline:{prisma:"transparent"},custom:function(e){return e.$backgroundColor}}),(function(e){return"outline"===e.$appearance&&Object(f.css)(["border-color:",";"],v.variables.interactiveColorBorder)}),Object(v.pick)({enterprise:Object(f.css)(["color:",",line-height:",";margin:0 2px 2px 0;"],v.variables.textGray,v.variables.lineHeight),prisma:Object(f.css)(["color:",";line-height:16px;margin:1px;"],(function(e){return"error"===e.$appearance?v.variables.contentColorInverted:v.variables.contentColorDefault}))}),Object(v.pick)({enterprise:{comfortable:Object(f.css)(["height:calc("," - 6px);padding:4px 7px;"],v.variables.inputHeight),compact:Object(f.css)(["height:calc("," - 6px);padding:2px 4px;"],v.variables.inputHeight)},prisma:{comfortable:Object(f.css)(["height:calc("," - 8px);padding:7px 7px;font-size:",";"],v.variables.inputHeight,v.variables.fontSizeSmall),compact:Object(f.css)(["height:calc("," - 8px);padding:3px 7px;font-size:",";"],v.variables.inputHeight,v.variables.fontSizeSmall)}}),(function(e){return e.$disabled&&Object(f.css)(["background-color:",";"],Object(v.pickVariant)("$appearance",{default:{enterprise:{dark:"rgba(0, 0, 0, 0.15)",light:"rgba(0, 0, 0, 0.05)"},prisma:v.variables.interactiveColorBackgroundDisabled},info:{enterprise:v.mixins.colorWithAlpha(v.variables.infoColorL10,.3)},success:{enterprise:v.mixins.colorWithAlpha(v.variables.successColorL10,.3)},warning:{enterprise:v.mixins.colorWithAlpha(v.variables.warningColorL10,.3)},error:{enterprise:v.mixins.colorWithAlpha(v.variables.errorColorL10,.3),prisma:v.variables.interactiveColorBackgroundDisabled},outline:{prisma:v.variables.interactiveColorBackgroundDisabled},custom:{enterprise:{dark:"rgba(0, 0, 0, 0.15)",light:"rgba(0, 0, 0, 0.05)"},prisma:v.variables.interactiveColorBackgroundDisabled}}))})),m=d()(y).withConfig({displayName:"ChipStyles__Styled",componentId:"sc-1sd3tsh-1"})(["align-items:center;"]),g=d.a.div.withConfig({displayName:"ChipStyles__StyledInner",componentId:"sc-1sd3tsh-2"})(["",";"],Object(v.pick)({enterprise:Object(f.css)(["display:flex;max-width:100%;"]),prisma:Object(f.css)(["display:grid;max-width:100%;height:16px;column-gap:",";",";"],Object(v.pick)({prisma:{compact:v.variables.spacingXSmall,comfortable:v.variables.spacingSmall}}),(function(e){var t=e.$icon,n=e.$removable,r=Object(f.css)(["grid-template-columns:1fr;"]);return t&&n?r=Object(f.css)(["grid-template-columns:0fr 1fr 0fr;"]):t?r=Object(f.css)(["grid-template-columns:0fr 1fr;"]):n&&(r=Object(f.css)(["grid-template-columns:1fr 0fr;"])),r}))})),O=d.a.div.withConfig({displayName:"ChipStyles__StyledIcon",componentId:"sc-1sd3tsh-3"})(["",";margin-right:",";color:",";"],Object(v.pick)({prisma:{compact:Object(f.css)(["font-size:14px;display:inline-flex;svg{height:16px;vertical-align:baseline;}"]),comfortable:Object(f.css)(["font-size:18px;display:inline-flex;align-self:center;svg{height:16px;vertical-align:baseline;}"])},enterprise:Object(f.css)(["flex:0 0 auto;"])}),Object(v.pick)({enterprise:"3px"}),Object(v.pickVariant)("$disabled",{true:v.variables.contentColorDisabled,false:{enterprise:function(e){return e.$foregroundColor||v.variables.contentColorDefault},prisma:function(e){var t=e.$foregroundColor,n=e.$appearance;return t||("error"===n?v.variables.contentColorInverted:v.variables.contentColorDefault)}}})),x=d.a.div.withConfig({displayName:"ChipStyles__StyledLabel",componentId:"sc-1sd3tsh-4"})([""," ",";color:",";"],v.mixins.ellipsis(),Object(v.pick)({enterprise:Object(f.css)(["flex:0 1 auto;"])}),Object(v.pickVariant)("$disabled",{true:v.variables.contentColorDisabled,false:{enterprise:function(e){return e.$foregroundColor||v.variables.contentColorDefault},prisma:function(e){var t=e.$foregroundColor,n=e.$appearance;return t||("error"===n?v.variables.contentColorInverted:v.variables.contentColorActive)}}})),j=d.a.span.withConfig({displayName:"ChipStyles__StyledRemove",componentId:"sc-1sd3tsh-5"})(["",";"],Object(v.pick)({enterprise:Object(f.css)(["flex:0 0 auto;padding-left:",";font-size:",";color:",";"],v.variables.spacingQuarter,Object(v.pick)({compact:"9px",comfortable:"10.5px"}),(function(e){var t=e.$disabled,n=e.$foregroundColor;return t?v.variables.contentColorDisabled:n||v.variables.textGray})),prisma:Object(f.css)(["font-size:",";display:flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:12px;font-size:9px;color:",";"],Object(v.pick)({compact:"9px",comfortable:"10.5px"}),(function(e){var t=e.$disabled,n=e.$foregroundColor;return t?v.variables.contentColorDisabled:n||"inherit"}))})),w=d()(y.withComponent(h.a)).withConfig({displayName:"ChipStyles__StyledClickable",componentId:"sc-1sd3tsh-6"})(["flex:0 1 auto;line-height:16px;cursor:pointer;&:focus{",";}&:not([disabled]):hover{",";}",";"],Object(v.pick)({enterprise:Object(f.css)(["box-shadow:",";color:",";"],v.variables.focusShadow,v.variables.linkColor),prisma:Object(f.css)(["color:",";","{background-color:",";box-shadow:0 0 0 3px ",";}"],v.variables.contentColorActive,j,v.variables.interactiveColorOverlayHover,v.variables.focusColor)}),Object(v.pick)({enterprise:Object(f.css)(["background-color:",";","{color:",";}"],Object(v.pickVariant)("$appearance",{default:{dark:v.variables.gray30,light:v.variables.gray96},info:v.variables.infoColorL20,success:v.variables.successColorL20,warning:v.variables.warningColorL20,error:v.variables.errorColorL20,custom:{dark:v.variables.gray30,light:v.variables.gray96}}),j,(function(e){return e.$foregroundColor||v.variables.linkColor})),prisma:Object(f.css)(["color:",";","{background-color:",";",";}"],v.variables.contentColorActive,j,v.variables.interactiveColorOverlayHover,(function(e){return"error"===e.$appearance&&Object(f.css)(["color:",";"],v.variables.contentColorInverted)}))}),Object(v.pick)({prisma:Object(f.css)(["&:not([disabled]):active ","{background-color:",";}"],j,v.variables.interactiveColorOverlayActive)}));function C(){return C=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},C.apply(this,arguments)}function S(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,a=void 0;try{for(var i,l=e[Symbol.iterator]();!(r=(i=l.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){o=!0,a=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw a}}return n}}(e,t)||function(e,t){if(e){if("string"==typeof e)return k(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?k(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function k(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function P(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var E={appearance:u.a.oneOf(["info","success","warning","error","outline"]),backgroundColor:u.a.string,children:u.a.node.isRequired,disabled:u.a.bool,elementRef:u.a.oneOfType([u.a.func,u.a.object]),foregroundColor:u.a.string,icon:u.a.node,onRequestRemove:u.a.func,value:u.a.any};function _(e){var t=e.appearance,n=e.backgroundColor,r=e.disabled,o=e.foregroundColor,i=e.icon,l=P(e,["appearance","backgroundColor","disabled","foregroundColor","icon"]),c=o&&Object(a.isCSSColor)(o)?o:void 0,s=n&&Object(a.isCSSColor)(n)?n:void 0;return[{"data-test":"chip",$appearance:t||(s?"custom":"default"),$backgroundColor:s,$foregroundColor:c,disabled:r,icon:i},l]}function T(e){var t=S(_(e),2),n=t[0],a=t[1],l=n.$appearance,s=n.$foregroundColor,u=n.disabled,f=n.icon,d=P(n,["$appearance","$foregroundColor","disabled","icon"]),b=a.children,h=a.elementRef,v=a.onRequestRemove,y=a.value,m=P(a,["children","elementRef","onRequestRemove","value"]),k=Object(r.useCallback)((function(e){v(e,{value:y})}),[v,y]);return o.a.createElement(w,C({$appearance:l,$disabled:u,$foregroundColor:s,"data-test-value":y,disabled:u,elementRef:h,onClick:k},d,c()(m,Object.keys(E))),o.a.createElement(g,{$icon:!!f,$removable:!0},f&&o.a.createElement(O,{$appearance:l,$disabled:u,$foregroundColor:s},f),o.a.createElement(x,{"data-test":"label",$appearance:l,$disabled:u,$foregroundColor:s},b),o.a.createElement(j,{$disabled:u,$foregroundColor:s},o.a.createElement(p.a,{"data-test":"crossmark",enterpriseSize:.85,prismaSize:"small",screenReaderText:Object(i._)("Remove")}))))}function D(e){var t=S(_(e),2),n=t[0],r=t[1],a=n.$appearance,i=n.$foregroundColor,l=n.disabled,s=n.icon,u=P(n,["$appearance","$foregroundColor","disabled","icon"]),p=r.children,f=r.elementRef,d=P(r,["children","elementRef"]);return o.a.createElement(m,C({$appearance:a,$disabled:l,ref:f},u,c()(d,Object.keys(E))),o.a.createElement(g,{$icon:!!s,$removable:!1},s&&o.a.createElement(O,{$appearance:a,$disabled:l,$foregroundColor:i},s),o.a.createElement(x,{"data-test":"label",$appearance:a,$disabled:l,$foregroundColor:i},p)))}function I(e){return function(e){return!!e.onRequestRemove}(e)?o.a.createElement(T,e):o.a.createElement(D,e)}I.propTypes=E,I.defaultProps={disabled:!1};var R=I},2:function(e,t){e.exports=n(7294)},22:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(23),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L10.5858 12L5.2929 17.2929C4.90238 17.6834 4.90238 18.3166 5.2929 18.7071C5.68342 19.0976 6.31659 19.0976 6.70711 18.7071L12 13.4142L17.2929 18.7071C17.6834 19.0976 18.3166 19.0976 18.7071 18.7071C19.0976 18.3166 19.0976 17.6834 18.7071 17.2929L13.4142 12L18.7071 6.70711C19.0976 6.31658 19.0976 5.68342 18.7071 5.29289C18.3166 4.90237 17.6834 4.90237 17.2929 5.29289L12 10.5858L6.70711 5.29289Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M12.2024 2.69009C12.5092 2.38325 13.0067 2.38325 13.3136 2.69009C13.6204 2.99693 13.6204 3.49442 13.3136 3.80126L9.11721 7.99762L13.3114 12.1918C13.6206 12.501 13.6206 13.0023 13.3114 13.3114C13.0023 13.6206 12.501 13.6206 12.1918 13.3114L7.99762 9.11721L3.885 13.2298C3.57816 13.5367 3.08067 13.5367 2.77383 13.2298C2.46699 12.923 2.46699 12.4255 2.77383 12.1187L6.88645 8.00604L2.69183 3.81142C2.38267 3.50226 2.38267 3.001 2.69183 2.69183C3.001 2.38267 3.50226 2.38267 3.81142 2.69183L8.00604 6.88646L12.2024 2.69009Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},23:function(e,t){e.exports=n(1476)},3:function(e,t){e.exports=n(2788)},37:function(e,t){e.exports=n(4592)},47:function(e,t){e.exports=n(3461)},5:function(e,t){e.exports=n(6219)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var r=n(2),o=n.n(r),a=n(3);function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n.n(a).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function c(e){return o.a.createElement(l,i({xmlns:"http://www.w3.org/2000/svg"},e))}},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(0);function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}var p={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},f={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:i.a.func,enterpriseSize:i.a.oneOfType([i.a.number,i.a.string]),enterpriseWidth:i.a.oneOfType([i.a.number,i.a.string]),enterpriseHeight:i.a.oneOfType([i.a.number,i.a.string]),Prisma24:i.a.func.isRequired,Prisma20:i.a.func,Prisma16:i.a.func,prismaSize:i.a.oneOf(["medium","small"]),inline:i.a.bool,screenReaderText:i.a.string};function b(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,a=e.Prisma16,i=e.prismaSize,d=e.inline,b=e.enterpriseSize,h=e.enterpriseWidth,v=e.enterpriseHeight,y=e.screenReaderText,m=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),g=Object(l.useSplunkTheme)(),O=g.family,x=g.density;if("enterprise"===O)return o.a.createElement(t,u({size:b,width:h,height:v,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},m));var j=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?p:f},m);if("small"===i){var w=a||n;return o.a.createElement(w,u({width:"16",height:"16"},j))}if("compact"===x){var C=r||n;return o.a.createElement(C,u({width:"20",height:"20"},j))}return o.a.createElement(n,u({width:"24",height:"24"},j))}b.propTypes=d,b.defaultProps={inline:!0,prismaSize:"medium"}}})},8539:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=160)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},11:function(e,t){e.exports=n(9726)},12:function(e,t){e.exports=n(5917)},160:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return z}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(5),s=n(11),u=n(55),p=n.n(u),f=n(29),d=n(3),b=n.n(d),h=n(8),v=n.n(h),y=n(12),m=n.n(y),g=n(0),O=b()(v.a).withConfig({displayName:"CollapsiblePanelStyles__StyledBox",componentId:"sc-1phikbp-0"})(["display:flex;flex-direction:column;min-height:",";",";& + &{margin-top:",";}"],Object(g.pick)({enterprise:Object(d.css)(["calc("," + 12px)"],g.variables.lineHeight),prisma:{comfortable:"56px",compact:"48px"}}),Object(g.pick)({prisma:Object(d.css)(["background-color:",";"],g.variables.backgroundColorSection)}),Object(g.pick)({enterprise:"2px",prisma:"1px"})),x=b.a.span.withConfig({displayName:"CollapsiblePanelStyles__StyledIcon",componentId:"sc-1phikbp-1"})(["position:absolute;left:",";transition:transform ",";",";"],Object(g.pick)({enterprise:"12px",prisma:"20px"}),Object(g.pick)({enterprise:"300ms",prisma:"200ms"}),Object(g.pick)({prisma:Object(d.css)(["color:",";display:flex;top:",";[disabled] > &{color:inherit;}"],g.variables.contentColorDefault,Object(g.pick)({comfortable:"20px",compact:"16px"}))})),j=b.a.div.withConfig({displayName:"CollapsiblePanelStyles__StyledTitleWithActions",componentId:"sc-1phikbp-2"})(["flex-shrink:0;border-bottom:0;position:relative;padding:",";transition:background-color 0.2s,border 0.2s,box-shadow 0.2s;color:",";"," ",""],Object(g.pick)({enterprise:Object(d.css)([""," "," "," 30px"],g.variables.spacingXSmall,g.variables.spacingSmall,g.variables.spacingXSmall),prisma:{comfortable:"8px 10px 8px 52px",compact:"8px 10px 8px 52px"}}),Object(g.pick)({enterprise:g.variables.textColor,prisma:g.variables.contentColorActive}),Object(g.pick)({prisma:Object(d.css)(["background-color:",";"],g.variables.interactiveColorBackground),enterprise:{dark:Object(d.css)(["background-color:",";"],g.variables.gray45),light:Object(d.css)(["background-color:",";"],g.variables.gray96)}}),(function(e){return e.$disabled&&Object(d.css)(["cursor:default;color:",";"],Object(g.pick)({enterprise:g.variables.contentColorDefault,prisma:g.variables.contentColorDisabled}))})),w=b()(m.a).withConfig({displayName:"CollapsiblePanelStyles__StyledClickableIcon",componentId:"sc-1phikbp-3"})(["position:absolute;left:",";padding:",";top:8px;& > svg{transition:transform ",";}",";"," &:focus:not([disabled]),&:active:not([disabled]){color:",";box-shadow:",";}&:hover:not([disabled]){color:",";background-color:",";}"],Object(g.pick)({enterprise:"4px",prisma:"8px"}),Object(g.pick)({enterprise:{comfortable:"2px 8px",compact:"0px 8px"},prisma:{comfortable:"12px",compact:"8px"}}),Object(g.pick)({enterprise:"300ms",prisma:"200ms"}),Object(g.pick)({prisma:Object(d.css)(["color:",";display:flex;[disabled] > &{color:inherit;}"],g.variables.contentColorDefault)}),Object(g.pickVariant)("$open",{true:Object(d.css)(["& > svg{transform:rotate(90deg);}"])}),Object(g.pick)({enterprise:g.variables.textColor,prisma:g.variables.contentColorActive}),g.variables.focusShadowInset,Object(g.pick)({enterprise:g.variables.textColor,prisma:g.variables.contentColorActive}),Object(g.pick)({enterprise:{light:g.variables.gray92,dark:g.variables.gray30},prisma:g.mixins.overlayColors(g.variables.interactiveColorBackground,g.variables.interactiveColorOverlayHover)})),C=b()(m.a).withConfig({displayName:"CollapsiblePanelStyles__StyledTitleClickable",componentId:"sc-1phikbp-4"})(["width:100%;flex-shrink:0;border-bottom:0;cursor:pointer;position:relative;display:block;transition:background-color 0.2s,border 0.2s,box-shadow 0.2s;padding:",";color:",";"," "," &[disabled]{cursor:default;color:",";}&:focus:not([disabled]),&:active:not([disabled]){color:",";box-shadow:",";}&:hover:not([disabled]){color:",";background-color:",";}"],Object(g.pick)({enterprise:"6px 30px",prisma:{comfortable:"18px 20px 18px 52px",compact:"14px 20px 14px 52px"}}),Object(g.pick)({enterprise:g.variables.textColor,prisma:g.variables.contentColorActive}),Object(g.pick)({prisma:Object(d.css)(["background-color:",";"],g.variables.interactiveColorBackground)}),Object(g.pickVariant)("$open",{true:Object(d.css)(["","{transform:rotate(90deg);}"],x),false:{enterprise:{dark:Object(d.css)(["background-color:",";"],g.variables.gray45),light:Object(d.css)(["background-color:",";"],g.variables.gray96)}}}),Object(g.pick)({enterprise:g.variables.contentColorDefault,prisma:g.variables.contentColorDisabled}),Object(g.pick)({enterprise:g.variables.textColor,prisma:g.variables.contentColorActive}),g.variables.focusShadowInset,Object(g.pick)({enterprise:g.variables.textColor,prisma:g.variables.contentColorActive}),Object(g.pick)({enterprise:{light:g.variables.gray92,dark:g.variables.gray30},prisma:g.mixins.overlayColors(g.variables.interactiveColorBackground,g.variables.interactiveColorOverlayHover)})),S=b.a.span.withConfig({displayName:"CollapsiblePanelStyles__StyledHeadingContent",componentId:"sc-1phikbp-5"})(["display:flex;justify-content:space-between;"," ",""],Object(g.pick)({prisma:Object(d.css)(["font-weight:",";"],g.variables.fontWeightSemiBold)}),(function(e){return e.$titleWithActions&&Object(d.css)(["min-height:",";"],Object(g.pick)({prisma:{comfortable:"40px",compact:"32px"}}))})),k=b.a.span.withConfig({displayName:"CollapsiblePanelStyles__StyledDescription",componentId:"sc-1phikbp-6"})(["font-size:",";margin-left:",";"],g.variables.fontSizeSmall,Object(g.pick)({enterprise:g.variables.spacingHalf,prisma:g.variables.spacingLarge}));function P(e){return P="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},P(e)}function E(){return E=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},E.apply(this,arguments)}function _(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function T(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?_(Object(n),!0).forEach((function(t){M(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):_(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function D(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function I(e,t){return I=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},I(e,t)}function R(e,t){return!t||"object"!==P(t)&&"function"!=typeof t?L(e):t}function L(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function A(e){return A=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},A(e)}function M(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var B={innerBodyStyles:i.a.object,children:i.a.node,defaultOpen:i.a.bool,description:i.a.string,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),headingLevel:i.a.number,onRequestClose:i.a.func,onRequestOpen:i.a.func,open:i.a.bool,overflow:i.a.string,panelId:i.a.any,renderChildrenWhenCollapsed:i.a.bool,title:i.a.node.isRequired,titleWithActions:i.a.bool},N=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&I(e,t)}(u,e);var t,n,r,a,i=(r=u,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=A(r);if(a){var n=A(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return R(this,e)});function u(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,u),M(L(t=i.call(this,e)),"controlledExternally",void 0),M(L(t),"containerId",void 0),M(L(t),"toggleId",void 0),M(L(t),"handleRequestClose",(function(e){var n=t.props,r=n.panelId,o=n.onRequestClose;null==o||o({event:e,panelId:r,reason:"toggleClick"}),t.setState(T({animating:!0},t.isControlled()?{}:{open:!1}))})),M(L(t),"handleRequestOpen",(function(e){var n=t.props,r=n.panelId,o=n.onRequestOpen;null==o||o({event:e,panelId:r,reason:"toggleClick"}),t.setState(T({animating:!0},t.isControlled()?{}:{open:!0}))})),M(L(t),"handleAnimationEnd",(function(){t.setState({animating:!1})})),t.controlledExternally=Object(l.has)(e,"open"),t.state=T({animating:!1},t.isControlled()?void 0:{open:e.defaultOpen||!1}),t.containerId="container-".concat(Object(s.createGUID)()),t.toggleId="toggle-".concat(Object(s.createGUID)()),t}return t=u,(n=[{key:"componentDidUpdate",value:function(e){this.props.open!==e.open&&this.setState({animating:!0})}},{key:"isControlled",value:function(){return this.controlledExternally}},{key:"render",value:function(){var e=this.props,t=e.innerBodyStyles,n=e.children,r=e.description,a=e.disabled,i=e.elementRef,s=e.headingLevel,d=e.overflow,b=e.renderChildrenWhenCollapsed,h=e.title,v=e.titleWithActions,y=this.state.animating,m=this.isControlled()?this.props.open:this.state.open;return o.a.createElement(O,E({"data-test":"collapsible-panel",elementRef:i},Object(l.omit)(this.props,Object(l.keys)(u.propTypes))),v?o.a.createElement(j,{$disabled:a},o.a.createElement(w,{disabled:a,onClick:m?this.handleRequestClose:this.handleRequestOpen,id:this.toggleId,"aria-controls":this.containerId,"aria-expanded":m,$open:!!m,"data-test":"toggle"},o.a.createElement(f.a,{screenReaderText:m?Object(c._)("Panel is open"):Object(c._)("Panel is closed"),prismaSize:"small"})),o.a.createElement(S,{$titleWithActions:v,"data-test":"title"},h)):o.a.createElement("span",{"data-test":"heading",role:s?"heading":void 0,"aria-level":s},o.a.createElement(C,{disabled:a,onClick:m?this.handleRequestClose:this.handleRequestOpen,id:this.toggleId,"aria-controls":this.containerId,"aria-expanded":m,$open:!!m,"data-test":"toggle"},o.a.createElement(x,null,o.a.createElement(f.a,{screenReaderText:m?Object(c._)("Panel is open"):Object(c._)("Panel is closed"),prismaSize:"small"})),o.a.createElement(S,null,o.a.createElement("span",{"data-test":"title"},h),r&&o.a.createElement(k,{"data-test":"description"},r)))),o.a.createElement(p.a,{outerId:this.containerId,"aria-labelledby":this.toggleId,"data-test":"body",outerStyle:{overflow:y?"hidden":d},innerStyle:T({tableLayout:"fixed"},t),open:m,onAnimationEnd:this.handleAnimationEnd,renderChildrenWhenCollapsed:b},n))}}])&&D(t.prototype,n),u}(r.Component);M(N,"propTypes",B),M(N,"defaultProps",{disabled:!1,overflow:"auto",renderChildrenWhenCollapsed:!1,titleWithActions:!1});var z=N},2:function(e,t){e.exports=n(7294)},29:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(35),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M14.7861 11.9999L8.48587 5.69972C8.09534 5.3092 8.09534 4.67603 8.48587 4.28551C8.87639 3.89499 9.50956 3.89499 9.90008 4.28551L16.5538 10.9393C17.1396 11.525 17.1396 12.4748 16.5538 13.0606L9.90142 19.713C9.5109 20.1035 8.87773 20.1035 8.48721 19.713C8.09669 19.3224 8.09669 18.6893 8.48721 18.2988L14.7861 11.9999Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M11.7109 7.9976L5.71017 13.9983L4.29597 12.5841L8.88914 7.99095L4.34482 3.40363L5.76567 1.99609L11.7109 7.9976Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},3:function(e,t){e.exports=n(2788)},35:function(e,t){e.exports=n(4345)},4:function(e,t){e.exports=n(5220)},5:function(e,t){e.exports=n(6219)},55:function(e,t){e.exports=n(380)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var r=n(2),o=n.n(r),a=n(3);function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n.n(a).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function c(e){return o.a.createElement(l,i({xmlns:"http://www.w3.org/2000/svg"},e))}},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(0);function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}var p={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},f={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:i.a.func,enterpriseSize:i.a.oneOfType([i.a.number,i.a.string]),enterpriseWidth:i.a.oneOfType([i.a.number,i.a.string]),enterpriseHeight:i.a.oneOfType([i.a.number,i.a.string]),Prisma24:i.a.func.isRequired,Prisma20:i.a.func,Prisma16:i.a.func,prismaSize:i.a.oneOf(["medium","small"]),inline:i.a.bool,screenReaderText:i.a.string};function b(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,a=e.Prisma16,i=e.prismaSize,d=e.inline,b=e.enterpriseSize,h=e.enterpriseWidth,v=e.enterpriseHeight,y=e.screenReaderText,m=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),g=Object(l.useSplunkTheme)(),O=g.family,x=g.density;if("enterprise"===O)return o.a.createElement(t,u({size:b,width:h,height:v,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},m));var j=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?p:f},m);if("small"===i){var w=a||n;return o.a.createElement(w,u({width:"16",height:"16"},j))}if("compact"===x){var C=r||n;return o.a.createElement(C,u({width:"20",height:"20"},j))}return o.a.createElement(n,u({width:"24",height:"24"},j))}b.propTypes=d,b.defaultProps={inline:!0,prismaSize:"medium"}},8:function(e,t){e.exports=n(6493)}})},1569:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=124)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},124:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return T})),n.d(t,"Column",(function(){return m})),n.d(t,"Row",(function(){return C}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(42),c=n.n(l),s=n(4),u=n(3),p=n.n(u),f=n(0),d=p.a.div.withConfig({displayName:"ColumnStyles__Styled",componentId:"sc-1pchz98-0"})(["",";"],f.mixins.reset("block")),b=n(57);function h(){return h=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},h.apply(this,arguments)}var v={children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),gutter:i.a.number,isFirstChild:i.a.bool,isLastChild:i.a.bool,span:i.a.number,style:i.a.object};function y(e){var t=e.children,n=e.elementRef,r=e.gutter,a=e.span,i=void 0===a?1:a,l=e.isFirstChild,c=e.isLastChild,u=e.style,p=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","elementRef","gutter","span","isFirstChild","isLastChild","style"]),f=r?"calc((100% - ".concat(11*r,"px) * ").concat(i/12," + (").concat(r,"px * ").concat(i-1,"))"):"".concat(100/12*i,"%");Object(b.a)(r);var v={marginLeft:l?void 0:r/2,marginRight:c?void 0:r/2,flex:"".concat(i," ").concat(i," auto"),width:f};return o.a.createElement(d,h({"data-test":"column",ref:n,style:Object(s.defaults)({},u,v)},p),t)}y.propTypes=v;var m=y,g=p.a.div.withConfig({displayName:"RowStyles__Styled",componentId:"sc-121ntds-0"})(["",";flex-flow:row nowrap;&[data-align-items='start']{align-items:flex-start;}&[data-align-items='end']{align-items:flex-end;}&[data-align-items='center']{align-items:center;}&[data-align-items='stretch']{align-items:stretch;}"],f.mixins.reset("flex")),O=p.a.div.withConfig({displayName:"RowStyles__StyledDivider",componentId:"sc-121ntds-1"})(["border-left:1px solid ",";flex:0 0 1;align-self:stretch;"],Object(f.pick)({prisma:f.variables.neutral200,enterprise:{light:f.variables.gray92,dark:f.variables.gray60}}));function x(){return x=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},x.apply(this,arguments)}var j={alignItems:i.a.oneOf(["start","end","center","stretch"]),children:i.a.node,divider:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),gutter:i.a.number,isFirstChild:i.a.bool,isLastChild:i.a.bool,style:i.a.object};function w(e){var t=e.alignItems,n=void 0===t?"stretch":t,a=e.children,i=e.divider,l=e.elementRef,c=e.gutter,u=e.isFirstChild,p=e.isLastChild,f=e.style,d=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["alignItems","children","divider","elementRef","gutter","isFirstChild","isLastChild","style"]),h=Object(r.useCallback)((function(e,t){return Object(r.cloneElement)(e,{gutter:c,isFirstChild:0===t,isLastChild:t===r.Children.count(a)-1})}),[a,c]),v=Object(r.useCallback)((function(e,t,n,r){return e.push(t),i&&n<r.length-1&&e.push(o.a.createElement(O,{key:"".concat(n,"-divider")})),e}),[i]);Object(b.a)(c);var y={marginTop:u?void 0:c/2,marginBottom:p?void 0:c/2},m=r.Children.toArray(a).filter(r.isValidElement).map(h).reduce(v,[]);return o.a.createElement(g,x({style:Object(s.defaults)({},f,y),"data-align-items":n,"data-test":"row",ref:l},d),m)}w.propTypes=j;var C=w,S=p.a.div.withConfig({displayName:"ColumnLayoutStyles__Styled",componentId:"sc-3eatxz-0"})(["",";flex-direction:column;"],f.mixins.reset("flex")),k=p.a.div.withConfig({displayName:"ColumnLayoutStyles__StyledDivider",componentId:"sc-3eatxz-1"})(["border-top:1px solid ",";height:0;"],Object(f.pick)({prisma:f.variables.neutral200,enterprise:{light:f.variables.gray92,dark:f.variables.gray60}}));function P(){return P=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},P.apply(this,arguments)}var E={children:i.a.node,divider:i.a.oneOf(["none","vertical","horizontal"]),elementRef:i.a.oneOfType([i.a.func,i.a.object]),gutter:i.a.number};function _(e){var t=e.children,n=e.divider,a=void 0===n?"none":n,i=e.elementRef,l=e.gutter,s=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","divider","elementRef","gutter"]),u=c()(),p=u.family,f=u.density,d=Object(r.useCallback)((function(e,n){var o=0===n,i=n===r.Children.count(t)-1,c=l;return void 0===c&&("prisma"===p?"compact"===f?c=16:"comfortable"===f&&(c=24):"enterprise"===p&&(c=30)),Object(r.cloneElement)(e,{gutter:c,divider:"vertical"===a,isFirstChild:o,isLastChild:i})}),[t,f,a,p,l]),b=Object(r.useCallback)((function(e,t,n,r){return e.push(t),"horizontal"===a&&n<r.length-1&&e.push(o.a.createElement(k,{key:"".concat(n,"-divider")})),e}),[a]),h=r.Children.toArray(t).filter(r.isValidElement).map(d).reduce(b,[]);return o.a.createElement(S,P({"data-test":"column-layout",ref:i},s),h)}_.propTypes=E,_.Row=C,_.Column=m;var T=_},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)},4:function(e,t){e.exports=n(5220)},42:function(e,t){e.exports=n(1093)},57:function(e,t,n){"use strict";function r(e,t){if(null==e)throw new Error(null!=t?t:"Unexpected undefined or null")}n.d(t,"a",(function(){return r}))}})},6300:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=161)}({1:function(e,t){e.exports=n(1581)},10:function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},11:function(e,t){e.exports=n(9726)},13:function(e,t){e.exports=n(2725)},161:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return W})),n.d(t,"Option",(function(){return T})),n.d(t,"Divider",(function(){return f.Divider})),n.d(t,"Heading",(function(){return f.Heading}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(26),s=n(11),u=n(5),p=n(9),f=n(13),d=n(18),b=n.n(d),h=n(36),v=n.n(h),y=n(24),m=n.n(y);function g(e){return g="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},g(e)}function O(){return O=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},O.apply(this,arguments)}function x(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function j(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function w(e,t){return w=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},w(e,t)}function C(e,t){return!t||"object"!==g(t)&&"function"!=typeof t?S(e):t}function S(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function k(e){return k=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},k(e)}function P(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var E={active:i.a.bool,description:i.a.string,descriptionPosition:i.a.oneOf(["right","bottom"]),disabled:i.a.bool,icon:i.a.node,label:i.a.string,matchRanges:i.a.arrayOf(i.a.shape({start:i.a.number.isRequired,end:i.a.number.isRequired})),onClick:i.a.func,truncate:i.a.bool,value:i.a.string.isRequired},_=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&w(e,t)}(l,e);var t,n,r,a,i=(r=l,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=k(r);if(a){var n=k(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return C(this,e)});function l(){var e;x(this,l);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return P(S(e=i.call.apply(i,[this].concat(n))),"item",null),P(S(e),"handleClick",(function(t){var n=e.props,r=n.disabled,o=n.onClick,a=n.value;r||null==o||o(t,{value:a})})),e}return t=l,(n=[{key:"scrollIntoViewIfNeeded",value:function(){var e;null===(e=this.item)||void 0===e||e.scrollIntoViewIfNeeded()}},{key:"render",value:function(){var e=this,t=this.props,n=t.value,r=t.label,a=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(t,["value","label"]),i=void 0===r?n:r;return o.a.createElement(f.Item,O({ref:function(t){e.item=t},"data-test":"option","data-test-value":n},a,{onClick:this.handleClick,role:"option","aria-selected":!1}),i)}}])&&j(t.prototype,n),l}(r.PureComponent);P(_,"propTypes",E),P(_,"defaultProps",{active:!1,descriptionPosition:"bottom",disabled:!1,truncate:!1});var T=_,D=n(10);function I(e){return I="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},I(e)}function R(){return R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},R.apply(this,arguments)}function L(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function A(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?L(Object(n),!0).forEach((function(t){$(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):L(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function M(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function B(e,t){return B=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},B(e,t)}function N(e,t){return!t||"object"!==I(t)&&"function"!=typeof t?z(e):t}function z(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function F(e){return F=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},F(e)}function $(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var H={animateLoading:i.a.bool,append:i.a.bool,children:i.a.node,controlledFilter:i.a.bool,defaultPlacement:i.a.oneOf(["above","below","vertical"]),defaultValue:i.a.string,describedBy:i.a.string,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),error:i.a.bool,footerMessage:i.a.node,inline:i.a.bool,inputRef:i.a.oneOfType([i.a.func,i.a.object]),isLoadingOptions:i.a.bool,labelledBy:i.a.string,loadingMessage:i.a.node,menuStyle:i.a.object,name:i.a.string,noOptionsMessage:i.a.node,onChange:i.a.func,onClose:i.a.func,onFocus:i.a.func,onKeyDown:i.a.func,onOpen:i.a.func,onScroll:i.a.func,onScrollBottom:i.a.func,placeholder:i.a.string,prepend:i.a.bool,size:i.a.oneOf(["small","medium","large"]),value:i.a.string},V={animateLoading:!1,controlledFilter:!1,defaultPlacement:"vertical",disabled:!1,error:!1,inline:!1,isLoadingOptions:!1,menuStyle:{},placeholder:Object(u._)("Select..."),size:"medium"},q=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&B(e,t)}(h,e);var t,n,a,i,d=(a=h,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=F(a);if(i){var n=F(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return N(this,e)});function h(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,h),$(z(t=d.call(this,e)),"activeItemId",void 0),$(z(t),"activeValue",void 0),$(z(t),"availableOptionCount",0),$(z(t),"controlledExternally",void 0),$(z(t),"focusCalledInternally",!1),$(z(t),"options",void 0),$(z(t),"popoverId",void 0),$(z(t),"previousActiveIndex",null),$(z(t),"textInput",null),$(z(t),"handleInputMount",(function(e){t.textInput=e,Object(D.a)(t.props.inputRef,e)})),$(z(t),"handleAnchorMount",(function(e){t.setState({anchor:e}),Object(D.a)(t.props.elementRef,e)})),$(z(t),"handleActiveOptionMount",(function(e){t.previousActiveIndex!==t.state.activeIndex&&(null==e||e.scrollIntoViewIfNeeded())})),$(z(t),"handleInputFocus",(function(e){var n,r;t.focusCalledInternally?t.focusCalledInternally=!1:t.open(),null===(n=(r=t.props).onFocus)||void 0===n||n.call(r,e)})),$(z(t),"handleChange",(function(e,n){var r,o,a=n.value,i=n.selectedOption,l=t.props.name,c=i?void 0:a;t.isControlled()?t.setState({activeIndex:0,typedValue:c}):t.setState({value:a,activeIndex:0,typedValue:c}),null===(r=(o=t.props).onChange)||void 0===r||r.call(o,e,{value:a,name:l})})),$(z(t),"handleSelectOption",(function(e,n){t.handleChange(e,A(A({},n),{},{selectedOption:!0})),t.focusCalledInternally=!0,t.focus(),t.close()})),$(z(t),"handleInputKeyDown",(function(e){var n=t.props,o=n.children,a=n.onKeyDown,i=n.onScrollBottom,l=t.availableOptionCount,c=t.activeValue,s=Object(p.keycode)(e.nativeEvent);if(t.state.open)switch(s){case"enter":c&&t.handleSelectOption(e,{value:c});break;case"tab":t.close();break;case"down":if(t.setState((function(e){return{activeIndex:Math.min(e.activeIndex+1,l-1)}})),o&&i){var u=r.Children.count(o)-2;t.state.activeIndex===u&&t.handleScrollBottom(e)}break;case"up":t.setState((function(e){return{activeIndex:Math.max(e.activeIndex-1,0)}}))}else!1===Object(p.addsCharacter)(e.nativeEvent)&&"enter"!==s&&"backspace"!==s&&"down"!==s&&"up"!==s||t.open();null==a||a(e)})),$(z(t),"handleInputClick",(function(){t.state.open||t.props.disabled||t.open()})),$(z(t),"handleRequestClose",(function(e){var n,r,o,a,i,l,c,s,u,p=e.event,f=e.reason;("offScreen"===f||"escapeKey"===f||"clickAway"===f&&t.textInput&&(n=t.textInput,o=(r=p).clientX,a=r.clientY,l=(i=n.getBoundingClientRect()).top,c=i.left,s=i.bottom,u=i.right,!(o>c&&o<u&&a>l&&a<s)))&&t.close()})),$(z(t),"handleScrollBottom",(function(e){var n,r;t.state.open&&!t.props.isLoadingOptions&&(null===(n=(r=t.props).onScrollBottom)||void 0===n||n.call(r,e))})),$(z(t),"renderMenu",(function(e){var n=e.anchorWidth,a=e.maxHeight,i=t.props,s=i.children,u=i.controlledFilter,p=i.isLoadingOptions,d=i.menuStyle,b=i.onScrollBottom,h=t.state,y=h.activeIndex,m=h.typedValue,g=t.getValue(),O=r.Children.toArray(s).filter(r.isValidElement),x=Object(l.some)(O,(function(e){return e.type!==f.Heading&&(void 0===e.props.label?e.props.value===g:void 0!==e.props.label&&void 0!==m?e.props.label===g:e.props.value===g)}));!x&&g&&O.unshift(o.a.createElement(T,{key:"currentValueOption",value:g,"data-test-current-value-option":g})),t.availableOptionCount=0,t.activeValue=void 0;var j=Object(c.stringToKeywords)(m?g:t.getDisplayValue());return t.options=(u?O:O.filter((function(e){return void 0!==e.props.label?Object(c.testPhrase)(e.props.label,j):void 0===e.props.value||Object(c.testPhrase)(e.props.value,j)}))).map((function(e,n){if(!Object(l.has)(e.props,"active"))return e;var o=t.availableOptionCount===y;t.availableOptionCount+=1;var a=void 0!==e.props.label?e.props.label:e.props.value,i=e.props.matchRanges,s=!u&&g&&(x||n>0)&&Object(c.keywordLocations)(a,j)||void 0;return o?(t.activeValue=e.props.value,Object(r.cloneElement)(e,{ref:t.handleActiveOptionMount,id:t.activeItemId,onClick:t.handleSelectOption,matchRanges:i||s,active:!0})):Object(r.cloneElement)(e,{onClick:t.handleSelectOption,matchRanges:i||s})})),o.a.createElement(v.a,R({style:Object(l.extend)({overflow:"auto",width:Math.max(null!=n?n:0,200)},d),controlledExternally:!0,maxHeight:null!=a?a:void 0,onScrollBottom:b?t.handleScrollBottom:void 0,isLoading:p},Object(l.pick)(t.props,"className","noOptionsMessage","footerMessage","animateLoading","loadingMessage","onScroll")),t.options)})),t.state={activeIndex:0,anchor:null,typedValue:void 0,open:!1,value:e.defaultValue||""},t.controlledExternally=Object(l.has)(e,"value"),t.popoverId=Object(s.createDOMID)("popover"),t.activeItemId=Object(s.createDOMID)("active-item"),t}return t=h,(n=[{key:"componentDidUpdate",value:function(e,t){this.previousActiveIndex=t.activeIndex}},{key:"getValue",value:function(){return this.isControlled()?this.props.value:this.state.value}},{key:"getDisplayValue",value:function(){var e=this.getValue(),t=this.state.typedValue,n=r.Children.toArray(this.props.children).filter(r.isValidElement),o=!t&&n.find((function(t){return void 0!==t.props.label&&t.props.value===e}));return o?null==o?void 0:o.props.label:e}},{key:"open",value:function(){var e=this;this.setState({open:!0,activeIndex:0},(function(){var t,n;null===(t=(n=e.props).onOpen)||void 0===t||t.call(n)}))}},{key:"close",value:function(){var e=this;this.setState({open:!1},(function(){var t,n;e.previousActiveIndex=null,null===(t=(n=e.props).onClose)||void 0===t||t.call(n)}))}},{key:"focus",value:function(){var e;null===(e=this.textInput)||void 0===e||e.focus()}},{key:"isControlled",value:function(){return this.controlledExternally}},{key:"render",value:function(){var e=this.props.defaultPlacement,t=this.state,n=t.anchor,r=t.open,a=this.getValue(),i=this.getDisplayValue();return o.a.createElement(m.a,R({autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",spellCheck:!1,canClear:!0,"data-test":"combo-box"},Object(l.omit)(this.props,"animateLoading","className","controlledFilter","defaultValue","footerMessage","isLoadingOptions","loadingMessage","menuStyle","noOptionsMessage","onClose","onOpen","onScroll","onScrollBottom","spellCheck"),{"data-test-popover-id":this.popoverId,"data-test-label":i,"data-test-value":a,"data-test-open":r&&!!n,onFocus:this.handleInputFocus,onClick:this.handleInputClick,onChange:this.handleChange,onKeyDown:this.handleInputKeyDown,inputRef:this.handleInputMount,elementRef:this.handleAnchorMount,role:"combobox",value:i,"aria-activedescendant":this.activeItemId,"aria-expanded":r,"aria-haspopup":!0,"aria-label":Object(u._)("Value input"),"aria-controls":r?this.popoverId:void 0}),o.a.createElement(b.a,{anchor:n,autoCloseWhenOffScreen:!0,canCoverAnchor:!1,defaultPlacement:e,id:this.popoverId,onRequestClose:this.handleRequestClose,open:r&&!!n,repositionMode:"flip"},this.renderMenu))}}])&&M(t.prototype,n),h}(r.Component);$(q,"propTypes",H),$(q,"defaultProps",V),$(q,"Option",T),$(q,"Divider",f.Divider),$(q,"Heading",f.Heading);var W=q},18:function(e,t){e.exports=n(9016)},2:function(e,t){e.exports=n(7294)},24:function(e,t){e.exports=n(6401)},26:function(e,t){e.exports=n(583)},36:function(e,t){e.exports=n(8566)},4:function(e,t){e.exports=n(5220)},5:function(e,t){e.exports=n(6219)},9:function(e,t){e.exports=n(2916)}})},2215:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=142)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},11:function(e,t){e.exports=n(9726)},14:function(e,t){e.exports=n(5766)},142:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return F})),n.d(t,"ControlGroupContext",(function(){return C}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(0),s=n(11),u=n(8),p=n.n(u),f=n(14),d=n.n(f),b=n(52),h=n.n(b),v=n(3),y=n.n(v),m=y()(p.a).withConfig({displayName:"ControlGroupStyles__StyledBox",componentId:"wjnyif-0"})([""," "," max-width:600px;margin-bottom:",";"," color:",";",""],c.mixins.reset("block"),c.mixins.clearfix(),Object(c.pick)({enterprise:Object(v.css)(["calc("," * 0.75)"],c.variables.spacing),prisma:{comfortable:"16px",compact:"12px"}}),Object(c.pick)({prisma:{comfortable:Object(v.css)(["&:first-child{margin-top:",";}&:last-child{margin-bottom:",";}"],c.variables.spacingMedium,c.variables.spacingMedium),compact:Object(v.css)(["&:first-child{margin-top:",";}&:last-child{margin-bottom:",";}"],c.variables.spacingSmall,c.variables.spacingSmall)}}),Object(c.pick)({enterprise:c.variables.textColor,prisma:c.variables.contentColorMuted}),(function(e){return e.$error&&Object(v.css)(["color:",";"],Object(c.pick)({enterprise:{light:c.variables.errorColorD10,dark:c.variables.errorColorL20},prisma:c.variables.accentColorNegative}))})),g=y()(p.a).withConfig({displayName:"ControlGroupStyles__StyledControlsStackBox",componentId:"wjnyif-1"})(["flex-direction:column;"]),O=y.a.div.withConfig({displayName:"ControlGroupStyles__StyledLabelWrapper",componentId:"wjnyif-2"})(["display:inline-flex;align-items:center;"," ",""],Object(c.pick)({enterprise:Object(v.css)(["justify-content:flex-end;"])}),(function(e){return"top"===e.$labelPosition?Object(v.css)(["",""],Object(c.pick)({prisma:Object(v.css)(["padding-bottom:",";"],c.variables.spacingXSmall)})):Object(v.css)(["",""],Object(c.pick)({prisma:Object(v.css)(["min-height:",";"],c.variables.inputHeight)}))})),x=y()(O).withConfig({displayName:"ControlGroupStyles__StyledLabelWrapperLeft",componentId:"wjnyif-3"})(["float:left;"]),j=y.a.label.withConfig({displayName:"ControlGroupStyles__StyledLabel",componentId:"wjnyif-4"})(["padding:",";word-wrap:break-word;color:inherit;text-align:",";"],Object(c.pick)({enterprise:{comfortable:"6px 0",compact:"4px 0"}}),Object(c.pick)({enterprise:"right",prisma:"left"})),w=y.a.div.withConfig({displayName:"ControlGroupStyles__StyledHelp",componentId:"wjnyif-5"})(["",";font-size:",";color:",";margin-top:",";[aria-invalid] > &{color:inherit;}"],c.mixins.reset("block"),c.variables.fontSizeSmall,c.variables.contentColorMuted,Object(c.pick)({enterprise:"2px",prisma:"4px"})),C=o.a.createContext({});function S(e){return S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},S(e)}function k(){return k=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},k.apply(this,arguments)}function P(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function E(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?P(Object(n),!0).forEach((function(t){A(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):P(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function _(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function T(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function D(e,t){return D=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},D(e,t)}function I(e,t){return!t||"object"!==S(t)&&"function"!=typeof t?R(e):t}function R(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function L(e){return L=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},L(e)}function A(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var M={children:i.a.node,controlsLayout:i.a.oneOf(["fill","fillJoin","none","stack"]),elementRef:i.a.oneOfType([i.a.func,i.a.object]),error:i.a.bool,help:i.a.node,hideLabel:i.a.bool,label:i.a.string.isRequired,labelFor:i.a.string,labelPosition:i.a.oneOf(["left","top"]),labelWidth:i.a.oneOfType([i.a.number,i.a.string]),size:i.a.oneOf(["small","medium"]),splunkTheme:i.a.object,tooltip:i.a.node,tooltipDefaultPlacement:i.a.oneOf(["above","below","left","right","theme"])},B={flexGrow:1},N=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&D(e,t)}(u,e);var t,n,a,i,c=(a=u,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=L(a);if(i){var n=L(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return I(this,e)});function u(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,u),A(R(t=c.call(this,e)),"helpId",void 0),A(R(t),"labelId",void 0),A(R(t),"contextValue",void 0),A(R(t),"childIds",void 0),A(R(t),"stackLayoutChildStyle",void 0),A(R(t),"getChildID",(function(e,n){var r="".concat(e,"-").concat(n),o=t.childIds[r];return o&&o.length||(o=Object(s.createDOMID)(e),t.childIds[r]=o),o})),A(R(t),"getStackLayoutChildStyle",(function(e,n){return e?(n&&(t.stackLayoutChildStyle.marginBottom="12px"),t.stackLayoutChildStyle.marginBottom="16px"):t.stackLayoutChildStyle.marginBottom="0",t.stackLayoutChildStyle})),A(R(t),"hasInputId",(function(e){return e.type&&e.type.propTypes&&Object.prototype.hasOwnProperty.call(e.type.propTypes,"inputId")})),A(R(t),"getLinkedId",(function(e){if(0!==e.length){var n=(a=e,i=1,function(e){if(Array.isArray(e))return e}(a)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,a=void 0;try{for(var i,l=e[Symbol.iterator]();!(r=(i=l.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){o=!0,a=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw a}}return n}}(a,i)||function(e,t){if(e){if("string"==typeof e)return _(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_(e,t):void 0}}(a,i)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())[0],r=Object(l.find)(e,(function(e){return e.type&&"Text"===e.type.componentType})),o=t.hasInputId(n);return 1===e.length&&n&&n.props?o?n.props.inputId:n.props.id:r&&r.props?r.props.inputId:n.props?o?n.props.inputId:n.props.id:void 0}var a,i})),t.labelId=Object(s.createDOMID)("label"),t.helpId=Object(s.createDOMID)("help"),t.contextValue=t.createContextValue(),t.childIds={},t.stackLayoutChildStyle={},t}return t=u,(n=[{key:"shouldComponentUpdate",value:function(e){return o.a.Children.count(e.children)!==o.a.Children.count(this.props.children)&&(this.childIds={}),!0}},{key:"createContextValue",value:function(){return{labelAttrs:{text:this.props.label,id:this.labelId}}}},{key:"getContextValue",value:function(){var e,t;return this.props.label===(null===(e=this.contextValue.labelAttrs)||void 0===e?void 0:e.text)&&this.labelId===(null===(t=this.contextValue.labelAttrs)||void 0===t?void 0:t.id)||(this.contextValue=this.createContextValue()),this.contextValue}},{key:"render",value:function(){var e=this,t=this.props,n=t.children,a=t.controlsLayout,i=t.error,c=t.help,s=t.hideLabel,u=t.label,f=t.labelFor,b=t.labelPosition,v=t.labelWidth,y=t.size,S=t.splunkTheme,P=t.tooltip,_=t.tooltipDefaultPlacement,T=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(t,["children","controlsLayout","error","help","hideLabel","label","labelFor","labelPosition","labelWidth","size","splunkTheme","tooltip","tooltipDefaultPlacement"]),D=S.isPrisma,I=S.isCompact,R=r.Children.toArray(n).filter(r.isValidElement),L=R.length,A=T,M=R.map((function(t,n){var o={key:t.key||n};if("fillJoin"===a&&(n>0&&(o.prepend=!0),n<L-1&&(o.append=!0),(o.prepend||o.append)&&(o.inline=!1)),"fill"===a&&L>1&&(o.inline=!0),"stack"===a&&(o.inline=!1,n<L-1)){var i=e.getStackLayoutChildStyle(D,I);o.style=t.props.style?E(E({},t.props.style),i):i}return o.labelledBy=e.labelId,e.props.help&&(o.describedBy=e.helpId),"Multiselect"===t.type.componentType?!1===t.props.compact&&(o.labelText=u):o.labelText=u,1!==L||"fillJoin"!==a&&"fill"!==a||(o.style=t.props.style?E(E({},t.props.style),B):B),!f&&t&&(e.hasInputId(t)?o.inputId=t.props.inputId||e.getChildID("input-id",n):o.id=t.props.id||e.getChildID("id",n)),Object(r.cloneElement)(t,o)})),N=this.getLinkedId(M);i&&(A["aria-invalid"]=!0);var z="left"===b?{width:v}:void 0,F=Object(l.isFinite)(v)?"".concat(v,"px"):v,$=D?"16px":"20px",H="left"===b?{marginLeft:"calc(".concat(F," + ").concat($,")")}:void 0,V="stack"===a?g:p.a,q="left"===b?x:O,W=o.a.createElement(q,{style:z,$labelPosition:b},o.a.createElement(j,{"data-size":y,"data-test":"label",id:this.labelId,htmlFor:f||N,$tooltip:!!P},u,!D&&!s&&P&&o.a.createElement("span",null," "),!s&&P&&o.a.createElement(d.a,null,P)),!s&&P&&o.a.createElement(h.a,{closeWhen:"notOnClick",content:P,defaultPlacement:_,"aria-hidden":"true"}));return o.a.createElement(m,k({"data-test":"control-group",$error:i},A),o.a.createElement(C.Provider,{value:this.getContextValue()},s?o.a.createElement(d.a,null,W):W,o.a.createElement(V,{"data-test":"controls",flex:"none"!==a,style:H},M),c&&o.a.createElement(w,{"data-test":"help",id:this.helpId,style:H},c)))}}])&&T(t.prototype,n),u}(r.Component);A(N,"propTypes",M),A(N,"defaultProps",{controlsLayout:"fill",error:!1,hideLabel:!1,labelPosition:"left",labelWidth:120,size:"medium"});var z=Object(c.withSplunkTheme)(N);z.propTypes=N.propTypes;var F=z},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)},4:function(e,t){e.exports=n(5220)},52:function(e,t){e.exports=n(5458)},8:function(e,t){e.exports=n(6493)}})},2346:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=126)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},126:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return C})),n.d(t,"Description",(function(){return b})),n.d(t,"Term",(function(){return O}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(3),c=n.n(l),s=n(0),u=c.a.dd.withConfig({displayName:"DescriptionStyles__Styled",componentId:"sc-1jglixb-0"})(["",";min-height:",";padding-left:5px;",""],s.mixins.reset("block"),s.variables.lineHeight,Object(s.pick)({prisma:Object(l.css)(["color:",";"],s.variables.contentColorActive)}));function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},p.apply(this,arguments)}var f={children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object])};function d(e){var t=e.children,n=e.elementRef,r=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","elementRef"]);return o.a.createElement(u,p({"data-test":"description",ref:n},r),t)}d.propTypes=f;var b=d,h=c.a.dl.withConfig({displayName:"DefinitionListStyles__Styled",componentId:"sc-1pqfrgm-0"})(["",";"],s.mixins.reset("block")),v=c.a.dt.withConfig({displayName:"TermStyles__Styled",componentId:"sc-1ao97j9-0"})(["",";float:left;width:120px;overflow:hidden;overflow-x:hidden;white-space:nowrap;font-weight:400;word-wrap:normal;"," ",""],s.mixins.reset("block"),Object(s.pick)({prisma:Object(l.css)(["color:",";"],s.variables.contentColorMuted)}),Object(s.pick)({enterprise:Object(l.css)(["&::after{content:'","';}"]," ".concat(".".repeat(100)))}));function y(){return y=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},y.apply(this,arguments)}var m={children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object])};function g(e){var t=e.children,n=e.elementRef,r=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","elementRef"]);return o.a.createElement(v,y({"data-test":"term",ref:n},r),t)}g.propTypes=m;var O=g;function x(){return x=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},x.apply(this,arguments)}var j={children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),termWidth:i.a.oneOfType([i.a.number,i.a.string])};function w(e){var t=e.children,n=e.elementRef,a=e.termWidth,i=void 0===a?120:a,l=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","elementRef","termWidth"]);return o.a.createElement(h,x({"data-test":"definition-list",ref:n},l),function(e){var t=e.children,n=e.termWidth;return r.Children.toArray(t).filter(r.isValidElement).map((function(e){return e.type===O?Object(r.cloneElement)(e,{style:{width:n}}):e.type===b?Object(r.cloneElement)(e,{style:{marginLeft:n}}):e}))}({children:t,termWidth:i}))}w.propTypes=j,w.Description=b,w.Term=O;var C=w},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)}})},7049:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=118)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},11:function(e,t){e.exports=n(9726)},118:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return ye})),n.d(t,"Item",(function(){return W}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(15),s=n.n(c),u=n(0),p=n(5),f=n(11),d=n(45),b=n(90),h=n.n(b),v=n(22),y=n(25),m=n.n(y);function g(){return g=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},g.apply(this,arguments)}function O(e){return o.a.createElement(m.a,g({hideDefaultTooltip:!0,viewBox:"0 0 16 16",width:"16px",height:"16px"},e),o.a.createElement("path",{d:"M8.624 14.7021C8.23332 15.0928 7.59989 15.0928 7.2092 14.7021L2.33962 9.83209C0.546941 8.03927 0.54695 5.1325 2.33964 3.33968C4.13162 1.54758 7.03672 1.54684 8.82962 3.33802L14.1746 8.67787C15.2682 9.77043 15.2687 11.5429 14.1756 12.636C13.083 13.7288 11.3115 13.7288 10.2189 12.636L4.87676 7.29338C4.48607 6.90266 4.48607 6.26917 4.87676 5.87845C5.26744 5.48773 5.90087 5.48773 6.29155 5.87845L11.6337 11.2211C11.9449 11.5324 12.4496 11.5324 12.7608 11.2211C13.0722 10.9097 13.0721 10.4048 12.7606 10.0936L7.41557 4.75369C6.40415 3.74325 4.76532 3.74367 3.75442 4.75463C2.74312 5.766 2.74312 7.40578 3.75441 8.41715L8.62399 13.2871C9.01468 13.6779 9.01468 14.3113 8.624 14.7021Z",fill:"currentColor"}))}function x(){return x=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},x.apply(this,arguments)}function j(e){var t="compact"===Object(u.useSplunkTheme)().density?"20px":"24px";return o.a.createElement(m.a,x({hideDefaultTooltip:!0,viewBox:"0 0 24 24",width:t,height:t},e),o.a.createElement("path",{d:"M18.2685 14.3175L18.4349 14.9384C18.6078 14.558 18.7453 14.162 18.8452 13.7556C18.9449 13.3507 19.0068 12.9373 19.0303 12.521L19.0362 12.4167C19.0663 11.883 19.0409 11.3476 18.9604 10.8191L18.9462 10.7261C18.8794 10.287 18.7695 9.85559 18.6181 9.43803C18.4827 9.06459 18.3148 8.70378 18.1162 8.35979L18.0868 8.30889C17.8331 7.86964 17.5281 7.46215 17.1781 7.09503C16.9596 6.8658 16.7243 6.65314 16.4743 6.4588L16.318 6.33739C16.0132 6.10052 15.6825 5.88712 15.34 5.70564C14.95 5.49901 14.5348 5.32943 14.1132 5.20545C13.7201 5.08986 13.317 5.01136 12.9093 4.97099L12.8406 4.96419C12.4182 4.92237 11.993 4.91829 11.5699 4.95201C11.1331 4.98682 10.7005 5.06176 10.2774 5.17589L9.70069 5.33148C9.16747 5.47533 8.61859 5.15969 8.47474 4.62647C8.33089 4.09324 8.64653 3.54437 9.17976 3.40051L9.7565 3.24492C10.298 3.09883 10.8519 3.00289 11.411 2.95833C11.9526 2.91517 12.497 2.92038 13.0377 2.97392L13.1063 2.98072C13.6384 3.03341 14.1644 3.13584 14.6774 3.28668C15.2296 3.44906 15.7694 3.66976 16.2764 3.9384C16.7197 4.17329 17.1479 4.44938 17.5453 4.75819L17.7015 4.8796C18.0299 5.13478 18.3388 5.41401 18.6257 5.715C19.0853 6.19704 19.4858 6.73209 19.8188 7.30885L19.8482 7.35975C20.1055 7.80535 20.323 8.27272 20.4984 8.75646C20.6944 9.29736 20.8368 9.85624 20.9234 10.425L20.9376 10.518C21.0389 11.1833 21.0709 11.8573 21.033 12.5293L21.0271 12.6335C20.9967 13.1731 20.9164 13.7087 20.7873 14.2334C20.6488 14.7966 20.4548 15.3442 20.2083 15.8683L20.718 15.7317C21.2515 15.5888 21.7998 15.9054 21.9428 16.4389C22.0857 16.9723 21.7691 17.5207 21.2356 17.6636L18.8208 18.3106C18.0206 18.525 17.1981 18.0501 16.9837 17.2499L16.3367 14.8352C16.1937 14.3017 16.5103 13.7534 17.0438 13.6104C17.5773 13.4675 18.1256 13.7841 18.2685 14.3175ZM3.92363 7.90992L3.33327 8.06809C2.7998 8.21103 2.25147 7.89443 2.10854 7.36097C1.9656 6.8275 2.2822 6.27917 2.81566 6.13623L5.2305 5.48922C6.03069 5.27483 6.85318 5.7497 7.06759 6.54989L7.71463 8.96466C7.85757 9.49813 7.54099 10.0465 7.00752 10.1894C6.47405 10.3324 5.92572 10.0158 5.78278 9.4823L5.64111 8.9536C5.46988 9.32312 5.33225 9.70767 5.23007 10.1026C5.1256 10.5063 5.05872 10.9189 5.03027 11.3349L5.02314 11.4391C4.98667 11.9725 5.00567 12.5081 5.07982 13.0376L5.09286 13.1307C5.15447 13.5705 5.25921 14.0032 5.40556 14.4226C5.53644 14.7976 5.70008 15.1604 5.89456 15.5068L5.92334 15.558C6.17169 16.0003 6.47181 16.4114 6.81738 16.7826C7.03315 17.0145 7.26586 17.2299 7.51359 17.4273L7.66835 17.5505C7.97029 17.791 8.29849 18.0084 8.63879 18.1939C9.02626 18.4052 9.43938 18.5797 9.8595 18.7088C10.2512 18.829 10.6533 18.9124 11.0605 18.9576L11.1291 18.9652C11.551 19.0121 11.9761 19.0213 12.3996 18.9926C12.8368 18.963 13.2703 18.8933 13.6946 18.7842L14.2732 18.6355C14.8081 18.4981 15.3532 18.8202 15.4906 19.3552C15.6281 19.8901 15.3059 20.4351 14.771 20.5726L14.1924 20.7213C13.6492 20.8609 13.0943 20.9502 12.5346 20.988C11.9925 21.0247 11.4483 21.013 10.9083 20.953L10.8397 20.9454C10.3082 20.8863 9.78352 20.7776 9.27238 20.6206C8.72212 20.4517 8.18505 20.2245 7.68131 19.9498C7.24086 19.7097 6.81595 19.4285 6.42229 19.1149L6.26753 18.9917C5.94226 18.7326 5.6367 18.4497 5.35338 18.1453C4.89963 17.6578 4.50556 17.118 4.17948 16.5373L4.1507 16.486C3.89877 16.0374 3.6868 15.5674 3.51725 15.0816C3.32768 14.5384 3.192 13.9779 3.1122 13.4081L3.09915 13.315C3.0058 12.6485 2.98189 11.9741 3.0278 11.3027L3.03493 11.1985C3.07179 10.6594 3.15847 10.1248 3.29383 9.60161C3.44505 9.01718 3.65617 8.4503 3.92363 7.90992Z",fill:"currentColor"}))}function w(){return w=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},w.apply(this,arguments)}function C(e){var t="compact"===Object(u.useSplunkTheme)().density?"20px":"24px";return o.a.createElement(m.a,w({hideDefaultTooltip:!0,viewBox:"0 0 24 24",width:t,height:t},e),o.a.createElement("path",{d:"M10 4V6H14V4H10ZM16 6H17H19H20C20.5523 6 21 6.44772 21 7C21 7.55228 20.5523 8 20 8H19V20.5C19 21.3284 18.3284 22 17.5 22H6.5C5.67157 22 5 21.3284 5 20.5V8H4C3.44772 8 3 7.55228 3 7C3 6.44772 3.44772 6 4 6H5H7H8V3.5C8 2.67157 8.67157 2 9.5 2H14.5C15.3284 2 16 2.67157 16 3.5V6ZM7 8V20H17V8H7ZM10.5858 14L9.2929 15.2929C8.90237 15.6834 8.90237 16.3166 9.2929 16.7071C9.68342 17.0976 10.3166 17.0976 10.7071 16.7071L12 15.4142L13.2929 16.7071C13.6834 17.0976 14.3166 17.0976 14.7071 16.7071C15.0976 16.3166 15.0976 15.6834 14.7071 15.2929L13.4142 14L14.7071 12.7071C15.0976 12.3166 15.0976 11.6834 14.7071 11.2929C14.3166 10.9024 13.6834 10.9024 13.2929 11.2929L12 12.5858L10.7071 11.2929C10.3166 10.9024 9.68342 10.9024 9.29289 11.2929C8.90237 11.6834 8.90237 12.3166 9.29289 12.7071L10.5858 14Z",fill:"currentColor"}))}var S=Object(r.createContext)({disabled:!1});S.displayName="File";var k=S,P=n(3),E=n.n(P),_=n(8),T=n.n(_),D=n(12),I=n.n(D),R=n(59),L=E()(T.a).withConfig({displayName:"ItemStyles__StyledBox",componentId:"sc-1fsk3kr-0"})(["position:relative;width:100%;max-width:400px;margin:",";background-color:",";border-radius:",";min-height:32px;color:",";"," "," "," ",";"],Object(u.pick)({enterprise:"5px auto 0",prisma:{comfortable:"8px auto 0",compact:"4px auto 0"}}),Object(u.pick)({enterprise:{light:u.variables.gray92,dark:u.variables.gray45},prisma:u.variables.interactiveColorBackground}),Object(u.pick)({enterprise:"2px",prisma:u.variables.borderRadius}),Object(u.pick)({enterprise:u.variables.textGray,prisma:u.variables.contentColorDefault}),Object(u.pick)({prisma:Object(P.css)(["border:1px solid ",";padding-left:12px;"],u.variables.neutral200),enterprise:Object(P.css)(["line-height:24px;"])}),Object(u.pick)({enterprise:{compact:Object(P.css)(["min-height:24px;"])}}),(function(e){return e.$error&&Object(u.pick)({enterprise:Object(P.css)(["box-shadow:inset 0 0 0 1px ",";"],u.variables.errorColor),prisma:Object(P.css)(["box-shadow:inset 0 0 0 1px ",";background-color:",";"],u.variables.accentColorNegative,u.variables.interactiveColorBackground)})}),(function(e){return e.$disabled&&Object(P.css)(["cursor:not-allowed;background-color:",";"],Object(u.pick)({enterprise:{dark:u.variables.gray60,light:u.variables.gray96},prisma:Object(R.overlayColors)(u.variables.interactiveColorBackground,u.variables.interactiveColorBackgroundDisabled)}))})),A=E.a.div.withConfig({displayName:"ItemStyles__StyledErrorText",componentId:"sc-1fsk3kr-1"})(["font-size:",";color:",";line-height:16px;margin-top:4px;text-align:left;"],u.variables.fontSizeSmall,u.variables.accentColorNegative),M=E()(I.a).withConfig({displayName:"ItemStyles__StyledIconClickable",componentId:"sc-1fsk3kr-2"})(["color:",";border-radius:",";padding:",";text-align:center;"," "," &:focus{color:",";","}&:hover{background-color:",";color:",";}"],Object(u.pick)({enterprise:"inherit",prisma:u.variables.contentColorDefault}),Object(u.pick)({enterprise:"0 2px 2px 0",prisma:"50%"}),Object(u.pick)({enterprise:"3px 0",prisma:{comfortable:"0 8px",compact:"0 6px"}}),Object(u.pick)({enterprise:Object(P.css)(["flex-basis:",";"],u.variables.inputHeight)}),(function(e){return e.$error&&Object(P.css)(["",""],Object(u.pick)({enterprise:Object(P.css)(["border:1px solid ",";border-left:none;"],u.variables.errorColor)}))}),Object(u.pick)({enterprise:u.variables.linkColor,prisma:u.variables.contentColorActive}),Object(u.pick)({enterprise:Object(P.css)(["box-shadow:",";"],u.variables.focusShadow),prisma:Object(P.css)(["background-color:",";box-shadow:0 0 0 3px ",";"],u.variables.interactiveColorOverlayHover,u.variables.focusColor)}),Object(u.pick)({enterprise:{light:u.variables.gray96,dark:u.variables.gray30},prisma:u.variables.interactiveColorOverlayHover}),Object(u.pick)({enterprise:u.variables.linkColor,prisma:u.variables.contentColorActive})),B=E()(I.a).withConfig({displayName:"ItemStyles__StyledTrashIcon",componentId:"sc-1fsk3kr-3"})(["color:",";border-radius:50%;padding:",";margin-right:",";text-align:center;&:focus{color:",";background-color:",";box-shadow:0 0 0 3px ",";}&:hover{background-color:",";color:",";}"],u.variables.contentColorDefault,Object(u.pick)({comfortable:"0 8px",compact:"0 6px"}),Object(u.pick)({comfortable:"0 4px",compact:"0 6px"}),u.variables.contentColorActive,u.variables.interactiveColorOverlayHover,u.variables.focusColor,u.variables.interactiveColorOverlayHover,u.variables.contentColorActive),N=E.a.div.withConfig({displayName:"ItemStyles__StyledLabel",componentId:"sc-1fsk3kr-4"})(["color:",";overflow:hidden;white-space:nowrap;text-overflow:ellipsis;flex:1 0 0px;padding:",";border-radius:",";",""],u.variables.contentColorActive,Object(u.pick)({enterprise:"3px 0 3px 10px",prisma:{comfortable:"10px 0 10px 0",compact:"6px 0 6px 0"}}),Object(u.pick)({enterprise:"2px",prisma:u.variables.borderRadius}),(function(e){return e.$disabled&&Object(u.pick)({enterprise:{light:Object(P.css)(["color:",";"],u.variables.textGray),dark:Object(P.css)(["color:",";"],u.variables.textGray)},prisma:Object(P.css)(["color:",";"],u.variables.contentColorDisabled)})})),z=E.a.div.withConfig({displayName:"ItemStyles__StyledPaperClipIcon",componentId:"sc-1fsk3kr-5"})(["color:",";padding:",";",""],u.variables.neutral400,Object(u.pick)({comfortable:"8px 4px 8px 0",compact:"4px 4px 4px 0"}),(function(e){return e.$disabled&&Object(P.css)(["color:",";cursor:not-allowed;"],u.variables.contentColorDisabled)})),F=E.a.span.withConfig({displayName:"ItemStyles__StyledPercentage",componentId:"sc-1fsk3kr-6"})(["color:",";"],u.variables.contentColorMuted),$=E.a.div.withConfig({displayName:"ItemStyles__StyledProgress",componentId:"sc-1fsk3kr-7"})(["position:absolute;left:0;top:0;width:","%;height:100%;background:",";transition:width 300ms;border-radius:",";"],(function(e){return e.$uploadPercentage}),u.variables.interactiveColorOverlaySelected,u.variables.borderRadius);function H(){return H=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},H.apply(this,arguments)}var V={disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),error:i.a.bool,index:i.a.number,itemId:i.a.any,name:i.a.string.isRequired,uploadPercentage:i.a.number};function q(e){var t=e.disabled,n=e.error,a=void 0!==n&&n,i=e.itemId,c=e.name,s=e.index,f=void 0===s?0:s,b=e.uploadPercentage,y=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["disabled","error","itemId","name","index","uploadPercentage"]),m=Object(u.useSplunkTheme)().isPrisma,g=Object(r.useContext)(S).onRequestRemove;function x(e){e.preventDefault(),null==g||g({itemId:i,name:c,index:f})}var w=Object(r.useContext)(S).onRequestRetry,k=Object(r.useContext)(S).disabled,P=Object(d.sprintf)(Object(p._)('Remove "%(filename)s"'),{filename:c}),E=Object(d.sprintf)(Object(p._)('Retry "%(filename)s"'),{filename:c}),_=Object(d.sprintf)(Object(p._)('Uploading "%(filename)s"'),{filename:c}),T=o.a.createElement("span",null,o.a.createElement("span",{style:{paddingRight:"4px"}},Object(p._)("Uploading ")),o.a.createElement(F,null,b,"%")),D=m&&!Object(l.isUndefined)(b)&&b>0?T:c,I=void 0!==t?t:k;return o.a.createElement(o.a.Fragment,null,o.a.createElement(L,H({"data-test":"item","data-test-disabled":I},y,{flex:!0,$error:a,$disabled:I}),m&&Object(l.isUndefined)(b)&&o.a.createElement(z,{"data-test":"paper-clip",$disabled:I},o.a.createElement(O,{"aria-hidden":"true"})),o.a.createElement(N,{"data-test":"label",$error:a,$disabled:I},D),m&&w&&a&&o.a.createElement(M,{"data-test":"retry",onClick:function(e){e.preventDefault(),null==w||w({itemId:i,name:c,index:f})},"aria-label":E},o.a.createElement(j,{screenReaderText:Object(p._)("Retry")})),!I&&(m&&Object(l.isUndefined)(b)&&!a?o.a.createElement(B,{"data-test":"remove",onClick:x,"aria-label":P},o.a.createElement(C,{screenReaderText:Object(p._)("Remove")})):o.a.createElement(M,{"data-test":"remove",$error:a,onClick:x,"aria-label":P},o.a.createElement(v.a,{screenReaderText:Object(p._)("Remove")}))),!Object(l.isUndefined)(b)&&b>0&&(m?o.a.createElement($,{$uploadPercentage:b,"aria-label":_,role:"progressbar","aria-valuenow":b,"aria-valuemin":0,"aria-valuemax":100}):o.a.createElement(h.a,{style:{position:"absolute",left:0,top:0,right:0,zIndex:1},percentage:b,"aria-label":_}))),m&&a&&o.a.createElement(A,null,Object(p._)("Something went wrong.")))}q.propTypes=V;var W=q;function K(){return K=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},K.apply(this,arguments)}function U(e){return o.a.createElement(m.a,K({hideDefaultTooltip:!0,screenReaderText:Object(p._)("File upload"),viewBox:"0 0 72 88"},e),o.a.createElement("path",{d:"M50,27 L68.0005854,27 C70.2022516,27 72,28.7919267 72,31.0023804 L72,83.9976196 C72,86.2074215 70.2094011,88 68.0005854,88 L3.99941455,88 C1.79774843,88 0,86.2080733 0,83.9976196 L0,31.0023804 C0,28.7925785 1.79059889,27 3.99941455,27 L21,27 L21,32 L5.99898406,32 C5.4472604,32 5,32.4408979 5,32.9958767 L5,82.0041233 C5,82.5541308 5.44605521,83 5.99898406,83 L66.0010159,83 C66.5527396,83 67,82.5591021 67,82.0041233 L67,32.9958767 C67,32.4458692 66.5539448,32 66.0010159,32 L50,32 L50,27 Z"}),o.a.createElement("path",{d:"M41.9634682,10 L41.9634682,28 L46.9634682,28 L46.9634682,5 L44.4634682,5 L23.9634682,5 L23.9634682,10 L41.9634682,10 Z",transform:"translate(35.463468, 16.500000) rotate(-45.000000) translate(-35.463468, -16.500000) "}),o.a.createElement("rect",{x:"33",y:"3",width:"5",height:"51"}))}var Z=E.a.input.withConfig({displayName:"FileStyles__StyledInput",componentId:"sc-1wyh4cf-0"})(["&[type='file']{width:0.1px;height:0.1px;opacity:0;overflow:hidden;position:absolute;z-index:-1;}"]),G=Object(P.css)(["fill:",";"],Object(u.pick)({enterprise:{light:u.variables.gray60,dark:u.variables.gray80}})),X=E()(U).withConfig({displayName:"FileStyles__StyledNormalIcon",componentId:"sc-1wyh4cf-1"})(["",";height:1.4em;width:1.4em;display:inline-block;vertical-align:middle;padding-bottom:3px;"],G),Y=E()(U).withConfig({displayName:"FileStyles__StyledWindowIcon",componentId:"sc-1wyh4cf-2"})(["",";height:48px;width:48px;position:absolute;top:30px;left:50%;transform:translateX(-50%);"],G),Q=E.a.label.withConfig({displayName:"FileStyles__StyledLink",componentId:"sc-1wyh4cf-3"})(["",";color:",";cursor:pointer;font-size:inherit;font-weight:inherit;&:hover,&[data-focused]{text-decoration:underline;}&[data-focused]{box-shadow:",";}"],u.mixins.reset("inline"),u.variables.linkColor,Object(u.pick)({enterprise:u.variables.focusShadowInset,prisma:u.variables.focusShadow})),J=E.a.div.withConfig({displayName:"FileStyles__StyledNormalText",componentId:"sc-1wyh4cf-4"})([""," "," "," ",""],Object(u.pick)({enterprise:Object(P.css)(["display:inline-block;"]),prisma:Object(P.css)(["display:inline-flex;flex-direction:column;justify-content:center;text-align:center;color:",";border:1px dashed ",";padding:8px;border-radius:",";min-height:128px;&:not(:last-child){margin-bottom:4px;}"],u.variables.contentColorActive,u.variables.contentColorMuted,u.variables.borderRadius)}),(function(e){return e.$dragOver&&Object(P.css)(["",""],Object(u.pick)({prisma:Object(P.css)(["border:1px dashed ",";background-color:",";"],u.variables.interactiveColorPrimary,u.mixins.colorWithAlpha(u.variables.interactiveColorPrimary,.1))}))}),(function(e){var t=e.$error,n=e.$dragOver;return t&&!n&&Object(u.pick)({prisma:Object(P.css)(["border:1px dashed ",";color:",";background-color:",";"],u.variables.accentColorNegative,u.variables.accentColorNegative,u.mixins.colorWithAlpha(u.variables.accentColorNegative,.1))})}),(function(e){return e.$disabled&&Object(P.css)(["border:none;min-height:0;color:",";cursor:not-allowed;"],Object(u.pick)({prisma:u.variables.contentColorDisabled}))})),ee=E.a.div.withConfig({displayName:"FileStyles__StyledWindowText",componentId:"sc-1wyh4cf-5"})(["margin-top:",";margin-bottom:",";font-size:",";",""],Object(u.pick)({enterprise:Object(P.css)(["calc("," * 4)"],u.variables.spacing),prisma:Object(P.css)(["calc("," * 4)"],u.variables.spacingLarge)}),Object(u.pick)({enterprise:u.variables.spacingHalf,prisma:u.variables.spacingMedium}),u.variables.fontSizeXLarge,Object(u.pick)({prisma:Object(P.css)(["color:",";"],u.variables.contentColorActive)})),te=E.a.div.withConfig({displayName:"FileStyles__StyledSubtitle",componentId:"sc-1wyh4cf-6"})(["color:",";padding:4px 8px;font-size:12px;line-height:16px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"],u.variables.contentColorMuted),ne=E.a.div.withConfig({displayName:"FileStyles__StyledHelp",componentId:"sc-1wyh4cf-7"})(["margin-bottom:",";"],Object(u.pick)({enterprise:u.variables.spacingXLarge,prisma:Object(P.css)(["calc("," * 1.5)"],u.variables.spacingLarge)})),re=E.a.div.withConfig({displayName:"FileStyles__StyledWindowDrop",componentId:"sc-1wyh4cf-8"})(["position:fixed;top:0;left:0;right:0;bottom:0;border:",";z-index:"," + 10;"],Object(u.pick)({enterprise:"5px solid ".concat(u.variables.accentColorL10),prisma:"5px solid ".concat(u.variables.interactiveColorPrimary)}),u.variables.zindexModal),oe=E()(T.a).withConfig({displayName:"FileStyles__StyledDropNormalTargetBox",componentId:"sc-1wyh4cf-9"})(["",";flex-direction:column;justify-content:center;text-align:center;border-radius:",";"," "," "," "," "," ",""],u.mixins.reset("flex"),u.variables.borderRadius,Object(u.pick)({enterprise:Object(P.css)(["line-height:calc("," - 2px);"],u.variables.inputHeight)}),Object(u.pick)({enterprise:{comfortable:Object(P.css)(["min-height:73px;padding:",";"],u.variables.spacingQuarter),compact:Object(P.css)(["min-height:63px;padding:3px;"])}}),Object(u.pick)({enterprise:{light:Object(P.css)(["border:1px dashed ",";"],u.variables.borderColor),dark:Object(P.css)(["border:1px dashed ",";"],u.variables.textGray)}}),(function(e){return e.$dragOver&&Object(u.pick)({enterprise:Object(P.css)(["border:1px solid ",";"],u.variables.accentColorL10)})}),(function(e){var t=e.$error,n=e.$dragOver;return t&&!n&&Object(u.pick)({enterprise:Object(P.css)(["border:1px solid ",";"],u.variables.errorColor)})}),(function(e){var t=e.$disabled,n=e.$fileCount;return t&&Object(P.css)(["border:",";color:",";cursor:not-allowed;"," ",""],Object(u.pick)({enterprise:"none",prisma:"1px solid ".concat(u.variables.contentColorDisabled)}),Object(u.pick)({enterprise:u.variables.textGray,prisma:u.variables.contentColorDisabled}),0===n&&Object(u.pick)({enterprise:{light:Object(P.css)(["background-color:",";"],u.variables.gray96),dark:Object(P.css)(["background-color:",";"],u.variables.gray60)},prisma:Object(P.css)(["border:1px dashed ",";min-height:128px;"],u.variables.contentColorDisabled)}),0!==n&&Object(u.pick)({prisma:Object(P.css)(["","{padding:0;}"],J)}))})),ae=E()(T.a).withConfig({displayName:"FileStyles__StyledWindowDropTargetBox",componentId:"sc-1wyh4cf-10"})(["position:relative;text-align:center;min-height:250px;padding:",";",""],u.variables.spacingLarge,(function(e){return e.$disabled&&Object(P.css)(["color:",";"],Object(u.pick)({enterprise:u.variables.textGray,prisma:u.variables.contentColorMuted}))}));function ie(e){return ie="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ie(e)}function le(){return le=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},le.apply(this,arguments)}function ce(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function se(e,t){return se=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},se(e,t)}function ue(e,t){return!t||"object"!==ie(t)&&"function"!=typeof t?pe(e):t}function pe(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function fe(e){return fe=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},fe(e)}function de(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var be={accept:i.a.string,allowMultiple:i.a.bool,children:i.a.node,disabled:i.a.bool,dropAnywhere:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),fullscreen:i.a.bool,error:i.a.bool,help:i.a.node,name:i.a.string,onRequestAdd:i.a.func,onRequestRemove:i.a.func,onRequestRetry:i.a.func,supportsMessage:i.a.node,splunkTheme:i.a.object},he=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&se(e,t)}(u,e);var t,n,a,i,c=(a=u,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=fe(a);if(i){var n=fe(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return ue(this,e)});function u(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,u),de(pe(t=c.call(this,e)),"inputId",void 0),de(pe(t),"inputCount",void 0),de(pe(t),"handleInputChange",(function(e){var n;t.addFiles(null!==(n=e.currentTarget.files)&&void 0!==n?n:void 0)})),de(pe(t),"handleInputFocus",(function(){t.setState({focusedInput:!0})})),de(pe(t),"handleInputBlur",(function(){t.setState({focusedInput:!1})})),de(pe(t),"handleDragOver",(function(e){t.state.dragOver||t.setState({dragOver:!0}),e.preventDefault()})),de(pe(t),"handleDragLeave",(function(){t.setState({dragOver:!1})})),de(pe(t),"handleDrop",(function(e){var n;e.preventDefault(),t.handleDragLeave(),t.addFiles(null===(n=e.dataTransfer)||void 0===n?void 0:n.files)})),t.state={dragOver:!1,focusedInput:!1},t.inputId=Object(f.createDOMID)(),t.inputCount=0,t.handleDragLeave=Object(l.debounce)(t.handleDragLeave,300),t}return t=u,(n=[{key:"addFiles",value:function(e){var t=this.props.name;if(void 0!==e&&e.length>0){var n,r,o=Array.from(e);null===(n=(r=this.props).onRequestAdd)||void 0===n||n.call(r,this.props.allowMultiple?o:[o[0]],{name:t})}else{var a,i;null===(a=(i=this.props).onRequestAdd)||void 0===a||a.call(i,[],{name:t})}this.inputCount+=1}},{key:"render",value:function(){var e=this.props,t=e.accept,n=e.allowMultiple,a=e.children,i=e.disabled,c=e.dropAnywhere,u=e.error,f=e.fullscreen,d=e.help,b=e.name,h=e.onRequestRemove,v=e.onRequestRetry,y=e.splunkTheme,m=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["accept","allowMultiple","children","disabled","dropAnywhere","error","fullscreen","help","name","onRequestRemove","onRequestRetry","splunkTheme"]),g=y.isPrisma,O=0,x=r.Children.toArray(a).filter(r.isValidElement).map((function(e,t){return O+=1,Object(r.cloneElement)(e,{index:t,key:e.key||e.props.itemId||"item-".concat(t)})})),j=f||c,w=j||i,C=j&&!i,S=f?ae:oe,P=f?ee:J,E=f?Y:X,_=!w&&(this.state.dragOver||!1),T=Object(l.isString)(t)&&Object(l.toUpper)(t.split(",").join(", ")),D=null;return this.props.supportsMessage?D=o.a.createElement(te,null,this.props.supportsMessage):g&&!i&&(D=t?o.a.createElement(te,null,Object(p._)("Supports ".concat(T))):o.a.createElement(te,null,Object(p._)("Supports all file types"))),o.a.createElement(S,le({onDragOver:w?void 0:this.handleDragOver,onDragLeave:w?void 0:this.handleDragLeave,onDrop:w?void 0:this.handleDrop,$disabled:i,$dragOver:_,$error:u,$fileCount:O,"data-test":"file"},Object(l.omit)(m,"onRequestAdd","onRequestRemove")),o.a.createElement(P,{$disabled:i,$dragOver:_,$error:u},!i&&!g&&o.a.createElement(E,{$dragOver:_,$error:u})," ",o.a.createElement("span",null,!j&&!i&&Object(p._)("Drop your file here or"),C&&Object(p._)("Drop your file anywhere or")," ",0===O&&i&&Object(p._)("No Files Selected"),o.a.createElement(Q,{htmlFor:this.inputId,"data-focused":this.state.focusedInput||null},o.a.createElement(Z,{accept:t,"data-test":"file-input",disabled:i,id:this.inputId,key:"file-input-".concat(this.inputCount),multiple:n||void 0,onBlur:this.handleInputBlur,onChange:this.handleInputChange,onFocus:this.handleInputFocus,type:"file"}),!i&&Object(p._)("upload file…"))),D),!i&&d&&o.a.createElement(ne,{"data-test":"help"},d),C&&this.state.dragOver&&o.a.createElement(re,{"data-test":"file-window-drop",onDragLeave:this.handleDragLeave}),C&&o.a.createElement(o.a.Fragment,null,o.a.createElement(s.a,{target:window,eventType:"dragover",listener:this.handleDragOver}),o.a.createElement(s.a,{target:window,eventType:"drop",listener:this.handleDrop})),o.a.createElement(k.Provider,{value:{disabled:i,onRequestRemove:h?function(e){null==h||h({event:e,index:e.index,filename:e.name,itemId:e.itemId,name:b})}:void 0,onRequestRetry:v?function(e){null==v||v({event:e,filename:e.name,index:e.index,itemId:e.itemId,name:b})}:void 0}},x))}}])&&ce(t.prototype,n),u}(r.Component);de(he,"propTypes",be),de(he,"defaultProps",{allowMultiple:!1,disabled:!1,dropAnywhere:!1,error:!1}),de(he,"Item",W);var ve=Object(u.withSplunkTheme)(he);ve.propTypes=he.propTypes,ve.Item=W;var ye=ve},12:function(e,t){e.exports=n(5917)},15:function(e,t){e.exports=n(9213)},2:function(e,t){e.exports=n(7294)},22:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(23),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L10.5858 12L5.2929 17.2929C4.90238 17.6834 4.90238 18.3166 5.2929 18.7071C5.68342 19.0976 6.31659 19.0976 6.70711 18.7071L12 13.4142L17.2929 18.7071C17.6834 19.0976 18.3166 19.0976 18.7071 18.7071C19.0976 18.3166 19.0976 17.6834 18.7071 17.2929L13.4142 12L18.7071 6.70711C19.0976 6.31658 19.0976 5.68342 18.7071 5.29289C18.3166 4.90237 17.6834 4.90237 17.2929 5.29289L12 10.5858L6.70711 5.29289Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M12.2024 2.69009C12.5092 2.38325 13.0067 2.38325 13.3136 2.69009C13.6204 2.99693 13.6204 3.49442 13.3136 3.80126L9.11721 7.99762L13.3114 12.1918C13.6206 12.501 13.6206 13.0023 13.3114 13.3114C13.0023 13.6206 12.501 13.6206 12.1918 13.3114L7.99762 9.11721L3.885 13.2298C3.57816 13.5367 3.08067 13.5367 2.77383 13.2298C2.46699 12.923 2.46699 12.4255 2.77383 12.1187L6.88645 8.00604L2.69183 3.81142C2.38267 3.50226 2.38267 3.001 2.69183 2.69183C3.001 2.38267 3.50226 2.38267 3.81142 2.69183L8.00604 6.88646L12.2024 2.69009Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},23:function(e,t){e.exports=n(1476)},25:function(e,t){e.exports=n(6817)},3:function(e,t){e.exports=n(2788)},4:function(e,t){e.exports=n(5220)},45:function(e,t){e.exports=n(8154)},5:function(e,t){e.exports=n(6219)},59:function(e,t){e.exports=n(9482)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var r=n(2),o=n.n(r),a=n(3);function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n.n(a).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function c(e){return o.a.createElement(l,i({xmlns:"http://www.w3.org/2000/svg"},e))}},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(0);function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}var p={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},f={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:i.a.func,enterpriseSize:i.a.oneOfType([i.a.number,i.a.string]),enterpriseWidth:i.a.oneOfType([i.a.number,i.a.string]),enterpriseHeight:i.a.oneOfType([i.a.number,i.a.string]),Prisma24:i.a.func.isRequired,Prisma20:i.a.func,Prisma16:i.a.func,prismaSize:i.a.oneOf(["medium","small"]),inline:i.a.bool,screenReaderText:i.a.string};function b(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,a=e.Prisma16,i=e.prismaSize,d=e.inline,b=e.enterpriseSize,h=e.enterpriseWidth,v=e.enterpriseHeight,y=e.screenReaderText,m=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),g=Object(l.useSplunkTheme)(),O=g.family,x=g.density;if("enterprise"===O)return o.a.createElement(t,u({size:b,width:h,height:v,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},m));var j=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?p:f},m);if("small"===i){var w=a||n;return o.a.createElement(w,u({width:"16",height:"16"},j))}if("compact"===x){var C=r||n;return o.a.createElement(C,u({width:"20",height:"20"},j))}return o.a.createElement(n,u({width:"24",height:"24"},j))}b.propTypes=d,b.defaultProps={inline:!0,prismaSize:"medium"}},8:function(e,t){e.exports=n(6493)},90:function(e,t){e.exports=n(1040)}})},8580:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=163)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},163:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return v}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(3),c=n.n(l),s=n(0),u=Object(l.css)(["margin:0.707em 0 0.2em;"]),p=c.a.h1.withConfig({displayName:"HeadingStyles__StyledH1",componentId:"sc-15s3yx3-0"})(["",";margin:1.414em 0 0.4em;text-rendering:optimizelegibility;color:",";"," "," font-size:",";font-weight:",";"],s.mixins.reset("block"),Object(s.pickVariant)("$isSection",{true:Object(s.pick)({enterprise:{dark:s.variables.gray80,light:s.variables.gray45},prisma:s.variables.contentColorDefault}),false:{prisma:s.variables.contentColorActive}}),Object(s.pick)({prisma:Object(l.css)(["line-height:",";"],Object(s.pickVariant)("as",{h1:"48px",h2:"24px",h3:"24px",h4:"24px",h5:"16px"}))}),(function(e){return e.$isSection&&u}),Object(s.pickVariant)("as",{h1:{enterprise:s.variables.fontSizeXXLarge,prisma:"36px"},h2:{enterprise:s.variables.fontSizeXLarge,prisma:"24px"},h3:{enterprise:s.variables.fontSizeLarge,prisma:"20px"},h4:{enterprise:s.variables.fontSize,prisma:function(e){return e.$isSection?"14px":"16px"}},h5:function(e){return e.$isSection&&Object(s.pick)({enterprise:"12px",prisma:"13px"})}}),(function(e){var t=e.as,n=e.$isSection;return"h4"!==t||n?Object(s.pick)({enterprise:s.variables.fontWeightSemiBold,prisma:s.variables.fontWeightBold}):"bold"}));function f(){return f=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},f.apply(this,arguments)}var d={children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),level:i.a.oneOf([1,2,3,4,"s","ss"])},b={1:"h1",2:"h2",3:"h3",4:"h4",s:"h4",ss:"h5"};function h(e){var t,n=e.level,r=void 0===n?2:n,a=e.children,i=e.elementRef,l=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["level","children","elementRef"]);return o.a.createElement(p,f({as:b[r],$isSection:(t=r,"s"===t.toString().charAt(0)),"data-test":"heading",ref:i},l),a)}h.propTypes=d;var v=h},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)}})},2725:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=117)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},10:function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},117:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return Te})),n.d(t,"Item",(function(){return Oe})),n.d(t,"Heading",(function(){return L})),n.d(t,"Divider",(function(){return x})),n.d(t,"MenuContext",(function(){return m}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(47),c=n.n(l),s=n(18),u=n(28),p=n(9),f=n(98),d=n.n(f),b=n(3),h=n.n(b),v=n(0),y=h.a.div.withConfig({displayName:"DividerStyles__Styled",componentId:"l3zfh3-0"})(["border-top:1px solid ",";",""],Object(v.pick)({enterprise:v.variables.borderColor,prisma:v.variables.neutral200}),Object(v.pick)({prisma:{comfortable:Object(b.css)(["margin:8px 0;"]),compact:Object(b.css)(["margin:6px 0;"])}})),m=Object(r.createContext)({role:"menu"});function g(){return g=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},g.apply(this,arguments)}function O(e){var t=g({},e),n=Object(r.useContext)(m).role;return o.a.createElement(y,g({"aria-hidden":"listbox"===n,"data-test":"divider",role:"separator"},t))}O.propTypes={},O.filterFirst=!0,O.filterConsecutive=!0,O.filterLast=!0;var x=O,j=n(58),w=n.n(j),C=n(42),S=n.n(C),k=h.a.div.withConfig({displayName:"HeadingStyles__Styled",componentId:"mcd2ws-0"})([""," border-top:1px solid transparent;padding:",";&:not(:first-child){",";}"],v.mixins.reset("block"),Object(v.pick)({enterprise:Object(b.css)([""," "," 6px"],v.variables.spacingQuarter,v.variables.spacingHalf),prisma:{comfortable:"13px 16px 10px 16px",compact:"9px 16px 6px 16px"}}),Object(v.pick)({enterprise:Object(b.css)(["border-top:",";"],v.variables.border),prisma:{comfortable:Object(b.css)(["border-top:1px solid ",";margin-top:6px;padding-top:19px;"],v.variables.neutral200),compact:Object(b.css)(["border-top:1px solid ",";margin-top:6px;padding-top:15px;"],v.variables.neutral200)}})),P=h.a.h5.withConfig({displayName:"HeadingStyles__PrismaSectionTitle",componentId:"mcd2ws-1"})([""," font-size:",";line-height:",";font-weight:",";letter-spacing:0.02em;"],v.mixins.reset("block"),v.variables.fontSizeSmall,v.variables.lineHeight,v.variables.fontWeightBold);function E(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function _(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?E(Object(n),!0).forEach((function(t){T(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):E(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function T(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(){return D=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},D.apply(this,arguments)}var I={children:i.a.node,title:i.a.bool,outerStyle:i.a.object};function R(e){var t=e.children,n=e.title,a=e.outerStyle,i=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","title","outerStyle"]),l=Object(r.useContext)(m).role,c="prisma"===S()().family?o.a.createElement(k,{style:a},o.a.createElement(P,D({as:n?"h4":"h5","data-test":"heading"},i),t)):o.a.createElement(w.a,D({style:_(_({},a),{},{margin:0}),level:n?4:"ss","data-test":"heading"},i),t);return o.a.createElement(k,{"aria-hidden":"listbox"===l},c)}R.propTypes=I,R.filterConsecutive=!0,R.filterLast=!0;var L=R,A=n(4),M=n(56),B=n(99),N=n.n(B),z=n(7),F=n(6);function $(){return $=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},$.apply(this,arguments)}function H(e){var t=$({},e);return o.a.createElement(F.a,$({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M8.77004 16.4985C8.77004 16.9313 9.28241 17.1597 9.60425 16.8704L14.6126 12.3696C14.8337 12.1709 14.8336 11.8243 14.6125 11.6257L9.60412 7.12744C9.28225 6.83834 8.77002 7.06678 8.77002 7.49943L8.77004 16.4985Z",fill:"currentColor"}))}function V(e){return o.a.createElement(z.a,$({Enterprise:N.a,Prisma24:H},e))}var q=n(29),W=n(12),K=n.n(W),U=n(72),Z=n.n(U),G=Object(b.css)(["color:",";font-size:",";line-height:",";overflow:inherit;white-space:inherit;text-overflow:inherit;"],Object(v.pick)({prisma:v.variables.contentColorDefault,enterprise:v.variables.textGray}),v.variables.fontSizeSmall,Object(v.pick)({prisma:"16px"})),X=h.a.span.withConfig({displayName:"ItemStyles__StyledItemDescriptionBottom",componentId:"sc-4kc053-0"})(["",";display:block;"],G),Y=h.a.span.withConfig({displayName:"ItemStyles__StyledItemDescriptionRight",componentId:"sc-4kc053-1"})(["",";float:right;padding-left:",";max-width:50%;text-align:right;box-sizing:border-box;"],G,v.variables.spacing),Q=h.a.div.withConfig({displayName:"ItemStyles__StyledItemSelectedIcon",componentId:"sc-4kc053-2"})(["position:absolute;"," color:",";"],Object(v.pick)({prisma:Object(b.css)(["right:16px;"]),enterprise:Object(b.css)(["top:5px;right:3px;left:8px;"])}),Object(v.pick)({prisma:v.variables.contentColorActive,enterprise:v.variables.accentColorL10})),J=h.a.span.withConfig({displayName:"ItemStyles__StyledItemIcon",componentId:"sc-4kc053-3"})(["flex:0 0 auto;padding-right:",";min-width:10px;display:inline-block;text-align:center;vertical-align:",";",""],Object(v.pick)({prisma:"8px",enterprise:"3px"}),Object(v.pick)({prisma:"initial",enterprise:"middle"}),Object(v.pick)({prisma:Object(b.css)(["color:",";display:inline-flex;align-items:center;min-width:20px;min-height:20px;"],v.variables.contentColorMuted),enterprise:Object(b.css)(["transform:translateY(-1px);"])})),ee=h()(K.a).withConfig({displayName:"ItemStyles__StyledClickable",componentId:"sc-4kc053-4"})(["display:block;position:relative;cursor:pointer;color:",";word-wrap:break-word;max-width:100%;width:100%;padding:",";"," "," "," &:not([disabled]){&:hover{background:",";","}&:focus{outline:0;box-shadow:",";","}"," ","}&[disabled]{color:",";cursor:not-allowed;",",","{color:inherit;}","{cursor:not-allowed;color:",";}","}",""],Object(v.pick)({prisma:v.variables.contentColorActive,enterprise:{dark:v.variables.gray96,light:v.variables.gray22}}),Object(v.pick)({prisma:{comfortable:"10px 16px",compact:"6px 16px"},enterprise:"6px 10px"}),(function(e){var t=e.$isSelectable,n=e.$selectableAppearance;return t&&Object(v.pick)({prisma:Object(b.css)(["padding-right:44px;",""],(function(){return"checkbox"===n&&"padding-left: 42px;"})),enterprise:Object(b.css)(["padding-right:10px;padding-left:",";"],(function(){return"checkbox"===n?"32px":"28px"}))})}),(function(e){var t=e.$active,n=e.$preventFocus;return t&&!n&&Object(b.css)(["box-shadow:",";"],v.variables.focusShadowInset)}),(function(e){return e.$active&&Object(b.css)(["background:",";font-weight:",";"],Object(v.pick)({enterprise:{light:v.variables.gray92,dark:v.variables.gray22},prisma:v.variables.neutral100}),v.variables.fontWeightBold)}),Object(v.pick)({prisma:v.variables.interactiveColorOverlayHover,enterprise:v.variables.backgroundColorHover}),(function(e){return e.$selected&&Object(v.pick)({prisma:Object(b.css)(["background:",";"],v.mixins.overlayColors(v.variables.interactiveColorOverlaySelected,v.variables.interactiveColorOverlayHover))})}),v.variables.focusShadowInset,Object(v.pick)({prisma:Object(b.css)(["background:",";"],v.variables.interactiveColorOverlayHover)}),Object(v.pick)({prisma:Object(b.css)(["&:active{background:",";}"],v.variables.interactiveColorOverlayActive)}),(function(e){return e.$selected&&Object(v.pick)({prisma:Object(b.css)(["background:",";&:active{background:",";}"],v.variables.interactiveColorOverlaySelected,v.mixins.overlayColors(v.variables.interactiveColorOverlaySelected,v.variables.interactiveColorOverlayActive))})}),Object(v.pick)({enterprise:{light:v.variables.gray45,dark:v.variables.contentColorDisabled},prisma:v.variables.contentColorDisabled}),X,Y,Q,Object(v.pick)({prisma:v.variables.contentColorDisabled,enterprise:v.variables.gray80}),Object(v.pick)({prisma:Object(b.css)(["& > * > ","{color:",";}"],J,v.variables.contentColorDisabled)}),(function(e){return e.$selected&&Object(v.pick)({prisma:Object(b.css)(["","{color:",";}"],J,v.variables.contentColorActive)})})),te=h()(Z.a).withConfig({displayName:"ItemStyles__StyledSwitch",componentId:"sc-4kc053-5"})(["position:absolute;left:",";top:",";"],Object(v.pick)({prisma:"16px",enterprise:"8px"}),Object(v.pick)({prisma:"0px",enterprise:{comfortable:"-1px",compact:"2px"}})),ne=h.a.span.withConfig({displayName:"ItemStyles__StyledInnerWrapper",componentId:"sc-4kc053-6"})(["display:flex;align-items:flex-start;"]),re=h.a.span.withConfig({displayName:"ItemStyles__StyledTitleAndDescriptionWrapper",componentId:"sc-4kc053-7"})(["max-width:100%;width:100%;align-self:center;word-break:break-word;white-space:normal;",""],(function(e){return e.$truncate&&Object(b.css)(["white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"])})),oe=h.a.div.withConfig({displayName:"ItemStyles__StyledLabel",componentId:"sc-4kc053-8"})(["overflow:inherit;white-space:inherit;text-overflow:inherit;max-width:100%;min-height:20px;",""],(function(e){return e.$truncate&&Object(b.css)(["display:block;clear:both;"])})),ae=h.a.span.withConfig({displayName:"ItemStyles__StyledMatch",componentId:"sc-4kc053-9"})(["border-bottom:1px solid ",";"],Object(v.pick)({prisma:v.variables.contentColorActive,enterprise:{dark:v.variables.gray96,light:v.variables.gray45}})),ie=h.a.span.withConfig({displayName:"ItemStyles__StyledSubmenu",componentId:"sc-4kc053-10"})(["float:right;padding-left:",";color:",";"],v.variables.spacingSmall,Object(v.pick)({prisma:"inherit",enterprise:v.variables.textGray})),le=n(10);function ce(e){return ce="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ce(e)}function se(){return se=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},se.apply(this,arguments)}function ue(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function pe(e,t,n){return t&&ue(e.prototype,t),n&&ue(e,n),e}function fe(e,t){return fe=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},fe(e,t)}function de(e,t){return!t||"object"!==ce(t)&&"function"!=typeof t?be(e):t}function be(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function he(e){return he=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},he(e)}function ve(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var ye={active:i.a.bool,children:i.a.node,description:i.a.string,descriptionPosition:i.a.oneOf(["right","bottom"]),disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),hasSubmenu:i.a.bool,icon:i.a.node,itemKey:i.a.number,matchRanges:i.a.arrayOf(i.a.shape({start:i.a.number.isRequired,end:i.a.number.isRequired})),onClick:i.a.func,onFocus:i.a.func,openInNewContext:i.a.bool,preventFocus:i.a.bool,role:i.a.oneOf(["menuitem","menuitemradio","menuitemcheckbox","listboxitem","option"]),selectable:i.a.bool,selectableAppearance:i.a.oneOf(["checkmark","checkbox"]),selected:i.a.bool,splunkTheme:i.a.object,to:i.a.string,truncate:i.a.bool},me=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&fe(e,t)}(a,e);var t,n,r=(t=a,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=he(t);if(n){var o=he(this).constructor;e=Reflect.construct(r,arguments,o)}else e=r.apply(this,arguments);return de(this,e)});function a(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,a),ve(be(t=r.call(this,e)),"el",null),ve(be(t),"handleFocus",(function(e){var n=t.props,r=n.onFocus,o=n.itemKey;null==r||r(e,{itemKey:o})})),ve(be(t),"handleMount",(function(e){t.el=e,Object(le.a)(t.props.elementRef,e)})),a.validateProps(e),t}return pe(a,null,[{key:"validateProps",value:function(e){}}]),pe(a,[{key:"componentDidUpdate",value:function(){a.validateProps(this.props)}},{key:"focus",value:function(){var e;null===(e=this.el)||void 0===e||e.focus()}},{key:"scrollIntoViewIfNeeded",value:function(){var e=this.el;if(e){var t=e.offsetParent;t&&(t.scrollTop+t.clientHeight<e.offsetTop+e.clientHeight?t.scrollTop=e.offsetTop+e.clientHeight-t.clientHeight:t.scrollTop>e.offsetTop&&(t.scrollTop=e.offsetTop))}}},{key:"renderLabel",value:function(){var e=this.props,t=e.children,n=e.matchRanges;if(!n||!Object(A.isString)(t))return t;var r=[];return r.push(t.substring(0,n[0].start)),n.forEach((function(e,a){r.push(o.a.createElement(ae,{key:a,"data-test":"match"},t.substring(e.start,e.end))),a<n.length-1?r.push(t.substring(e.end,n[a+1].start)):r.push(t.substring(e.end,t.length))})),r}},{key:"render",value:function(){var e=this.props,t=e.active,n=e.children,r=e.hasSubmenu,a=e.selectable,i=e.selectableAppearance,l=e.selected,c=e.icon,s=e.description,u=e.disabled,p=e.onClick,f=e.preventFocus,d=e.role,b=e.splunkTheme,h=e.to,v=e.truncate,y=e.descriptionPosition,m=e.openInNewContext,g=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["active","children","hasSubmenu","selectable","selectableAppearance","selected","icon","description","disabled","onClick","preventFocus","role","splunkTheme","to","truncate","descriptionPosition","openInNewContext"]),O=b.isPrisma,x=a||l,j={nonselectable:"menuitem",checkmark:"menuitemradio",checkbox:"menuitemcheckbox"}[x?i:"nonselectable"],w={"aria-haspopup":!!r||void 0,"aria-checked":!("checkmark"!==i||!l)||void 0},C=O?"right":"left",S=s&&"right"===y&&"right"!==C,k=s&&!S,P=l&&"checkmark"===i&&o.a.createElement(Q,null,o.a.createElement(M.a,{enterpriseSize:.85,prismaSize:"small",inline:!0,style:O?c?{verticalAlign:"sub"}:{verticalAlign:"text-top"}:void 0}));return o.a.createElement(ee,se({$isSelectable:x,$selectableAppearance:i,$selected:l,$active:t,$preventFocus:f,"data-test-selected":x?l:null,"data-test":"item","data-has-icon":!!c,disabled:u,onClick:p,onFocus:this.handleFocus,onMouseDown:function(e){f&&e.preventDefault()},role:d||j,to:h,title:v&&Object(A.isString)(n)?n:void 0,openInNewContext:m},w,Object(A.omit)(g,"onFocus"),{elementRef:this.handleMount}),"left"===C&&P,a&&"checkbox"===i&&o.a.createElement(te,{interactive:!1,selected:l,selectedLabel:"Selected",value:"menu-item"}),r&&o.a.createElement(ie,null,O?o.a.createElement(V,null):o.a.createElement(q.a,null)),S&&o.a.createElement(Y,{"data-test":"description"},s),o.a.createElement(ne,null,c&&o.a.createElement(J,null,c),o.a.createElement(re,{$truncate:v},o.a.createElement(oe,{$truncate:v,"data-test":"label"},this.renderLabel()),k&&o.a.createElement(X,{"data-test":"description"},s)),"right"===C&&P))}}]),a}(r.Component);ve(me,"propTypes",ye),ve(me,"defaultProps",{active:!1,descriptionPosition:"bottom",disabled:!1,hasSubmenu:!1,openInNewContext:!1,preventFocus:!1,selectable:!1,selectableAppearance:"checkmark",selected:!1,truncate:!1});var ge=Object(v.withSplunkTheme)(me);ge.propTypes=me.propTypes;var Oe=ge,xe=n(68),je=n.n(xe),we=Object(b.css)(["border-top:1px solid ",";"],Object(v.pick)({enterprise:v.variables.gray60,prisma:v.variables.neutral200})),Ce=h.a.div.withConfig({displayName:"MenuStyles__Styled",componentId:"sc-1olffp9-0"})(["",";background-color:",";border-radius:",";min-width:60px;overflow:auto;position:relative;"," &:focus{outline:0;box-shadow:",";","}& + &{","}"],v.mixins.reset("block"),Object(v.pick)({enterprise:v.variables.backgroundColor,prisma:v.variables.backgroundColorPopup}),v.variables.borderRadius,Object(v.pick)({prisma:Object(b.css)(["padding:8px 0;"])}),v.variables.focusShadowInset,Object(v.pick)({prisma:Object(b.css)(["background:",";"],v.variables.interactiveColorOverlayHover)}),we),Se=h()(Ce.withComponent(je.a)).withConfig({displayName:"MenuStyles__StyledScroll",componentId:"sc-1olffp9-1"})([""," + &,& + ","{","}"],Ce,Ce,we),ke=n(44);function Pe(){return Pe=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Pe.apply(this,arguments)}var Ee={children:i.a.node,controlledExternally:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),retainFocus:i.a.bool,stopScrollPropagation:i.a.bool};function _e(e){var t=e.children,n=e.controlledExternally,a=e.elementRef,i=e.retainFocus,l=e.stopScrollPropagation,f=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","controlledExternally","elementRef","retainFocus","stopScrollPropagation"]),b=Object(r.useContext)(m).role,h=void 0===b?"menu":b,v=Object(r.useContext)(s.PopoverContext).retainFocus,y=d()(),g=!0;null!=i?g=i:null!=v&&(g=v);var O,j=o.a.useRef(0),w=[],C=0,S=!1,k=!1,P=!1,E=r.Children.toArray(t).filter(r.isValidElement).reduce((function(e,t,r,a){if(t.type===x&&t.type.filterFirst&&0===e.length)return e;if((t.type===x||t.type===L)&&t.type.filterConsecutive&&!t.props.title&&a.length>r+1){var i=a[r+1];if((i.type===x||i.type===L)&&i.type.filterConsecutive)return e}if((t.type===x||t.type===L)&&t.type.filterLast&&r===a.length-1)return e;if(t.type!==x&&t.type!==L&&"string"!=typeof t.type){var l=o.a.createRef();w.push(l),null!=O||"disabled"in t.props&&t.props.disabled||(O=C),j.current===C&&"disabled"in t.props&&t.props.disabled&&(S=!0),"selected"in t.props&&t.props.selected&&(k=!0,"disabled"in t.props&&!t.props.disabled&&(P=!0));var c=n||j.current!==C?-1:void 0;return e.push(o.a.cloneElement(t,{itemKey:C,onFocus:function(e,t){var n=t.itemKey;null!=n&&(j.current=n)},preventFocus:n,ref:function(e){Object(le.a)(t.ref,e),Object(le.a)(l,e)},tabIndex:c})),C+=1,e}return e.push(t),e}),[]);O===j.current||k&&!P||!S||null==O||(j.current=O,y());var _={"data-test":"menu",onKeyDown:function(e){var t,n,r,o=Object(p.keycode)(e.nativeEvent),a=j.current;"down"===o||g&&Object(u.isTabKey)(e)?t=Object(ke.a)(w,a,a+1):"up"===o||g&&Object(u.isTabKey)(e)&&e.shiftKey?t=Object(ke.b)(w,a,a-1):"home"===o?t=Object(ke.a)(w,a,0):"end"===o&&(t=Object(ke.b)(w,a,w.length-1)),null!=t&&(null===(n=t.current)||void 0===n||null===(r=n.focus)||void 0===r||r.call(n),e.preventDefault())},role:h,tabIndex:null!=O||n?void 0:0};return l?o.a.createElement(Se,Pe({},_,{elementRef:a,stopScrollPropagation:!0},c()(f,"tagName")),E):o.a.createElement(Ce,Pe({},_,{ref:a},f),E)}_e.propTypes=Ee,_e.defaultProps={stopScrollPropagation:!1},_e.Item=Oe,_e.Divider=x,_e.Heading=L;var Te=_e},12:function(e,t){e.exports=n(5917)},18:function(e,t){e.exports=n(9016)},2:function(e,t){e.exports=n(7294)},28:function(e,t){e.exports=n(8568)},29:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(35),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M14.7861 11.9999L8.48587 5.69972C8.09534 5.3092 8.09534 4.67603 8.48587 4.28551C8.87639 3.89499 9.50956 3.89499 9.90008 4.28551L16.5538 10.9393C17.1396 11.525 17.1396 12.4748 16.5538 13.0606L9.90142 19.713C9.5109 20.1035 8.87773 20.1035 8.48721 19.713C8.09669 19.3224 8.09669 18.6893 8.48721 18.2988L14.7861 11.9999Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M11.7109 7.9976L5.71017 13.9983L4.29597 12.5841L8.88914 7.99095L4.34482 3.40363L5.76567 1.99609L11.7109 7.9976Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},3:function(e,t){e.exports=n(2788)},35:function(e,t){e.exports=n(4345)},4:function(e,t){e.exports=n(5220)},42:function(e,t){e.exports=n(1093)},44:function(e,t,n){"use strict";function r(e,t,n){for(var r=0;r<e.length;r+=1){var o,a=(r+n)%e.length;if(!0!==(null===(o=e[a].current)||void 0===o?void 0:o.props.disabled))return e[a]}return e[t]}function o(e,t,n){for(var r=e.length;r>0;r-=1){var o,a=(r+n)%e.length;if(!0!==(null===(o=e[a].current)||void 0===o?void 0:o.props.disabled))return e[a]}return e[t]}n.d(t,"a",(function(){return r})),n.d(t,"b",(function(){return o}))},47:function(e,t){e.exports=n(3461)},50:function(e,t){e.exports=n(746)},56:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(50),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M20.7071 5.59294C21.0977 5.98347 21.0977 6.61663 20.7071 7.00716L10.1447 17.5695C9.55896 18.1553 8.60922 18.1553 8.02343 17.5695L3.29289 12.839C2.90237 12.4485 2.90237 11.8153 3.29289 11.4248C3.68342 11.0343 4.31658 11.0343 4.70711 11.4248L9.08409 15.8018L19.2929 5.59294C19.6835 5.20242 20.3166 5.20242 20.7071 5.59294Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M13.999 4.75712L6.17736 12.5786L1.99561 8.39691L3.40981 6.98269L6.17737 9.75021L12.5848 3.3429L13.999 4.75712Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},58:function(e,t){e.exports=n(8580)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var r=n(2),o=n.n(r),a=n(3);function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n.n(a).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function c(e){return o.a.createElement(l,i({xmlns:"http://www.w3.org/2000/svg"},e))}},68:function(e,t){e.exports=n(1052)},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(0);function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}var p={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},f={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:i.a.func,enterpriseSize:i.a.oneOfType([i.a.number,i.a.string]),enterpriseWidth:i.a.oneOfType([i.a.number,i.a.string]),enterpriseHeight:i.a.oneOfType([i.a.number,i.a.string]),Prisma24:i.a.func.isRequired,Prisma20:i.a.func,Prisma16:i.a.func,prismaSize:i.a.oneOf(["medium","small"]),inline:i.a.bool,screenReaderText:i.a.string};function b(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,a=e.Prisma16,i=e.prismaSize,d=e.inline,b=e.enterpriseSize,h=e.enterpriseWidth,v=e.enterpriseHeight,y=e.screenReaderText,m=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),g=Object(l.useSplunkTheme)(),O=g.family,x=g.density;if("enterprise"===O)return o.a.createElement(t,u({size:b,width:h,height:v,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},m));var j=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?p:f},m);if("small"===i){var w=a||n;return o.a.createElement(w,u({width:"16",height:"16"},j))}if("compact"===x){var C=r||n;return o.a.createElement(C,u({width:"20",height:"20"},j))}return o.a.createElement(n,u({width:"24",height:"24"},j))}b.propTypes=d,b.defaultProps={inline:!0,prismaSize:"medium"}},72:function(e,t){e.exports=n(7885)},9:function(e,t){e.exports=n(2916)},98:function(e,t){e.exports=n(5473)},99:function(e,t){e.exports=n(9135)}})},4355:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=129)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},10:function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},101:function(e,t){e.exports=n(1008)},11:function(e,t){e.exports=n(9726)},129:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return _e})),n.d(t,"Divider",(function(){return s.Divider})),n.d(t,"Heading",(function(){return s.Heading})),n.d(t,"Option",(function(){return j}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(5),s=n(13),u=n(30);function p(e){return p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},p(e)}function f(){return f=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},f.apply(this,arguments)}function d(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function b(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function h(e,t){return h=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},h(e,t)}function v(e,t){return!t||"object"!==p(t)&&"function"!=typeof t?y(e):t}function y(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function m(e){return m=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},m(e)}function g(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var O={active:i.a.bool,children:i.a.node,compact:i.a.bool,description:i.a.string,descriptionPosition:i.a.oneOf(["right","bottom"]),disabled:i.a.bool,hidden:i.a.bool,icon:i.a.node,label:i.a.string.isRequired,matchRanges:i.a.arrayOf(i.a.shape({start:i.a.number.isRequired,end:i.a.number.isRequired})),onClick:i.a.func,selected:i.a.bool,selectedAppearance:i.a.oneOf(["info","success","warning","error"]),selectedBackgroundColor:i.a.string,selectedForegroundColor:i.a.string,truncate:i.a.bool,value:i.a.oneOfType([i.a.string,i.a.number,i.a.bool]).isRequired},x=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&h(e,t)}(l,e);var t,n,r,a,i=(r=l,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=m(r);if(a){var n=m(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return v(this,e)});function l(){var e;d(this,l);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return g(y(e=i.call.apply(i,[this].concat(n))),"c",null),g(y(e),"handleMount",(function(t){e.c=t})),e}return t=l,(n=[{key:"scrollIntoViewIfNeeded",value:function(){var e;null===(e=this.c)||void 0===e||e.scrollIntoViewIfNeeded()}},{key:"focus",value:function(){var e;null===(e=this.c)||void 0===e||e.focus()}},{key:"render",value:function(){var e=this.props,t=e.compact,n=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["compact"]);return o.a.createElement(u.a,f({},n,{multiple:t,ref:this.handleMount}),this.props.children||this.props.label)}}])&&b(t.prototype,n),l}(r.PureComponent);g(x,"propTypes",O),g(x,"defaultProps",{compact:!1,descriptionPosition:"bottom",disabled:!1,selected:!1,truncate:!1});var j=x,w=n(46);function C(e){return C="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},C(e)}function S(){return S=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},S.apply(this,arguments)}function k(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function P(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function E(e,t){return E=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},E(e,t)}function _(e,t){return!t||"object"!==C(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function T(e){return T=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},T(e)}function D(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var I={allowNewValues:i.a.bool,animateLoading:i.a.bool,children:i.a.node,controlledFilter:i.a.bool,defaultPlacement:i.a.oneOf(["above","below","vertical"]),defaultValues:i.a.array,describedBy:i.a.string,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),error:i.a.bool,footerMessage:i.a.node,inline:i.a.bool,inputId:i.a.string,inputRef:i.a.oneOfType([i.a.func,i.a.object]),isLoadingOptions:i.a.bool,labelledBy:i.a.string,loadingMessage:i.a.node,menuStyle:i.a.object,name:i.a.string,noOptionsMessage:i.a.node,onChange:i.a.func,onClose:i.a.func,onFilterChange:i.a.func,onOpen:i.a.func,onScroll:i.a.func,onScrollBottom:i.a.func,placeholder:i.a.string,repositionMode:i.a.oneOf(["none","flip"]),showSelectedValuesFirst:i.a.oneOf(["nextOpen","immediately","never"]),tabConfirmsNewValue:i.a.bool,values:i.a.array},R={allowNewValues:!1,animateLoading:!1,defaultPlacement:"vertical",disabled:!1,inline:!1,isLoadingOptions:!1,menuStyle:{},noOptionsMessage:Object(c._)("No matches"),placeholder:Object(c._)("Select..."),showSelectedValuesFirst:"nextOpen",tabConfirmsNewValue:!1},L=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&E(e,t)}(c,e);var t,n,a,i,l=(a=c,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=T(a);if(i){var n=T(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return _(this,e)});function c(){return k(this,c),l.apply(this,arguments)}return t=c,(n=[{key:"render",value:function(){var e=this.props,t=e.defaultValues,n=e.children,a=e.controlledFilter,i=e.values,l=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["defaultValues","children","controlledFilter","values"]),c={children:r.Children.toArray(n).map((function(e){return Object(w.d)(e)?o.a.createElement(u.a,S({},e.props,{multiple:!0})):e})),filter:!a||"controlled"};return null!=t&&(c.defaultValues=t),null!=i&&(c.values=i),o.a.createElement(w.c,S({},l,c,{multiple:!0}))}}])&&P(t.prototype,n),c}(r.Component);D(L,"propTypes",I),D(L,"defaultProps",R),D(L,"Option",j),D(L,"Divider",s.Divider),D(L,"Heading",s.Heading);var A=L,M=n(26),B=n(11),N=n(9),z=n(101),F=n.n(z),$=n(36),H=n.n($),V=n(18),q=n.n(V),W=n(14),K=n.n(W),U=n(3),Z=n.n(U),G=n(8),X=n.n(G),Y=n(0),Q=Z()(X.a).withConfig({displayName:"NormalStyles__StyledBox",componentId:"sc-1uwwpco-0"})(["border-radius:",";align-items:flex-start;flex-wrap:wrap;min-height:",";max-height:300px;overflow-y:auto;border:1px solid ",";padding:",";"," "," "," "," "," &[data-inline]{width:400px;}[data-inline='true'] + &{margin-left:","}"],Y.variables.borderRadius,Y.variables.inputHeight,Object(Y.pick)({enterprise:{light:Y.variables.gray60,dark:Y.variables.borderColor},prisma:Y.variables.interactiveColorBorder}),Object(Y.pick)({enterprise:"2px 0 0 2px",prisma:"2px"}),Object(Y.pick)({enterprise:{light:Object(U.css)(["background-color:",";"],Y.variables.white),dark:Object(U.css)(["background-color:",";"],Y.variables.gray22)}}),(function(e){return e.$hasfocus&&Object(Y.pick)({enterprise:Object(U.css)(["box-shadow:",";"],Y.variables.focusShadow),prisma:Object(U.css)(["border-color:",";"],Y.variables.focusColor)})}),(function(e){return e.$error&&Object(U.css)(["border-color:",";color:",";"],Y.variables.accentColorNegative,Y.variables.accentColorNegative)}),(function(e){var t=e.$disabled,n=e.$hasfocus;return t?Object(Y.pick)({enterprise:{light:Object(U.css)(["background-color:",";cursor:not-allowed;"],Y.variables.gray96),dark:Object(U.css)(["background-color:",";border-color:",";cursor:not-allowed;"],Y.variables.gray22,Y.variables.gray30)},prisma:Object(U.css)(["border-color:",";cursor:not-allowed;"],Y.variables.interactiveColorBorderDisabled)}):!n&&Object(U.css)(["&:hover{border-color:",";}"],Object(Y.pick)({enterprise:Y.variables.borderColor,prisma:Y.variables.interactiveColorBorderHover}))}),(function(e){return e.$popoverOpen&&Object(U.css)(["position:relative;z-index:calc("," - 2);"],Y.variables.zindexFixedNavbar)}),Object(Y.pick)({enterprise:Y.variables.spacingHalf,prisma:Y.variables.spacingSmall})),J=Z.a.div.withConfig({displayName:"NormalStyles__StyledInputWrapper",componentId:"sc-1uwwpco-1"})(["flex:1 0 auto;max-width:100%;"]),ee=Z.a.input.withConfig({displayName:"NormalStyles__StyledInput",componentId:"sc-1uwwpco-2"})(["",";min-width:100%;max-width:100%;line-height:12px;",""],Y.mixins.reset("block"),Object(Y.pick)({enterprise:{comfortable:Object(U.css)(["padding:",";"],Y.variables.spacingQuarter),compact:Object(U.css)(["padding:3px;"])},prisma:{comfortable:Object(U.css)(["padding:7px 10px;"]),compact:Object(U.css)(["padding:3px;"])}})),te=Z.a.div.withConfig({displayName:"NormalStyles__StyledOverlay",componentId:"sc-1uwwpco-3"})(["",""],(function(e){return e.$popoveropen&&Object(U.css)(["position:fixed;top:0;left:0;width:100%;height:100%;z-index:calc("," - 2);"],Y.variables.zindexFixedNavbar)})),ne=n(10);function re(e){return re="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},re(e)}function oe(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function ae(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function ie(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?ae(Object(n),!0).forEach((function(t){de(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ae(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function le(){return le=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},le.apply(this,arguments)}function ce(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function se(e,t){return se=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},se(e,t)}function ue(e,t){return!t||"object"!==re(t)&&"function"!=typeof t?pe(e):t}function pe(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function fe(e){return fe=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},fe(e)}function de(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var be={allowNewValues:i.a.bool,animateLoading:i.a.bool,children:i.a.node,controlledFilter:i.a.bool,defaultPlacement:i.a.oneOf(["above","below","vertical"]),defaultValues:i.a.array,describedBy:i.a.string,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),error:i.a.bool,footerMessage:i.a.node,inline:i.a.bool,inputId:i.a.string,inputRef:i.a.oneOfType([i.a.func,i.a.object]),isLoadingOptions:i.a.bool,labelledBy:i.a.string,loadingMessage:i.a.node,menuStyle:i.a.object,name:i.a.string,noOptionsMessage:i.a.node,onChange:i.a.func,onClose:i.a.func,onFilterChange:i.a.func,onOpen:i.a.func,onScroll:i.a.func,onScrollBottom:i.a.func,placeholder:i.a.string,repositionMode:i.a.oneOf(["none","flip"]),tabConfirmsNewValue:i.a.bool,useClickawayOverlay:i.a.bool,values:i.a.array},he={allowNewValues:!1,animateLoading:!1,defaultPlacement:"vertical",disabled:!1,inline:!1,isLoadingOptions:!1,menuStyle:{},noOptionsMessage:Object(c._)("No matches"),placeholder:Object(c._)("Select..."),tabConfirmsNewValue:!1,useClickawayOverlay:!1},ve=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&se(e,t)}(s,e);var t,n,a,i,c=(a=s,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=fe(a);if(i){var n=fe(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return ue(this,e)});function s(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,s),de(pe(t=c.call(this,e)),"activeItemId",void 0),de(pe(t),"activeValue",void 0),de(pe(t),"availableOptionCount",void 0),de(pe(t),"children",void 0),de(pe(t),"controlledExternally",void 0),de(pe(t),"input",null),de(pe(t),"popoverId",void 0),de(pe(t),"previousActiveIndex",null),de(pe(t),"handleClick",(function(){var e;null===(e=t.input)||void 0===e||e.focus()})),de(pe(t),"handleRequestRemove",(function(e,n){var r=n.value;Object(l.defer)((function(){return t.removeValue(e,r)}))})),de(pe(t),"handleInputFocus",(function(e){var n,r;""!==t.state.filterKeyword&&(null===(n=(r=t.props).onFilterChange)||void 0===n||n.call(r,e,{keyword:""})),t.setState({filterKeyword:"",hasFocus:!0,open:!0},(function(){var e,n;null===(e=(n=t.props).onOpen)||void 0===e||e.call(n)}))})),de(pe(t),"handleInputKeyDown",(function(e){var n,o,a,i=t.props,c=i.children,s=i.onScrollBottom,u=i.tabConfirmsNewValue,p=Object(N.keycode)(e.nativeEvent);if("tab"===p&&t.state.open&&(u&&!Object(l.isUndefined)(t.activeValue)&&t.availableOptionCount<=1?(e.preventDefault(),t.addValue(e,t.activeValue),null===(a=t.input)||void 0===a||a.focus()):t.setState({open:!1})),!(e.shiftKey||e.metaKey||e.ctrlKey)){if("end"===p&&t.state.open&&(e.preventDefault(),t.setState({activeIndex:t.availableOptionCount-1})),"home"===p&&t.state.open&&(e.preventDefault(),t.setState({activeIndex:0})),"down"===p&&(e.preventDefault(),t.state.open?t.setState((function(e){return{activeIndex:Math.min(e.activeIndex+1,t.availableOptionCount-1)}})):t.setState({activeIndex:0,open:!0}),c&&s)){var f,d=r.Children.toArray(c).length-(2+(null!==(f=t.getCurrentValues())&&void 0!==f?f:[]).length);t.state.activeIndex===d&&t.handleScrollBottom(e)}"up"===p&&(e.preventDefault(),t.state.open?t.setState((function(e){return{activeIndex:Math.max(e.activeIndex-1,0)}})):t.setState({activeIndex:0,open:!0})),"enter"===p&&!Object(l.isUndefined)(t.activeValue)&&t.state.open&&t.addValue(e,t.activeValue),"backspace"===p&&""===(null===(n=t.input)||void 0===n?void 0:n.value)&&(null===(o=t.getCurrentValues())||void 0===o?void 0:o.length)&&t.removeValue(e,Object(l.last)(t.getCurrentValues()))}})),de(pe(t),"handleInputChange",(function(e){var n,r;t.setState({filterKeyword:e.target.value,open:!0,activeIndex:0}),null===(n=(r=t.props).onFilterChange)||void 0===n||n.call(r,e,{keyword:e.target.value})})),de(pe(t),"handleMenuOptionClick",(function(e,n){var r,o=n.value;t.addValue(e,o),null===(r=t.input)||void 0===r||r.focus()})),de(pe(t),"handleInputBlur",(function(e){var n,r,o=document.getElementById(t.popoverId),a=e.relatedTarget||document.activeElement,i=o&&a&&o.contains(a);t.setState((function(e){return{filterKeyword:i?e.filterKeyword:"",hasFocus:!1}})),i||null===(n=(r=t.props).onFilterChange)||void 0===n||n.call(r,e,{keyword:""})})),de(pe(t),"handleRequestClose",(function(e){var n,r,o=e.reason,a=e.event;("escapeKey"===o||"offScreen"===o||"clickAway"===o&&void 0!==a&&!(null===(n=t.state.el)||void 0===n?void 0:n.contains(a.target)))&&t.setState({open:!1},(function(){var e,n;t.previousActiveIndex=null,null===(e=(n=t.props).onClose)||void 0===e||e.call(n)})),"escapeKey"===o&&(null===(r=t.input)||void 0===r||r.focus())})),de(pe(t),"handleScrollBottom",(function(e){var n,r;t.state.open&&!t.props.isLoadingOptions&&(null===(n=(r=t.props).onScrollBottom)||void 0===n||n.call(r,e),t.setState({loadingMoreMessage:"".concat(t.availableOptionCount," options, loading more options")}))})),de(pe(t),"handleMount",(function(e){t.setState({el:e}),Object(ne.a)(t.props.elementRef,e)})),de(pe(t),"handleInputMount",(function(e){t.input=e,Object(ne.a)(t.props.inputRef,e)})),de(pe(t),"handleActiveOptionMount",(function(e){t.previousActiveIndex!==t.state.activeIndex&&(null==e||e.scrollIntoViewIfNeeded())})),de(pe(t),"renderMenu",(function(e){var n=e.anchorWidth,r=e.maxHeight,a=e.placement;return o.a.createElement(H.a,le({controlledExternally:!0,placement:null!=a?a:void 0,maxHeight:null!=r?r:void 0,isLoading:t.props.isLoadingOptions,onScrollBottom:t.props.onScrollBottom?t.handleScrollBottom:void 0},Object(l.pick)(t.props,"noOptionsMessage","footerMessage","animateLoading","loadingMessage","onScroll"),{style:Object(l.extend)({width:Math.max(null!=n?n:0,200)},t.props.menuStyle)}),t.children)})),t.state={activeIndex:0,el:null,filterKeyword:"",hasFocus:!1,open:!1,values:e.defaultValues||[],loadingMoreMessage:""},t.availableOptionCount=0,t.children=[],t.controlledExternally=Object(l.has)(e,"values"),t.activeItemId=Object(B.createDOMID)("active-item"),t.popoverId=Object(B.createDOMID)("popover"),t}return t=s,(n=[{key:"componentDidUpdate",value:function(e,t){this.previousActiveIndex=t.activeIndex,this.isControlled()&&e.values!==this.props.values&&this.setState({filterKeyword:"",activeIndex:0})}},{key:"getCurrentValues",value:function(){return this.isControlled()?this.props.values:this.state.values}},{key:"isControlled",value:function(){return this.controlledExternally}},{key:"focus",value:function(){this.input&&this.input.focus()}},{key:"addValue",value:function(e,t){var n,r,o,a=(null!==(n=this.getCurrentValues())&&void 0!==n?n:[]).concat([t]),i=this.props.name;this.isControlled()||this.setState({values:a,activeIndex:0,open:!0,filterKeyword:""}),null===(r=(o=this.props).onChange)||void 0===r||r.call(o,e,{values:a,name:i})}},{key:"removeValue",value:function(e,t){var n,r,o=Object(l.without)(this.getCurrentValues(),t),a=this.props.name;this.isControlled()||this.setState({values:o}),null===(n=(r=this.props).onChange)||void 0===n||n.call(r,e,{values:o,name:a})}},{key:"renderButtons",value:function(e){var t=this;return e.map((function(e){var n=e;return o.a.createElement(F.a,{"aria-selected":!0,disabled:t.props.disabled,icon:n.props?n.props.icon:void 0,key:(n.props?n.props.value:n).toString(),"data-test":"selected-option",onRequestRemove:t.handleRequestRemove,role:"option",value:n.props?n.props.value:n,appearance:n.props?n.props.selectedAppearance:void 0,backgroundColor:n.props?n.props.selectedBackgroundColor:void 0,foregroundColor:n.props?n.props.selectedForegroundColor:void 0},n.props?n.props.children||n.props.label:n)}))}},{key:"render",value:function(){var e,t=this,n=this.props,a=n.allowNewValues,i=n.children,c=n.controlledFilter,s=n.defaultPlacement,u=n.describedBy,p=n.disabled,f=n.error,d=n.inline,b=n.inputId,h=n.labelledBy,v=n.placeholder,y=n.repositionMode,m=n.useClickawayOverlay,g=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(n,["allowNewValues","children","controlledFilter","defaultPlacement","describedBy","disabled","error","inline","inputId","labelledBy","placeholder","repositionMode","useClickawayOverlay"]),O=ie(ie({},Object(l.pickBy)(g,(function(e,t){return"role"===t||0===t.indexOf("aria-")}))),{},{"aria-describedby":u,"aria-labelledby":h,"aria-invalid":f||void 0}),x=null!==(e=this.getCurrentValues())&&void 0!==e?e:[],w=x.slice(0),C=x.indexOf(this.state.filterKeyword)>=0;x&&x.length&&r.Children.toArray(i).filter(r.isValidElement).filter((function(e){return e.type===j})).forEach((function(e){if(e.type===j){var t=x.indexOf(e.props.value);-1!==t&&(w[t]=e)}}));var S=Object(M.stringToKeywords)(this.state.filterKeyword),k=c?r.Children.toArray(i):r.Children.toArray(i).filter((function(e){return!Object(l.get)(e,["props","label"],!1)||Object(M.testPhrase)(e.props.label,S)}));this.availableOptionCount=0,this.activeValue=void 0,this.children=r.Children.map(k,(function(e,n){if(!e.props||!Object(l.has)(e.props,"value"))return e;var o=e;if(o.props.value===t.state.filterKeyword&&(C=!0),x.indexOf(o.props.value)>=0)return null;var a=o.props,i=a.children,s=a.label,u=a.matchRanges,p=void 0===i||Object(l.isString)(i),f=p&&!c&&!u&&S&&Object(M.keywordLocations)(s,S);return Object(r.cloneElement)(o,{key:n,onClick:t.handleMenuOptionClick,matchRanges:p&&(u||f)||void 0})})).filter((function(e){return null!==e})),a&&!C&&this.state.filterKeyword&&this.children.unshift(o.a.createElement(j,{label:"".concat(this.state.filterKeyword," (new value)"),value:this.state.filterKeyword,key:"newValue",onClick:this.handleMenuOptionClick})),this.state.open&&(this.children=r.Children.map(this.children,(function(e){if(!e.props||!Object(l.has)(e.props,"value"))return e;var n=e,o=t.availableOptionCount===t.state.activeIndex;return t.availableOptionCount+=1,o?(n.props.disabled||(t.activeValue=n.props.value),Object(r.cloneElement)(n,{active:o,id:t.activeItemId,ref:t.handleActiveOptionMount})):n})));var P,E="".concat(.8*this.state.filterKeyword.length,"em");return[o.a.createElement(Q,le({key:"control","data-test-values":JSON.stringify(x),inline:d,$hasfocus:this.state.hasFocus},l.omit.apply(void 0,[g,"animateLoading","controlledFilter","defaultValues","footerMessage","inputRef","isLoadingOptions","labelledBy","menuStyle","noOptionsMessage","onChange","onFilterChange","onScroll","onScrollBottom","onClose","onOpen","values","useClickawayOverlay"].concat((P=Object(l.keys)(O),function(e){if(Array.isArray(e))return oe(e)}(P)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(P)||function(e,t){if(e){if("string"==typeof e)return oe(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?oe(e,t):void 0}}(P)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()))),{onClick:p?void 0:this.handleClick,$disabled:p,$error:f,"data-test-popover-id":this.popoverId,$popoverOpen:this.state.open,flex:!0,elementRef:this.handleMount,role:"listbox","aria-disabled":p||void 0}),o.a.createElement(K.a,{role:"status","aria-live":"polite"},this.state.loadingMoreMessage),this.renderButtons(w),!p&&o.a.createElement(J,{role:"combobox","aria-owns":this.state.open?this.popoverId:void 0,"aria-haspopup":!0,"aria-expanded":this.state.open},o.a.createElement(ee,le({"data-test":"textbox",id:b,ref:this.handleInputMount,onBlur:this.handleInputBlur,onFocus:this.handleInputFocus,onChange:this.handleInputChange,onKeyDown:this.handleInputKeyDown,value:this.state.filterKeyword,autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",spellCheck:!1,"aria-autocomplete":"list",style:{flexBasis:E,width:E},placeholder:x.length?"":v,"aria-activedescendant":this.state.open&&this.availableOptionCount>0?this.activeItemId:void 0,"aria-controls":this.state.open?this.popoverId:void 0},O))),!p&&o.a.createElement(q.a,{open:this.state.open&&!!this.state.el,autoCloseWhenOffScreen:!0,anchor:this.state.el,onRequestClose:this.handleRequestClose,canCoverAnchor:!1,defaultPlacement:s,repositionMode:y,id:this.popoverId},this.renderMenu)),m&&this.state.open?o.a.createElement(te,{key:"overlay",$popoveropen:this.state.open,"data-test":"overlay"}):null]}}])&&ce(t.prototype,n),s}(r.Component);de(ve,"propTypes",be),de(ve,"defaultProps",he),de(ve,"Option",j),de(ve,"Divider",s.Divider),de(ve,"Heading",s.Heading);var ye=ve;function me(e){return me="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},me(e)}function ge(){return ge=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},ge.apply(this,arguments)}function Oe(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function xe(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function je(e,t){return je=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},je(e,t)}function we(e,t){return!t||"object"!==me(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function Ce(e){return Ce=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},Ce(e)}function Se(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var ke={allowNewValues:i.a.bool,animateLoading:i.a.bool,children:i.a.node,compact:i.a.bool,controlledFilter:i.a.bool,defaultPlacement:i.a.oneOf(["above","below","vertical"]),defaultValues:i.a.array,describedBy:i.a.string,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),error:i.a.bool,footerMessage:i.a.node,inline:i.a.bool,inputId:i.a.string,inputRef:i.a.oneOfType([i.a.func,i.a.object]),isLoadingOptions:i.a.bool,labelledBy:i.a.string,loadingMessage:i.a.node,menuStyle:i.a.object,name:i.a.string,noOptionsMessage:i.a.node,onChange:i.a.func,onClose:i.a.func,onFilterChange:i.a.func,onOpen:i.a.func,onScroll:i.a.func,onScrollBottom:i.a.func,placeholder:i.a.string,repositionMode:i.a.oneOf(["none","flip"]),showSelectedValuesFirst:i.a.oneOf(["nextOpen","immediately","never"]),tabConfirmsNewValue:i.a.bool,useClickawayOverlay:i.a.bool,values:i.a.array},Pe={allowNewValues:!1,animateLoading:!1,compact:!1,defaultPlacement:"vertical",disabled:!1,inline:!1,isLoadingOptions:!1,menuStyle:{},noOptionsMessage:Object(c._)("No matches"),placeholder:Object(c._)("Select..."),repositionMode:"flip",tabConfirmsNewValue:!1,useClickawayOverlay:!1},Ee=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&je(e,t)}(c,e);var t,n,r,a,i=(r=c,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=Ce(r);if(a){var n=Ce(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return we(this,e)});function c(){return Oe(this,c),i.apply(this,arguments)}return t=c,(n=[{key:"render",value:function(){return(e=this.props)&&!0===e.compact?o.a.createElement(A,ge({"data-test":"multiselect"},Object(l.omit)(this.props,"compact"))):o.a.createElement(ye,ge({"data-test":"multiselect"},Object(l.omit)(this.props,"compact")));var e}}])&&xe(t.prototype,n),c}(r.Component);Se(Ee,"propTypes",ke),Se(Ee,"defaultProps",Pe),Se(Ee,"componentType","Multiselect"),Se(Ee,"Option",j),Se(Ee,"Heading",s.Heading),Se(Ee,"Divider",s.Divider);var _e=Ee},13:function(e,t){e.exports=n(2725)},14:function(e,t){e.exports=n(5766)},16:function(e,t){e.exports=n(6416)},18:function(e,t){e.exports=n(9016)},2:function(e,t){e.exports=n(7294)},20:function(e,t){e.exports=n(6635)},24:function(e,t){e.exports=n(6401)},26:function(e,t){e.exports=n(583)},3:function(e,t){e.exports=n(2788)},30:function(e,t,n){"use strict";var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(13);function c(e){return c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c(e)}function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function p(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function f(e,t){return f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},f(e,t)}function d(e,t){return!t||"object"!==c(t)&&"function"!=typeof t?b(e):t}function b(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function h(e){return h=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},h(e)}function v(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var y={active:i.a.bool,children:i.a.node,description:i.a.string,descriptionPosition:i.a.oneOf(["right","bottom"]),disabled:i.a.bool,hidden:i.a.bool,icon:i.a.node,label:i.a.string.isRequired,multiple:i.a.bool,matchRanges:i.a.arrayOf(i.a.shape({start:i.a.number.isRequired,end:i.a.number.isRequired})),onClick:i.a.func,selected:i.a.bool,truncate:i.a.bool,value:i.a.oneOfType([i.a.string,i.a.number,i.a.bool]).isRequired},m=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}(c,e);var t,n,r,a,i=(r=c,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=h(r);if(a){var n=h(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return d(this,e)});function c(){var e;u(this,c);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return v(b(e=i.call.apply(i,[this].concat(n))),"c",null),v(b(e),"handleClick",(function(t){var n=e.props,r=n.onClick,o=n.value;n.disabled||null==r||r(t,{value:o})})),v(b(e),"handleMount",(function(t){e.c=t})),e}return t=c,(n=[{key:"scrollIntoViewIfNeeded",value:function(){var e;null===(e=this.c)||void 0===e||e.scrollIntoViewIfNeeded()}},{key:"focus",value:function(){var e;null===(e=this.c)||void 0===e||e.focus()}},{key:"render",value:function(){var e=this.props,t=e.value,n=e.children,r=e.label,a=e.multiple,i=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["value","children","label","multiple"]);return o.a.createElement(l.Item,s({"aria-selected":this.props.selected,"data-test-value":t,"data-test":"option",ref:this.handleMount},i,{selectable:!0,selectableAppearance:a?"checkbox":void 0,onClick:this.handleClick,role:"option",value:t.toString()}),n||r)}}])&&p(t.prototype,n),c}(r.PureComponent);v(m,"propTypes",y),v(m,"defaultProps",{descriptionPosition:"bottom",disabled:!1,multiple:!1,selected:!1,truncate:!1}),t.a=m},31:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(43),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M10.5,3.0015 C14.6421,3.0015 18,6.3593 18,10.5015 C18,12.2112 17.4279,13.7873 16.4647,15.0489 L20.7077,19.292 C21.0983,19.6825 21.0983,20.3156 20.7077,20.7062 C20.3172,21.0967 19.6841,21.0967 19.2935,20.7062 L15.0509,16.4635 C13.7888,17.4283 12.2113,18.0015 10.5,18.0015 C6.3579,18.0015 3,14.6436 3,10.5015 C3,6.3593 6.3579,3.0015 10.5,3.0015 Z M10.5,5.0015 C7.4624,5.0015 5,7.4639 5,10.5015 C5,13.539 7.4624,16.0015 10.5,16.0015 C13.5376,16.0015 16,13.539 16,10.5015 C16,7.4639 13.5376,5.0015 10.5,5.0015 Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M6.85277,2.0015 C9.53288,2.0015 11.7055,4.1741 11.7055,6.8542 C11.7055,7.8463 11.4079,8.7688 10.897,9.5373 L10.9245,9.5098 L14.0018,12.5871 L12.5876,14.0014 L9.51025,10.924 L9.53587,10.8984 C8.76733,11.4093 7.84481,11.707 6.85277,11.707 C4.17266,11.707 2,9.5343 2,6.8542 C2,4.1741 4.17266,2.0015 6.85277,2.0015 Z M6.85277,4.0015 C5.27723,4.0015 4,5.2787 4,6.8542 C4,8.4298 5.27723,9.707 6.85277,9.707 C8.42831,9.707 9.70554,8.4298 9.70554,6.8542 C9.70554,5.2787 8.42831,4.0015 6.85277,4.0015 Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},33:function(e,t){e.exports=n(6206)},36:function(e,t){e.exports=n(8566)},4:function(e,t){e.exports=n(5220)},40:function(e,t,n){"use strict";n.d(t,"a",(function(){return p}));var r=n(2),o=n.n(r),a=n(41),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M7.2788 9.00002C6.84609 9.00002 6.61768 9.51239 6.90691 9.83423L11.4078 14.8426C11.6065 15.0637 11.953 15.0636 12.1517 14.8425L16.6499 9.8341C16.939 9.51223 16.7106 9 16.2779 9L7.2788 9.00002Z",fill:"currentColor"}))}function p(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma24:u},e))}},41:function(e,t){e.exports=n(7924)},43:function(e,t){e.exports=n(8044)},46:function(e,t,n){"use strict";n.d(t,"a",(function(){return v.Divider})),n.d(t,"b",(function(){return v.Heading})),n.d(t,"d",(function(){return te}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(26),s=n(11),u=n(5),p=n(9),f=n(20),d=n.n(f),b=n(33),h=n.n(b),v=n(13),y=n(36),m=n.n(y),g=n(24),O=n.n(g),x=n(40),j=n(31),w=n(30),C=n(3),S=n.n(C),k=n(16),P=n.n(k),E=n(0),_=S()(P.a).withConfig({displayName:"SelectBaseStyles__StyledButton",componentId:"sc-16cj7sk-0"})(["&[data-inline]{width:",";}",""],(function(e){return e.$multiple?"400px":"auto"}),(function(e){return!e.$multiple&&"flex-grow: 0;"})),T=S.a.span.withConfig({displayName:"SelectBaseStyles__StyledLinkIcon",componentId:"sc-16cj7sk-1"})(["padding-right:2px;"]),D=S.a.span.withConfig({displayName:"SelectBaseStyles__StyledLinkCaret",componentId:"sc-16cj7sk-2"})(["padding-left:2px;"]),I=S.a.div.withConfig({displayName:"SelectBaseStyles__StyledFilter",componentId:"sc-16cj7sk-3"})(["padding:",";min-width:160px;"],Object(E.pick)({enterprise:"8px",prisma:"10px 16px"})),R=S.a.span.withConfig({displayName:"SelectBaseStyles__StyledSearchIconWrapper",componentId:"sc-16cj7sk-4"})(["color:",";pointer-events:none;padding:",";"],Object(E.pick)({enterprise:{light:E.variables.gray60,dark:E.variables.white},prisma:E.variables.contentColorMuted}),Object(E.pick)({comfortable:"0 8px",compact:"0 6px"})),L=S.a.span.withConfig({displayName:"SelectBaseStyles__StyledCount",componentId:"sc-16cj7sk-5"})(["padding-right:",";"],Object(E.pick)({enterprise:E.variables.spacingQuarter,prisma:E.variables.spacingXSmall})),A=S()(h.a).withConfig({displayName:"SelectBaseStyles__StyledControlsLink",componentId:"sc-16cj7sk-6"})(["",";"],(function(e){return e.$disabled&&Object(C.css)(["color:",";"],E.variables.contentColorDisabled)})),M=S.a.div.withConfig({displayName:"SelectBaseStyles__StyledToggleAllControls",componentId:"sc-16cj7sk-7"})(["padding:",";",""],Object(E.pick)({enterprise:"5px 8px",prisma:"10px 16px"}),Object(E.pickVariant)("$placement",{above:{enterprise:Object(C.css)(["border-top:",";"],E.variables.border),prisma:Object(C.css)(["border-top:1px solid ",";"],E.variables.neutral200)},below:{enterprise:Object(C.css)(["border-bottom:",";"],E.variables.border),prisma:Object(C.css)(["border-bottom:1px solid ",";"],E.variables.neutral200)}})),B=function(e,t){return e?e.label.charAt(t).toLowerCase():""},N=function(e,t){if(!e.length)return e;var n=null,r=!1,o=e.filter((function(e){var o=B(e,t.index);if(o===t.value)return r=!0,!0;if(!r){var a=B(n,t.index);a?o>t.value?(a<t.value||a>o)&&(n=e):o>a&&(n=e):n=e}return!1}));return 0===o.length&&n?[n]:o};function z(e){return z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},z(e)}function F(){return F=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},F.apply(this,arguments)}function $(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function H(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?$(Object(n),!0).forEach((function(t){Q(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):$(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function V(e){return function(e){if(Array.isArray(e))return W(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||q(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function q(e,t){if(e){if("string"==typeof e)return W(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?W(e,t):void 0}}function W(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function K(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function U(e,t,n){return t&&K(e.prototype,t),n&&K(e,n),e}function Z(e,t){return Z=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},Z(e,t)}function G(e,t){return!t||"object"!==z(t)&&"function"!=typeof t?X(e):t}function X(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function Y(e){return Y=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},Y(e)}function Q(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var J={allowKeyMatching:i.a.bool,allowNewValues:i.a.bool,animateLoading:i.a.bool,appearance:i.a.oneOf(["default","link","primary","pill","toggle","flat"]),append:i.a.bool,children:i.a.node,defaultPlacement:i.a.oneOf(["above","below","vertical"]),defaultValues:i.a.array,describedBy:i.a.string,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),error:i.a.bool,filter:i.a.oneOf([!1,!0,"controlled"]),footerMessage:i.a.node,inline:i.a.bool,inputId:i.a.string,inputRef:i.a.oneOfType([i.a.func,i.a.object]),isLoadingOptions:i.a.bool,labelledBy:i.a.string,labelText:i.a.string,loadingMessage:i.a.node,menuStyle:i.a.object,multiple:i.a.bool,name:i.a.string,noOptionsMessage:i.a.node,onChange:i.a.func,onClose:i.a.func,onFilterChange:i.a.func,onOpen:i.a.func,onScroll:i.a.func,onScrollBottom:i.a.func,placeholder:i.a.string,prefixLabel:i.a.string,prepend:i.a.bool,repositionMode:i.a.oneOf(["none","flip"]),showSelectedValuesFirst:i.a.oneOf(["nextOpen","immediately","never"]),suffixLabel:i.a.string,tabConfirmsNewValue:i.a.bool,values:i.a.array},ee={allowKeyMatching:!0,allowNewValues:!1,animateLoading:!1,appearance:"toggle",append:!1,defaultPlacement:"vertical",disabled:!1,filter:!1,inline:!1,isLoadingOptions:!1,menuStyle:{},multiple:!1,noOptionsMessage:Object(u._)("No matches"),placeholder:Object(u._)("Select..."),prepend:!1,repositionMode:"flip",tabConfirmsNewValue:!1};function te(e){return e&&Object(l.has)(e.props,"value")}var ne=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&Z(e,t)}(i,e);var t,n,a=(t=i,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=Y(t);if(n){var o=Y(this).constructor;e=Reflect.construct(r,arguments,o)}else e=r.apply(this,arguments);return G(this,e)});function i(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,i),Q(X(t=a.call(this,e)),"activeItemId",void 0),Q(X(t),"activeValue",void 0),Q(X(t),"availableOptionCount",void 0),Q(X(t),"controlledExternally",void 0),Q(X(t),"displayedValues",void 0),Q(X(t),"dropdown",null),Q(X(t),"firstSelectedEnabledOption",null),Q(X(t),"firstSelectedOptionIndex",void 0),Q(X(t),"menuId",void 0),Q(X(t),"previousActiveIndex",null),Q(X(t),"selectedOptionCount",void 0),Q(X(t),"optionRefsByKey",void 0),Q(X(t),"matchCharacter",void 0),Q(X(t),"matchTimeout",void 0),Q(X(t),"currentMatchOptions",void 0),Q(X(t),"availableMatchOptions",void 0),Q(X(t),"resetMatches",(function(){t.matchCharacter=null,t.currentMatchOptions=[],t.matchTimeout&&clearTimeout(t.matchTimeout)})),Q(X(t),"handleSelectAll",(function(e){var n,r,a,i=t.props,c=i.name,s=i.children;if(i.multiple){var u=null!==(n=t.getCurrentValues())&&void 0!==n?n:[],p=Object(l.uniq)(u.concat(t.displayedValues));p=o.a.Children.toArray(s).filter((function(e){return te(e)&&Object(l.includes)(p,e.props.value)&&(!e.props.disabled||Object(l.includes)(u,e.props.value))})).map((function(e){return e.props.value})),t.isControlled()||t.setState({values:p}),null===(r=(a=t.props).onChange)||void 0===r||r.call(a,e,{values:p,name:c})}})),Q(X(t),"handleClearAll",(function(e){var n,r,a,i=t.props,c=i.name,s=i.children;if(i.multiple){var u=null!==(n=t.getCurrentValues())&&void 0!==n?n:[],p=l.without.apply(void 0,[u].concat(V(t.displayedValues))),f=o.a.Children.toArray(s).filter((function(e){return te(e)&&(Object(l.includes)(u,e.props.value)&&e.props.disabled||Object(l.includes)(p,e.props.value))})).map((function(e){return e.props.value}));t.isControlled()||t.setState({values:f}),null===(r=(a=t.props).onChange)||void 0===r||r.call(a,e,{values:f,name:c})}})),Q(X(t),"handleTextKeyDown",(function(e){var n=t.props,o=n.children,a=n.onScrollBottom,i=n.tabConfirmsNewValue,c=Object(p.keycode)(e.nativeEvent);if("tab"===c&&i&&!Object(l.isUndefined)(t.activeValue)&&t.availableOptionCount<=1&&(e.preventDefault(),t.toggleValue(e,t.activeValue)),!(e.shiftKey||e.metaKey||e.ctrlKey)){if("down"===c&&(e.preventDefault(),t.setState((function(e){return{activeIndex:Math.min(e.activeIndex+1,t.availableOptionCount-1)}})),o&&a)){var s,u=r.Children.toArray(o).length-(2+(null!==(s=t.getCurrentValues())&&void 0!==s?s:[]).length);t.state.activeIndex===u&&t.handleScrollBottom(e)}"up"===c&&(e.preventDefault(),t.setState((function(e){return{activeIndex:Math.max(e.activeIndex-1,0)}}))),"enter"===c&&!Object(l.isUndefined)(t.activeValue)&&t.state.open&&(e.preventDefault(),t.toggleValue(e,t.activeValue))}})),Q(X(t),"handleMenuOptionClick",(function(e,n){var r=n.value;e.preventDefault(),t.state.open&&t.toggleValue(e,r)})),Q(X(t),"handleMenuOptionKeyDown",(function(e,n){var r=e.nativeEvent.key;if(1===r.length){var o=[],a={index:0,value:r};if(t.matchCharacter)t.currentMatchOptions.length>1&&(a.index=t.matchCharacter.index+1,o=N(t.currentMatchOptions,a));else{if(" "===r)return void t.resetMatches();o=N(t.availableMatchOptions,a)}if(o.length){var i=0;if(0===a.index&&o.length>1){var l=o.indexOf(t.availableMatchOptions[n]);l>=0&&(i=l===o.length-1?0:l+1)}var c,s=t.optionRefsByKey[o[i].itemKey];null!=s&&(null==s||null===(c=s.focus)||void 0===c||c.call(s))}t.currentMatchOptions=o,t.matchCharacter=a,t.matchTimeout&&clearTimeout(t.matchTimeout),t.matchTimeout=setTimeout(t.resetMatches,500),e.preventDefault(),e.stopPropagation()}})),Q(X(t),"handleTextChange",(function(e,n){var r,o,a=n.value;t.setState({filterKeyword:a,open:!0,activeIndex:0}),null===(r=(o=t.props).onFilterChange)||void 0===r||r.call(o,e,{keyword:a})})),Q(X(t),"handleTextFocus",(function(){t.setState({textHasFocus:!0})})),Q(X(t),"handleTextBlur",(function(){t.setState({textHasFocus:!1})})),Q(X(t),"handleRequestOpen",(function(e){var n={open:!0,topValues:t.getTopValues()};t.props.multiple&&(n.filterKeyword="");var r=t.state.filterKeyword;t.setState(n,(function(){var n,o,a,i,l;null===(n=(o=t.props).onOpen)||void 0===n||n.call(o),t.firstSelectedEnabledOption&&!t.hasFilter()?t.firstSelectedEnabledOption.focus():t.setState({activeIndex:null!==(a=t.firstSelectedOptionIndex)&&void 0!==a?a:0}),r!==t.state.filterKeyword&&(null===(i=(l=t.props).onFilterChange)||void 0===i||i.call(l,e,{keyword:t.state.filterKeyword}))}))})),Q(X(t),"handleRequestClose",(function(){t.setState({open:!1,activeIndex:0},(function(){var e,n;t.previousActiveIndex=null,null===(e=(n=t.props).onClose)||void 0===e||e.call(n)}))})),Q(X(t),"handleScrollBottom",(function(e){var n,r;t.state.open&&!t.props.isLoadingOptions&&(null===(n=(r=t.props).onScrollBottom)||void 0===n||n.call(r,e))})),Q(X(t),"handleActiveOptionMount",(function(e){t.previousActiveIndex!==t.state.activeIndex&&(null==e||e.scrollIntoViewIfNeeded())})),Q(X(t),"handleOptionMount",(function(e,n,r){r&&(t.firstSelectedEnabledOption=e),null==e?delete t.optionRefsByKey[n]:t.optionRefsByKey[n]=e})),Q(X(t),"createChildren",(function(){var e,n=t.state,a=n.filterKeyword,i=n.textHasFocus,s=n.topValues,u=t.props,p=u.allowKeyMatching,f=u.allowNewValues,d=u.filter,b=u.multiple,h=u.showSelectedValuesFirst,y=u.isLoadingOptions,m=u.onScrollBottom,g=t.getCurrentValues();t.availableOptionCount=0,t.firstSelectedOptionIndex=void 0,t.selectedOptionCount=0,t.activeValue=void 0,t.availableMatchOptions=[];var O,x=0,j=!1,C="immediately"===h?t.getTopValues():s,S=r.Children.toArray(t.props.children).reduce((function(n,a,i){if(!te(a))return n.push(a),n;a.props.value===t.state.filterKeyword&&(e=!0);var l=g&&g.indexOf(a.props.value)>=0,c=!!l&&!a.props.disabled&&!O,s=p&&!b&&!d&&!y&&!m,u="".concat(a.props.label,"-").concat(a.props.value),f=-1;!s||a.props.disabled||a.props.hidden||(t.availableMatchOptions.push({itemKey:u,label:a.props.label,value:a.props.value}),f=t.availableMatchOptions.length-1);var h=Object(r.cloneElement)(a,{key:a.key||i,onClick:t.handleMenuOptionClick,onKeyDown:s?function(e){return t.handleMenuOptionKeyDown(e,f)}:void 0,selected:l,multiple:b,role:"option",ref:function(e){return t.handleOptionMount(e,u,c)}});return c&&(O=!0),C&&C.indexOf(a.props.value)>=0?(0===x&&(n.splice(x,0,o.a.createElement(v.Divider,{key:"topDivider"})),j=!0),n.splice(x,0,h),x+=1):n.push(h),n}),[]);b&&Object(l.forEachRight)(g,(function(n){if(!Object(l.find)(S,(function(e){return te(e)&&e.props&&e.props.value===n}))){n===t.state.filterKeyword&&(e=!0);var r=C&&C.indexOf(n)>=0,a=C.length;0===x&&(S.splice(0,0,o.a.createElement(v.Divider,{key:"topDivider"})),x+=1,j=!0),S.splice(r?0:a+1,0,o.a.createElement(w.a,{label:String(n),value:n,key:"missing-value-".concat(n),onClick:t.handleMenuOptionClick,multiple:b,selected:!0})),r&&(x+=1)}}));var k="controlled"===d,P=Object(c.stringToKeywords)(a);if(S=k?S:S.filter((function(e){return!te(e)||Object(c.testPhrase)(e.props.label,P)})).map((function(e){if(!te(e))return e;var t=P&&Object(c.keywordLocations)(e.props.label,P);return Object(r.cloneElement)(e,{matchRanges:t||void 0})})),f&&!e&&a){var E=j?x+1:x;S.splice(E,0,o.a.createElement(w.a,{label:"".concat(a," (new value)"),value:a,key:"newValue",multiple:b,onClick:t.handleMenuOptionClick}))}return S=S.reduce((function(e,n){if(!te(n))return e.push(n),e;if(n.props&&n.props.hidden)return e;n.props.selected&&!n.props.disabled&&null==t.firstSelectedOptionIndex&&(t.firstSelectedOptionIndex=t.availableOptionCount);var o=t.availableOptionCount===t.state.activeIndex;if(t.availableOptionCount+=1,t.selectedOptionCount+=n.props.selected?1:0,!o||!i)return e.push(n),e;n.props.disabled||(t.activeValue=n.props.value);var a=Object(r.cloneElement)(n,{active:o,id:t.activeItemId,ref:t.handleActiveOptionMount});return e.push(a),e}),[]),t.displayedValues=S.reduce((function(e,t){return te(t)&&e.push(t.props.value),e}),[]),S})),Q(X(t),"wrapLabel",(function(e){var t=e.prefixLabel,n=e.label,r=e.suffixLabel,o=n;return t&&(o=["".concat(t,": ")].concat(o)),r&&(o=Object(l.castArray)(o).concat(" ".concat(r))),o})),t.state={activeIndex:0,filterKeyword:"",open:!1,textHasFocus:!1,topValues:[],values:e.defaultValues||[]},t.controlledExternally=Object(l.has)(e,"values"),t.displayedValues=[],t.availableOptionCount=0,t.firstSelectedOptionIndex=void 0,t.selectedOptionCount=0,t.matchCharacter=null,t.matchTimeout=null,t.currentMatchOptions=[],t.availableMatchOptions=[],t.optionRefsByKey={},i.validateAppearance(e),t.menuId=Object(s.createDOMID)("menu"),t.activeItemId=Object(s.createDOMID)("active-item"),t}return U(i,null,[{key:"validateAppearance",value:function(e){}}]),U(i,[{key:"componentDidUpdate",value:function(e,t){i.validateAppearance(this.props),this.previousActiveIndex=t.activeIndex}},{key:"getCurrentValues",value:function(){var e=this.isControlled()?this.props.values:this.state.values;return this.props.multiple||null==e?e:e.slice(0,1)}},{key:"getTopValues",value:function(){var e;return this.props.multiple&&"never"!==this.props.showSelectedValuesFirst&&null!==(e=this.getCurrentValues())&&void 0!==e?e:[]}},{key:"isControlled",value:function(){return this.controlledExternally}},{key:"hasFilter",value:function(){return!!this.props.filter}},{key:"toggleValue",value:function(e,t){var n,r,o,a,i=null!==(n=this.getCurrentValues())&&void 0!==n?n:[],l=i.indexOf(t),c=this.props,s=c.name,u=c.multiple;a=u?l>=0?[].concat(V(i.slice(0,l)),V(i.slice(l+1))):i.concat([t]):[t];var p=!this.isControlled();p&&this.setState({values:a}),u?p&&this.setState({open:!0}):(this.handleRequestClose({reason:"contentClick"}),this.focus()),null===(r=(o=this.props).onChange)||void 0===r||r.call(o,e,{values:a,name:s})}},{key:"focus",value:function(){var e;null===(e=this.dropdown)||void 0===e||e.focus()}},{key:"renderControls",value:function(e){var t=e.hasChildren,n=e.placement,r=this.state.filterKeyword,a=this.props,i=a.inputId,l=a.inputRef,c=a.multiple,s=o.a.createElement(M,{$placement:n,key:"selectAll"},o.a.createElement(A,{$disabled:!(this.availableOptionCount-this.selectedOptionCount),onClick:this.handleSelectAll,"data-test":"select-all",style:{marginRight:20}},r?Object(u._)("Select All Matches"):Object(u._)("Select All")),o.a.createElement(A,{$disabled:!this.selectedOptionCount,onClick:this.handleClearAll,"data-test":"clear-all"},r?Object(u._)("Clear All Matches"):Object(u._)("Clear All")));return this.hasFilter()&&o.a.createElement("div",{key:"controls"},o.a.createElement(I,{key:"filter","data-test":"filter"},o.a.createElement(O.a,{value:r,autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",spellCheck:!1,onChange:this.handleTextChange,onKeyDown:this.handleTextKeyDown,onFocus:this.handleTextFocus,onBlur:this.handleTextBlur,placeholder:Object(u._)("filter"),role:"combobox","aria-expanded":"true","aria-label":Object(u._)("Filter"),"aria-activedescendant":this.activeItemId,"aria-controls":this.menuId,inputRef:l,inputId:i,canClear:!0,startAdornment:o.a.createElement(R,null,o.a.createElement(j.a,{role:"presentation",enterpriseSize:"16px",inline:!1,screenReaderText:Object(u._)("Search")}))})),c&&t&&s)}},{key:"render",value:function(){var e,t,n,a=this,c=this.props,s=c.appearance,p=c.children,f=c.defaultPlacement,b=c.describedBy,v=c.disabled,y=c.elementRef,g=c.error,O=c.inline,j=c.inputId,w=c.labelledBy,C=c.labelText,S=c.multiple,k=c.placeholder,P=c.prefixLabel,E=c.repositionMode,I=c.suffixLabel,R=this.hasFilter(),A=!1,M=r.Children.toArray(p),B=null!==(e=this.getCurrentValues())&&void 0!==e?e:[];(n=B.reduce((function(e,n,r,o){var a=Object(l.find)(M,(function(e){return te(e)&&e.props.value===n}));return a?(e.push(a.props.children||a.props.label),a.props.disabled||(A=!0),S||1!==B.length||(t=a.props.icon)):S&&e.push(n),r<o.length-1&&e.push(Object(u._)(", ")),e}),[])).length>0&&(n=this.wrapLabel({prefixLabel:P,label:n,suffixLabel:I})),(0===n.length||!S&&n.every((function(e){return""===e})))&&(n=[k]);var N=n;n.length>1&&(N=this.wrapLabel({prefixLabel:P,label:["".concat(B.length," items selected")],suffixLabel:I}));var z,$,V=this.createChildren(),W=H({"aria-describedby":b,"aria-label":"".concat(C?"".concat(C,", "):"").concat(N),"aria-labelledby":C?void 0:w,"aria-multiselectable":S,"data-select-appearance":s,"data-test":S?"multiselect":"select",disabled:v,elementRef:y,error:g},Object(l.omit)(this.props,Object(l.keys)(i.propTypes)));if(S)W["data-test-values"]=JSON.stringify(B);else{var K=(z=B,$=1,function(e){if(Array.isArray(e))return e}(z)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,a=void 0;try{for(var i,l=e[Symbol.iterator]();!(r=(i=l.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){o=!0,a=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw a}}return n}}(z,$)||q(z,$)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())[0];W["data-test-value"]=K}var U="link"===s?o.a.createElement(h.a,F({},W,{"data-select-appearance":"link"}),!!t&&o.a.createElement(T,null,t),n||k,o.a.createElement(D,null,o.a.createElement(x.a,{enterpriseSize:.5,prismaSize:"small"}))):o.a.createElement(_,F({},W,{$multiple:S,appearance:s,label:n,error:g,icon:t,inline:O,isMenu:!0,role:"listbox",onClick:this.props.onClick},Object(l.pick)(this.props,i.invalidLinkAppearanceProps)),!!B.length&&S&&o.a.createElement(L,{"data-role":"count"},"(",B.length,")")),Z=function(e){var t=e.anchorWidth,n=e.maxHeight,r=e.placement,i=a.props.multiple?{width:Math.max(null!=t?t:0,200)}:{minWidth:null!=t?t:void 0,maxWidth:Math.max(null!=t?t:0,300)};return o.a.createElement(m.a,F({"aria-multiselectable":S,childrenStart:a.renderControls({placement:r,hasChildren:!!V.length}),controlledExternally:a.hasFilter(),placement:null!=r?r:void 0,maxHeight:null!=n?n:void 0,onScrollBottom:a.props.onScrollBottom?a.handleScrollBottom:void 0,"data-test":"results-menu",isLoading:a.props.isLoadingOptions,id:a.menuId},Object(l.pick)(a.props,"noOptionsMessage","footerMessage","animateLoading","loadingMessage","onScroll"),{style:H(H({},i),a.props.menuStyle),tabIndex:B.length>0&&!A?0:void 0}),V)};return o.a.createElement(d.a,{closeReasons:["clickAway","escapeKey","offScreen","tabKey","toggleClick"],inputId:j,toggle:U,onRequestOpen:this.handleRequestOpen,onRequestClose:this.handleRequestClose,open:this.state.open,repositionMode:E,defaultPlacement:R?f:void 0,canCoverAnchor:window.innerHeight<500,ref:function(e){a.dropdown=e},retainFocus:!1,takeFocus:0===B.length||B.length>0&&!A||!!R},Z)}}]),i}(r.Component);Q(ne,"propTypes",J),Q(ne,"defaultProps",ee),Q(ne,"Option",w.a),Q(ne,"Divider",v.Divider),Q(ne,"Heading",v.Heading),Q(ne,"invalidLinkAppearanceProps",["append","error","prepend"]),t.c=ne},5:function(e,t){e.exports=n(6219)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var r=n(2),o=n.n(r),a=n(3);function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n.n(a).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function c(e){return o.a.createElement(l,i({xmlns:"http://www.w3.org/2000/svg"},e))}},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(0);function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}var p={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},f={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:i.a.func,enterpriseSize:i.a.oneOfType([i.a.number,i.a.string]),enterpriseWidth:i.a.oneOfType([i.a.number,i.a.string]),enterpriseHeight:i.a.oneOfType([i.a.number,i.a.string]),Prisma24:i.a.func.isRequired,Prisma20:i.a.func,Prisma16:i.a.func,prismaSize:i.a.oneOf(["medium","small"]),inline:i.a.bool,screenReaderText:i.a.string};function b(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,a=e.Prisma16,i=e.prismaSize,d=e.inline,b=e.enterpriseSize,h=e.enterpriseWidth,v=e.enterpriseHeight,y=e.screenReaderText,m=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),g=Object(l.useSplunkTheme)(),O=g.family,x=g.density;if("enterprise"===O)return o.a.createElement(t,u({size:b,width:h,height:v,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},m));var j=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?p:f},m);if("small"===i){var w=a||n;return o.a.createElement(w,u({width:"16",height:"16"},j))}if("compact"===x){var C=r||n;return o.a.createElement(C,u({width:"20",height:"20"},j))}return o.a.createElement(n,u({width:"24",height:"24"},j))}b.propTypes=d,b.defaultProps={inline:!0,prismaSize:"medium"}},8:function(e,t){e.exports=n(6493)},9:function(e,t){e.exports=n(2916)}})},8411:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=122)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},102:function(e,t){e.exports=n(2666)},122:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return U}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(45),c=n(5),s=n(8),u=n.n(s),p=n(0),f=n(102),d=n.n(f),b=n(7),h=n(6);function v(){return v=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},v.apply(this,arguments)}function y(e){var t=v({},e);return o.a.createElement(h.a,v({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M6.28933 12.0001C6.28933 11.0964 5.5567 10.3637 4.65297 10.3637C3.74923 10.3637 3.0166 11.0964 3.0166 12.0001C3.0166 12.9038 3.74923 13.6365 4.65297 13.6365C5.5567 13.6365 6.28933 12.9038 6.28933 12.0001ZM12.0166 10.3637C12.9204 10.3637 13.653 11.0964 13.653 12.0001C13.653 12.9038 12.9204 13.6365 12.0166 13.6365C11.1129 13.6365 10.3802 12.9038 10.3802 12.0001C10.3802 11.0964 11.1129 10.3637 12.0166 10.3637ZM19.3803 10.3637C20.284 10.3637 21.0166 11.0964 21.0166 12.0001C21.0166 12.9038 20.284 13.6365 19.3803 13.6365C18.4765 13.6365 17.7439 12.9038 17.7439 12.0001C17.7439 11.0964 18.4765 10.3637 19.3803 10.3637Z",fill:"currentColor"}))}function m(e){return o.a.createElement(b.a,v({Enterprise:d.a,Prisma24:y},e))}var g=n(3),O=n.n(g),x=O.a.span.withConfig({displayName:"PageSeparatorStyles__StyledEllipsisWrapper",componentId:"j50fqf-0"})(["display:flex;align-items:center;margin:",";color:",";"],Object(p.pick)({enterprise:"0px 11px",prisma:"0px 20px"}),p.variables.contentColorActive),j=function(){var e="enterprise"===Object(p.useSplunkTheme)().family?o.a.createElement("span",{role:"separator"},"…"):o.a.createElement(m,{prismaSize:"small",role:"separator"});return o.a.createElement(x,null,e)},w=n(4),C=n(48),S=n.n(C),k=O()(S.a).withConfig({displayName:"ButtonStyles__StyledButtonSimple",componentId:"sc-1neztq7-0"})(["min-width:",";min-height:",";text-align:center;flex-shrink:0;",""],p.variables.inputHeight,p.variables.inputHeight,Object(p.pick)({enterprise:{comfortable:Object(g.css)(["padding:",";"],p.variables.spacingQuarter),compact:Object(g.css)(["padding:3px;"])},prisma:Object(g.css)(["padding:",";"," & + &{margin-left:8px;}"],Object(p.pick)({comfortable:"5px 8px",compact:"4px"}),(function(e){return e.selected&&Object(g.css)(["font-weight:",";"],p.variables.fontWeightBold)}))})),P=O.a.div.withConfig({displayName:"ButtonStyles__StyledPrevNext",componentId:"sc-1neztq7-1"})(["padding:",";white-space:nowrap;"],Object(p.pick)({enterprise:"0 3px",prisma:"0 8px"}));function E(e){return E="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},E(e)}function _(){return _=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},_.apply(this,arguments)}function T(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function D(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function I(e,t){return I=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},I(e,t)}function R(e,t){return!t||"object"!==E(t)&&"function"!=typeof t?L(e):t}function L(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function A(e){return A=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},A(e)}function M(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var B={children:i.a.node,label:i.a.node,onClick:i.a.func,page:i.a.number,selected:i.a.bool},N=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&I(e,t)}(l,e);var t,n,r,a,i=(r=l,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=A(r);if(a){var n=A(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return R(this,e)});function l(){var e;T(this,l);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return M(L(e=i.call.apply(i,[this].concat(n))),"handleClick",(function(t){var n=e.props,r=n.onClick,o=n.page;null==r||r(t,{page:o})})),e}return t=l,(n=[{key:"render",value:function(){var e=this.props,t=e.children,n=e.label,r=e.page,a=e.selected;return o.a.createElement(k,_({"data-test":"page","data-test-page":r,appearance:"pill",onClick:void 0!==r?this.handleClick:void 0,inline:!1,selected:a},Object(w.omit)(this.props,Object(w.keys)(l.propTypes))),n,t&&o.a.createElement(P,null,t))}}])&&D(t.prototype,n),l}(r.Component);M(N,"propTypes",B),M(N,"defaultProps",{selected:!1});var z=N,F=n(62),$=n(29),H=O()(F.a).withConfig({displayName:"PaginatorStyles__StyledChevronLeft",componentId:"pmabsp-0"})(["",""],Object(p.pick)({enterprise:Object(g.css)(["margin:-1px 3px 0px 0px;"]),prisma:Object(g.css)(["margin:-2px 6px 0px 0px;color:",";"],(function(e){return e.$disabled?p.variables.contentColorDisabled:p.variables.contentColorMuted}))})),V=O()($.a).withConfig({displayName:"PaginatorStyles__StyledChevronRight",componentId:"pmabsp-1"})(["",""],Object(p.pick)({enterprise:Object(g.css)(["margin:-1px 0px 0px 3px;"]),prisma:Object(g.css)(["margin:-2px 0px 0px 6px;color:",";"],(function(e){return e.$disabled?p.variables.contentColorDisabled:p.variables.contentColorMuted}))}));function q(){return q=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},q.apply(this,arguments)}var W={alwaysShowLastPageLink:i.a.bool,current:i.a.number,elementRef:i.a.oneOfType([i.a.func,i.a.object]),numPageLinks:i.a.number,onChange:i.a.func,totalPages:i.a.number};function K(e){var t,n,r=e.onChange,a=e.current,i=void 0===a?1:a,s=e.alwaysShowLastPageLink,p=void 0!==s&&s,f=e.numPageLinks,d=void 0===f?5:f,b=e.totalPages,h=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["onChange","current","alwaysShowLastPageLink","numPageLinks","totalPages"]),v=Math.min(d,b),y=Math.ceil(v/2),m=Math.ceil(b-v/2),g=[];if(b<=1)return null;i<=y+1?n=(t=1)+Math.min(b,v)-1:i>y&&i<m?t=(n=Math.ceil(i+(v-2)/2))-v+2:(t=b-v==1?1:b-v+1,n=b),n=p&&n+1===b?b:n,g.push(o.a.createElement(z,{"data-test":"prev",disabled:1===i,onClick:r,page:i-1,key:"prev","aria-label":Object(c._)("Go to previous page")},o.a.createElement(H,{$disabled:1===i}),Object(c._)("Prev"))),i>y&&b>v&&1!==t&&(g.push(o.a.createElement(z,{label:"1",key:"first",onClick:r,page:1,"aria-label":Object(c._)("Go to first page")})),g.push(o.a.createElement(j,{"data-test":"page",key:"prevEllipsis"})));for(var O=t;O<=n;O+=1){var x=O===i;g.push(o.a.createElement(z,{label:String(O),selected:x,onClick:r,page:O,key:O,"aria-label":x?Object(c._)("Current page"):Object(l.sprintf)(Object(c._)("Go to page %(pageNumber)d"),{pageNumber:O})}))}return i<=m&&b>v&&n!==b&&(g.push(o.a.createElement(j,{"data-test":"page",key:"nextEllipsis"})),p&&g.push(o.a.createElement(z,{"data-test":"last",label:String(b),key:"last",onClick:r,page:b,"aria-label":Object(c._)("Go to last page")}))),g.push(o.a.createElement(z,{"data-test":"next",disabled:i===b,onClick:r,page:i+1,key:"next","aria-label":Object(c._)("Go to next page")},Object(c._)("Next"),o.a.createElement(V,{$disabled:i===b}))),o.a.createElement(u.a,q({"data-test":"paginator","data-test-current":i,flex:!0,inline:!0,role:"navigation","aria-label":Object(c._)("Pagination navigation")},h),g)}K.propTypes=W;var U=K},2:function(e,t){e.exports=n(7294)},29:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(35),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M14.7861 11.9999L8.48587 5.69972C8.09534 5.3092 8.09534 4.67603 8.48587 4.28551C8.87639 3.89499 9.50956 3.89499 9.90008 4.28551L16.5538 10.9393C17.1396 11.525 17.1396 12.4748 16.5538 13.0606L9.90142 19.713C9.5109 20.1035 8.87773 20.1035 8.48721 19.713C8.09669 19.3224 8.09669 18.6893 8.48721 18.2988L14.7861 11.9999Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M11.7109 7.9976L5.71017 13.9983L4.29597 12.5841L8.88914 7.99095L4.34482 3.40363L5.76567 1.99609L11.7109 7.9976Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},3:function(e,t){e.exports=n(2788)},35:function(e,t){e.exports=n(4345)},4:function(e,t){e.exports=n(5220)},45:function(e,t){e.exports=n(8154)},48:function(e,t){e.exports=n(2254)},5:function(e,t){e.exports=n(6219)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var r=n(2),o=n.n(r),a=n(3);function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n.n(a).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function c(e){return o.a.createElement(l,i({xmlns:"http://www.w3.org/2000/svg"},e))}},62:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(63),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M9.21394 12L15.5141 5.69985C15.9046 5.30933 15.9046 4.67616 15.5141 4.28564C15.1236 3.89511 14.4904 3.89511 14.0999 4.28564L7.44618 10.9394C6.86039 11.5252 6.86039 12.4749 7.44618 13.0607L14.0999 19.7144C14.4904 20.105 15.1236 20.105 15.5141 19.7144C15.9046 19.3239 15.9046 18.6907 15.5141 18.3002L9.21394 12Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M4.28906 7.9976L10.2898 13.9983L11.704 12.5841L7.11086 7.99095L11.6552 3.40363L10.2343 1.99609L4.28906 7.9976Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},63:function(e,t){e.exports=n(720)},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(0);function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}var p={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},f={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:i.a.func,enterpriseSize:i.a.oneOfType([i.a.number,i.a.string]),enterpriseWidth:i.a.oneOfType([i.a.number,i.a.string]),enterpriseHeight:i.a.oneOfType([i.a.number,i.a.string]),Prisma24:i.a.func.isRequired,Prisma20:i.a.func,Prisma16:i.a.func,prismaSize:i.a.oneOf(["medium","small"]),inline:i.a.bool,screenReaderText:i.a.string};function b(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,a=e.Prisma16,i=e.prismaSize,d=e.inline,b=e.enterpriseSize,h=e.enterpriseWidth,v=e.enterpriseHeight,y=e.screenReaderText,m=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),g=Object(l.useSplunkTheme)(),O=g.family,x=g.density;if("enterprise"===O)return o.a.createElement(t,u({size:b,width:h,height:v,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},m));var j=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?p:f},m);if("small"===i){var w=a||n;return o.a.createElement(w,u({width:"16",height:"16"},j))}if("compact"===x){var C=r||n;return o.a.createElement(C,u({width:"20",height:"20"},j))}return o.a.createElement(n,u({width:"24",height:"24"},j))}b.propTypes=d,b.defaultProps={inline:!0,prismaSize:"medium"}},8:function(e,t){e.exports=n(6493)}})},1040:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=171)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},171:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return P}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(38),s=n(3),u=n.n(s),p=n(49),f=n.n(p),d=n(52),b=n.n(d),h=n(8),v=n.n(h),y=n(0),m=u()(v.a).withConfig({displayName:"ProgressStyles__StyledBox",componentId:"csowex-0"})(["background-color:",";"],Object(y.pick)({enterprise:y.variables.transparent,prisma:y.variables.neutral200})),g=u()(b.a).withConfig({displayName:"ProgressStyles__StyledTooltip",componentId:"csowex-1"})(["background-color:",";height:",";position:relative;overflow:hidden;padding-left:",";",";"],Object(y.pick)({enterprise:y.variables.accentColorD10,prisma:Object(y.pickVariant)("$type",{info:y.variables.interactiveColorPrimary,success:y.variables.accentColorPositive,warning:y.variables.accentColorWarning,error:y.variables.accentColorNegative})}),Object(y.pick)({enterprise:"3px",prisma:"4px"}),Object(y.pick)({enterprise:y.variables.spacingHalf,prisma:"10px"}),(function(e){return e.$animated&&Object(s.css)(["transition:width 300ms;"])})),O=Object(s.keyframes)(["from{opacity:0;}to{opacity:1;}"]),x=Object(s.keyframes)(["from{background-position:130%;}to{background-position:-30%;}"]),j=u.a.div.withConfig({displayName:"ProgressStyles__StyledPuck",componentId:"csowex-2"})(["height:",";width:",";position:absolute;right:0;top:0;background:",";",""],Object(y.pick)({enterprise:"3px",prisma:"4px"}),Object(y.pick)({enterprise:"300px",prisma:"100%"}),Object(y.pick)({enterprise:Object(s.css)(["linear-gradient( 90deg,",",",",40%,",",80%,"," )"],y.variables.accentColorD10,y.variables.accentColorL10,y.variables.accentColorL40,y.variables.accentColorL40),prisma:function(e){var t=e.$animated,n=Object(y.pickVariant)("$type",{info:y.variables.interactiveColorPrimary,success:y.variables.accentColorPositive,warning:y.variables.accentColorWarning,error:y.variables.accentColorNegative});if(t){var r=Object(y.pickVariant)("$type",{info:y.variables.statusColorInfo,success:y.variables.statusColorNormal,warning:y.variables.statusColorMedium,error:y.variables.statusColorHigh});return Object(s.css)(["radial-gradient(circle at center,",","," 30%);"],r,n)}return n}}),(function(e){return e.$animated&&Object(y.pick)({enterprise:Object(s.css)(["animation-duration:1500ms;animation-name:",";animation-iteration-count:infinite;animation-direction:alternate;"],O),prisma:function(){var t=Object(y.pickVariant)("$type",{info:y.variables.statusColorInfo,success:y.variables.statusColorNormal,warning:y.variables.statusColorMedium,error:y.variables.statusColorHigh})(e);return Object(s.css)(["background-size:200% 100%;animation:"," 1500ms infinite cubic-bezier(0.33,0,0.67,1);&::after{content:'';display:block;width:60px;background:linear-gradient( to right,rgba(255,255,255,0),"," 70%,rgba(255,255,255,0.75) );height:100%;position:absolute;right:0;}"],x,f()(t(e)).setAlpha(.75).toRgbString())}})}));function w(){return w=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},w.apply(this,arguments)}function C(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var S={elementRef:i.a.oneOfType([i.a.func,i.a.object]),percentage:i.a.number,tooltip:i.a.node,type:i.a.oneOf(["info","success","warning","error"])};function k(e){var t,n,a=e.percentage,i=e.tooltip,s=e.type,u=void 0===s?"info":s,p=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["percentage","tooltip","type"]),f=(t=Object(r.useState)(!1),n=2,function(e){if(Array.isArray(e))return e}(t)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,a=void 0;try{for(var i,l=e[Symbol.iterator]();!(r=(i=l.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){o=!0,a=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw a}}return n}}(t,n)||function(e,t){if(e){if("string"==typeof e)return C(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?C(e,t):void 0}}(t,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),d=f[0],b=f[1],h="on"===Object(c.useAnimationToggle)(),v=Object(r.useCallback)((function(){b(!0)}),[]),y=Object(r.useCallback)((function(){b(!1)}),[]),O=i||"".concat(a,"%");return o.a.createElement(m,w({$animated:h,"data-test":"progress",onMouseEnter:v,onMouseLeave:y},p),Object(l.isNumber)(a)&&o.a.createElement(g,{inline:!1,open:d,content:O,style:{width:"".concat(a,"%")},role:"progressbar","aria-valuenow":a,"aria-valuemin":0,"aria-valuemax":100,$animated:h,$type:u},o.a.createElement(j,{$animated:h,$type:u})))}k.propTypes=S;var P=k},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)},38:function(e,t){e.exports=n(6603)},4:function(e,t){e.exports=n(5220)},49:function(e,t){e.exports=n(7621)},52:function(e,t){e.exports=n(5458)},8:function(e,t){e.exports=n(6493)}})},4228:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=130)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},12:function(e,t){e.exports=n(5917)},130:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return $})),n.d(t,"Option",(function(){return S}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(9),s=n(0),u=n(16),p=n.n(u),f=n(3),d=n.n(f),b=n(12),h=n.n(b),v=d()(h.a).withConfig({displayName:"OptionStyles__StyledClickable",componentId:"fyq77p-0"})(["border-radius:3px;flex:1 1 auto;display:flex;justify-content:center;align-items:center;color:",";padding:2px 12px;height:calc("," - 6px);position:relative;gap:",";& + &{margin-left:2px;}"," "," &:focus{color:",";box-shadow:",";z-index:2;&:active{background-color:",";}}"," ",""],s.variables.contentColorDefault,s.variables.inputHeight,s.variables.spacingXSmall,(function(e){return e.$selected&&Object(f.css)(["color:",";background-color:",";box-shadow:",";"],s.variables.contentColorActive,Object(s.pick)({dark:s.variables.interactiveColorOverlaySelected,light:s.variables.white}),s.variables.embossShadow)}),(function(e){var t=e.$selected,n=e.disabled;return t&&n&&Object(f.css)(["background-color:",";"],s.variables.backgroundColorPage)}),s.variables.contentColorActive,s.variables.focusShadow,s.variables.interactiveColorOverlayActive,(function(e){var t=e.$selected,n=e.disabled;return!t&&!n&&Object(f.css)(["&:hover{color:",";background-color:",";}&:active{background-color:",";}"],s.variables.contentColorActive,s.variables.interactiveColorOverlayHover,s.variables.interactiveColorOverlayActive)}),(function(e){return e.disabled&&Object(f.css)(["color:",";"],s.variables.contentColorDisabled)})),y=d.a.div.withConfig({displayName:"OptionStyles__StyledIcon",componentId:"fyq77p-1"})(["flex:0 0 auto;margin-top:-2px;font-size:15px;"]),m=d.a.div.withConfig({displayName:"OptionStyles__StyledLabel",componentId:"fyq77p-2"})([""," flex:0 1 auto;",""],s.mixins.ellipsis,Object(s.pick)({enterprise:Object(f.css)(["&:not(:first-child){margin-left:",";}"],s.variables.spacingXSmall)})),g=d.a.div.withConfig({displayName:"OptionStyles__StyledAdornment",componentId:"fyq77p-3"})(["flex:0 0 auto;",""],Object(s.pick)({enterprise:Object(f.css)(["&:not(:first-child){margin-left:",";}"],s.variables.spacingXSmall)})),O=Object(r.createContext)({});O.displayName="RadioBar";var x=O;function j(){return j=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},j.apply(this,arguments)}var w={disabled:i.a.bool,startAdornment:i.a.node,endAdornment:i.a.node,icon:i.a.node,label:i.a.string,selected:i.a.bool,value:i.a.any.isRequired};function C(e){var t=e.disabled,n=e.icon,a=e.label,i=e.selected,l=e.startAdornment,c=e.endAdornment,s=e.value,u=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["disabled","icon","label","selected","startAdornment","endAdornment","value"]),f=Object(r.useContext)(x),d=f.onClick,b=f.appearance,h=f.error,O=f.onKeyDown,w=f.firstValue,C=f.selectedValue,S=-1;C?s===C&&(S=0):s===w&&(S=0);var k=S;return"prisma"===b?o.a.createElement(v,j({"data-test":"option","data-test-value":s},u,{onClick:i?void 0:function(e){return null==d?void 0:d(e,{value:s,label:a})},role:"radio","aria-checked":i,$selected:i,tabIndex:k,disabled:t,onKeyDown:function(e){return null==O?void 0:O(e,{value:s,label:a})}}),n&&o.a.createElement(y,null,n),l&&o.a.createElement(g,null,l),a&&o.a.createElement(m,null,a),c&&o.a.createElement(g,null,c)):o.a.createElement(p.a,j({"data-test":"option","data-test-value":s,appearance:b,disabled:t,icon:n,selected:i,value:s,error:h},u,{onClick:i?void 0:function(e){return null==d?void 0:d(e,{value:s,label:a})},role:"radio","aria-checked":i,tabIndex:k,onKeyDown:function(e){return null==O?void 0:O(e,{value:s,label:a})}}),l&&o.a.createElement(g,null,l),a&&o.a.createElement(m,null,a),c&&o.a.createElement(g,null,c))}C.propTypes=w;var S=C,k=n(8),P=n.n(k),E=d()(P.a).withConfig({displayName:"RadioBarStyles__StyledRadioBar",componentId:"gg1b79-0"})(["height:",";"," [data-inline] + &{margin-left:",";}"],s.variables.inputHeight,Object(s.pick)({prisma:Object(f.css)(["padding:2px;border-radius:",";border:1px solid ",";background:",";"],s.variables.borderRadius,(function(e){return e.$error?s.variables.accentColorNegative:"transparent"}),(function(e){return e.$disabled?s.variables.interactiveColorBackgroundDisabled:s.variables.interactiveColorBackground}))}),Object(s.pick)({enterprise:s.variables.spacingHalf,prisma:s.variables.spacingSmall}));function _(e){return _="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},_(e)}function T(){return T=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},T.apply(this,arguments)}function D(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function I(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function R(e,t){return R=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},R(e,t)}function L(e,t){return!t||"object"!==_(t)&&"function"!=typeof t?A(e):t}function A(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function M(e){return M=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},M(e)}function B(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var N={appearance:i.a.oneOf(["default","pill"]),children:i.a.node,defaultValue:i.a.any,describedBy:i.a.string,elementRef:i.a.oneOfType([i.a.func,i.a.object]),error:i.a.bool,inline:i.a.bool,labelledBy:i.a.string,name:i.a.string,onChange:i.a.func,splunkTheme:i.a.object,value:i.a.any},z=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&R(e,t)}(u,e);var t,n,a,i,s=(a=u,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=M(a);if(i){var n=M(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return L(this,e)});function u(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,u),B(A(t=s.call(this,e)),"controlledExternally",void 0),B(A(t),"filteredValues",[]),B(A(t),"handleClick",(function(e,n){t.handleOnChange(e,n)})),B(A(t),"handleOnKeyDown",(function(e,n){var r,o=n.value,a=n.label,i=Object(c.keycode)(e.nativeEvent),l=e.currentTarget,s=null,u=0,p=t.filteredValues.indexOf(o);if("down"===i||"right"===i)e.preventDefault(),(u=p+1)>t.filteredValues.length-1&&(u=0),s=l.nextSibling?l.nextSibling:null===(r=l.parentElement)||void 0===r?void 0:r.firstElementChild;else if("up"===i||"left"===i){var f;e.preventDefault(),(u=p-1)<0&&(u=t.filteredValues.length-1),s=l.previousSibling?l.previousSibling:null===(f=l.parentElement)||void 0===f?void 0:f.lastElementChild}if(s){var d;null===(d=s)||void 0===d||d.focus();var b=t.filteredValues[u];t.handleOnChange(e,{value:b,label:a})}})),B(A(t),"handleOnChange",(function(e,n){var r,o;t.props.value!==n.value&&(null===(r=(o=t.props).onChange)||void 0===r||r.call(o,e,function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?D(Object(n),!0).forEach((function(t){B(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):D(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({name:t.props.name},n)),t.isControlled()||t.setState({value:n.value}))})),t.controlledExternally=Object(l.has)(e,"value"),t.isControlled()||(t.state={value:e.defaultValue}),t}return t=u,(n=[{key:"componentDidUpdate",value:function(e){}},{key:"isControlled",value:function(){return this.controlledExternally}},{key:"render",value:function(){var e=this,t=this.props,n=t.appearance,a=t.children,i=t.describedBy,c=t.error,s=t.labelledBy,u=t.splunkTheme,p=t.value,f=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(t,["appearance","children","describedBy","error","labelledBy","splunkTheme","value"]),d=this.isControlled()?p:this.state.value,b=u.isPrisma,h=!0;this.filteredValues=[];var v=r.Children.toArray(a).filter(r.isValidElement).map((function(t,n,o){var a=o.length;return e.filteredValues.push(t.props.value),t.props&&!t.props.disabled&&(h=!1),Object(r.cloneElement)(t,{selected:t.props.value===d,key:t.key||n,append:n<a-1,prepend:n>0})})),y=this.filteredValues[0],m={appearance:b?"prisma":n,onClick:this.handleClick,error:!b&&c,onKeyDown:this.handleOnKeyDown,firstValue:y,selectedValue:d};return o.a.createElement(E,T({flex:!0,$disabled:h,$error:c,"data-test":"radio-bar","data-test-value":d,role:"radiogroup","aria-labelledby":s,"aria-describedby":i},Object(l.omit)(f,"onChange")),o.a.createElement(x.Provider,{value:m},v))}}])&&I(t.prototype,n),u}(r.Component);B(z,"propTypes",N),B(z,"defaultProps",{appearance:"default",error:!1,inline:!1}),B(z,"Option",S);var F=Object(s.withSplunkTheme)(z);F.propTypes=z.propTypes,F.Option=S;var $=F},16:function(e,t){e.exports=n(6416)},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)},4:function(e,t){e.exports=n(5220)},8:function(e,t){e.exports=n(6493)},9:function(e,t){e.exports=n(2916)}})},8566:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=173)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},10:function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},103:function(e,t){e.exports=n(5101)},104:function(e,t){e.exports=n(5414)},13:function(e,t){e.exports=n(2725)},173:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return L}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(5),s=n(103),u=n(13),p=n.n(u),f=n(3),d=n.n(f),b=n(104),h=n.n(b),v=n(0),y=d.a.div.withConfig({displayName:"ResultsMenuStyles__Styled",componentId:"avbhl8-0"})(["",";flex-direction:column;max-height:calc(100vh - 20px);",""],v.mixins.reset("flex"),Object(v.pick)({prisma:Object(f.css)(["border-radius:",";background-color:",";"],v.variables.borderRadius,v.variables.backgroundColorPopup)})),m=d.a.div.withConfig({displayName:"ResultsMenuStyles__StyledFooter",componentId:"avbhl8-1"})(["padding:",";color:",";",""],Object(v.pick)({prisma:{comfortable:"10px 16px",compact:"6px 16px"},enterprise:"6px 10px"}),Object(v.pick)({prisma:v.variables.contentColorMuted,enterprise:v.variables.textGray}),(function(e){return"above"===e.$placement?Object(v.pick)({prisma:Object(f.css)(["border-bottom:1px solid ",";"],v.variables.neutral200),enterprise:Object(f.css)(["border-bottom:",";"],v.variables.border)}):Object(v.pick)({prisma:Object(f.css)(["border-top:1px solid ",";"],v.variables.neutral200),enterprise:Object(f.css)(["border-top:",";"],v.variables.border)})})),g=d.a.li.withConfig({displayName:"ResultsMenuStyles__StyledLoading",componentId:"avbhl8-2"})(["",";padding:",";"],v.mixins.reset("flex"),Object(v.pick)({prisma:{comfortable:"10px 16px",compact:"6px 16px"},enterprise:"6px 10px"})),O=d()(h.a).withConfig({displayName:"ResultsMenuStyles__StyledWait",componentId:"avbhl8-3"})(["margin-right:",";flex:0 0 auto;"],v.variables.spacingQuarter),x=d.a.div.withConfig({displayName:"ResultsMenuStyles__StyledLoadingMessage",componentId:"avbhl8-4"})(["flex:1 0 0;color:",";"],Object(v.pick)({prisma:v.variables.contentColorMuted,enterprise:v.variables.textGray})),j=n(10);function w(e){return w="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},w(e)}function C(){return C=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},C.apply(this,arguments)}function S(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function k(e,t){return k=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},k(e,t)}function P(e,t){return!t||"object"!==w(t)&&"function"!=typeof t?E(e):t}function E(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function _(e){return _=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},_(e)}function T(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var D={animateLoading:i.a.bool,children:i.a.node,controlledExternally:i.a.bool,childrenStart:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),footerMessage:i.a.node,isLoading:i.a.bool,loadingMessage:i.a.node,maxHeight:i.a.number,noOptionsMessage:i.a.node,onScroll:i.a.func,onScrollBottom:i.a.func,placement:i.a.string},I={animateLoading:!1,isLoading:!1,loadingMessage:Object(c._)("Loading..."),noOptionsMessage:Object(c._)("No matches")},R=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&k(e,t)}(f,e);var t,n,a,i,c=(a=f,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=_(a);if(i){var n=_(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return P(this,e)});function f(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,f),T(E(t=c.call(this,e)),"scrollBottomOffset",void 0),T(E(t),"itemMinHeight",void 0),T(E(t),"handleMenuMount",(function(e){t.setState({menuEl:e})})),T(E(t),"handleMount",(function(e){t.setState({containerEl:e}),Object(j.a)(t.props.elementRef,e)})),T(E(t),"handleMouseEnter",(function(){t.setState({windowTop:document.documentElement.scrollTop})})),T(E(t),"handleMouseLeave",(function(){t.setState({windowTop:document.documentElement.scrollTop})})),T(E(t),"handleScroll",(function(e){var n,r;if(null!=t.props.onScrollBottom&&e.target&&t.state.menuEl){var o=t.state.menuEl.scrollHeight-t.state.menuEl.offsetHeight-t.scrollBottomOffset;t.state.menuEl.scrollTop+1>=o&&t.handleScrollBottom(e)}null===(n=(r=t.props).onScroll)||void 0===n||n.call(r,e)})),T(E(t),"handleWheelMenu",(function(e){e.stopPropagation(),document.documentElement.scrollTop=t.state.windowTop})),T(E(t),"handleScrollBottomOnFullMenu",(function(){var e=r.Children.count(t.props.children),n=t.state,o=n.childrenCount,a=n.menuMaxHeight;t.checkFullHeight()&&t.handleScrollBottom(null),a&&null!=e&&e!==o&&t.setState({numberOfItemsLoaded:e-(null!=o?o:0),scrollBottomTriggered:!1}),e!==o&&t.setState({childrenCount:e})})),t.state={containerEl:null,menuEl:null,menuMaxHeight:void 0,numberOfItemsLoaded:0,scrollBottomTriggered:!1,windowTop:0},t.scrollBottomOffset=400,t.itemMinHeight=28,t}return t=f,(n=[{key:"componentDidUpdate",value:function(){var e=this.state,t=e.containerEl,n=e.menuEl,r=e.menuMaxHeight;if(s.isIE11&&t&&n){if(this.props.maxHeight){var o=t.scrollHeight-n.clientHeight,a=this.props.maxHeight-o;(void 0===r||Math.abs(r-a)>1)&&this.setState({menuMaxHeight:a})}this.props&&this.props.onScrollBottom&&this.props.children&&this.handleScrollBottomOnFullMenu()}}},{key:"handleScrollBottom",value:function(e){var t,n;this.state.scrollBottomTriggered||(this.setState({scrollBottomTriggered:!0}),null===(t=(n=this.props).onScrollBottom)||void 0===t||t.call(n,e))}},{key:"checkFullHeight",value:function(){var e=this.state.menuEl;return e&&e.scrollHeight===e.offsetHeight}},{key:"renderFooterMessage",value:function(){return this.props.footerMessage&&!!r.Children.toArray(this.props.children).length&&o.a.createElement(m,{$placement:this.props.placement,"data-test":"footer-message",key:"footer"},this.props.footerMessage)}},{key:"render",value:function(){var e=this.props,t=e.animateLoading,n=e.children,a=e.controlledExternally,i=e.childrenStart,c=e.isLoading,s=e.loadingMessage,d=e.noOptionsMessage,b=e.onScrollBottom,h=e.placement,v=e.style,m=e.tabIndex,j=Object(l.omit)(this.props,Object(l.keys)(f.propTypes)),w=r.Children.toArray(n).filter(r.isValidElement).some((function(e){var t=e.type;return!(t===u.Divider&&t.filterFirst||(t===u.Divider||t===u.Heading)&&(t.filterLast||t.filterConsecutive))})),S=this.checkFullHeight();return o.a.createElement(y,C({key:"wrapper",style:v,ref:this.handleMount,onWheel:b?this.handleWheelMenu:void 0,onMouseEnter:b?this.handleMouseEnter:void 0,onMouseLeave:b?this.handleMouseLeave:void 0},Object(l.omit)(j,"tabIndex")),"above"!==h&&i,"above"===h&&this.renderFooterMessage(),o.a.createElement(u.MenuContext.Provider,{value:{role:"listbox"}},o.a.createElement(p.a,{key:"menu",style:{overflow:"auto",maxHeight:this.state.menuMaxHeight||"calc(100vh - 20px)",flexDirection:"column"},controlledExternally:a,elementRef:this.handleMenuMount,onScroll:this.handleScroll,stopScrollPropagation:!0,tabIndex:m},!w&&d&&!c&&o.a.createElement(p.a.Item,{"data-test":"no-results-message",disabled:!0},d),n,b&&!S&&o.a.createElement("div",{"data-test":"results-menu-bottom-spacer",style:{height:this.state.scrollBottomTriggered&&this.state.numberOfItemsLoaded*this.itemMinHeight||0}}),c&&o.a.createElement(g,null,t&&o.a.createElement(O,null),o.a.createElement(x,null,s)))),"above"!==h&&this.renderFooterMessage(),"above"===h&&i)}}])&&S(t.prototype,n),f}(r.Component);T(R,"propTypes",D),T(R,"defaultProps",I);var L=R},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)},4:function(e,t){e.exports=n(5220)},5:function(e,t){e.exports=n(6219)}})},1052:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=146)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},10:function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},146:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return z}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(34),s=n(3),u=n.n(s),p=n(0),f=n(21),d=n(15),b=n.n(d),h=n(39),v=n(10);function y(e){return y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},y(e)}function m(){return m=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},m.apply(this,arguments)}function g(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function O(e,t){return O=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},O(e,t)}function x(e,t){return!t||"object"!==y(t)&&"function"!=typeof t?j(e):t}function j(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function w(e){return w=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},w(e)}function C(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var S={children:i.a.node,defaultLeft:i.a.number,defaultTop:i.a.number,elementRef:i.a.oneOfType([i.a.func,i.a.object]),left:i.a.object,onScroll:i.a.func,stopScrollPropagation:i.a.oneOf([!0,!1,"window"]),tagName:i.a.string,top:i.a.object},k=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&O(e,t)}(c,e);var t,n,r,a,i=(r=c,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=w(r);if(a){var n=w(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return x(this,e)});function c(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,c),C(j(t=i.call(this,e)),"defaultWindowOverflowX","visible"),C(j(t),"defaultWindowOverflowY","visible"),C(j(t),"handleWheel",(function(e){var n=t.state.containerEl;if(n&&(n.clientWidth===n.scrollWidth||n.clientHeight===n.scrollHeight)){if(n.clientWidth!==n.scrollWidth){if(e.deltaX<0&&n.scrollLeft<Math.abs(e.deltaX))return n.scrollLeft=0,e.stopPropagation(),void e.preventDefault();var r=n.scrollWidth-n.clientWidth;e.deltaX&&e.deltaX+n.scrollLeft>r&&(n.scrollLeft=r,e.stopPropagation(),e.preventDefault())}if(n.clientHeight!==n.scrollHeight){if(e.deltaY<0&&n.scrollTop<Math.abs(e.deltaY))return n.scrollTop=0,e.stopPropagation(),void e.preventDefault();var o=n.scrollHeight-n.clientHeight;e.deltaY&&e.deltaY+n.scrollTop>o&&(n.scrollTop=o,e.stopPropagation(),e.preventDefault())}}})),C(j(t),"handleMount",(function(e){t.setState({containerEl:e}),Object(v.a)(t.props.elementRef,e)})),C(j(t),"handleMouseEnter",(function(){t.defaultWindowOverflowX=document.body.style.overflowX,t.defaultWindowOverflowY=document.body.style.overflowY,document.body.style.overflowX="hidden",document.body.style.overflowY="hidden"})),C(j(t),"handleMouseLeave",(function(){document.body.style.overflowX=t.defaultWindowOverflowX,document.body.style.overflowY=t.defaultWindowOverflowY})),t.state={containerEl:null},t}return t=c,(n=[{key:"componentDidUpdate",value:function(e,t){var n,r;this.state.containerEl&&(t.containerEl||(this.state.containerEl.scrollTop=this.props.defaultTop,this.state.containerEl.scrollLeft=this.props.defaultLeft),Object(l.isFinite)(this.props.top)&&(this.state.containerEl.scrollTop=(null===(n=this.props.top)||void 0===n?void 0:n.get())||0),Object(l.isFinite)(this.props.left)&&(this.state.containerEl.scrollLeft=(null===(r=this.props.left)||void 0===r?void 0:r.get())||0))}},{key:"render",value:function(){var e=this.props,t=e.children,n=e.onScroll,r=e.stopScrollPropagation,a=e.top,i=e.left,s=this.state.containerEl,u=f.animated[this.props.tagName];return o.a.createElement(o.a.Fragment,null,o.a.createElement(u,m({},Object(l.omit)(this.props,Object(l.keys)(c.propTypes)),{ref:this.handleMount,onMouseEnter:"window"===r?this.handleMouseEnter:void 0,onMouseLeave:"window"===r?this.handleMouseLeave:void 0,onScroll:n,scrollTop:a,scrollLeft:i}),o.a.createElement(h.ScrollContainerProvider,{value:s},t)),!0===r&&s&&o.a.createElement(b.a,{target:s,eventType:"wheel",listener:this.handleWheel,options:{passive:!1}}))}}])&&g(t.prototype,n),c}(r.Component);C(k,"propTypes",S),C(k,"defaultProps",{defaultLeft:0,defaultTop:0,tagName:"div"});var P=k,E=u()(P).withConfig({displayName:"ScrollStyles__StyledInner",componentId:"sc-1xspttf-0"})(["",";overflow:auto;overflow-y:auto;overflow-x:hidden;"],p.mixins.reset("block"));function _(e){return _="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},_(e)}function T(){return T=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},T.apply(this,arguments)}function D(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function I(e,t){return I=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},I(e,t)}function R(e,t){return!t||"object"!==_(t)&&"function"!=typeof t?L(e):t}function L(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function A(e){return A=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},A(e)}function M(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var B={children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),left:i.a.number,onScroll:i.a.func,onScrollComplete:i.a.func,stopScrollPropagation:i.a.oneOf([!0,!1,"window"]),tagName:i.a.string,top:i.a.number},N=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&I(e,t)}(s,e);var t,n,r,a,i=(r=s,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=A(r);if(a){var n=A(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return R(this,e)});function s(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,s),M(L(t=i.call(this,e)),"handleRest",(function(){var e,n;null===(e=(n=t.props).onScrollComplete)||void 0===e||e.call(n)})),M(L(t),"handleScroll",(function(e){var n,r;t.setState({currentLeft:e.currentTarget.scrollLeft,currentTop:e.currentTarget.scrollTop}),null===(n=(r=t.props).onScroll)||void 0===n||n.call(r,e)})),M(L(t),"renderInner",(function(e){var n=t.props,r=n.children,a=n.elementRef,i=n.left,c=n.top,s=(n.onScrollComplete,function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(n,["children","elementRef","left","top","onScrollComplete"]));return o.a.createElement(E,T({"data-test":"scroll"},s,{key:"inner",top:Object(l.isFinite)(c)?e.top:void 0,left:Object(l.isFinite)(i)?e.left:void 0,elementRef:a,onScroll:t.handleScroll}),r)})),t.state={currentLeft:0,currentTop:0},t}return t=s,(n=[{key:"render",value:function(){var e=this.props,t=e.left,n=e.top,r=this.state,a=r.currentLeft,i=r.currentTop,s={};return Object(l.isFinite)(t)?s.left=t:s.left=a,Object(l.isFinite)(n)?s.top=n:s.top=i,o.a.createElement(c.Spring,{from:{left:0,top:0},to:s,onRest:this.handleRest,config:{precision:10}},this.renderInner)}}])&&D(t.prototype,n),s}(r.Component);M(N,"propTypes",B),M(N,"defaultProps",{stopScrollPropagation:!1,tagName:"div"});var z=N},15:function(e,t){e.exports=n(9213)},2:function(e,t){e.exports=n(7294)},21:function(e,t){e.exports=n(9920)},3:function(e,t){e.exports=n(2788)},34:function(e,t){e.exports=n(2640)},39:function(e,t){e.exports=n(7009)},4:function(e,t){e.exports=n(5220)}})},6521:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=176)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},11:function(e,t){e.exports=n(9726)},13:function(e,t){e.exports=n(2725)},16:function(e,t){e.exports=n(6416)},176:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return R})),n.d(t,"Divider",(function(){return s.a})),n.d(t,"Heading",(function(){return s.b})),n.d(t,"Option",(function(){return j}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(5),s=n(46),u=n(30);function p(e){return p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},p(e)}function f(){return f=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},f.apply(this,arguments)}function d(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function b(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function h(e,t){return h=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},h(e,t)}function v(e,t){return!t||"object"!==p(t)&&"function"!=typeof t?y(e):t}function y(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function m(e){return m=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},m(e)}function g(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var O={active:i.a.bool,children:i.a.node,description:i.a.string,descriptionPosition:i.a.oneOf(["right","bottom"]),disabled:i.a.bool,hidden:i.a.bool,icon:i.a.node,label:i.a.string.isRequired,matchRanges:i.a.arrayOf(i.a.shape({start:i.a.number.isRequired,end:i.a.number.isRequired})),onClick:i.a.func,selected:i.a.bool,truncate:i.a.bool,value:i.a.oneOfType([i.a.string,i.a.number,i.a.bool]).isRequired},x=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&h(e,t)}(l,e);var t,n,r,a,i=(r=l,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=m(r);if(a){var n=m(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return v(this,e)});function l(){var e;d(this,l);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return g(y(e=i.call.apply(i,[this].concat(n))),"c",null),g(y(e),"handleMount",(function(t){e.c=t})),e}return t=l,(n=[{key:"scrollIntoViewIfNeeded",value:function(){var e;null===(e=this.c)||void 0===e||e.scrollIntoViewIfNeeded()}},{key:"focus",value:function(){var e;null===(e=this.c)||void 0===e||e.focus()}},{key:"render",value:function(){return o.a.createElement(u.a,f({},this.props,{multiple:!1,ref:this.handleMount}),this.props.children||this.props.label)}}])&&b(t.prototype,n),l}(r.PureComponent);g(x,"propTypes",O),g(x,"defaultProps",{active:!1,descriptionPosition:"bottom",disabled:!1,hidden:!1,selected:!1,truncate:!1});var j=x;function w(e){return w="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},w(e)}function C(){return C=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},C.apply(this,arguments)}function S(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function k(e,t){return k=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},k(e,t)}function P(e,t){return!t||"object"!==w(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function E(e){return E=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},E(e)}function _(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var T={allowKeyMatching:i.a.bool,animateLoading:i.a.bool,appearance:i.a.oneOf(["default","link","primary","pill","toggle","flat"]),append:i.a.bool,children:i.a.node,defaultPlacement:i.a.oneOf(["above","below","vertical"]),defaultValue:i.a.oneOfType([i.a.string,i.a.number,i.a.bool]),describedBy:i.a.string,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),error:i.a.bool,filter:i.a.oneOf([!1,!0,"controlled"]),footerMessage:i.a.node,inline:i.a.bool,inputId:i.a.string,inputRef:i.a.oneOfType([i.a.func,i.a.object]),isLoadingOptions:i.a.bool,labelledBy:i.a.string,labelText:i.a.string,loadingMessage:i.a.node,menuStyle:i.a.object,name:i.a.string,noOptionsMessage:i.a.node,onChange:i.a.func,onClose:i.a.func,onFilterChange:i.a.func,onOpen:i.a.func,onScroll:i.a.func,onScrollBottom:i.a.func,placeholder:i.a.string,prefixLabel:i.a.string,prepend:i.a.bool,suffixLabel:i.a.string,value:i.a.oneOfType([i.a.string,i.a.number,i.a.bool])},D={allowKeyMatching:!0,animateLoading:!1,appearance:"toggle",append:!1,children:[],defaultPlacement:"vertical",disabled:!1,error:!1,filter:!1,inline:!0,isLoadingOptions:!1,menuStyle:{},noOptionsMessage:Object(c._)("No matches"),placeholder:Object(c._)("Select..."),prepend:!1},I=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&k(e,t)}(c,e);var t,n,r,a,i=(r=c,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=E(r);if(a){var n=E(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return P(this,e)});function c(e){var t;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,c),t=i.call(this,e);var n={};return Object(l.has)(e,"defaultValue")&&(null!=e.defaultValue?n.defaultValues=[e.defaultValue]:n.defaultValues=[]),t.state=n,t}return t=c,(n=[{key:"componentDidUpdate",value:function(e){}},{key:"render",value:function(){var e=this.props,t=(e.defaultValue,e.onChange),n=e.value,r=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["defaultValue","onChange","value"]),a={onChange:function(e,n){var r=n.name,o=n.values;null==t||t(e,{name:r,value:o[0]})}};return Object(l.has)(this.props,"value")?a.values=null!=n?[n]:[]:null!=this.state.defaultValues&&(a.defaultValues=this.state.defaultValues),o.a.createElement(s.c,C({},r,a,{multiple:!1}))}}])&&S(t.prototype,n),c}(r.Component);_(I,"propTypes",T),_(I,"defaultProps",D),_(I,"Option",j),_(I,"Heading",s.b),_(I,"Divider",s.a);var R=I},2:function(e,t){e.exports=n(7294)},20:function(e,t){e.exports=n(6635)},24:function(e,t){e.exports=n(6401)},26:function(e,t){e.exports=n(583)},3:function(e,t){e.exports=n(2788)},30:function(e,t,n){"use strict";var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(13);function c(e){return c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c(e)}function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function p(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function f(e,t){return f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},f(e,t)}function d(e,t){return!t||"object"!==c(t)&&"function"!=typeof t?b(e):t}function b(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function h(e){return h=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},h(e)}function v(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var y={active:i.a.bool,children:i.a.node,description:i.a.string,descriptionPosition:i.a.oneOf(["right","bottom"]),disabled:i.a.bool,hidden:i.a.bool,icon:i.a.node,label:i.a.string.isRequired,multiple:i.a.bool,matchRanges:i.a.arrayOf(i.a.shape({start:i.a.number.isRequired,end:i.a.number.isRequired})),onClick:i.a.func,selected:i.a.bool,truncate:i.a.bool,value:i.a.oneOfType([i.a.string,i.a.number,i.a.bool]).isRequired},m=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}(c,e);var t,n,r,a,i=(r=c,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=h(r);if(a){var n=h(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return d(this,e)});function c(){var e;u(this,c);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return v(b(e=i.call.apply(i,[this].concat(n))),"c",null),v(b(e),"handleClick",(function(t){var n=e.props,r=n.onClick,o=n.value;n.disabled||null==r||r(t,{value:o})})),v(b(e),"handleMount",(function(t){e.c=t})),e}return t=c,(n=[{key:"scrollIntoViewIfNeeded",value:function(){var e;null===(e=this.c)||void 0===e||e.scrollIntoViewIfNeeded()}},{key:"focus",value:function(){var e;null===(e=this.c)||void 0===e||e.focus()}},{key:"render",value:function(){var e=this.props,t=e.value,n=e.children,r=e.label,a=e.multiple,i=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["value","children","label","multiple"]);return o.a.createElement(l.Item,s({"aria-selected":this.props.selected,"data-test-value":t,"data-test":"option",ref:this.handleMount},i,{selectable:!0,selectableAppearance:a?"checkbox":void 0,onClick:this.handleClick,role:"option",value:t.toString()}),n||r)}}])&&p(t.prototype,n),c}(r.PureComponent);v(m,"propTypes",y),v(m,"defaultProps",{descriptionPosition:"bottom",disabled:!1,multiple:!1,selected:!1,truncate:!1}),t.a=m},31:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(43),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M10.5,3.0015 C14.6421,3.0015 18,6.3593 18,10.5015 C18,12.2112 17.4279,13.7873 16.4647,15.0489 L20.7077,19.292 C21.0983,19.6825 21.0983,20.3156 20.7077,20.7062 C20.3172,21.0967 19.6841,21.0967 19.2935,20.7062 L15.0509,16.4635 C13.7888,17.4283 12.2113,18.0015 10.5,18.0015 C6.3579,18.0015 3,14.6436 3,10.5015 C3,6.3593 6.3579,3.0015 10.5,3.0015 Z M10.5,5.0015 C7.4624,5.0015 5,7.4639 5,10.5015 C5,13.539 7.4624,16.0015 10.5,16.0015 C13.5376,16.0015 16,13.539 16,10.5015 C16,7.4639 13.5376,5.0015 10.5,5.0015 Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M6.85277,2.0015 C9.53288,2.0015 11.7055,4.1741 11.7055,6.8542 C11.7055,7.8463 11.4079,8.7688 10.897,9.5373 L10.9245,9.5098 L14.0018,12.5871 L12.5876,14.0014 L9.51025,10.924 L9.53587,10.8984 C8.76733,11.4093 7.84481,11.707 6.85277,11.707 C4.17266,11.707 2,9.5343 2,6.8542 C2,4.1741 4.17266,2.0015 6.85277,2.0015 Z M6.85277,4.0015 C5.27723,4.0015 4,5.2787 4,6.8542 C4,8.4298 5.27723,9.707 6.85277,9.707 C8.42831,9.707 9.70554,8.4298 9.70554,6.8542 C9.70554,5.2787 8.42831,4.0015 6.85277,4.0015 Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},33:function(e,t){e.exports=n(6206)},36:function(e,t){e.exports=n(8566)},4:function(e,t){e.exports=n(5220)},40:function(e,t,n){"use strict";n.d(t,"a",(function(){return p}));var r=n(2),o=n.n(r),a=n(41),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M7.2788 9.00002C6.84609 9.00002 6.61768 9.51239 6.90691 9.83423L11.4078 14.8426C11.6065 15.0637 11.953 15.0636 12.1517 14.8425L16.6499 9.8341C16.939 9.51223 16.7106 9 16.2779 9L7.2788 9.00002Z",fill:"currentColor"}))}function p(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma24:u},e))}},41:function(e,t){e.exports=n(7924)},43:function(e,t){e.exports=n(8044)},46:function(e,t,n){"use strict";n.d(t,"a",(function(){return v.Divider})),n.d(t,"b",(function(){return v.Heading})),n.d(t,"d",(function(){return te}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(26),s=n(11),u=n(5),p=n(9),f=n(20),d=n.n(f),b=n(33),h=n.n(b),v=n(13),y=n(36),m=n.n(y),g=n(24),O=n.n(g),x=n(40),j=n(31),w=n(30),C=n(3),S=n.n(C),k=n(16),P=n.n(k),E=n(0),_=S()(P.a).withConfig({displayName:"SelectBaseStyles__StyledButton",componentId:"sc-16cj7sk-0"})(["&[data-inline]{width:",";}",""],(function(e){return e.$multiple?"400px":"auto"}),(function(e){return!e.$multiple&&"flex-grow: 0;"})),T=S.a.span.withConfig({displayName:"SelectBaseStyles__StyledLinkIcon",componentId:"sc-16cj7sk-1"})(["padding-right:2px;"]),D=S.a.span.withConfig({displayName:"SelectBaseStyles__StyledLinkCaret",componentId:"sc-16cj7sk-2"})(["padding-left:2px;"]),I=S.a.div.withConfig({displayName:"SelectBaseStyles__StyledFilter",componentId:"sc-16cj7sk-3"})(["padding:",";min-width:160px;"],Object(E.pick)({enterprise:"8px",prisma:"10px 16px"})),R=S.a.span.withConfig({displayName:"SelectBaseStyles__StyledSearchIconWrapper",componentId:"sc-16cj7sk-4"})(["color:",";pointer-events:none;padding:",";"],Object(E.pick)({enterprise:{light:E.variables.gray60,dark:E.variables.white},prisma:E.variables.contentColorMuted}),Object(E.pick)({comfortable:"0 8px",compact:"0 6px"})),L=S.a.span.withConfig({displayName:"SelectBaseStyles__StyledCount",componentId:"sc-16cj7sk-5"})(["padding-right:",";"],Object(E.pick)({enterprise:E.variables.spacingQuarter,prisma:E.variables.spacingXSmall})),A=S()(h.a).withConfig({displayName:"SelectBaseStyles__StyledControlsLink",componentId:"sc-16cj7sk-6"})(["",";"],(function(e){return e.$disabled&&Object(C.css)(["color:",";"],E.variables.contentColorDisabled)})),M=S.a.div.withConfig({displayName:"SelectBaseStyles__StyledToggleAllControls",componentId:"sc-16cj7sk-7"})(["padding:",";",""],Object(E.pick)({enterprise:"5px 8px",prisma:"10px 16px"}),Object(E.pickVariant)("$placement",{above:{enterprise:Object(C.css)(["border-top:",";"],E.variables.border),prisma:Object(C.css)(["border-top:1px solid ",";"],E.variables.neutral200)},below:{enterprise:Object(C.css)(["border-bottom:",";"],E.variables.border),prisma:Object(C.css)(["border-bottom:1px solid ",";"],E.variables.neutral200)}})),B=function(e,t){return e?e.label.charAt(t).toLowerCase():""},N=function(e,t){if(!e.length)return e;var n=null,r=!1,o=e.filter((function(e){var o=B(e,t.index);if(o===t.value)return r=!0,!0;if(!r){var a=B(n,t.index);a?o>t.value?(a<t.value||a>o)&&(n=e):o>a&&(n=e):n=e}return!1}));return 0===o.length&&n?[n]:o};function z(e){return z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},z(e)}function F(){return F=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},F.apply(this,arguments)}function $(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function H(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?$(Object(n),!0).forEach((function(t){Q(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):$(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function V(e){return function(e){if(Array.isArray(e))return W(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||q(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function q(e,t){if(e){if("string"==typeof e)return W(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?W(e,t):void 0}}function W(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function K(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function U(e,t,n){return t&&K(e.prototype,t),n&&K(e,n),e}function Z(e,t){return Z=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},Z(e,t)}function G(e,t){return!t||"object"!==z(t)&&"function"!=typeof t?X(e):t}function X(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function Y(e){return Y=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},Y(e)}function Q(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var J={allowKeyMatching:i.a.bool,allowNewValues:i.a.bool,animateLoading:i.a.bool,appearance:i.a.oneOf(["default","link","primary","pill","toggle","flat"]),append:i.a.bool,children:i.a.node,defaultPlacement:i.a.oneOf(["above","below","vertical"]),defaultValues:i.a.array,describedBy:i.a.string,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),error:i.a.bool,filter:i.a.oneOf([!1,!0,"controlled"]),footerMessage:i.a.node,inline:i.a.bool,inputId:i.a.string,inputRef:i.a.oneOfType([i.a.func,i.a.object]),isLoadingOptions:i.a.bool,labelledBy:i.a.string,labelText:i.a.string,loadingMessage:i.a.node,menuStyle:i.a.object,multiple:i.a.bool,name:i.a.string,noOptionsMessage:i.a.node,onChange:i.a.func,onClose:i.a.func,onFilterChange:i.a.func,onOpen:i.a.func,onScroll:i.a.func,onScrollBottom:i.a.func,placeholder:i.a.string,prefixLabel:i.a.string,prepend:i.a.bool,repositionMode:i.a.oneOf(["none","flip"]),showSelectedValuesFirst:i.a.oneOf(["nextOpen","immediately","never"]),suffixLabel:i.a.string,tabConfirmsNewValue:i.a.bool,values:i.a.array},ee={allowKeyMatching:!0,allowNewValues:!1,animateLoading:!1,appearance:"toggle",append:!1,defaultPlacement:"vertical",disabled:!1,filter:!1,inline:!1,isLoadingOptions:!1,menuStyle:{},multiple:!1,noOptionsMessage:Object(u._)("No matches"),placeholder:Object(u._)("Select..."),prepend:!1,repositionMode:"flip",tabConfirmsNewValue:!1};function te(e){return e&&Object(l.has)(e.props,"value")}var ne=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&Z(e,t)}(i,e);var t,n,a=(t=i,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=Y(t);if(n){var o=Y(this).constructor;e=Reflect.construct(r,arguments,o)}else e=r.apply(this,arguments);return G(this,e)});function i(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,i),Q(X(t=a.call(this,e)),"activeItemId",void 0),Q(X(t),"activeValue",void 0),Q(X(t),"availableOptionCount",void 0),Q(X(t),"controlledExternally",void 0),Q(X(t),"displayedValues",void 0),Q(X(t),"dropdown",null),Q(X(t),"firstSelectedEnabledOption",null),Q(X(t),"firstSelectedOptionIndex",void 0),Q(X(t),"menuId",void 0),Q(X(t),"previousActiveIndex",null),Q(X(t),"selectedOptionCount",void 0),Q(X(t),"optionRefsByKey",void 0),Q(X(t),"matchCharacter",void 0),Q(X(t),"matchTimeout",void 0),Q(X(t),"currentMatchOptions",void 0),Q(X(t),"availableMatchOptions",void 0),Q(X(t),"resetMatches",(function(){t.matchCharacter=null,t.currentMatchOptions=[],t.matchTimeout&&clearTimeout(t.matchTimeout)})),Q(X(t),"handleSelectAll",(function(e){var n,r,a,i=t.props,c=i.name,s=i.children;if(i.multiple){var u=null!==(n=t.getCurrentValues())&&void 0!==n?n:[],p=Object(l.uniq)(u.concat(t.displayedValues));p=o.a.Children.toArray(s).filter((function(e){return te(e)&&Object(l.includes)(p,e.props.value)&&(!e.props.disabled||Object(l.includes)(u,e.props.value))})).map((function(e){return e.props.value})),t.isControlled()||t.setState({values:p}),null===(r=(a=t.props).onChange)||void 0===r||r.call(a,e,{values:p,name:c})}})),Q(X(t),"handleClearAll",(function(e){var n,r,a,i=t.props,c=i.name,s=i.children;if(i.multiple){var u=null!==(n=t.getCurrentValues())&&void 0!==n?n:[],p=l.without.apply(void 0,[u].concat(V(t.displayedValues))),f=o.a.Children.toArray(s).filter((function(e){return te(e)&&(Object(l.includes)(u,e.props.value)&&e.props.disabled||Object(l.includes)(p,e.props.value))})).map((function(e){return e.props.value}));t.isControlled()||t.setState({values:f}),null===(r=(a=t.props).onChange)||void 0===r||r.call(a,e,{values:f,name:c})}})),Q(X(t),"handleTextKeyDown",(function(e){var n=t.props,o=n.children,a=n.onScrollBottom,i=n.tabConfirmsNewValue,c=Object(p.keycode)(e.nativeEvent);if("tab"===c&&i&&!Object(l.isUndefined)(t.activeValue)&&t.availableOptionCount<=1&&(e.preventDefault(),t.toggleValue(e,t.activeValue)),!(e.shiftKey||e.metaKey||e.ctrlKey)){if("down"===c&&(e.preventDefault(),t.setState((function(e){return{activeIndex:Math.min(e.activeIndex+1,t.availableOptionCount-1)}})),o&&a)){var s,u=r.Children.toArray(o).length-(2+(null!==(s=t.getCurrentValues())&&void 0!==s?s:[]).length);t.state.activeIndex===u&&t.handleScrollBottom(e)}"up"===c&&(e.preventDefault(),t.setState((function(e){return{activeIndex:Math.max(e.activeIndex-1,0)}}))),"enter"===c&&!Object(l.isUndefined)(t.activeValue)&&t.state.open&&(e.preventDefault(),t.toggleValue(e,t.activeValue))}})),Q(X(t),"handleMenuOptionClick",(function(e,n){var r=n.value;e.preventDefault(),t.state.open&&t.toggleValue(e,r)})),Q(X(t),"handleMenuOptionKeyDown",(function(e,n){var r=e.nativeEvent.key;if(1===r.length){var o=[],a={index:0,value:r};if(t.matchCharacter)t.currentMatchOptions.length>1&&(a.index=t.matchCharacter.index+1,o=N(t.currentMatchOptions,a));else{if(" "===r)return void t.resetMatches();o=N(t.availableMatchOptions,a)}if(o.length){var i=0;if(0===a.index&&o.length>1){var l=o.indexOf(t.availableMatchOptions[n]);l>=0&&(i=l===o.length-1?0:l+1)}var c,s=t.optionRefsByKey[o[i].itemKey];null!=s&&(null==s||null===(c=s.focus)||void 0===c||c.call(s))}t.currentMatchOptions=o,t.matchCharacter=a,t.matchTimeout&&clearTimeout(t.matchTimeout),t.matchTimeout=setTimeout(t.resetMatches,500),e.preventDefault(),e.stopPropagation()}})),Q(X(t),"handleTextChange",(function(e,n){var r,o,a=n.value;t.setState({filterKeyword:a,open:!0,activeIndex:0}),null===(r=(o=t.props).onFilterChange)||void 0===r||r.call(o,e,{keyword:a})})),Q(X(t),"handleTextFocus",(function(){t.setState({textHasFocus:!0})})),Q(X(t),"handleTextBlur",(function(){t.setState({textHasFocus:!1})})),Q(X(t),"handleRequestOpen",(function(e){var n={open:!0,topValues:t.getTopValues()};t.props.multiple&&(n.filterKeyword="");var r=t.state.filterKeyword;t.setState(n,(function(){var n,o,a,i,l;null===(n=(o=t.props).onOpen)||void 0===n||n.call(o),t.firstSelectedEnabledOption&&!t.hasFilter()?t.firstSelectedEnabledOption.focus():t.setState({activeIndex:null!==(a=t.firstSelectedOptionIndex)&&void 0!==a?a:0}),r!==t.state.filterKeyword&&(null===(i=(l=t.props).onFilterChange)||void 0===i||i.call(l,e,{keyword:t.state.filterKeyword}))}))})),Q(X(t),"handleRequestClose",(function(){t.setState({open:!1,activeIndex:0},(function(){var e,n;t.previousActiveIndex=null,null===(e=(n=t.props).onClose)||void 0===e||e.call(n)}))})),Q(X(t),"handleScrollBottom",(function(e){var n,r;t.state.open&&!t.props.isLoadingOptions&&(null===(n=(r=t.props).onScrollBottom)||void 0===n||n.call(r,e))})),Q(X(t),"handleActiveOptionMount",(function(e){t.previousActiveIndex!==t.state.activeIndex&&(null==e||e.scrollIntoViewIfNeeded())})),Q(X(t),"handleOptionMount",(function(e,n,r){r&&(t.firstSelectedEnabledOption=e),null==e?delete t.optionRefsByKey[n]:t.optionRefsByKey[n]=e})),Q(X(t),"createChildren",(function(){var e,n=t.state,a=n.filterKeyword,i=n.textHasFocus,s=n.topValues,u=t.props,p=u.allowKeyMatching,f=u.allowNewValues,d=u.filter,b=u.multiple,h=u.showSelectedValuesFirst,y=u.isLoadingOptions,m=u.onScrollBottom,g=t.getCurrentValues();t.availableOptionCount=0,t.firstSelectedOptionIndex=void 0,t.selectedOptionCount=0,t.activeValue=void 0,t.availableMatchOptions=[];var O,x=0,j=!1,C="immediately"===h?t.getTopValues():s,S=r.Children.toArray(t.props.children).reduce((function(n,a,i){if(!te(a))return n.push(a),n;a.props.value===t.state.filterKeyword&&(e=!0);var l=g&&g.indexOf(a.props.value)>=0,c=!!l&&!a.props.disabled&&!O,s=p&&!b&&!d&&!y&&!m,u="".concat(a.props.label,"-").concat(a.props.value),f=-1;!s||a.props.disabled||a.props.hidden||(t.availableMatchOptions.push({itemKey:u,label:a.props.label,value:a.props.value}),f=t.availableMatchOptions.length-1);var h=Object(r.cloneElement)(a,{key:a.key||i,onClick:t.handleMenuOptionClick,onKeyDown:s?function(e){return t.handleMenuOptionKeyDown(e,f)}:void 0,selected:l,multiple:b,role:"option",ref:function(e){return t.handleOptionMount(e,u,c)}});return c&&(O=!0),C&&C.indexOf(a.props.value)>=0?(0===x&&(n.splice(x,0,o.a.createElement(v.Divider,{key:"topDivider"})),j=!0),n.splice(x,0,h),x+=1):n.push(h),n}),[]);b&&Object(l.forEachRight)(g,(function(n){if(!Object(l.find)(S,(function(e){return te(e)&&e.props&&e.props.value===n}))){n===t.state.filterKeyword&&(e=!0);var r=C&&C.indexOf(n)>=0,a=C.length;0===x&&(S.splice(0,0,o.a.createElement(v.Divider,{key:"topDivider"})),x+=1,j=!0),S.splice(r?0:a+1,0,o.a.createElement(w.a,{label:String(n),value:n,key:"missing-value-".concat(n),onClick:t.handleMenuOptionClick,multiple:b,selected:!0})),r&&(x+=1)}}));var k="controlled"===d,P=Object(c.stringToKeywords)(a);if(S=k?S:S.filter((function(e){return!te(e)||Object(c.testPhrase)(e.props.label,P)})).map((function(e){if(!te(e))return e;var t=P&&Object(c.keywordLocations)(e.props.label,P);return Object(r.cloneElement)(e,{matchRanges:t||void 0})})),f&&!e&&a){var E=j?x+1:x;S.splice(E,0,o.a.createElement(w.a,{label:"".concat(a," (new value)"),value:a,key:"newValue",multiple:b,onClick:t.handleMenuOptionClick}))}return S=S.reduce((function(e,n){if(!te(n))return e.push(n),e;if(n.props&&n.props.hidden)return e;n.props.selected&&!n.props.disabled&&null==t.firstSelectedOptionIndex&&(t.firstSelectedOptionIndex=t.availableOptionCount);var o=t.availableOptionCount===t.state.activeIndex;if(t.availableOptionCount+=1,t.selectedOptionCount+=n.props.selected?1:0,!o||!i)return e.push(n),e;n.props.disabled||(t.activeValue=n.props.value);var a=Object(r.cloneElement)(n,{active:o,id:t.activeItemId,ref:t.handleActiveOptionMount});return e.push(a),e}),[]),t.displayedValues=S.reduce((function(e,t){return te(t)&&e.push(t.props.value),e}),[]),S})),Q(X(t),"wrapLabel",(function(e){var t=e.prefixLabel,n=e.label,r=e.suffixLabel,o=n;return t&&(o=["".concat(t,": ")].concat(o)),r&&(o=Object(l.castArray)(o).concat(" ".concat(r))),o})),t.state={activeIndex:0,filterKeyword:"",open:!1,textHasFocus:!1,topValues:[],values:e.defaultValues||[]},t.controlledExternally=Object(l.has)(e,"values"),t.displayedValues=[],t.availableOptionCount=0,t.firstSelectedOptionIndex=void 0,t.selectedOptionCount=0,t.matchCharacter=null,t.matchTimeout=null,t.currentMatchOptions=[],t.availableMatchOptions=[],t.optionRefsByKey={},i.validateAppearance(e),t.menuId=Object(s.createDOMID)("menu"),t.activeItemId=Object(s.createDOMID)("active-item"),t}return U(i,null,[{key:"validateAppearance",value:function(e){}}]),U(i,[{key:"componentDidUpdate",value:function(e,t){i.validateAppearance(this.props),this.previousActiveIndex=t.activeIndex}},{key:"getCurrentValues",value:function(){var e=this.isControlled()?this.props.values:this.state.values;return this.props.multiple||null==e?e:e.slice(0,1)}},{key:"getTopValues",value:function(){var e;return this.props.multiple&&"never"!==this.props.showSelectedValuesFirst&&null!==(e=this.getCurrentValues())&&void 0!==e?e:[]}},{key:"isControlled",value:function(){return this.controlledExternally}},{key:"hasFilter",value:function(){return!!this.props.filter}},{key:"toggleValue",value:function(e,t){var n,r,o,a,i=null!==(n=this.getCurrentValues())&&void 0!==n?n:[],l=i.indexOf(t),c=this.props,s=c.name,u=c.multiple;a=u?l>=0?[].concat(V(i.slice(0,l)),V(i.slice(l+1))):i.concat([t]):[t];var p=!this.isControlled();p&&this.setState({values:a}),u?p&&this.setState({open:!0}):(this.handleRequestClose({reason:"contentClick"}),this.focus()),null===(r=(o=this.props).onChange)||void 0===r||r.call(o,e,{values:a,name:s})}},{key:"focus",value:function(){var e;null===(e=this.dropdown)||void 0===e||e.focus()}},{key:"renderControls",value:function(e){var t=e.hasChildren,n=e.placement,r=this.state.filterKeyword,a=this.props,i=a.inputId,l=a.inputRef,c=a.multiple,s=o.a.createElement(M,{$placement:n,key:"selectAll"},o.a.createElement(A,{$disabled:!(this.availableOptionCount-this.selectedOptionCount),onClick:this.handleSelectAll,"data-test":"select-all",style:{marginRight:20}},r?Object(u._)("Select All Matches"):Object(u._)("Select All")),o.a.createElement(A,{$disabled:!this.selectedOptionCount,onClick:this.handleClearAll,"data-test":"clear-all"},r?Object(u._)("Clear All Matches"):Object(u._)("Clear All")));return this.hasFilter()&&o.a.createElement("div",{key:"controls"},o.a.createElement(I,{key:"filter","data-test":"filter"},o.a.createElement(O.a,{value:r,autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",spellCheck:!1,onChange:this.handleTextChange,onKeyDown:this.handleTextKeyDown,onFocus:this.handleTextFocus,onBlur:this.handleTextBlur,placeholder:Object(u._)("filter"),role:"combobox","aria-expanded":"true","aria-label":Object(u._)("Filter"),"aria-activedescendant":this.activeItemId,"aria-controls":this.menuId,inputRef:l,inputId:i,canClear:!0,startAdornment:o.a.createElement(R,null,o.a.createElement(j.a,{role:"presentation",enterpriseSize:"16px",inline:!1,screenReaderText:Object(u._)("Search")}))})),c&&t&&s)}},{key:"render",value:function(){var e,t,n,a=this,c=this.props,s=c.appearance,p=c.children,f=c.defaultPlacement,b=c.describedBy,v=c.disabled,y=c.elementRef,g=c.error,O=c.inline,j=c.inputId,w=c.labelledBy,C=c.labelText,S=c.multiple,k=c.placeholder,P=c.prefixLabel,E=c.repositionMode,I=c.suffixLabel,R=this.hasFilter(),A=!1,M=r.Children.toArray(p),B=null!==(e=this.getCurrentValues())&&void 0!==e?e:[];(n=B.reduce((function(e,n,r,o){var a=Object(l.find)(M,(function(e){return te(e)&&e.props.value===n}));return a?(e.push(a.props.children||a.props.label),a.props.disabled||(A=!0),S||1!==B.length||(t=a.props.icon)):S&&e.push(n),r<o.length-1&&e.push(Object(u._)(", ")),e}),[])).length>0&&(n=this.wrapLabel({prefixLabel:P,label:n,suffixLabel:I})),(0===n.length||!S&&n.every((function(e){return""===e})))&&(n=[k]);var N=n;n.length>1&&(N=this.wrapLabel({prefixLabel:P,label:["".concat(B.length," items selected")],suffixLabel:I}));var z,$,V=this.createChildren(),W=H({"aria-describedby":b,"aria-label":"".concat(C?"".concat(C,", "):"").concat(N),"aria-labelledby":C?void 0:w,"aria-multiselectable":S,"data-select-appearance":s,"data-test":S?"multiselect":"select",disabled:v,elementRef:y,error:g},Object(l.omit)(this.props,Object(l.keys)(i.propTypes)));if(S)W["data-test-values"]=JSON.stringify(B);else{var K=(z=B,$=1,function(e){if(Array.isArray(e))return e}(z)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,a=void 0;try{for(var i,l=e[Symbol.iterator]();!(r=(i=l.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){o=!0,a=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw a}}return n}}(z,$)||q(z,$)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())[0];W["data-test-value"]=K}var U="link"===s?o.a.createElement(h.a,F({},W,{"data-select-appearance":"link"}),!!t&&o.a.createElement(T,null,t),n||k,o.a.createElement(D,null,o.a.createElement(x.a,{enterpriseSize:.5,prismaSize:"small"}))):o.a.createElement(_,F({},W,{$multiple:S,appearance:s,label:n,error:g,icon:t,inline:O,isMenu:!0,role:"listbox",onClick:this.props.onClick},Object(l.pick)(this.props,i.invalidLinkAppearanceProps)),!!B.length&&S&&o.a.createElement(L,{"data-role":"count"},"(",B.length,")")),Z=function(e){var t=e.anchorWidth,n=e.maxHeight,r=e.placement,i=a.props.multiple?{width:Math.max(null!=t?t:0,200)}:{minWidth:null!=t?t:void 0,maxWidth:Math.max(null!=t?t:0,300)};return o.a.createElement(m.a,F({"aria-multiselectable":S,childrenStart:a.renderControls({placement:r,hasChildren:!!V.length}),controlledExternally:a.hasFilter(),placement:null!=r?r:void 0,maxHeight:null!=n?n:void 0,onScrollBottom:a.props.onScrollBottom?a.handleScrollBottom:void 0,"data-test":"results-menu",isLoading:a.props.isLoadingOptions,id:a.menuId},Object(l.pick)(a.props,"noOptionsMessage","footerMessage","animateLoading","loadingMessage","onScroll"),{style:H(H({},i),a.props.menuStyle),tabIndex:B.length>0&&!A?0:void 0}),V)};return o.a.createElement(d.a,{closeReasons:["clickAway","escapeKey","offScreen","tabKey","toggleClick"],inputId:j,toggle:U,onRequestOpen:this.handleRequestOpen,onRequestClose:this.handleRequestClose,open:this.state.open,repositionMode:E,defaultPlacement:R?f:void 0,canCoverAnchor:window.innerHeight<500,ref:function(e){a.dropdown=e},retainFocus:!1,takeFocus:0===B.length||B.length>0&&!A||!!R},Z)}}]),i}(r.Component);Q(ne,"propTypes",J),Q(ne,"defaultProps",ee),Q(ne,"Option",w.a),Q(ne,"Divider",v.Divider),Q(ne,"Heading",v.Heading),Q(ne,"invalidLinkAppearanceProps",["append","error","prepend"]),t.c=ne},5:function(e,t){e.exports=n(6219)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var r=n(2),o=n.n(r),a=n(3);function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n.n(a).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function c(e){return o.a.createElement(l,i({xmlns:"http://www.w3.org/2000/svg"},e))}},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(0);function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}var p={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},f={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:i.a.func,enterpriseSize:i.a.oneOfType([i.a.number,i.a.string]),enterpriseWidth:i.a.oneOfType([i.a.number,i.a.string]),enterpriseHeight:i.a.oneOfType([i.a.number,i.a.string]),Prisma24:i.a.func.isRequired,Prisma20:i.a.func,Prisma16:i.a.func,prismaSize:i.a.oneOf(["medium","small"]),inline:i.a.bool,screenReaderText:i.a.string};function b(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,a=e.Prisma16,i=e.prismaSize,d=e.inline,b=e.enterpriseSize,h=e.enterpriseWidth,v=e.enterpriseHeight,y=e.screenReaderText,m=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),g=Object(l.useSplunkTheme)(),O=g.family,x=g.density;if("enterprise"===O)return o.a.createElement(t,u({size:b,width:h,height:v,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},m));var j=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?p:f},m);if("small"===i){var w=a||n;return o.a.createElement(w,u({width:"16",height:"16"},j))}if("compact"===x){var C=r||n;return o.a.createElement(C,u({width:"20",height:"20"},j))}return o.a.createElement(n,u({width:"24",height:"24"},j))}b.propTypes=d,b.defaultProps={inline:!0,prismaSize:"medium"}},9:function(e,t){e.exports=n(2916)}})},9895:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=179)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},179:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return v}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(3),c=n.n(l),s=n(8),u=n.n(s),p=n(0),f=c()(u.a).withConfig({displayName:"StaticContentStyles__StyledBox",componentId:"sxqyrp-0"})(["",";position:relative;margin:0;font-weight:",";word-wrap:break-word;min-height:",";padding:",";[data-inline] + &[data-inline]{margin-left:",";}"],p.mixins.reset("flex"),p.variables.fontWeightSemiBold,p.variables.inputHeight,Object(p.pick)({enterprise:{comfortable:"6px 7px",compact:"4px 5px"},prisma:{comfortable:"10px 0",compact:"6px 0"}}),Object(p.pick)({enterprise:p.variables.spacingQuarter,prisma:p.variables.spacingLarge}));function d(){return d=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},d.apply(this,arguments)}var b={children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),inline:i.a.bool,size:i.a.oneOf(["small","medium"])};function h(e){var t=e.children,n=e.inline,r=void 0!==n&&n,a=e.size,i=void 0===a?"medium":a,l=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","inline","size"]);return o.a.createElement(f,d({"data-test":"static-content","data-size":i,inline:r},l),t)}h.propTypes=b;var v=h},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)},8:function(e,t){e.exports=n(6493)}})},7885:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=149)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},11:function(e,t){e.exports=n(9726)},12:function(e,t){e.exports=n(5917)},14:function(e,t){e.exports=n(5766)},149:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return K}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(38),c=n.n(l),s=n(14),u=n.n(s),p=n(11),f=n(50),d=n.n(f),b=n(0);function h(){return"enterprise"===Object(b.useSplunkTheme)().family?o.a.createElement(d.a,{inline:!1,size:"12px",screenReaderText:null,hideDefaultTooltip:!0,style:{marginTop:"1px"}}):o.a.createElement("svg",{width:"12",height:"12",viewBox:"-1 -2 11 10",style:{display:"block"},xmlns:"http://www.w3.org/2000/svg"},o.a.createElement("path",{d:"M8.70711 0.292893C9.09763 0.683417 9.09763 1.31658 8.70711 1.70711L4.32132 6.0929C3.73559 6.67862 2.78596 6.67869 2.20015 6.09305L0.292997 4.18646C-0.0975845 3.79599 -0.0976776 3.16282 0.292789 2.77224C0.683256 2.38166 1.31642 2.38157 1.707 2.77203L3.26061 4.32518L7.29289 0.292893C7.68342 -0.0976311 8.31658 -0.0976311 8.70711 0.292893Z",fill:"currentColor"}))}var v=n(3),y=n.n(v),m=n(8),g=n.n(m),O=n(12),x=n.n(O),j="18px",w="20px",C=y()(g.a).withConfig({displayName:"SwitchStyles__StyledBox",componentId:"sc-844ieu-0"})(["display:inline;position:relative;color:",";flex-shrink:0;padding:",";[data-inline] + &{margin-left:",";}"],Object(b.pickVariant)("$switchState",{error:{enterprise:b.variables.errorColor,prisma:b.variables.accentColorNegative},disabled:{enterprise:b.variables.textDisabledColor,prisma:b.variables.contentColorDisabled}}),Object(b.pick)({enterprise:Object(v.css)(["calc(("," - ",") / 2) 0"],b.variables.inputHeight,j),prisma:{compact:"6px 0",comfortable:"10px 0"}}),Object(b.pick)({enterprise:b.variables.spacingHalf,prisma:b.variables.spacingSmall})),S=y()(x.a).withConfig({displayName:"SwitchStyles__StyledCheckboxClickable",componentId:"sc-844ieu-1"})([""," position:relative;width:",";height:",";line-height:",";padding:2px;border-radius:2px;cursor:pointer;flex:0 0 auto;border:",";color:",";"," &:focus{box-shadow:",";}"," "," &[disabled]{cursor:not-allowed;border-color:",";","}"],b.mixins.reset("inline"),j,j,j,Object(b.pick)({enterprise:Object(b.pick)({light:Object(v.css)(["1px solid ",""],b.variables.gray45),dark:Object(v.css)(["1px solid ",""],b.variables.gray80)}),prisma:Object(v.css)(["2px solid ",""],b.variables.contentColorMuted)}),Object(b.pick)({enterprise:Object(b.pick)({light:b.variables.gray45,dark:b.variables.gray80}),prisma:b.variables.white}),Object(b.pick)({prisma:Object(v.css)(["top:1px;padding:1px;border-radius:3px;"," ",""],(function(e){return e.$interactive&&Object(v.css)(["&:not([disabled]):not(:focus):hover{box-shadow:0 0 0 2px ",",0 0 0 5px ",";}"],b.variables.backgroundColorPage,b.variables.interactiveColorOverlayHover)}),(function(e){return!e.$selected&&Object(v.css)(["&:not([disabled]):not(:focus):hover{border-color:",";}"],b.variables.contentColorDefault)}))}),b.variables.focusShadow,(function(e){return e.$selected&&Object(v.css)(["&:not([disabled]){border-color:",";background-color:",";}"],Object(b.pick)({enterprise:{light:b.variables.gray45,dark:b.variables.gray80},prisma:b.variables.interactiveColorPrimary}),Object(b.pick)({enterprise:"#none",prisma:Object(v.css)(["",";"],b.variables.interactiveColorPrimary)}))}),(function(e){return e.$error&&Object(b.pick)({enterprise:Object(b.pick)({light:Object(v.css)(["&:not([disabled]){border-color:",";color:",";","}"],b.variables.errorColorL30,b.variables.errorColor,(function(e){return e.$selected&&Object(v.css)(["border-color:",";"],b.variables.errorColor)})),dark:Object(v.css)(["border-color:",";}"],b.variables.errorColor)}),prisma:Object(v.css)(["&:not([disabled]){border-color:",";","}"],b.variables.accentColorNegative,(function(e){return e.$selected&&Object(v.css)(["background-color:",";"],b.variables.accentColorNegative)}))})}),Object(b.pick)({enterprise:{light:b.variables.borderColor,dark:b.variables.gray45},prisma:b.variables.contentColorDisabled}),(function(e){return e.$selected&&Object(b.pick)({prisma:Object(v.css)(["border-color:transparent;background-color:",";"],b.variables.interactiveColorBackgroundDisabled)})})),k=S.withComponent("span"),P=y.a.div.withConfig({displayName:"SwitchStyles__StyledSome",componentId:"sc-844ieu-2"})(["display:block;margin:",";height:",";width:",";background:currentColor;border-radius:1px;"],Object(b.pick)({enterprise:"2px",prisma:"5px 2px"}),Object(b.pick)({enterprise:Object(v.css)(["calc("," - 10px);"],j),prisma:"2px"}),Object(b.pick)({enterprise:Object(v.css)(["calc("," - 10px);"],j),prisma:"8px"})),E=y.a.div.withConfig({displayName:"SwitchStyles__StyledIndicator",componentId:"sc-844ieu-3"})(["background-color:",";border-color:",";box-sizing:border-box;border-radius:50%;border-width:1px;position:absolute;left:-1px;top:-1px;",";"," "," ",""],Object(b.pick)({enterprise:{light:b.variables.gray98,dark:b.variables.gray80},prisma:b.variables.white}),Object(b.pick)({enterprise:{light:b.variables.gray60,dark:b.variables.borderColor},prisma:b.variables.transparent}),(function(e){var t=e.$delay;return t&&Object(v.css)(["transition:left ",";"],t)}),Object(b.pick)({enterprise:Object(v.css)(["width:",";height:",";border-style:solid;"],j,j),prisma:Object(v.css)(["height:16px;width:16px;margin:2px;border-style:none;box-shadow:",";"],b.variables.embossShadow)}),(function(e){return e.$disabled&&Object(v.css)(["border-color:",";border-style:solid;background-color:",";"],Object(b.pick)({enterprise:{light:b.mixins.colorWithAlpha(b.variables.borderLightColor,.8),dark:b.variables.gray22},prisma:b.variables.transparent}),Object(b.pick)({enterprise:{dark:b.variables.gray45},prisma:b.mixins.colorWithAlpha(b.variables.white,.3)}))}),(function(e){return e.$selected&&Object(v.css)(["left:",";"],Object(b.pick)({enterprise:Object(v.css)(["calc(100% - "," + 1px)"],j),prisma:Object(v.css)(["calc(100% - "," + 1px)"],w)}))})),_=y.a.div.withConfig({displayName:"SwitchStyles__StyledToggleOutline",componentId:"sc-844ieu-4"})(["position:absolute;border:1px solid transparent;",";border-radius:",";top:-1px;right:-1px;bottom:-1px;left:-1px;z-index:1;"," ",""],(function(e){var t=e.$delay;return t&&Object(v.css)(["transition:border-color ",";"],t)}),Object(b.pick)({enterprise:Object(v.css)(["calc("," * 0.5)"],j),prisma:"15px"}),Object(b.pick)({prisma:Object(v.css)(["margin:-6px;"])}),(function(e){return e.$error&&Object(v.css)(["border-color:",";"],Object(b.pick)({enterprise:b.variables.errorColor,prisma:b.variables.transparent}))})),T=y()(x.a).withConfig({displayName:"SwitchStyles__StyledToggleClickable",componentId:"sc-844ieu-5"})(["position:relative;"," border-radius:",";transition:background-color ",";flex:0 0 auto;border:1px solid ",";"," &:not([disabled]){&:focus{outline:0;box-shadow:",";","}&:hover ","{background-color:",";}&:hover ","{background-color:",";}};&[disabled]{border:1px solid ",";background-color:",";"," ","}",";",""],Object(b.pick)({enterprise:Object(b.pick)({light:Object(v.css)(["width:calc("," * 2);background-color:",";height:",";"],j,b.variables.gray98,j),dark:Object(v.css)(["width:calc("," * 2);background-color:",";height:",";"],j,b.variables.gray45,j)}),prisma:Object(v.css)(["width:32px;background-color:",";height:",";top:1px;"],b.variables.contentColorMuted,w)}),j,(function(e){return e.$delay}),Object(b.pick)({enterprise:{light:b.variables.gray60,dark:b.variables.borderColor},prisma:b.variables.transparent}),Object(b.pick)({enterprise:Object(v.css)(["box-shadow:inset 0 2px 0 rgba(0,0,0,0.1);"])}),Object(b.pick)({enterprise:Object(v.css)(["",",inset 0 2px 0 rgba(0,0,0,0.1);"],b.variables.focusShadow),prisma:b.variables.focusShadow}),Object(b.pick)({enterprise:Object(v.css)(["> ","{border-color:",";}"],_,b.mixins.colorWithAlpha(b.variables.focusColor,.8))}),E,Object(b.pick)({enterprise:Object(b.pick)({light:b.variables.gray96,dark:"#b1bcc7"}),prisma:b.variables.white}),_,Object(b.pick)({prisma:b.variables.interactiveColorOverlayHover}),Object(b.pick)({enterprise:{light:b.variables.borderLightColor,dark:b.variables.borderColor},prisma:b.variables.transparent}),Object(b.pick)({enterprise:{light:b.variables.gray96,dark:b.variables.gray30},prisma:b.variables.interactiveColorBackgroundDisabled}),Object(b.pick)({enterprise:Object(v.css)(["box-shadow:inset 0 2px 0 rgba(0,0,0,0.06);"])}),(function(e){return e.$selected&&Object(v.css)(["border-color:transparent;background-color:",";"],Object(b.pick)({enterprise:Object(b.pick)({light:b.variables.accentColorL40,dark:b.variables.accentColorD20}),prisma:b.mixins.colorWithAlpha(b.variables.interactiveColorPrimary,.7)}))}),(function(e){return e.$selected&&Object(v.css)(["border-color:",";background-color:",";",""],Object(b.pick)({enterprise:b.variables.accentColorL10,prisma:b.variables.transparent}),Object(b.pick)({enterprise:b.variables.accentColorL10,prisma:b.variables.interactiveColorPrimary}),Object(b.pick)({prisma:Object(v.css)(["box-shadow:",";"],b.variables.embossShadow)}))}),(function(e){return e.$error&&Object(v.css)(["border-color:",";",";"],Object(b.pick)({enterprise:b.variables.errorColor,prisma:b.variables.transparent}),Object(b.pick)({prisma:Object(v.css)(["background-color:",";"],b.variables.accentColorNegative)}))})),D=T.withComponent("span"),I=y.a.label.withConfig({displayName:"SwitchStyles__StyledLabel",componentId:"sc-844ieu-6"})([""," flex:1 1 auto;padding-left:",";color:inherit;",";"],b.mixins.reset("inline-block"),Object(b.pick)({enterprise:Object(v.css)(["",";"],b.variables.spacingQuarter),prisma:"8px"}),(function(e){return!e.$disabled&&Object(v.css)(["cursor:pointer;"])}));function R(e){return R="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},R(e)}function L(){return L=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},L.apply(this,arguments)}function A(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function M(e,t,n){return t&&A(e.prototype,t),n&&A(e,n),e}function B(e,t){return B=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},B(e,t)}function N(e,t){return!t||"object"!==R(t)&&"function"!=typeof t?z(e):t}function z(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function F(e){return F=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},F(e)}function $(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var H={appearance:i.a.oneOf(["checkbox","toggle"]),children:i.a.node,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),error:i.a.bool,id:i.a.string,inline:i.a.bool,interactive:i.a.bool,labelledBy:i.a.string,onClick:i.a.func,selected:i.a.oneOf([!0,!1,"some"]),selectedLabel:i.a.string,someSelectedLabel:i.a.string,unselectedLabel:i.a.string,value:i.a.any},V={checkbox:S,toggle:T},q={checkbox:k,toggle:D},W=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&B(e,t)}(a,e);var t,n,r=(t=a,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=F(t);if(n){var o=F(this).constructor;e=Reflect.construct(r,arguments,o)}else e=r.apply(this,arguments);return N(this,e)});function a(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,a),$(z(t=r.call(this,e)),"clickableId",void 0),$(z(t),"labelId",void 0),$(z(t),"toggle",null),$(z(t),"componentDidUpdate",a.validateProps),$(z(t),"handleContainerClick",(function(e){var n,r,o=t.props,a=o.value,i=o.selected;null===(n=(r=t.props).onClick)||void 0===n||n.call(r,e,{value:a,selected:i})})),t.labelId=Object(p.createDOMID)("label"),t.clickableId=Object(p.createDOMID)("clickable"),a.validateProps(e),t}return M(a,null,[{key:"validateProps",value:function(e){e.selected,e.appearance}}]),M(a,[{key:"focus",value:function(){var e;null===(e=this.toggle)||void 0===e||e.focus()}},{key:"render",value:function(){var e=this,t=this.props,n=t.appearance,r=t.children,a=t.disabled,i=t.error,l=t.id,s=t.inline,p=t.interactive,f=t.labelledBy,d=(t.onClick,t.selected),b=t.selectedLabel,v=t.someSelectedLabel,y=t.unselectedLabel,m=t.value,g=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(t,["appearance","children","disabled","error","id","inline","interactive","labelledBy","onClick","selected","selectedLabel","someSelectedLabel","unselectedLabel","value"]),O=f,x=l;r&&(O=this.labelId,x=l||this.clickableId);var j,w={true:b,false:y,some:v},S={disabled:a,$interactive:p,$error:i,$selected:"some"===d||d,"aria-labelledby":p?O:void 0,"aria-checked":p?"some"===d?"mixed":d:void 0,"aria-invalid":!!i||void 0,id:x,ref:function(t){e.toggle=t},onClick:a||!p?void 0:this.handleContainerClick,"data-test":"button","data-selected":d},k=V[n],T=q[n],D=function(e){return function(){var t=o.a.createElement(o.a.Fragment,null,o.a.createElement(E,{$delay:e,$disabled:a,$error:!a&&i,$selected:d}),o.a.createElement(_,{$delay:e,$error:!a&&i}));return p?o.a.createElement(k,L({role:"switch"},S,{$delay:e}),t):o.a.createElement(T,L({},S,{$delay:e}),t)}},R=(a?"disabled":i&&"error")||null,A=!!b||!!v||!!y;return o.a.createElement(C,L({flex:!0,inline:s,"data-test":"switch","data-test-selected":d,"data-test-value":m,"data-test-error":!!i||void 0,"data-error":!!i||void 0,"data-disabled":!!a||void 0,$switchState:R},g),"toggle"===n&&o.a.createElement(c.a,{on:D("200ms"),off:D()}),"toggle"!==n&&(j=o.a.createElement(o.a.Fragment,null,!0===d&&"checkbox"===n&&o.a.createElement(h,null),"some"===d&&"checkbox"===n&&o.a.createElement(P,null)),p?o.a.createElement(k,L({"data-clickable":!0,role:n},S),j):o.a.createElement(T,S,j)),p&&A&&o.a.createElement(u.a,null,w["".concat(d)]),r&&o.a.createElement(I,{$disabled:a,"data-test":"label",id:O,htmlFor:x,"data-disabled":a||null},r))}}]),a}(r.Component);$(W,"propTypes",H),$(W,"defaultProps",{appearance:"checkbox",disabled:!1,error:!1,inline:!1,interactive:!0,selected:!1});var K=W},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)},38:function(e,t){e.exports=n(6603)},50:function(e,t){e.exports=n(746)},8:function(e,t){e.exports=n(6493)}})},2672:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=132)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},10:function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},11:function(e,t){e.exports=n(9726)},12:function(e,t){e.exports=n(5917)},132:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return q})),n.d(t,"Tab",(function(){return z}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(9),c=n(3),s=n.n(c),u=n(0),p=s.a.div.withConfig({displayName:"TabBarStyles__Styled",componentId:"sc-1t85fen-0"})([""," position:relative;&::before{content:'';display:block;position:absolute;left:0;top:0;right:0;bottom:0;border:0 solid ",";}",";"],u.mixins.reset("flex"),Object(u.pick)({enterprise:u.variables.borderLightColor,prisma:u.variables.neutral200}),Object(u.pickVariant)("$layout",{horizontal:{prisma:Object(u.pickVariant)("$withUnderline",{true:Object(c.css)(["&::before{border-bottom-width:1px;}"])}),enterprise:Object(c.css)(["&::before{border-bottom-width:1px;}"])},vertical:{enterprise:Object(c.css)(["display:inline-block;&::before{border-right-width:1px;}"]),prisma:Object(c.css)(["&::before{border-bottom-width:1px;}"])}})),f=n(11),d=n(18),b=n.n(d),h=n(14),v=n.n(h),y=n(12),m=n.n(y),g=s()(m.a).withConfig({displayName:"TabStyles__StyledClickable",componentId:"sc-1ry8mzj-0"})(["flex:0 1 auto;display:block;position:relative;line-height:",";text-align:center;white-space:nowrap;color:",";",";&[aria-selected='true']{cursor:default;","}&[aria-selected='false']{box-shadow:none;font-weight:",";"," &:hover:not([disabled]){","}}&:focus{box-shadow:",";","}"],Object(u.pick)({enterprise:"24px",prisma:"20px"}),u.variables.contentColorDefault,Object(u.pickVariant)("$layout",{horizontal:Object(c.css)(["padding:",";margin-bottom:1px;"],Object(u.pick)({enterprise:"3px 20px",prisma:{comfortable:"0 20px",compact:"0 16px"}})),vertical:{enterprise:Object(c.css)(["width:100%;text-align:left;right:1px;padding:10px 20px;",""],(function(e){return e.$icon&&Object(c.css)(["text-align:center;"])})),prisma:Object(c.css)(["padding:",";margin-bottom:1px;"],Object(u.pick)({enterprise:"3px 20px",prisma:{comfortable:"0 20px",compact:"0 16px"}}))}}),Object(u.pick)({enterprise:Object(c.css)(["font-weight:",";"],u.variables.fontWeightBold),prisma:Object(c.css)(["color:",";font-weight:",";"],u.variables.contentColorActive,u.variables.fontWeightBold)}),Object(u.pick)({enterprise:"normal",prisma:u.variables.fontWeightSemiBold}),Object(u.pick)({prisma:Object(c.css)(["&::after{display:block;content:attr(title);font-weight:",";height:0;color:transparent;overflow:hidden;visibility:hidden;}"],u.variables.fontWeightBold)}),Object(u.pick)({prisma:Object(c.css)(["color:",";"],u.variables.contentColorActive)}),u.variables.focusShadowInset,Object(u.pick)({prisma:Object(c.css)(["color:",";"],u.variables.contentColorActive)})),O=s.a.div.withConfig({displayName:"TabStyles__StyledUnderline",componentId:"sc-1ry8mzj-1"})(["position:absolute;"," ",";[aria-selected='true'] > &{background-color:",";",";}",":hover:not([disabled]) > &{",";}"],Object(u.pick)({enterprise:Object(c.css)(["background:",";"],u.variables.borderLightColor)}),Object(u.pickVariant)("$layout",{horizontal:Object(c.css)(["height:0;box-sizing:border-box;width:",";"," transition:height 0.2s;"],Object(u.pick)({enterprise:Object(c.css)(["calc(100% - 20px * 2)"]),prisma:{comfortable:Object(c.css)(["calc(100% - 20px * 2)"]),compact:Object(c.css)(["calc(100% - 16px * 2)"])}}),Object(u.pick)({enterprise:Object(c.css)(["bottom:-1px;"])})),vertical:{enterprise:Object(c.css)(["width:0;height:calc(100% - 10px * 2);top:10px;right:-1px;transition:width 0.2s;"]),prisma:Object(c.css)(["height:0;box-sizing:border-box;width:",";transition:height 0.2s;"],Object(u.pick)({comfortable:Object(c.css)(["calc(100% - 20px * 2)"]),compact:Object(c.css)(["calc(100% - 16px * 2)"])}))}}),Object(u.pick)({enterprise:u.variables.accentColor,prisma:u.variables.contentColorActive}),Object(u.pickVariant)("$layout",{horizontal:{enterprise:Object(c.css)(["height:3px;"]),prisma:Object(u.pickVariant)("$withUnderline",{true:Object(c.css)(["height:1px;"])})},vertical:{enterprise:Object(c.css)(["width:3px;"]),prisma:Object(c.css)(["height:1px;"])}}),g,Object(u.pickVariant)("$layout",{horizontal:{enterprise:Object(c.css)(["height:3px;"])},vertical:{enterprise:Object(c.css)(["width:3px;"])}})),x=s.a.span.withConfig({displayName:"TabStyles__StyledIcon",componentId:"sc-1ry8mzj-2"})(["",";"],Object(u.pickVariant)("$iconSize",{inline:Object(c.css)([""," text-align:left;padding-right:",";> svg{transform:translateY(-1px);}"],Object(u.pick)({prisma:Object(c.css)(["display:inline-block;width:16px;height:16px;"])}),Object(u.pick)({enterprise:"0.4em",prisma:"8px"})),small:Object(c.css)(["font-size:24px;height:24px;text-align:center;display:block;padding:4px 0;"]),large:Object(c.css)(["font-size:48px;height:48px;text-align:center;display:block;padding:8px 0 0;"])})),j=s.a.div.withConfig({displayName:"TabStyles__StyledLabel",componentId:"sc-1ry8mzj-3"})(["overflow:hidden;text-overflow:ellipsis;min-width:10px;margin:",";"],Object(u.pick)({enterprise:"0",prisma:{comfortable:"16px 0",compact:"10px 0"}})),w=s.a.div.withConfig({displayName:"TabStyles__StyledCount",componentId:"sc-1ry8mzj-4"})([""," display:inline-block;background:",";border-radius:18px;color:",";font-size:",";line-height:10px;padding:4px 6px;margin-left:",";"," &[disabled]{background:",";color:",";}"],u.mixins.reset("inlne-block"),u.variables.interactiveColorBackground,u.variables.contentColorDefault,Object(u.pick)({enterprise:"inherit",prisma:"10px"}),Object(u.pick)({enterprise:"0",prisma:"8px"}),Object(u.pick)({enterprise:Object(c.css)(["&::before{content:'(';}&::after{content:')';}"])}),u.variables.interactiveColorBackgroundDisabled,u.variables.contentColorDisabled),C=s.a.div.withConfig({displayName:"TabStyles__StyledTooltipContent",componentId:"sc-1ry8mzj-5"})(["padding:8px;font-size:",";"],u.variables.fontSizeSmall),S=n(10),k=Object(r.createContext)({});k.displayName="TabBar";var P=k;function E(e){return E="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},E(e)}function _(){return _=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},_.apply(this,arguments)}function T(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function D(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function I(e,t){return I=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},I(e,t)}function R(e,t){return!t||"object"!==E(t)&&"function"!=typeof t?L(e):t}function L(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function A(e){return A=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},A(e)}function M(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var B={active:i.a.bool,ariaControls:i.a.string,count:i.a.number,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),icon:i.a.node,id:i.a.string,label:i.a.oneOfType([i.a.string,i.a.element]),tabId:i.a.string,tabKey:i.a.number,to:i.a.string,tooltip:i.a.node},N=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&I(e,t)}(l,e);var t,n,r,a,i=(r=l,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=A(r);if(a){var n=A(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return R(this,e)});function l(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,l),M(L(t=i.call(this,e)),"popoverId",void 0),M(L(t),"handleMount",(function(e){t.setState({anchor:e}),Object(S.a)(t.props.elementRef,e)})),M(L(t),"handleTooltipOpen",(function(){t.setState({open:!0})})),M(L(t),"handleTooltipClose",(function(){t.setState({open:!1})})),M(L(t),"handleClick",(function(e){var n=t.props,r=n.active,o=n.tabId,a=n.tabKey,i=n.to,l=t.context.onClick;r||null==l||l(e,{tabId:o,tabKey:a}),(null==i||null!=i&&r)&&e.preventDefault()})),M(L(t),"handleFocus",(function(e){t.handleTooltipOpen();var n=t.props,r=n.tabId,o=n.tabKey,a=t.context.onFocus;null==a||a(e,{tabId:r,tabKey:o})})),t.popoverId=Object(f.createDOMID)("popover"),t.state={open:!1,anchor:null},t}return t=l,n=[{key:"focus",value:function(){var e;null===(e=this.state.anchor)||void 0===e||e.focus()}},{key:"render",value:function(){var e=this.props,t=e.active,n=e.ariaControls,r=e.count,a=e.disabled,i=e.icon,l=e.label,c=e.tabId,s=e.to,u=e.tooltip,p=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["active","ariaControls","count","disabled","icon","label","tabId","to","tooltip"]),f=this.state,d=f.anchor,h=f.open,y=this.context,m=y.appearance,S=y.disabled,k=y.iconSize,P=y.layout,E=y.width,D=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?T(Object(n),!0).forEach((function(t){M(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):T(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({},p),I=S||a,R=k||"inline",L=P||"horizontal",A=E?{width:E}:D;return o.a.createElement(g,_({"aria-controls":n,"aria-selected":t,"data-test":"tab","data-test-tab-id":c,"data-test-popover-id":u?this.popoverId:void 0,$layout:L,$icon:!(!i||"inline"===R)||void 0,disabled:I,elementRef:this.handleMount,style:A},p,{onClick:this.handleClick,onFocus:this.handleFocus,onMouseEnter:this.handleTooltipOpen,onBlur:this.handleTooltipClose,onMouseLeave:this.handleTooltipClose,role:"tab",tabIndex:t?void 0:-1,title:l,to:s}),o.a.createElement(j,{"data-test":"label",$withUnderline:"navigation"===m},i&&o.a.createElement(x,{$iconSize:R},i),l,(0===r||r)&&o.a.createElement(w,{"data-test":"count",disabled:I},r)),o.a.createElement(O,{$layout:L,$withUnderline:"navigation"===m}),!a&&u&&o.a.createElement(b.a,{anchor:d,appearance:"inverted",closeReasons:[],defaultPlacement:"vertical"===L?"right":"above",id:this.popoverId,open:!!d&&h},o.a.createElement(C,null,u)),u&&o.a.createElement(v.a,null,u))}}],n&&D(t.prototype,n),l}(r.Component);M(N,"propTypes",B),M(N,"defaultProps",{active:!1}),M(N,"contextType",P);var z=N,F=n(44);function $(){return $=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},$.apply(this,arguments)}var H={autoActivate:i.a.bool,activeTabId:i.a.string,appearance:i.a.oneOf(["navigation","context"]),children:i.a.node,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),iconSize:i.a.oneOf(["inline","small","large"]),layout:i.a.oneOf(["horizontal","vertical"]),onChange:i.a.func,tabWidth:i.a.number};function V(e){var t=e.activeTabId,n=e.autoActivate,a=e.appearance,i=void 0===a?"navigation":a,c=e.children,s=e.disabled,u=void 0!==s&&s,f=e.elementRef,d=e.iconSize,b=void 0===d?"inline":d,h=e.layout,v=void 0===h?"horizontal":h,y=e.onChange,m=e.tabWidth,g=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["activeTabId","autoActivate","appearance","children","disabled","elementRef","iconSize","layout","onChange","tabWidth"]),O=Object(r.useRef)(0),x=[],j=Object(r.useMemo)((function(){return"vertical"===v?"down":"right"}),[v]),w=Object(r.useMemo)((function(){return"vertical"===v?"up":"left"}),[v]),C=0,S=r.Children.toArray(c).filter(r.isValidElement).map((function(e){if("string"==typeof e.type||e.type.name!==z.name)return e;var n=o.a.createRef();x.push(n);var a={active:t===e.props.tabId,tabKey:C,ref:n};return C+=1,Object(r.cloneElement)(e,a)})),k=m&&m>50?m:null;return o.a.createElement(p,$({"data-tab-layout":v,"data-test-active-tab-id":t,"data-test":"tab-bar",role:"tablist",ref:f,$layout:v,$withUnderline:"navigation"===i,onKeyDown:function(e){var t,n,r=Object(l.keycode)(e.nativeEvent);r===j?t=Object(F.a)(x,O.current,O.current+1):r===w?t=Object(F.b)(x,O.current,O.current-1):"home"===r?t=Object(F.a)(x,O.current,0):"end"===r&&(t=Object(F.b)(x,O.current,x.length-1)),null!=t&&(null===(n=t.current)||void 0===n||n.focus(),e.preventDefault())}},g),o.a.createElement(P.Provider,{value:{appearance:i,disabled:u,iconSize:b,layout:v,onClick:function(e,t){null==y||y(e,{selectedTabId:t.tabId})},onFocus:function(e,t){var r=t.tabKey;null!=r&&(O.current=r),n&&(null==y||y(e,{selectedTabId:t.tabId}))},width:k}},S))}V.propTypes=H,V.Tab=z;var q=V},14:function(e,t){e.exports=n(5766)},18:function(e,t){e.exports=n(9016)},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)},44:function(e,t,n){"use strict";function r(e,t,n){for(var r=0;r<e.length;r+=1){var o,a=(r+n)%e.length;if(!0!==(null===(o=e[a].current)||void 0===o?void 0:o.props.disabled))return e[a]}return e[t]}function o(e,t,n){for(var r=e.length;r>0;r-=1){var o,a=(r+n)%e.length;if(!0!==(null===(o=e[a].current)||void 0===o?void 0:o.props.disabled))return e[a]}return e[t]}n.d(t,"a",(function(){return r})),n.d(t,"b",(function(){return o}))},9:function(e,t){e.exports=n(2916)}})},7599:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=115)}([function(e,t){e.exports=n(5947)},function(e,t){e.exports=n(1581)},function(e,t){e.exports=n(7294)},function(e,t){e.exports=n(2788)},function(e,t){e.exports=n(5220)},function(e,t){e.exports=n(6219)},function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var r=n(2),o=n.n(r),a=n(3);function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n.n(a).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function c(e){return o.a.createElement(l,i({xmlns:"http://www.w3.org/2000/svg"},e))}},function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(0);function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}var p={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},f={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:i.a.func,enterpriseSize:i.a.oneOfType([i.a.number,i.a.string]),enterpriseWidth:i.a.oneOfType([i.a.number,i.a.string]),enterpriseHeight:i.a.oneOfType([i.a.number,i.a.string]),Prisma24:i.a.func.isRequired,Prisma20:i.a.func,Prisma16:i.a.func,prismaSize:i.a.oneOf(["medium","small"]),inline:i.a.bool,screenReaderText:i.a.string};function b(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,a=e.Prisma16,i=e.prismaSize,d=e.inline,b=e.enterpriseSize,h=e.enterpriseWidth,v=e.enterpriseHeight,y=e.screenReaderText,m=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),g=Object(l.useSplunkTheme)(),O=g.family,x=g.density;if("enterprise"===O)return o.a.createElement(t,u({size:b,width:h,height:v,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},m));var j=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?p:f},m);if("small"===i){var w=a||n;return o.a.createElement(w,u({width:"16",height:"16"},j))}if("compact"===x){var C=r||n;return o.a.createElement(C,u({width:"20",height:"20"},j))}return o.a.createElement(n,u({width:"24",height:"24"},j))}b.propTypes=d,b.defaultProps={inline:!0,prismaSize:"medium"}},,function(e,t){e.exports=n(2916)},function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},function(e,t){e.exports=n(9726)},,,function(e,t){e.exports=n(5766)},function(e,t){e.exports=n(9213)},function(e,t){e.exports=n(6416)},,function(e,t){e.exports=n(9016)},function(e,t,n){"use strict";n.d(t,"a",(function(){return o}));var r={document:n(27).b,navigator:{userAgent:""},location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""},history:{replaceState:function(){},pushState:function(){},go:function(){},back:function(){}},CustomEvent:function(){return this},addEventListener:function(){},removeEventListener:function(){},getComputedStyle:function(){return{getPropertyValue:function(){return""}}},Image:function(){},Date:function(){},screen:{},setTimeout:function(){},clearTimeout:function(){},matchMedia:function(){return{}},requestAnimationFrame:function(e){return"undefined"==typeof setTimeout?(e(),null):setTimeout(e,0)},cancelAnimationFrame:function(e){"undefined"!=typeof setTimeout&&clearTimeout(e)}};function o(){return"undefined"!=typeof window?window:r}},function(e,t){e.exports=n(6635)},,,,,,,function(e,t,n){"use strict";n.d(t,"a",(function(){return o})),n.d(t,"b",(function(){return r}));var r={body:{appendChild:function(){return[]}},addEventListener:function(){},removeEventListener:function(){},activeElement:{blur:function(){},nodeName:""},querySelector:function(){return null},querySelectorAll:function(){return[]},getElementById:function(){return null},createEvent:function(){return{initEvent:function(){}}},createElement:function(){return{children:[],childNodes:[],style:{},setAttribute:function(){},getElementsByTagName:function(){return[]}}},createElementNS:function(){return{}},importNode:function(){return null},location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""}};function o(){return"undefined"!=typeof document?document:r}},,function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(35),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M14.7861 11.9999L8.48587 5.69972C8.09534 5.3092 8.09534 4.67603 8.48587 4.28551C8.87639 3.89499 9.50956 3.89499 9.90008 4.28551L16.5538 10.9393C17.1396 11.525 17.1396 12.4748 16.5538 13.0606L9.90142 19.713C9.5109 20.1035 8.87773 20.1035 8.48721 19.713C8.09669 19.3224 8.09669 18.6893 8.48721 18.2988L14.7861 11.9999Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M11.7109 7.9976L5.71017 13.9983L4.29597 12.5841L8.88914 7.99095L4.34482 3.40363L5.76567 1.99609L11.7109 7.9976Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},,,,,,function(e,t){e.exports=n(4345)},,,,function(e,t){e.exports=n(7009)},function(e,t,n){"use strict";n.d(t,"a",(function(){return p}));var r=n(2),o=n.n(r),a=n(41),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M7.2788 9.00002C6.84609 9.00002 6.61768 9.51239 6.90691 9.83423L11.4078 14.8426C11.6065 15.0637 11.953 15.0636 12.1517 14.8425L16.6499 9.8341C16.939 9.51223 16.7106 9 16.2779 9L7.2788 9.00002Z",fill:"currentColor"}))}function p(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma24:u},e))}},function(e,t){e.exports=n(7924)},,,,,,,,,,function(e,t){e.exports=n(272)},function(e,t){e.exports=n(5458)},,,,,function(e,t,n){"use strict";function r(e,t){if(null==e)throw new Error(null!=t?t:"Unexpected undefined or null")}n.d(t,"a",(function(){return r}))},,,,,,,,function(e,t,n){"use strict";n.d(t,"a",(function(){return p}));var r=n(2),o=n.n(r),a=n(66),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M12.0167 6.27273C12.9205 6.27273 13.6531 5.5401 13.6531 4.63636C13.6531 3.73263 12.9205 3 12.0167 3C11.113 3 10.3804 3.73263 10.3804 4.63636C10.3804 5.5401 11.113 6.27273 12.0167 6.27273ZM13.6531 12C13.6531 12.9038 12.9205 13.6364 12.0167 13.6364C11.113 13.6364 10.3804 12.9038 10.3804 12C10.3804 11.0963 11.113 10.3636 12.0167 10.3636C12.9205 10.3636 13.6531 11.0963 13.6531 12ZM13.6531 19.3637C13.6531 20.2674 12.9205 21 12.0167 21C11.113 21 10.3804 20.2674 10.3804 19.3637C10.3804 18.4599 11.113 17.7273 12.0167 17.7273C12.9205 17.7273 13.6531 18.4599 13.6531 19.3637Z",fill:"currentColor"}))}function p(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma24:u},e))}},function(e,t){e.exports=n(6261)},function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(51),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M12.0003 14.7858L18.2955 8.49062C18.686 8.1001 19.3192 8.1001 19.7097 8.49062C20.1003 8.88115 20.1003 9.51431 19.7097 9.90484L13.061 16.5536C12.4752 17.1394 11.5255 17.1394 10.9397 16.5536L4.28899 9.90289C3.89846 9.51236 3.89846 8.8792 4.28899 8.48868C4.67951 8.09815 5.31268 8.09815 5.7032 8.48868L12.0003 14.7858Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M8.0015 11.7109L14.0022 5.71017L12.588 4.29597L7.99485 8.88914L3.40754 4.34482L2 5.76567L8.0015 11.7109Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},,,,,function(e,t){e.exports=n(7885)},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,function(e,t){e.exports=n(1746)},function(e,t){e.exports=n(5336)},function(e,t){e.exports=n(1022)},function(e,t){e.exports=n(7631)},function(e,t){e.exports=n(8808)},,,,function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return cr})),n.d(t,"Body",(function(){return T})),n.d(t,"Caption",(function(){return F})),n.d(t,"Cell",(function(){return J})),n.d(t,"Head",(function(){return vn})),n.d(t,"HeadCell",(function(){return it})),n.d(t,"HeadDropdownCell",(function(){return Rn})),n.d(t,"Row",(function(){return en}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(107),s=n.n(c),u=n(15),p=n.n(u),f=n(9),d=n(39),b=n(3),h=n.n(b),v=n(0),y=h.a.tbody.withConfig({displayName:"BodyStyles__Styled",componentId:"sc-1k5p6pq-0"})([""," z-index:0;"],v.mixins.reset("table-row-group")),m=n(10),g=n(19);function O(e){return O="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},O(e)}function x(){return x=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},x.apply(this,arguments)}function j(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function w(e,t){return w=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},w(e,t)}function C(e,t){return!t||"object"!==O(t)&&"function"!=typeof t?S(e):t}function S(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function k(e){return k=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},k(e)}function P(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var E={actions:i.a.bool,children:i.a.node,elementRef:i.a.oneOfType([i.a.func,i.a.object]),movableColumns:i.a.bool,rowExpansion:i.a.oneOf(["single","multi","none","controlled"]),onRequestMoveRow:i.a.func,stripeRows:i.a.bool},_=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&w(e,t)}(s,e);var t,n,a,i,c=(a=s,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=k(a);if(i){var n=k(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return C(this,e)});function s(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,s),P(S(t=c.call(this,e)),"el",null),P(S(t),"rect",void 0),P(S(t),"rowHeight",void 0),P(S(t),"rows",void 0),P(S(t),"handleDragStart",(function(e,n){var r,o,a,i,l=Object(g.a)();t.rect=null===(r=t.el)||void 0===r||null===(o=r.parentElement)||void 0===o||null===(a=o.parentElement)||void 0===a?void 0:a.getBoundingClientRect(),t.rowHeight=null===(i=t.el)||void 0===i?void 0:i.children[0].getBoundingClientRect().height,t.setState({dragIndex:e,dragDataId:n}),l.addEventListener("dragenter",t.handleDragEnter),l.addEventListener("dragover",t.handleDragOver),l.addEventListener("drop",t.handleDrop),l.addEventListener("dragend",t.handleDragEnd)})),P(S(t),"handleDragOver",(function(e){e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move");var n=e.clientY;t.updateScrollPosition(n),t.updateDragPosition(n)})),P(S(t),"handleDragEnter",(function(e){e.preventDefault(),t.setState({dragPosition:e.clientY})})),P(S(t),"handleDrop",(function(e){e.preventDefault()})),P(S(t),"handleDragEnd",(function(){var e=t.state,n=e.dragIndex,r=e.dragDataId,o=t.calculateGuideIndex();if(void 0!==n){var a,i,l=n<o?o-1:o;n!==l&&(null===(a=(i=t.props).onRequestMoveRow)||void 0===a||a.call(i,{fromIndex:n,toIndex:l,dataId:r}))}t.setState({dragPosition:void 0}),t.cleanupDrag()})),P(S(t),"onRequestMoveRow",(function(e){var n,o,a=e.dataId,i=e.fromIndex,l=e.toIndex;t.setState({dragDataId:a}),l<r.Children.toArray(t.props.children).length&&(null===(n=(o=t.props).onRequestMoveRow)||void 0===n||n.call(o,{fromIndex:i,toIndex:l,dataId:a}))})),P(S(t),"handleMount",(function(e){t.el=e,Object(m.a)(t.props.elementRef,e)})),P(S(t),"updateDragPosition",Object(l.throttle)(t.updateDragPositionImpl,100,{trailing:!1})),t.state={dragDataId:void 0,expanded:[]},t.rowHeight=0,t}return t=s,(n=[{key:"componentWillUnmount",value:function(){this.cleanupDrag()}},{key:"handleRowExpansion",value:function(e,t,n){var r=this.state.expanded;"single"===this.props.rowExpansion?Object(l.includes)(r,t)?this.setState({expanded:[]}):this.setState({expanded:[t]}):"multi"===this.props.rowExpansion&&(Object(l.includes)(r,t)?this.setState({expanded:Object(l.without)(r,t)}):this.setState({expanded:r.concat(t)})),null==n||n(e)}},{key:"calculateGuideIndex",value:function(){var e=this.state,t=e.dragIndex,n=e.dragPosition;if(void 0===n||!this.el)return-1;this.rows=Array.from(this.el.children);var r=Object(l.findIndex)(this.rows,(function(e){var t=e.getBoundingClientRect();return n>t.top&&n<t.bottom}));if(-1===r){var o=this.el.getBoundingClientRect();return n<o.top?0:this.rows.length}return void 0!==t&&r>t?r+1:r}},{key:"updateDragPositionImpl",value:function(e){this.setState({dragPosition:e})}},{key:"updateScrollPosition",value:function(e){var t,n,r=this.rect;(null===(t=this.el)||void 0===t||null===(n=t.parentElement)||void 0===n?void 0:n.parentElement)&&r&&void 0!==this.rowHeight&&e<r.top+2*this.rowHeight+5&&(this.el.parentElement.parentElement.scrollTop-=1)}},{key:"cleanupDrag",value:function(){var e=Object(g.a)();e.removeEventListener("dragenter",this.handleDragEnter),e.removeEventListener("dragover",this.handleDragOver),e.removeEventListener("drop",this.handleDrop),e.removeEventListener("dragend",this.handleDragEnd),this.updateDragPosition.cancel(),this.rows=void 0,this.rect=void 0}},{key:"render",value:function(){var e,t=this,n=this.props,a=n.actions,i=n.children,c=n.movableColumns,s=n.onRequestMoveRow,u=n.rowExpansion,p=n.stripeRows,f=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(n,["actions","children","movableColumns","onRequestMoveRow","rowExpansion","stripeRows"]),d=[],b=this.calculateGuideIndex(),h=null===(e=this.state.dragDataId)||void 0===e?void 0:e.toString(),v=r.Children.toArray(i).filter(r.isValidElement);return v.forEach((function(e,n){var o="none";if(b===v.length&&n+1===v.length?o="after":b===n&&(o="before"),e){var i=e.key,f=p?n%2?"even":"odd":"none",y="controlled"===u?e.props.expanded:Object(l.includes)(t.state.expanded,i);d.push(Object(r.cloneElement)(e,{index:n,showRowGuideline:o,stripe:f,actions:a,expanded:y,expandable:"none"!==u,draggable:!!s,movableColumns:c,onExpansion:function(n){t.handleRowExpansion(n,i,e.props.onExpansion)},onRequestMoveRow:s?t.onRequestMoveRow:void 0,onDragStart:s?t.handleDragStart:void 0,key:e.key||e.props.dataId||n,dataId:e.key||e.props.dataId||n,activeElementId:h})),y&&e.props.expansionRow&&r.Children.forEach(e.props.expansionRow,(function(e,t){return d.push(Object(r.cloneElement)(e,{key:"".concat(i,"-expansion-").concat(t),stripe:f,movableColumns:c,onRequestMoveRow:s,"data-expansion-row":"true"}))}))}})),0===d.length?null:o.a.createElement(y,x({"data-test":"body"},f,{ref:this.handleMount}),d)}}])&&j(t.prototype,n),s}(r.Component);P(_,"splunkUiType","Table.Body"),P(_,"propTypes",E),P(_,"defaultProps",{actions:!1,rowExpansion:"none",stripeRows:!1});var T=_,D=h.a.div.withConfig({displayName:"TableStyles__Styled",componentId:"sc-1cmfss7-0"})(["",";max-width:100%;position:relative;z-index:1;@media print{max-height:none !important;}"],v.mixins.reset("block")),I=h.a.div.withConfig({displayName:"TableStyles__StyledTableContainer",componentId:"sc-1cmfss7-1"})(["overflow:auto;&::before{content:'';width:100%;height:0;top:0;position:absolute;}"]),R=h.a.table.withConfig({displayName:"TableStyles__StyledTable",componentId:"sc-1cmfss7-2"})(["",";position:relative;border-collapse:collapse;border-spacing:0;min-width:100%;z-index:0;&[data-fixed-column='true']{table-layout:fixed;min-width:0;width:0;}"," @media print{width:100%;max-width:100%;table-layout:auto;}"],v.mixins.reset("table"),(function(e){return e.$resizableFillLayout&&Object(b.css)(["width:100%;min-width:100%;table-layout:fixed;"])})),L=h.a.div.withConfig({displayName:"TableStyles__StyledDockedScrollbar",componentId:"sc-1cmfss7-3"})(["position:fixed;bottom:0;overflow:auto;z-index:calc("," + 1);"],v.variables.zindexFixedNavbar),A=h.a.div.withConfig({displayName:"TableStyles__StyledDockedScrollbarContent",componentId:"sc-1cmfss7-4"})(["height:1px;"]),M=h.a.caption.withConfig({displayName:"TableStyles__StyledTableCaption",componentId:"sc-1cmfss7-5"})(["padding:",";font-size:",";caption-side:",";"],Object(v.pick)({enterprise:"".concat(v.variables.spacingQuarter," 0"),prisma:"5px 0"}),v.variables.fontSizeLarge,(function(e){return e.side}));function B(){return B=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},B.apply(this,arguments)}var N={children:i.a.node.isRequired,side:i.a.oneOf(["top","bottom"])};function z(e){var t=e.children,n=e.side,r=void 0===n?"top":n,a=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","side"]);return o.a.createElement(M,B({"data-test":"caption",side:r},a),t)}z.propTypes=N,z.splunkUiType="Table.Caption";var F=z,$=h.a.td.withConfig({displayName:"CellStyles__Styled",componentId:"sc-1955xk2-0"})([""," padding:",";border-left:0 solid transparent;border-right:0 solid transparent;word-wrap:break-word;line-height:",";vertical-align:top;"," "," "," "," "," "," [data-expansion-row='true'] > &:first-child{padding-top:8px;}[data-expansion-row='true'] > &:last-child{padding-bottom:14px;}[data-has-movable-columns='true'] > &:not([data-movable-column='false']){","}"],v.mixins.reset("table-cell"),Object(v.pick)({enterprise:"6px 12px",prisma:{comfortable:"14px 8px",compact:"6px 8px"}}),v.variables.lineHeight,Object(v.pickVariant)("$align",{center:Object(b.css)(["text-align:center;"]),left:Object(b.css)(["text-align:left;"]),right:Object(b.css)(["text-align:right;"])}),Object(v.pickVariant)("$variant",{expand:{enterprise:Object(b.css)(["padding:6px 0 0 0;"]),prisma:{comfortable:Object(b.css)(["padding:12px 0 0 0;"]),compact:Object(b.css)(["padding:4px 0 0 0;"])}},actions:{prisma:{comfortable:Object(b.css)(["padding:4px 8px;"]),compact:Object(b.css)(["padding:0 8px 0 0;"])}},toggle:{prisma:{comfortable:Object(b.css)(["padding:10px 0 0 0;"]),compact:Object(b.css)(["padding:6px 0 0 0;"])}}}),Object(v.pickVariant)("$appearance",{rowLink:{enterprise:Object(b.css)(["color:",";*:hover > &{cursor:pointer;}"],v.variables.linkColor),prisma:Object(b.css)(["color:",";*:hover > &{cursor:pointer;}"],v.variables.contentColorDefault)},link:{enterprise:Object(b.css)(["color:",";&:hover{cursor:pointer;color:{dark:variables.accentColorL20,light:variables.linkColor,};box-shadow:",";}&:focus{color:{dark:variables.accentColorL20,light:variables.focusColor,};box-shadow:",";}"],v.variables.linkColor,v.variables.focusShadowInset,v.variables.focusShadowInset)}}),(function(e){return e.$clickable&&Object(b.css)(["cursor:pointer;&:hover{background-color:",";color:",";}&:focus{box-shadow:",";color:",";}&:active{background:",";}"],Object(v.pick)({enterprise:{light:v.variables.accentColorL50,dark:v.variables.accentColorD50},prisma:v.variables.interactiveColorOverlayHover}),Object(v.pick)({prisma:v.variables.contentColorDefault}),v.variables.focusShadowInset,Object(v.pick)({prisma:v.variables.contentColorDefault}),Object(v.pick)({prisma:v.variables.interactiveColorOverlayActive}))}),(function(e){return e.$expanded&&Object(b.css)(["background-color:",";"],Object(v.pick)({prisma:v.variables.interactiveColorOverlaySelected}))}),(function(e){return e.$disabled&&Object(b.css)(["color:",";"],Object(v.pick)({prisma:v.variables.contentColorDisabled}))}),Object(v.pick)({enterprise:Object(b.css)(["padding-left:29px;&:first-child{padding-left:28px;}"])}));function H(e){return H="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},H(e)}function V(){return V=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},V.apply(this,arguments)}function q(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function W(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function K(e,t){return K=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},K(e,t)}function U(e,t){return!t||"object"!==H(t)&&"function"!=typeof t?Z(e):t}function Z(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function G(e){return G=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},G(e)}function X(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var Y={align:i.a.oneOf(["left","center","right"]),appearance:i.a.oneOf(["data","link","rowLink"]),children:i.a.node,data:i.a.any,elementRef:i.a.oneOfType([i.a.func,i.a.object]),onClick:i.a.func,onKeyDown:i.a.func,disabled:i.a.bool,expand:i.a.bool,variant:i.a.oneOf(["toggle","expand","drag","actions"])},Q=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&K(e,t)}(l,e);var t,n,r,a,i=(r=l,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=G(r);if(a){var n=G(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return U(this,e)});function l(){var e;q(this,l);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return X(Z(e=i.call.apply(i,[this].concat(n))),"el",null),X(Z(e),"handleMount",(function(t){e.el=t,Object(m.a)(e.props.elementRef,t)})),X(Z(e),"handleClick",(function(t){var n=e.props,r=n.data,o=n.onClick;null==o||o(t,r)})),X(Z(e),"handleKeyDown",(function(t){var n=e.props,r=n.data,o=n.onClick,a=n.onKeyDown;"enter"===Object(f.keycode)(t.nativeEvent)&&(null==o||o(t,r)),null==a||a(t)})),e}return t=l,(n=[{key:"render",value:function(){var e=this.props,t=e.align,n=e.appearance,r=e.children,a=e.disabled,i=(e.elementRef,e.onClick),l=(e.onKeyDown,e.variant),c=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["align","appearance","children","disabled","elementRef","onClick","onKeyDown","variant"]),s=void 0!==i,u=s?"link":"data";return o.a.createElement($,V({"data-test":"cell",$align:t,$appearance:n||u,$clickable:!!s||void 0,$disabled:!!a,$variant:l,onClick:this.handleClick,onKeyDown:this.handleKeyDown,ref:this.handleMount,tabIndex:s?0:void 0},c),r)}}])&&W(t.prototype,n),l}(r.Component);X(Q,"splunkUiType","Table.Cell"),X(Q,"propTypes",Y),X(Q,"defaultProps",{align:"left"});var J=Q,ee=n(5),te=n(108),ne=n.n(te),re=n(7),oe=n(6);function ae(){return ae=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},ae.apply(this,arguments)}function ie(e){var t=ae({},e);return o.a.createElement(oe.a,ae({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M6.55086 12.337C6.16033 11.9465 5.52717 11.9465 5.13664 12.337C4.74612 12.7276 4.74612 13.3607 5.13664 13.7512L10.9391 19.5537C11.5249 20.1395 12.4746 20.1395 13.0604 19.5537L18.8628 13.7513C19.2534 13.3607 19.2534 12.7276 18.8628 12.337C18.4723 11.9465 17.8391 11.9465 17.4486 12.337L13 16.7856V5.00244C13 4.45016 12.5523 4.00244 12 4.00244C11.4477 4.00244 11 4.45016 11 5.00244V16.7862L6.55086 12.337Z",fill:"currentColor"}))}function le(e){var t=ae({},e);return o.a.createElement(oe.a,ae({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M8 2C8.55228 2 9 2.44772 9 3V10.0858L11.7929 7.29289C12.1834 6.90237 12.8166 6.90237 13.2071 7.29289C13.5976 7.68342 13.5976 8.31658 13.2071 8.70711L9.06066 12.8536C8.47487 13.4393 7.52513 13.4393 6.93934 12.8536L2.79289 8.70711C2.40237 8.31658 2.40237 7.68342 2.79289 7.29289C3.18342 6.90237 3.81658 6.90237 4.20711 7.29289L7 10.0858V3C7 2.44772 7.44772 2 8 2Z",fill:"currentColor"}))}function ce(e){return o.a.createElement(re.a,ae({Enterprise:ne.a,Prisma16:le,Prisma24:ie},e))}var se=n(109),ue=n.n(se);function pe(){return pe=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},pe.apply(this,arguments)}function fe(e){var t=pe({},e);return o.a.createElement(oe.a,pe({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M6.55135 11.6631C6.16082 12.0536 5.52766 12.0536 5.13713 11.6631C4.74661 11.2725 4.74661 10.6394 5.13713 10.2488L10.9396 4.44642C11.5253 3.86064 12.4751 3.86063 13.0609 4.44642L18.8633 10.2488C19.2538 10.6394 19.2538 11.2725 18.8633 11.6631C18.4728 12.0536 17.8396 12.0536 17.4491 11.6631L13 7.21397V19.0009C13 19.5532 12.5523 20.0009 12 20.0009C11.4477 20.0009 11 19.5532 11 19.0009V7.21441L6.55135 11.6631Z",fill:"currentColor"}))}function de(e){var t=pe({},e);return o.a.createElement(oe.a,pe({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M9 5.91414L11.7929 8.70703C12.1834 9.09756 12.8166 9.09756 13.2071 8.70703C13.5976 8.31651 13.5976 7.68334 13.2071 7.29282L9.06066 3.14637C8.47487 2.56059 7.52513 2.56058 6.93934 3.14637L2.79289 7.29282C2.40237 7.68334 2.40237 8.31651 2.79289 8.70703C3.18342 9.09756 3.81658 9.09756 4.20711 8.70703L7 5.91414V12.9999C7 13.5522 7.44772 13.9999 8 13.9999C8.55228 13.9999 9 13.5522 9 12.9999V5.91414Z",fill:"currentColor"}))}function be(e){return o.a.createElement(re.a,pe({Enterprise:ue.a,Prisma16:de,Prisma24:fe},e))}var he=n(110),ve=n.n(he);function ye(){return ye=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},ye.apply(this,arguments)}function me(e){var t=ye({},e);return o.a.createElement(oe.a,ye({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M7.2788 9.00002C6.84609 9.00002 6.61768 9.51239 6.90691 9.83423L11.4078 14.8426C11.6065 15.0637 11.953 15.0636 12.1517 14.8425L16.6499 9.8341C16.939 9.51223 16.7106 9 16.2779 9L7.2788 9.00002Z",fill:"currentColor"}))}function ge(e){var t=ye({},e);return o.a.createElement(oe.a,ye({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M6.93934 2.14662C7.52513 1.56083 8.47487 1.56083 9.06066 2.14662L11.7071 4.79306C12.0976 5.18359 12.0976 5.81675 11.7071 6.20728C11.3166 6.5978 10.6834 6.5978 10.2929 6.20728L9 4.91438V11.0859L10.2929 9.79297C10.6834 9.40244 11.3166 9.40244 11.7071 9.79297C12.0976 10.1835 12.0976 10.8167 11.7071 11.2072L9.06066 13.8536C8.47487 14.4394 7.52513 14.4394 6.93934 13.8536L4.29289 11.2072C3.90237 10.8167 3.90237 10.1835 4.29289 9.79297C4.68342 9.40244 5.31658 9.40244 5.70711 9.79297L7 11.0859V4.91438L5.70711 6.20728C5.31658 6.5978 4.68342 6.5978 4.29289 6.20728C3.90237 5.81675 3.90237 5.18359 4.29289 4.79306L6.93934 2.14662Z",fill:"currentColor"}))}function Oe(e){return o.a.createElement(re.a,ye({Enterprise:ve.a,Prisma16:ge,Prisma24:me},e))}var xe=n(40),je=n(14),we=n.n(je),Ce=h.a.div.withConfig({displayName:"HeadInnerStyles__StyledDragContainer",componentId:"sc-1sa0wng-0"})(["position:absolute;cursor:move;top:0;"," padding:",";"],Object(v.pick)({enterprise:Object(b.css)(["left:0;"]),prisma:Object(b.css)(["right:0;"])}),Object(v.pick)({enterprise:"9px 12px",prisma:{comfortable:"17px 4px 14px",compact:"9px 4px 6px"}})),Se=h.a.span.withConfig({displayName:"HeadInnerStyles__StyledMenuIcon",componentId:"sc-1sa0wng-1"})([""," color:",";position:relative;"],Object(v.pick)({prisma:Object(b.css)(["display:inline-flex;"]),enterprise:Object(b.css)(["padding-left:4px;"])}),Object(v.pick)({enterprise:v.variables.textGray,prisma:v.variables.contentColorDefault})),ke=h.a.span.withConfig({displayName:"HeadInnerStyles__StyledLabel",componentId:"sc-1sa0wng-2"})(["flex:0 1 auto;position:relative;word-wrap:break-word;word-break:break-word;"," "," "," "," "," + &{margin-left:",";}"],Object(v.pick)({enterprise:function(e){return"right"!==e.$align&&Object(b.css)(["display:flex;justify-content:space-between;"])},prisma:Object(b.css)(["display:flex;"])}),Object(v.pickVariant)("$truncate",{true:Object(b.css)(["overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"])}),Object(v.pickVariant)("$fill",{true:Object(b.css)(["flex:1 0 0px;"])}),Object(v.pickVariant)("$align",{right:Object(b.css)(["& > &{text-align:right;}"]),left:Object(b.css)(["& > &{text-align:left;}"]),center:Object(b.css)(["& > &{text-align:center;}"])}),Ce,Object(v.pick)({enterprise:"12px"})),Pe=h.a.div.withConfig({displayName:"HeadInnerStyles__Styled",componentId:"sc-1sa0wng-3"})([""," ",";position:relative;font-size:",";",";line-height:",";justify-content:",";padding:",";"," "," "," &[data-helper]{background-color:",";position:absolute;left:-10000px;top:-10000px;box-shadow:",";box-sizing:border-box;background-repeat:repeat-x;",";}@media print{background-image:none;}"],v.mixins.reset("flex"),v.mixins.clearfix(),Object(v.pick)({enterprise:"inherit",prisma:"12px"}),Object(v.pick)({prisma:Object(b.css)(["font-weight:bold;"])}),Object(v.pick)({enterprise:v.variables.lineHeight,prisma:"16px"}),Object(v.pickVariant)("$align",{center:"center",left:"flex-start",right:"flex-end"}),Object(v.pick)({enterprise:"6px 12px",prisma:{comfortable:"16px 10px",compact:"8px"}}),(function(e){return e.$hasActionsHead&&Object(b.css)(["padding:0;"])}),(function(e){return e.$dragging&&Object(b.css)(["opacity:0;"])}),(function(e){return e.$draggable&&Object(b.css)(["padding-left:",";-webkit-user-drag:element;user-select:none;"],Object(v.pick)({enterprise:"16px"}))}),Object(v.pick)({enterprise:{light:v.variables.accentColorL50,dark:v.variables.accentColorD50},prisma:v.mixins.overlayColors(v.variables.interactiveColorBackground,v.variables.interactiveColorOverlaySelected)}),Object(v.pick)({enterprise:v.variables.overlayShadow,prisma:v.variables.dragShadow}),Object(v.pick)({enterprise:Object(b.css)(["border:1px solid ",";"],v.variables.borderColor)})),Ee=h.a.span.withConfig({displayName:"HeadInnerStyles__StyledSortIcon",componentId:"sc-1sa0wng-4"})(["flex:0 0 auto;",";margin-top:-1px;"," color:",";",""],Object(v.pick)({enterprise:Object(b.css)(["right:0;"]),prisma:Object(b.css)(["left:0;"])}),Object(v.pick)({prisma:Object(b.css)(["margin-right:4px;"]),enterprise:Object(b.css)(["margin-left:10px;"])}),Object(v.pick)({enterprise:{light:v.variables.textGray,dark:v.variables.gray80}}),(function(e){return e.$sorted&&Object(b.css)(["color:",";"],Object(v.pick)({enterprise:v.variables.accentColor,prisma:v.variables.contentColorDefault}))})),_e=h.a.button.withConfig({displayName:"HeadInnerStyles__StyledResize",componentId:"sc-1sa0wng-5"})(["",";position:absolute;right:-5px;width:9px;top:0;bottom:0;z-index:1;cursor:col-resize;th:last-child > "," > &{right:0;width:5px;}&::-moz-focus-inner{border:0;padding:0;}&:focus{outline:none;&::before{content:'';position:absolute;background:",";box-shadow:",";left:4px;width:1px;top:0;bottom:0;}}"],v.mixins.reset("block"),Pe,v.variables.focusColor,v.variables.focusShadow),Te=h.a.th.withConfig({displayName:"HeadCellStyles__Styled",componentId:"sc-1hj81sa-0"})(["",";background-color:",";box-sizing:content-box;text-align:left;vertical-align:",";& + &{border-left:1px solid ",";}"," "," "," ",""],v.mixins.reset("table-cell"),Object(v.pick)({enterprise:{light:v.variables.gray92,dark:v.variables.black},prisma:v.variables.interactiveColorBackground}),(function(e){return e.$variant?"middle":"top"}),Object(v.pick)({enterprise:v.variables.backgroundColor,prisma:v.variables.backgroundColorPage}),(function(e){var t=e.$isFixed,n=e.$zIndex;return t&&Object(b.css)(["position:sticky;top:0;z-index:",";&:not(:first-child)::before{content:'';height:100%;position:absolute;top:0;bottom:0;box-shadow:-1px 0 0 0 ",";width:2px;border:0;left:0;margin-right:-2px;color:transparent;}&:not(:last-child)::after{content:'';height:100%;position:absolute;top:0;bottom:0;box-shadow:1px 0 0 0 ",";width:2px;border:0;right:0;margin-left:-2px;color:transparent;}"],n,Object(v.pick)({enterprise:v.variables.backgroundColor,prisma:v.variables.backgroundColorPage}),Object(v.pick)({enterprise:v.variables.backgroundColor,prisma:v.variables.backgroundColorPage}))}),(function(e){return e.$clickable&&Object(b.css)(["cursor:pointer;&:focus{box-shadow:",";outline:none;& > ","{color:",";background-color:",";}}&:hover{outline:none;& > ","{color:",";background-color:",";}}&:active{& > ","{background-color:",";}}"],v.variables.focusShadowInset,Pe,Object(v.pick)({enterprise:{light:v.variables.accentColorD10,dark:v.variables.linkColorHover}}),Object(v.pick)({prisma:v.variables.interactiveColorOverlaySelected}),Pe,Object(v.pick)({enterprise:{light:v.variables.accentColorD10,dark:v.variables.linkColorHover}}),Object(v.pick)({prisma:v.variables.interactiveColorOverlayHover}),Pe,Object(v.pick)({prisma:v.variables.interactiveColorOverlayActive}))}),(function(e){return e.$dragging&&Object(b.css)(["background-color:",";&:focus{box-shadow:none;}"],Object(v.pick)({enterprise:{light:v.variables.gray80,dark:v.variables.gray20},prisma:v.mixins.overlayColors(v.variables.backgroundColorPage,v.variables.interactiveColorOverlayDrag)}))}),Object(v.pickVariant)("$variant",{actions:Object(b.css)(["& > ","{padding-right:8px;}"],Pe),info:Object(b.css)(["& > ","{",";}"],Pe,Object(v.pick)({enterprise:Object(b.css)(["padding-top:7px;"]),prisma:{comfortable:Object(b.css)(["padding:16px 12px;"]),compact:Object(b.css)(["padding:6px 12px;"])}})),toggleAll:Object(b.css)(["& > ","{padding-top:",";}"],Pe,Object(v.pick)({prisma:{comfortable:"14px",compact:"7px"}}))})),De=h.a.div.withConfig({displayName:"HeadCellStyles__StyledGuideLine",componentId:"sc-1hj81sa-1"})([""," width:1px;position:absolute;background-color:",";height:100%;top:0;z-index:1;",""],v.mixins.reset("block"),Object(v.pick)({enterprise:v.variables.linkColor,prisma:v.variables.interactiveColorPrimary}),Object(v.pickVariant)("$position",{before:Object(b.css)(["float:left;",":not(:first-child) > &{margin-left:-1px;}"],Te),after:Object(b.css)(["right:0;"])})),Ie=h.a.td.withConfig({displayName:"RowDragCellStyles__Styled",componentId:"sc-9kbaj2-0"})([""," box-sizing:content-box;touch-action:none;width:",";& + &{border-left:",";}&:focus{box-shadow:",";outline:none;}&:hover{background-color:",";outline:none;}&:active{background-color:",";}",""],v.mixins.reset("table-cell"),Object(v.pick)({enterprise:"32px",prisma:"36px"}),Object(v.pick)({enterprise:"1px solid ".concat(v.variables.backgroundColor),prisma:"1px solid ".concat(v.variables.interactiveColorBorder)}),v.variables.focusShadowInset,Object(v.pick)({enterprise:{light:v.variables.accentColorL50,dark:v.variables.accentColorD50},prisma:v.variables.interactiveColorOverlayHover}),Object(v.pick)({prisma:v.variables.interactiveColorOverlayActive}),(function(e){return e.$dragging&&Object(b.css)(["&:active{background-color:",";}"],Object(v.pick)({prisma:v.mixins.overlayColors(v.variables.backgroundColorPage,v.variables.interactiveColorOverlayDrag)}))})),Re=h.a.div.withConfig({displayName:"RowDragCellStyles__StyledGuideLine",componentId:"sc-9kbaj2-1"})([""," width:100%;height:1px;position:absolute;left:0;z-index:1;",""],v.mixins.reset("block"),Object(v.pickVariant)("$position",{before:Object(b.css)(["&::before{content:' ';border-top:1px solid;border-color:",";width:100%;height:1px;top:0;position:absolute;}"],Object(v.pick)({enterprise:v.variables.linkColor,prisma:v.variables.interactiveColorPrimary})),after:Object(b.css)(["&::after{bottom:0;background-color:",";}"],Object(v.pick)({enterprise:v.variables.linkColor,prisma:v.variables.interactiveColorPrimary}))})),Le=h.a.div.withConfig({displayName:"RowDragCellStyles__StyledDrag",componentId:"sc-9kbaj2-2"})([""," ",";justify-content:center;cursor:move;"," "," &[data-helper]{background-color:",";position:absolute;left:-10000px;top:-10000px;box-shadow:",";box-sizing:border-box;background-repeat:repeat-x;",";}@media print{background-image:none;}"],v.mixins.reset("flex"),v.mixins.clearfix(),(function(e){return e.$dragging&&Object(b.css)(["opacity:0;"])}),(function(e){return e.$draggable&&Object(b.css)(["padding:",";-webkit-user-drag:element;user-select:none;"],Object(v.pick)({enterprise:"9px 0",prisma:{comfortable:"16px 17px 15px",compact:"9px 17px 6px"}}))}),Object(v.pick)({enterprise:{light:v.variables.accentColorL50,dark:v.variables.accentColorD50},prisma:v.mixins.overlayColors(v.variables.interactiveColorBackground,v.variables.interactiveColorOverlaySelected)}),Object(v.pick)({enterprise:v.variables.overlayShadow,prisma:v.variables.dragShadow}),Object(v.pick)({enterprise:Object(b.css)(["border:1px solid ",";"],v.variables.borderColor)})),Ae=h.a.div.withConfig({displayName:"DragHandleStyles__StyledDrag",componentId:"sc-9eqfn5-0"})(["display:block;cursor:move;background:",";",""],v.variables.draggableBackground,Object(v.pick)({enterprise:Object(b.css)(["width:7px;height:14px;"]),prisma:Object(b.css)(["width:6px;height:20px;margin-top:-3px;opacity:0;",":focus &,",":hover &,"," &,[data-helper] &{opacity:1;}"],Te,Te,Ie)})),Me={screenReaderContent:i.a.string};function Be(e){var t=e.screenReaderContent;return o.a.createElement(Ae,null,o.a.createElement(we.a,null,t))}Be.propTypes=Me;var Ne=Be,ze=n(27);function Fe(){return Fe=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Fe.apply(this,arguments)}function $e(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,a=void 0;try{for(var i,l=e[Symbol.iterator]();!(r=(i=l.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){o=!0,a=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw a}}return n}}(e,t)||He(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function He(e,t){if(e){if("string"==typeof e)return Ve(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Ve(e,t):void 0}}function Ve(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var qe={align:i.a.oneOf(["left","center","right"]),columnId:i.a.any,hasActionsHead:i.a.bool,id:i.a.string,index:i.a.number,isMenu:i.a.bool,label:i.a.node,onAutosizeColumn:i.a.func,onDragEnd:i.a.func,onDragStart:i.a.func,onRequestResize:i.a.func,resizable:i.a.bool,sortDir:i.a.string,truncate:i.a.bool,width:i.a.oneOfType([i.a.number,i.a.oneOf(["auto"])])};function We(e){var t,n=e.index,a=e.columnId,i=e.id,c=e.width,s=e.onDragEnd,u=e.onAutosizeColumn,d=e.align,b=void 0===d?"left":d,h=e.label,v=e.hasActionsHead,y=void 0!==v&&v,m=e.isMenu,O=void 0!==m&&m,x=e.onDragStart,j=e.onRequestResize,w=e.resizable,C=void 0===w||w,S=e.sortDir,k=void 0===S?void 0:S,P=e.truncate,E=void 0===P||P,_=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["index","columnId","id","width","onDragEnd","onAutosizeColumn","align","label","hasActionsHead","isMenu","onDragStart","onRequestResize","resizable","sortDir","truncate"]),T=$e(Object(r.useState)(),2),D=T[0],I=T[1],R=$e(Object(r.useState)(!1),2),L=R[0],A=R[1],M=$e(Object(r.useState)(!1),2),B=M[0],N=M[1],z=$e(Object(r.useState)(0),2),F=z[0],$=z[1],H=$e(Object(r.useState)(0),2),V=H[0],q=H[1],W=Object(r.useRef)(null);if(Object(r.useEffect)((function(){return function(){return null==D?void 0:D.remove()}}),[D]),"auto"===c){var K,U=W.current,Z=null==U||null===(K=U.parentElement)||void 0===K?void 0:K.getBoundingClientRect();t=null==Z?void 0:Z.width}else t=c;var G,X=!!x,Y=Object(g.a)();return o.a.createElement(Pe,Fe({draggable:X||void 0,onDragStart:X?function(e){var t,r=Object(ze.a)(),o=W.current;if(e.dataTransfer.setDragImage&&(null==o?void 0:o.parentElement)){var i=o.parentElement.getBoundingClientRect(),l=o.cloneNode(!0);l.style.width="".concat(i.width,"px"),l.style.height="".concat(i.height,"px"),l.setAttribute("data-helper","true"),r.body.appendChild(l),e.dataTransfer.setDragImage(l,e.clientX-i.left,e.clientY-i.top),N(!0),I(l)}e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text",null!==(t=null==o?void 0:o.textContent)&&void 0!==t?t:""),null==x||x(n,a)}:void 0,onDragEnd:X?function(){I(void 0),N(!1),null==s||s()}:void 0,ref:W,$hasActionsHead:!!y,$align:b,$draggable:X,$dragging:!!B},Object(l.omit)(_,[].concat(function(e){if(Array.isArray(e))return Ve(e)}(G=Object.keys(We.propTypes))||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(G)||He(G)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),["id"]))),L&&o.a.createElement(o.a.Fragment,null,o.a.createElement(p.a,{target:Y,eventType:"mouseup",listener:function(){A(!1)}}),o.a.createElement(p.a,{target:Y,eventType:"mousemove",listener:function(e){var t=F-e.clientX,r=Math.max(V-t,16);void 0!==n&&(null==j||j(e,{index:n,columnId:a,id:i,width:r}))}})),j&&C&&o.a.createElement(_e,{onMouseDown:function(e){if("auto"===c){var n,r=W.current,o=null==r||null===(n=r.parentElement)||void 0===n?void 0:n.getBoundingClientRect();t=null==o?void 0:o.width}else t=c;void 0!==t&&(e.preventDefault(),$(e.clientX),q(t||0),A(!0))},onDoubleClick:function(e){void 0!==n&&(null==u||u(e,{index:n,columnId:a}))},onKeyDown:function(e){var r=Object(f.keycode)(e.nativeEvent);if(void 0!==j&&void 0!==n){if("auto"===c){var o,l=W.current,s=null==l||null===(o=l.parentElement)||void 0===o?void 0:o.getBoundingClientRect();t=null==s?void 0:s.width}else t=c;if(void 0!==t){if("left"===r){e.preventDefault();var u=Math.max(t-10,20);j(e,{index:n,columnId:a,id:i,width:u})}"right"===r&&(e.preventDefault(),j(e,{index:n,columnId:a,id:i,width:t+10}))}}},"data-test":"resize"}),X&&o.a.createElement(Ce,null,o.a.createElement(Ne,{screenReaderContent:Object(ee._)("Press left or right arrow key to reorder the columns.")})),o.a.createElement(ke,{$align:b,$truncate:E,$fill:O},h,O&&o.a.createElement(Se,null,o.a.createElement(xe.a,{enterpriseSize:.5,prismaSize:"small",screenReaderText:Object(ee._)("Click to open menu")}))),k&&o.a.createElement(Ee,{$sorted:"none"!==k},"none"===k&&o.a.createElement(Oe,{prismaSize:"small",screenReaderText:Object(ee._)("Click to sort")}),"asc"===k&&o.a.createElement(be,{prismaSize:"small",inline:!0,screenReaderText:Object(ee._)("Press to sort descending")}),"desc"===k&&o.a.createElement(ce,{prismaSize:"small",inline:!0,screenReaderText:Object(ee._)("Press to sort ascending")})))}We.propTypes=qe;var Ke=We,Ue=Object(r.createContext)({});Ue.displayName="Table";var Ze=Ue;function Ge(e){return Ge="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ge(e)}function Xe(){return Xe=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Xe.apply(this,arguments)}function Ye(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Qe(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function Je(e,t){return Je=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},Je(e,t)}function et(e,t){return!t||"object"!==Ge(t)&&"function"!=typeof t?tt(e):t}function tt(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function nt(e){return nt=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},nt(e)}function rt(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var ot={align:i.a.oneOf(["left","center","right"]),children:i.a.node,columnId:i.a.any,elementRef:i.a.oneOfType([i.a.func,i.a.object]),hasActionsHead:i.a.bool,index:i.a.number,onAutosizeColumn:i.a.func,onSort:i.a.func,onDragStart:i.a.func,onKeyDown:i.a.func,onClick:i.a.func,onRequestMoveColumn:i.a.func,onRequestResize:i.a.func,resizable:i.a.bool,showGuideline:i.a.oneOf(["none","before","after"]),sortDir:i.a.oneOf(["asc","desc","none"]),sortKey:i.a.string,truncate:i.a.bool,visible:i.a.bool,width:i.a.oneOfType([i.a.number,i.a.oneOf(["auto"])]),variant:i.a.oneOf(["toggleAll","info","actions"]),zIndex:i.a.number},at=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&Je(e,t)}(c,e);var t,n,r,a,i=(r=c,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=nt(r);if(a){var n=nt(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return et(this,e)});function c(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,c),rt(tt(t=i.call(this,e)),"handleClick",(function(e){var n,r;if("resize"!==e.target.getAttribute("data-test")&&t.props.onSort&&void 0!==t.props.index){var o=t.props,a=o.sortKey,i=o.sortDir,l=o.id,c=o.index,s=o.columnId;t.props.onSort(e,{sortKey:a,sortDir:i,id:l,columnId:s,index:c})}null===(n=(r=t.props).onClick)||void 0===n||n.call(r)})),rt(tt(t),"handleKeyDown",(function(e){var n=t.props,r=n.columnId,o=n.index,a=n.onKeyDown,i=n.onRequestMoveColumn;"resize"!==e.target.getAttribute("data-test")&&("enter"===Object(f.keycode)(e.nativeEvent)?t.handleClick(e):"left"===Object(f.keycode)(e.nativeEvent)&&void 0!==o&&o>0?null==i||i({fromIndex:o,toIndex:o-1,columnId:r}):"right"===Object(f.keycode)(e.nativeEvent)&&void 0!==o&&(null==i||i({fromIndex:o,toIndex:o+1,columnId:r}))),void 0!==o&&(null==a||a(e,{index:o,columnId:r}))})),rt(tt(t),"handleDragStart",(function(e,n){var r,o;t.setState({isDragging:!0}),null===(r=(o=t.props).onDragStart)||void 0===r||r.call(o,e,n)})),rt(tt(t),"handleDragEnd",(function(){t.setState({isDragging:!1})})),rt(tt(t),"sortDirAriaMapping",{asc:"ascending",desc:"descending",none:"none"}),t.state={isDragging:!1},t}return t=c,(n=[{key:"render",value:function(){var e,t=this.props,n=t.align,r=t.children,a=t.columnId,i=t.elementRef,s=t.hasActionsHead,u=t.id,p=t.index,f=t.onAutosizeColumn,d=t.onClick,b=t.onDragStart,h=t.onRequestResize,v=t.onSort,y=t.resizable,m=t.showGuideline,g=t.sortDir,O=t.style,x=t.variant,j=t.truncate,w=t.visible,C=t.width,S=t.zIndex,k=!!b,P=!!v&&!!g,E=void 0!==d,_=Object(l.merge)(O,{width:C}),T=!s&&j,D=this.context.headType;return o.a.createElement(Te,Xe({style:_,ref:i,"aria-sort":v&&(this.sortDirAriaMapping[g]||"none"),"data-test":"head-cell","data-test-label":Object(l.isString)(r)?r:void 0,"data-test-sort-dir":v&&g,id:w?u:void 0,onClick:v||E?this.handleClick:void 0,tabIndex:w&&(k||v||E)?0:void 0,$dragging:this.state.isDragging||void 0,$clickable:k||P||E,$variant:x,$zIndex:S,$isFixed:"fixed"===D},Object(l.omit)(this.props,[].concat(function(e){if(Array.isArray(e))return Ye(e)}(e=Object.keys(c.propTypes))||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return Ye(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Ye(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),["id","style"])),{onKeyDown:k||v||E?this.handleKeyDown:void 0}),o.a.createElement(Ke,{label:r,align:n,columnId:a,hasActionsHead:s,id:u,index:p,resizable:w&&y,onDragStart:b?this.handleDragStart:void 0,onDragEnd:b?this.handleDragEnd:void 0,onAutosizeColumn:f,onRequestResize:h,sortDir:v&&g,truncate:T,width:C}),"none"!==m&&o.a.createElement(De,{$position:m}))}}])&&Qe(t.prototype,n),c}(r.Component);rt(at,"splunkUiType","Table.HeadCell"),rt(at,"propTypes",ot),rt(at,"defaultProps",{align:"left",resizable:!0,showGuideline:"none",sortDir:"none",truncate:!0,visible:!0,zIndex:1}),rt(at,"contextType",Ze);var it=at,lt=n(111),ct=n.n(lt),st=n(29);function ut(){var e=Object(v.useSplunkTheme)().family,t=Object(ee._)("More Information");return"prisma"===e?o.a.createElement(st.a,{screenReaderText:t,prismaSize:"small"}):o.a.createElement(ct.a,{screenReaderText:t})}var pt=n(16),ft=n.n(pt),dt=n(20),bt=n.n(dt),ht=n(52),vt=n.n(ht),yt=n(67),mt=n(65);function gt(e){return gt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},gt(e)}function Ot(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function xt(e,t){return xt=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},xt(e,t)}function jt(e,t){return!t||"object"!==gt(t)&&"function"!=typeof t?wt(e):t}function wt(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function Ct(e){return Ct=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},Ct(e)}function St(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var kt={activeElementId:i.a.string,dataId:i.a.oneOfType([i.a.string,i.a.number]),index:i.a.number,onDragEnd:i.a.func,onDragStart:i.a.func,onKeyDown:i.a.func,onRequestMoveRow:i.a.func,rowSpan:i.a.number,showRowGuideline:i.a.oneOf(["none","before","after"])},Pt=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&xt(e,t)}(l,e);var t,n,r,a,i=(r=l,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=Ct(r);if(a){var n=Ct(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return jt(this,e)});function l(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,l),St(wt(t=i.call(this,e)),"cloneEl",void 0),St(wt(t),"el",null),St(wt(t),"handleMount",(function(e){t.el=e})),St(wt(t),"handleDragStart",(function(e){var n,r,o,a,i,l=Object(ze.a)();if(e.stopPropagation(),e.dataTransfer.setDragImage&&(null===(n=t.el)||void 0===n?void 0:n.parentElement)){var c=t.el.parentElement.getBoundingClientRect();t.cloneEl=t.el.cloneNode(!0),t.cloneEl.style.width="".concat(c.width,"px"),t.cloneEl.style.height="".concat(c.height,"px"),t.cloneEl.setAttribute("data-helper","true"),l.body.appendChild(t.cloneEl),e.dataTransfer.setDragImage(t.cloneEl,e.clientX-c.left,e.clientY-c.top),t.setState({isDragging:!0})}e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text",null!==(r=null===(o=t.el)||void 0===o?void 0:o.textContent)&&void 0!==r?r:""),null===(a=(i=t.props).onDragStart)||void 0===a||a.call(i,t.props.index,t.props.dataId)})),St(wt(t),"handleDragEnd",(function(){var e,n;t.cleanupDrag(),t.setState({isDragging:!1}),null===(e=(n=t.props).onDragEnd)||void 0===e||e.call(n)})),St(wt(t),"handleKeyDown",(function(e){var n=t.props,r=n.onRequestMoveRow,o=n.index,a=n.dataId,i=n.onKeyDown,l=Object(f.keycode)(e.nativeEvent);"up"!==l&&"down"!==l||e.preventDefault(),"up"===l&&void 0!==o&&o>0?null==r||r({fromIndex:o,toIndex:o-1,dataId:a}):"down"===l&&void 0!==o&&(null==r||r({fromIndex:o,toIndex:o+1,dataId:a})),void 0!==o&&(null==i||i(e,{index:o,dataId:a}))})),t.state={isDragging:!1},t}return t=l,(n=[{key:"componentDidMount",value:function(){var e,t,n=this.props;n.dataId===n.activeElementId&&(null===(e=this.el)||void 0===e||null===(t=e.parentElement)||void 0===t||t.focus())}},{key:"componentWillUnmount",value:function(){this.cleanupDrag()}},{key:"cleanupDrag",value:function(){var e;this.cloneEl&&(this.cloneEl.remove?this.cloneEl.remove():null===(e=this.cloneEl.parentNode)||void 0===e||e.removeChild(this.cloneEl),this.cloneEl=void 0)}},{key:"render",value:function(){var e=this.props,t=e.showRowGuideline,n=e.rowSpan;return o.a.createElement(Ie,{$align:"center","data-test":"drag",$dragging:this.state.isDragging,tabIndex:0,rowSpan:n,onKeyDown:this.handleKeyDown},"none"!==t&&o.a.createElement(Re,{$position:t}),o.a.createElement(Le,{draggable:!0,$draggable:!0,$dragging:this.state.isDragging||void 0,onDragStart:this.handleDragStart,onDragEnd:this.handleDragEnd,ref:this.handleMount},o.a.createElement(Ne,{screenReaderContent:Object(ee._)("Press up or down arrow key to reorder the columns.")})))}}])&&Ot(t.prototype,n),l}(r.Component);St(Pt,"propTypes",kt),St(Pt,"defaultProps",{showRowGuideline:"none"});var Et=Pt,_t=h.a.tr.withConfig({displayName:"RowStyles__StyledStripeNone",componentId:"f0igqq-0"})([""," background-color:",";",";@media print{background-color:none;}"," ",""],v.mixins.reset("table-row"),Object(v.pick)({prisma:v.variables.transparent}),(function(e){return e.$clickable&&Object(b.css)(["cursor:pointer;&:hover{background-color:",";}&:focus{box-shadow:",";}"],Object(v.pick)({enterprise:{light:v.variables.accentColorL50,dark:v.variables.accentColorD50},prisma:v.variables.interactiveColorOverlayHover}),v.variables.focusShadowInset)}),(function(e){var t=e.disabled,n=e.$expandable;return!t&&!n&&Object(b.css)(["&:not([data-expansion-row='true']){&:hover{background-color:",";}}"],Object(v.pick)({prisma:v.variables.interactiveColorOverlayHover}))}),(function(e){return e.disabled&&Object(b.css)(["color:",";"],Object(v.pick)({prisma:v.variables.contentColorDisabled}))})),Tt=h()(_t).withConfig({displayName:"RowStyles__StyledStripeOdd",componentId:"f0igqq-1"})(["background-color:",";"],Object(v.pick)({enterprise:{dark:v.variables.gray22},prisma:v.variables.transparent})),Dt=h()(_t).withConfig({displayName:"RowStyles__StyledStripeEven",componentId:"f0igqq-2"})(["background-color:",";"],Object(v.pick)({enterprise:{light:v.variables.gray96,dark:v.variables.gray20},prisma:v.variables.transparent})),It=h()(J).withConfig({displayName:"RowStyles__StyledCellSelectionDisabled",componentId:"f0igqq-3"})(["&&{cursor:not-allowed;}"]),Rt=h()(J).withConfig({displayName:"RowStyles__StyledCellExpansionDisabled",componentId:"f0igqq-4"})(["width:",";"],Object(v.pick)({enterprise:"35px",prisma:"40px"})),Lt=n(72),At=n.n(Lt),Mt=h()(At.a).withConfig({displayName:"ToggleStyles__StyledSwitch",componentId:"sc-1x3ikch-0"})(["margin:",";justify-content:center;"],Object(v.pickVariant)("$allRows",{true:{enterprise:"-6px 0",prisma:"-10px 0"},false:"-6px 0"}));function Bt(){return Bt=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Bt.apply(this,arguments)}var Nt={allRows:i.a.bool,disabled:i.a.bool,onClick:i.a.func,selected:i.a.oneOf([!0,!1,"some"])};function zt(e){var t=e.allRows,n=void 0!==t&&t,r=e.disabled,a=e.selected,i=void 0!==a&&a,l=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["allRows","disabled","selected"]),c=n?Object(ee._)("No rows selected"):Object(ee._)("Row unselected");return"some"===i?c=Object(ee._)("Some rows selected"):i&&(c=n?Object(ee._)("All rows selected"):Object(ee._)("Row selected")),o.a.createElement(Mt,Bt({$allRows:n},l,{interactive:!1,disabled:r,value:"",selected:i,"aria-label":c,selectedLabel:n?Object(ee._)("All rows selected"):Object(ee._)("Row selected"),unselectedLabel:n?Object(ee._)("No rows selected"):Object(ee._)("Row unselected"),someSelectedLabel:Object(ee._)("Some rows selected")}))}zt.propTypes=Nt;var Ft=zt;function $t(e){return $t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},$t(e)}function Ht(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function Vt(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function qt(e,t){return qt=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},qt(e,t)}function Wt(e,t){return!t||"object"!==$t(t)&&"function"!=typeof t?Kt(e):t}function Kt(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function Ut(e){return Ut=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},Ut(e)}function Zt(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Gt(){return Gt=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Gt.apply(this,arguments)}var Xt={odd:Tt,even:Dt,none:_t},Yt={activeElementId:i.a.string,actionPrimary:i.a.element,actionsSecondary:i.a.element,children:i.a.node,data:i.a.any,dataId:i.a.oneOfType([i.a.string,i.a.number]),disabled:i.a.bool,draggable:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),expandable:i.a.bool,expanded:i.a.bool,expansionRow:i.a.oneOfType([i.a.element,i.a.arrayOf(i.a.element)]),actions:i.a.bool,index:i.a.number,movableColumns:i.a.bool,onClick:i.a.func,onDragStart:i.a.func,onExpansion:i.a.func,onKeyDown:i.a.func,onRequestMoveRow:i.a.func,onRequestToggle:i.a.func,selected:i.a.bool,showRowGuideline:i.a.oneOf(["none","before","after"]),stripe:i.a.oneOf(["odd","even","none"])},Qt=o.a.forwardRef((function(e,t){return o.a.createElement(vt.a,Gt({content:Object(ee._)("Actions"),contentRelationship:"label"},e),o.a.createElement(ft.a,{appearance:"secondary","data-test":"actions-secondary-toggle",icon:o.a.createElement(mt.a,null),elementRef:t}))})),Jt=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&qt(e,t)}(s,e);var t,n,a,i,c=(a=s,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=Ut(a);if(i){var n=Ut(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return Wt(this,e)});function s(){var e;Ht(this,s);for(var t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];return Zt(Kt(e=c.call.apply(c,[this].concat(n))),"elementRef",null),Zt(Kt(e),"handleClick",(function(t){for(var n=e.props,r=n.data,o=n.onClick,a=t.target;a&&e.elementRef!==a;){if("BUTTON"===a.tagName||"A"===a.tagName)return;a=a.parentNode}t.defaultPrevented||null==o||o(t,r)})),Zt(Kt(e),"handleKeyDown",(function(t){var n=e.props,r=n.data,o=n.onClick,a=n.onKeyDown;"enter"===Object(f.keycode)(t.nativeEvent)&&o&&o(t,r),null==a||a(t)})),Zt(Kt(e),"handleToggle",(function(t){var n=e.props,r=n.data,o=n.disabled,a=n.onRequestToggle;o||(t.preventDefault(),null==a||a(t,r))})),Zt(Kt(e),"handleExpansion",(function(t){var n=e.props,r=n.data,o=n.onExpansion;t.preventDefault(),null==o||o(t,r)})),Zt(Kt(e),"renderActionPrimary",(function(){var t=e.props.actionPrimary;return t&&t.props.onClick?Object(r.cloneElement)(t,{onClick:function(n){var r,o;return n.preventDefault(),null===(r=(o=t.props).onClick)||void 0===r?void 0:r.call(o,n,e.props.data)}}):t})),Zt(Kt(e),"renderActionsSecondary",(function(){var t=e.props.actionsSecondary;if(t&&t.props.children){var n=r.Children.toArray(t.props.children).filter(r.isValidElement).map((function(t){return t.props.onClick?Object(r.cloneElement)(t,{onClick:function(n){var r,o;return n.preventDefault(),null===(r=(o=t.props).onClick)||void 0===r?void 0:r.call(o,n,e.props.data)}}):t}));return Object(r.cloneElement)(t,{children:n})}return t})),Zt(Kt(e),"handleMount",(function(t){Object(m.a)(e.props.elementRef,t),e.elementRef=t})),e}return t=s,(n=[{key:"render",value:function(){var e=this.props,t=e.actions,n=e.actionPrimary,a=e.actionsSecondary,i=e.activeElementId,c=e.children,s=e.dataId,u=e.disabled,p=e.draggable,f=(e.elementRef,e.expandable),d=e.expanded,b=e.expansionRow,h=e.index,v=e.movableColumns,y=e.onClick,m=e.onDragStart,g=(e.onExpansion,e.onRequestMoveRow),O=e.onRequestToggle,x=e.selected,j=e.showRowGuideline,w=e.stripe,C=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["actions","actionPrimary","actionsSecondary","activeElementId","children","dataId","disabled","draggable","elementRef","expandable","expanded","expansionRow","index","movableColumns","onClick","onDragStart","onExpansion","onRequestMoveRow","onRequestToggle","selected","showRowGuideline","stripe"]),S=y?r.Children.toArray(c).filter(r.isValidElement).map((function(e){return Object(r.cloneElement)(e,{appearance:"rowLink",disabled:u})})):r.Children.toArray(c).map((function(e){return Object(r.cloneElement)(e,{disabled:u})})),k=Xt[w],P=u?It:J,E=d?r.Children.count(b)+1:void 0,_=v?"false":void 0,T=o.a.createElement(Qt,null);return o.a.createElement(k,Gt({"data-test":"row","data-test-selected":O?x:void 0,$clickable:!!y,"data-has-movable-columns":v?"true":void 0,disabled:!!u,$expandable:!!f,ref:this.handleMount,tabIndex:y?0:void 0},Object(l.omit)(C,"data"),{onClick:y?this.handleClick:void 0,onKeyDown:this.handleKeyDown,$rowSelected:!(!O||!x)}),p&&o.a.createElement(Et,{activeElementId:i,dataId:s,"data-movable-column":_,index:h,onRequestMoveRow:g,onDragStart:m,rowSpan:E,showRowGuideline:j}),O&&o.a.createElement(P,{appearance:y?"rowLink":"data","data-test":"toggle",variant:"toggle","data-movable-column":_,onClick:this.handleToggle,rowSpan:E,role:"checkbox","aria-checked":x},o.a.createElement(Ft,{disabled:u,selected:x})),f&&b&&o.a.createElement(J,{align:"center",appearance:"data","aria-expanded":d,"aria-label":Object(ee._)("Expandable row"),"data-movable-column":_,"data-test":"expand",expand:d,onClick:this.handleExpansion,rowSpan:E,variant:"expand"},o.a.createElement("div",{"aria-hidden":!0,title:d?Object(ee._)("Collapse row"):Object(ee._)("Expand row")},d?o.a.createElement(yt.a,{prismaSize:"small"}):o.a.createElement(st.a,{prismaSize:"small"}))),f&&!b&&o.a.createElement(Rt,{variant:"expand","data-movable-column":_}),S,t&&!n&&!a&&o.a.createElement(J,{align:"right",appearance:u?"data":"rowLink","data-test":"row-actions",variant:"actions","data-movable-column":_}),(n||a)&&o.a.createElement(J,{align:"right",appearance:"rowLink","data-test":"row-actions",variant:"actions","data-movable-column":_},n&&this.renderActionPrimary(),a&&o.a.createElement(bt.a,{toggle:T},this.renderActionsSecondary())))}}])&&Vt(t.prototype,n),s}(r.Component);Zt(Jt,"splunkUiType","Table.Row"),Zt(Jt,"propTypes",Yt),Zt(Jt,"defaultProps",{stripe:"none"});var en=Jt,tn=h.a.thead.withConfig({displayName:"HeadStyles__Styled",componentId:"iap21t-0"})(["",";"],v.mixins.reset("table-header-group")),nn=h()(it).withConfig({displayName:"HeadStyles__StyledToggleAll",componentId:"iap21t-1"})(["width:",";"],Object(v.pick)({enterprise:"42px",prisma:"40px"})),rn=h()(it).withConfig({displayName:"HeadStyles__StyledInfo",componentId:"iap21t-2"})(["width:",";"],Object(v.pick)({enterprise:"32px",prisma:"40px"})),on=h()(it).withConfig({displayName:"HeadStyles__StyledDragRow",componentId:"iap21t-3"})(["width:",";"],Object(v.pick)({enterprise:"32px",prisma:"40px"}));function an(e){return an="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},an(e)}function ln(){return ln=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},ln.apply(this,arguments)}function cn(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function sn(e,t){return sn=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},sn(e,t)}function un(e,t){return!t||"object"!==an(t)&&"function"!=typeof t?pn(e):t}function pn(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function fn(e){return fn=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},fn(e)}function dn(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var bn={actions:i.a.arrayOf(i.a.node),actionsColumnWidth:i.a.number,children:i.a.node,dragPosition:i.a.number,dragIndex:i.a.number,elementRef:i.a.oneOfType([i.a.func,i.a.object]),hasDragColumn:i.a.bool,hasInfoColumn:i.a.bool,onAutosizeColumn:i.a.func,onDragStart:i.a.func,onRequestMoveColumn:i.a.func,onRequestResizeColumn:i.a.func,onRequestToggleAllRows:i.a.func,rowSelection:i.a.oneOf(["all","some","none"])},hn=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&sn(e,t)}(u,e);var t,n,a,i,c,s=(i=u,c=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=fn(i);if(c){var n=fn(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return un(this,e)});function u(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,u),dn(pn(t=s.call(this,e)),"cells",void 0),dn(pn(t),"el",null),dn(pn(t),"onRequestMoveColumn",(function(e){var n,o,a=e.columnId,i=e.fromIndex,l=e.toIndex;l<r.Children.toArray(t.props.children).length&&(null===(n=(o=t.props).onRequestMoveColumn)||void 0===n||n.call(o,{fromIndex:i,toIndex:l,columnId:a}))})),dn(pn(t),"handleMount",(function(e){t.el=e,Object(m.a)(t.props.elementRef,e)})),dn(pn(t),"handleDragStart",(function(e,n){var r,o,a=Object(g.a)();t.setState({dragColumnId:n}),a.addEventListener("dragend",t.handleDragEnd),null===(r=(o=t.props).onDragStart)||void 0===r||r.call(o,{dragIndex:e})})),dn(pn(t),"handleDragEnd",(function(){var e,n,r=t.state.dragColumnId,o=t.props.dragIndex,a=t.calculateGuideIndex(),i=void 0!==o&&o<a?a-1:a;void 0!==o&&o!==i&&(null===(e=(n=t.props).onRequestMoveColumn)||void 0===e||e.call(n,{fromIndex:o,toIndex:i,columnId:r})),t.cleanupDrag()})),t.state={dragColumnId:void 0},t}return t=u,a=[{key:"validateChildrenWidth",value:function(e){}}],(n=[{key:"componentDidUpdate",value:function(){}},{key:"componentWillUnmount",value:function(){this.cleanupDrag()}},{key:"getCellWidths",value:function(){var e,t,n,r=Object(g.a)();return Array.from(null!==(e=null===(t=this.el)||void 0===t||null===(n=t.firstElementChild)||void 0===n?void 0:n.children)&&void 0!==e?e:[]).map((function(e){var t=r.getComputedStyle(e);return e.clientWidth-parseFloat(t.getPropertyValue("padding-right"))-parseFloat(t.getPropertyValue("padding-left"))}))}},{key:"getClientHeight",value:function(){var e;return null===(e=this.el)||void 0===e?void 0:e.clientHeight}},{key:"getEl",value:function(){return this.el}},{key:"calculateGuideIndex",value:function(){var e,t,n,r=this.props,o=r.dragIndex,a=r.dragPosition,i=r.hasInfoColumn,c=r.hasDragColumn,s=r.onRequestToggleAllRows;if(void 0===this.props.dragPosition||!this.el)return-1;this.cells=Array.from(null!==(e=null===(t=this.el)||void 0===t||null===(n=t.firstElementChild)||void 0===n?void 0:n.children)&&void 0!==e?e:[]).slice(i?1:0).slice(c?1:0).slice(s?1:0);var u=Object(l.findIndex)(this.cells,(function(e){var t=e.getBoundingClientRect();return void 0!==a&&a>t.left&&a<t.right}));if(-1===u){var p=this.el.getBoundingClientRect();return void 0!==a&&a<p.left?0:this.cells.length}return void 0!==o&&u>o?u+1:u}},{key:"cleanupDrag",value:function(){Object(g.a)().removeEventListener("dragend",this.handleDragEnd),this.cells=void 0}},{key:"render",value:function(){var e=this,t=this.props,n=t.actions,a=t.actionsColumnWidth,i=t.children,c=t.hasDragColumn,s=t.hasInfoColumn,p=t.onAutosizeColumn,f=t.onRequestMoveColumn,d=t.onRequestResizeColumn,b=t.onRequestToggleAllRows,h=t.rowSelection,v=this.calculateGuideIndex(),y=r.Children.toArray(i).filter(r.isValidElement),m=y.length+(n.length||a?1:0),g=y.map((function(t,n,o){var a="none";return v===o.length&&n+1===o.length?a="after":v===n&&(a="before"),Object(r.cloneElement)(t,{index:n,showGuideline:a,onRequestResize:d,onDragStart:f?e.handleDragStart:void 0,onRequestMoveColumn:f?e.onRequestMoveColumn:void 0,onAutosizeColumn:p,key:t.key||t.props.columnId||n,zIndex:m-n})})),O=void 0===h?void 0:{all:!0,none:!1,some:"some"}[h],x="some"===O?"mixed":O,j=a||48;return o.a.createElement(tn,ln({ref:this.handleMount,"data-test":"head"},Object(l.omit)(this.props,Object(l.keys)(u.propTypes))),o.a.createElement(en,null,c&&o.a.createElement(on,{key:"drag_rows_head_cell","data-test":"drag-rows-head-cell",align:"center",resizable:!1,zIndex:m+3}),b&&o.a.createElement(nn,{key:"toggle_all","data-test":"toggle-all",resizable:!1,align:"center",onClick:b,variant:"toggleAll",truncate:!1,role:"checkbox","aria-checked":x,zIndex:m+2},o.a.createElement(Ft,{selected:O,allRows:!0})),s&&o.a.createElement(rn,{key:"more_info_head_cell","data-test":"more-info-head-cell",align:"center",resizable:!1,variant:"info",zIndex:m+1},o.a.createElement(ut,null)),g,n.length>0&&o.a.createElement(it,{hasActionsHead:!0,key:"actions_head_cell","data-test":"actions-head-cell",align:"right",resizable:!1,width:j,style:{minWidth:j},variant:"actions",zIndex:1},n),0===n.length&&a&&o.a.createElement(it,{key:"actions_head_cell","data-test":"actions-head-cell",align:"right",resizable:!1,width:a,style:{minWidth:a},variant:"actions",zIndex:1}," ")))}}])&&cn(t.prototype,n),a&&cn(t,a),u}(r.Component);dn(hn,"splunkUiType","Table.Head"),dn(hn,"propTypes",bn),dn(hn,"defaultProps",{actions:[]});var vn=hn,yn=n(11),mn=n(18),gn=n.n(mn);function On(e){return On="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},On(e)}function xn(){return xn=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},xn.apply(this,arguments)}function jn(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function wn(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function Cn(e,t){return Cn=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},Cn(e,t)}function Sn(e,t){return!t||"object"!==On(t)&&"function"!=typeof t?kn(e):t}function kn(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function Pn(e){return Pn=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},Pn(e)}function En(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var _n=["clickAway","contentClick","escapeKey","offScreen","tabKey","toggleClick"],Tn={align:i.a.oneOf(["left","center","right"]),canCoverHead:i.a.bool,children:i.a.node.isRequired,closeReasons:i.a.arrayOf(i.a.oneOf(_n)),columnId:i.a.any,defaultPlacement:i.a.oneOf(["above","below","left","right","vertical","horizontal"]),elementRef:i.a.oneOfType([i.a.func,i.a.object]),focusToggleReasons:i.a.arrayOf(i.a.oneOf(_n)),index:i.a.number,label:i.a.node,onAutosizeColumn:i.a.func,onDragStart:i.a.func,onKeyDown:i.a.func,onRequestClose:i.a.func,onRequestMoveColumn:i.a.func,onRequestOpen:i.a.func,onRequestResize:i.a.func,open:i.a.bool,repositionMode:i.a.oneOf(["none","flip","any"]),resizable:i.a.bool,retainFocus:i.a.bool,showGuideline:i.a.oneOf(["none","before","after"]),takeFocus:i.a.bool,truncate:i.a.bool,visible:i.a.bool,width:i.a.number,variant:i.a.oneOf(["toggleAll","info","actions"]),zIndex:i.a.number},Dn={align:"left",canCoverHead:!0,closeReasons:_n,defaultPlacement:"below",focusToggleReasons:["contentClick","escapeKey","toggleClick"],repositionMode:"flip",resizable:!0,retainFocus:!1,takeFocus:!0,truncate:!0,visible:!0,zIndex:1},In=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&Cn(e,t)}(c,e);var t,n,r,a,i=(r=c,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=Pn(r);if(a){var n=Pn(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return Sn(this,e)});function c(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,c),En(kn(t=i.call(this,e)),"cellId",void 0),En(kn(t),"controlledExternally",void 0),En(kn(t),"popoverId",void 0),En(kn(t),"handleMount",(function(e){t.setState({el:e}),Object(m.a)(t.props.elementRef,e)})),En(kn(t),"handleRequestClose",(function(e){var n=e.reason,r=e.event,o=t.props,a=o.closeReasons,i=o.columnId,c=o.focusToggleReasons,s=o.index,u=o.onRequestClose;if("clickAway"===n&&void 0!==r)for(var p=r.target;p;){if(p===t.state.el)return;p=p.parentNode}t.isOpen()&&Object(l.includes)(a,n)&&void 0!==s&&(Object(l.includes)(c,n)&&t.focus(),t.isControlled()||t.setState({open:!1}),null==u||u(r,{index:s,reason:n,columnId:i}))})),En(kn(t),"handleClick",(function(e){var n,r,o=t.props,a=o.columnId,i=o.index;if("resize"!==e.target.getAttribute("data-test"))if(t.setState({clientX:e.clientX||void 0}),t.isOpen())null===(n=(r=t).handleRequestClose)||void 0===n||n.call(r,{reason:"toggleClick",event:e});else if(void 0!==i){var l,c;null===(l=(c=t.props).onRequestOpen)||void 0===l||l.call(c,e,{reason:"toggleClick",columnId:a,index:i}),t.isControlled()||t.setState({open:!0})}})),En(kn(t),"handleKeyDown",(function(e){var n=t.props,r=n.columnId,o=n.index,a=n.onKeyDown,i=n.onRequestMoveColumn;"resize"!==e.target.getAttribute("data-test")&&("enter"===Object(f.keycode)(e.nativeEvent)?t.handleClick(e):"left"===Object(f.keycode)(e.nativeEvent)&&void 0!==o&&o>0?null==i||i({fromIndex:o,toIndex:o-1,columnId:r}):"right"===Object(f.keycode)(e.nativeEvent)&&void 0!==o&&(null==i||i({fromIndex:o,toIndex:o+1,columnId:r}))),void 0!==o&&(null==a||a(e,{index:o,columnId:r}))})),En(kn(t),"handleContentClick",(function(e){t.handleRequestClose({reason:"contentClick",event:e})})),En(kn(t),"handleDragStart",(function(e,n){var r,o;t.setState({isDragging:!0}),null===(r=(o=t.props).onDragStart)||void 0===r||r.call(o,e,n)})),En(kn(t),"handleDragEnd",(function(){t.setState({isDragging:!1})})),t.state={el:null,isDragging:!1,open:!1},t.controlledExternally=Object(l.has)(e,"open"),t.popoverId=Object(yn.createDOMID)("popover"),t.cellId=Object(yn.createDOMID)("cellId"),t}return t=c,n=[{key:"componentDidUpdate",value:function(e){e.visible&&!this.props.visible&&this.handleRequestClose({reason:"offScreen"})}},{key:"focus",value:function(){var e;null===(e=this.state.el)||void 0===e||e.focus()}},{key:"isOpen",value:function(){return this.isControlled()?this.props.open:this.state.open}},{key:"isControlled",value:function(){return this.controlledExternally}},{key:"render",value:function(){var e,t,n=this,r=this.props,a=r.align,i=r.canCoverHead,s=r.children,u=r.closeReasons,p=r.columnId,f=r.defaultPlacement,d=r.id,b=r.index,h=r.label,v=r.onAutosizeColumn,y=r.onDragStart,m=r.onRequestResize,g=r.repositionMode,O=r.resizable,x=r.retainFocus,j=r.showGuideline,w=r.style,C=r.takeFocus,S=r.truncate,k=r.variant,P=r.visible,E=r.width,_=r.zIndex,T=this.state,D=T.el,I=T.clientX,R=d||this.cellId,L=this.context.headType;return o.a.createElement(Te,xn({style:Object(l.merge)(w,{width:E}),"data-test":"head-cell",$dragging:this.state.isDragging||void 0,$clickable:!0,$variant:k,id:P?R:void 0,tabIndex:P?0:void 0,ref:this.handleMount},Object(l.omit)(this.props,[].concat(function(e){if(Array.isArray(e))return jn(e)}(t=Object.keys(c.propTypes))||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(t)||function(e,t){if(e){if("string"==typeof e)return jn(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?jn(e,t):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),["id","style"])),{onClick:this.handleClick,onKeyDown:this.handleKeyDown,"aria-haspopup":!0,"aria-owns":this.popoverId,"aria-expanded":this.isOpen(),$isFixed:"fixed"===L,$zIndex:_}),o.a.createElement(Ke,{label:h,align:a,columnId:p,id:d,index:b,isMenu:!0,resizable:P&&O,onDragStart:y?this.handleDragStart:void 0,onDragEnd:y?this.handleDragEnd:void 0,onAutosizeColumn:v,onRequestResize:m,truncate:S,width:E}),"none"!==j&&o.a.createElement(De,{$position:j}),o.a.createElement(gn.a,{align:"center",open:!!D&&this.isOpen(),autoCloseWhenOffScreen:Object(l.includes)(u,"offScreen"),anchor:D,canCoverAnchor:i,retainFocus:x,defaultPlacement:f,onRequestClose:this.handleRequestClose,repositionMode:g,id:this.popoverId,"aria-labelledby":d||this.cellId,takeFocus:C,pointTo:void 0!==I&&Object(l.isFinite)(I)?{x:I-(null!==(e=null==D?void 0:D.getBoundingClientRect().left)&&void 0!==e?e:0)}:void 0},Object(l.isFunction)(s)?function(){return o.a.createElement("div",{onClick:n.handleContentClick},s.apply(void 0,arguments))}:o.a.createElement("div",{onClick:this.handleContentClick},s)))}}],n&&wn(t.prototype,n),c}(r.Component);En(In,"splunkUiType","Table.HeadDropdownCell"),En(In,"possibleCloseReasons",_n),En(In,"propTypes",Tn),En(In,"defaultProps",Dn),En(In,"contextType",Ze);var Rn=In,Ln=h()(R).withConfig({displayName:"HeadTableStyles__Styled",componentId:"g85wgf-0"})(["min-width:0;table-layout:fixed;"]),An=h.a.div.withConfig({displayName:"HeadTableStyles__StyledDockedContainer",componentId:"g85wgf-1"})(["overflow:hidden;position:fixed;box-shadow:",";z-index:",";@media print{display:none;}"],Object(v.pick)({enterprise:v.variables.overlayShadow,prisma:"none"}),v.variables.zindexFixedNavbar),Mn=h()(An).withConfig({displayName:"HeadTableStyles__StyledFixedContainer",componentId:"g85wgf-2"})(["position:absolute;box-shadow:none;z-index:1;"]);function Bn(e){return Bn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Bn(e)}function Nn(){return Nn=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Nn.apply(this,arguments)}function zn(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function Fn(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function $n(e,t){return $n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},$n(e,t)}function Hn(e,t){return!t||"object"!==Bn(t)&&"function"!=typeof t?Vn(e):t}function Vn(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function qn(e){return qn=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},qn(e)}function Wn(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var Kn={cellWidths:i.a.arrayOf(i.a.number).isRequired,dragIndex:i.a.number,elementRef:i.a.oneOfType([i.a.func,i.a.object]),hasDragColumn:i.a.bool,hasRowExpansion:i.a.bool,hasRowSelection:i.a.bool,headType:i.a.oneOf(["docked","fixed"]).isRequired,horizontalOffset:i.a.number,isFixedColumn:i.a.bool,rowSelection:i.a.oneOf(["all","some","none"]),tableStyle:i.a.object,tableWidth:i.a.number.isRequired,tHead:i.a.element.isRequired,top:i.a.number.isRequired,width:i.a.number.isRequired},Un=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&$n(e,t)}(s,e);var t,n,a,i,c=(a=s,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=qn(a);if(i){var n=qn(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return Hn(this,e)});function s(){var e;zn(this,s);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return Wn(Vn(e=c.call.apply(c,[this].concat(n))),"head",null),Wn(Vn(e),"handleHeadMount",(function(t){e.head=t})),e}return t=s,(n=[{key:"getHead",value:function(){return this.head}},{key:"render",value:function(){var e=this.props,t=e.cellWidths,n=e.elementRef,a=e.hasDragColumn,i=e.hasRowExpansion,c=e.hasRowSelection,s=e.headType,u=e.horizontalOffset,p=e.isFixedColumn,f=e.tableStyle,d=e.tableWidth,b=e.tHead,h=e.top,v=e.width,y=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["cellWidths","elementRef","hasDragColumn","hasRowExpansion","hasRowSelection","headType","horizontalOffset","isFixedColumn","tableStyle","tableWidth","tHead","top","width"]),m="docked"===s?An:Mn,g=0;i&&(g+=1),c&&(g+=1),a&&(g+=1);var O=p?r.Children.toArray(b.props.children):r.Children.toArray(b.props.children).filter(r.isValidElement).map((function(e,n){return Object(r.cloneElement)(e,{style:Object(l.extend)({},e.props.style,{width:t[n+g]})})})),x=Object(r.cloneElement)(b,{ref:this.handleHeadMount,"data-test":"".concat(s,"-head")},O);return o.a.createElement(m,{style:{top:h,width:v},ref:n},o.a.createElement(Ln,Nn({"data-test":"".concat(s,"-head-table"),"data-fixed-column":p?"true":void 0,style:Object(l.extend)({},f,{marginLeft:u,width:p?void 0:d})},Object(l.omit)(y,"dragIndex")),x))}}])&&Fn(t.prototype,n),s}(r.Component);Wn(Un,"propTypes",Kn),Wn(Un,"defaultProps",{horizontalOffset:0});var Zn=Un,Gn=n(57);function Xn(e){return Xn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Xn(e)}function Yn(){return Yn=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Yn.apply(this,arguments)}function Qn(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Jn(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function er(e,t,n){return t&&Jn(e.prototype,t),n&&Jn(e,n),e}function tr(e,t){return tr=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},tr(e,t)}function nr(e,t){return!t||"object"!==Xn(t)&&"function"!=typeof t?rr(e):t}function rr(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function or(e){return or=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},or(e)}function ar(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var ir={actions:i.a.arrayOf(i.a.element),actionsColumnWidth:i.a.number,children:i.a.node,dockOffset:i.a.number,dockScrollBar:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),headType:i.a.oneOf(["docked","fixed","inline"]),innerStyle:i.a.object,onRequestToggleAllRows:i.a.func,onScroll:i.a.func,outerStyle:i.a.object,rowExpansion:i.a.oneOf(["single","multi","controlled","none"]),rowSelection:i.a.oneOf(["all","some","none"]),stripeRows:i.a.bool,tableStyle:i.a.object,onRequestMoveColumn:i.a.func,onRequestMoveRow:i.a.func,onRequestResizeColumn:i.a.func},lr=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&tr(e,t)}(i,e);var t,n,a=(t=i,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=or(t);if(n){var o=or(this).constructor;e=Reflect.construct(r,arguments,o)}else e=r.apply(this,arguments);return nr(this,e)});function i(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,i),ar(rr(t=a.call(this,e)),"dockedScrollBar",null),ar(rr(t),"head",null),ar(rr(t),"headFocusState",void 0),ar(rr(t),"headTable",null),ar(rr(t),"headTableEl",null),ar(rr(t),"scrollSource",void 0),ar(rr(t),"table",null),ar(rr(t),"tableContainer",null),ar(rr(t),"updateDockedHeadState",(function(){var e=Object(g.a)();if(!t.isInline()){var n=rr(t),r=n.tableContainer,o=n.head,a=n.table,l=t.props.dockOffset;if(a&&o){var c=o.getCellWidths(),s=o.getClientHeight(),u=i.getOffset(a).top-e.pageYOffset-(null!=s?s:0)+a.offsetHeight,p=Math.min(u,l);t.setState({width:null==r?void 0:r.clientWidth,tableWidth:null==a?void 0:a.clientWidth,cellWidths:c,top:p})}}})),ar(rr(t),"handleScroll",Object(l.throttle)(t.updateDockedHeadState,0)),ar(rr(t),"handleResize",Object(l.throttle)(t.updateDockedHeadState,50)),ar(rr(t),"handleContainerScroll",(function(e){var n,r;null===(n=(r=t.props).onScroll)||void 0===n||n.call(r,e),(t.isFixed()||t.headerIsDocked())&&t.tableContainer&&t.setState({horizontalOffset:-t.tableContainer.scrollLeft}),t.dockedScrollBar&&"dockedScrollBar"!==t.scrollSource&&t.tableContainer?(t.scrollSource="container",t.dockedScrollBar.scrollLeft=t.tableContainer.scrollLeft):t.scrollSource=void 0})),ar(rr(t),"handleDockedScrollBarScroll",(function(){"container"!==t.scrollSource&&t.tableContainer&&t.dockedScrollBar?(t.scrollSource="dockedScrollBar",t.tableContainer.scrollLeft=t.dockedScrollBar.scrollLeft):t.scrollSource=void 0})),ar(rr(t),"handleDragStart",(function(e){var n=e.dragIndex,r=Object(g.a)();t.setState({dragIndex:n}),r.addEventListener("dragenter",t.handleDragEnter),r.addEventListener("dragover",t.handleDragOver),r.addEventListener("drop",t.handleDrop),r.addEventListener("dragend",t.handleDragEnd)})),ar(rr(t),"handleDragOver",(function(e){e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move"),t.updateDragPosition(e.clientX)})),ar(rr(t),"handleDragEnter",(function(e){e.preventDefault(),t.setState({dragPosition:e.clientX})})),ar(rr(t),"handleDragEnd",(function(){t.setState({dragPosition:void 0}),t.cleanupDrag()})),ar(rr(t),"handleDrop",(function(e){e.preventDefault()})),ar(rr(t),"handleHeadMount",(function(e){t.head=e})),ar(rr(t),"handleHeadTableMount",(function(e){if(e)t.headFocusState&&(i.applyHeadFocusState(e.getHead(),t.headFocusState),t.headFocusState=void 0);else{var n,r=i.getHeadFocusState(null===(n=t.headTable)||void 0===n?void 0:n.getHead());r&&i.applyHeadFocusState(t.head,r)}t.headTable=e})),ar(rr(t),"handleHeadTableElementMount",(function(e){t.headTableEl=e})),ar(rr(t),"handleHeadTableKeyUp",(function(e){if(t.headTableEl&&t.tableContainer&&"tab"===Object(f.keycode)(e.nativeEvent)){var n=t.headTableEl.scrollLeft;0!==n&&(t.headTableEl.scrollLeft=0,t.tableContainer.scrollLeft+=n)}})),ar(rr(t),"handleAutosizeColumn",(function(e,n){var r,o,a,i,c=n.index,s=n.columnId,u=Object(ze.a)();if(void 0!==c){var p="none"===t.props.rowExpansion?1:2,f=null===(r=t.tableContainer)||void 0===r?void 0:r.querySelectorAll("thead th:nth-child(".concat(c+p,"), tbody td:nth-child(").concat(c+p,")")),d=u.createElement("div");d.style.float="left",d.style.position="fixed",d.style.top="-100",d.style.left="0",d.style.maxHeight="10px",d.style.overflow="hidden",Object(l.forEach)(f,(function(e){var t=e.cloneNode(!0);t.style.display="block",t.style.width="auto",d.appendChild(t)})),u.body.appendChild(d),null===(o=(a=t.props).onRequestResizeColumn)||void 0===o||o.call(a,e,{index:c,columnId:s,width:d.clientWidth+1}),null===(i=d.parentNode)||void 0===i||i.removeChild(d)}})),ar(rr(t),"updateDragPosition",Object(l.throttle)(t.updateDragPositionImpl,100,{trailing:!1})),t.state={dragPosition:void 0},t}return er(i,null,[{key:"getHeadFocusState",value:function(e){var t,n,r=Object(ze.a)();if(null!=e){var o=null===(t=e.getEl())||void 0===t?void 0:t.children[0].children,a=Object(l.indexOf)(o,r.activeElement);if(a>-1)return{target:"headCell",index:a};var i=null===(n=e.getEl())||void 0===n?void 0:n.querySelectorAll("[data-test=resize]"),c=Object(l.indexOf)(i,r.activeElement);return c>-1?{target:"resizeButton",index:c}:void 0}}},{key:"getOffset",value:function(e){var t=Object(g.a)(),n=e.getBoundingClientRect();return{top:n.top+t.pageYOffset,left:n.left+t.pageXOffset}}},{key:"applyHeadFocusState",value:function(e,t){var n,r,o,a,i=t.target,l=t.index;if("headCell"===i)o=null==e||null===(a=e.getEl())||void 0===a?void 0:a.children[0].children[l];else if("resizeButton"===i){var c;o=null==e||null===(c=e.getEl())||void 0===c?void 0:c.querySelectorAll("[data-test=resize]")[l]}null===(n=o)||void 0===n||null===(r=n.focus)||void 0===r||r.call(n)}}]),er(i,[{key:"componentDidUpdate",value:function(e){var t=this.head,n=this.headTable;if(t&&n){var r=t.getCellWidths();Object(l.isEqual)(this.state.cellWidths,r)||this.updateDockedHeadState()}"inline"===e.headType&&"inline"!==this.props.headType&&this.updateDockedHeadState()}},{key:"componentDidMount",value:function(){this.updateDockedHeadState()}},{key:"componentWillUnmount",value:function(){this.handleScroll.cancel(),this.handleResize.cancel(),this.cleanupDrag()}},{key:"createHead",value:function(e){var t=this.props,n=t.actions,o=t.actionsColumnWidth,a=t.onRequestMoveColumn,i=t.onRequestMoveRow,l=t.onRequestResizeColumn,c=t.onRequestToggleAllRows,s=t.rowExpansion,u=t.rowSelection,p=this.state.dragIndex,f=r.Children.toArray(e.props.children).filter(r.isValidElement),d=n.filter(r.isValidElement);return Object(r.cloneElement)(e,{actions:d,actionsColumnWidth:o,dragIndex:p,dragPosition:this.state.dragPosition,hasInfoColumn:"none"!==s,hasDragColumn:!!i,onAutosizeColumn:this.handleAutosizeColumn,onDragStart:a?this.handleDragStart:void 0,onRequestMoveColumn:a,onRequestResizeColumn:l,onRequestToggleAllRows:c,ref:this.handleHeadMount,rowSelection:u},f)}},{key:"createBody",value:function(e){var t=this.props.actions.filter(r.isValidElement);return Object(r.cloneElement)(e,{actions:t.length>0,movableColumns:!!this.props.onRequestMoveColumn,onRequestMoveRow:this.props.onRequestMoveRow,rowExpansion:this.props.rowExpansion,stripeRows:this.props.stripeRows})}},{key:"isInline",value:function(){return"inline"===this.props.headType}},{key:"headerIsDocked",value:function(){return"docked"===this.props.headType}},{key:"isFixed",value:function(){return"fixed"===this.props.headType}},{key:"showDockedHeader",value:function(){var e=Object(g.a)();if(!(this.headerIsDocked()&&this.table&&this.head&&this.tableContainer))return!1;var t=this.props.dockOffset,n=i.getOffset(this.tableContainer).top;return e.pageYOffset>=n-t}},{key:"showDockedScrollBar",value:function(){var e=Object(g.a)();if(!this.props.dockScrollBar||!this.table||!this.tableContainer)return!1;var t=this.tableContainer.getBoundingClientRect();return t.bottom>e.innerHeight&&t.top<e.innerHeight}},{key:"updateDragPositionImpl",value:function(e){this.setState({dragPosition:e})}},{key:"cleanupDrag",value:function(){var e=Object(g.a)();e.removeEventListener("dragenter",this.handleDragEnter),e.removeEventListener("dragover",this.handleDragOver),e.removeEventListener("drop",this.handleDrop),e.removeEventListener("dragend",this.handleDragEnd),this.updateDragPosition.cancel()}},{key:"renderHeadTable",value:function(e,t){if(this.showDockedHeader()){this.headFocusState=i.getHeadFocusState(this.head);var n=this.state,r=n.cellWidths,a=n.dragIndex,l=n.horizontalOffset,c=n.tableWidth,s=n.top,u=n.width;return void 0!==r&&void 0!==c&&void 0!==s&&void 0!==u&&o.a.createElement(Zn,{headType:"docked",tHead:e,cellWidths:r,dragIndex:a,horizontalOffset:l,tableWidth:c,top:s,width:u,tableStyle:this.props.tableStyle,isFixedColumn:t,ref:this.handleHeadTableMount,onKeyUp:this.handleHeadTableKeyUp,elementRef:this.handleHeadTableElementMount,hasDragColumn:!!this.props.onRequestMoveRow,hasRowExpansion:"none"!==this.props.rowExpansion,hasRowSelection:!!this.props.onRequestToggleAllRows})}return!1}},{key:"renderDockedScrollbar",value:function(){var e=this,t=Object(g.a)();if(!this.showDockedScrollBar())return!1;var n=0;if(this.dockedScrollBar&&this.head&&this.table&&this.head){var r,a,i=t.innerHeight-this.table.getBoundingClientRect().top-(null!==(r=null===(a=this.head.getEl())||void 0===a?void 0:a.offsetHeight)&&void 0!==r?r:0);n=Math.min(i-this.dockedScrollBar.offsetHeight,0)}return o.a.createElement(L,{style:{width:this.state.width,marginBottom:n},onScroll:this.handleDockedScrollBarScroll,"data-test":"docked-scroll-bar",ref:function(t){e.dockedScrollBar=t}},o.a.createElement(A,{style:{width:this.state.tableWidth},"data-test":"docked-scroll-content"}))}},{key:"render",value:function(){var e,t,n,a=this,c=this.props,u=c.children,f=c.elementRef,b=c.headType,h=c.innerStyle,v=c.onRequestResizeColumn,y=c.onRequestToggleAllRows,m=c.outerStyle,O=c.resizableFillLayout,x=c.rowSelection,j=c.tableStyle,w=!!v;r.Children.toArray(u).forEach((function(o){var i=o.type.splunkUiType;"Table.Head"===i?(e=a.createHead(o),w||(w=!r.Children.toArray(o.props.children).filter(r.isValidElement).some((function(e){return!Object(l.has)(e.props,"width")})))):"Table.Body"===i?t=a.createBody(o):"Table.Caption"===i&&(n=o)})),Object(Gn.a)(e,"A Table.Head is required.");var C=this.renderHeadTable(e,w),S=r.Children.toArray(e.props.children).filter(r.isValidElement).map((function(e){return Object(r.cloneElement)(e,{visible:!C})}));e=Object(r.cloneElement)(e,{},S);var k,P=this.context||Object(g.a)(),E=this.isFixed()?this.tableContainer:P;return O&&(w=!1),o.a.createElement(D,Yn({"data-test":"table",ref:f,style:m,"data-test-row-selection":y?x:void 0},Object(l.omit)(this.props,[].concat(function(e){if(Array.isArray(e))return Qn(e)}(k=Object.keys(i.propTypes))||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(k)||function(e,t){if(e){if("string"==typeof e)return Qn(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Qn(e,t):void 0}}(k)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),["style"]))),o.a.createElement(p.a,{target:Object(g.a)(),eventType:"scroll",listener:this.handleScroll,options:{passive:!1,capture:!0}}),o.a.createElement(s.a,{handleWidth:!0,onResize:this.handleResize}),o.a.createElement(Ze.Provider,{value:{headType:b}},C,o.a.createElement(I,{onScroll:this.handleContainerScroll,ref:function(e){a.tableContainer=e},style:h},o.a.createElement(d.ScrollContainerProvider,{value:E},o.a.createElement(R,{ref:function(e){a.table=e},"data-test":"main-table",style:j,"data-fixed-column":w?"true":void 0,$resizableFillLayout:O},n,e,t))),this.renderDockedScrollbar()))}}]),i}(r.Component);ar(lr,"propTypes",ir),ar(lr,"contextType",d.ScrollContainerContext),ar(lr,"defaultProps",{actions:[],dockOffset:0,headType:"inline",rowExpansion:"none",rowSelection:"none",resizableFillLayout:!1}),ar(lr,"Caption",F),ar(lr,"Head",vn),ar(lr,"HeadCell",it),ar(lr,"HeadDropdownCell",Rn),ar(lr,"Body",T),ar(lr,"Row",en),ar(lr,"Cell",J);var cr=lr}])},6401:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=139)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},10:function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},112:function(e,t){e.exports=n(4415)},139:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return ae}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(32),s=n(14),u=n.n(s),p=n(0),f=n(80),d=n(112),b=n.n(d),h=n(5),v=n(31),y=n(22),m=n(10),g=n(25),O=n.n(g);function x(){return x=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},x.apply(this,arguments)}var j=function(e){var t=Object(p.useSplunkTheme)(),n=t.family,r=t.density;if("enterprise"===n)return o.a.createElement(O.a,x({viewBox:"0 0 24 24",size:1.2,screenReaderText:Object(h._)("Hide password")},e),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M4.00691 3.89287C3.61638 3.50234 2.98322 3.50235 2.5927 3.89287C2.20217 4.2834 2.20217 4.91656 2.5927 5.30708L4.35908 7.07346C3.63043 7.75302 2.99174 8.52671 2.46085 9.37612L1.18794 11.4128C0.963393 11.7721 0.963395 12.2279 1.18794 12.5872L2.46085 14.6239C3.3213 16.0006 4.46494 17.1784 5.81576 18.0789L5.94933 18.1679C7.74121 19.3625 9.8466 20 12.0002 20C13.5116 20 14.9993 19.686 16.3715 19.0858L18.5982 21.3125C18.9887 21.703 19.6218 21.703 20.0124 21.3125C20.4029 20.922 20.4029 20.2888 20.0124 19.8983L4.00691 3.89287ZM14.8257 17.54L13.0353 15.7496C12.7056 15.8405 12.3583 15.889 11.9997 15.889C9.85196 15.889 8.11084 14.1479 8.11084 12.0001C8.11084 11.6415 8.15937 11.2943 8.25022 10.9646L5.77433 8.48871C5.15179 9.06078 4.60729 9.71541 4.15685 10.4361L3.17943 12L4.15685 13.5639C4.86685 14.6999 5.81053 15.6717 6.92516 16.4148L7.05873 16.5038C8.52208 17.4794 10.2415 18 12.0002 18C12.9658 18 13.9196 17.8431 14.8257 17.54Z",fill:"currentColor"}),o.a.createElement("path",{d:"M10.9657 8.25019L15.7496 13.0342C15.8402 12.7049 15.8886 12.3581 15.8886 12.0001C15.8886 9.85232 14.1475 8.11121 11.9997 8.11121C11.6417 8.11121 11.2949 8.15959 10.9657 8.25019Z",fill:"currentColor"}),o.a.createElement("path",{d:"M19.8435 13.5639C19.3932 14.2844 18.8488 14.939 18.2264 15.5109L19.6417 16.9262C20.3702 16.2467 21.0087 15.4731 21.5395 14.6239L22.8124 12.5872C23.037 12.2279 23.037 11.7721 22.8124 11.4128L21.5395 9.37612C20.6791 7.99942 19.5354 6.82164 18.1846 5.9211L18.051 5.83205C16.2591 4.63746 14.1538 4 12.0002 4C10.489 4 9.00149 4.31389 7.62941 4.91392L9.17525 6.45977C10.0811 6.15687 11.0347 6 12.0002 6C13.7589 6 15.4783 6.52059 16.9416 7.49615L17.0752 7.5852C18.1898 8.32829 19.1335 9.30013 19.8435 10.4361L20.8209 12L19.8435 13.5639Z",fill:"currentColor"}));var a="compact"===r?"20":"24";return o.a.createElement("svg",{width:a,height:a,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",style:{display:"block"}},o.a.createElement("title",null,Object(h._)("Hide password")),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M4.00691 3.89287C3.61638 3.50234 2.98322 3.50235 2.5927 3.89287C2.20217 4.2834 2.20217 4.91656 2.5927 5.30708L4.35908 7.07346C3.63043 7.75302 2.99174 8.52671 2.46085 9.37612L1.18794 11.4128C0.963393 11.7721 0.963395 12.2279 1.18794 12.5872L2.46085 14.6239C3.3213 16.0006 4.46494 17.1784 5.81576 18.0789L5.94933 18.1679C7.74121 19.3625 9.8466 20 12.0002 20C13.5116 20 14.9993 19.686 16.3715 19.0858L18.5982 21.3125C18.9887 21.703 19.6218 21.703 20.0124 21.3125C20.4029 20.922 20.4029 20.2888 20.0124 19.8983L4.00691 3.89287ZM14.8257 17.54L13.0353 15.7496C12.7056 15.8405 12.3583 15.889 11.9997 15.889C9.85196 15.889 8.11084 14.1479 8.11084 12.0001C8.11084 11.6415 8.15937 11.2943 8.25022 10.9646L5.77433 8.48871C5.15179 9.06078 4.60729 9.71541 4.15685 10.4361L3.17943 12L4.15685 13.5639C4.86685 14.6999 5.81053 15.6717 6.92516 16.4148L7.05873 16.5038C8.52208 17.4794 10.2415 18 12.0002 18C12.9658 18 13.9196 17.8431 14.8257 17.54Z",fill:"currentColor"}),o.a.createElement("path",{d:"M10.9657 8.25019L15.7496 13.0342C15.8402 12.7049 15.8886 12.3581 15.8886 12.0001C15.8886 9.85232 14.1475 8.11121 11.9997 8.11121C11.6417 8.11121 11.2949 8.15959 10.9657 8.25019Z",fill:"currentColor"}),o.a.createElement("path",{d:"M19.8435 13.5639C19.3932 14.2844 18.8488 14.939 18.2264 15.5109L19.6417 16.9262C20.3702 16.2467 21.0087 15.4731 21.5395 14.6239L22.8124 12.5872C23.037 12.2279 23.037 11.7721 22.8124 11.4128L21.5395 9.37612C20.6791 7.99942 19.5354 6.82164 18.1846 5.9211L18.051 5.83205C16.2591 4.63746 14.1538 4 12.0002 4C10.489 4 9.00149 4.31389 7.62941 4.91392L9.17525 6.45977C10.0811 6.15687 11.0347 6 12.0002 6C13.7589 6 15.4783 6.52059 16.9416 7.49615L17.0752 7.5852C18.1898 8.32829 19.1335 9.30013 19.8435 10.4361L20.8209 12L19.8435 13.5639Z",fill:"currentColor"}))};function w(){return w=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},w.apply(this,arguments)}var C=function(e){var t=Object(p.useSplunkTheme)(),n=t.family,r=t.density;if("enterprise"===n)return o.a.createElement(O.a,w({viewBox:"0 0 24 24",size:1.2,screenReaderText:Object(h._)("View password")},e),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M15.7745 11.8654C15.7745 14.0132 14.0334 15.7543 11.8857 15.7543C9.73788 15.7543 7.99677 14.0132 7.99677 11.8654C7.99677 9.71762 9.73788 7.9765 11.8857 7.9765C14.0334 7.9765 15.7745 9.71762 15.7745 11.8654ZM13.7745 11.8654C13.7745 12.9086 12.9289 13.7543 11.8857 13.7543C10.8424 13.7543 9.99677 12.9086 9.99677 11.8654C9.99677 10.8222 10.8424 9.9765 11.8857 9.9765C12.9289 9.9765 13.7745 10.8222 13.7745 11.8654Z",fill:"currentColor"}),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M11.8859 3.86536C9.73235 3.86536 7.62695 4.50282 5.83507 5.69741L5.7015 5.78646C4.35068 6.687 3.20704 7.86477 2.3466 9.24148L1.07369 11.2781C0.849136 11.6374 0.849137 12.0933 1.07369 12.4526L2.3466 14.4892C3.20704 15.8659 4.35068 17.0437 5.7015 17.9443L5.83507 18.0333C7.62695 19.2279 9.73235 19.8654 11.8859 19.8654C14.0395 19.8654 16.1449 19.2279 17.9368 18.0333L18.0703 17.9443C19.4212 17.0437 20.5648 15.8659 21.4252 14.4892L22.6982 12.4526C22.9227 12.0933 22.9227 11.6374 22.6982 11.2781L21.4252 9.24148C20.5648 7.86477 19.4212 6.687 18.0703 5.78645L17.9368 5.69741C16.1449 4.50282 14.0395 3.86536 11.8859 3.86536ZM6.94447 7.36151C8.40782 6.38594 10.1272 5.86536 11.8859 5.86536C13.6446 5.86536 15.364 6.38594 16.8274 7.36151L16.9609 7.45056C18.0756 8.19364 19.0193 9.16549 19.7293 10.3015L20.7067 11.8654L19.7293 13.4292C19.0193 14.5652 18.0756 15.5371 16.9609 16.2802L16.8274 16.3692C15.364 17.3448 13.6446 17.8654 11.8859 17.8654C10.1272 17.8654 8.40782 17.3448 6.94447 16.3692L6.8109 16.2802C5.69627 15.5371 4.75259 14.5652 4.04259 13.4292L3.06517 11.8654L4.04259 10.3015C4.75259 9.16549 5.69627 8.19364 6.8109 7.45056L6.94447 7.36151Z",fill:"currentColor"}));var a="compact"===r?"20":"24";return o.a.createElement("svg",{width:a,height:a,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",style:{display:"block"}},o.a.createElement("title",null,Object(h._)("View password")),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M15.7745 11.8654C15.7745 14.0132 14.0334 15.7543 11.8857 15.7543C9.73788 15.7543 7.99677 14.0132 7.99677 11.8654C7.99677 9.71762 9.73788 7.9765 11.8857 7.9765C14.0334 7.9765 15.7745 9.71762 15.7745 11.8654ZM13.7745 11.8654C13.7745 12.9086 12.9289 13.7543 11.8857 13.7543C10.8424 13.7543 9.99677 12.9086 9.99677 11.8654C9.99677 10.8222 10.8424 9.9765 11.8857 9.9765C12.9289 9.9765 13.7745 10.8222 13.7745 11.8654Z",fill:"currentColor"}),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M11.8859 3.86536C9.73235 3.86536 7.62695 4.50282 5.83507 5.69741L5.7015 5.78646C4.35068 6.687 3.20704 7.86477 2.3466 9.24148L1.07369 11.2781C0.849136 11.6374 0.849137 12.0933 1.07369 12.4526L2.3466 14.4892C3.20704 15.8659 4.35068 17.0437 5.7015 17.9443L5.83507 18.0333C7.62695 19.2279 9.73235 19.8654 11.8859 19.8654C14.0395 19.8654 16.1449 19.2279 17.9368 18.0333L18.0703 17.9443C19.4212 17.0437 20.5648 15.8659 21.4252 14.4892L22.6982 12.4526C22.9227 12.0933 22.9227 11.6374 22.6982 11.2781L21.4252 9.24148C20.5648 7.86477 19.4212 6.687 18.0703 5.78645L17.9368 5.69741C16.1449 4.50282 14.0395 3.86536 11.8859 3.86536ZM6.94447 7.36151C8.40782 6.38594 10.1272 5.86536 11.8859 5.86536C13.6446 5.86536 15.364 6.38594 16.8274 7.36151L16.9609 7.45056C18.0756 8.19364 19.0193 9.16549 19.7293 10.3015L20.7067 11.8654L19.7293 13.4292C19.0193 14.5652 18.0756 15.5371 16.9609 16.2802L16.8274 16.3692C15.364 17.3448 13.6446 17.8654 11.8859 17.8654C10.1272 17.8654 8.40782 17.3448 6.94447 16.3692L6.8109 16.2802C5.69627 15.5371 4.75259 14.5652 4.04259 13.4292L3.06517 11.8654L4.04259 10.3015C4.75259 9.16549 5.69627 8.19364 6.8109 7.45056L6.94447 7.36151Z",fill:"currentColor"}))},S=n(3),k=n.n(S),P=n(8),E=n.n(P),_=n(16),T=n.n(_),D=Object(S.css)(["&,&[type]{cursor:not-allowed;color:",";&::placeholder{color:",";}}"],Object(p.pick)({enterprise:p.variables.textDisabledColor,prisma:p.variables.contentColorDisabled}),Object(p.pick)({enterprise:p.variables.textDisabledColor,prisma:p.variables.contentColorDisabled})),I=Object(S.css)(["border-radius:",";cursor:pointer;font-size:0.83333em;flex-grow:0;",";&:not([disabled]){color:",";}"],Object(p.pick)({enterprise:p.variables.borderRadius,prisma:"50%"}),Object(p.pick)({enterprise:Object(S.css)(["width:",";height:",";"],p.variables.inputHeight,p.variables.inputHeight),prisma:{comfortable:Object(S.css)(["width:26px;min-width:26px;min-height:26px;margin:8px;padding:0;"]),compact:Object(S.css)(["width:22px;min-width:22px;min-height:22px;margin:8px;padding:0;"])}}),Object(p.pick)({enterprise:{light:p.variables.gray60,dark:p.variables.white},prisma:p.variables.contentColorMuted})),R=k()(T.a).withConfig({displayName:"TextStyles__StyledClearButton",componentId:"eg7n6t-0"})(["display:none;visibility:hidden;",""],I),L=k.a.span.withConfig({displayName:"TextStyles__StyledSearchIconWrapper",componentId:"eg7n6t-1"})(["",";color:",";pointer-events:none;padding:",";",""],p.mixins.reset("inline-block"),Object(p.pick)({enterprise:{light:p.variables.gray60,dark:p.variables.white},prisma:p.variables.contentColorMuted}),Object(p.pick)({comfortable:"0 8px",compact:"0 6px"}),(function(e){return e.$disabled&&Object(S.css)(["",""],Object(p.pick)({enterprise:Object(S.css)(["color:",";"],p.variables.textDisabledColor),prisma:Object(S.css)(["color:",";"],p.variables.contentColorDisabled)}))})),A=(k()(v.a).withConfig({displayName:"TextStyles__StyledSearchIcon",componentId:"eg7n6t-2"})(["",";color:",";pointer-events:none;padding:",";",""],p.mixins.reset("inline-block"),Object(p.pick)({enterprise:{light:p.variables.gray60,dark:p.variables.white},prisma:p.variables.contentColorMuted}),Object(p.pick)({comfortable:"0 8px",compact:"0 6px"}),I),k()(E.a).withConfig({displayName:"TextStyles__StyledBox",componentId:"eg7n6t-3"})(["display:flex;justify-content:space-between;flex-grow:1;flex-shrink:1;position:relative;&[data-inline]{width:230px;flex-basis:230px;[data-inline] + &{margin-left:",";}}&:focus-within:not([disabled]){","{","}","{visibility:visible;display:block;}}",""],Object(p.pick)({enterprise:p.variables.spacingHalf,prisma:p.variables.spacingSmall}),L,Object(p.pick)({enterprise:Object(S.css)(["display:none;"])}),R,(function(e){return e.$isTimeInput&&Object(S.css)(["@media screen and (min--moz-device-pixel-ratio:0){","{display:none;}}"],R)}))),M=k.a.span.withConfig({displayName:"TextStyles__StyledInputWrapper",componentId:"eg7n6t-4"})(["",";flex-grow:1;min-height:",";position:relative;overflow:hidden;border:1px solid ",";border-radius:",";box-sizing:border-box;background-color:",";box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);padding:",";align-items:center;"," "," &:hover:not([disabled]){border-color:",";}&:focus-within:not([disabled]){","}"," "," "," ",""],p.mixins.reset("inline-flex"),p.variables.inputHeight,Object(p.pick)({enterprise:{light:p.variables.gray60,dark:p.variables.gray20},prisma:p.variables.interactiveColorBorder}),p.variables.borderRadius,Object(p.pick)({enterprise:{light:p.variables.white,dark:p.variables.gray22},prisma:p.variables.transparent}),Object(p.pick)({enterprise:"0px 10px",prisma:"0px 12px"}),(function(e){return e.$hasEndAdornment&&Object(S.css)(["padding-right:0;"])}),(function(e){return e.$hasStartAdornment&&Object(S.css)(["padding-left:0;"])}),Object(p.pick)({enterprise:{light:p.variables.gray60,dark:p.variables.gray20},prisma:p.variables.interactiveColorBorderHover}),Object(p.pick)({enterprise:Object(S.css)(["box-shadow:",";color:",";"],p.variables.focusShadow,p.variables.textColor),prisma:Object(S.css)(["border-color:",";color:",";"],p.variables.interactiveColorPrimary,p.variables.contentColorActive)}),(function(e){return e.$error&&Object(S.css)(["&,&:hover:not([disabled]){border-color:",";}&:focus-within:not([disabled]){","}"],Object(p.pick)({enterprise:p.variables.errorColor,prisma:p.variables.accentColorNegative}),Object(p.pick)({enterprise:Object(S.css)(["box-shadow:",";color:",";"],p.variables.focusShadow,p.variables.textColor),prisma:Object(S.css)(["border-color:",";color:",";"],p.variables.interactiveColorPrimary,p.variables.contentColorActive)}))}),(function(e){return e.$append&&Object(S.css)(["margin-right:-1px;border-top-right-radius:0;border-bottom-right-radius:0;border-right:none;"])}),(function(e){return e.$prepend&&Object(S.css)(["border-top-left-radius:0;border-bottom-left-radius:0;"])}),(function(e){return e.disabled&&Object(S.css)([""," box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);"],Object(p.pick)({enterprise:{light:Object(S.css)(["background-color:",";border-color:",";"],p.variables.gray96,p.variables.gray92),dark:Object(S.css)(["background-color:",";border-color:",";"],p.variables.gray22,p.variables.gray30)},prisma:Object(S.css)(["border-color:",";"],p.variables.interactiveColorBorderDisabled)}))})),B=k.a.input.withConfig({displayName:"TextStyles__StyledInput",componentId:"eg7n6t-5"})(["",";&,&[type]{outline-style:none;border:0;background:transparent;color:",";flex-grow:1;font-family:",";font-size:inherit;line-height:inherit;&[type='time']{&::-webkit-calendar-picker-indicator{display:none;}height:",";@media screen and (min--moz-device-pixel-ratio:0){padding-right:",";}}position:relative;&::placeholder{color:",";opacity:1;}"," ","}"],p.mixins.reset("inline-flex"),Object(p.pick)({enterprise:p.variables.textColor,prisma:p.variables.contentColorActive}),p.variables.sansFontFamily,Object(p.pick)({enterprise:"20px",prisma:{comfortable:"24px",compact:"20px"}}),Object(p.pick)({enterprise:p.variables.spacingHalf,prisma:"14px"}),p.variables.contentColorMuted,(function(e){return e.$error&&Object(S.css)(["&,&:hover{color:",";}"],Object(p.pick)({enterprise:{light:p.variables.errorColorD10,dark:p.variables.errorColorL20},prisma:p.variables.contentColorActive}))}),(function(e){return e.disabled&&D})),N=k()(T.a).withConfig({displayName:"TextStyles__StyledVisibilityToggle",componentId:"eg7n6t-6"})(["",""],I),z=k.a.span.withConfig({displayName:"TextStyles__StyledPlaceholder",componentId:"eg7n6t-7"})(["pointer-events:none;color:",";position:absolute;overflow:hidden;font-size:inherit;line-height:inherit;height:",";margin-right:",";",";",";",""],Object(p.pick)({enterprise:p.variables.textGray,prisma:p.variables.contentColorMuted}),p.variables.lineHeight,Object(p.pick)({enterprise:"10px",prisma:"14px"}),(function(e){var t=e.$hasStartAdornment,n=e.$startAdornmentWidth;return t&&(n?Object(S.css)(["margin-left:","px;"],n):Object(S.css)(["margin-left:",";"],Object(p.pick)({enterprise:{comfortable:"30px",compact:"26px"},prisma:{comfortable:"38px",compact:"30px"}})))}),(function(e){var t=e.$hasEndAdornment,n=e.$endAdornmentWidth;return t&&(n?Object(S.css)(["max-width:calc( 100% - "," - ","px );"],Object(p.pick)({enterprise:"10px",prisma:"14px"}),n):Object(S.css)(["max-width:calc( 100% - "," - "," );"],Object(p.pick)({enterprise:"10px",prisma:"14px"}),Object(p.pick)({enterprise:{comfortable:"30px",compact:"26px"},prisma:{comfortable:"38px",compact:"30px"}})))}),(function(e){var t=e.$hasBothAdornment,n=e.$endAdornmentWidth,r=e.$startAdornmentWidth;return t&&Object(S.css)(["max-width:calc(100% - ","px - ","px);"],r,n)})),F=Object(S.css)(["display:inline-flex;align-items:center;justify-content:center;height:",";pointer-events:none;"],Object(p.pick)({enterprise:{comfortable:"30px",compact:"26px"},prisma:{comfortable:"38px",compact:"30px"}})),$=k.a.div.withConfig({displayName:"TextStyles__StyledStartAdornmentHolder",componentId:"eg7n6t-8"})([""," ",";"],F,(function(e){var t=e.$width;return t?Object(S.css)(["min-width:","px;"],t):Object(S.css)(["min-width:",";"],Object(p.pick)({enterprise:{comfortable:"30px",compact:"26px"},prisma:{comfortable:"38px",compact:"30px"}}))})),H=k.a.div.withConfig({displayName:"TextStyles__StyledEndAdornmentHolder",componentId:"eg7n6t-9"})([""," ",";"],F,(function(e){var t=e.$width;return t?Object(S.css)(["min-width:","px;"],t):Object(S.css)(["min-width:",";"],Object(p.pick)({enterprise:{comfortable:"30px",compact:"26px"},prisma:{comfortable:"38px",compact:"30px"}}))})),V=k.a.div.withConfig({displayName:"TextStyles__StyledAdornment",componentId:"eg7n6t-10"})(["display:inline-flex;align-items:center;justify-content:center;position:absolute;pointer-events:none;z-index:1;height:",";color:",";",";",";",""],Object(p.pick)({enterprise:{comfortable:"30px",compact:"26px"},prisma:{comfortable:"38px",compact:"30px"}}),Object(p.pick)({enterprise:{light:p.variables.gray60,dark:p.variables.white},prisma:p.variables.contentColorMuted}),(function(e){return"start"===e.$position?Object(S.css)(["top:1px;left:1px;"]):Object(S.css)(["top:1px;right:1px;"])}),(function(e){return e.disabled&&D}),Object(p.pick)({enterprise:Object(S.css)(["margin-left:-1px;margin-right:-1px;"])}));function q(e){return q="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},q(e)}function W(){return W=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},W.apply(this,arguments)}function K(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function U(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Z(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?U(Object(n),!0).forEach((function(t){te(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):U(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function G(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function X(e,t,n){return t&&G(e.prototype,t),n&&G(e,n),e}function Y(e,t){return Y=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},Y(e,t)}function Q(e,t){return!t||"object"!==q(t)&&"function"!=typeof t?J(e):t}function J(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function ee(e){return ee=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},ee(e)}function te(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var ne={appearance:i.a.oneOf(["default","search"]),append:i.a.bool,autoCapitalize:i.a.string,autoComplete:i.a.string,autoCorrect:i.a.string,autoFocus:i.a.bool,canClear:i.a.bool,children:i.a.node,classNamePrivate:i.a.string,defaultValue:i.a.string,describedBy:i.a.string,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),endAdornment:i.a.node,error:i.a.bool,inline:i.a.bool,inputClassName:i.a.string,inputId:i.a.string,inputRef:i.a.oneOfType([i.a.func,i.a.object]),labelledBy:i.a.string,maxLength:i.a.number,multiline:i.a.bool,name:i.a.string,onBlur:i.a.func,onChange:i.a.func,onFocus:i.a.func,onKeyDown:i.a.func,onSelect:i.a.func,onInputClick:i.a.func,placeholder:i.a.string,prepend:i.a.bool,rowsMax:i.a.number,rowsMin:i.a.number,spellCheck:i.a.bool,tabIndex:i.a.number,startAdornment:i.a.node,splunkTheme:i.a.object,type:i.a.string,passwordVisibilityToggle:i.a.bool,useSyntheticPlaceholder:i.a.bool,value:i.a.string},re=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&Y(e,t)}(a,e);var t,n,r=(t=a,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=ee(t);if(n){var o=ee(this).constructor;e=Reflect.construct(r,arguments,o)}else e=r.apply(this,arguments);return Q(this,e)});function a(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,a),te(J(t=r.call(this,e)),"controlledExternally",void 0),te(J(t),"input",null),te(J(t),"startAdornment",null),te(J(t),"endAdornment",null),te(J(t),"getAdornmentWidth",(function(){var e=t.startAdornment?t.startAdornment.getBoundingClientRect():void 0,n=e&&Math.round(e.width);t.state.startAdornmentWidth!==n&&t.setState({startAdornmentWidth:n});var r=t.endAdornment?t.endAdornment.getBoundingClientRect():void 0,o=r&&Math.round(r.width);t.state.endAdornmentWidth!==o&&t.setState({endAdornmentWidth:o})})),te(J(t),"handleInputMount",(function(e){t.input=e,Object(m.a)(t.props.inputRef,e)})),te(J(t),"handleInputChange",(function(e){var n,r,o=e.target.value,a=t.props.name;t.isControlled()||t.setState({value:o}),null===(n=(r=t.props).onChange)||void 0===n||n.call(r,e,{value:o,name:a})})),te(J(t),"handleInputKeyDown",(function(e){var n,r;null===(n=(r=t.props).onKeyDown)||void 0===n||n.call(r,e)})),te(J(t),"handleInputSelect",(function(e){var n,r;null===(n=(r=t.props).onSelect)||void 0===n||n.call(r,e)})),te(J(t),"handleInputClick",(function(e){var n,r;null===(n=(r=t.props).onInputClick)||void 0===n||n.call(r,e)})),te(J(t),"handleInputFocus",(function(e){var n,r;null===(n=(r=t.props).onFocus)||void 0===n||n.call(r,e)})),te(J(t),"handleInputBlur",(function(e){var n,r;null===(n=(r=t.props).onBlur)||void 0===n||n.call(r,e)})),te(J(t),"handleClear",(function(e){var n,r;e.preventDefault();var o=t.props.name;t.isControlled()||t.setState({value:""}),null===(n=(r=t.props).onChange)||void 0===n||n.call(r,e,{value:"",name:o})})),te(J(t),"handleVisibilityToggle",(function(){t.setState((function(e){return{hideVisibility:!e.hideVisibility}}))})),te(J(t),"renderEndAdornment",(function(){var e,n=t.props,r=n.appearance,a=n.endAdornment,i=n.passwordVisibilityToggle,l=n.disabled,c=n.canClear,s=n.splunkTheme.isPrisma,u={ref:function(e){t.endAdornment=e},disabled:l,$position:"end"};if(a)return o.a.createElement(V,u,a);if(i&&!l){var p=t.state.hideVisibility?o.a.createElement(C,null):o.a.createElement(j,null);return o.a.createElement(V,u,o.a.createElement(N,{appearance:s?"secondary":"pill","data-test":"password-toggle",inline:!1,onClick:t.handleVisibilityToggle,type:"button",icon:p}))}var f=null===(e=t.context.labelAttrs)||void 0===e?void 0:e.text,d=f?Object(h._)("Clear ".concat(f," text field")):Object(h._)("Clear text field"),b=t.getDisplayValue();return s||"search"!==r?b&&(s&&"search"===r||c)?o.a.createElement(V,u,!l&&o.a.createElement(R,{"data-test":"clear",appearance:s?"secondary":"pill",onClick:t.handleClear,icon:o.a.createElement(y.a,{inline:!1,enterpriseSize:1,screenReaderText:d})})):void 0:b?o.a.createElement(V,u,!l&&o.a.createElement(R,{appearance:s?"secondary":"pill","data-test":"clear",inline:!1,icon:o.a.createElement(y.a,{enterpriseSize:1,screenReaderText:d}),onClick:t.handleClear}),o.a.createElement(L,{$disabled:l},o.a.createElement(v.a,{enterpriseSize:"16px",inline:!1}))):o.a.createElement(V,u,o.a.createElement(L,{$disabled:l},o.a.createElement(v.a,{enterpriseSize:"16px",inline:!1})))})),te(J(t),"renderStartAdornment",(function(){var e=t.props,n=e.appearance,r=e.startAdornment,a=e.splunkTheme,i=e.disabled,l=a.isPrisma,c={ref:function(e){t.startAdornment=e},disabled:i,$position:"start"};return r?o.a.createElement(V,c,r):l&&"search"===n?o.a.createElement(V,c,o.a.createElement(L,{$disabled:i},o.a.createElement(v.a,{enterpriseSize:"16px",inline:!1,screenReaderText:"Search"}))):void 0})),te(J(t),"getDisplayValue",(function(){return t.isControlled()?t.props.value:t.state.value})),t.controlledExternally=Object(l.has)(e,"value"),t.state={value:e.defaultValue||"",hideVisibility:!0},Object(l.has)(e,"useSyntheticPlaceholder")&&console.warn("The 'Text' prop 'useSyntheticPlaceholder' has been marked for deprecation."),a.validateRows(e),t}return X(a,null,[{key:"validateRows",value:function(e){e.rowsMin,e.rowsMax}}]),X(a,[{key:"componentDidMount",value:function(){this.getAdornmentWidth()}},{key:"componentDidUpdate",value:function(e){a.validateRows(this.props),this.getAdornmentWidth()}},{key:"isControlled",value:function(){return this.controlledExternally}},{key:"blur",value:function(){var e;null===(e=this.input)||void 0===e||e.blur()}},{key:"focus",value:function(){var e;null===(e=this.input)||void 0===e||e.focus()}},{key:"select",value:function(){var e;null===(e=this.input)||void 0===e||e.select()}},{key:"render",value:function(){var e,t=this.props,n=t.append,r=t.autoCapitalize,a=t.autoComplete,i=t.autoCorrect,s=t.autoFocus,p=t.children,f=t.className,d=t.classNamePrivate,h=t.disabled,v=t.describedBy,y=t.elementRef,m=t.error,g=t.inline,O=t.inputClassName,x=t.inputId,j=t.labelledBy,w=t.multiline,C=t.maxLength,S=t.name,k=t.passwordVisibilityToggle,P=t.placeholder,E=t.prepend,_=t.spellCheck,T=t.tabIndex,D=t.title,I=t.type,R=t.useSyntheticPlaceholder,L=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(t,["append","autoCapitalize","autoComplete","autoCorrect","autoFocus","children","className","classNamePrivate","disabled","describedBy","elementRef","error","inline","inputClassName","inputId","labelledBy","multiline","maxLength","name","passwordVisibilityToggle","placeholder","prepend","spellCheck","tabIndex","title","type","useSyntheticPlaceholder"]),N=Z(Z({role:"textbox"},Object(l.pickBy)(L,(function(e,t){return"role"===t||0===t.indexOf("aria-")}))),{},{"aria-describedby":v,"aria-labelledby":j,"aria-invalid":m||void 0}),F=Object(l.omit)(L,["inputRef","onBlur","onChange","onFocus","onKeyDown","onSelect","onInputClick","rowsMax","rowsMin"].concat(function(e){if(Array.isArray(e))return K(e)}(e=Object(l.keys)(N))||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return K(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?K(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())),V=this.getDisplayValue(),q={className:Object(c.toClassName)(f,O),$append:n||void 0,$error:m,$prepend:E||void 0},U=this.state.hideVisibility?"password":"text",G=k?U:I,X=Z(Z({},N),{},{"data-test":"textbox",autoCapitalize:r,autoComplete:a,autoCorrect:i,autoFocus:s,id:x,maxLength:C,placeholder:P&&!R?P:void 0,name:S,onChange:this.handleInputChange,onKeyDown:this.handleInputKeyDown,onSelect:this.handleInputSelect,onClick:this.handleInputClick,onFocus:this.handleInputFocus,onBlur:this.handleInputBlur,ref:this.handleInputMount,spellCheck:_,style:{height:this.state.height},title:D,tabIndex:T,type:G,value:V,$error:m}),Y=R&&P&&!V,Q="password"===I||k?void 0:V,J="time"===I,ee=!!this.renderEndAdornment(),te=!!this.renderStartAdornment();return w?o.a.createElement(b.a,this.props):o.a.createElement(A,W({tabIndex:-1,$isTimeInput:J,className:Object(c.toClassName)(f,d),"data-test":"text","data-test-value":Q,elementRef:y,flex:!0,inline:g},F),this.renderStartAdornment(),o.a.createElement(M,W({$hasEndAdornment:ee,$hasStartAdornment:te,disabled:h},q),te&&o.a.createElement($,{$width:this.state.startAdornmentWidth}),h?o.a.createElement(B,W({className:Object(c.toClassName)(f,d),"data-test":"textbox",disabled:!0,readOnly:!0,type:G,value:V,placeholder:P&&!R?P:void 0},N)):o.a.createElement(B,W({},X,{onClick:this.handleInputClick})),Y&&o.a.createElement(u.a,null,P),Y&&o.a.createElement(z,{$endAdornmentWidth:this.state.endAdornmentWidth,$hasBothAdornment:te&&ee,$hasEndAdornment:ee,$hasStartAdornment:te,$startAdornmentWidth:this.state.startAdornmentWidth,"aria-hidden":!0,"data-role":"placeholder"},P),p,ee&&o.a.createElement(H,{$width:this.state.endAdornmentWidth})),this.renderEndAdornment())}}]),a}(r.Component);te(re,"propTypes",ne),te(re,"defaultProps",{appearance:"default",append:!1,autoFocus:!1,canClear:!1,disabled:!1,error:!1,inline:!1,multiline:!1,placeholder:"",prepend:!1,rowsMax:8,rowsMin:2,tabIndex:0,type:"text",passwordVisibilityToggle:!1}),te(re,"componentType","Text"),te(re,"contextType",f.ControlGroupContext);var oe=Object(p.withSplunkTheme)(re);oe.propTypes=re.propTypes,oe.componentType=re.componentType;var ae=oe},14:function(e,t){e.exports=n(5766)},16:function(e,t){e.exports=n(6416)},2:function(e,t){e.exports=n(7294)},22:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(23),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L10.5858 12L5.2929 17.2929C4.90238 17.6834 4.90238 18.3166 5.2929 18.7071C5.68342 19.0976 6.31659 19.0976 6.70711 18.7071L12 13.4142L17.2929 18.7071C17.6834 19.0976 18.3166 19.0976 18.7071 18.7071C19.0976 18.3166 19.0976 17.6834 18.7071 17.2929L13.4142 12L18.7071 6.70711C19.0976 6.31658 19.0976 5.68342 18.7071 5.29289C18.3166 4.90237 17.6834 4.90237 17.2929 5.29289L12 10.5858L6.70711 5.29289Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M12.2024 2.69009C12.5092 2.38325 13.0067 2.38325 13.3136 2.69009C13.6204 2.99693 13.6204 3.49442 13.3136 3.80126L9.11721 7.99762L13.3114 12.1918C13.6206 12.501 13.6206 13.0023 13.3114 13.3114C13.0023 13.6206 12.501 13.6206 12.1918 13.3114L7.99762 9.11721L3.885 13.2298C3.57816 13.5367 3.08067 13.5367 2.77383 13.2298C2.46699 12.923 2.46699 12.4255 2.77383 12.1187L6.88645 8.00604L2.69183 3.81142C2.38267 3.50226 2.38267 3.001 2.69183 2.69183C3.001 2.38267 3.50226 2.38267 3.81142 2.69183L8.00604 6.88646L12.2024 2.69009Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},23:function(e,t){e.exports=n(1476)},25:function(e,t){e.exports=n(6817)},3:function(e,t){e.exports=n(2788)},31:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(43),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M10.5,3.0015 C14.6421,3.0015 18,6.3593 18,10.5015 C18,12.2112 17.4279,13.7873 16.4647,15.0489 L20.7077,19.292 C21.0983,19.6825 21.0983,20.3156 20.7077,20.7062 C20.3172,21.0967 19.6841,21.0967 19.2935,20.7062 L15.0509,16.4635 C13.7888,17.4283 12.2113,18.0015 10.5,18.0015 C6.3579,18.0015 3,14.6436 3,10.5015 C3,6.3593 6.3579,3.0015 10.5,3.0015 Z M10.5,5.0015 C7.4624,5.0015 5,7.4639 5,10.5015 C5,13.539 7.4624,16.0015 10.5,16.0015 C13.5376,16.0015 16,13.539 16,10.5015 C16,7.4639 13.5376,5.0015 10.5,5.0015 Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M6.85277,2.0015 C9.53288,2.0015 11.7055,4.1741 11.7055,6.8542 C11.7055,7.8463 11.4079,8.7688 10.897,9.5373 L10.9245,9.5098 L14.0018,12.5871 L12.5876,14.0014 L9.51025,10.924 L9.53587,10.8984 C8.76733,11.4093 7.84481,11.707 6.85277,11.707 C4.17266,11.707 2,9.5343 2,6.8542 C2,4.1741 4.17266,2.0015 6.85277,2.0015 Z M6.85277,4.0015 C5.27723,4.0015 4,5.2787 4,6.8542 C4,8.4298 5.27723,9.707 6.85277,9.707 C8.42831,9.707 9.70554,8.4298 9.70554,6.8542 C9.70554,5.2787 8.42831,4.0015 6.85277,4.0015 Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},32:function(e,t){e.exports=n(9867)},4:function(e,t){e.exports=n(5220)},43:function(e,t){e.exports=n(8044)},5:function(e,t){e.exports=n(6219)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var r=n(2),o=n.n(r),a=n(3);function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n.n(a).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function c(e){return o.a.createElement(l,i({xmlns:"http://www.w3.org/2000/svg"},e))}},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(0);function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}var p={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},f={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:i.a.func,enterpriseSize:i.a.oneOfType([i.a.number,i.a.string]),enterpriseWidth:i.a.oneOfType([i.a.number,i.a.string]),enterpriseHeight:i.a.oneOfType([i.a.number,i.a.string]),Prisma24:i.a.func.isRequired,Prisma20:i.a.func,Prisma16:i.a.func,prismaSize:i.a.oneOf(["medium","small"]),inline:i.a.bool,screenReaderText:i.a.string};function b(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,a=e.Prisma16,i=e.prismaSize,d=e.inline,b=e.enterpriseSize,h=e.enterpriseWidth,v=e.enterpriseHeight,y=e.screenReaderText,m=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),g=Object(l.useSplunkTheme)(),O=g.family,x=g.density;if("enterprise"===O)return o.a.createElement(t,u({size:b,width:h,height:v,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},m));var j=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?p:f},m);if("small"===i){var w=a||n;return o.a.createElement(w,u({width:"16",height:"16"},j))}if("compact"===x){var C=r||n;return o.a.createElement(C,u({width:"20",height:"20"},j))}return o.a.createElement(n,u({width:"24",height:"24"},j))}b.propTypes=d,b.defaultProps={inline:!0,prismaSize:"medium"}},8:function(e,t){e.exports=n(6493)},80:function(e,t){e.exports=n(2215)}})},4415:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=151)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},10:function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},15:function(e,t){e.exports=n(9213)},151:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return G}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(32),s=n(15),u=n.n(s),p=n(0),f=n(80),d=n(5),b=n(31),h=n(22),v=n(10),y=n(3),m=n.n(y),g=n(8),O=n.n(g),x=n(16),j=n.n(x),w=Object(y.css)(["cursor:not-allowed;color:",";&::placeholder{color:",";}"],Object(p.pick)({enterprise:p.variables.textDisabledColor,prisma:p.variables.contentColorDisabled}),Object(p.pick)({enterprise:p.variables.textDisabledColor,prisma:p.variables.contentColorDisabled})),C=Object(y.css)(["border-radius:",";cursor:pointer;font-size:0.83333em;flex-grow:0;",";&:not([disabled]){color:",";}"],Object(p.pick)({enterprise:p.variables.borderRadius,prisma:"50%"}),Object(p.pick)({enterprise:Object(y.css)(["width:",";height:",";"],p.variables.inputHeight,p.variables.inputHeight),prisma:{comfortable:Object(y.css)(["width:26px;min-width:26px;min-height:26px;margin:8px;padding:0;"]),compact:Object(y.css)(["width:22px;min-width:22px;min-height:22px;margin:8px;padding:0;"])}}),Object(p.pick)({enterprise:{light:p.variables.gray60,dark:p.variables.white},prisma:p.variables.contentColorMuted})),S=m()(j.a).withConfig({displayName:"TextAreaStyles__StyledClearButton",componentId:"gfy8yp-0"})(["display:none;visibility:hidden;",""],C),k=m.a.span.withConfig({displayName:"TextAreaStyles__StyledSearchIconWrapper",componentId:"gfy8yp-1"})(["",";color:",";pointer-events:none;padding:",";",""],p.mixins.reset("inline-block"),Object(p.pick)({enterprise:{light:p.variables.gray60,dark:p.variables.white},prisma:p.variables.contentColorMuted}),Object(p.pick)({comfortable:"0 8px",compact:"0 6px"}),(function(e){return e.$disabled&&Object(y.css)(["",""],Object(p.pick)({enterprise:Object(y.css)(["color:",";"],p.variables.textDisabledColor),prisma:Object(y.css)(["color:",";"],p.variables.contentColorDisabled)}))})),P=m()(O.a).withConfig({displayName:"TextAreaStyles__StyledBox",componentId:"gfy8yp-2"})(["display:flex;justify-content:space-between;flex-grow:1;flex-shrink:1;position:relative;&[data-inline]{width:230px;flex-basis:230px;[data-inline] + &{margin-left:",";}}&:focus-within:not([disabled]){","{","}","{visibility:visible;display:block;}}"],Object(p.pick)({enterprise:p.variables.spacingHalf,prisma:p.variables.spacingSmall}),k,Object(p.pick)({enterprise:Object(y.css)(["display:none;"])}),S),E=m.a.span.withConfig({displayName:"TextAreaStyles__StyledTextAreaWrapper",componentId:"gfy8yp-3"})([""," flex-grow:1;min-height:",";position:relative;overflow:hidden;border:1px solid ",";border-radius:",";box-sizing:border-box;background-color:",";box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);padding:",";"," "," &:hover:not([disabled]){border-color:",";}&:focus-within:not([disabled]){","}"," "," "," ",""],p.mixins.reset("inline-flex"),p.variables.inputHeight,Object(p.pick)({enterprise:{light:p.variables.gray60,dark:p.variables.gray20},prisma:p.variables.interactiveColorBorder}),p.variables.borderRadius,Object(p.pick)({enterprise:{light:p.variables.white,dark:p.variables.gray22},prisma:p.variables.transparent}),Object(p.pick)({enterprise:"0px 0px 0px 10px",prisma:"0px 12px"}),(function(e){return e.$hasEndAdornment&&Object(y.css)(["padding-right:0;"])}),(function(e){return e.$hasStartAdornment&&Object(y.css)(["padding-left:0;"])}),Object(p.pick)({enterprise:{light:p.variables.gray60,dark:p.variables.gray20},prisma:p.variables.interactiveColorBorderHover}),Object(p.pick)({enterprise:Object(y.css)(["box-shadow:",";color:",";"],p.variables.focusShadow,p.variables.textColor),prisma:Object(y.css)(["border-color:",";color:",";"],p.variables.interactiveColorPrimary,p.variables.contentColorActive)}),(function(e){return e.$error&&Object(y.css)(["&,&:hover:not([disabled]){border-color:",";}&:focus-within:not([disabled]){","}"],Object(p.pick)({enterprise:p.variables.errorColor,prisma:p.variables.accentColorNegative}),Object(p.pick)({enterprise:Object(y.css)(["box-shadow:",";color:",";"],p.variables.focusShadow,p.variables.textColor),prisma:Object(y.css)(["border-color:",";color:",";"],p.variables.interactiveColorPrimary,p.variables.contentColorActive)}))}),(function(e){return e.$append&&Object(y.css)(["margin-right:-1px;border-top-right-radius:0;border-bottom-right-radius:0;border-right:none;"])}),(function(e){return e.$prepend&&Object(y.css)(["border-top-left-radius:0;border-bottom-left-radius:0;"])}),(function(e){return e.disabled&&Object(y.css)([""," box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);"],Object(p.pick)({enterprise:{light:Object(y.css)(["background-color:",";border-color:",";"],p.variables.gray96,p.variables.gray92),dark:Object(y.css)(["background-color:",";border-color:",";"],p.variables.gray22,p.variables.gray30)},prisma:Object(y.css)(["border-color:",";"],p.variables.interactiveColorBorderDisabled)}))})),_=m.a.textarea.withConfig({displayName:"TextAreaStyles__StyledTextArea",componentId:"gfy8yp-4"})(["",";outline-style:none;border:0;background:transparent;color:",";flex-grow:1;font-family:",";font-size:inherit;line-height:inherit;padding-top:",";padding-bottom:",";padding-right:",";position:relative;resize:none;overflow:auto;white-space:pre-wrap;&::placeholder{color:",";opacity:1;}"," ",""],p.mixins.reset("inline-flex"),Object(p.pick)({enterprise:p.variables.textColor,prisma:p.variables.contentColorActive}),p.variables.sansFontFamily,Object(p.pick)({enterprise:{comfortable:p.variables.spacingQuarter,compact:"3px"},prisma:{comfortable:p.variables.spacingSmall,compact:"5px"}}),Object(p.pick)({enterprise:{comfortable:p.variables.spacingQuarter,compact:"3px"},prisma:{comfortable:p.variables.spacingSmall,compact:"5px"}}),Object(p.pick)({enterprise:"10px",prisma:"14px"}),p.variables.contentColorMuted,(function(e){return e.$error&&Object(y.css)(["&,&:hover{color:",";}"],Object(p.pick)({enterprise:{light:p.variables.errorColorD10,dark:p.variables.errorColorL20},prisma:p.variables.contentColorActive}))}),(function(e){return e.disabled&&w})),T=(m()(j.a).withConfig({displayName:"TextAreaStyles__StyledVisibilityToggle",componentId:"gfy8yp-5"})(["",""],C),m.a.span.withConfig({displayName:"TextAreaStyles__StyledPlaceholder",componentId:"gfy8yp-6"})(["pointer-events:none;color:",";position:absolute;overflow:hidden;font-size:inherit;line-height:inherit;height:",";margin-right:",";",";",";",""],Object(p.pick)({enterprise:p.variables.textGray,prisma:p.variables.contentColorMuted}),p.variables.lineHeight,Object(p.pick)({enterprise:"10px",prisma:"14px"}),(function(e){var t=e.$hasStartAdornment,n=e.$startAdornmentWidth;return t&&(n?Object(y.css)(["margin-left:","px;"],n):Object(y.css)(["margin-left:",";"],Object(p.pick)({enterprise:{comfortable:"30px",compact:"26px"},prisma:{comfortable:"38px",compact:"30px"}})))}),(function(e){var t=e.$hasEndAdornment,n=e.$endAdornmentWidth;return t&&(n?Object(y.css)(["max-width:calc( 100% - "," - ","px );"],Object(p.pick)({enterprise:"10px",prisma:"14px"}),n):Object(y.css)(["max-width:calc( 100% - "," - "," );"],Object(p.pick)({enterprise:"10px",prisma:"14px"}),Object(p.pick)({enterprise:{comfortable:"30px",compact:"26px"},prisma:{comfortable:"38px",compact:"30px"}})))}),(function(e){var t=e.$hasBothAdornment,n=e.$endAdornmentWidth,r=e.$startAdornmentWidth;return t&&Object(y.css)(["max-width:calc(100% - ","px - ","px);"],r,n)})),Object(y.css)(["display:inline-flex;align-items:center;justify-content:center;height:",";pointer-events:none;"],Object(p.pick)({enterprise:{comfortable:"30px",compact:"26px"},prisma:{comfortable:"38px",compact:"30px"}}))),D=m.a.div.withConfig({displayName:"TextAreaStyles__StyledStartAdornmentHolder",componentId:"gfy8yp-7"})([""," ",";"],T,(function(e){var t=e.$width;return t?Object(y.css)(["min-width:","px;"],t):Object(y.css)(["min-width:",";"],Object(p.pick)({enterprise:{comfortable:"30px",compact:"26px"},prisma:{comfortable:"38px",compact:"30px"}}))})),I=m.a.div.withConfig({displayName:"TextAreaStyles__StyledEndAdornmentHolder",componentId:"gfy8yp-8"})([""," ",";"],T,(function(e){var t=e.$width;return t?Object(y.css)(["min-width:","px;"],t):Object(y.css)(["min-width:",";"],Object(p.pick)({enterprise:{comfortable:"30px",compact:"26px"},prisma:{comfortable:"38px",compact:"30px"}}))})),R=m.a.div.withConfig({displayName:"TextAreaStyles__StyledAdornment",componentId:"gfy8yp-9"})(["display:inline-flex;align-items:center;justify-content:center;position:absolute;pointer-events:none;z-index:1;height:",";color:",";",";",";",""],Object(p.pick)({enterprise:{comfortable:"30px",compact:"26px"},prisma:{comfortable:"38px",compact:"30px"}}),Object(p.pick)({enterprise:{light:p.variables.gray60,dark:p.variables.white},prisma:p.variables.contentColorMuted}),(function(e){return"start"===e.$position?Object(y.css)(["top:1px;left:1px;"]):Object(y.css)(["top:1px;right:1px;"])}),(function(e){return e.disabled&&w}),Object(p.pick)({enterprise:Object(y.css)(["margin-left:-1px;margin-right:-1px;"])}));function L(e){return L="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},L(e)}function A(){return A=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},A.apply(this,arguments)}function M(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function B(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function N(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?B(Object(n),!0).forEach((function(t){W(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):B(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function z(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function F(e,t,n){return t&&z(e.prototype,t),n&&z(e,n),e}function $(e,t){return $=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},$(e,t)}function H(e,t){return!t||"object"!==L(t)&&"function"!=typeof t?V(e):t}function V(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function q(e){return q=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},q(e)}function W(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var K={appearance:i.a.oneOf(["default","search"]),append:i.a.bool,autoCapitalize:i.a.string,autoComplete:i.a.string,autoCorrect:i.a.string,autoFocus:i.a.bool,canClear:i.a.bool,children:i.a.node,classNamePrivate:i.a.string,defaultValue:i.a.string,describedBy:i.a.string,disabled:i.a.bool,elementRef:i.a.oneOfType([i.a.func,i.a.object]),endAdornment:i.a.node,error:i.a.bool,inline:i.a.bool,inputClassName:i.a.string,inputId:i.a.string,inputRef:i.a.oneOfType([i.a.func,i.a.object]),labelledBy:i.a.string,maxLength:i.a.number,name:i.a.string,onBlur:i.a.func,onChange:i.a.func,onFocus:i.a.func,onKeyDown:i.a.func,onSelect:i.a.func,onInputClick:i.a.func,placeholder:i.a.string,prepend:i.a.bool,rowsMax:i.a.number,rowsMin:i.a.number,spellCheck:i.a.bool,tabIndex:i.a.number,startAdornment:i.a.node,splunkTheme:i.a.object,value:i.a.string},U=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&$(e,t)}(a,e);var t,n,r=(t=a,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=q(t);if(n){var o=q(this).constructor;e=Reflect.construct(r,arguments,o)}else e=r.apply(this,arguments);return H(this,e)});function a(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,a),W(V(t=r.call(this,e)),"controlledExternally",void 0),W(V(t),"input",null),W(V(t),"shadow",null),W(V(t),"startAdornment",null),W(V(t),"endAdornment",null),W(V(t),"getAdornmentWidth",(function(){var e=t.startAdornment?t.startAdornment.getBoundingClientRect():void 0,n=e&&Math.round(e.width);t.state.startAdornmentWidth!==n&&t.setState({startAdornmentWidth:n});var r=t.endAdornment?t.endAdornment.getBoundingClientRect():void 0,o=r&&Math.round(r.width);t.state.endAdornmentWidth!==o&&t.setState({endAdornmentWidth:o})})),W(V(t),"handleResize",(function(){t.syncHeightWithShadow()})),W(V(t),"handleInputMount",(function(e){t.input=e,Object(v.a)(t.props.inputRef,e)})),W(V(t),"handleInputChange",(function(e){var n,r,o=e.target.value,a=t.props.name;t.isControlled()||t.setState({value:o}),null===(n=(r=t.props).onChange)||void 0===n||n.call(r,e,{value:o,name:a})})),W(V(t),"handleInputKeyDown",(function(e){var n,r;null===(n=(r=t.props).onKeyDown)||void 0===n||n.call(r,e)})),W(V(t),"handleInputSelect",(function(e){var n,r;null===(n=(r=t.props).onSelect)||void 0===n||n.call(r,e)})),W(V(t),"handleInputClick",(function(e){var n,r;null===(n=(r=t.props).onInputClick)||void 0===n||n.call(r,e)})),W(V(t),"handleInputFocus",(function(e){var n,r;null===(n=(r=t.props).onFocus)||void 0===n||n.call(r,e)})),W(V(t),"handleInputBlur",(function(e){var n,r;null===(n=(r=t.props).onBlur)||void 0===n||n.call(r,e)})),W(V(t),"handleClear",(function(e){var n,r;e.preventDefault();var o=t.props.name;t.isControlled()||t.setState({value:""}),null===(n=(r=t.props).onChange)||void 0===n||n.call(r,e,{value:"",name:o})})),W(V(t),"syncHeightWithShadow",(function(){var e=function(e){var t=e.height,n=e.rowsMax,r=e.rowsMin,o=e.shadow;if(o){var a=window.getComputedStyle(o),i=a.getPropertyValue("line-height");if("inherit"===i||"normal"===i)return!1;var l=parseInt(i,10),c=parseInt(a.getPropertyValue("padding-top"),10),s=parseInt(a.getPropertyValue("padding-bottom"),10),u=parseInt(a.getPropertyValue("border-top-width"),10),p=parseInt(a.getPropertyValue("border-bottom-width"),10),f=o.scrollHeight+u+p;if(void 0===f||isNaN(f))return!1;if(n>=r){var d=n*l+c+s+u+p+1;f=Math.min(d,f)}var b=r*l+c+s+u+p+1;if(t!==(f=Math.max(b,f)))return f}return!1}({height:t.state.height,rowsMax:t.props.rowsMax,rowsMin:t.props.rowsMin,shadow:t.shadow});!1!==e&&t.setState({height:e})})),W(V(t),"renderEndAdornment",(function(){var e,n=t.props,r=n.appearance,a=n.endAdornment,i=n.disabled,l=n.canClear,c=n.splunkTheme.isPrisma,s={ref:function(e){t.endAdornment=e},disabled:i,$position:"end"};if(a)return o.a.createElement(R,s,a);var u=null===(e=t.context.labelAttrs)||void 0===e?void 0:e.text,p=u?Object(d._)("Clear ".concat(u," text field")):Object(d._)("Clear text field");return c||"search"!==r?t.getDisplayValue()&&(c&&"search"===r||l)?o.a.createElement(R,s,!i&&o.a.createElement(S,{"data-test":"clear",appearance:c?"secondary":"pill",onClick:t.handleClear,icon:o.a.createElement(h.a,{inline:!1,enterpriseSize:1,screenReaderText:p})})):void 0:o.a.createElement(R,s,o.a.createElement(S,{appearance:c?"secondary":"pill","data-test":"clear",inline:!1,icon:o.a.createElement(h.a,{enterpriseSize:1,screenReaderText:p}),onClick:t.handleClear}),o.a.createElement(k,{$disabled:i},o.a.createElement(b.a,{enterpriseSize:"16px",inline:!1})))})),W(V(t),"renderStartAdornment",(function(){var e=t.props,n=e.appearance,r=e.startAdornment,a=e.splunkTheme,i=e.disabled,l=a.isPrisma,c={ref:function(e){t.startAdornment=e},disabled:i,$position:"start"};return r?o.a.createElement(R,c,r):l&&"search"===n?o.a.createElement(R,c,o.a.createElement(k,{$disabled:i},o.a.createElement(b.a,{enterpriseSize:"16px",inline:!1,screenReaderText:"Search"}))):void 0})),W(V(t),"getDisplayValue",(function(){return t.isControlled()?t.props.value:t.state.value})),t.controlledExternally=Object(l.has)(e,"value"),t.state={value:e.defaultValue||""},a.validateRows(e),t.handleResize=Object(l.throttle)(t.handleResize,100),t}return F(a,null,[{key:"validateRows",value:function(e){e.rowsMin,e.rowsMax}}]),F(a,[{key:"componentDidMount",value:function(){Object(l.defer)(this.syncHeightWithShadow),this.getAdornmentWidth()}},{key:"componentDidUpdate",value:function(e){this.syncHeightWithShadow(),a.validateRows(this.props),this.getAdornmentWidth()}},{key:"isControlled",value:function(){return this.controlledExternally}},{key:"blur",value:function(){var e;null===(e=this.input)||void 0===e||e.blur()}},{key:"focus",value:function(){var e;null===(e=this.input)||void 0===e||e.focus()}},{key:"select",value:function(){var e;null===(e=this.input)||void 0===e||e.select()}},{key:"render",value:function(){var e,t=this,n=this.props,r=n.append,a=n.autoCapitalize,i=n.autoComplete,s=n.autoCorrect,p=n.autoFocus,f=n.children,d=n.className,b=n.classNamePrivate,h=n.disabled,v=n.describedBy,y=n.elementRef,m=n.error,g=n.inline,O=n.inputClassName,x=n.inputId,j=n.labelledBy,w=n.maxLength,C=n.name,S=n.placeholder,k=n.prepend,T=n.spellCheck,R=n.tabIndex,L=n.title,B=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(n,["append","autoCapitalize","autoComplete","autoCorrect","autoFocus","children","className","classNamePrivate","disabled","describedBy","elementRef","error","inline","inputClassName","inputId","labelledBy","maxLength","name","placeholder","prepend","spellCheck","tabIndex","title"]),z=N(N({},Object(l.pickBy)(B,(function(e,t){return"role"===t||0===t.indexOf("aria-")}))),{},{"aria-describedby":v,"aria-labelledby":j,"aria-invalid":m||void 0,"aria-multiline":!0}),F=Object(l.omit)(B,["inputRef","onBlur","onChange","onFocus","onKeyDown","onSelect","onInputClick","rowsMax","rowsMin"].concat(function(e){if(Array.isArray(e))return M(e)}(e=Object(l.keys)(z))||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return M(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?M(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())),$=this.getDisplayValue(),H={className:Object(c.toClassName)(d,O),$append:r||void 0,$error:m,$prepend:k||void 0},V=N(N({},z),{},{"data-test":"textbox",autoCapitalize:a,autoComplete:i,autoCorrect:s,autoFocus:p,id:x,maxLength:w,placeholder:S,name:C,onChange:this.handleInputChange,onKeyDown:this.handleInputKeyDown,onSelect:this.handleInputSelect,onClick:this.handleInputClick,onFocus:this.handleInputFocus,onBlur:this.handleInputBlur,ref:this.handleInputMount,role:"textbox",spellCheck:T,style:{height:this.state.height},title:L,tabIndex:R,value:$,$error:m}),q=!!this.renderEndAdornment(),W=!!this.renderStartAdornment();return o.a.createElement(P,A({tabIndex:-1,className:Object(c.toClassName)(d,b),"data-test":"text","data-test-value":$,elementRef:y,flex:!0,inline:g},F),this.renderStartAdornment(),o.a.createElement(E,A({$hasEndAdornment:q,$hasStartAdornment:W,disabled:h},H),W&&o.a.createElement(D,{$width:this.state.startAdornmentWidth}),o.a.createElement(_,{"aria-hidden":"true",onChange:l.noop,onClick:this.handleInputClick,style:{width:"100%",position:"absolute",overflow:"hidden",left:-1e4,top:-1e4},tabIndex:-1,ref:function(e){t.shadow=e},value:$}),h?o.a.createElement(_,A({as:"textarea",className:Object(c.toClassName)(d,b),"data-multiline":"true","data-test":"text",disabled:!0,readOnly:!0,style:{height:this.state.height},value:$,placeholder:S,ref:function(e){t.shadow=e}},z)):o.a.createElement(_,A({as:"textarea"},V,{onClick:this.handleInputClick})),o.a.createElement(u.a,{target:window,eventType:"resize",listener:this.handleResize}),f,q&&o.a.createElement(I,{$width:this.state.endAdornmentWidth})),this.renderEndAdornment())}}]),a}(r.Component);W(U,"propTypes",K),W(U,"defaultProps",{appearance:"default",append:!1,autoFocus:!1,canClear:!1,disabled:!1,error:!1,inline:!1,placeholder:"",prepend:!1,rowsMax:8,rowsMin:2,tabIndex:0}),W(U,"componentType","TextArea"),W(U,"contextType",f.ControlGroupContext);var Z=Object(p.withSplunkTheme)(U);Z.propTypes=U.propTypes,Z.componentType=U.componentType;var G=Z},16:function(e,t){e.exports=n(6416)},2:function(e,t){e.exports=n(7294)},22:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(23),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L10.5858 12L5.2929 17.2929C4.90238 17.6834 4.90238 18.3166 5.2929 18.7071C5.68342 19.0976 6.31659 19.0976 6.70711 18.7071L12 13.4142L17.2929 18.7071C17.6834 19.0976 18.3166 19.0976 18.7071 18.7071C19.0976 18.3166 19.0976 17.6834 18.7071 17.2929L13.4142 12L18.7071 6.70711C19.0976 6.31658 19.0976 5.68342 18.7071 5.29289C18.3166 4.90237 17.6834 4.90237 17.2929 5.29289L12 10.5858L6.70711 5.29289Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M12.2024 2.69009C12.5092 2.38325 13.0067 2.38325 13.3136 2.69009C13.6204 2.99693 13.6204 3.49442 13.3136 3.80126L9.11721 7.99762L13.3114 12.1918C13.6206 12.501 13.6206 13.0023 13.3114 13.3114C13.0023 13.6206 12.501 13.6206 12.1918 13.3114L7.99762 9.11721L3.885 13.2298C3.57816 13.5367 3.08067 13.5367 2.77383 13.2298C2.46699 12.923 2.46699 12.4255 2.77383 12.1187L6.88645 8.00604L2.69183 3.81142C2.38267 3.50226 2.38267 3.001 2.69183 2.69183C3.001 2.38267 3.50226 2.38267 3.81142 2.69183L8.00604 6.88646L12.2024 2.69009Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},23:function(e,t){e.exports=n(1476)},3:function(e,t){e.exports=n(2788)},31:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),a=n(43),i=n.n(a),l=n(7),c=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function u(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M10.5,3.0015 C14.6421,3.0015 18,6.3593 18,10.5015 C18,12.2112 17.4279,13.7873 16.4647,15.0489 L20.7077,19.292 C21.0983,19.6825 21.0983,20.3156 20.7077,20.7062 C20.3172,21.0967 19.6841,21.0967 19.2935,20.7062 L15.0509,16.4635 C13.7888,17.4283 12.2113,18.0015 10.5,18.0015 C6.3579,18.0015 3,14.6436 3,10.5015 C3,6.3593 6.3579,3.0015 10.5,3.0015 Z M10.5,5.0015 C7.4624,5.0015 5,7.4639 5,10.5015 C5,13.539 7.4624,16.0015 10.5,16.0015 C13.5376,16.0015 16,13.539 16,10.5015 C16,7.4639 13.5376,5.0015 10.5,5.0015 Z",fill:"currentColor"}))}function p(e){var t=s({},e);return o.a.createElement(c.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M6.85277,2.0015 C9.53288,2.0015 11.7055,4.1741 11.7055,6.8542 C11.7055,7.8463 11.4079,8.7688 10.897,9.5373 L10.9245,9.5098 L14.0018,12.5871 L12.5876,14.0014 L9.51025,10.924 L9.53587,10.8984 C8.76733,11.4093 7.84481,11.707 6.85277,11.707 C4.17266,11.707 2,9.5343 2,6.8542 C2,4.1741 4.17266,2.0015 6.85277,2.0015 Z M6.85277,4.0015 C5.27723,4.0015 4,5.2787 4,6.8542 C4,8.4298 5.27723,9.707 6.85277,9.707 C8.42831,9.707 9.70554,8.4298 9.70554,6.8542 C9.70554,5.2787 8.42831,4.0015 6.85277,4.0015 Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:i.a,Prisma16:p,Prisma24:u},e))}},32:function(e,t){e.exports=n(9867)},4:function(e,t){e.exports=n(5220)},43:function(e,t){e.exports=n(8044)},5:function(e,t){e.exports=n(6219)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var r=n(2),o=n.n(r),a=n(3);function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n.n(a).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function c(e){return o.a.createElement(l,i({xmlns:"http://www.w3.org/2000/svg"},e))}},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(0);function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}var p={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},f={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:i.a.func,enterpriseSize:i.a.oneOfType([i.a.number,i.a.string]),enterpriseWidth:i.a.oneOfType([i.a.number,i.a.string]),enterpriseHeight:i.a.oneOfType([i.a.number,i.a.string]),Prisma24:i.a.func.isRequired,Prisma20:i.a.func,Prisma16:i.a.func,prismaSize:i.a.oneOf(["medium","small"]),inline:i.a.bool,screenReaderText:i.a.string};function b(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,a=e.Prisma16,i=e.prismaSize,d=e.inline,b=e.enterpriseSize,h=e.enterpriseWidth,v=e.enterpriseHeight,y=e.screenReaderText,m=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),g=Object(l.useSplunkTheme)(),O=g.family,x=g.density;if("enterprise"===O)return o.a.createElement(t,u({size:b,width:h,height:v,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},m));var j=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?p:f},m);if("small"===i){var w=a||n;return o.a.createElement(w,u({width:"16",height:"16"},j))}if("compact"===x){var C=r||n;return o.a.createElement(C,u({width:"20",height:"20"},j))}return o.a.createElement(n,u({width:"24",height:"24"},j))}b.propTypes=d,b.defaultProps={inline:!0,prismaSize:"medium"}},8:function(e,t){e.exports=n(6493)},80:function(e,t){e.exports=n(2215)}})},5458:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=152)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},11:function(e,t){e.exports=n(9726)},12:function(e,t){e.exports=n(5917)},14:function(e,t){e.exports=n(5766)},152:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return $}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(18),s=n.n(c),u=n(14),p=n.n(u),f=n(0),d=n(11),b=n(5),h=n(25),v=n.n(h);function y(){return y=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},y.apply(this,arguments)}var m=function(e){var t=Object(f.useSplunkTheme)(),n=t.family,r=t.density;if("enterprise"===n)return o.a.createElement(v.a,y({screenReaderText:Object(b._)("Info Circle"),viewBox:"0 0 24 24"},e),o.a.createElement("path",{fill:"currentColor",d:"M12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22ZM13.2001 8.1999C13.2001 7.53716 12.6628 6.9999 12.0001 6.9999C11.3373 6.9999 10.8001 7.53716 10.8001 8.1999C10.8001 8.86264 11.3373 9.3999 12.0001 9.3999C12.6628 9.3999 13.2001 8.86264 13.2001 8.1999ZM11.0001 16.0094V11.9999C11.0001 11.4476 11.4478 10.9999 12.0001 10.9999C12.5524 10.9999 13.0001 11.4476 13.0001 11.9999V16.0094C13.0001 16.5617 12.5524 17.0094 12.0001 17.0094C11.4478 17.0094 11.0001 16.5617 11.0001 16.0094Z"}));var a="compact"===r?"20":"24";return o.a.createElement("svg",{width:a,height:a,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",style:{display:"block"}},o.a.createElement("path",{d:"M12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22ZM13.2003 8.1999C13.2003 7.53716 12.663 6.9999 12.0003 6.9999C11.3376 6.9999 10.8003 7.53716 10.8003 8.1999C10.8003 8.86264 11.3376 9.3999 12.0003 9.3999C12.663 9.3999 13.2003 8.86264 13.2003 8.1999ZM11.0005 16.0094V11.9999C11.0005 11.4476 11.4482 10.9999 12.0005 10.9999C12.5528 10.9999 13.0005 11.4476 13.0005 11.9999V16.0094C13.0005 16.5617 12.5528 17.0094 12.0005 17.0094C11.4482 17.0094 11.0005 16.5617 11.0005 16.0094Z",fill:"currentColor",fillRule:"evenodd"}))},g=n(3),O=n.n(g),x=n(12),j=n.n(x),w="16px",C=O.a.span.withConfig({displayName:"TooltipStyles__Styled",componentId:"sc-67fvgm-0"})(["",";"],f.mixins.reset("block")),S=O.a.span.withConfig({displayName:"TooltipStyles__StyledInline",componentId:"sc-67fvgm-1"})(["",";"],f.mixins.reset("inline-block")),k=O.a.span.withConfig({displayName:"TooltipStyles__StyledToggle",componentId:"sc-67fvgm-2"})(["display:block;"]),P=O.a.span.withConfig({displayName:"TooltipStyles__StyledToggleInline",componentId:"sc-67fvgm-3"})(["display:inline-block;"]),E=O.a.div.withConfig({displayName:"TooltipStyles__StyledContent",componentId:"sc-67fvgm-4"})(["padding:",";font-size:",";line-height:",";user-select:none;"],Object(f.pick)({enterprise:f.variables.spacingHalf,prisma:Object(f.pickVariant)("$isLabel",{false:"12px 16px",true:"4px 8px"})}),Object(f.pick)({enterprise:f.variables.fontSizeSmall,prisma:"inherit"}),Object(f.pick)({enterprise:"18px",prisma:Object(f.pickVariant)("$isLabel",{false:"inherit",true:"18px"})})),_=O()(j.a).withConfig({displayName:"TooltipStyles__StyledButton",componentId:"sc-67fvgm-5"})(["cursor:default;"," "," &:focus{box-shadow:",";}"],Object(f.pick)({enterprise:Object(g.css)(["display:inline-block;width:",";height:",";border:2px solid ",";border-radius:",";font-size:",";font-weight:",";line-height:calc("," - 2px);text-align:center;color:",";vertical-align:baseline;&:not([disabled]){&:hover{text-decoration:none;}}"],w,w,f.variables.linkColor,w,f.variables.fontSizeSmall,f.variables.fontWeightSemiBold,w,f.variables.linkColor),prisma:Object(g.css)(["color:",";border-radius:50%;display:inline-block;vertical-align:middle;&:hover,&:focus{color:",";background:",";}"],f.variables.contentColorMuted,f.variables.contentColorActive,f.variables.interactiveColorOverlayHover)}),Object(f.pick)({prisma:{comfortable:Object(g.css)(["padding:8px;"]),compact:Object(g.css)(["padding:6px;"])}}),f.variables.focusShadow);function T(e){return T="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},T(e)}function D(){return D=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},D.apply(this,arguments)}function I(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function R(e,t){return R=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},R(e,t)}function L(e,t){return!t||"object"!==T(t)&&"function"!=typeof t?A(e):t}function A(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function M(e){return M=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},M(e)}function B(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var N={appearance:i.a.string,children:i.a.node,closeDelay:i.a.number,closeWhen:i.a.oneOf(["default","notOnClick"]),content:i.a.node,contentRelationship:i.a.oneOf(["label","description"]),defaultPlacement:i.a.oneOf(["above","below","left","right","theme"]),elementRef:i.a.oneOfType([i.a.func,i.a.object]),inline:i.a.bool,onRequestClose:i.a.func,onRequestOpen:i.a.func,open:i.a.bool,openDelay:i.a.oneOfType([i.a.oneOf(["primary","secondary"]),i.a.number]),splunkTheme:i.a.object},z=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&R(e,t)}(u,e);var t,n,a,i,c=(a=u,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=M(a);if(i){var n=M(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return L(this,e)});function u(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,u),B(A(t=c.call(this,e)),"ariaId",void 0),B(A(t),"controlledExternally",void 0),B(A(t),"popoverId",void 0),B(A(t),"timeout",void 0),B(A(t),"handleMount",(function(e){e?(e.addEventListener("mouseenter",t.handleMouseEnter),e.addEventListener("mouseleave",t.handleMouseLeave)):t.state.anchor&&(t.state.anchor.removeEventListener("mouseenter",t.handleMouseEnter),t.state.anchor.removeEventListener("mouseleave",t.handleMouseLeave)),t.setState({anchor:e})})),B(A(t),"handlePopoverMount",(function(e){e?(e.addEventListener("mouseenter",t.handleMouseEnterPopover),e.addEventListener("mouseleave",t.handleMouseLeavePopover)):t.state.popoverEl&&(t.state.popoverEl.removeEventListener("mouseenter",t.handleMouseEnterPopover),t.state.popoverEl.removeEventListener("mouseleave",t.handleMouseLeavePopover)),t.setState({popoverEl:e})})),B(A(t),"handleMouseEnter",(function(e){t.handleRequestOpen(e,{reason:"mouseEnterToggle"})})),B(A(t),"handleMouseEnterPopover",(function(e){"mouseLeavePopover"!==t.state.lastCloseReason&&t.handleRequestOpen(e,{reason:"mouseEnterPopover"})})),B(A(t),"handleMouseLeave",(function(e){t.handleRequestClose(e,{reason:"mouseLeaveToggle"})})),B(A(t),"handleMouseLeavePopover",(function(e){t.handleRequestClose(e,{reason:"mouseLeavePopover"})})),B(A(t),"handleClick",(function(e){"notOnClick"!==t.props.closeWhen&&t.handleRequestClose(e,{reason:"toggleClick"})})),B(A(t),"handleFocus",(function(e){t.handleRequestOpen(e,{reason:"focusToggle"})})),B(A(t),"handleBlur",(function(e){t.handleRequestClose(e,{reason:"blurToggle"})})),B(A(t),"handlePopoverOnRequestClose",(function(e){t.handleRequestClose(null,e)})),B(A(t),"handleRequestClose",(function(e,n){var r=t.props.closeDelay;void 0!==t.timeout&&clearTimeout(t.timeout),t.timeout=setTimeout((function(){var r,o;t.isControlled()||t.setState({open:!1}),t.setState({lastCloseReason:n.reason}),null===(r=(o=t.props).onRequestClose)||void 0===r||r.call(o,e,n)}),r)})),B(A(t),"handleRequestOpen",(function(e,n){var r=t.props.openDelay,o="number"==typeof r?r:"primary"===r?300:750;void 0!==t.timeout&&clearTimeout(t.timeout),t.timeout=setTimeout((function(){var r,o;t.isControlled()||t.setState({open:!0}),null===(r=(o=t.props).onRequestOpen)||void 0===r||r.call(o,e,n)}),o)})),t.controlledExternally=Object(l.has)(e,"open"),t.popoverId=Object(d.createDOMID)("popover"),t.ariaId=Object(d.createDOMID)("aria-id"),t.state={anchor:null,open:!1,popoverEl:null,lastCloseReason:null},t}return t=u,(n=[{key:"componentDidUpdate",value:function(){}},{key:"componentWillUnmount",value:function(){void 0!==this.timeout&&clearTimeout(this.timeout)}},{key:"isControlled",value:function(){return this.controlledExternally}},{key:"render",value:function(){var e,t=this.props,n=t.appearance,a=t.children,i=t.content,l=t.defaultPlacement,c=t.elementRef,u=t.inline,f=(t.onRequestClose,t.onRequestOpen,t.open),d=t.splunkTheme,h=t.contentRelationship,v=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(t,["appearance","children","content","defaultPlacement","elementRef","inline","onRequestClose","onRequestOpen","open","splunkTheme","contentRelationship"]),y=this.state.anchor,g=!!i,O=y&&this.isControlled()?f:g&&this.state.open,x=u?S:C,j=u?P:k,w=d.isPrisma,T=w?"below":"above";return"label"===h?e={labelledBy:this.ariaId,"aria-labelledby":this.ariaId}:"description"===h&&(e={describedBy:this.ariaId,"aria-describedby":this.ariaId}),o.a.createElement(x,D({"data-test":"tooltip","data-test-open":O,"data-test-popover-id":this.popoverId,ref:c},v),o.a.createElement(j,{onClick:this.handleClick,onFocus:this.handleFocus,onBlur:this.handleBlur,ref:this.handleMount,"data-test":"toggle"},g&&Object(r.isValidElement)(a)?Object(r.cloneElement)(a,e):a,g&&!a&&o.a.createElement(_,{"aria-describedby":this.ariaId},w?o.a.createElement(m,{hideDefaultTooltip:!0,screenReaderText:Object(b._)("More info"),style:{height:"22px",width:"22px"}}):o.a.createElement(o.a.Fragment,null,o.a.createElement("span",{"aria-hidden":"true"},"?"),o.a.createElement(p.a,null,Object(b._)("More info")))),g&&o.a.createElement(p.a,{id:this.ariaId},i)),o.a.createElement(s.a,{role:"tooltip",align:"center",anchor:y,appearance:n,closeReasons:["offScreen","escapeKey"],defaultPlacement:"theme"===l?T:l,id:this.popoverId,open:O,onRequestClose:this.handlePopoverOnRequestClose,elementRef:this.handlePopoverMount},o.a.createElement(E,{$isLabel:"label"===h},i)))}}])&&I(t.prototype,n),u}(r.Component);B(z,"propTypes",N),B(z,"defaultProps",{appearance:"inverted",closeDelay:0,closeWhen:"default",contentRelationship:"description",defaultPlacement:"theme",inline:!0,openDelay:"primary"});var F=Object(f.withSplunkTheme)(z);F.propTypes=z.propTypes;var $=F},18:function(e,t){e.exports=n(9016)},2:function(e,t){e.exports=n(7294)},25:function(e,t){e.exports=n(6817)},3:function(e,t){e.exports=n(2788)},4:function(e,t){e.exports=n(5220)},5:function(e,t){e.exports=n(6219)}})},380:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=180)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},180:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return _}));var r=n(2),o=n.n(r),a=n(1),i=n.n(a),l=n(4),c=n(34),s=n(28),u=n(32),p=n(21),f=n(3),d=n.n(f),b=n(0),h=d()(p.animated.div).withConfig({displayName:"TransitionOpenStyles__Styled",componentId:"sc-1x58s0g-0"})(["",";",";"],b.mixins.reset("block"),(function(e){return e.$hideOverflow&&Object(f.css)(["overflow:hidden;"])})),v=d()(p.animated.div).withConfig({displayName:"TransitionOpenStyles__StyledInner",componentId:"sc-1x58s0g-1"})(["",";",";width:100%;"],b.mixins.reset("table"),b.mixins.clearfix());function y(e){return y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},y(e)}function m(){return m=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},m.apply(this,arguments)}function g(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function O(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?g(Object(n),!0).forEach((function(t){k(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):g(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function x(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function j(e,t){return j=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},j(e,t)}function w(e,t){return!t||"object"!==y(t)&&"function"!=typeof t?C(e):t}function C(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function S(e){return S=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},S(e)}function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var P={animation:i.a.oneOf(["slideFromTop","slideFromRight","slideFromBottom","slideFromLeft","expandHeight","expandWidth","none"]),animateOnMount:i.a.bool,children:i.a.node,className:i.a.string,id:i.a.string,innerClassName:i.a.string,innerStyle:i.a.object,onAnimationEnd:i.a.func,open:i.a.bool,outerClassName:i.a.string,outerId:i.a.string,outerStyle:i.a.object,renderChildrenWhenCollapsed:i.a.bool,retainFocus:i.a.bool,takeFocus:i.a.bool},E=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&j(e,t)}(p,e);var t,n,r,a,i=(r=p,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=S(r);if(a){var n=S(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return w(this,e)});function p(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,p),k(C(t=i.call(this,e)),"allowAnimationUpdates",!0),k(C(t),"getValue",(function(e){var n=t.props.animation,r=0;if(e)switch(t.props.takeFocus&&Object(s.takeFocus)(e,"container"),n){case"slideFromTop":case"slideFromBottom":case"expandHeight":case"none":r=e.offsetHeight;break;case"slideFromLeft":case"slideFromRight":case"expandWidth":r=e.offsetWidth}return r})),k(C(t),"handleMount",(function(e){var n=t.getValue(e);t.setState({value:n,innerEl:e})})),k(C(t),"handleRest",(function(){var e,n;t.allowAnimationUpdates&&t.setState({animating:!1}),null===(e=(n=t.props).onAnimationEnd)||void 0===e||e.call(n)})),k(C(t),"handleTab",(function(e){t.state.innerEl&&Object(s.handleTab)(t.state.innerEl,e)})),k(C(t),"internalRender",(function(e){var n,r=e.value,a=e.transform,i=t.props,c=i.animation,s=i.className,f=i.children,d=i.id,b=i.innerClassName,y=i.innerStyle,g=i.open,x=i.outerClassName,j=i.outerId,w=i.outerStyle,C=i.renderChildrenWhenCollapsed,S=t.state.animating;if(S)switch(c){case"slideFromTop":case"slideFromBottom":case"expandHeight":case"none":n="height";break;case"slideFromLeft":case"slideFromRight":case"expandWidth":n="width"}return g||S||!C?o.a.createElement(h,{$hideOverflow:!g||S,className:Object(u.toClassName)(s,x),style:O(O({},w),n&&k({},n,r)),id:j},(g||S)&&o.a.createElement(v,m({"data-test":"transition-open"},Object(l.omit)(t.props,Object(l.keys)(p.propTypes)),{ref:t.handleMount,tabIndex:-1,className:b,id:d,onKeyDown:t.props.retainFocus?t.handleTab:void 0,style:O(O({},y),{},{transform:a})}),f)):o.a.createElement(h,{$hideOverflow:!1,className:Object(u.toClassName)(s,x),style:O(O({},w),n&&k({},n,r)),id:j},o.a.createElement(v,m({"data-test":"transition-open"},Object(l.omit)(t.props,Object(l.keys)(p.propTypes)),{ref:t.handleMount,tabIndex:-1,className:b,id:d,onKeyDown:t.props.retainFocus?t.handleTab:void 0,style:O(O({},y),{},{transform:a,display:"none"})}),f))})),k(C(t),"getSpringTransition",(function(){var e=t.props,n=e.open,r=e.animation,o=t.state.value,a={value:n?o:0},i={value:n?0:o},l={precision:1};if("expandWidth"===r||"expandHeight"===r||"none"===r)return{to:a,config:l};if(!o)return null;if("slideFromTop"!==r&&"slideFromLeft"!==r)return{to:a,from:i,config:l};var c="slideFromTop"===r?"Y":"X",s="translate".concat(c,"(").concat(n?0:-o,"px)"),u="translate".concat(c,"(").concat(n?-o:0,"px)");return{to:O({transform:s},a),from:O({transform:u},i)}})),t.state={animating:!!e.animateOnMount&&e.open,innerEl:null,prevOpen:e.open},t}return t=p,(n=[{key:"componentDidUpdate",value:function(){var e=this.getValue(this.state.innerEl);this.state.value===e||this.state.animating||this.setState({value:e})}},{key:"componentWillUnmount",value:function(){this.allowAnimationUpdates=!1}},{key:"render",value:function(){var e=this.props.animation;return o.a.createElement(c.Spring,m({},this.getSpringTransition(),{immediate:"none"===e,onRest:this.handleRest}),this.internalRender)}}])&&x(t.prototype,n),p}(r.Component);k(E,"propTypes",P),k(E,"defaultProps",{animation:"expandHeight",animateOnMount:!1,innerStyle:{},open:!1,outerStyle:{},renderChildrenWhenCollapsed:!1,retainFocus:!1,takeFocus:!1}),k(E,"getDerivedStateFromProps",(function(e,t){return e.open!==t.prevOpen?{animating:!0,prevOpen:e.open}:null}));var _=E},2:function(e,t){e.exports=n(7294)},21:function(e,t){e.exports=n(9920)},28:function(e,t){e.exports=n(8568)},3:function(e,t){e.exports=n(2788)},32:function(e,t){e.exports=n(9867)},34:function(e,t){e.exports=n(2640)},4:function(e,t){e.exports=n(5220)}})},5473:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=187)}({187:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return a}));var r=n(2);function o(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var a=function(){var e,t,n=(e=Object(r.useReducer)((function(e){return e+1}),0),t=2,function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,a=void 0;try{for(var i,l=e[Symbol.iterator]();!(r=(i=l.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){o=!0,a=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw a}}return n}}(e,t)||function(e,t){if(e){if("string"==typeof e)return o(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?o(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}());return n[0],n[1]}},2:function(e,t){e.exports=n(7294)}})},4592:(e,t)=>{"use strict";function n(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function r(e){return/(^#[0-9a-f]{3}$)|(^#[0-9a-f]{6}$)|(^#[0-9a-f]{4}$)|(^#[0-9a-f]{8}$)/i.test(e.toString().toLowerCase())}Object.defineProperty(t,"__esModule",{value:!0}),t.expandShortHandHex=function(e){if("string"==typeof e){var t=e.startsWith("#"),r=t?e.slice(1):e,o=/^[0-9A-F]{3,4}$/i.test(r),a=(4,function(e){if(Array.isArray(e))return e}(f=r)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,a=void 0;try{for(var i,l=e[Symbol.iterator]();!(r=(i=l.next()).done)&&(n.push(i.value),4!==n.length);r=!0);}catch(e){o=!0,a=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw a}}return n}}(f)||function(e,t){if(e){if("string"==typeof e)return n(e,4);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?n(e,4):void 0}}(f)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),i=a[0],l=a[1],c=a[2],s=a[3],u=void 0===s?"":s,p=o?"".concat(i).concat(i).concat(l).concat(l).concat(c).concat(c).concat(u).concat(u):r;return t?"#".concat(p):p}var f;return e},t.isValidHexColor=r,t.isCSSColor=function(e){return"string"==typeof e&&(!!r(e)||("transparent"===e||"currentColor"===e||o.includes(e.toLowerCase())))},t.extendedColorKeywords=void 0;var o=["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"];t.extendedColorKeywords=o},583:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.stringToKeywords=o,t.testPhrase=a,t.keywordLocationsAll=i,t.keywordLocations=function(e,t){var n=i(e,t);if(!n||n.length!==t.length)return!1;var r=n[0],o=r.start,a=r.end,l=[];function c(){l.push({start:o,end:a})}return n.slice(1).forEach((function(e){e.start>a?(c(),o=e.start,a=e.end):e.end>a&&(a=e.end)})),c(),l},t.filterByKeywords=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(e){return e},r=o(t);return e.filter((function(e){return a(n(e),r)}))};var r=n(5220);function o(e){return(0,r.isString)(e)?(e.match(/(?:[^\s"]+|"[^"]*")+/g)||[]).map((function(e){return e.replace(/^"(.*)"$/,"$1").toLowerCase()})):[]}function a(e,t){if(!(0,r.isString)(e))return!1;var n=e.toLowerCase();return t.every((function(e){return(0,r.includes)(n,e)}))}function i(e,t){if(!(0,r.isString)(e)||!t||!t.length)return!1;var n=e.toLowerCase();return t.reduce((function(e,t){var r=n.indexOf(t);return r>=0&&e.push({keyword:t,start:r,end:r+t.length}),e}),[]).sort((function(e,t){return e.start!==t.start?e.start>t.start?1:-1:e.end>t.end?1:-1}))}},8154:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.sprintf=l,t.abbreviateNumber=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"en-us",n=(0,r.toNumber)(e);return n<=1e3?n.toLocaleString(t):n<1e4?l((0,o._)("%sK"),(0,a.roundToDecimal)(n/1e3,-2).toLocaleString(t)):n<1e5?l((0,o._)("%sK"),(0,a.roundToDecimal)(n/1e3,-1).toLocaleString(t)):n<999500?l((0,o._)("%sK"),(0,a.roundToDecimal)(n/1e3,0).toLocaleString(t)):n<1e7?l((0,o._)("%sM"),(0,a.roundToDecimal)(n/1e6,-2).toLocaleString(t)):n<1e8?l((0,o._)("%sM"),(0,a.roundToDecimal)(n/1e6,-1).toLocaleString(t)):n<9995e5?l((0,o._)("%sM"),(0,a.roundToDecimal)(n/1e6,0).toLocaleString(t)):l((0,o._)("%sB"),n<1e10?(0,a.roundToDecimal)(n/1e9,-2).toLocaleString(t):n<1e11?(0,a.roundToDecimal)(n/1e9,-1).toLocaleString(t):(0,a.roundToDecimal)(n/1e9,0).toLocaleString(t))},t.bytesToFileSize=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"en-us",n=(e||0)/1024;if(n<0)throw new RangeError("bytes must be >= 0");if(0===Math.floor(n))return l((0,o._)("%s B"),e.toLocaleString(t));var r=n/1024;if(0===Math.floor(r))return l((0,o._)("%s KB"),(0,a.roundToDecimal)(n,-2).toLocaleString(t));var i=r/1024;if(0===Math.floor(i))return l((0,o._)("%s MB"),(0,a.roundToDecimal)(r,-2).toLocaleString(t));var c=i/1024;return 0===Math.floor(c)?l((0,o._)("%s GB"),(0,a.roundToDecimal)(i,-2).toLocaleString(t)):l((0,o._)("%s TB"),(0,a.roundToDecimal)(c,-2).toLocaleString(t))},t.smartTrim=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.precomposed,o=void 0!==r&&r;if(!e||t<1||e.length<=t)return e;var a=o?"…":"...";if(1===t)return"".concat(e[0]).concat(a);var i=Math.ceil(e.length/2),l=e.length-t,c=Math.ceil(l/2),s=l-c;return"".concat(e.substring(0,i-c)).concat(a).concat(e.substring(i+s))};var r=n(5220),o=n(6219),a=n(2732),i=n(8816);function l(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];return(0,i.sprintfFormat)((0,i.sprintfParse)(e),[e].concat(n))}},2732:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.strictParseFloat=function(e){return o.test(e)?parseFloat(e):NaN},t.roundToDecimal=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return(0,r.round)(e,-1*t)},t.floorPowerOfTen=function(e){return Math.pow(10,Math.floor(Math.log(e)/Math.LN10))},t.isLessThanMinSafeInt=function(e){return!!(0,r.isNumber)(e)&&e<=-9007199254740991},t.isGreaterThanMaxSafeInt=function(e){return!!(0,r.isNumber)(e)&&e>=9007199254740991};var r=n(5220),o=/(^[-+]?[0-9]*[.]?[0-9]*$)|(^[-+]?[0-9][.]?[0-9]*e[-+]?[0-9][0-9]*$)/i},8816:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.sprintfFormat=l,t.sprintfParse=s;var r=n(5220);function o(e){return o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o(e)}var a={notType:/[^T]/,notPrimitive:/[^v]/,number:/[diefg]/,numericArg:/[bcdiefguxX]/,json:/[j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,keyAccess:/^\.([a-z_][a-z_\d]*)/i,indexAccess:/^\[(\d+)\]/,sign:/^[+-]/};function i(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];return l(s(e),[e].concat(n))}function l(e,t){var n,l,c,s,u,p,f,d,b,h=e.length,v=1,y="";for(l=0;l<h;l+=1)if("string"==typeof e[l])y+=e[l];else if("object"===o(e[l])){if((s=e[l]).keys)for(n=t[v],c=0;c<s.keys.length;c+=1){if(!(0,r.has)(n,s.keys[c]))throw new Error(i('[sprintf] property "%s" does not exist',s.keys[c]));n=n[s.keys[c]]}else s.paramNo?n=t[s.paramNo]:(n=t[v],v+=1);if(a.notType.test(s.type)&&a.notPrimitive.test(s.type)&&n instanceof Function&&(n=n()),a.numericArg.test(s.type)&&"number"!=typeof n&&Number.isNaN(Number(n)))throw new TypeError(i("[sprintf] expecting number but found %T",n));switch(a.number.test(s.type)&&(d=n>=0),s.type){case"b":n=parseInt(n,10).toString(2);break;case"c":n=String.fromCharCode(parseInt(n,10));break;case"d":case"i":n=parseInt(n,10);break;case"j":n=JSON.stringify(n,null,s.width?parseInt(s.width,10):0);break;case"e":n=s.precision?parseFloat(n).toExponential(s.precision):parseFloat(n).toExponential();break;case"f":n=s.precision?parseFloat(n).toFixed(s.precision):parseFloat(n);break;case"g":n=s.precision?String(Number(n.toPrecision(s.precision))):parseFloat(n);break;case"o":n=(parseInt(n,10)>>>0).toString(8);break;case"s":n=String(n),n=s.precision?n.substring(0,s.precision):n;break;case"t":n=String(!!n),n=s.precision?n.substring(0,s.precision):n;break;case"T":n=Object.prototype.toString.call(n).slice(8,-1).toLowerCase(),n=s.precision?n.substring(0,s.precision):n;break;case"u":n=parseInt(n,10)>>>0;break;case"v":n=n.valueOf(),n=s.precision?n.substring(0,s.precision):n;break;case"x":n=(parseInt(n,10)>>>0).toString(16);break;case"X":n=(parseInt(n,10)>>>0).toString(16).toUpperCase()}a.json.test(s.type)?y+=n:(!a.number.test(s.type)||d&&!s.sign?b="":(b=d?"+":"-",n=n.toString().replace(a.sign,"")),p=s.padChar?"0"===s.padChar?"0":s.padChar.charAt(1):" ",f=s.width-(b+n).length,u=s.width&&f>0?(0,r.repeat)(p,f):"",y+=s.align?b+n+u:"0"===p?b+u+n:u+b+n)}return y}var c=Object.create(null);function s(e){if(c[e])return c[e];for(var t,n=e,r=0,o=[];n;){if(null!==(t=a.text.exec(n)))o.push(t[0]);else if(null!==(t=a.modulo.exec(n)))o.push("%");else{if(null===(t=a.placeholder.exec(n)))throw new SyntaxError("[sprintf] unexpected placeholder");if(t[2]){r|=1;var i=t[2],l=[],s=[];if(null===(l=a.key.exec(i)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(s.push(l[1]);""!==(i=i.substring(l[0].length));)if(null!==(l=a.keyAccess.exec(i)))s.push(l[1]);else{if(null===(l=a.indexAccess.exec(i)))throw new SyntaxError("[sprintf] failed to parse named argument key");s.push(l[1])}t[2]=s}else r|=2;if(3===r)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");o.push({placeholder:t[0],paramNo:t[1],keys:t[2],sign:t[3],padChar:t[4],align:t[5],width:t[6],precision:t[7],type:t[8]})}n=n.substring(t[0].length)}return c[e]=o,c[e]}},5101:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isIE11=function(){return!!navigator.userAgent.match(/Trident\/7\./)}},7145:(e,t)=>{"use strict";function n(e){return"object"!=typeof e||"toString"in e?e:Object.prototype.toString.call(e).slice(8,-1)}Object.defineProperty(t,"__esModule",{value:!0});var r="object"==typeof process&&!0;function o(e,t){if(!e){if(r)throw new Error("Invariant failed");throw new Error(t())}}t.invariant=o;var a=Object.prototype.hasOwnProperty,i=Array.prototype.splice,l=Object.prototype.toString;function c(e){return l.call(e).slice(8,-1)}var s=Object.assign||function(e,t){return u(t).forEach((function(n){a.call(t,n)&&(e[n]=t[n])})),e},u="function"==typeof Object.getOwnPropertySymbols?function(e){return Object.keys(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.keys(e)};function p(e){return Array.isArray(e)?s(e.constructor(e.length),e):"Map"===c(e)?new Map(e):"Set"===c(e)?new Set(e):e&&"object"==typeof e?s(Object.create(Object.getPrototypeOf(e)),e):e}var f=function(){function e(){this.commands=s({},d),this.update=this.update.bind(this),this.update.extend=this.extend=this.extend.bind(this),this.update.isEquals=function(e,t){return e===t},this.update.newContext=function(){return(new e).update}}return Object.defineProperty(e.prototype,"isEquals",{get:function(){return this.update.isEquals},set:function(e){this.update.isEquals=e},enumerable:!0,configurable:!0}),e.prototype.extend=function(e,t){this.commands[e]=t},e.prototype.update=function(e,t){var n=this,r="function"==typeof t?{$apply:t}:t;Array.isArray(e)&&Array.isArray(r)||o(!Array.isArray(r),(function(){return"update(): You provided an invalid spec to update(). The spec may not contain an array except as the value of $set, $push, $unshift, $splice or any custom command allowing an array value."})),o("object"==typeof r&&null!==r,(function(){return"update(): You provided an invalid spec to update(). The spec and every included key path must be plain objects containing one of the following commands: "+Object.keys(n.commands).join(", ")+"."}));var i=e;return u(r).forEach((function(t){if(a.call(n.commands,t)){var o=e===i;i=n.commands[t](r[t],i,r,e),o&&n.isEquals(i,e)&&(i=e)}else{var l="Map"===c(e)?n.update(e.get(t),r[t]):n.update(e[t],r[t]),s="Map"===c(i)?i.get(t):i[t];n.isEquals(l,s)&&(void 0!==l||a.call(e,t))||(i===e&&(i=p(e)),"Map"===c(i)?i.set(t,l):i[t]=l)}})),i},e}();t.Context=f;var d={$push:function(e,t,n){return h(t,n,"$push"),e.length?t.concat(e):t},$unshift:function(e,t,n){return h(t,n,"$unshift"),e.length?e.concat(t):t},$splice:function(e,t,r,a){return function(e,t){o(Array.isArray(e),(function(){return"Expected $splice target to be an array; got "+n(e)})),y(t.$splice)}(t,r),e.forEach((function(e){y(e),t===a&&e.length&&(t=p(a)),i.apply(t,e)})),t},$set:function(e,t,n){return function(e){o(1===Object.keys(e).length,(function(){return"Cannot have more than one key in an object with $set"}))}(n),e},$toggle:function(e,t){v(e,"$toggle");var n=e.length?p(t):t;return e.forEach((function(e){n[e]=!t[e]})),n},$unset:function(e,t,n,r){return v(e,"$unset"),e.forEach((function(e){Object.hasOwnProperty.call(t,e)&&(t===r&&(t=p(r)),delete t[e])})),t},$add:function(e,t,n,r){return m(t,"$add"),v(e,"$add"),"Map"===c(t)?e.forEach((function(e){var n=e[0],o=e[1];t===r&&t.get(n)!==o&&(t=p(r)),t.set(n,o)})):e.forEach((function(e){t!==r||t.has(e)||(t=p(r)),t.add(e)})),t},$remove:function(e,t,n,r){return m(t,"$remove"),v(e,"$remove"),e.forEach((function(e){t===r&&t.has(e)&&(t=p(r)),t.delete(e)})),t},$merge:function(e,t,r,a){var i,l;return i=t,o((l=e)&&"object"==typeof l,(function(){return"update(): $merge expects a spec of type 'object'; got "+n(l)})),o(i&&"object"==typeof i,(function(){return"update(): $merge expects a target of type 'object'; got "+n(i)})),u(e).forEach((function(n){e[n]!==t[n]&&(t===a&&(t=p(a)),t[n]=e[n])})),t},$apply:function(e,t){var r;return o("function"==typeof(r=e),(function(){return"update(): expected spec of $apply to be a function; got "+n(r)+"."})),e(t)}},b=new f;function h(e,t,r){o(Array.isArray(e),(function(){return"update(): expected target of "+n(r)+" to be an array; got "+n(e)+"."})),v(t[r],r)}function v(e,t){o(Array.isArray(e),(function(){return"update(): expected spec of "+n(t)+" to be an array; got "+n(e)+". Did you forget to wrap your parameter in an array?"}))}function y(e){o(Array.isArray(e),(function(){return"update(): expected spec of $splice to be an array of arrays; got "+n(e)+". Did you forget to wrap your parameters in an array?"}))}function m(e,t){var r=c(e);o("Map"===r||"Set"===r,(function(){return"update(): "+n(t)+" expects a target of type Set or Map; got "+n(r)}))}t.isEquals=b.update.isEquals,t.extend=b.extend,t.default=b.update,t.default.default=e.exports=s(t.default,t)},4800:(e,t,n)=>{var r=n(3446)(n(6695),"DataView");e.exports=r},8:(e,t,n)=>{var r=n(3446)(n(6695),"Promise");e.exports=r},6405:(e,t,n)=>{var r=n(3446)(n(6695),"Set");e.exports=r},3422:(e,t,n)=>{var r=n(259),o=n(3539),a=n(5413),i=n(8463),l=n(7776),c=n(8929);function s(e){var t=this.__data__=new r(e);this.size=t.size}s.prototype.clear=o,s.prototype.delete=a,s.prototype.get=i,s.prototype.has=l,s.prototype.set=c,e.exports=s},2067:(e,t,n)=>{var r=n(6695).Uint8Array;e.exports=r},6440:(e,t,n)=>{var r=n(3446)(n(6695),"WeakMap");e.exports=r},5953:e=>{e.exports=function(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)}},7456:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length;++n<r&&!1!==t(e[n],n,e););return e}},726:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length,o=0,a=[];++n<r;){var i=e[n];t(i,n,e)&&(a[o++]=i)}return a}},5615:(e,t,n)=>{var r=n(1814),o=n(7579),a=n(6753),i=n(2452),l=n(1348),c=n(9492),s=Object.prototype.hasOwnProperty;e.exports=function(e,t){var n=a(e),u=!n&&o(e),p=!n&&!u&&i(e),f=!n&&!u&&!p&&c(e),d=n||u||p||f,b=d?r(e.length,String):[],h=b.length;for(var v in e)!t&&!s.call(e,v)||d&&("length"==v||p&&("offset"==v||"parent"==v)||f&&("buffer"==v||"byteLength"==v||"byteOffset"==v)||l(v,h))||b.push(v);return b}},1743:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length,o=Array(r);++n<r;)o[n]=t(e[n],n,e);return o}},92:e=>{e.exports=function(e,t){for(var n=-1,r=t.length,o=e.length;++n<r;)e[o+n]=t[n];return e}},2098:(e,t,n)=>{var r=n(6193),o=n(4904),a=Object.prototype.hasOwnProperty;e.exports=function(e,t,n){var i=e[t];a.call(e,t)&&o(i,n)&&(void 0!==n||t in e)||r(e,t,n)}},1155:(e,t,n)=>{var r=n(3867),o=n(2471);e.exports=function(e,t){return e&&r(t,o(t),e)}},9727:(e,t,n)=>{var r=n(3867),o=n(4147);e.exports=function(e,t){return e&&r(t,o(t),e)}},6193:(e,t,n)=>{var r=n(2799);e.exports=function(e,t,n){"__proto__"==t&&r?r(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0}):e[t]=n}},7465:(e,t,n)=>{var r=n(3422),o=n(7456),a=n(2098),i=n(1155),l=n(9727),c=n(8458),s=n(5225),u=n(2975),p=n(5335),f=n(6949),d=n(6227),b=n(8844),h=n(6644),v=n(9042),y=n(8925),m=n(6753),g=n(2452),O=n(8330),x=n(4538),j=n(5341),w=n(2471),C=n(4147),S="[object Arguments]",k="[object Function]",P="[object Object]",E={};E[S]=E["[object Array]"]=E["[object ArrayBuffer]"]=E["[object DataView]"]=E["[object Boolean]"]=E["[object Date]"]=E["[object Float32Array]"]=E["[object Float64Array]"]=E["[object Int8Array]"]=E["[object Int16Array]"]=E["[object Int32Array]"]=E["[object Map]"]=E["[object Number]"]=E[P]=E["[object RegExp]"]=E["[object Set]"]=E["[object String]"]=E["[object Symbol]"]=E["[object Uint8Array]"]=E["[object Uint8ClampedArray]"]=E["[object Uint16Array]"]=E["[object Uint32Array]"]=!0,E["[object Error]"]=E[k]=E["[object WeakMap]"]=!1,e.exports=function e(t,n,_,T,D,I){var R,L=1&n,A=2&n,M=4&n;if(_&&(R=D?_(t,T,D,I):_(t)),void 0!==R)return R;if(!x(t))return t;var B=m(t);if(B){if(R=h(t),!L)return s(t,R)}else{var N=b(t),z=N==k||"[object GeneratorFunction]"==N;if(g(t))return c(t,L);if(N==P||N==S||z&&!D){if(R=A||z?{}:y(t),!L)return A?p(t,l(R,t)):u(t,i(R,t))}else{if(!E[N])return D?t:{};R=v(t,N,L)}}I||(I=new r);var F=I.get(t);if(F)return F;I.set(t,R),j(t)?t.forEach((function(r){R.add(e(r,n,_,r,t,I))})):O(t)&&t.forEach((function(r,o){R.set(o,e(r,n,_,o,t,I))}));var $=B?void 0:(M?A?d:f:A?C:w)(t);return o($||t,(function(r,o){$&&(r=t[o=r]),a(R,o,e(r,n,_,o,t,I))})),R}},4411:(e,t,n)=>{var r=n(4538),o=Object.create,a=function(){function e(){}return function(t){if(!r(t))return{};if(o)return o(t);e.prototype=t;var n=new e;return e.prototype=void 0,n}}();e.exports=a},3895:(e,t,n)=>{var r=n(92),o=n(9399);e.exports=function e(t,n,a,i,l){var c=-1,s=t.length;for(a||(a=o),l||(l=[]);++c<s;){var u=t[c];n>0&&a(u)?n>1?e(u,n-1,a,i,l):r(l,u):i||(l[l.length]=u)}return l}},435:(e,t,n)=>{var r=n(8637),o=n(2351);e.exports=function(e,t){for(var n=0,a=(t=r(t,e)).length;null!=e&&n<a;)e=e[o(t[n++])];return n&&n==a?e:void 0}},4043:(e,t,n)=>{var r=n(92),o=n(6753);e.exports=function(e,t,n){var a=t(e);return o(e)?a:r(a,n(e))}},3742:(e,t,n)=>{var r=n(7486),o=n(7101);e.exports=function(e){return o(e)&&"[object Arguments]"==r(e)}},9575:(e,t,n)=>{var r=n(8844),o=n(7101);e.exports=function(e){return o(e)&&"[object Map]"==r(e)}},8125:(e,t,n)=>{var r=n(8844),o=n(7101);e.exports=function(e){return o(e)&&"[object Set]"==r(e)}},753:(e,t,n)=>{var r=n(7486),o=n(9620),a=n(7101),i={};i["[object Float32Array]"]=i["[object Float64Array]"]=i["[object Int8Array]"]=i["[object Int16Array]"]=i["[object Int32Array]"]=i["[object Uint8Array]"]=i["[object Uint8ClampedArray]"]=i["[object Uint16Array]"]=i["[object Uint32Array]"]=!0,i["[object Arguments]"]=i["[object Array]"]=i["[object ArrayBuffer]"]=i["[object Boolean]"]=i["[object DataView]"]=i["[object Date]"]=i["[object Error]"]=i["[object Function]"]=i["[object Map]"]=i["[object Number]"]=i["[object Object]"]=i["[object RegExp]"]=i["[object Set]"]=i["[object String]"]=i["[object WeakMap]"]=!1,e.exports=function(e){return a(e)&&o(e.length)&&!!i[r(e)]}},429:(e,t,n)=>{var r=n(1235),o=n(3118),a=Object.prototype.hasOwnProperty;e.exports=function(e){if(!r(e))return o(e);var t=[];for(var n in Object(e))a.call(e,n)&&"constructor"!=n&&t.push(n);return t}},8470:(e,t,n)=>{var r=n(4538),o=n(1235),a=n(6782),i=Object.prototype.hasOwnProperty;e.exports=function(e){if(!r(e))return a(e);var t=o(e),n=[];for(var l in e)("constructor"!=l||!t&&i.call(e,l))&&n.push(l);return n}},8724:(e,t,n)=>{var r=n(2882),o=n(2799),a=n(4631),i=o?function(e,t){return o(e,"toString",{configurable:!0,enumerable:!1,value:r(t),writable:!0})}:a;e.exports=i},4772:e=>{e.exports=function(e,t,n){var r=-1,o=e.length;t<0&&(t=-t>o?0:o+t),(n=n>o?o:n)<0&&(n+=o),o=t>n?0:n-t>>>0,t>>>=0;for(var a=Array(o);++r<o;)a[r]=e[r+t];return a}},1814:e=>{e.exports=function(e,t){for(var n=-1,r=Array(e);++n<e;)r[n]=t(n);return r}},9968:(e,t,n)=>{var r=n(4380),o=n(1743),a=n(6753),i=n(9530),l=r?r.prototype:void 0,c=l?l.toString:void 0;e.exports=function e(t){if("string"==typeof t)return t;if(a(t))return o(t,e)+"";if(i(t))return c?c.call(t):"";var n=t+"";return"0"==n&&1/t==-1/0?"-0":n}},6169:e=>{e.exports=function(e){return function(t){return e(t)}}},6985:(e,t,n)=>{var r=n(8637),o=n(2721),a=n(195),i=n(2351);e.exports=function(e,t){return t=r(t,e),null==(e=a(e,t))||delete e[i(o(t))]}},8637:(e,t,n)=>{var r=n(6753),o=n(3865),a=n(8960),i=n(708);e.exports=function(e,t){return r(e)?e:o(e,t)?[e]:a(i(e))}},7922:(e,t,n)=>{var r=n(2067);e.exports=function(e){var t=new e.constructor(e.byteLength);return new r(t).set(new r(e)),t}},8458:(e,t,n)=>{e=n.nmd(e);var r=n(6695),o=t&&!t.nodeType&&t,a=o&&e&&!e.nodeType&&e,i=a&&a.exports===o?r.Buffer:void 0,l=i?i.allocUnsafe:void 0;e.exports=function(e,t){if(t)return e.slice();var n=e.length,r=l?l(n):new e.constructor(n);return e.copy(r),r}},2518:(e,t,n)=>{var r=n(7922);e.exports=function(e,t){var n=t?r(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.byteLength)}},6823:e=>{var t=/\w*$/;e.exports=function(e){var n=new e.constructor(e.source,t.exec(e));return n.lastIndex=e.lastIndex,n}},9753:(e,t,n)=>{var r=n(4380),o=r?r.prototype:void 0,a=o?o.valueOf:void 0;e.exports=function(e){return a?Object(a.call(e)):{}}},4258:(e,t,n)=>{var r=n(7922);e.exports=function(e,t){var n=t?r(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.length)}},5225:e=>{e.exports=function(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n<r;)t[n]=e[n];return t}},3867:(e,t,n)=>{var r=n(2098),o=n(6193);e.exports=function(e,t,n,a){var i=!n;n||(n={});for(var l=-1,c=t.length;++l<c;){var s=t[l],u=a?a(n[s],e[s],s,n,e):void 0;void 0===u&&(u=e[s]),i?o(n,s,u):r(n,s,u)}return n}},2975:(e,t,n)=>{var r=n(3867),o=n(690);e.exports=function(e,t){return r(e,o(e),t)}},5335:(e,t,n)=>{var r=n(3867),o=n(5579);e.exports=function(e,t){return r(e,o(e),t)}},2694:(e,t,n)=>{var r=n(8474);e.exports=function(e){return r(e)?void 0:e}},2799:(e,t,n)=>{var r=n(3446),o=function(){try{var e=r(Object,"defineProperty");return e({},"",{}),e}catch(e){}}();e.exports=o},3381:(e,t,n)=>{var r=n(3608),o=n(1987),a=n(4093);e.exports=function(e){return a(o(e,void 0,r),e+"")}},6949:(e,t,n)=>{var r=n(4043),o=n(690),a=n(2471);e.exports=function(e){return r(e,a,o)}},6227:(e,t,n)=>{var r=n(4043),o=n(5579),a=n(4147);e.exports=function(e){return r(e,a,o)}},2439:(e,t,n)=>{var r=n(340)(Object.getPrototypeOf,Object);e.exports=r},690:(e,t,n)=>{var r=n(726),o=n(5963),a=Object.prototype.propertyIsEnumerable,i=Object.getOwnPropertySymbols,l=i?function(e){return null==e?[]:(e=Object(e),r(i(e),(function(t){return a.call(e,t)})))}:o;e.exports=l},5579:(e,t,n)=>{var r=n(92),o=n(2439),a=n(690),i=n(5963),l=Object.getOwnPropertySymbols?function(e){for(var t=[];e;)r(t,a(e)),e=o(e);return t}:i;e.exports=l},8844:(e,t,n)=>{var r=n(4800),o=n(6299),a=n(8),i=n(6405),l=n(6440),c=n(7486),s=n(6154),u="[object Map]",p="[object Promise]",f="[object Set]",d="[object WeakMap]",b="[object DataView]",h=s(r),v=s(o),y=s(a),m=s(i),g=s(l),O=c;(r&&O(new r(new ArrayBuffer(1)))!=b||o&&O(new o)!=u||a&&O(a.resolve())!=p||i&&O(new i)!=f||l&&O(new l)!=d)&&(O=function(e){var t=c(e),n="[object Object]"==t?e.constructor:void 0,r=n?s(n):"";if(r)switch(r){case h:return b;case v:return u;case y:return p;case m:return f;case g:return d}return t}),e.exports=O},6644:e=>{var t=Object.prototype.hasOwnProperty;e.exports=function(e){var n=e.length,r=new e.constructor(n);return n&&"string"==typeof e[0]&&t.call(e,"index")&&(r.index=e.index,r.input=e.input),r}},9042:(e,t,n)=>{var r=n(7922),o=n(2518),a=n(6823),i=n(9753),l=n(4258);e.exports=function(e,t,n){var c=e.constructor;switch(t){case"[object ArrayBuffer]":return r(e);case"[object Boolean]":case"[object Date]":return new c(+e);case"[object DataView]":return o(e,n);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return l(e,n);case"[object Map]":case"[object Set]":return new c;case"[object Number]":case"[object String]":return new c(e);case"[object RegExp]":return a(e);case"[object Symbol]":return i(e)}}},8925:(e,t,n)=>{var r=n(4411),o=n(2439),a=n(1235);e.exports=function(e){return"function"!=typeof e.constructor||a(e)?{}:r(o(e))}},9399:(e,t,n)=>{var r=n(4380),o=n(7579),a=n(6753),i=r?r.isConcatSpreadable:void 0;e.exports=function(e){return a(e)||o(e)||!!(i&&e&&e[i])}},1348:e=>{var t=/^(?:0|[1-9]\d*)$/;e.exports=function(e,n){var r=typeof e;return!!(n=null==n?9007199254740991:n)&&("number"==r||"symbol"!=r&&t.test(e))&&e>-1&&e%1==0&&e<n}},3865:(e,t,n)=>{var r=n(6753),o=n(9530),a=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,i=/^\w*$/;e.exports=function(e,t){if(r(e))return!1;var n=typeof e;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=e&&!o(e))||i.test(e)||!a.test(e)||null!=t&&e in Object(t)}},1235:e=>{var t=Object.prototype;e.exports=function(e){var n=e&&e.constructor;return e===("function"==typeof n&&n.prototype||t)}},704:(e,t,n)=>{var r=n(9776);e.exports=function(e){var t=r(e,(function(e){return 500===n.size&&n.clear(),e})),n=t.cache;return t}},3118:(e,t,n)=>{var r=n(340)(Object.keys,Object);e.exports=r},6782:e=>{e.exports=function(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}},6924:(e,t,n)=>{e=n.nmd(e);var r=n(8552),o=t&&!t.nodeType&&t,a=o&&e&&!e.nodeType&&e,i=a&&a.exports===o&&r.process,l=function(){try{return a&&a.require&&a.require("util").types||i&&i.binding&&i.binding("util")}catch(e){}}();e.exports=l},340:e=>{e.exports=function(e,t){return function(n){return e(t(n))}}},1987:(e,t,n)=>{var r=n(5953),o=Math.max;e.exports=function(e,t,n){return t=o(void 0===t?e.length-1:t,0),function(){for(var a=arguments,i=-1,l=o(a.length-t,0),c=Array(l);++i<l;)c[i]=a[t+i];i=-1;for(var s=Array(t+1);++i<t;)s[i]=a[i];return s[t]=n(c),r(e,this,s)}}},195:(e,t,n)=>{var r=n(435),o=n(4772);e.exports=function(e,t){return t.length<2?e:r(e,o(t,0,-1))}},4093:(e,t,n)=>{var r=n(8724),o=n(696)(r);e.exports=o},696:e=>{var t=Date.now;e.exports=function(e){var n=0,r=0;return function(){var o=t(),a=16-(o-r);if(r=o,a>0){if(++n>=800)return arguments[0]}else n=0;return e.apply(void 0,arguments)}}},3539:(e,t,n)=>{var r=n(259);e.exports=function(){this.__data__=new r,this.size=0}},5413:e=>{e.exports=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n}},8463:e=>{e.exports=function(e){return this.__data__.get(e)}},7776:e=>{e.exports=function(e){return this.__data__.has(e)}},8929:(e,t,n)=>{var r=n(259),o=n(6299),a=n(3209);e.exports=function(e,t){var n=this.__data__;if(n instanceof r){var i=n.__data__;if(!o||i.length<199)return i.push([e,t]),this.size=++n.size,this;n=this.__data__=new a(i)}return n.set(e,t),this.size=n.size,this}},8960:(e,t,n)=>{var r=n(704),o=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,a=/\\(\\)?/g,i=r((function(e){var t=[];return 46===e.charCodeAt(0)&&t.push(""),e.replace(o,(function(e,n,r,o){t.push(r?o.replace(a,"$1"):n||e)})),t}));e.exports=i},2351:(e,t,n)=>{var r=n(9530);e.exports=function(e){if("string"==typeof e||r(e))return e;var t=e+"";return"0"==t&&1/e==-1/0?"-0":t}},2882:e=>{e.exports=function(e){return function(){return e}}},3608:(e,t,n)=>{var r=n(3895);e.exports=function(e){return null!=e&&e.length?r(e,1):[]}},4631:e=>{e.exports=function(e){return e}},7579:(e,t,n)=>{var r=n(3742),o=n(7101),a=Object.prototype,i=a.hasOwnProperty,l=a.propertyIsEnumerable,c=r(function(){return arguments}())?r:function(e){return o(e)&&i.call(e,"callee")&&!l.call(e,"callee")};e.exports=c},6753:e=>{var t=Array.isArray;e.exports=t},2133:(e,t,n)=>{var r=n(9657),o=n(9620);e.exports=function(e){return null!=e&&o(e.length)&&!r(e)}},2452:(e,t,n)=>{e=n.nmd(e);var r=n(6695),o=n(1220),a=t&&!t.nodeType&&t,i=a&&e&&!e.nodeType&&e,l=i&&i.exports===a?r.Buffer:void 0,c=(l?l.isBuffer:void 0)||o;e.exports=c},9620:e=>{e.exports=function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}},8330:(e,t,n)=>{var r=n(9575),o=n(6169),a=n(6924),i=a&&a.isMap,l=i?o(i):r;e.exports=l},7101:e=>{e.exports=function(e){return null!=e&&"object"==typeof e}},8474:(e,t,n)=>{var r=n(7486),o=n(2439),a=n(7101),i=Function.prototype,l=Object.prototype,c=i.toString,s=l.hasOwnProperty,u=c.call(Object);e.exports=function(e){if(!a(e)||"[object Object]"!=r(e))return!1;var t=o(e);if(null===t)return!0;var n=s.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&c.call(n)==u}},5341:(e,t,n)=>{var r=n(8125),o=n(6169),a=n(6924),i=a&&a.isSet,l=i?o(i):r;e.exports=l},9530:(e,t,n)=>{var r=n(7486),o=n(7101);e.exports=function(e){return"symbol"==typeof e||o(e)&&"[object Symbol]"==r(e)}},9492:(e,t,n)=>{var r=n(753),o=n(6169),a=n(6924),i=a&&a.isTypedArray,l=i?o(i):r;e.exports=l},2471:(e,t,n)=>{var r=n(5615),o=n(429),a=n(2133);e.exports=function(e){return a(e)?r(e):o(e)}},4147:(e,t,n)=>{var r=n(5615),o=n(8470),a=n(2133);e.exports=function(e){return a(e)?r(e,!0):o(e)}},2721:e=>{e.exports=function(e){var t=null==e?0:e.length;return t?e[t-1]:void 0}},3461:(e,t,n)=>{var r=n(1743),o=n(7465),a=n(6985),i=n(8637),l=n(3867),c=n(2694),s=n(3381),u=n(6227),p=s((function(e,t){var n={};if(null==e)return n;var s=!1;t=r(t,(function(t){return t=i(t,e),s||(s=t.length>1),t})),l(e,u(e),n),s&&(n=o(n,7,c));for(var p=t.length;p--;)a(n,t[p]);return n}));e.exports=p},5963:e=>{e.exports=function(){return[]}},1220:e=>{e.exports=function(){return!1}},708:(e,t,n)=>{var r=n(9968);e.exports=function(e){return null==e?"":r(e)}},7794:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>T});var r=n(7294),o=n(3935);function a(e){var t=!1;return function(){t||(console.warn(e),t=!0)}}a("\n>> Error, via react-flip-move <<\n\nYou provided a stateless functional component as a child to <FlipMove>. Unfortunately, SFCs aren't supported, because Flip Move needs access to the backing instances via refs, and SFCs don't have a public instance that holds that info.\n\nPlease wrap your components in a native element (eg. <div>), or a non-functional component.\n"),a("\n>> Error, via react-flip-move <<\n\nYou provided a primitive (text or number) node as a child to <FlipMove>. Flip Move needs containers with unique keys to move children around.\n\nPlease wrap your value in a native element (eg. <span>), or a component.\n");var i,l,c=a("\n>> Warning, via react-flip-move <<\n\nWhen using \"wrapperless\" mode (by supplying 'typeName' of 'null'), strange things happen when the direct parent has the default \"static\" position.\n\nFlipMove has added 'position: relative' to this node, to ensure Flip Move animates correctly.\n\nTo avoid seeing this warning, simply apply a non-static position to that parent node.\n"),s=a("\n>> Warning, via react-flip-move <<\n\nOne or more of Flip Move's child elements have the html attribute 'disabled' set to true.\n\nPlease note that this will cause animations to break in Internet Explorer 11 and below. Either remove the disabled attribute or set 'animation' to false.\n"),u={elevator:{from:{transform:"scale(0)",opacity:"0"},to:{transform:"",opacity:""}},fade:{from:{opacity:"0"},to:{opacity:""}},accordionVertical:{from:{transform:"scaleY(0)",transformOrigin:"center top"},to:{transform:"",transformOrigin:"center top"}},accordionHorizontal:{from:{transform:"scaleX(0)",transformOrigin:"left center"},to:{transform:"",transformOrigin:"left center"}},none:null},p={elevator:{from:{transform:"scale(1)",opacity:"1"},to:{transform:"scale(0)",opacity:"0"}},fade:{from:{opacity:"1"},to:{opacity:"0"}},accordionVertical:{from:{transform:"scaleY(1)",transformOrigin:"center top"},to:{transform:"scaleY(0)",transformOrigin:"center top"}},accordionHorizontal:{from:{transform:"scaleX(1)",transformOrigin:"left center"},to:{transform:"scaleX(0)",transformOrigin:"left center"}},none:null},f=u,d="elevator",b=function(e,t){for(var n=0;n<t.length;n++)if(e(t[n],n,t))return t[n]},h=function(e){return(h=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)})(e)},v=(i=function(e){return e.replace(/([A-Z])/g,"-$1").toLowerCase()},l={},function(e){return l[e]||(l[e]=i(e)),l[e]}),y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},m=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},g=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},O=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)},x=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t};function j(e){var t,n;return n=t=function(t){function n(){return m(this,n),x(this,t.apply(this,arguments))}return O(n,t),n.prototype.checkChildren=function(e){},n.prototype.convertProps=function(e){var t={children:e.children,easing:e.easing,onStart:e.onStart,onFinish:e.onFinish,onStartAll:e.onStartAll,onFinishAll:e.onFinishAll,typeName:e.typeName,disableAllAnimations:e.disableAllAnimations,getPosition:e.getPosition,maintainContainerHeight:e.maintainContainerHeight,verticalAlignment:e.verticalAlignment,duration:this.convertTimingProp("duration"),delay:this.convertTimingProp("delay"),staggerDurationBy:this.convertTimingProp("staggerDurationBy"),staggerDelayBy:this.convertTimingProp("staggerDelayBy"),appearAnimation:this.convertAnimationProp(e.appearAnimation,f),enterAnimation:this.convertAnimationProp(e.enterAnimation,u),leaveAnimation:this.convertAnimationProp(e.leaveAnimation,p),delegated:{}};this.checkChildren(t.children);var n=Object.keys(t),r=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n={};return Object.keys(e).forEach((function(r){-1===t.indexOf(r)&&(n[r]=e[r])})),n}(this.props,n);return r.style=g({position:"relative"},r.style),t.delegated=r,t},n.prototype.convertTimingProp=function(e){var t=this.props[e],r="number"==typeof t?t:parseInt(t,10);return isNaN(r)?n.defaultProps[e]:r},n.prototype.convertAnimationProp=function(e,t){switch(void 0===e?"undefined":y(e)){case"boolean":return t[e?d:"none"];case"string":return-1===Object.keys(t).indexOf(e)?t.elevator:t[e];default:return e}},n.prototype.render=function(){return r.createElement(e,this.convertProps(this.props))},n}(r.Component),t.defaultProps={easing:"ease-in-out",duration:350,delay:0,staggerDurationBy:0,staggerDelayBy:0,typeName:"div",enterAnimation:d,leaveAnimation:d,disableAllAnimations:!1,getPosition:function(e){return e.getBoundingClientRect()},maintainContainerHeight:!1,verticalAlignment:"top"},n}function w(e){var t=e.domNode,n=e.styles;Object.keys(n).forEach((function(e){t.style.setProperty(v(e),n[e])}))}var C=function(e){var t=e.childDomNode,n={top:0,left:0,right:0,bottom:0,height:0,width:0},r=e.childBoundingBox||n,o=e.parentBoundingBox||n,a=(0,e.getPosition)(t),i=a.top-o.top,l=a.left-o.left;return[r.left-l,r.top-i]},S=function(e,t){var n=t.delay,r=t.duration,o=t.staggerDurationBy,a=t.staggerDelayBy,i=t.easing;return n+=e*a,r+=e*o,["transform","opacity"].map((function(e){return e+" "+r+"ms "+i+" "+n+"ms"})).join(", ")},k=function(){var e={transition:"transitionend","-o-transition":"oTransitionEnd","-moz-transition":"transitionend","-webkit-transition":"webkitTransitionEnd"};if("undefined"==typeof document)return"";var t=document.createElement("fakeelement"),n=b((function(e){return void 0!==t.style.getPropertyValue(e)}),Object.keys(e));return n?e[n]:""}(),P=!k;function E(e){return e.key||""}function _(e){return r.Children.toArray(e)}const T=j(function(e){function t(){var n,r;m(this,t);for(var a=arguments.length,i=Array(a),l=0;l<a;l++)i[l]=arguments[l];return n=r=x(this,e.call.apply(e,[this].concat(i))),r.state={children:_(r.props?r.props.children:[]).map((function(e){return g({},e,{element:e,appearing:!0})}))},r.childrenData={},r.parentData={domNode:null,boundingBox:null},r.heightPlaceholderData={domNode:null},r.remainingAnimations=0,r.childrenToAnimate=[],r.findDOMContainer=function(){var e=o.findDOMNode(r),t=e&&e.parentNode;t&&t instanceof HTMLElement&&("static"===window.getComputedStyle(t).position&&(t.style.position="relative",c()),r.parentData.domNode=t)},r.runAnimation=function(){var e=r.state.children.filter(r.doesChildNeedToBeAnimated),t=e.map((function(e){return r.computeInitialStyles(e)}));e.forEach((function(e,n){r.remainingAnimations+=1,r.childrenToAnimate.push(E(e)),r.animateChild(e,n,t[n])})),"function"==typeof r.props.onStartAll&&r.callChildrenHook(r.props.onStartAll)},r.doesChildNeedToBeAnimated=function(e){if(!E(e))return!1;var t=r.getChildData(E(e)),n=t.domNode,o=t.boundingBox,a=r.parentData.boundingBox;if(!n)return!1;var i=r.props,l=i.appearAnimation,c=i.enterAnimation,s=i.leaveAnimation,u=i.getPosition,p=e.appearing&&l,f=e.entering&&c,d=e.leaving&&s;if(p||f||d)return!0;var b=C({childDomNode:n,childBoundingBox:o,parentBoundingBox:a,getPosition:u}),h=b[0],v=b[1];return 0!==h||0!==v},x(r,n)}return O(t,e),t.prototype.componentDidMount=function(){null===this.props.typeName&&this.findDOMContainer(),this.props.appearAnimation&&!this.isAnimationDisabled(this.props)&&(this.prepForAnimation(),this.runAnimation())},t.prototype.componentDidUpdate=function(e){null===this.props.typeName&&this.findDOMContainer(),!function(e,t){if(e===t)return!0;var n=!h(e)||!h(t),r=e.length!==t.length;return!n&&!r&&function(e,n){for(var r=0;r<n.length;r++)if(n[r]!==t[r])return!1;return!0}(0,e)}(_(this.props.children).map((function(e){return e.key})),_(e.children).map((function(e){return e.key})))&&!this.isAnimationDisabled(this.props)&&(this.prepForAnimation(),this.runAnimation())},t.prototype.calculateNextSetOfChildren=function(e){var t=this,n=e.map((function(e){var n=t.findChildByKey(e.key),r=!n||n.leaving;return g({},e,{element:e,entering:r})})),r=0;return this.state.children.forEach((function(o,a){if(!b((function(e){return e.key===E(o)}),e)&&t.props.leaveAnimation){var i=g({},o,{leaving:!0}),l=a+r;n.splice(l,0,i),r+=1}})),n},t.prototype.prepForAnimation=function(){var e=this,t=this.props,n=t.leaveAnimation,r=t.maintainContainerHeight,o=t.getPosition;n&&(this.state.children.filter((function(e){return e.leaving})).forEach((function(t){var n=e.getChildData(E(t));!e.isAnimationDisabled(e.props)&&n.domNode&&n.domNode.disabled&&s(),n.boundingBox&&function(e,t){var n=e.domNode,r=e.boundingBox;if(n&&r){var o=window.getComputedStyle(n),a=["margin-top","margin-left","margin-right"].reduce((function(e,t){var n,r=o.getPropertyValue(t);return g({},e,((n={})[t]=Number(r.replace("px","")),n))}),{});w({domNode:n,styles:{position:"absolute",top:("bottom"===t?r.top-r.height:r.top)-a["margin-top"]+"px",left:r.left-a["margin-left"]+"px",right:r.right-a["margin-right"]+"px"}})}}(n,e.props.verticalAlignment)})),r&&this.heightPlaceholderData.domNode&&function(e){var t=e.domNode,n=e.parentData,r=e.getPosition,o=n.domNode,a=n.boundingBox;if(o&&a){w({domNode:t,styles:{height:"0"}});var i=a.height-r(o).height;w({domNode:t,styles:{height:i>0?i+"px":"0"}})}}({domNode:this.heightPlaceholderData.domNode,parentData:this.parentData,getPosition:o})),this.state.children.forEach((function(t){var n=e.getChildData(E(t)).domNode;n&&(t.entering||t.leaving||w({domNode:n,styles:{transition:""}}))}))},t.prototype.UNSAFE_componentWillReceiveProps=function(e){this.updateBoundingBoxCaches();var t=_(e.children);this.setState({children:this.isAnimationDisabled(e)?t.map((function(e){return g({},e,{element:e})})):this.calculateNextSetOfChildren(t)})},t.prototype.animateChild=function(e,t,n){var r=this,o=this.getChildData(E(e)).domNode;o&&(w({domNode:o,styles:n}),this.props.onStart&&this.props.onStart(e,o),requestAnimationFrame((function(){requestAnimationFrame((function(){var n={transition:S(t,r.props),transform:"",opacity:""};e.appearing&&r.props.appearAnimation?n=g({},n,r.props.appearAnimation.to):e.entering&&r.props.enterAnimation?n=g({},n,r.props.enterAnimation.to):e.leaving&&r.props.leaveAnimation&&(n=g({},n,r.props.leaveAnimation.to)),w({domNode:o,styles:n})}))})),this.bindTransitionEndHandler(e))},t.prototype.bindTransitionEndHandler=function(e){var t=this,n=this.getChildData(E(e)).domNode;n&&n.addEventListener(k,(function r(o){o.target===n&&(n.style.transition="",t.triggerFinishHooks(e,n),n.removeEventListener(k,r),e.leaving&&t.removeChildData(E(e)))}))},t.prototype.triggerFinishHooks=function(e,t){var n=this;if(this.props.onFinish&&this.props.onFinish(e,t),this.remainingAnimations-=1,0===this.remainingAnimations){var r=this.state.children.filter((function(e){return!e.leaving})).map((function(e){return g({},e,{element:e.element,appearing:!1,entering:!1})}));this.setState({children:r},(function(){"function"==typeof n.props.onFinishAll&&n.callChildrenHook(n.props.onFinishAll),n.childrenToAnimate=[]})),this.heightPlaceholderData.domNode&&(this.heightPlaceholderData.domNode.style.height="0")}},t.prototype.callChildrenHook=function(e){var t=this,n=[],r=[];this.childrenToAnimate.forEach((function(e){var o=t.findChildByKey(e);o&&(n.push(o),t.hasChildData(e)&&r.push(t.getChildData(e).domNode))})),e(n,r)},t.prototype.updateBoundingBoxCaches=function(){var e=this,t=this.parentData.domNode;if(t){this.parentData.boundingBox=this.props.getPosition(t);var n=[];this.state.children.forEach((function(r){var o,a,i,l,c,s,u,p,f,d,b,h=E(r);if(h)if(e.hasChildData(h)){var v=e.getChildData(h);v.domNode&&r?n.push((o={childDomNode:v.domNode,parentDomNode:t,getPosition:e.props.getPosition},a=o.childDomNode,l=(i=o.getPosition)(o.parentDomNode),c=i(a),s=c.top,u=c.left,p=c.right,f=c.bottom,d=c.width,b=c.height,{top:s-l.top,left:u-l.left,right:l.right-p,bottom:l.bottom-f,width:d,height:b})):n.push(null)}else n.push(null);else n.push(null)})),this.state.children.forEach((function(t,r){var o=E(t),a=n[r];o&&e.setChildData(o,{boundingBox:a})}))}},t.prototype.computeInitialStyles=function(e){if(e.appearing)return this.props.appearAnimation?this.props.appearAnimation.from:{};if(e.entering)return this.props.enterAnimation?g({position:"",top:"",left:"",right:"",bottom:""},this.props.enterAnimation.from):{};if(e.leaving)return this.props.leaveAnimation?this.props.leaveAnimation.from:{};var t=this.getChildData(E(e)),n=t.domNode,r=t.boundingBox,o=this.parentData.boundingBox;if(!n)return{};var a=C({childDomNode:n,childBoundingBox:r,parentBoundingBox:o,getPosition:this.props.getPosition});return{transform:"translate("+a[0]+"px, "+a[1]+"px)"}},t.prototype.isAnimationDisabled=function(e){return P||e.disableAllAnimations||0===e.duration&&0===e.delay&&0===e.staggerDurationBy&&0===e.staggerDelayBy},t.prototype.findChildByKey=function(e){return b((function(t){return E(t)===e}),this.state.children)},t.prototype.hasChildData=function(e){return Object.prototype.hasOwnProperty.call(this.childrenData,e)},t.prototype.getChildData=function(e){return this.hasChildData(e)?this.childrenData[e]:{}},t.prototype.setChildData=function(e,t){this.childrenData[e]=g({},this.getChildData(e),t)},t.prototype.removeChildData=function(e){delete this.childrenData[e],this.setState((function(t){return g({},t,{children:t.children.filter((function(t){return t.element.key!==e}))})}))},t.prototype.createHeightPlaceholder=function(){var e=this,t=this.props.typeName,n="ul"===t||"ol"===t?"li":"div";return(0,r.createElement)(n,{key:"height-placeholder",ref:function(t){e.heightPlaceholderData.domNode=t},style:{visibility:"hidden",height:0}})},t.prototype.childrenWithRefs=function(){var e=this;return this.state.children.map((function(t){return(0,r.cloneElement)(t.element,{ref:function(n){if(n){var r=function(e){if("undefined"==typeof HTMLElement)return null;if(e instanceof HTMLElement)return e;var t=(0,o.findDOMNode)(e);return t&&t.nodeType===Node.TEXT_NODE?null:t}(n);e.setChildData(E(t),{domNode:r})}}})}))},t.prototype.render=function(){var e=this,t=this.props,n=t.typeName,o=t.delegated,a=t.leaveAnimation,i=t.maintainContainerHeight,l=this.childrenWithRefs();if(a&&i&&l.push(this.createHeightPlaceholder()),!n)return l;var c=g({},o,{children:l,ref:function(t){e.parentData.domNode=t}});return(0,r.createElement)(n,c)},t}(r.Component))},1746:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>pe,withResizeDetector:()=>ue});var r=n(7294),o=n(1581),a=n.n(o),i=function(){if("undefined"!=typeof Map)return Map;function e(e,t){var n=-1;return e.some((function(e,r){return e[0]===t&&(n=r,!0)})),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(t){var n=e(this.__entries__,t),r=this.__entries__[n];return r&&r[1]},t.prototype.set=function(t,n){var r=e(this.__entries__,t);~r?this.__entries__[r][1]=n:this.__entries__.push([t,n])},t.prototype.delete=function(t){var n=this.__entries__,r=e(n,t);~r&&n.splice(r,1)},t.prototype.has=function(t){return!!~e(this.__entries__,t)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(e,t){void 0===t&&(t=null);for(var n=0,r=this.__entries__;n<r.length;n++){var o=r[n];e.call(t,o[1],o[0])}},t}()}(),l="undefined"!=typeof window&&"undefined"!=typeof document&&window.document===document,c=void 0!==n.g&&n.g.Math===Math?n.g:"undefined"!=typeof self&&self.Math===Math?self:"undefined"!=typeof window&&window.Math===Math?window:Function("return this")(),s="function"==typeof requestAnimationFrame?requestAnimationFrame.bind(c):function(e){return setTimeout((function(){return e(Date.now())}),1e3/60)},u=["top","right","bottom","left","width","height","size","weight"],p="undefined"!=typeof MutationObserver,f=function(){function e(){this.connected_=!1,this.mutationEventsAdded_=!1,this.mutationsObserver_=null,this.observers_=[],this.onTransitionEnd_=this.onTransitionEnd_.bind(this),this.refresh=function(e,t){var n=!1,r=!1,o=0;function a(){n&&(n=!1,e()),r&&l()}function i(){s(a)}function l(){var e=Date.now();if(n){if(e-o<2)return;r=!0}else n=!0,r=!1,setTimeout(i,20);o=e}return l}(this.refresh.bind(this))}return e.prototype.addObserver=function(e){~this.observers_.indexOf(e)||this.observers_.push(e),this.connected_||this.connect_()},e.prototype.removeObserver=function(e){var t=this.observers_,n=t.indexOf(e);~n&&t.splice(n,1),!t.length&&this.connected_&&this.disconnect_()},e.prototype.refresh=function(){this.updateObservers_()&&this.refresh()},e.prototype.updateObservers_=function(){var e=this.observers_.filter((function(e){return e.gatherActive(),e.hasActive()}));return e.forEach((function(e){return e.broadcastActive()})),e.length>0},e.prototype.connect_=function(){l&&!this.connected_&&(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),p?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){l&&this.connected_&&(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(e){var t=e.propertyName,n=void 0===t?"":t;u.some((function(e){return!!~n.indexOf(e)}))&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),d=function(e,t){for(var n=0,r=Object.keys(t);n<r.length;n++){var o=r[n];Object.defineProperty(e,o,{value:t[o],enumerable:!1,writable:!1,configurable:!0})}return e},b=function(e){return e&&e.ownerDocument&&e.ownerDocument.defaultView||c},h=O(0,0,0,0);function v(e){return parseFloat(e)||0}function y(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];return t.reduce((function(t,n){return t+v(e["border-"+n+"-width"])}),0)}var m="undefined"!=typeof SVGGraphicsElement?function(e){return e instanceof b(e).SVGGraphicsElement}:function(e){return e instanceof b(e).SVGElement&&"function"==typeof e.getBBox};function g(e){return l?m(e)?function(e){var t=e.getBBox();return O(0,0,t.width,t.height)}(e):function(e){var t=e.clientWidth,n=e.clientHeight;if(!t&&!n)return h;var r=b(e).getComputedStyle(e),o=function(e){for(var t={},n=0,r=["top","right","bottom","left"];n<r.length;n++){var o=r[n],a=e["padding-"+o];t[o]=v(a)}return t}(r),a=o.left+o.right,i=o.top+o.bottom,l=v(r.width),c=v(r.height);if("border-box"===r.boxSizing&&(Math.round(l+a)!==t&&(l-=y(r,"left","right")+a),Math.round(c+i)!==n&&(c-=y(r,"top","bottom")+i)),!function(e){return e===b(e).document.documentElement}(e)){var s=Math.round(l+a)-t,u=Math.round(c+i)-n;1!==Math.abs(s)&&(l-=s),1!==Math.abs(u)&&(c-=u)}return O(o.left,o.top,l,c)}(e):h}function O(e,t,n,r){return{x:e,y:t,width:n,height:r}}var x=function(){function e(e){this.broadcastWidth=0,this.broadcastHeight=0,this.contentRect_=O(0,0,0,0),this.target=e}return e.prototype.isActive=function(){var e=g(this.target);return this.contentRect_=e,e.width!==this.broadcastWidth||e.height!==this.broadcastHeight},e.prototype.broadcastRect=function(){var e=this.contentRect_;return this.broadcastWidth=e.width,this.broadcastHeight=e.height,e},e}(),j=function(e,t){var n,r,o,a,i,l,c,s=(r=(n=t).x,o=n.y,a=n.width,i=n.height,l="undefined"!=typeof DOMRectReadOnly?DOMRectReadOnly:Object,c=Object.create(l.prototype),d(c,{x:r,y:o,width:a,height:i,top:o,right:r+a,bottom:i+o,left:r}),c);d(this,{target:e,contentRect:s})},w=function(){function e(e,t,n){if(this.activeObservations_=[],this.observations_=new i,"function"!=typeof e)throw new TypeError("The callback provided as parameter 1 is not a function.");this.callback_=e,this.controller_=t,this.callbackCtx_=n}return e.prototype.observe=function(e){if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");if("undefined"!=typeof Element&&Element instanceof Object){if(!(e instanceof b(e).Element))throw new TypeError('parameter 1 is not of type "Element".');var t=this.observations_;t.has(e)||(t.set(e,new x(e)),this.controller_.addObserver(this),this.controller_.refresh())}},e.prototype.unobserve=function(e){if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");if("undefined"!=typeof Element&&Element instanceof Object){if(!(e instanceof b(e).Element))throw new TypeError('parameter 1 is not of type "Element".');var t=this.observations_;t.has(e)&&(t.delete(e),t.size||this.controller_.removeObserver(this))}},e.prototype.disconnect=function(){this.clearActive(),this.observations_.clear(),this.controller_.removeObserver(this)},e.prototype.gatherActive=function(){var e=this;this.clearActive(),this.observations_.forEach((function(t){t.isActive()&&e.activeObservations_.push(t)}))},e.prototype.broadcastActive=function(){if(this.hasActive()){var e=this.callbackCtx_,t=this.activeObservations_.map((function(e){return new j(e.target,e.broadcastRect())}));this.callback_.call(e,t,e),this.clearActive()}},e.prototype.clearActive=function(){this.activeObservations_.splice(0)},e.prototype.hasActive=function(){return this.activeObservations_.length>0},e}(),C="undefined"!=typeof WeakMap?new WeakMap:new i,S=function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var n=f.getInstance(),r=new w(t,n,this);C.set(this,r)};["observe","unobserve","disconnect"].forEach((function(e){S.prototype[e]=function(){var t;return(t=C.get(this))[e].apply(t,arguments)}}));const k=void 0!==c.ResizeObserver?c.ResizeObserver:S,P=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)},E="object"==typeof global&&global&&global.Object===Object&&global;var _="object"==typeof self&&self&&self.Object===Object&&self;const T=E||_||Function("return this")(),D=function(){return T.Date.now()};var I=/\s/;var R=/^\s+/;const L=function(e){return e?e.slice(0,function(e){for(var t=e.length;t--&&I.test(e.charAt(t)););return t}(e)+1).replace(R,""):e},A=T.Symbol;var M=Object.prototype,B=M.hasOwnProperty,N=M.toString,z=A?A.toStringTag:void 0;var F=Object.prototype.toString;var $=A?A.toStringTag:void 0;const H=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":$&&$ in Object(e)?function(e){var t=B.call(e,z),n=e[z];try{e[z]=void 0;var r=!0}catch(e){}var o=N.call(e);return r&&(t?e[z]=n:delete e[z]),o}(e):function(e){return F.call(e)}(e)};var V=/^[-+]0x[0-9a-f]+$/i,q=/^0b[01]+$/i,W=/^0o[0-7]+$/i,K=parseInt;const U=function(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return null!=e&&"object"==typeof e}(e)&&"[object Symbol]"==H(e)}(e))return NaN;if(P(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=P(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=L(e);var n=q.test(e);return n||W.test(e)?K(e.slice(2),n?2:8):V.test(e)?NaN:+e};var Z=Math.max,G=Math.min;const X=function(e,t,n){var r,o,a,i,l,c,s=0,u=!1,p=!1,f=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function d(t){var n=r,a=o;return r=o=void 0,s=t,i=e.apply(a,n)}function b(e){return s=e,l=setTimeout(v,t),u?d(e):i}function h(e){var n=e-c;return void 0===c||n>=t||n<0||p&&e-s>=a}function v(){var e=D();if(h(e))return y(e);l=setTimeout(v,function(e){var n=t-(e-c);return p?G(n,a-(e-s)):n}(e))}function y(e){return l=void 0,f&&r?d(e):(r=o=void 0,i)}function m(){var e=D(),n=h(e);if(r=arguments,o=this,c=e,n){if(void 0===l)return b(c);if(p)return clearTimeout(l),l=setTimeout(v,t),d(c)}return void 0===l&&(l=setTimeout(v,t)),i}return t=U(t)||0,P(n)&&(u=!!n.leading,a=(p="maxWait"in n)?Z(U(n.maxWait)||0,t):a,f="trailing"in n?!!n.trailing:f),m.cancel=function(){void 0!==l&&clearTimeout(l),s=0,r=c=o=l=void 0},m.flush=function(){return void 0===l?i:y(D())},m};function Y(e){return Y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Y(e)}function Q(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function J(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function ee(e,t,n){return t&&J(e.prototype,t),n&&J(e,n),e}function te(e,t){return!t||"object"!==Y(t)&&"function"!=typeof t?ae(e):t}function ne(e){return ne=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},ne(e)}function re(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&oe(e,t)}function oe(e,t){return oe=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},oe(e,t)}function ae(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function ie(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var le={debounce:X,throttle:function(e,t,n){var r=!0,o=!0;if("function"!=typeof e)throw new TypeError("Expected a function");return P(n)&&(r="leading"in n?!!n.leading:r,o="trailing"in n?!!n.trailing:o),X(e,t,{leading:r,maxWait:t,trailing:o})}},ce={position:"absolute",width:0,height:0,visibility:"hidden",display:"none"},se=function(e){function t(e){var n;Q(this,t),ie(ae(ae(n=te(this,ne(t).call(this,e)))),"getElement",(function(){var e=n.props.resizableElementId,t=e&&document.getElementById(e),r=n.el&&n.el.parentElement;return t||r})),ie(ae(ae(n)),"createResizeHandler",(function(e){var t=n.props,r=t.handleWidth,o=t.handleHeight,a=t.onResize;e.forEach((function(e){var t=e.contentRect,i=t.width,l=t.height,c=r&&n.state.width!==i,s=o&&n.state.height!==l;n.skipOnMount||!c&&!s||"undefined"==typeof window||(n.animationFrameID=window.requestAnimationFrame((function(){a(i,l),n.setState({width:i,height:l})}))),n.skipOnMount=!1}))})),ie(ae(ae(n)),"handleRenderProp",(function(){var e=n.state,t=e.width,o=e.height,a=n.props.render;if(a&&"function"==typeof a)return(0,r.cloneElement)(a({width:t,height:o}),{key:"render"})})),ie(ae(ae(n)),"renderChildren",(function(){var e,t=n.state,o=t.width,a=t.height;return(e=n.props.children,e?Array.isArray(e)?e:[e]:[]).filter((function(e){return!!e})).map((function(e,t){return function(e){if(!P(e))return!1;var t=H(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t}(e)?(0,r.cloneElement)(e(o,a),{key:t}):(0,r.isValidElement)(e)?(0,r.cloneElement)(e,{width:o,height:a,key:t}):e}))}));var o=e.skipOnMount,a=e.refreshMode,i=e.refreshRate,l=e.refreshOptions;return n.state={width:void 0,height:void 0},n.skipOnMount=o,n.animationFrameID=null,n.resizeHandler=le[a]?le[a](n.createResizeHandler,i,l):n.createResizeHandler,n.ro=new k(n.resizeHandler),n}return re(t,e),ee(t,[{key:"componentDidMount",value:function(){var e=this.getElement();e&&this.ro.observe(e)}},{key:"componentWillUnmount",value:function(){var e=this.getElement();e&&this.ro.unobserve(e),"undefined"!=typeof window&&this.animationFrameID&&window.cancelAnimationFrame(this.animationFrameID),this.resizeHandler&&this.resizeHandler.cancel&&this.resizeHandler.cancel()}},{key:"render",value:function(){var e,t=this,n=this.props.nodeType;return[(0,r.createElement)(n,{key:"resize-detector",style:ce,ref:function(e){t.el=e}}),this.handleRenderProp()].concat(function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e=this.renderChildren())||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}())}}]),t}(r.PureComponent);se.propTypes={handleWidth:a().bool,handleHeight:a().bool,skipOnMount:a().bool,refreshRate:a().number,refreshMode:a().string,refreshOptions:a().shape({leading:a().bool,trailing:a().bool}),resizableElementId:a().string,onResize:a().func,render:a().func,children:a().any,nodeType:a().node},se.defaultProps={handleWidth:!1,handleHeight:!1,skipOnMount:!1,refreshRate:1e3,refreshMode:void 0,refreshOptions:void 0,resizableElementId:"",onResize:function(e){return e},render:void 0,children:null,nodeType:"div"};var ue=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{handleWidth:!0,handleHeight:!0};return function(n){function o(){return Q(this,o),te(this,ne(o).apply(this,arguments))}return re(o,n),ee(o,[{key:"render",value:function(){return r.createElement(se,t,r.createElement(e,this.props))}}]),o}(r.Component)};const pe=se},8721:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});const r={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};let o;const a=new Uint8Array(16);function i(){if(!o&&(o="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!o))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return o(a)}const l=[];for(let e=0;e<256;++e)l.push((e+256).toString(16).slice(1));const c=function(e,t,n){if(r.randomUUID&&!t&&!e)return r.randomUUID();const o=(e=e||{}).random||(e.rng||i)();if(o[6]=15&o[6]|64,o[8]=63&o[8]|128,t){n=n||0;for(let e=0;e<16;++e)t[n+e]=o[e];return t}return function(e,t=0){return(l[e[t+0]]+l[e[t+1]]+l[e[t+2]]+l[e[t+3]]+"-"+l[e[t+4]]+l[e[t+5]]+"-"+l[e[t+6]]+l[e[t+7]]+"-"+l[e[t+8]]+l[e[t+9]]+"-"+l[e[t+10]]+l[e[t+11]]+l[e[t+12]]+l[e[t+13]]+l[e[t+14]]+l[e[t+15]]).toLowerCase()}(o)}},7061:(e,t,n)=>{var r=n(8698).default;function o(){"use strict";e.exports=o=function(){return t},e.exports.__esModule=!0,e.exports.default=e.exports;var t={},n=Object.prototype,a=n.hasOwnProperty,i=Object.defineProperty||function(e,t,n){e[t]=n.value},l="function"==typeof Symbol?Symbol:{},c=l.iterator||"@@iterator",s=l.asyncIterator||"@@asyncIterator",u=l.toStringTag||"@@toStringTag";function p(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{p({},"")}catch(e){p=function(e,t,n){return e[t]=n}}function f(e,t,n,r){var o=t&&t.prototype instanceof h?t:h,a=Object.create(o.prototype),l=new E(r||[]);return i(a,"_invoke",{value:C(e,n,l)}),a}function d(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}t.wrap=f;var b={};function h(){}function v(){}function y(){}var m={};p(m,c,(function(){return this}));var g=Object.getPrototypeOf,O=g&&g(g(_([])));O&&O!==n&&a.call(O,c)&&(m=O);var x=y.prototype=h.prototype=Object.create(m);function j(e){["next","throw","return"].forEach((function(t){p(e,t,(function(e){return this._invoke(t,e)}))}))}function w(e,t){function n(o,i,l,c){var s=d(e[o],e,i);if("throw"!==s.type){var u=s.arg,p=u.value;return p&&"object"==r(p)&&a.call(p,"__await")?t.resolve(p.__await).then((function(e){n("next",e,l,c)}),(function(e){n("throw",e,l,c)})):t.resolve(p).then((function(e){u.value=e,l(u)}),(function(e){return n("throw",e,l,c)}))}c(s.arg)}var o;i(this,"_invoke",{value:function(e,r){function a(){return new t((function(t,o){n(e,r,t,o)}))}return o=o?o.then(a,a):a()}})}function C(e,t,n){var r="suspendedStart";return function(o,a){if("executing"===r)throw new Error("Generator is already running");if("completed"===r){if("throw"===o)throw a;return{value:void 0,done:!0}}for(n.method=o,n.arg=a;;){var i=n.delegate;if(i){var l=S(i,n);if(l){if(l===b)continue;return l}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if("suspendedStart"===r)throw r="completed",n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r="executing";var c=d(e,t,n);if("normal"===c.type){if(r=n.done?"completed":"suspendedYield",c.arg===b)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(r="completed",n.method="throw",n.arg=c.arg)}}}function S(e,t){var n=e.iterator[t.method];if(void 0===n){if(t.delegate=null,"throw"===t.method){if(e.iterator.return&&(t.method="return",t.arg=void 0,S(e,t),"throw"===t.method))return b;t.method="throw",t.arg=new TypeError("The iterator does not provide a 'throw' method")}return b}var r=d(n,e.iterator,t.arg);if("throw"===r.type)return t.method="throw",t.arg=r.arg,t.delegate=null,b;var o=r.arg;return o?o.done?(t[e.resultName]=o.value,t.next=e.nextLoc,"return"!==t.method&&(t.method="next",t.arg=void 0),t.delegate=null,b):o:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,b)}function k(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function P(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function E(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(k,this),this.reset(!0)}function _(e){if(e){var t=e[c];if(t)return t.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var n=-1,r=function t(){for(;++n<e.length;)if(a.call(e,n))return t.value=e[n],t.done=!1,t;return t.value=void 0,t.done=!0,t};return r.next=r}}return{next:T}}function T(){return{value:void 0,done:!0}}return v.prototype=y,i(x,"constructor",{value:y,configurable:!0}),i(y,"constructor",{value:v,configurable:!0}),v.displayName=p(y,u,"GeneratorFunction"),t.isGeneratorFunction=function(e){var t="function"==typeof e&&e.constructor;return!!t&&(t===v||"GeneratorFunction"===(t.displayName||t.name))},t.mark=function(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,y):(e.__proto__=y,p(e,u,"GeneratorFunction")),e.prototype=Object.create(x),e},t.awrap=function(e){return{__await:e}},j(w.prototype),p(w.prototype,s,(function(){return this})),t.AsyncIterator=w,t.async=function(e,n,r,o,a){void 0===a&&(a=Promise);var i=new w(f(e,n,r,o),a);return t.isGeneratorFunction(n)?i:i.next().then((function(e){return e.done?e.value:i.next()}))},j(x),p(x,u,"Generator"),p(x,c,(function(){return this})),p(x,"toString",(function(){return"[object Generator]"})),t.keys=function(e){var t=Object(e),n=[];for(var r in t)n.push(r);return n.reverse(),function e(){for(;n.length;){var r=n.pop();if(r in t)return e.value=r,e.done=!1,e}return e.done=!0,e}},t.values=_,E.prototype={constructor:E,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(P),!e)for(var t in this)"t"===t.charAt(0)&&a.call(this,t)&&!isNaN(+t.slice(1))&&(this[t]=void 0)},stop:function(){this.done=!0;var e=this.tryEntries[0].completion;if("throw"===e.type)throw e.arg;return this.rval},dispatchException:function(e){if(this.done)throw e;var t=this;function n(n,r){return i.type="throw",i.arg=e,t.next=n,r&&(t.method="next",t.arg=void 0),!!r}for(var r=this.tryEntries.length-1;r>=0;--r){var o=this.tryEntries[r],i=o.completion;if("root"===o.tryLoc)return n("end");if(o.tryLoc<=this.prev){var l=a.call(o,"catchLoc"),c=a.call(o,"finallyLoc");if(l&&c){if(this.prev<o.catchLoc)return n(o.catchLoc,!0);if(this.prev<o.finallyLoc)return n(o.finallyLoc)}else if(l){if(this.prev<o.catchLoc)return n(o.catchLoc,!0)}else{if(!c)throw new Error("try statement without catch or finally");if(this.prev<o.finallyLoc)return n(o.finallyLoc)}}}},abrupt:function(e,t){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&a.call(r,"finallyLoc")&&this.prev<r.finallyLoc){var o=r;break}}o&&("break"===e||"continue"===e)&&o.tryLoc<=t&&t<=o.finallyLoc&&(o=null);var i=o?o.completion:{};return i.type=e,i.arg=t,o?(this.method="next",this.next=o.finallyLoc,b):this.complete(i)},complete:function(e,t){if("throw"===e.type)throw e.arg;return"break"===e.type||"continue"===e.type?this.next=e.arg:"return"===e.type?(this.rval=this.arg=e.arg,this.method="return",this.next="end"):"normal"===e.type&&t&&(this.next=t),b},finish:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),P(n),b}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var o=r.arg;P(n)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,n){return this.delegate={iterator:_(e),resultName:t,nextLoc:n},"next"===this.method&&(this.arg=void 0),b}},t}e.exports=o,e.exports.__esModule=!0,e.exports.default=e.exports},8698:e=>{function t(n){return e.exports=t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},4687:(e,t,n)=>{var r=n(7061)();e.exports=r;try{regeneratorRuntime=r}catch(e){"object"==typeof globalThis?globalThis.regeneratorRuntime=r:Function("r","regeneratorRuntime = r")(r)}},5861:(e,t,n)=>{"use strict";function r(e,t,n,r,o,a,i){try{var l=e[a](i),c=l.value}catch(e){return void n(e)}l.done?t(c):Promise.resolve(c).then(r,o)}function o(e){return function(){var t=this,n=arguments;return new Promise((function(o,a){var i=e.apply(t,n);function l(e){r(i,o,a,l,c,"next",e)}function c(e){r(i,o,a,l,c,"throw",e)}l(void 0)}))}}n.d(t,{Z:()=>o})},4942:(e,t,n)=>{"use strict";function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}n.d(t,{Z:()=>r})},7462:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(this,arguments)}n.d(t,{Z:()=>r})},4925:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}n.d(t,{Z:()=>r})},2982:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(907),o=n(181);function a(e){return function(e){if(Array.isArray(e))return(0,r.Z)(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||(0,o.Z)(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}}}]);
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/js/build/354.js b/deployment-apps/metricator-for-nmon/appserver/static/js/build/354.js
    new file mode 100644
    index 0000000..f4312ca
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/js/build/354.js
    @@ -0,0 +1 @@
    +(self.webpackChunk_splunk_ucc_ui_lib=self.webpackChunk_splunk_ucc_ui_lib||[]).push([[354],{7354:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=147)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},10:function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},147:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return H})),n.d(t,"Panel",(function(){return k}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(4),u=n(21),c=n(34),f=n(3),s=n.n(f),p=n(8),d=n.n(p),y=n(0),b=s()(Object(u.animated)(d.a)).withConfig({displayName:"SlidingPanelsStyles__StyledBox",componentId:"su6isq-0"})(["overflow:hidden;position:relative;"]),v=s()(u.animated.div).withConfig({displayName:"SlidingPanelsStyles__Styled",componentId:"su6isq-1"})(["",";",";"],y.mixins.reset("block"),y.mixins.clearfix()),m=n(10);function h(e){return h="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},h(e)}function O(){return O=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},O.apply(this,arguments)}function g(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function P(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function j(e,t){return j=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},j(e,t)}function w(e,t){return!t||"object"!==h(t)&&"function"!=typeof t?S(e):t}function S(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function _(e){return _=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},_(e)}function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var x={elementRef:a.a.oneOfType([a.a.func,a.a.object]),panelId:a.a.any.isRequired,onMount:a.a.func,onUnmount:a.a.func},E=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&j(e,t)}(u,e);var t,n,r,i,a=(r=u,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=_(r);if(i){var n=_(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return w(this,e)});function u(){var e;g(this,u);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return I(S(e=a.call.apply(a,[this].concat(n))),"el",null),I(S(e),"handleMount",(function(t){e.el=t,Object(m.a)(e.props.elementRef,t)})),e}return t=u,(n=[{key:"componentDidMount",value:function(){var e,t;null===(e=(t=this.props).onMount)||void 0===e||e.call(t,this)}},{key:"componentWillUnmount",value:function(){var e,t;null===(e=(t=this.props).onUnmount)||void 0===e||e.call(t,this)}},{key:"getHeight",value:function(){var e;return null===(e=this.el)||void 0===e?void 0:e.clientHeight}},{key:"getWidth",value:function(){var e;return null===(e=this.el)||void 0===e?void 0:e.clientWidth}},{key:"render",value:function(){var e=this.props.panelId;return o.a.createElement(v,O({"data-test":"panel","data-test-panel-id":e},Object(l.omit)(this.props,Object(l.keys)(u.propTypes)),{ref:this.handleMount}))}}])&&P(t.prototype,n),u}(r.Component);I(E,"propTypes",x),I(E,"defaultProps",{});var k=E;function R(e){return R="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},R(e)}function C(){return C=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},C.apply(this,arguments)}function A(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function M(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?A(Object(n),!0).forEach((function(t){W(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):A(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function T(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function D(e,t){return D=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},D(e,t)}function U(e,t){return!t||"object"!==R(t)&&"function"!=typeof t?N(e):t}function N(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function L(e){return L=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},L(e)}function W(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var X={activePanelId:a.a.any.isRequired,children:a.a.node,elementRef:a.a.oneOfType([a.a.func,a.a.object]),innerClassName:a.a.string,innerStyle:a.a.object,onAnimationEnd:a.a.func,outerClassName:a.a.string,outerStyle:a.a.object,transition:a.a.oneOf(["forward","backward"])},q=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&D(e,t)}(s,e);var t,n,i,a,f=(i=s,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=L(i);if(a){var n=L(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return U(this,e)});function s(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,s),W(N(t=f.call(this,e)),"panelInstances",{}),W(N(t),"allowAnimationUpdates",!0),W(N(t),"willEnter",(function(){return{translateX:0}})),W(N(t),"willLeave",(function(e){return e?{translateX:-1,position:"absolute",left:0,top:0}:{translateX:-1}})),W(N(t),"handlePanelMount",(function(e){t.panelInstances[e.props.panelId]=e,e.props.panelId===t.props.activePanelId&&t.setState({activePanel:e,panelLoading:!1})})),W(N(t),"handlePanelUnmount",(function(e){delete t.panelInstances[e.props.panelId]})),W(N(t),"handleAnimationEnd",(function(){var e,n;t.allowAnimationUpdates&&t.setState({animating:!1}),null===(e=(n=t.props).onAnimationEnd)||void 0===e||e.call(n)})),W(N(t),"renderPanel",(function(e,n,i){var a,l=t.props,c=l.children,f=l.transition,s=r.Children.toArray(c).filter(r.isValidElement).find((function(e){return e.props.panelId===n})),p=null===(a=e.translateX)||void 0===a?void 0:a.to((function(e){return"translateX(".concat(e*i*("forward"===f?1:-1),"px)")}));return s?o.a.createElement(u.animated.div,{style:e},Object(r.cloneElement)(s,{style:M(M({},s.props.style),{},{transform:p}),onMount:t.handlePanelMount,onUnmount:t.handlePanelUnmount})):null})),W(N(t),"renderOuterContainer",(function(e){var n=t.props,i=n.activePanelId,a=n.children,f=n.elementRef,p=n.outerClassName,d=n.outerStyle,y=n.innerClassName,v=n.innerStyle,m=t.state.animating,h=M(M({},d),m?{width:e.width,height:e.height}:{});r.Children.toArray(a).filter(r.isValidElement).find((function(e){return e.props.panelId===i}));var O=m?{translateX:1}:{},g=Object(l.filter)(Object(l.values)(t.panelInstances),(function(e){return!!e})).map((function(e){var n,r=t.panelInstances[e.props.panelId];return r&&null!==(n=r.getWidth())&&void 0!==n?n:0})).reduce((function(e,t){return Math.max(e,t)}),0);return o.a.createElement(b,C({className:p,"data-test-active-panel-id":i,"data-test":"sliding-panels",elementRef:f,style:h},Object(l.omit)(t.props,Object(l.keys)(s.propTypes))),o.a.createElement(c.Transition,{from:O,enter:t.willEnter(),leave:t.willLeave(m),items:i},(function(e,n){return o.a.createElement(u.animated.div,{style:v,className:y},t.renderPanel(e,n,g))})))})),t.state={animating:!1,panelLoading:!1,prevActivePanelId:t.props.activePanelId,slidingId:0},t}return t=s,(n=[{key:"componentWillUnmount",value:function(){this.allowAnimationUpdates=!1}},{key:"render",value:function(){var e=this.state,t=e.activePanel,n=e.panelLoading,r={width:t?t.getWidth():0,height:t?t.getHeight():0};return o.a.createElement(c.Spring,{to:r,onRest:this.handleAnimationEnd,immediate:n,config:{precision:1}},this.renderOuterContainer)}}])&&T(t.prototype,n),s}(r.Component);W(q,"propTypes",X),W(q,"defaultProps",{transition:"forward"}),W(q,"Panel",k),W(q,"getDerivedStateFromProps",(function(e,t){return e.activePanelId!==t.prevActivePanelId?{animating:!0,panelLoading:!0,prevActivePanelId:e.activePanelId,slidingId:t.slidingId+1}:null}));var H=q},2:function(e,t){e.exports=n(7294)},21:function(e,t){e.exports=n(9920)},3:function(e,t){e.exports=n(2788)},34:function(e,t){e.exports=n(2640)},4:function(e,t){e.exports=n(5220)},8:function(e,t){e.exports=n(6493)}})}}]);
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/js/build/656.js b/deployment-apps/metricator-for-nmon/appserver/static/js/build/656.js
    new file mode 100644
    index 0000000..e870fd5
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/js/build/656.js
    @@ -0,0 +1 @@
    +"use strict";(self.webpackChunk_splunk_ucc_ui_lib=self.webpackChunk_splunk_ucc_ui_lib||[]).push([[656],{5464:(e,t,n)=>{n.d(t,{Z:()=>yt});var r,a=n(1002),o=n(5861),i=n(2982),l=n(5671),s=n(3144),c=n(7326),u=n(9340),d=n(2963),p=n(1120),f=n(4942),h=n(168),m=n(4687),v=n.n(m),g=n(7294),y=n(1581),b=n.n(y),E=n(7145),k=n.n(E),Z=n(8721),O=n(8539),C=n.n(O),w=n(8689),R=n.n(w),S=n(2788),x=n(2215),N=n.n(x),P=n(6206),j=n.n(P),_=S.default.span(r||(r=(0,h.Z)(["\n    color: ",";\n"])),(function(e){return e.color}));function M(e){return g.createElement("div",{"data-test":"msg-markdown"},(t=e.text,"link"===e.markdownType?t=g.createElement(j(),{to:e.link},e.text):"hybrid"===e.markdownType?(t=function(t,n){for(var r=[],a=0;a<t.length;a+=1){var o=[i=t[a],g.createElement(j(),{key:i,to:e.link},e.linkText)];r=r.concat(o)}var i;return r}(t.split(e.token))).pop():"text"===e.markdownType&&(t=g.createElement(_,{color:e.color},e.text)),t));var t}M.propTypes={text:b().string,link:b().string,color:b().string,markdownType:b().string,token:b().string,linkText:b().string};const T=g.memo(M);function D(e){var t=e.controlOptions,n=t.text,r=t.link;return g.createElement(j(),{to:r,openInNewContext:!0},n)}D.propTypes={controlOptions:b().object};const F=D;var V,q=n(6401),A=n.n(q);var z=(0,S.default)(A())(V||(V=(0,h.Z)(["\n    width: 320px !important;\n"]))),L=function(e){(0,u.Z)(a,e);var t,n,r=(t=a,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=(0,p.Z)(t);if(n){var a=(0,p.Z)(this).constructor;e=Reflect.construct(r,arguments,a)}else e=r.apply(this,arguments);return(0,d.Z)(this,e)});function a(){var e;(0,l.Z)(this,a);for(var t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];return e=r.call.apply(r,[this].concat(n)),(0,f.Z)((0,c.Z)(e),"handleChange",(function(t,n){var r=n.value;e.props.handleChange(e.props.field,r)})),e}return(0,s.Z)(a,[{key:"render",value:function(){var e,t;return g.createElement(z,{inline:!0,error:this.props.error,placeholder:null===(e=this.props)||void 0===e||null===(t=e.controlOptions)||void 0===t?void 0:t.placeholder,className:this.props.field,disabled:this.props.disabled,value:null===this.props.value||void 0===this.props.value?"":this.props.value.toString(),onChange:this.handleChange,type:this.props.encrypted?"password":"text"})}}]),a}(g.Component);L.propTypes={value:b().oneOfType([b().string,b().number]),handleChange:b().func.isRequired,field:b().string,error:b().bool,controlOptions:b().object,encrypted:b().bool,disabled:b().bool};const I=L;var B,K=n(4415),H=n.n(K),U=(0,S.default)(H())(B||(B=(0,h.Z)(["\n    width: 320px !important;\n"])));function $(e){var t,n,r,a,o,i;return g.createElement(U,{inline:!0,canClear:!0,error:e.error,placeholder:null==e||null===(t=e.controlOptions)||void 0===t?void 0:t.placeholder,className:e.field,disabled:e.disabled,value:(null===(n=e.value)||void 0===n?void 0:n.toString())||"",onChange:function(t,n){var r=n.value;e.handleChange(e.field,r)},rowsMax:null!=e&&null!==(r=e.controlOptions)&&void 0!==r&&r.rowsMax?null==e||null===(a=e.controlOptions)||void 0===a?void 0:a.rowsMax:12,rowsMin:null!=e&&null!==(o=e.controlOptions)&&void 0!==o&&o.rowsMin?null==e||null===(i=e.controlOptions)||void 0===i?void 0:i.rowsMin:8})}$.propTypes={value:b().oneOfType([b().string,b().number]),handleChange:b().func.isRequired,field:b().string,error:b().bool,controlOptions:b().object,disabled:b().bool};const W=$;var G,X,Y=n(885),J=n(4925),Q=n(6521),ee=n.n(Q),te=n(6300),ne=n.n(te),re=n(6416),ae=n.n(re),oe=n(4789),ie=n.n(oe),le=n(6219),se=n(1721),ce=n(2297),ue=n(4255);function de(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function pe(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?de(Object(n),!0).forEach((function(t){(0,f.Z)(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):de(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var fe=(0,S.default)(ee())(G||(G=(0,h.Z)(["\n    width: 320px !important;\n"]))),he=S.default.div(X||(X=(0,h.Z)(["\n    div:first-child {\n        width: 320px !important;\n    }\n"])));function me(e){var t=e.field,n=e.disabled,r=void 0!==n&&n,a=e.error,o=void 0!==a&&a,i=e.controlOptions,l=e.dependencyValues,s=(0,J.Z)(e,["field","disabled","error","controlOptions","dependencyValues"]),c=i.endpointUrl,u=i.denyList,d=i.allowList,p=i.placeholder,f=void 0===p?(0,le._)("Select a value"):p,h=i.dependencies,m=i.createSearchChoice,v=i.referenceName,y=i.disableSearch,b=i.labelField,E=i.autoCompleteFields,k=i.hideClearBtn;function Z(e,n){s.handleChange(t,n.value)}var O=m?ne().Option:ee().Option,C=m?ne().Heading:ee().Heading;function w(e){var t=[];return e.forEach((function(e){e.value&&e.label&&t.push(g.createElement(O,{label:e.label,value:e.value,key:e.value})),e.children&&e.label&&(t.push(g.createElement(C,{key:e.label},e.label)),e.children.forEach((function(e){t.push(g.createElement(O,{label:e.label,value:e.value,key:e.value}))})))})),t}var R=(0,g.useState)(!1),S=(0,Y.Z)(R,2),x=S[0],N=S[1],P=(0,g.useState)(null),j=(0,Y.Z)(P,2),_=j[0],M=j[1];(0,g.useEffect)((function(){if(c||v||!E){var e=!0,t=se.ZP.CancelToken.source(),n={cancelToken:t.token,handleError:!0,params:{count:-1}};return v?n.serviceName=v:c&&(n.endpointUrl=c),l&&(n.params=pe(pe({},n.params),l)),!h||l&&Object.keys(l).length?(N(!0),(0,ce.L)(n).then((function(t){e&&(M(w((0,ue.gB)(t.data.entry,b,d,u))),N(!1))})).catch((function(){e&&N(!1)}))):M(null),function(){t.cancel("Operation canceled."),e=!1}}M(w(E))}),[l]);var T=!!x||r,D=x?(0,le._)("Loading"):f,F=!T&&!k;return m?g.createElement(he,{className:"dropdownBox"},g.createElement(ne(),{value:null===e.value?"":e.value,name:t,error:o,placeholder:D,disabled:T,onChange:Z,inline:!0},_&&_.length>0&&_)):g.createElement(g.Fragment,null,g.createElement(fe,{className:"dropdownBox","data-test-loading":x,value:e.value,name:t,error:o,placeholder:D,disabled:T,onChange:Z,filter:!y,inline:!0},_&&_.length>0&&_),F?g.createElement(ae(),{"data-test":"clear",appearance:"secondary",icon:g.createElement(ie(),null),onClick:function(){return s.handleChange(t,"RESET_DROPDOWN_VALUE")}}):null)}me.propTypes={disabled:b().bool,value:b().string,error:b().bool,handleChange:b().func.isRequired,field:b().string,dependencyValues:b().object,controlOptions:b().shape({autoCompleteFields:b().array,endpointUrl:b().string,denyList:b().string,allowList:b().string,placeholder:b().string,dependencies:b().array,createSearchChoice:b().bool,referenceName:b().string,disableSearch:b().bool,labelField:b().string,hideClearBtn:b().bool})};const ve=me;var ge,ye=n(4355),be=n.n(ye),Ee=n(9609);function ke(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Ze(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?ke(Object(n),!0).forEach((function(t){(0,f.Z)(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ke(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var Oe=(0,S.default)(be())(ge||(ge=(0,h.Z)(["\n    width: 320px !important;\n"])));function Ce(e){var t=e.field,n=e.disabled,r=void 0!==n&&n,a=e.error,o=void 0!==a&&a,i=e.value,l=e.controlOptions,s=e.dependencyValues,c=(0,J.Z)(e,["field","disabled","error","value","controlOptions","dependencyValues"]),u=l.endpointUrl,d=l.denyList,p=l.allowList,f=l.items,h=l.dependencies,m=l.referenceName,v=l.placeholder,y=l.createSearchChoice,b=l.labelField,E=l.delimiter,k=void 0===E?",":E;function Z(e){return e.map((function(e){return g.createElement(be().Option,{label:e.label,value:e.value,key:e.value})}))}var O=(0,g.useState)(!1),C=(0,Y.Z)(O,2),w=C[0],R=C[1],S=(0,g.useState)(null),x=(0,Y.Z)(S,2),N=x[0],P=x[1];(0,g.useEffect)((function(){if(u||!f){var e=!0,t=se.ZP.CancelToken.source(),n={cancelToken:t.token,handleError:!0,params:{count:-1}};return m?n.serviceName=m:u&&(n.endpointUrl=u),s&&(n.params=Ze(Ze({},n.params),s)),h&&!s||(R(!0),(0,ce.L)(n).then((function(t){e&&(P(Z((0,ue.gB)(t.data.entry,b,p,d))),R(!1))})).catch((function(){e&&R(!1)}))),function(){t.cancel("Operation canceled."),e=!1}}P(Z(f))}),[s]);var j=!!w||r,_=w?(0,Ee.P)(115):v,M=i?i.split(k):[];return g.createElement(Oe,{values:M,error:o,name:t,placeholder:_,disabled:j,allowNewValues:y,onChange:function(e,n){var r=n.values;c.handleChange(t,r.join(k))},inline:!0},N&&N.length>0&&N)}Ce.propTypes={disabled:b().bool,value:b().string,error:b().bool,handleChange:b().func.isRequired,field:b().string,dependencyValues:b().object,controlOptions:b().shape({delimiter:b().string,placeholder:b().string,createSearchChoice:b().bool,referenceName:b().string,dependencies:b().array,endpointUrl:b().string,denyList:b().string,allowList:b().string,labelField:b().string,items:b().arrayOf(b().shape({label:b().string.isRequired,value:b().string.isRequired}))})};const we=Ce;var Re=n(7885),Se=n.n(Re);var xe=function(e){(0,u.Z)(a,e);var t,n,r=(t=a,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=(0,p.Z)(t);if(n){var a=(0,p.Z)(this).constructor;e=Reflect.construct(r,arguments,a)}else e=r.apply(this,arguments);return(0,d.Z)(this,e)});function a(){var e;(0,l.Z)(this,a);for(var t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];return e=r.call.apply(r,[this].concat(n)),(0,f.Z)((0,c.Z)(e),"handleChange",(function(){e.props.value&&!(0,ue.mA)(e.props.value)?e.props.handleChange(e.props.field,0):e.props.handleChange(e.props.field,1)})),e}return(0,s.Z)(a,[{key:"render",value:function(){return g.createElement(Se(),{key:this.props.field,value:this.props.field,onClick:this.handleChange,disabled:this.props.disabled,selected:!(!this.props.value||(0,ue.mA)(this.props.value)),appearance:"checkbox"})}}]),a}(g.Component);xe.propTypes={value:b().oneOfType([b().bool,b().number,b().string]),handleChange:b().func.isRequired,field:b().string,disabled:b().bool};const Ne=xe;var Pe,je,_e=n(4228),Me=n.n(_e);var Te=(0,S.default)(Me())(Pe||(Pe=(0,h.Z)(["\n    width: 320px;\n"]))),De=(0,S.default)(Me().Option)(je||(je=(0,h.Z)(["\n    margin-left: 0px !important;\n"]))),Fe=function(e){(0,u.Z)(a,e);var t,n,r=(t=a,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=(0,p.Z)(t);if(n){var a=(0,p.Z)(this).constructor;e=Reflect.construct(r,arguments,a)}else e=r.apply(this,arguments);return(0,d.Z)(this,e)});function a(){var e;(0,l.Z)(this,a);for(var t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];return e=r.call.apply(r,[this].concat(n)),(0,f.Z)((0,c.Z)(e),"handleChange",(function(t,n){var r=n.value;e.props.handleChange(e.props.field,r)})),e}return(0,s.Z)(a,[{key:"render",value:function(){return g.createElement(Te,{inline:!0,onChange:this.handleChange,value:this.props.value,key:this.props.field},this.props.controlOptions.items.map((function(e){return g.createElement(De,{key:e.value,value:e.value,label:e.label})})))}}]),a}(g.Component);Fe.propTypes={value:b().string,handleChange:b().func.isRequired,field:b().string,controlOptions:b().object};const Ve=Fe;var qe=n(9895),Ae=n.n(qe);function ze(e){var t=e.controlOptions.defaultValue;return g.createElement(Ae(),null,t)}ze.propTypes={controlOptions:b().object};const Le=ze;var Ie=n(4266);var Be=function(e){(0,u.Z)(a,e);var t,n,r=(t=a,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=(0,p.Z)(t);if(n){var a=(0,p.Z)(this).constructor;e=Reflect.construct(r,arguments,a)}else e=r.apply(this,arguments);return(0,d.Z)(this,e)});function a(e){var t;return(0,l.Z)(this,a),t=r.call(this,e),(0,f.Z)((0,c.Z)(t),"setValue",(function(e){t.props.handleChange(t.props.field,e)})),t.state={loading:!0},t.shouldRender=!0,t}return(0,s.Z)(a,[{key:"componentDidMount",value:function(){var e=this,t=(0,ue.YK)(),n=t.meta.name;a.loadCustomControl(this.props.controlOptions.src,this.props.controlOptions.type,n).then((function(n){var r=new n(t,e.el,e.props.data,e.setValue,e.props.utilCustomFunctions);r.render(),"function"==typeof r.validation&&e.props.addCustomValidator(e.props.field,r.validation),e.setState({loading:!1})}))}},{key:"shouldComponentUpdate",value:function(e,t){return!(t.loading||!this.shouldRender||(this.shouldRender=!1,0))}},{key:"render",value:function(){var e=this;return g.createElement(g.Fragment,null,this.state.loading&&(0,le._)("Loading..."),g.createElement("span",{ref:function(t){e.el=t},style:{visibility:this.state.loading?"hidden":"visible"}}))}}]),a}(g.Component);(0,f.Z)(Be,"loadCustomControl",(function(e,t,n){return new Promise((function(r){"external"===t?import("".concat((0,Ie.a)(),"/custom/").concat(e,".js")).then((function(e){var t=e.default;r(t)})):require(["app/".concat(n,"/js/build/custom/").concat(e)],(function(e){r(e)}))}))})),Be.propTypes={data:b().object,field:b().string,handleChange:b().func,controlOptions:b().object,addCustomValidator:b().func,utilCustomFunctions:b().object};const Ke=Be;var He,Ue=n(7049),$e=n.n(Ue),We=(0,S.default)($e())(He||(He=(0,h.Z)(["\n    width: 320px !important;\n"])));function Ge(e){var t=e.field,n=e.disabled,r=e.error,a=e.controlOptions,o=e.handleChange,i=new FileReader,l=(0,g.useState)(""),s=(0,Y.Z)(l,2),c=s[0],u=s[1];return g.createElement(We,{key:t,onRequestAdd:function(e){if(e.length){var n=e[0];1===i.readyState&&i.abort(),i.readAsBinaryString(n),i.onload=function(){var e={fileName:n.name,fileSize:n.size,fileContent:i.result};u(n.name),o(t,e)}}},onRequestRemove:function(){1===i.readyState&&i.abort(),u(null),o(t,"")},supportsMessage:g.createElement(g.Fragment,null," ",null==a?void 0:a.fileSupportMessage," "),disabled:n,accept:".json"},c&&g.createElement($e().Item,{error:r,name:c}))}Ge.propTypes={field:b().string,error:b().bool,controlOptions:b().object,disabled:b().bool,handleChange:b().func};const Xe={text:I,textarea:W,singleSelect:ve,helpLink:F,multipleSelect:we,checkbox:Ne,radio:Ve,file:Ge,placeholder:Le,custom:Ke};var Ye,Je;var Qe=S.default.div(Ye||(Ye=(0,h.Z)(["\n    margin-left: 30px;\n"]))),et=(0,S.default)(N()).attrs((function(e){return{"data-name":e.dataName}}))(Je||(Je=(0,h.Z)(["\n    width: 100%;\n    max-width: 100%;\n\n    > * {\n        &:first-child {\n            width: 240px !important;\n        }\n        &:nth-child(3) {\n            margin-left: 270px !important;\n            width: 320px;\n        }\n    }\n"]))),tt=function(e){(0,u.Z)(a,e);var t,n,r=(t=a,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=(0,p.Z)(t);if(n){var a=(0,p.Z)(this).constructor;e=Reflect.construct(r,arguments,a)}else e=r.apply(this,arguments);return(0,d.Z)(this,e)});function a(e){var t;return(0,l.Z)(this,a),(t=r.call(this,e)).controlType=a.isString(e.entity.type)?Xe[e.entity.type]:null,t}return(0,s.Z)(a,[{key:"render",value:function(){var e,t=this.props.entity,n=t.field,r=t.type,a=t.label,o=t.tooltip,i=t.help,l=t.encrypted,s=void 0!==l&&l,c=this.props.utilityFuncts,u=c.handleChange,d=c.addCustomValidator,p=c.utilCustomFunctions,f=this.props.markdownMessage||{},h=f.text,m=f.link,v=f.color,y=f.markdownType,b=f.token,E=f.linkText;if("custom"===this.props.entity.type){var k={value:this.props.value,mode:this.props.mode,serviceName:this.props.serviceName};e=this.controlType?g.createElement(this.controlType,{data:k,field:n,handleChange:u,addCustomValidator:d,utilCustomFunctions:p,controlOptions:this.props.entity.options}):"No View Found for ".concat(r," type")}else e=this.controlType?g.createElement(this.controlType,{handleChange:u,value:this.props.value,field:n,controlOptions:this.props.entity.options,error:this.props.error,disabled:this.props.disabled,encrypted:s,dependencyValues:this.props.dependencyValues}):"No View Found for ".concat(r," type");var Z=g.createElement(g.Fragment,null,g.createElement(T,{text:h||"",link:m||"",color:v||"",markdownType:y||"",token:b||"",linkText:E||""}),i);return this.props.display&&g.createElement(et,{label:a,help:Z,tooltip:o,error:this.props.error,dataName:n},g.createElement(Qe,null,e))}}]),a}(g.PureComponent);(0,f.Z)(tt,"isString",(function(e){return!!("string"==typeof e||e instanceof String)})),tt.propTypes={mode:b().string,utilityFuncts:b().object,value:b().any,display:b().bool,error:b().bool,entity:b().object,disabled:b().bool,markdownMessage:b().object,serviceName:b().string,dependencyValues:b().object};const nt=tt;var rt={url:{regex:/^(?:(?:https?|ftp|opc\.tcp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?_?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))?)(?::\d{2,5})?(?:\/[^\s]*)?$/,inputValueType:(0,Ee.P)(111)},email:{regex:/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,inputValueType:(0,Ee.P)(112)},ipv4:{regex:/^(?:(?:[0-1]?\d{1,2}|2[0-4]\d|25[0-5])(?:\.|$)){4}$/,inputValueType:(0,Ee.P)(113)},date:{regex:/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,inputValueType:(0,Ee.P)(114)}},at=n(4317);const ot="512000",it=function(){function e(t){(0,l.Z)(this,e),(0,f.Z)(this,"checkIsFieldHasInput",(function(e){return void 0!==e&&""!==e&&null!==e})),this.entities=t,this.isName=t.find((function(e){return"name"===e.field}))}return(0,s.Z)(e,[{key:"RequiredValidator",value:function(e,t,n){return!this.checkIsFieldHasInput(n)&&{errorField:e,errorMsg:(0,Ee.P)(6,[t])}}},{key:"StringValidator",value:function(e,t,n,r){var a=(0,at.LE)(n.minLength,n.maxLength).error;return a?{errorField:e,errorMsg:a}:this.checkIsFieldHasInput(r)&&r.length>n.maxLength?{errorField:e,errorMsg:n.errorMsg?n.errorMsg:(0,Ee.P)(18,[t,n.maxLength])}:!!(this.checkIsFieldHasInput(r)&&r.length<n.minLength)&&{errorField:e,errorMsg:n.errorMsg?n.errorMsg:(0,Ee.P)(17,[t,n.minLength])}}},{key:"RegexValidator",value:function(e,t,n,r){var a=(0,at.en)(n.pattern),o=a.error,i=a.result;return o?{errorField:e,errorMsg:o}:!(!this.checkIsFieldHasInput(r)||i.test(r))&&{errorField:e,errorMsg:n.errorMsg?n.errorMsg:(0,Ee.P)(15,[t,n.pattern])}}},{key:"PreDefinedRegexValidator",value:function(e,t,n,r,a,o){var i=(0,at.en)(a),l=i.error,s=i.result;return l?{errorField:e,errorMsg:l}:!(!this.checkIsFieldHasInput(r)||s.test(r))&&{errorField:e,errorMsg:n.errorMsg?n.errorMsg:(0,Ee.P)(19,[t,o])}}},{key:"NumberValidator",value:function(e,t,n,r){var a=(0,at.nC)(n.range).error;if(a)return{errorField:e,errorMsg:a};var o=Number(r);return Number.isNaN(o)?{errorField:e,errorMsg:n.errorMsg?n.errorMsg:(0,Ee.P)(16,[t])}:!!(this.checkIsFieldHasInput(r)&&o>n.range[1]||o<n.range[0])&&{errorField:e,errorMsg:n.errorMsg?n.errorMsg:(0,Ee.P)(8,[t,n.range[0],n.range[1]])}}},{key:"FileValidator",value:function(e,t,n){if(n){var r=(0,at.GE)(n,t.supportedFileTypes),a=r.isValidExtension,o=r.fileSize,i=r.isValidContent;if(!a)return{errorField:e,errorMsg:t.errorMsg||(0,Ee.P)(24,[t.supportedFileTypes])};if(o>ot){var l="".concat(500,"KB");return{errorField:e,errorMsg:(0,Ee.P)(25,[l])}}if(!i)return{errorField:e,errorMsg:(0,Ee.P)(26)}}return!1}},{key:"doValidation",value:function(t){if(this.isName){var n=t.name,r=this.isName.label;if(void 0===n||""===n||null==n)return{errorField:"name",errorMsg:(0,Ee.P)(0,[r])};if(!("string"==typeof n||n instanceof String))return{errorField:"name",errorMsg:(0,Ee.P)(1,[r])};if(n.startsWith("_")||"."===n||".."===n||"default"===n.toLowerCase())return{errorField:"name",errorMsg:(0,Ee.P)(3,[r])};if(["*","\\","[","]","(",")","?",":"].some((function(e){return n.indexOf(e)>-1})))return{errorField:"name",errorMsg:(0,Ee.P)(3,[r])};if(n.length>=1024)return{errorField:"name",errorMsg:(0,Ee.P)(22,[r])}}var a,o,i;for(o=0;o<this.entities.length;o+=1){if(!0===this.entities[o].required&&(a=this.RequiredValidator(this.entities[o].field,this.entities[o].label,t[this.entities[o].field])))return a;if(""!==t[this.entities[o].field]&&null!==t[this.entities[o].field]&&this.entities[o].validators)for(i=0;i<this.entities[o].validators.length;i+=1)switch(this.entities[o].validators[i].type){case"string":if(a=this.StringValidator(this.entities[o].field,this.entities[o].label,this.entities[o].validators[i],t[this.entities[o].field]))return a;break;case"regex":if(a=this.RegexValidator(this.entities[o].field,this.entities[o].label,this.entities[o].validators[i],t[this.entities[o].field]))return a;break;case"number":if(a=this.NumberValidator(this.entities[o].field,this.entities[o].label,this.entities[o].validators[i],t[this.entities[o].field]))return a;break;case"url":if(a=this.PreDefinedRegexValidator(this.entities[o].field,this.entities[o].label,this.entities[o].validators[i],t[this.entities[o].field],rt.url.regex,rt.url.inputValueType))return a;break;case"date":if(a=this.PreDefinedRegexValidator(this.entities[o].field,this.entities[o].label,this.entities[o].validators[i],t[this.entities[o].field],rt.date.regex,rt.date.inputValueType))return a;break;case"email":if(a=this.PreDefinedRegexValidator(this.entities[o].field,this.entities[o].label,this.entities[o].validators[i],t[this.entities[o].field],rt.email.regex,rt.email.inputValueType))return a;break;case"ipv4":if(a=this.PreDefinedRegexValidator(this.entities[o].field,this.entities[o].label,this.entities[o].validators[i],t[this.entities[o].field],rt.ipv4.regex,rt.ipv4.inputValueType))return a;break;case"file":if(a=this.FileValidator(this.entities[o].field,this.entities[o].validators[i],t[this.entities[o].field]))return a;break;case"custom":if(a=e.CustomValidator(this.entities[o].validators[i].validatorFunc,this.entities[o].field,t[this.entities[o].field]))return a}}return!1}}],[{key:"CustomValidator",value:function(e,t,n){var r=e(t,n);return"string"==typeof r&&{errorField:t,errorMsg:r}}}]),e}();var lt,st,ct=n(6549),ut=n(4843),dt="Error occurred while trying to authenticate. Please try Again.",pt=n(6057);function ft(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function ht(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?ft(Object(n),!0).forEach((function(t){(0,f.Z)(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ft(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var mt=(0,S.default)(C())(lt||(lt=(0,h.Z)(["\n    span {\n        button {\n            background-color: transparent;\n            font-size: 16px;\n            margin: 10px 0;\n\n            &:hover:not([disabled]),\n            &:focus:not([disabled]),\n            &:active:not([disabled]) {\n                background-color: transparent;\n                box-shadow: none;\n            }\n        }\n    }\n\n    .collapsible-element {\n        padding-top: 15px;\n    }\n"]))),vt=S.default.div(st||(st=(0,h.Z)(["\n    padding: 6px 10px;\n    background-color: #f2f4f5;\n"]))),gt=function(e){(0,u.Z)(h,e);var t,n,r=(t=h,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=(0,p.Z)(t);if(n){var a=(0,p.Z)(this).constructor;e=Reflect.construct(r,arguments,a)}else e=r.apply(this,arguments);return(0,d.Z)(this,e)});function h(e,t){var n;(0,l.Z)(this,h),n=r.call(this,e),(0,f.Z)((0,c.Z)(n),"updateEntitiesForGroup",(function(e){n.groups&&n.groups.length&&n.groups.forEach((function(t){var r;t&&null!==(r=t.fields)&&void 0!==r&&r.length&&t.fields.forEach((function(t){var r=e.entity.findIndex((function(e){return e.field===t}));if(-1!==r){var a=JSON.parse(JSON.stringify(e.entity[r]));a.isGrouping=!0,n.entities.splice(r,1,a)}}))}))})),(0,f.Z)((0,c.Z)(n),"handleSubmit",(function(){if(n.clearErrorMsg(),n.props.handleFormSubmit(!0,!1),n.datadict={},Object.keys(n.state.data).forEach((function(e){n.datadict[e]=n.state.data[e].value})),!n.hook||"function"!=typeof n.hook.onSave||n.hook.onSave(n.datadict)){var e=function(){var e;if(Object.keys(n.state.data).forEach((function(e){n.datadict[e]=n.state.data[e].value})),[ct.jg,ct.Oh].includes(n.props.mode)&&Boolean(Object.values(n.context.rowData).find((function(e){return Object.keys(e).find((function(e){return e===n.datadict.name}))})))){var t=n.entities.findIndex((function(e){return"name"===e.field}));return n.setErrorFieldMsg("name",(0,Ee.P)(2,[n.entities[t].label,n.datadict.name])),void n.props.handleFormSubmit(!1,!1)}if(n.isOAuth){var r=[];Object.keys(n.authMap).forEach((function(e){e!==n.datadict.auth_type&&n.isAuthVal||(r=[].concat((0,i.Z)(r),(0,i.Z)(n.authMap[e])))})),e=n.entities.map((function(e){return r.includes(e.field)?ht({required:!0},e):e}))}else e=n.entities;var a=new it(e).doValidation(n.datadict);if(a?n.setErrorFieldMsg(a.errorField,a.errorMsg):n.options&&n.options.saveValidator&&(a=function(e,t){var n=(0,at.IX)(e),r=n.error,a=n.result;if(r)return{errorMsg:r};var o=a(t);return"string"==typeof o?{errorMsg:o}:void 0}(n.options.saveValidator,n.datadict))&&n.setErrorMsg(a.errorMsg),a)n.props.handleFormSubmit(!1,!1);else if(n.isOAuth&&(n.isSingleOauth||n.isAuthVal&&"oauth"===n.datadict.auth_type)){var l="?response_type=code&client_id=".concat(n.datadict.client_id,"&redirect_uri=").concat(n.datadict.redirect_url),s=null!=n.isoauthState&&n.isoauthState;"true"!==s&&!0!==s||(n.state_enabled=!0,n.oauth_state=(0,Z.Z)().replace(/-/g,""),l="".concat(l,"&state=").concat(n.oauth_state));var c="https://".concat(n.datadict.endpoint).concat(n.oauthConf.authCodeEndpoint).concat(l);(0,o.Z)(v().mark((function e(){return v().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n.isCalled=!1,n.isError=!1,n.isResponse=!1,n.childWin=window.open(c,"".concat(n.appName," OAuth"),"width=".concat(n.oauthConf.popupWidth,", height=").concat(n.oauthConf.popupHeight)),window.getMessage=function(e){n.isCalled=!0,n.handleOauthToken(e)},e.next=7,n.waitForAuthentication(n.oauthConf.authTimeout);case 7:if(n.isCalled||!n.childWin.closed){e.next=11;break}return n.setErrorMsg("Authentication process interrupted. Please try again."),n.props.handleFormSubmit(!1,!1),e.abrupt("return",!1);case 11:if(n.isCalled){e.next=15;break}return n.setErrorMsg("Request time out while authenticating. Please try again."),n.props.handleFormSubmit(!1,!1),e.abrupt("return",!1);case 15:return e.next=17,n.waitForBackendResponse(30);case 17:if(n.isResponse||n.isError){e.next=22;break}return n.isError=!0,n.setErrorMsg("Request time out while getting accesstoken. Please try again."),n.props.handleFormSubmit(!1,!1),e.abrupt("return",!1);case 22:return e.abrupt("return",!0);case 23:case"end":return e.stop()}}),e)})))().then((function(){n.isError?n.props.handleFormSubmit(!1,!1):n.saveData()}))}else n.saveData()};n.hook&&"function"==typeof n.hook.onSave&&void 0!==n.onSavePromise?n.onSavePromise.then((function(){e()})):e()}else n.props.handleFormSubmit(!1,!1)})),(0,f.Z)((0,c.Z)(n),"saveData",(function(){var e=new URLSearchParams;Object.keys(n.datadict).forEach((function(t){null!=n.datadict[t]&&("object"===(0,a.Z)(n.datadict[t])&&"file"===n.entities.find((function(e){return e.field===t})).type?e.append(t,n.datadict[t].fileContent):e.append(t,n.datadict[t]))})),n.isAuthVal&&Object.keys(n.authMap).forEach((function(t){n.datadict.auth_type!==t&&n.authMap[t].forEach((function(t){e.set(t,"")}))})),n.isOAuth&&e.delete("redirect_url"),n.props.mode===ct.bZ&&e.delete("name"),(0,ce.L)({serviceName:n.endpoint,body:e,customHeaders:{"Content-Type":"application/x-www-form-urlencoded"},method:"post",handleError:!1}).then((function(e){var t,r=null==e||null===(t=e.data)||void 0===t?void 0:t.entry[0];if(n.props.mode!==ct.DE){var a={};a[r.name]=ht(ht(ht({},n.datadict),r.content),{},{id:r.id,name:r.name,serviceName:n.props.serviceName}),n.context.setRowData(k()(n.context.rowData,(0,f.Z)({},n.props.serviceName,{$merge:a})))}n.hook&&"function"==typeof n.hook.onSaveSuccess&&n.hook.onSaveSuccess(),n.props.mode===ct.bZ?(0,ue.Ke)('Updated "'.concat(r.name,'"'),"success"):n.props.mode===ct.DE?(0,ue.Ke)('Updated "'.concat(n.mode_config_title?n.mode_config_title:r.name,'"'),"success"):(0,ue.Ke)('Created "'.concat(r.name,'"'),"success"),n.props.handleFormSubmit(!1,!0)})).catch((function(e){var t=(0,Ee.n)(e);n.setState({errorMsg:t}),n.hook&&"function"==typeof n.hook.onSaveFail&&n.hook.onSaveFail(),n.props.handleFormSubmit(!1,!1)}))})),(0,f.Z)((0,c.Z)(n),"handleChange",(function(e,t){var r={};if("auth_type"===e&&Object.keys(n.authMap).forEach((function(e){e===t?n.authMap[e].forEach((function(e){r[e]={display:{$set:!0}}})):n.authMap[e].forEach((function(e){r[e]={display:{$set:!1}}}))})),n.dependencyMap.has(e)){var a=n.dependencyMap.get(e);Object.keys(a).forEach((function(o){var i={},l=!0;a[o].forEach((function(r){var a=!!n.entities.find((function(e){return e.field===r})).required,o=r===e?t:n.state.data[r].value;a&&!o?(l=!1,i[r]=null):"RESET_DROPDOWN_VALUE"===o?l=!0:i[r]=o})),l&&(r[o]={dependencyValues:{$set:i},value:{$set:null}})}))}var o="RESET_DROPDOWN_VALUE"===t?"":t;r[e]={value:{$set:o}};var i=k()(n.state,{data:r}),l=n.clearAllErrorMsg(i);n.setState(l),n.hookDeferred&&n.hookDeferred.then((function(){"function"==typeof n.hook.onChange&&n.hook.onChange(e,o,l)}))})),(0,f.Z)((0,c.Z)(n),"addCustomValidator",(function(e,t){var r=n.entities.findIndex((function(t){return t.field===e})),a=[{type:"custom",validatorFunc:t}];n.entities[r].validators=a})),(0,f.Z)((0,c.Z)(n),"setErrorFieldMsg",(function(e,t){n.setState((function(n){var r=k()(n,{data:(0,f.Z)({},e,{error:{$set:!0}})});return r.errorMsg=t,r}))})),(0,f.Z)((0,c.Z)(n),"setErrorField",(function(e){n.setState((function(t){return k()(t,{data:(0,f.Z)({},e,{error:{$set:!0}})})}))})),(0,f.Z)((0,c.Z)(n),"clearErrorMsg",(function(){n.state.errorMsg&&n.setState((function(e){return ht(ht({},e),{},{errorMsg:""})}))})),(0,f.Z)((0,c.Z)(n),"setErrorMsg",(function(e){n.setState((function(t){return ht(ht({},t),{},{errorMsg:e})}))})),(0,f.Z)((0,c.Z)(n),"clearAllErrorMsg",(function(e){var t=ht({},e||n.state);t.errorMsg="",t.warningMsg="";var r=ht({},e?e.data:n.state.data),a={};return Object.keys(r).forEach((function(e){r[e].error?a[e]=ht(ht({},r[e]),{},{error:!1}):a[e]=r[e]})),t.data=a,e?t:null})),(0,f.Z)((0,c.Z)(n),"generateErrorMessage",(function(){return n.state.errorMsg?g.createElement(R(),{appearance:"fill",type:"error"},n.state.errorMsg):null})),(0,f.Z)((0,c.Z)(n),"generateWarningMessage",(function(){return n.state.warningMsg?g.createElement(R(),{appearance:"fill",type:"warning"},n.state.warningMsg):null})),(0,f.Z)((0,c.Z)(n),"loadHook",(function(e,t,r){return new Promise((function(a){"external"===t?import("".concat((0,Ie.a)(),"/custom/").concat(e,".js")).then((function(e){var t=e.default;n.hook=new t(r,n.props.serviceName,n.state,n.props.mode,n.util,n.props.groupName),a(t)})):require(["app/".concat(n.appName,"/js/build/custom/").concat(e)],(function(e){n.hook=new e(r,n.props.serviceName,n.state,n.props.mode,n.util),a(e)}))}))})),(0,f.Z)((0,c.Z)(n),"handleOauthToken",(function(e){if(!e||e&&e.error||void 0===e.code)return n.setErrorMsg(dt),n.isError=!0,n.isResponse=!0,!1;var t=e.state;if(!0===n.state_enabled&&n.oauth_state!==t)return n.setErrorMsg("Response not received from the expected sender. Please try again."),n.isError=!0,n.isResponse=!0,!1;var r=decodeURIComponent(e.code),a={method:"POST",url:"https://".concat(n.datadict.endpoint).concat(n.oauthConf.accessTokenEndpoint),grant_type:"authorization_code",client_id:n.datadict.client_id,client_secret:n.datadict.client_secret,code:r,redirect_uri:n.datadict.redirect_url},o=new URLSearchParams;Object.keys(a).forEach((function(e){o.append(e,a[e])}));var i="".concat(n.appName,"_oauth/oauth");(0,ce.L)({endpointUrl:i,body:o,customHeaders:{"Content-Type":"application/x-www-form-urlencoded"},method:"post",handleError:!1}).then((function(e){if(void 0===e.data.entry[0].content.error){var t=e.data.entry[0].content.access_token,r=e.data.entry[0].content.instance_url,a=e.data.entry[0].content.refresh_token;return n.datadict.instance_url=r,n.datadict.refresh_token=a,n.datadict.access_token=t,n.isResponse=!0,!0}return n.setErrorMsg(e.data.entry[0].content.error),n.isError=!0,n.isResponse=!0,!1})).catch((function(){return n.setErrorMsg(dt),n.isError=!0,n.isResponse=!0,!1}))})),(0,f.Z)((0,c.Z)(n),"waitForAuthentication",function(){var e=(0,o.Z)(v().mark((function e(t){return v().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(t-=1,!0!==n.isCalled){e.next=3;break}return e.abrupt("return",!0);case 3:if(0!==t&&!n.childWin.closed){e.next=6;break}return n.isError=!0,e.abrupt("return",!1);case 6:return e.next=8,n.sleep(n.waitForAuthentication,t);case 8:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),(0,f.Z)((0,c.Z)(n),"waitForBackendResponse",function(){var e=(0,o.Z)(v().mark((function e(t){return v().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(t+=1,!0!==n.isResponse){e.next=3;break}return e.abrupt("return",!0);case 3:if(60!==t){e.next=5;break}return e.abrupt("return",!1);case 5:return e.next=7,n.sleep(n.waitForBackendResponse,t);case 7:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),(0,f.Z)((0,c.Z)(n),"sleep",function(){var e=(0,o.Z)(v().mark((function e(t){var r,a,o,i=arguments;return v().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,n.timeout(1e3);case 2:for(r=i.length,a=new Array(r>1?r-1:0),o=1;o<r;o++)a[o-1]=i[o];return e.abrupt("return",t.apply(void 0,a));case 4:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),(0,f.Z)((0,c.Z)(n),"timeout",(function(e){return new Promise((function(t){return setTimeout(t,e)}))})),(0,f.Z)((0,c.Z)(n),"renderGroupElements",(function(){var e=null;return n.groups&&n.groups.length&&(e=n.groups.map((function(e){var t,r=(null===(t=e.fields)||void 0===t?void 0:t.length)&&e.fields.map((function(e){return n.entities.map((function(t){if(t.field===e){var r=n.state.data[t.field];return g.createElement(nt,{key:t.field,utilityFuncts:n.utilControlWrapper,value:r.value,display:r.display,error:r.error,entity:t,serviceName:n.props.serviceName,mode:n.props.mode,disabled:r.disabled,markdownMessage:r.markdownMessage,dependencyValues:r.dependencyValues||null})}return null}))}));return e.options.isExpandable?g.createElement(mt,{title:e.label},g.createElement("div",{className:"collapsible-element"},r)):g.createElement(g.Fragment,null,g.createElement(vt,null,e.label),g.createElement("div",null,r))}))),e})),n.flag=!0,n.state={},n.currentInput={};var s=(0,ue.YK)();n.appName=s.meta.name,n.endpoint=e.mode===ct.bZ||e.mode===ct.DE?"".concat(n.props.serviceName,"/").concat(encodeURIComponent(n.props.stanzaName)):"".concat(n.props.serviceName),n.util={setState:function(e){n.onSavePromise=new Promise((function(t){n.setState((function(t){return e(t)}),t)}))},setErrorFieldMsg:n.setErrorFieldMsg,clearAllErrorMsg:n.clearAllErrorMsg,setErrorMsg:n.setErrorMsg},n.utilControlWrapper={handleChange:n.handleChange,addCustomValidator:n.addCustomValidator,utilCustomFunctions:n.util},e.page===ut.b?s.pages.inputs.services.forEach((function(r){r.name===e.serviceName&&(n.groups=r.groups,n.entities=r.entity,n.updateEntitiesForGroup(r),n.options=r.options,r.hook&&(n.hookDeferred=n.loadHook(r.hook.src,r.hook.type,s)),e.mode!==ct.bZ&&e.mode!==ct.Oh||(n.currentInput=t.rowData[e.serviceName][e.stanzaName]))})):s.pages.configuration.tabs.forEach((function(r){(r.table?r.name===e.serviceName:r.name===e.stanzaName&&"settings"===e.serviceName)&&(n.entities=r.entity,n.options=r.options,r.hook&&(n.hookDeferred=n.loadHook(r.hook.src,r.hook.type,s)),!r.table||e.mode!==ct.bZ&&e.mode!==ct.Oh?e.mode===ct.DE?(n.currentInput=e.currentServiceState,n.mode_config_title=r.title):n.currentInput=t.rowData[e.serviceName]:n.currentInput=t.rowData[e.serviceName][e.stanzaName])})),n.dependencyMap=new Map,n.isOAuth=!1,n.isAuthVal=!1,n.authMap={};var u={},d=[];n.entities.forEach((function(t){if("oauth"===t.type){if(n.isOAuth=!0,e.page===ut.y&&"account"===e.serviceName){var r,a,o,i=null==t||null===(r=t.options)||void 0===r?void 0:r.auth_type;if(n.isoauthState=void 0!==(null==t||null===(a=t.options)||void 0===a?void 0:a.oauth_state_enabled)?null==t||null===(o=t.options)||void 0===o?void 0:o.oauth_state_enabled:null,i.length>1){n.isAuthVal=!0;var l={};l.value=void 0!==n.currentInput.auth_type?n.currentInput.auth_type:i[0],l.display=!0,l.error=!1,l.disabled=!1,u.auth_type=l;var s={field:"auth_type",type:"singleSelect",label:"Auth Type"},c={basic:"Basic Authentication",oauth:"OAuth 2.0 Authentication"};s.options={},s.options.hideClearBtn=!0,s.options.autoCompleteFields=i.map((function(e){return{label:c[e],value:e}})),d.push(s)}else n.isSingleOauth=i.includes("oauth");if(i.forEach((function(r){var a=[],o=null==t?void 0:t.options[r];o&&(o.forEach((function(t){var o={};if(e.mode===ct.jg)o.value=void 0!==(null==t?void 0:t.defaultValue)?t.defaultValue:null;else{var i=void 0!==(null==t?void 0:t.encrypted)&&(null==t?void 0:t.encrypted);o.value=i?"":n.currentInput[t.field]}o.display=void 0===u.auth_type||r===u.auth_type.value,o.error=!1,o.disabled=!1,u[t.field]=o,t.type=void 0!==(null==t?void 0:t.type)?t.type:"text","redirect_url"===t.field&&(o.value=window.location.href.split("?")[0].replace("configuration","".concat(n.appName.toLowerCase(),"_redirect")),o.disabled=!0),d.push(t),a.push(t.field)})),n.authMap[r]=a)})),i.includes("oauth")){var p={};p.popupWidth=t.options.oauth_popup_width?t.options.oauth_popup_width:600,p.popupHeight=t.options.oauth_popup_height?t.options.oauth_popup_height:600,p.authTimeout=t.options.oauth_timeout?t.options.oauth_timeout:180,p.authCodeEndpoint=t.options.auth_code_endpoint?t.options.auth_code_endpoint:null,p.accessTokenEndpoint=t.options.access_token_endpoint?t.options.access_token_endpoint:null,n.oauthConf=p}}}else{var h,m,v={};if(t.encrypted=void 0!==t.encrypted&&t.encrypted,e.mode===ct.jg)v.value=void 0!==t.defaultValue?t.defaultValue:null,v.display=void 0===(null==t||null===(m=t.options)||void 0===m?void 0:m.display)||t.options.display,v.error=!1,v.disabled=!1,u[t.field]=v;else if(e.mode===ct.bZ){var g,y;v.value=void 0!==n.currentInput[t.field]?n.currentInput[t.field]:null,v.value=t.encrypted?"":v.value,v.display=void 0===(null==t||null===(g=t.options)||void 0===g?void 0:g.display)||t.options.display,v.error=!1,v.disabled=!1,"name"===t.field?v.disabled=!0:void 0!==(null==t||null===(y=t.options)||void 0===y?void 0:y.disableonEdit)&&(v.disabled=t.options.disableonEdit),u[t.field]=v}else if(e.mode===ct.Oh){var b;v.value="name"===t.field||t.encrypted?"":n.currentInput[t.field],v.display=void 0===(null==t||null===(b=t.options)||void 0===b?void 0:b.display)||t.options.display,v.error=!1,v.disabled=!1,u[t.field]=v}else{if(e.mode!==ct.DE)throw new Error("Invalid mode :",e.mode);var E,k;t.defaultValue=void 0!==t.defaultValue?t.defaultValue:null,v.value=void 0!==n.currentInput[t.field]?n.currentInput[t.field]:t.defaultValue,v.value=t.encrypted?"":v.value,v.display=void 0===(null==t||null===(E=t.options)||void 0===E?void 0:E.display)||t.options.display,v.error=!1,v.disabled=!1,"name"===t.field?v.disabled=!0:void 0!==(null==t||null===(k=t.options)||void 0===k?void 0:k.disableonEdit)&&(v.disabled=t.options.disableonEdit),u[t.field]=v}var Z=null===(h=t.options)||void 0===h?void 0:h.dependencies;Z&&Z.forEach((function(e){var r=n.dependencyMap.get(e);r?r[t.field]=Z:n.dependencyMap.set(e,(0,f.Z)({},t.field,Z))})),d.push(t)}})),n.entities=d;var p={};n.dependencyMap.forEach((function(e){p=ht(ht({},p),e)}));var m={};return Object.keys(p).forEach((function(e){var t=p[e],r={},a=!0;t.forEach((function(e){var t=!!n.entities.find((function(t){return t.field===e})).required,o=u[e].value;t&&!o?(a=!1,r[e]=null):r[e]=o})),a&&(m[e]={dependencyValues:{$set:r}})})),u=k()(u,m),n.state={data:u,errorMsg:"",warningMsg:""},n.hookDeferred&&n.hookDeferred.then((function(){if("function"==typeof n.hook.onCreate)try{n.hook.onCreate()}catch(e){console.error(e)}})),n}return(0,s.Z)(h,[{key:"render",value:function(){var e=this;return this.flag&&(this.hookDeferred&&this.hookDeferred.then((function(){if("function"==typeof e.hook.onRender)try{e.hook.onRender()}catch(e){console.error(e)}})),this.props.mode===ct.bZ&&this.hookDeferred&&this.hookDeferred.then((function(){if("function"==typeof e.hook.onEditLoad)try{e.hook.onEditLoad()}catch(e){console.error(e)}})),this.flag=!1),g.createElement("div",null,g.createElement("form",{style:this.props.mode===ct.DE?{marginTop:"25px"}:{}},this.generateWarningMessage(),this.generateErrorMessage(),this.renderGroupElements(),this.entities.map((function(t){var n;if(t.isGrouping)return null;var r=e.state.data[t.field];return r.placeholder&&(t=ht(ht({},t),{},{options:ht(ht({},t.options),{},{placeholder:r.placeholder})})),t.required||Object.prototype.hasOwnProperty.call(t,"oauth_field")||null!==(n=t.options)&&void 0!==n&&n.placeholder||(t.options=ht(ht({},t.options),{},{placeholder:"optional"})),g.createElement(nt,{key:t.field,utilityFuncts:e.utilControlWrapper,value:r.value,display:r.display,error:r.error,entity:t,serviceName:e.props.serviceName,mode:e.props.mode,disabled:r.disabled,markdownMessage:r.markdownMessage,dependencyValues:r.dependencyValues||null})}))))}}]),h}(g.PureComponent);(0,f.Z)(gt,"contextType",pt.Z),gt.propTypes={page:b().string,serviceName:b().string,stanzaName:b().string,currentServiceState:b().object,mode:b().string,handleFormSubmit:b().func,groupName:b().string};const yt=gt},5792:(e,t,n)=>{n.d(t,{Z:()=>S});var r,a=n(5671),o=n(3144),i=n(7326),l=n(9340),s=n(2963),c=n(1120),u=n(4942),d=n(168),p=n(7294),f=n(1581),h=n.n(f),m=n(6416),v=n.n(m),g=n(1158),y=n.n(g),b=n(2788),E=n(5414),k=n.n(E),Z=n(6219),O=n(6549),C=n(5464);var w=(0,b.default)(y())(r||(r=(0,d.Z)(["\n    width: 800px;\n"]))),R=function(e){(0,l.Z)(d,e);var t,n,r=(t=d,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=(0,c.Z)(t);if(n){var a=(0,c.Z)(this).constructor;e=Reflect.construct(r,arguments,a)}else e=r.apply(this,arguments);return(0,s.Z)(this,e)});function d(e){var t;return(0,a.Z)(this,d),t=r.call(this,e),(0,u.Z)((0,i.Z)(t),"handleRequestClose",(function(){t.props.handleRequestClose()})),(0,u.Z)((0,i.Z)(t),"handleSubmit",(function(){t.form.current.handleSubmit()&&t.handleRequestClose()})),(0,u.Z)((0,i.Z)(t),"handleFormSubmit",(function(e,n){t.setState({isSubmititng:e}),n&&t.handleRequestClose()})),t.form=p.createRef(),t.state={isSubmititng:!1},e.mode===O.jg?t.buttonText=(0,Z._)("Add"):e.mode===O.Oh?t.buttonText=(0,Z._)("Save"):e.mode===O.bZ?t.buttonText=(0,Z._)("Update"):t.buttonText=(0,Z._)("Submit"),t}return(0,o.Z)(d,[{key:"render",value:function(){return p.createElement(w,{open:this.props.open},p.createElement(y().Header,{title:this.props.formLabel,onRequestClose:this.handleRequestClose}),p.createElement(y().Body,null,p.createElement(C.Z,{ref:this.form,page:this.props.page,serviceName:this.props.serviceName,mode:this.props.mode,stanzaName:this.props.stanzaName,handleFormSubmit:this.handleFormSubmit,groupName:this.props.groupName})),p.createElement(y().Footer,null,p.createElement(v(),{appearance:"secondary",onClick:this.handleRequestClose,label:(0,Z._)("Cancel"),disabled:this.state.isSubmititng}),p.createElement(v(),{className:"saveBtn",appearance:"primary",label:this.state.isSubmititng?p.createElement(k(),null):this.buttonText,onClick:this.handleSubmit,disabled:this.state.isSubmititng})))}}]),d}(p.Component);R.propTypes={page:h().string,open:h().bool,handleRequestClose:h().func,serviceName:h().string,mode:h().string,stanzaName:h().string,formLabel:h().string,groupName:h().string};const S=R},3649:(e,t,n)=>{n.d(t,{Z:()=>Z});var r=n(885),a=n(7294),o=n(1581),i=n.n(o),l=n(6416),s=n.n(l),c=n(6206),u=n.n(c),d=n(5414),p=n.n(d),f=n(1569),h=n.n(f),m=n(6219),v=n(5947),g=n(6549),y=n(5464),b=n(1263),E=n(4843);function k(e){var t=e.handleRequestClose,n=e.serviceName,o=e.mode,i=e.stanzaName,l=e.formLabel,c=e.page,d=e.groupName,f=(0,a.useRef)(),k=(0,a.useState)(!1),Z=(0,r.Z)(k,2),O=Z[0],C=Z[1],w=(0,m._)("Submit");o===g.jg?w=(0,m._)("Add"):o===g.Oh?w=(0,m._)("Clone Input"):o===g.bZ&&(w=(0,m._)("Update"));var R={boxShadow:(0,v.useSplunkTheme)().embossShadow,padding:"1%",backgroundColor:"white"};return a.createElement(h(),{gutter:8},a.createElement(h().Row,{style:{padding:"5px 0px"}},a.createElement(h().Column,null,a.createElement(b.pZ,null,a.createElement(u(),{onClick:t},c===E.b?(0,m._)("Inputs"):(0,m._)("Configuration"))," > ",(0,m._)(l)))),a.createElement(h().Row,null,a.createElement(h().Column,{span:2}),a.createElement(h().Column,{span:8,style:R},a.createElement(y.Z,{ref:f,page:c,serviceName:n,mode:o,stanzaName:i,handleFormSubmit:function(e,n){C(e),n&&t()},groupName:d})),a.createElement(h().Column,{span:2})),a.createElement(h().Row,null,a.createElement(h().Column,{span:7}),a.createElement(h().Column,{span:3,style:{textAlign:"right"}},a.createElement(s(),{appearance:"secondary",onClick:t,label:(0,m._)("Cancel"),disabled:O,style:{width:"80px"}}),a.createElement(s(),{appearance:"primary",label:O?a.createElement(p(),null):w,onClick:function(){f.current.handleSubmit()&&t()},disabled:O,style:{width:"80px"}})),a.createElement(h().Column,{span:2})))}k.propTypes={handleRequestClose:i().func,serviceName:i().string,mode:i().string,stanzaName:i().string,formLabel:i().string,page:i().string,groupName:i().string};const Z=(0,a.memo)(k)},5496:(e,t,n)=>{n.d(t,{Z:()=>Z});var r=n(5671),a=n(3144),o=n(9340),i=n(2963),l=n(1120),s=n(7294),c=n(1581),u=n.n(c),d=n(8580),p=n.n(d),f=n(6219),h=n(2978),m=n.n(h),v=n(4003),g=n.n(v),y=n(6206),b=n.n(y);const E={ERR0001:s.createElement(s.Fragment,null,"This is normal on Splunk search heads as they do not require an Input page. Check your installation or return to the ",s.createElement(b(),{to:"configuration"},"configuration page"),"."),ERR0002:"Configuration page failed to load, the server reported internal errors which may indicate you do not have access to this page.",ERR0003:"Failed to load content due to no response from server!",ERR0004:"Failed to load content due to failed request processing!",ERR0005:"Failed to load current state for selected entity in form!"};var k=function(e){(0,o.Z)(u,e);var t,n,c=(t=u,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=(0,l.Z)(t);if(n){var a=(0,l.Z)(this).constructor;e=Reflect.construct(r,arguments,a)}else e=r.apply(this,arguments);return(0,i.Z)(this,e)});function u(e){var t;return(0,r.Z)(this,u),(t=c.call(this,e)).state={errorCode:null,error:null},t}return(0,a.Z)(u,[{key:"componentDidCatch",value:function(e){this.setState({error:e})}},{key:"render",value:function(){var e;return this.state.error?s.createElement("div",{style:{marginTop:"10%"}},s.createElement(m(),{style:{boxShadow:"10px 10px 5px #aaaaaa"}},s.createElement(m().Header,null,s.createElement(p(),{style:{textAlign:"center"},level:2},s.createElement(g(),{style:{fontSize:"120px",color:"#ff9900"}}),s.createElement("br",null),s.createElement("br",null),"ERR0001"===this.state.errorCode?(0,f._)("Failed to load Inputs Page"):(0,f._)("Something went wrong!"))),s.createElement(m().Body,null,this.state.errorCode?s.createElement(s.Fragment,null,(0,f._)(E[this.state.errorCode]),s.createElement("br",null),s.createElement("br",null)):null,s.createElement("details",{style:{whiteSpace:"pre-wrap"}},null===(e=this.state.error)||void 0===e?void 0:e.toString())),s.createElement(m().Footer,{showBorder:!1},this.state.errorCode?this.state.errorCode:null))):this.props.children}}],[{key:"getDerivedStateFromError",value:function(e){return{errorCode:e.uccErrorCode}}}]),u}(s.Component);k.propTypes={children:u().oneOfType([u().arrayOf(u().node),u().node]).isRequired};const Z=k},7588:(e,t,n)=>{n.d(t,{Z:()=>ze});var r=n(4942),a=n(885),o=n(7294),i=n(7145),l=n.n(i),s=n(1721),c=n(1581),u=n.n(c),d=n(6070),p=n(2297),f=n(4255),h=n(7462),m=n(7599),v=n.n(m),g=n(6219),y=n(4893),b=n(6549),E=n(4843),k=n(168),Z=n(2346),O=n.n(Z),C=n(2788),w=n(5671),R=n(3144),S=n(7326),x=n(9340),N=n(2963),P=n(1120),j=n(4266);var _=function(e){(0,x.Z)(i,e);var t,n,a=(t=i,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=(0,P.Z)(t);if(n){var a=(0,P.Z)(this).constructor;e=Reflect.construct(r,arguments,a)}else e=r.apply(this,arguments);return(0,N.Z)(this,e)});function i(e){var t;return(0,w.Z)(this,i),t=a.call(this,e),(0,r.Z)((0,S.Z)(t),"loadCustomControl",(function(){return new Promise((function(e){if("external"===t.props.type)import("".concat((0,j.a)(),"/custom/").concat(t.props.fileName,".js")).then((function(t){var n=t.default;e(n)}));else{var n=(0,f.YK)().meta.name;require(["app/".concat(n,"/js/build/custom/").concat(t.props.fileName)],(function(t){return e(t)}))}}))})),t.state={loading:!0},t.shouldRender=!0,t}return(0,R.Z)(i,[{key:"componentDidMount",value:function(){var e=this,t=(0,f.YK)();this.setState({loading:!0}),this.loadCustomControl().then((function(n){e.customControl=new n(t,e.props.serviceName,e.el,e.props.row,e.props.field),e.setState({loading:!1})}))}},{key:"shouldComponentUpdate",value:function(e,t){return this.props.row!==e.row||!(t.loading||!this.shouldRender)&&(this.shouldRender=!1,!0)}},{key:"render",value:function(){var e=this;if(!this.state.loading)try{this.customControl.render(this.props.row,this.props.field)}catch(e){console.error(e)}return o.createElement(o.Fragment,null,this.state.loading&&(0,g._)("Loading..."),o.createElement("span",{ref:function(t){e.el=t},style:{visibility:this.state.loading?"hidden":"visible"}}))}}]),i}(o.Component);_.propTypes={serviceName:u().string.isRequired,row:u().object.isRequired,field:u().string,fileName:u().string.isRequired,type:u().string};const M=_;var T,D=(0,C.default)(v().Cell)(T||(T=(0,k.Z)(["\n    border-top: none;\n"])));function F(e,t,n){var r,a,i=null===(r=(0,f.YK)().pages)||void 0===r?void 0:r.inputs,l=null!=i&&i.table?i.table.customRow:null===(a=i.services.find((function(e){return e.name===t.serviceName})).table)||void 0===a?void 0:a.customRow;return o.createElement(v().Row,{key:"".concat(t.id,"-expansion")},o.createElement(D,{colSpan:e},l&&l.src?o.createElement(o.Fragment,null,o.createElement(M,{serviceName:t.serviceName,row:t,fileName:l.src,type:l.type})):o.createElement(O(),{termWidth:250},function(e,t){var n=[];return null!=t&&t.length&&t.forEach((function(t){var r=(0,g._)(t.label);t.field in e&&null!==e[t.field]&&""!==e[t.field]&&(n.push(o.createElement(O().Term,{key:t.field},r)),n.push(o.createElement(O().Description,{key:"".concat(t.field,"_decr")},t.mapping&&t.mapping[e[t.field]]?t.mapping[e[t.field]]:String(e[t.field]))))})),n}(t,n))))}var V,q,A=n(9881),z=n(5414),L=n.n(z),I=n(7885),B=n.n(I),K=n(5864),H=n.n(K),U=n(5458),$=n.n(U),W=n(1),G=n.n(W),X=n(4193),Y=n.n(X),J=n(8442),Q=n.n(J),ee=(0,C.default)(v().Cell)(V||(V=(0,k.Z)(["\n    padding: 2px;\n"]))),te=C.default.div(q||(q=(0,k.Z)(["\n    display: flex;\n\n    .toggle_switch {\n        padding: 0;\n        margin-right: 10px;\n    }\n"])));function ne(e){var t=e.row,n=e.columns,r=e.headerMapping,a=e.handleToggleActionClick,i=e.handleEditActionClick,l=e.handleCloneActionClick,s=e.handleDeleteActionClick,c=(0,o.useCallback)((function(e){return o.createElement(ee,{"data-column":"actions",key:e.id},o.createElement(H(),null,o.createElement($(),{content:(0,g._)("Edit")},o.createElement(d.xV,{appearance:"flat",icon:o.createElement(G(),{screenReaderText:null,size:1}),onClick:function(){return i(e)},className:"editBtn"})),o.createElement($(),{content:(0,g._)("Clone")},o.createElement(d.xV,{appearance:"flat",icon:o.createElement(Y(),{screenReaderText:null,size:1}),onClick:function(){return l(e)},className:"cloneBtn"})),o.createElement($(),{content:(0,g._)("Delete")},o.createElement(d.xV,{appearance:"destructive",icon:o.createElement(Q(),{screenReaderText:null,size:1}),onClick:function(){return s(e)},className:"deleteBtn"}))))}),[i,l,s]),u="Enabled";return t.__toggleShowSpinner?u=o.createElement(L(),null):t.disabled&&(u=null!=r&&r.disabled&&r.disabled[t.disabled]?r.disabled[t.disabled]:"Disabled"),o.createElement(v().Row,(0,h.Z)({key:t.id},e),n&&n.length&&n.map((function(e){var n="";if(e.customCell&&e.customCell.src)n=o.createElement(v().Cell,{"data-column":e.field,key:e.field},function(e,n){return o.createElement(M,{serviceName:t.serviceName,field:n.field,row:e,fileName:n.customCell.src,type:n.customCell.type})}(t,e));else if("disabled"===e.field){var i,l;n=o.createElement(v().Cell,{"data-column":e.field,key:e.field},o.createElement(te,null,o.createElement(B(),{key:t.name,value:t.disabled,onClick:function(){return a(t)},selected:!t.disabled,disabled:t.__toggleShowSpinner,appearance:"toggle",className:"toggle_switch",selectedLabel:(0,g._)(null!=r&&null!==(i=r.disabled)&&void 0!==i&&i.false?r.disabled.false:"Enabled"),unselectedLabel:(0,g._)(null!=r&&null!==(l=r.disabled)&&void 0!==l&&l.true?r.disabled.true:"Disabled")}),o.createElement("span",{"data-test":"status"},u)))}else n="actions"===e.field?c(t):o.createElement(v().Cell,{style:{wordBreak:"break-all"},"data-column":e.field,key:e.field},r[e.field]&&Object.prototype.hasOwnProperty.call(r[e.field],t[e.field])?r[e.field][t[e.field]]:t[e.field]);return n})))}ne.propTypes={row:u().any,columns:u().array,headerMapping:u().object,handleToggleActionClick:u().func,handleEditActionClick:u().func,handleCloneActionClick:u().func,handleDeleteActionClick:u().func};const re=o.memo(ne);var ae,oe=n(5792),ie=n(6416),le=n.n(ie),se=n(1158),ce=n.n(se),ue=n(8689),de=n.n(ue),pe=n(6057),fe=n(9609);function he(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function me(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?he(Object(n),!0).forEach((function(t){(0,r.Z)(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):he(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var ve=(0,C.default)(ce())(ae||(ae=(0,k.Z)(["\n    width: 800px;\n"]))),ge=function(e){(0,x.Z)(i,e);var t,n,a=(t=i,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=(0,P.Z)(t);if(n){var a=(0,P.Z)(this).constructor;e=Reflect.construct(r,arguments,a)}else e=r.apply(this,arguments);return(0,N.Z)(this,e)});function i(e){var t;return(0,w.Z)(this,i),t=a.call(this,e),(0,r.Z)((0,S.Z)(t),"handleRequestClose",(function(){t.state.ErrorMsg="",t.props.handleRequestClose()})),(0,r.Z)((0,S.Z)(t),"handleDelete",(function(){t.setState((function(e){return me(me({},e),{},{isDeleting:!0,ErrorMsg:""})}),(function(){(0,p.L)({serviceName:"".concat(t.props.serviceName,"/").concat(encodeURIComponent(t.props.stanzaName)),customHeaders:{"Content-Type":"application/x-www-form-urlencoded"},method:"delete",handleError:!1}).catch((function(e){var n=(0,fe.n)(e);return t.setState({ErrorMsg:n,isDeleting:!1}),Promise.reject(e)})).then((function(){t.context.setRowData(l()(t.context.rowData,(0,r.Z)({},t.props.serviceName,{$unset:[t.props.stanzaName]}))),t.setState({isDeleting:!1}),t.handleRequestClose(),(0,f.Ke)('Deleted "'.concat(t.props.stanzaName,'"'),"success")}))}))})),(0,r.Z)((0,S.Z)(t),"generateErrorMessage",(function(){return t.state.ErrorMsg?o.createElement("div",null,o.createElement(de(),{appearance:"fill",type:"error"},t.state.ErrorMsg)):null})),t.state={isDeleting:!1,ErrorMsg:""},t}return(0,R.Z)(i,[{key:"render",value:function(){var e;return e=this.props.page===E.b?(0,fe.P)(103,[this.props.stanzaName]):(0,fe.P)(102,[this.props.stanzaName]),o.createElement(ve,{open:this.props.open},o.createElement(ce().Header,{title:(0,fe.P)(101),onRequestClose:this.handleRequestClose}),o.createElement(ce().Body,{className:"deletePrompt"},this.generateErrorMessage(),o.createElement("p",null,e)),o.createElement(ce().Footer,null,o.createElement(le(),{appearance:"secondary",onClick:this.handleRequestClose,label:(0,g._)("Cancel"),disabled:this.state.isDeleting}),o.createElement(le(),{appearance:"primary",label:this.state.isDeleting?o.createElement(L(),null):(0,g._)("Delete"),onClick:this.handleDelete,disabled:this.state.isDeleting})))}}]),i}(o.Component);(0,r.Z)(ge,"contextType",pe.Z),ge.propTypes={page:u().string.isRequired,open:u().bool,handleRequestClose:u().func,serviceName:u().string,stanzaName:u().string};const ye=ge;function be(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Ee(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?be(Object(n),!0).forEach((function(t){(0,r.Z)(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):be(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function ke(e){var t=e.page,n=e.serviceName,r=e.data,i=e.handleToggleActionClick,l=e.handleOpenPageStyleDialog,s=e.handleSort,c=e.sortDir,u=e.sortKey,p=e.tableConfig,m=(0,f.YK)(),k=(0,o.useState)({open:!1}),Z=(0,a.Z)(k,2),O=Z[0],C=Z[1],w=(0,o.useState)({open:!1}),R=(0,a.Z)(w,2),S=R[0],x=R[1],N=(0,o.useContext)(pe.Z).rowData,P=p.moreInfo,j=p.header,_=p.header,M={};j.forEach((function(e){M[e.field]=e.mapping}));var T={};t===E.b?m.pages.inputs.services.forEach((function(e){T[e.name]=e.style===A.G?A.G:A.f})):m.pages.configuration.tabs.forEach((function(e){T[e.name]=e.style===A.G?A.G:A.f}));var D=(0,y.Z)();(0,o.useEffect)((function(){if(D&&(D.get("tab")===n||void 0===n))if(D.get("record")&&!O.open){var e=Object.keys(N).find((function(e){return void 0!==N[e][D.get("record")]}));if(e){var t=N[e][D.get("record")];C(Ee(Ee({},O),{},{open:!0,serviceName:t.serviceName,stanzaName:t.name,mode:b.bZ}))}}else!D.get("record")&&O.open&&C(Ee(Ee({},O),{},{open:!1}))}),[]);var V,q=function(){C(Ee(Ee({},O),{},{open:!1}))},z=(0,o.useCallback)((function(e){T[e.serviceName]===A.G?l(e,b.bZ):C(Ee(Ee({},O),{},{open:!0,serviceName:e.serviceName,stanzaName:e.name,mode:b.bZ}))}),[O]),L=(0,o.useCallback)((function(e){T[e.serviceName]===A.G?l(e,b.Oh):C(Ee(Ee({},O),{},{open:!0,serviceName:e.serviceName,stanzaName:e.name,mode:b.Oh}))}),[O]),I=(0,o.useCallback)((function(e){x(Ee(Ee({},S),{},{open:!0,stanzaName:e.name,serviceName:e.serviceName}))}),[S]),B=(V=[],_&&_.length&&_.forEach((function(e){V.push(Ee(Ee({},e),{},{sortKey:e.field||null,isCustomMapping:!!e.mapping}))})),V.push({label:"Actions",field:"actions",sortKey:""}),V),K=(0,o.useCallback)((function(){return o.createElement(v().Head,null,B&&B.length&&B.map((function(e){return o.createElement(v().HeadCell,{key:e.field,onSort:function(t){return e.sortKey?s(t,e):null},sortKey:e.sortKey?e.sortKey:null,sortDir:e.sortKey&&e.sortKey===u?c:"none"},e.label)})))}),[B,s,c,u]);return o.createElement(o.Fragment,null,B&&B.length&&o.createElement(v(),(0,h.Z)({stripeRows:!0,headType:"docked"},P?{rowExpansion:"single"}:{}),K(),o.createElement(v().Body,null,r&&r.length&&r.map((function(e){return o.createElement(re,(0,h.Z)({key:e.id,row:e,columns:B,headerMapping:M,handleEditActionClick:z,handleCloneActionClick:L,handleDeleteActionClick:I,handleToggleActionClick:i},P?{expansionRow:F(B.length,e,P)}:{}))})))),r.length?null:o.createElement(d.Pd,null,"No records found"),function(){if(O.open){var e,n;if("inputs"===t)e=null===(n=m.pages.inputs.services.find((function(e){return e.name===O.serviceName})))||void 0===n?void 0:n.title;else if("configuration"===t){var r;e=null===(r=m.pages.configuration.tabs.find((function(e){return e.name===O.serviceName})))||void 0===r?void 0:r.title}return o.createElement(oe.Z,{page:t,open:O.open,handleRequestClose:q,serviceName:O.serviceName,stanzaName:O.stanzaName,mode:O.mode,formLabel:O.mode===b.Oh?(0,g._)("Clone ")+e:(0,g._)("Update ")+e})}return null}(),o.createElement(ye,{page:t,open:S.open,handleRequestClose:function(){x(Ee(Ee({},S),{},{open:!1}))},serviceName:S.serviceName,stanzaName:S.stanzaName}))}ke.propTypes={page:u().string.isRequired,serviceName:u().string,data:u().array.isRequired,handleToggleActionClick:u().func,handleOpenPageStyleDialog:u().func,handleSort:u().func,sortDir:u().string,sortKey:u().string,tableConfig:u().object.isRequired};const Ze=(0,o.memo)(ke);var Oe=n(6521),Ce=n.n(Oe),we=n(8411),Re=n.n(we),Se=n(6401),xe=n.n(Se);function Ne(e){var t=(0,o.useContext)(pe.Z).searchText;return o.createElement(xe(),{appearance:"search",placeholder:"filter",onChange:e.handleChange,value:t})}Ne.propTypes={handleChange:u().func};const Pe=Ne;var je,_e,Me=C.default.div(je||(je=(0,k.Z)(["\n    display: flex;\n    justify-content: space-between;\n    border-top: 1px solid #ccc;\n    padding-top: 5px;\n    margin-bottom: 5px;\n"]))),Te=C.default.div(_e||(_e=(0,k.Z)(["\n    max-width: 300px;\n    width: 100%;\n"])));function De(e){var t=e.page,n=e.isOuterTable,r=e.services,a=e.totalElement,i=e.handleRequestModalOpen,l=(0,o.useContext)(pe.Z),s=l.pageSize,c=l.currentPage,u=l.setCurrentPage,p=l.setPageSize,f=l.searchType,h=l.setSearchType,m=l.setSearchText,v=t===E.b?"Input":"Item";return o.createElement(Me,null,o.createElement("div",null,o.createElement("span",{className:"inputNumber"},a,a>1?(0,g._)(" ".concat(v,"s")):(0,g._)(" ".concat(v))),t===E.b?o.createElement(d.fh,null,o.createElement(Ce(),{value:s,className:"dropdownPage",onChange:function(e,t){var n=t.value;u(0),p(n)}},o.createElement(Ce().Option,{key:"10",label:(0,g._)("10 Per Page"),value:10}),o.createElement(Ce().Option,{key:"25",label:(0,g._)("25 Per Page"),value:25}),o.createElement(Ce().Option,{key:"50",label:(0,g._)("50 Per Page"),value:50})),n?function(){if(r.length<2)return null;var e=[];return(e=r.map((function(e){return o.createElement(Ce().Option,{key:e.name,label:e.title,value:e.name})}))).unshift(o.createElement(Ce().Option,{key:"all",label:(0,g._)("All"),value:"all"})),o.createElement(Ce(),{value:f,className:"dropdownInput",onChange:function(e,t){var n=t.value;u(0),h(n)}},e)}():null):null),o.createElement(Te,null,o.createElement(Pe,{handleChange:function(e,t){var n=t.value;u(0),m(n)}})),o.createElement("div",null,o.createElement(Re(),{onChange:function(e,t){var n=t.page;return u(n-1)},current:c+1,alwaysShowLastPageLink:!0,totalPages:Math.ceil(a/s)}),t===E.b&&n?null:o.createElement(le(),{label:(0,g._)("Add"),appearance:"primary",onClick:i})))}De.propTypes={page:u().string,services:u().array,totalElement:u().number,isOuterTable:u().bool,handleRequestModalOpen:u().func};const Fe=De;function Ve(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function qe(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Ve(Object(n),!0).forEach((function(t){(0,r.Z)(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Ve(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Ae(e){var t,n=e.page,i=e.serviceName,c=e.handleRequestModalOpen,u=e.handleOpenPageStyleDialog,h=(0,o.useState)("name"),m=(0,a.Z)(h,2),v=m[0],g=m[1],y=(0,o.useState)("asc"),b=(0,a.Z)(y,2),k=b[0],Z=b[1],O=(0,o.useState)(!1),C=(0,a.Z)(O,2),w=C[0],R=C[1],S=(0,o.useState)(!0),x=(0,a.Z)(S,2),N=x[0],P=x[1],j=(0,o.useState)(null),_=(0,a.Z)(j,2),M=_[0],T=_[1],D=(0,o.useContext)(pe.Z),F=D.rowData,V=D.setRowData,q=D.pageSize,A=D.currentPage,z=D.searchText,L=D.searchType,I=(0,f.YK)(),B=null===(t=I.pages.inputs)||void 0===t?void 0:t.table,K=n===E.b?I.pages.inputs.services:I.pages.configuration.tabs.filter((function(e){return e.name===i})),H=n===E.b?B||K.find((function(e){return e.name===i})).table:I.pages.configuration.tabs.find((function(e){return e.name===i})).table,U=H.moreInfo,$=H.header,W=!!B;(0,o.useEffect)((function(){var e;e=[],K.forEach((function(t){e.push((0,p.L)({serviceName:t.name,params:{count:-1}}))})),s.ZP.all(e).catch((function(e){var t="",r="";return e.response?(t="Error received from server: ".concat(e.response.data.messages[0].text),r=n===E.b?"ERR0001":"ERR0002"):e.request?(t="No response received while making request to ".concat(n," services"),r="ERR0003"):(t="Error making request to ".concat(n," services"),r="ERR0004"),e.uccErrorCode=r,(0,f.Ke)(t),P(!1),T(e),Promise.reject(e)})).then((function(e){var t,n;t=e.map((function(e){return e.data.entry})),n={},K.forEach((function(e,r){if(e&&e.name&&t){var a={};t[r].forEach((function(t){a[t.name]=qe(qe({},t.content),{},{id:t.id,name:t.name,serviceName:e.name,serviceTitle:e.title||""})})),n[e.name]=a}})),V(n),P(!1)}))}),[]);var G=function(e){var t=[],n=[];return $.forEach((function(e){n.push(e.field)})),null==U||U.forEach((function(e){n.push(e.field)})),Object.keys(e).forEach((function(r){var a=!1;Object.keys(e[r]).forEach((function(o){n.includes(o)&&"string"==typeof e[r][o]&&e[r][o].toLowerCase().includes(z.toLowerCase().trim())&&!a&&(t.push(e[r]),a=!0)}))})),t};if(null!=M&&M.uccErrorCode)throw M;if(N)return o.createElement(d.XE,null);var X=function(){var e=[];"all"===L?Object.keys(F).forEach((function(t){var n;n=z&&z.length?G(F[t]):Object.keys(F[t]).map((function(e){return F[t][e]})),e=e.concat(n)})):e=G(F[L]),W||(e=e.filter((function(e){return e.serviceName===i})));var t=w?"serviceTitle":v,n=e.sort((function(e,n){if("asc"===k)return(void 0===e[t]?"":e[t])>(void 0===n[t]?"":n[t])?1:-1;if("desc"===k){var r=void 0===e[t]?"":e[t];return(void 0===n[t]?"":n[t])>r?1:-1}return 0})),r=n.slice(A*q,(A+1)*q);return A>0&&!r.length&&(r=n.slice((A-1)*q,q)),[r,e.length]}(),Y=(0,a.Z)(X,2),J=Y[0],Q=Y[1];return o.createElement(o.Fragment,null,o.createElement(Fe,{page:n,services:K,totalElement:Q,handleRequestModalOpen:c,isOuterTable:W}),o.createElement(Ze,{page:n,serviceName:i,data:J,handleToggleActionClick:function(e){return function(e){V((function(t){return l()(t,(0,r.Z)({},e.serviceName,(0,r.Z)({},e.name,{__toggleShowSpinner:{$set:!0}})))}));var t=new URLSearchParams;t.append("disabled",!e.disabled),(0,p.L)({serviceName:"".concat(e.serviceName,"/").concat(e.name),body:t,customHeaders:{"Content-Type":"application/x-www-form-urlencoded"},method:"post",handleError:!0,callbackOnError:function(){V((function(t){return l()(t,(0,r.Z)({},e.serviceName,(0,r.Z)({},e.name,{__toggleShowSpinner:{$set:!1}})))}))}}).then((function(t){V((function(n){return l()(n,(0,r.Z)({},e.serviceName,(0,r.Z)({},e.name,{disabled:{$set:(0,f.oA)(t.data.entry[0].content.disabled)},__toggleShowSpinner:{$set:!1}})))}))}))}(e)},handleSort:function(e,t){var n=v===t.sortKey?k:"none";Z("asc"===n?"desc":"asc"),g(t.sortKey),R(t.isCustomMapping)},sortDir:k,sortKey:v,handleOpenPageStyleDialog:u,tableConfig:H,services:K}))}Ae.propTypes={page:u().string,serviceName:u().string,handleRequestModalOpen:u().func,handleOpenPageStyleDialog:u().func};const ze=(0,o.memo)(Ae)},9881:(e,t,n)=>{n.d(t,{G:()=>r,f:()=>a});var r="page",a="modal"},6549:(e,t,n)=>{n.d(t,{DE:()=>i,Oh:()=>r,bZ:()=>o,jg:()=>a});var r="clone",a="create",o="edit",i="config"},6057:(e,t,n)=>{n.d(t,{W:()=>s,Z:()=>c});var r=n(885),a=n(7294),o=n(1581),i=n.n(o),l=(0,a.createContext)({rowData:{},setRowData:function(){}});function s(e){var t=e.children,n=(0,a.useState)({}),o=(0,r.Z)(n,2),i=o[0],s=o[1],c=(0,a.useState)(""),u=(0,r.Z)(c,2),d=u[0],p=u[1],f=(0,a.useState)("all"),h=(0,r.Z)(f,2),m=h[0],v=h[1],g=(0,a.useState)(10),y=(0,r.Z)(g,2),b=y[0],E=y[1],k=(0,a.useState)(0),Z=(0,r.Z)(k,2),O=Z[0],C=Z[1];return a.createElement(l.Provider,{value:{rowData:i,setRowData:s,searchText:d,setSearchText:p,searchType:m,setSearchType:v,pageSize:b,setPageSize:E,currentPage:O,setCurrentPage:C}},t)}s.propTypes={children:i().oneOfType([i().arrayOf(i().node),i().node]).isRequired};const c=l},4893:(e,t,n)=>{n.d(t,{Z:()=>a});var r=n(9250);const a=function(){return new URLSearchParams((0,r.TH)().search)}},1263:(e,t,n)=>{n.d(t,{pZ:()=>u,r3:()=>c});var r,a,o,i=n(168),l=n(2788),s=n(5947),c=l.default.div.attrs({className:"pageTitle"})(r||(r=(0,i.Z)(["\n    &.pageTitle {\n        font-size: ",";\n        margin-bottom: 20px;\n    }\n"])),s.variables.fontSizeXXLarge),u=l.default.div.attrs({className:"pageSubtitle"})(a||(a=(0,i.Z)(["\n    &.pageSubtitle {\n        font-size: ",";\n        margin-bottom: 10px;\n    }\n"])),s.variables.fontSize);l.default.div(o||(o=(0,i.Z)(["\n    .table-caption-inner {\n        text-align: left;\n    }\n"])))},2297:(e,t,n)=>{n.d(t,{L:()=>u});var r=n(4942),a=n(1721),o=n(2411),i=n(7212),l=n(4255);function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){(0,r.Z)(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var u=function(e){var t=e.serviceName,n=e.endpointUrl,r=e.params,s=e.body,u=e.cancelToken,d=e.customHeaders,p=void 0===d?{}:d,f=e.method,h=void 0===f?"get":f,m=e.handleError,v=void 0!==m&&m,g=e.callbackOnError,y=void 0===g?function(){}:g,b=t?(0,l.w3)(t):n,E={app:o.app,owner:"nobody"},k={"X-Splunk-Form-Key":o.CSRFToken,"X-Requested-With":"XMLHttpRequest","Content-Type":"application/json"},Z=Object.assign(k,p),O=(0,i.createRESTURL)(b,E),C={output_mode:"json"};r&&(C=c(c({},C),r));var w={params:C,method:h,url:O,credentials:"include",headers:Z,cancelToken:u};return"post"===h&&(w.data=s),v?(0,a.ZP)(w).catch((function(e){var t="";return a.ZP.isCancel(e)||(t=e.response?"Error response received from server: ".concat(e.response.data.messages[0].text):e.request?"No response received while making request to ".concat(b):"Error making ".concat(h," request to ").concat(b),(0,l.Ke)(t,"error"),y(e)),Promise.reject(e)})):(0,a.ZP)(w)}}}]);
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/js/build/772.js b/deployment-apps/metricator-for-nmon/appserver/static/js/build/772.js
    new file mode 100644
    index 0000000..cfb2f94
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/js/build/772.js
    @@ -0,0 +1 @@
    +"use strict";(self.webpackChunk_splunk_ucc_ui_lib=self.webpackChunk_splunk_ucc_ui_lib||[]).push([[772],{6772:(e,n,t)=>{t.r(n),t.d(n,{default:()=>U});var a,r=t(885),l=t(168),c=t(7294),o=t(6219),i=t(2672),u=t.n(i),s=t(1946),m=t.n(s),p=t(1569),d=t.n(p),b=t(2788),f=t(4893),g=t(4255),y=t(1263),E=t(5496),v=t(1581),h=t.n(v),O=t(6416),k=t.n(O),Z=t(5414),j=t.n(Z),S=t(5464),_=t(2297),w=t(6549),N=t(6070),P=t(4843),C=b.default.div(a||(a=(0,l.Z)(["\n    margin-left: 270px !important;\n    width: 150px;\n\n    .save_btn {\n        width: 100%;\n    }\n"])));function T(e){var n=e.serviceName,t=(0,c.useRef)(),a=(0,c.useState)(null),l=(0,r.Z)(a,2),i=l[0],u=l[1],s=(0,c.useState)(!1),m=(0,r.Z)(s,2),p=m[0],d=m[1],b=(0,c.useState)({}),f=(0,r.Z)(b,2),g=f[0],y=f[1];if((0,c.useEffect)((function(){(0,_.L)({serviceName:"settings/".concat(n),handleError:!0,callbackOnError:function(e){e.uccErrorCode="ERR0005",u(e)}}).then((function(e){y(e.data.entry[0].content)}))}),[n]),null!=i&&i.uccErrorCode)throw i;return Object.keys(g).length?c.createElement(c.Fragment,null,c.createElement(S.Z,{ref:t,page:P.y,stanzaName:n,serviceName:"settings",mode:w.DE,currentServiceState:g,handleFormSubmit:function(e){d(e)}}),c.createElement(C,null,c.createElement(k(),{className:"saveBtn",appearance:"primary",label:p?c.createElement(j(),null):(0,o._)("Save"),onClick:function(){t.current.handleSubmit()},disabled:p}))):c.createElement(N.XE,null)}T.propTypes={serviceName:h().string.isRequired};const R=T;var x=t(4942),L=t(6057),D=t(7588),I=t(5792),q=t(3649),z=t(9881);function F(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function A(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?F(Object(t),!0).forEach((function(n){(0,x.Z)(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):F(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function B(e){var n=e.selectedTab,t=e.updateIsPageOpen,a=(0,c.useState)({open:!1}),l=(0,r.Z)(a,2),o=l[0],i=l[1],u=n.style===z.G;return c.createElement(L.W,{value:null},u&&o.open?(t(!0),c.createElement(q.Z,{open:o.open,handleRequestClose:function(){i(A(A({},o),{},{open:!1})),t(!1)},serviceName:n.name,stanzaName:o.stanzaName,mode:o.mode,formLabel:o.formLabel,page:P.y})):null,u&&o.open?null:c.createElement(D.Z,{page:P.y,serviceName:n.name,handleRequestModalOpen:function(){i(A(A({},o),{},{open:!0,mode:w.jg,formLabel:"Add ".concat(n.title)}))},handleOpenPageStyleDialog:function(e,t){i(A(A({},o),{},{open:!0,stanzaName:e.name,formLabel:t===w.Oh?"Clone ".concat(n.title):"Update ".concat(n.title),mode:t}))}}),!u&&o.open?c.createElement(I.Z,{page:P.y,open:o.open,handleRequestClose:function(){i(A(A({},o),{},{open:!1}))},serviceName:n.name,mode:w.jg,formLabel:o.formLabel}):null)}B.propTypes={selectedTab:h().object,updateIsPageOpen:h().func};const G=(0,c.memo)(B);var K,M=(0,b.default)(d().Row)(K||(K=(0,l.Z)(["\n    padding: 5px 0px;\n\n    .dropdown {\n        text-align: right;\n    }\n\n    .input_button {\n        text-align: right;\n        margin-right: 0px;\n    }\n"])));const U=function(){var e=(0,g.YK)().pages.configuration,n=e.title,t=e.description,a=e.tabs,l=a.map((function(e){return e.name})),i=(0,c.useState)(a[0].name),s=(0,r.Z)(i,2),p=s[0],b=s[1],v=(0,c.useState)(!1),h=(0,r.Z)(v,2),O=h[0],k=h[1],Z=(0,f.Z)();(0,c.useEffect)((function(){Z&&l.includes(Z.get("tab"))&&Z.get("tab")!==p&&b(Z.get("tab"))}),[]);var j=(0,c.useCallback)((function(e,n){var t=n.selectedTabId;b(t),k(!1)}),[p]),S=function(e){k(e)};return c.createElement(E.Z,null,c.createElement("div",{style:O?{display:"none"}:{display:"block"}},c.createElement(d(),{gutter:8},c.createElement(M,null,c.createElement(d().Column,{span:9},c.createElement(y.r3,null,(0,o._)(n)),c.createElement(y.pZ,null,(0,o._)(t||""))))),c.createElement(u(),{activeTabId:p,onChange:j},a.map((function(e){return c.createElement(u().Tab,{key:e.name,label:(0,o._)(e.title),tabId:e.name})})))),a.map((function(e){return e.table?c.createElement("div",{key:e.name,style:e.name!==p?{display:"none"}:{display:"block"},id:"".concat(e.name,"Tab")},c.createElement(G,{key:e.name,selectedTab:e,updateIsPageOpen:S})):c.createElement("div",{key:e.name,style:e.name!==p?{display:"none"}:{display:"block"},id:"".concat(e.name,"Tab")},c.createElement(R,{key:e.name,serviceName:e.name}))})),c.createElement(m(),{position:"top-right"}))}}}]);
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/js/build/895.js b/deployment-apps/metricator-for-nmon/appserver/static/js/build/895.js
    new file mode 100644
    index 0000000..4638148
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/js/build/895.js
    @@ -0,0 +1 @@
    +"use strict";(self.webpackChunk_splunk_ucc_ui_lib=self.webpackChunk_splunk_ucc_ui_lib||[]).push([[895],{895:(e,n,t)=>{t.r(n),t.d(n,{default:()=>ne});var a=t(4942),r=t(885),i=t(168),l=t(7294),o=t(9250),c=t(1569),u=t.n(c),s=t(2788),p=t(1946),m=t.n(p),f=t(2672),d=t.n(f),g=t(6219),v=t(4255),h=t(1263),y=t(6057),b=t(6549),E=t(4843),S=t(9881),N=t(1581),k=t.n(N),O=t(6416),Z=t.n(O),C=t(6635),P=t.n(C),_=t(2725),j=t.n(_),w=t(7354),I=t.n(w),R=t(720),q=t.n(R),T=t(9609),x=t(5671),D=t(3144),L=t(7326),M=t(9340),B=t(2963),K=t(1120),z=t(4266);var F=function(e){(0,M.Z)(i,e);var n,t,r=(n=i,t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,a=(0,K.Z)(n);if(t){var r=(0,K.Z)(this).constructor;e=Reflect.construct(a,arguments,r)}else e=a.apply(this,arguments);return(0,B.Z)(this,e)});function i(e){var n;return(0,x.Z)(this,i),n=r.call(this,e),(0,a.Z)((0,L.Z)(n),"setValue",(function(e){n.props.handleChange(e)})),(0,a.Z)((0,L.Z)(n),"loadCustomMenu",(function(){return new Promise((function(e){if("external"===n.props.type)import("".concat((0,z.a)(),"/custom/").concat(n.props.fileName,".js")).then((function(n){var t=n.default;e(t)}));else{var t=(0,v.YK)().meta.name;require(["app/".concat(t,"/js/build/custom/").concat(n.props.fileName)],(function(n){return e(n)}))}}))})),n.state={loading:!0},n.shouldRender=!0,n}return(0,D.Z)(i,[{key:"componentDidMount",value:function(){var e=this,n=(0,v.YK)();this.setState({loading:!0}),this.loadCustomMenu().then((function(t){new t(n,e.el,e.setValue).render(),e.setState({loading:!1})}))}},{key:"shouldComponentUpdate",value:function(e,n){return!(n.loading||!this.shouldRender||(this.shouldRender=!1,0))}},{key:"render",value:function(){var e=this;return l.createElement(l.Fragment,null,this.state.loading&&(0,g._)("Loading..."),l.createElement("span",{ref:function(n){e.el=n},style:{visibility:this.state.loading?"hidden":"visible"}}))}}]),i}(l.Component);F.propTypes={fileName:k().string.isRequired,type:k().string,handleChange:k().func};const Y=F;function A(e){var n=e.handleRequestOpen,t=(0,l.useState)("main_panel"),a=(0,r.Z)(t,2),i=a[0],o=a[1],c=(0,l.useState)("forward"),u=(0,r.Z)(c,2),s=u[0],p=u[1],m=(0,l.useState)(!1),f=(0,r.Z)(m,2),d=f[0],h=f[1],y=(0,l.useState)(!1),b=(0,r.Z)(y,2),E=b[0],S=b[1],N=(0,v.YK)().pages.inputs,k=N.services,O=N.menu,C=N.groupsMenu,_=["clickAway","escapeKey","offScreen","toggleClick","contentClick"],w=l.createElement(Z(),{appearance:"primary",id:"addInputBtn",label:(0,g._)("Create New Input"),isMenu:!0});(0,l.useEffect)((function(){E&&(h(!0),S(!1))}),[d]);var R;return!k||null!=O&&O.src?l.createElement(l.Fragment,null,l.createElement(Y,{fileName:O.src,type:O.type,handleChange:function(e){var t=e.service;n(t)}})):1===k.length?l.createElement(Z(),{label:(0,T.P)(100),appearance:"primary",id:"addInputBtn",onClick:function(){n(k[0].name)}}):l.createElement(P(),{toggle:w,open:d,onRequestClose:function(e){var n=e.reason;h(!_.includes(n))},onRequestOpen:function(){h(!0)}},l.createElement(I(),{activePanelId:i,transition:s,style:{width:"200px"}},(R={main_panel:[]},C?C.forEach((function(e){null!=e&&e.groupServices?(R[e.groupName]=[],e.groupServices.forEach((function(n){R[e.groupName].push({name:n,title:k.find((function(e){return e.name===n})).title,hasSubmenu:!1})})),R.main_panel.push({name:e.groupName,title:e.groupTitle,hasSubmenu:!0})):R.main_panel.push({name:e.groupName,title:e.groupTitle,hasSubmenu:!1})})):R.main_panel=k.map((function(e){return{name:e.name,title:e.title,hasSubmenu:!1}})),function(e){return Object.keys(e).map((function(t){return l.createElement(I().Panel,{key:t,panelId:t},l.createElement(j(),null,"main_panel"!==t&&l.createElement(l.Fragment,null,l.createElement(j().Item,{icon:l.createElement(q(),null),onClick:function(){o("main_panel"),p("backward"),S(!0)}},"Back"),l.createElement(j().Divider,null)),(a=e[t],r=t,a.map((function(e){return null!=e&&e.hasSubmenu?l.createElement(j().Item,{hasSubmenu:!0,key:e.name,onClick:function(){o(e.name),p("forward"),S(!0)}},e.title):l.createElement(j().Item,{key:e.name,onClick:function(){n(e.name,r),S(!1)}},e.title)})))));var a,r}))}(R))))}A.propTypes={handleRequestOpen:k().func};const U=A;var V,G=t(7588),H=t(5792),W=t(5496),J=t(3649),Q=t(4893);function X(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function $(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?X(Object(t),!0).forEach((function(n){(0,a.Z)(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):X(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}var ee=(0,s.default)(u().Row)(V||(V=(0,i.Z)(["\n    padding: 5px 0px;\n\n    .dropdown {\n        text-align: right;\n    }\n\n    .input_button {\n        text-align: right;\n        margin-right: 0px;\n    }\n"])));const ne=function(){var e,n,t=(0,l.useState)({open:!1}),a=(0,r.Z)(t,2),i=a[0],c=a[1],s=(0,v.YK)(),p=s.pages.inputs,f=p.services,N=p.title,k=p.description,O=!!(null===(e=s.pages.inputs)||void 0===e?void 0:e.table),Z=(0,l.useState)(f[0].name),C=(0,r.Z)(Z,2),P=C[0],_=C[1],j=(0,l.useState)((null===(n=f[0])||void 0===n?void 0:n.description)||""),w=(0,r.Z)(j,2),I=w[0],R=w[1],q=(0,l.useState)(f[0].title),T=(0,r.Z)(q,2),x=T[0],D=T[1],L=[b.Oh,b.jg,b.bZ],M=f.map((function(e){return e.name})),B=(0,o.s0)(),K=(0,Q.Z)();(0,l.useEffect)((function(){z(),F()}),[(0,o.TH)().search]);var z=function(){var e=f.find((function(e){return e.name===K.get("service")}));K&&e&&L.includes(K.get("action"))&&!i.open?K.get("action")!==b.jg&&i.stanzaName?c($($({},i),{},{open:!0,isInputPageStyle:!0,serviceName:K.get("service"),mode:K.get("action")})):c($($({},i),{},{open:!0,isInputPageStyle:!0,serviceName:K.get("service"),formLabel:"Create ".concat(null==e?void 0:e.title),mode:b.jg})):K.get("service")&&K.get("action")||!i.open||!i.isInputPageStyle||c($($({},i),{},{open:!1}))},F=function(){K&&M.includes(K.get("service"))&&_(K.get("service"))},Y=function(e,n){var t=f.find((function(n){return n.name===e})),a=t.title,r=t.style===S.G;c($($({},i),{},{open:!0,serviceName:e,mode:b.jg,formLabel:"Add ".concat(a),isInputPageStyle:r,groupName:n})),r&&(K.set("service",e),K.set("action",b.jg),B({search:K.toString()}))},A=function(e,n){var t,a=null===(t=f.find((function(n){return n.name===e.serviceName})))||void 0===t?void 0:t.title;c($($({},i),{},{open:!0,isInputPageStyle:!0,serviceName:e.serviceName,stanzaName:e.name,formLabel:n===b.Oh?"Clone ".concat(a):"Update ".concat(a),mode:n})),K.set("service",e.serviceName),K.set("action",n),B({search:K.toString()})},V=(0,l.useCallback)((function(e,n){var t=n.selectedTabId;_(t);var a=f.find((function(e){return e.name===t}));a&&(R(a.description),D(a.title)),K.delete("action"),K.set("service",t),B({search:K.toString()})}),[P]);return l.createElement(W.Z,null,l.createElement(y.W,{value:null},i.isInputPageStyle&&i.open?l.createElement(J.Z,{open:i.open,handleRequestClose:function(){c($($({},i),{},{open:!1})),K.delete("action"),B({search:K.toString()})},serviceName:i.serviceName,stanzaName:i.stanzaName,mode:i.mode,formLabel:i.formLabel,page:E.b,groupName:i.groupName}):null," ",l.createElement("div",{style:i.isInputPageStyle&&i.open?{display:"none"}:{display:"block"}},l.createElement(u(),{gutter:8},l.createElement(ee,null,l.createElement(u().Column,{span:9},l.createElement(h.r3,null,O?(0,g._)(N||""):(0,g._)(x)),l.createElement(h.pZ,null,O?(0,g._)(k||""):(0,g._)(I||""))),l.createElement(u().Column,{className:"dropdown",span:3},O&&l.createElement(U,{handleRequestOpen:Y})))),O?l.createElement(G.Z,{page:E.b,handleOpenPageStyleDialog:A}):l.createElement(l.Fragment,null,l.createElement(d(),{activeTabId:P,onChange:V},f.map((function(e){return l.createElement(d().Tab,{key:e.name,label:(0,g._)(e.title),tabId:e.name})}))),f.map((function(e){return l.createElement("div",{key:e.name,style:e.name!==P?{display:"none"}:{display:"block"},id:"".concat(e.name,"Tab")},l.createElement(G.Z,{page:E.b,serviceName:e.name,handleRequestModalOpen:function(){return Y(e.name)},handleOpenPageStyleDialog:A}))}))),l.createElement(m(),{position:"top-right"}),!i.isInputPageStyle&&i.open?l.createElement(H.Z,{page:E.b,open:i.open,handleRequestClose:function(){c($($({},i),{},{open:!1}))},serviceName:i.serviceName,mode:b.jg,formLabel:i.formLabel,groupName:i.groupName}):null)))}}}]);
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/js/build/entry_page.js b/deployment-apps/metricator-for-nmon/appserver/static/js/build/entry_page.js
    new file mode 100644
    index 0000000..b2ce8f4
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/js/build/entry_page.js
    @@ -0,0 +1,2 @@
    +/*! For license information please see entry_page.js.LICENSE.txt */
    +(()=>{var __webpack_modules__={1314:(e,t,n)=>{"use strict";n.d(t,{He:()=>u,Ld:()=>_,eC:()=>f,f3:()=>l,iG:()=>c,rS:()=>d,sb:()=>b,ys:()=>a});var r=n(4813),o=n(7294);const i=Symbol.for("Animated:node"),a=e=>e&&e[i],l=(e,t)=>(0,r.dE)(e,i,t),u=e=>e&&e[i]&&e[i].getPayload();class s{constructor(){this.payload=void 0,l(this,this)}getPayload(){return this.payload||[]}}class c extends s{constructor(e){super(),this.done=!0,this.elapsedTime=void 0,this.lastPosition=void 0,this.lastVelocity=void 0,this.v0=void 0,this.durationProgress=0,this._value=e,r.is.num(this._value)&&(this.lastPosition=this._value)}static create(e){return new c(e)}getPayload(){return[this]}getValue(){return this._value}setValue(e,t){return r.is.num(e)&&(this.lastPosition=e,t&&(e=Math.round(e/t)*t,this.done&&(this.lastPosition=e))),this._value!==e&&(this._value=e,!0)}reset(){const{done:e}=this;this.done=!1,r.is.num(this._value)&&(this.elapsedTime=0,this.durationProgress=0,this.lastPosition=this._value,e&&(this.lastVelocity=null),this.v0=null)}}class f extends c{constructor(e){super(0),this._string=null,this._toString=void 0,this._toString=(0,r.mD)({output:[e,e]})}static create(e){return new f(e)}getValue(){let e=this._string;return null==e?this._string=this._toString(this._value):e}setValue(e){if(r.is.str(e)){if(e==this._string)return!1;this._string=e,this._value=1}else{if(!super.setValue(e))return!1;this._string=null}return!0}reset(e){e&&(this._toString=(0,r.mD)({output:[this.getValue(),e]})),this._value=0,super.reset()}}const p={dependencies:null};class d extends s{constructor(e){super(),this.source=e,this.setValue(e)}getValue(e){const t={};return(0,r.rU)(this.source,((n,o)=>{var a;(a=n)&&a[i]===a?t[o]=n.getValue(e):(0,r.j$)(n)?t[o]=(0,r.je)(n):e||(t[o]=n)})),t}setValue(e){this.source=e,this.payload=this._makePayload(e)}reset(){this.payload&&(0,r.S6)(this.payload,(e=>e.reset()))}_makePayload(e){if(e){const t=new Set;return(0,r.rU)(e,this._addToPayload,t),Array.from(t)}}_addToPayload(e){p.dependencies&&(0,r.j$)(e)&&p.dependencies.add(e);const t=u(e);t&&(0,r.S6)(t,(e=>this.add(e)))}}class h extends d{constructor(e){super(e)}static create(e){return new h(e)}getValue(){return this.source.map((e=>e.getValue()))}setValue(e){const t=this.getPayload();return e.length==t.length?t.map(((t,n)=>t.setValue(e[n]))).some(Boolean):(super.setValue(e.map(m)),!0)}}function m(e){return((0,r.Df)(e)?f:c).create(e)}function b(e){const t=a(e);return t?t.constructor:r.is.arr(e)?h:(0,r.Df)(e)?f:c}function y(){return y=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},y.apply(this,arguments)}const g=(e,t)=>{const n=!r.is.fun(e)||e.prototype&&e.prototype.isReactComponent;return(0,o.forwardRef)(((i,a)=>{const l=(0,o.useRef)(null),u=n&&(0,o.useCallback)((e=>{l.current=function(e,t){return e&&(r.is.fun(e)?e(t):e.current=t),t}(a,e)}),[a]),[s,c]=function(e,t){const n=new Set;return p.dependencies=n,e.style&&(e=y({},e,{style:t.createAnimatedStyle(e.style)})),e=new d(e),p.dependencies=null,[e,n]}(i,t),f=(0,r.NW)(),h=()=>{const e=l.current;n&&!e||!1===(!!e&&t.applyAnimatedValues(e,s.getValue(!0)))&&f()},m=new v(h,c),b=(0,o.useRef)();(0,r.LI)((()=>(b.current=m,(0,r.S6)(c,(e=>(0,r.UI)(e,m))),()=>{b.current&&((0,r.S6)(b.current.deps,(e=>(0,r.iL)(e,b.current))),r.Wn.cancel(b.current.update))}))),(0,o.useEffect)(h,[]),(0,r.tf)((()=>()=>{const e=b.current;(0,r.S6)(e.deps,(t=>(0,r.iL)(t,e)))}));const g=t.getComponentProps(s.getValue());return o.createElement(e,y({},g,{ref:u}))}))};class v{constructor(e,t){this.update=e,this.deps=t}eventObserved(e){"change"==e.type&&r.Wn.write(this.update)}}const w=Symbol.for("AnimatedComponent"),_=(e,{applyAnimatedValues:t=(()=>!1),createAnimatedStyle:n=(e=>new d(e)),getComponentProps:o=(e=>e)}={})=>{const i={applyAnimatedValues:t,createAnimatedStyle:n,getComponentProps:o},a=e=>{const t=x(e)||"Anonymous";return(e=r.is.str(e)?a[e]||(a[e]=g(e,i)):e[w]||(e[w]=g(e,i))).displayName=`Animated(${t})`,e};return(0,r.rU)(e,((t,n)=>{r.is.arr(e)&&(n=x(t)),a[n]=a(t)})),{animated:a}},x=e=>r.is.str(e)?e:e&&r.is.str(e.displayName)?e.displayName:r.is.fun(e)&&e.name||null},4928:(e,t,n)=>{"use strict";n.r(t),n.d(t,{BailSignal:()=>W,Controller:()=>de,FrameValue:()=>Q,Globals:()=>r.OH,Interpolation:()=>Ue,Spring:()=>Ne,SpringContext:()=>Oe,SpringRef:()=>Ce,SpringValue:()=>ne,Trail:()=>qe,Transition:()=>Be,config:()=>k,createInterpolator:()=>r.mD,easings:()=>L,inferTo:()=>g,interpolate:()=>Ke,to:()=>Ze,update:()=>Qe,useChain:()=>S,useIsomorphicLayoutEffect:()=>r.LI,useReducedMotion:()=>r.JZ,useSpring:()=>Pe,useSpringRef:()=>Te,useSprings:()=>Ee,useTrail:()=>Le,useTransition:()=>Me});var r=n(4813),o=n(7294),i=n(1314),a=n(6233),l={};for(const e in a)["default","Globals","createInterpolator","useIsomorphicLayoutEffect","useReducedMotion","BailSignal","Controller","FrameValue","Interpolation","Spring","SpringContext","SpringRef","SpringValue","Trail","Transition","config","easings","inferTo","interpolate","to","update","useChain","useSpring","useSpringRef","useSprings","useTrail","useTransition"].indexOf(e)<0&&(l[e]=()=>a[e]);n.d(t,l);var u=n(8716);l={};for(const e in u)["default","Globals","createInterpolator","useIsomorphicLayoutEffect","useReducedMotion","BailSignal","Controller","FrameValue","Interpolation","Spring","SpringContext","SpringRef","SpringValue","Trail","Transition","config","easings","inferTo","interpolate","to","update","useChain","useSpring","useSpringRef","useSprings","useTrail","useTransition"].indexOf(e)<0&&(l[e]=()=>u[e]);function s(){return s=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e,...t){return r.is.fun(e)?e(...t):e}n.d(t,l);const f=(e,t)=>!0===e||!!(t&&e&&(r.is.fun(e)?e(t):(0,r.qo)(e).includes(t))),p=(e,t)=>r.is.obj(e)?t&&e[t]:e,d=(e,t)=>!0===e.default?e[t]:e.default?e.default[t]:void 0,h=e=>e,m=(e,t=h)=>{let n=b;e.default&&!0!==e.default&&(e=e.default,n=Object.keys(e));const o={};for(const i of n){const n=t(e[i],i);r.is.und(n)||(o[i]=n)}return o},b=["config","onProps","onStart","onChange","onPause","onResume","onRest"],y={config:1,from:1,to:1,ref:1,loop:1,reset:1,pause:1,cancel:1,reverse:1,immediate:1,default:1,delay:1,onProps:1,onStart:1,onChange:1,onPause:1,onResume:1,onRest:1,onResolve:1,items:1,trail:1,sort:1,expires:1,initial:1,enter:1,update:1,leave:1,children:1,onDestroyed:1,keys:1,callId:1,parentId:1};function g(e){const t=function(e){const t={};let n=0;if((0,r.rU)(e,((e,r)=>{y[r]||(t[r]=e,n++)})),n)return t}(e);if(t){const n={to:t};return(0,r.rU)(e,((e,r)=>r in t||(n[r]=e))),n}return s({},e)}function v(e){return e=(0,r.je)(e),r.is.arr(e)?e.map(v):(0,r.Df)(e)?r.OH.createStringInterpolator({range:[0,1],output:[e,e]})(1):e}function w(e){for(const t in e)return!0;return!1}function _(e){return r.is.fun(e)||r.is.arr(e)&&r.is.obj(e[0])}function x(e,t){var n;null==(n=e.ref)||n.delete(e),null==t||t.delete(e)}function O(e,t){var n;t&&e.ref!==t&&(null==(n=e.ref)||n.delete(e),t.add(e),e.ref=t)}function S(e,t,n=1e3){(0,r.LI)((()=>{if(t){let o=0;(0,r.S6)(e,((e,i)=>{const a=e.current;if(a.length){let l=n*t[i];isNaN(l)?l=o:o=l,(0,r.S6)(a,(e=>{(0,r.S6)(e.queue,(e=>{const t=e.delay;e.delay=e=>l+c(t||0,e)}))})),e.start()}}))}else{let t=Promise.resolve();(0,r.S6)(e,(e=>{const n=e.current;if(n.length){const o=n.map((e=>{const t=e.queue;return e.queue=[],t}));t=t.then((()=>((0,r.S6)(n,((e,t)=>(0,r.S6)(o[t]||[],(t=>e.queue.push(t))))),Promise.all(e.start()))))}}))}}))}const k={default:{tension:170,friction:26},gentle:{tension:120,friction:14},wobbly:{tension:180,friction:12},stiff:{tension:210,friction:20},slow:{tension:280,friction:60},molasses:{tension:280,friction:120}},j=1.70158,C=1.525*j,E=j+1,P=2*Math.PI/3,A=2*Math.PI/4.5,T=e=>{const t=7.5625,n=2.75;return e<1/n?t*e*e:e<2/n?t*(e-=1.5/n)*e+.75:e<2.5/n?t*(e-=2.25/n)*e+.9375:t*(e-=2.625/n)*e+.984375},L={linear:e=>e,easeInQuad:e=>e*e,easeOutQuad:e=>1-(1-e)*(1-e),easeInOutQuad:e=>e<.5?2*e*e:1-Math.pow(-2*e+2,2)/2,easeInCubic:e=>e*e*e,easeOutCubic:e=>1-Math.pow(1-e,3),easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,easeInQuart:e=>e*e*e*e,easeOutQuart:e=>1-Math.pow(1-e,4),easeInOutQuart:e=>e<.5?8*e*e*e*e:1-Math.pow(-2*e+2,4)/2,easeInQuint:e=>e*e*e*e*e,easeOutQuint:e=>1-Math.pow(1-e,5),easeInOutQuint:e=>e<.5?16*e*e*e*e*e:1-Math.pow(-2*e+2,5)/2,easeInSine:e=>1-Math.cos(e*Math.PI/2),easeOutSine:e=>Math.sin(e*Math.PI/2),easeInOutSine:e=>-(Math.cos(Math.PI*e)-1)/2,easeInExpo:e=>0===e?0:Math.pow(2,10*e-10),easeOutExpo:e=>1===e?1:1-Math.pow(2,-10*e),easeInOutExpo:e=>0===e?0:1===e?1:e<.5?Math.pow(2,20*e-10)/2:(2-Math.pow(2,-20*e+10))/2,easeInCirc:e=>1-Math.sqrt(1-Math.pow(e,2)),easeOutCirc:e=>Math.sqrt(1-Math.pow(e-1,2)),easeInOutCirc:e=>e<.5?(1-Math.sqrt(1-Math.pow(2*e,2)))/2:(Math.sqrt(1-Math.pow(-2*e+2,2))+1)/2,easeInBack:e=>E*e*e*e-j*e*e,easeOutBack:e=>1+E*Math.pow(e-1,3)+j*Math.pow(e-1,2),easeInOutBack:e=>e<.5?Math.pow(2*e,2)*(7.189819*e-C)/2:(Math.pow(2*e-2,2)*((C+1)*(2*e-2)+C)+2)/2,easeInElastic:e=>0===e?0:1===e?1:-Math.pow(2,10*e-10)*Math.sin((10*e-10.75)*P),easeOutElastic:e=>0===e?0:1===e?1:Math.pow(2,-10*e)*Math.sin((10*e-.75)*P)+1,easeInOutElastic:e=>0===e?0:1===e?1:e<.5?-Math.pow(2,20*e-10)*Math.sin((20*e-11.125)*A)/2:Math.pow(2,-20*e+10)*Math.sin((20*e-11.125)*A)/2+1,easeInBounce:e=>1-T(1-e),easeOutBounce:T,easeInOutBounce:e=>e<.5?(1-T(1-2*e))/2:(1+T(2*e-1))/2},R=s({},k.default,{mass:1,damping:1,easing:L.linear,clamp:!1});class M{constructor(){this.tension=void 0,this.friction=void 0,this.frequency=void 0,this.damping=void 0,this.mass=void 0,this.velocity=0,this.restVelocity=void 0,this.precision=void 0,this.progress=void 0,this.duration=void 0,this.easing=void 0,this.clamp=void 0,this.bounce=void 0,this.decay=void 0,this.round=void 0,Object.assign(this,R)}}function D(e,t){if(r.is.und(t.decay)){const n=!r.is.und(t.tension)||!r.is.und(t.friction);!n&&r.is.und(t.frequency)&&r.is.und(t.damping)&&r.is.und(t.mass)||(e.duration=void 0,e.decay=void 0),n&&(e.frequency=void 0)}else e.duration=void 0}const I=[];class F{constructor(){this.changed=!1,this.values=I,this.toValues=null,this.fromValues=I,this.to=void 0,this.from=void 0,this.config=new M,this.immediate=!1}}function N(e,{key:t,props:n,defaultProps:o,state:i,actions:a}){return new Promise(((l,u)=>{var p;let d,h,m=f(null!=(p=n.cancel)?p:null==o?void 0:o.cancel,t);if(m)g();else{r.is.und(n.pause)||(i.paused=f(n.pause,t));let e=null==o?void 0:o.pause;!0!==e&&(e=i.paused||f(e,t)),d=c(n.delay||0,t),e?(i.resumeQueue.add(y),a.pause()):(a.resume(),y())}function b(){i.resumeQueue.add(y),i.timeouts.delete(h),h.cancel(),d=h.time-r.Wn.now()}function y(){d>0&&!r.OH.skipAnimation?(i.delayed=!0,h=r.Wn.setTimeout(g,d),i.pauseQueue.add(b),i.timeouts.add(h)):g()}function g(){i.delayed&&(i.delayed=!1),i.pauseQueue.delete(b),i.timeouts.delete(h),e<=(i.cancelId||0)&&(m=!0);try{a.start(s({},n,{callId:e,cancel:m}),l)}catch(e){u(e)}}}))}const z=(e,t)=>1==t.length?t[0]:t.some((e=>e.cancelled))?B(e.get()):t.every((e=>e.noop))?q(e.get()):$(e.get(),t.every((e=>e.finished))),q=e=>({value:e,noop:!0,finished:!0,cancelled:!1}),$=(e,t,n=!1)=>({value:e,finished:t,cancelled:n}),B=e=>({value:e,cancelled:!0,finished:!1});function U(e,t,n,o){const{callId:i,parentId:a,onRest:l}=t,{asyncTo:u,promise:c}=n;return a||e!==u||t.reset?n.promise=(async()=>{n.asyncId=i,n.asyncTo=e;const f=m(t,((e,t)=>"onRest"===t?void 0:e));let p,d;const h=new Promise(((e,t)=>(p=e,d=t))),b=e=>{const t=i<=(n.cancelId||0)&&B(o)||i!==n.asyncId&&$(o,!1);if(t)throw e.result=t,d(e),e},y=(e,t)=>{const a=new W,l=new H;return(async()=>{if(r.OH.skipAnimation)throw V(n),l.result=$(o,!1),d(l),l;b(a);const u=r.is.obj(e)?s({},e):s({},t,{to:e});u.parentId=i,(0,r.rU)(f,((e,t)=>{r.is.und(u[t])&&(u[t]=e)}));const c=await o.start(u);return b(a),n.paused&&await new Promise((e=>{n.resumeQueue.add(e)})),c})()};let g;if(r.OH.skipAnimation)return V(n),$(o,!1);try{let t;t=r.is.arr(e)?(async e=>{for(const t of e)await y(t)})(e):Promise.resolve(e(y,o.stop.bind(o))),await Promise.all([t.then(p),h]),g=$(o.get(),!0,!1)}catch(e){if(e instanceof W)g=e.result;else{if(!(e instanceof H))throw e;g=e.result}}finally{i==n.asyncId&&(n.asyncId=a,n.asyncTo=a?u:void 0,n.promise=a?c:void 0)}return r.is.fun(l)&&r.Wn.batchedUpdates((()=>{l(g,o,o.item)})),g})():c}function V(e,t){(0,r.yl)(e.timeouts,(e=>e.cancel())),e.pauseQueue.clear(),e.resumeQueue.clear(),e.asyncId=e.asyncTo=e.promise=void 0,t&&(e.cancelId=t)}class W extends Error{constructor(){super("An async animation has been interrupted. You see this error because you forgot to use `await` or `.catch(...)` on its returned promise."),this.result=void 0}}class H extends Error{constructor(){super("SkipAnimationSignal"),this.result=void 0}}const Z=e=>e instanceof Q;let K=1;class Q extends r.B0{constructor(...e){super(...e),this.id=K++,this.key=void 0,this._priority=0}get priority(){return this._priority}set priority(e){this._priority!=e&&(this._priority=e,this._onPriorityChange(e))}get(){const e=(0,i.ys)(this);return e&&e.getValue()}to(...e){return r.OH.to(this,e)}interpolate(...e){return(0,r.LW)(),r.OH.to(this,e)}toJSON(){return this.get()}observerAdded(e){1==e&&this._attach()}observerRemoved(e){0==e&&this._detach()}_attach(){}_detach(){}_onChange(e,t=!1){(0,r.k0)(this,{type:"change",parent:this,value:e,idle:t})}_onPriorityChange(e){this.idle||r.fT.sort(this),(0,r.k0)(this,{type:"priority",parent:this,priority:e})}}const G=Symbol.for("SpringPhase"),X=e=>(1&e[G])>0,Y=e=>(2&e[G])>0,J=e=>(4&e[G])>0,ee=(e,t)=>t?e[G]|=3:e[G]&=-3,te=(e,t)=>t?e[G]|=4:e[G]&=-5;class ne extends Q{constructor(e,t){if(super(),this.key=void 0,this.animation=new F,this.queue=void 0,this.defaultProps={},this._state={paused:!1,delayed:!1,pauseQueue:new Set,resumeQueue:new Set,timeouts:new Set},this._pendingCalls=new Set,this._lastCallId=0,this._lastToId=0,this._memoizedDuration=0,!r.is.und(e)||!r.is.und(t)){const n=r.is.obj(e)?s({},e):s({},t,{from:e});r.is.und(n.default)&&(n.default=!0),this.start(n)}}get idle(){return!(Y(this)||this._state.asyncTo)||J(this)}get goal(){return(0,r.je)(this.animation.to)}get velocity(){const e=(0,i.ys)(this);return e instanceof i.iG?e.lastVelocity||0:e.getPayload().map((e=>e.lastVelocity||0))}get hasAnimated(){return X(this)}get isAnimating(){return Y(this)}get isPaused(){return J(this)}get isDelayed(){return this._state.delayed}advance(e){let t=!0,n=!1;const o=this.animation;let{config:a,toValues:l}=o;const u=(0,i.He)(o.to);!u&&(0,r.j$)(o.to)&&(l=(0,r.qo)((0,r.je)(o.to))),o.values.forEach(((s,c)=>{if(s.done)return;const f=s.constructor==i.eC?1:u?u[c].lastPosition:l[c];let p=o.immediate,d=f;if(!p){if(d=s.lastPosition,a.tension<=0)return void(s.done=!0);let t=s.elapsedTime+=e;const n=o.fromValues[c],i=null!=s.v0?s.v0:s.v0=r.is.arr(a.velocity)?a.velocity[c]:a.velocity;let l;const u=a.precision||(n==f?.005:Math.min(1,.001*Math.abs(f-n)));if(r.is.und(a.duration))if(a.decay){const e=!0===a.decay?.998:a.decay,r=Math.exp(-(1-e)*t);d=n+i/(1-e)*(1-r),p=Math.abs(s.lastPosition-d)<=u,l=i*r}else{l=null==s.lastVelocity?i:s.lastVelocity;const t=a.restVelocity||u/10,o=a.clamp?0:a.bounce,c=!r.is.und(o),h=n==f?s.v0>0:n<f;let m,b=!1;const y=1,g=Math.ceil(e/y);for(let e=0;e<g&&(m=Math.abs(l)>t,m||(p=Math.abs(f-d)<=u,!p));++e)c&&(b=d==f||d>f==h,b&&(l=-l*o,d=f)),l+=(1e-6*-a.tension*(d-f)+.001*-a.friction*l)/a.mass*y,d+=l*y}else{let r=1;a.duration>0&&(this._memoizedDuration!==a.duration&&(this._memoizedDuration=a.duration,s.durationProgress>0&&(s.elapsedTime=a.duration*s.durationProgress,t=s.elapsedTime+=e)),r=(a.progress||0)+t/this._memoizedDuration,r=r>1?1:r<0?0:r,s.durationProgress=r),d=n+a.easing(r)*(f-n),l=(d-s.lastPosition)/e,p=1==r}s.lastVelocity=l,Number.isNaN(d)&&(console.warn("Got NaN while animating:",this),p=!0)}u&&!u[c].done&&(p=!1),p?s.done=!0:t=!1,s.setValue(d,a.round)&&(n=!0)}));const s=(0,i.ys)(this),c=s.getValue();if(t){const e=(0,r.je)(o.to);c===e&&!n||a.decay?n&&a.decay&&this._onChange(c):(s.setValue(e),this._onChange(e)),this._stop()}else n&&this._onChange(c)}set(e){return r.Wn.batchedUpdates((()=>{this._stop(),this._focus(e),this._set(e)})),this}pause(){this._update({pause:!0})}resume(){this._update({pause:!1})}finish(){if(Y(this)){const{to:e,config:t}=this.animation;r.Wn.batchedUpdates((()=>{this._onStart(),t.decay||this._set(e,!1),this._stop()}))}return this}update(e){return(this.queue||(this.queue=[])).push(e),this}start(e,t){let n;return r.is.und(e)?(n=this.queue||[],this.queue=[]):n=[r.is.obj(e)?e:s({},t,{to:e})],Promise.all(n.map((e=>this._update(e)))).then((e=>z(this,e)))}stop(e){const{to:t}=this.animation;return this._focus(this.get()),V(this._state,e&&this._lastCallId),r.Wn.batchedUpdates((()=>this._stop(t,e))),this}reset(){this._update({reset:!0})}eventObserved(e){"change"==e.type?this._start():"priority"==e.type&&(this.priority=e.priority+1)}_prepareNode(e){const t=this.key||"";let{to:n,from:o}=e;n=r.is.obj(n)?n[t]:n,(null==n||_(n))&&(n=void 0),o=r.is.obj(o)?o[t]:o,null==o&&(o=void 0);const a={to:n,from:o};return X(this)||(e.reverse&&([n,o]=[o,n]),o=(0,r.je)(o),r.is.und(o)?(0,i.ys)(this)||this._set(n):this._set(o)),a}_update(e,t){let n=s({},e);const{key:o,defaultProps:i}=this;n.default&&Object.assign(i,m(n,((e,t)=>/^on/.test(t)?p(e,o):e))),se(this,n,"onProps"),ce(this,"onProps",n,this);const a=this._prepareNode(n);if(Object.isFrozen(this))throw Error("Cannot animate a `SpringValue` object that is frozen. Did you forget to pass your component to `animated(...)` before animating its props?");const l=this._state;return N(++this._lastCallId,{key:o,props:n,defaultProps:i,state:l,actions:{pause:()=>{J(this)||(te(this,!0),(0,r.bl)(l.pauseQueue),ce(this,"onPause",$(this,re(this,this.animation.to)),this))},resume:()=>{J(this)&&(te(this,!1),Y(this)&&this._resume(),(0,r.bl)(l.resumeQueue),ce(this,"onResume",$(this,re(this,this.animation.to)),this))},start:this._merge.bind(this,a)}}).then((e=>{if(n.loop&&e.finished&&(!t||!e.noop)){const e=oe(n);if(e)return this._update(e,!0)}return e}))}_merge(e,t,n){if(t.cancel)return this.stop(!0),n(B(this));const o=!r.is.und(e.to),a=!r.is.und(e.from);if(o||a){if(!(t.callId>this._lastToId))return n(B(this));this._lastToId=t.callId}const{key:l,defaultProps:u,animation:p}=this,{to:d,from:h}=p;let{to:m=d,from:b=h}=e;!a||o||t.default&&!r.is.und(m)||(m=b),t.reverse&&([m,b]=[b,m]);const y=!(0,r.Xy)(b,h);y&&(p.from=b),b=(0,r.je)(b);const g=!(0,r.Xy)(m,d);g&&this._focus(m);const w=_(t.to),{config:x}=p,{decay:O,velocity:S}=x;(o||a)&&(x.velocity=0),t.config&&!w&&function(e,t,n){n&&(D(n=s({},n),t),t=s({},n,t)),D(e,t),Object.assign(e,t);for(const t in R)null==e[t]&&(e[t]=R[t]);let{mass:o,frequency:i,damping:a}=e;r.is.und(i)||(i<.01&&(i=.01),a<0&&(a=0),e.tension=Math.pow(2*Math.PI/i,2)*o,e.friction=4*Math.PI*a*o/i)}(x,c(t.config,l),t.config!==u.config?c(u.config,l):void 0);let k=(0,i.ys)(this);if(!k||r.is.und(m))return n($(this,!0));const j=r.is.und(t.reset)?a&&!t.default:!r.is.und(b)&&f(t.reset,l),C=j?b:this.get(),E=v(m),P=r.is.num(E)||r.is.arr(E)||(0,r.Df)(E),A=!w&&(!P||f(u.immediate||t.immediate,l));if(g){const e=(0,i.sb)(m);if(e!==k.constructor){if(!A)throw Error(`Cannot animate between ${k.constructor.name} and ${e.name}, as the "to" prop suggests`);k=this._set(E)}}const T=k.constructor;let L=(0,r.j$)(m),M=!1;if(!L){const e=j||!X(this)&&y;(g||e)&&(M=(0,r.Xy)(v(C),E),L=!M),((0,r.Xy)(p.immediate,A)||A)&&(0,r.Xy)(x.decay,O)&&(0,r.Xy)(x.velocity,S)||(L=!0)}if(M&&Y(this)&&(p.changed&&!j?L=!0:L||this._stop(d)),!w&&((L||(0,r.j$)(d))&&(p.values=k.getPayload(),p.toValues=(0,r.j$)(m)?null:T==i.eC?[1]:(0,r.qo)(E)),p.immediate!=A&&(p.immediate=A,A||j||this._set(d)),L)){const{onRest:e}=p;(0,r.S6)(ue,(e=>se(this,t,e)));const o=$(this,re(this,d));(0,r.bl)(this._pendingCalls,o),this._pendingCalls.add(n),p.changed&&r.Wn.batchedUpdates((()=>{p.changed=!j,null==e||e(o,this),j?c(u.onRest,o):null==p.onStart||p.onStart(o,this)}))}j&&this._set(C),w?n(U(t.to,t,this._state,this)):L?this._start():Y(this)&&!g?this._pendingCalls.add(n):n(q(C))}_focus(e){const t=this.animation;e!==t.to&&((0,r.Ll)(this)&&this._detach(),t.to=e,(0,r.Ll)(this)&&this._attach())}_attach(){let e=0;const{to:t}=this.animation;(0,r.j$)(t)&&((0,r.UI)(t,this),Z(t)&&(e=t.priority+1)),this.priority=e}_detach(){const{to:e}=this.animation;(0,r.j$)(e)&&(0,r.iL)(e,this)}_set(e,t=!0){const n=(0,r.je)(e);if(!r.is.und(n)){const e=(0,i.ys)(this);if(!e||!(0,r.Xy)(n,e.getValue())){const o=(0,i.sb)(n);e&&e.constructor==o?e.setValue(n):(0,i.f3)(this,o.create(n)),e&&r.Wn.batchedUpdates((()=>{this._onChange(n,t)}))}}return(0,i.ys)(this)}_onStart(){const e=this.animation;e.changed||(e.changed=!0,ce(this,"onStart",$(this,re(this,e.to)),this))}_onChange(e,t){t||(this._onStart(),c(this.animation.onChange,e,this)),c(this.defaultProps.onChange,e,this),super._onChange(e,t)}_start(){const e=this.animation;(0,i.ys)(this).reset((0,r.je)(e.to)),e.immediate||(e.fromValues=e.values.map((e=>e.lastPosition))),Y(this)||(ee(this,!0),J(this)||this._resume())}_resume(){r.OH.skipAnimation?this.finish():r.fT.start(this)}_stop(e,t){if(Y(this)){ee(this,!1);const n=this.animation;(0,r.S6)(n.values,(e=>{e.done=!0})),n.toValues&&(n.onChange=n.onPause=n.onResume=void 0),(0,r.k0)(this,{type:"idle",parent:this});const o=t?B(this.get()):$(this.get(),re(this,null!=e?e:n.to));(0,r.bl)(this._pendingCalls,o),n.changed&&(n.changed=!1,ce(this,"onRest",o,this))}}}function re(e,t){const n=v(t),o=v(e.get());return(0,r.Xy)(o,n)}function oe(e,t=e.loop,n=e.to){let r=c(t);if(r){const o=!0!==r&&g(r),i=(o||e).reverse,a=!o||o.reset;return ie(s({},e,{loop:t,default:!1,pause:void 0,to:!i||_(n)?n:void 0,from:a?e.from:void 0,reset:a},o))}}function ie(e){const{to:t,from:n}=e=g(e),o=new Set;return r.is.obj(t)&&le(t,o),r.is.obj(n)&&le(n,o),e.keys=o.size?Array.from(o):null,e}function ae(e){const t=ie(e);return r.is.und(t.default)&&(t.default=m(t)),t}function le(e,t){(0,r.rU)(e,((e,n)=>null!=e&&t.add(n)))}const ue=["onStart","onRest","onChange","onPause","onResume"];function se(e,t,n){e.animation[n]=t[n]!==d(t,n)?p(t[n],e.key):void 0}function ce(e,t,...n){var r,o,i,a;null==(r=(o=e.animation)[t])||r.call(o,...n),null==(i=(a=e.defaultProps)[t])||i.call(a,...n)}const fe=["onStart","onChange","onRest"];let pe=1;class de{constructor(e,t){this.id=pe++,this.springs={},this.queue=[],this.ref=void 0,this._flush=void 0,this._initialProps=void 0,this._lastAsyncId=0,this._active=new Set,this._changed=new Set,this._started=!1,this._item=void 0,this._state={paused:!1,pauseQueue:new Set,resumeQueue:new Set,timeouts:new Set},this._events={onStart:new Map,onChange:new Map,onRest:new Map},this._onFrame=this._onFrame.bind(this),t&&(this._flush=t),e&&this.start(s({default:!0},e))}get idle(){return!this._state.asyncTo&&Object.values(this.springs).every((e=>e.idle&&!e.isDelayed&&!e.isPaused))}get item(){return this._item}set item(e){this._item=e}get(){const e={};return this.each(((t,n)=>e[n]=t.get())),e}set(e){for(const t in e){const n=e[t];r.is.und(n)||this.springs[t].set(n)}}update(e){return e&&this.queue.push(ie(e)),this}start(e){let{queue:t}=this;return e?t=(0,r.qo)(e).map(ie):this.queue=[],this._flush?this._flush(this,t):(we(this,t),he(this,t))}stop(e,t){if(e!==!!e&&(t=e),t){const n=this.springs;(0,r.S6)((0,r.qo)(t),(t=>n[t].stop(!!e)))}else V(this._state,this._lastAsyncId),this.each((t=>t.stop(!!e)));return this}pause(e){if(r.is.und(e))this.start({pause:!0});else{const t=this.springs;(0,r.S6)((0,r.qo)(e),(e=>t[e].pause()))}return this}resume(e){if(r.is.und(e))this.start({pause:!1});else{const t=this.springs;(0,r.S6)((0,r.qo)(e),(e=>t[e].resume()))}return this}each(e){(0,r.rU)(this.springs,e)}_onFrame(){const{onStart:e,onChange:t,onRest:n}=this._events,o=this._active.size>0,i=this._changed.size>0;(o&&!this._started||i&&!this._started)&&(this._started=!0,(0,r.yl)(e,(([e,t])=>{t.value=this.get(),e(t,this,this._item)})));const a=!o&&this._started,l=i||a&&n.size?this.get():null;i&&t.size&&(0,r.yl)(t,(([e,t])=>{t.value=l,e(t,this,this._item)})),a&&(this._started=!1,(0,r.yl)(n,(([e,t])=>{t.value=l,e(t,this,this._item)})))}eventObserved(e){if("change"==e.type)this._changed.add(e.parent),e.idle||this._active.add(e.parent);else{if("idle"!=e.type)return;this._active.delete(e.parent)}r.Wn.onFrame(this._onFrame)}}function he(e,t){return Promise.all(t.map((t=>me(e,t)))).then((t=>z(e,t)))}async function me(e,t,n){const{keys:o,to:i,from:a,loop:l,onRest:u,onResolve:s}=t,c=r.is.obj(t.default)&&t.default;l&&(t.loop=!1),!1===i&&(t.to=null),!1===a&&(t.from=null);const f=r.is.arr(i)||r.is.fun(i)?i:void 0;f?(t.to=void 0,t.onRest=void 0,c&&(c.onRest=void 0)):(0,r.S6)(fe,(n=>{const o=t[n];if(r.is.fun(o)){const r=e._events[n];t[n]=({finished:e,cancelled:t})=>{const n=r.get(o);n?(e||(n.finished=!1),t&&(n.cancelled=!0)):r.set(o,{value:null,finished:e||!1,cancelled:t||!1})},c&&(c[n]=t[n])}}));const p=e._state;t.pause===!p.paused?(p.paused=t.pause,(0,r.bl)(t.pause?p.pauseQueue:p.resumeQueue)):p.paused&&(t.pause=!0);const h=(o||Object.keys(e.springs)).map((n=>e.springs[n].start(t))),m=!0===t.cancel||!0===d(t,"cancel");(f||m&&p.asyncId)&&h.push(N(++e._lastAsyncId,{props:t,state:p,actions:{pause:r.ZT,resume:r.ZT,start(t,n){m?(V(p,e._lastAsyncId),n(B(e))):(t.onRest=u,n(U(f,t,p,e)))}}})),p.paused&&await new Promise((e=>{p.resumeQueue.add(e)}));const b=z(e,await Promise.all(h));if(l&&b.finished&&(!n||!b.noop)){const n=oe(t,l,i);if(n)return we(e,[n]),me(e,n,!0)}return s&&r.Wn.batchedUpdates((()=>s(b,e,e.item))),b}function be(e,t){const n=s({},e.springs);return t&&(0,r.S6)((0,r.qo)(t),(e=>{r.is.und(e.keys)&&(e=ie(e)),r.is.obj(e.to)||(e=s({},e,{to:void 0})),ve(n,e,(e=>ge(e)))})),ye(e,n),n}function ye(e,t){(0,r.rU)(t,((t,n)=>{e.springs[n]||(e.springs[n]=t,(0,r.UI)(t,e))}))}function ge(e,t){const n=new ne;return n.key=e,t&&(0,r.UI)(n,t),n}function ve(e,t,n){t.keys&&(0,r.S6)(t.keys,(r=>{(e[r]||(e[r]=n(r)))._prepareNode(t)}))}function we(e,t){(0,r.S6)(t,(t=>{ve(e.springs,t,(t=>ge(t,e)))}))}function _e(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}const xe=["children"],Oe=e=>{let{children:t}=e,n=_e(e,xe);const i=(0,o.useContext)(Se),a=n.pause||!!i.pause,l=n.immediate||!!i.immediate;n=(0,r.Pr)((()=>({pause:a,immediate:l})),[a,l]);const{Provider:u}=Se;return o.createElement(u,{value:n},t)},Se=(ke=Oe,je={},Object.assign(ke,o.createContext(je)),ke.Provider._context=ke,ke.Consumer._context=ke,ke);var ke,je;Oe.Provider=Se.Provider,Oe.Consumer=Se.Consumer;const Ce=()=>{const e=[],t=function(t){(0,r.ZR)();const o=[];return(0,r.S6)(e,((e,i)=>{if(r.is.und(t))o.push(e.start());else{const r=n(t,e,i);r&&o.push(e.start(r))}})),o};t.current=e,t.add=function(t){e.includes(t)||e.push(t)},t.delete=function(t){const n=e.indexOf(t);~n&&e.splice(n,1)},t.pause=function(){return(0,r.S6)(e,(e=>e.pause(...arguments))),this},t.resume=function(){return(0,r.S6)(e,(e=>e.resume(...arguments))),this},t.set=function(t){(0,r.S6)(e,(e=>e.set(t)))},t.start=function(t){const n=[];return(0,r.S6)(e,((e,o)=>{if(r.is.und(t))n.push(e.start());else{const r=this._getProps(t,e,o);r&&n.push(e.start(r))}})),n},t.stop=function(){return(0,r.S6)(e,(e=>e.stop(...arguments))),this},t.update=function(t){return(0,r.S6)(e,((e,n)=>e.update(this._getProps(t,e,n)))),this};const n=function(e,t,n){return r.is.fun(e)?e(n,t):e};return t._getProps=n,t};function Ee(e,t,n){const i=r.is.fun(t)&&t;i&&!n&&(n=[]);const a=(0,o.useMemo)((()=>i||3==arguments.length?Ce():void 0),[]),l=(0,o.useRef)(0),u=(0,r.NW)(),c=(0,o.useMemo)((()=>({ctrls:[],queue:[],flush(e,t){const n=be(e,t);return l.current>0&&!c.queue.length&&!Object.keys(n).some((t=>!e.springs[t]))?he(e,t):new Promise((r=>{ye(e,n),c.queue.push((()=>{r(he(e,t))})),u()}))}})),[]),f=(0,o.useRef)([...c.ctrls]),p=[],d=(0,r.zH)(e)||0;function h(e,n){for(let r=e;r<n;r++){const e=f.current[r]||(f.current[r]=new de(null,c.flush)),n=i?i(r,e):t[r];n&&(p[r]=ae(n))}}(0,o.useMemo)((()=>{(0,r.S6)(f.current.slice(e,d),(e=>{x(e,a),e.stop(!0)})),f.current.length=e,h(d,e)}),[e]),(0,o.useMemo)((()=>{h(0,Math.min(d,e))}),n);const m=f.current.map(((e,t)=>be(e,p[t]))),b=(0,o.useContext)(Oe),y=(0,r.zH)(b),g=b!==y&&w(b);(0,r.LI)((()=>{l.current++,c.ctrls=f.current;const{queue:e}=c;e.length&&(c.queue=[],(0,r.S6)(e,(e=>e()))),(0,r.S6)(f.current,((e,t)=>{null==a||a.add(e),g&&e.start({default:b});const n=p[t];n&&(O(e,n.ref),e.ref?e.queue.push(n):e.start(n))}))})),(0,r.tf)((()=>()=>{(0,r.S6)(c.ctrls,(e=>e.stop(!0)))}));const v=m.map((e=>s({},e)));return a?[v,a]:v}function Pe(e,t){const n=r.is.fun(e),[[o],i]=Ee(1,n?e:[e],n?t||[]:t);return n||2==arguments.length?[o,i]:o}const Ae=()=>Ce(),Te=()=>(0,o.useState)(Ae)[0];function Le(e,t,n){var o;const i=r.is.fun(t)&&t;i&&!n&&(n=[]);let a,l=!0;const u=Ee(e,((e,n)=>{const r=i?i(e,n):t;return a=r.ref,l=l&&r.reverse,r}),n||[{}]),c=null!=(o=a)?o:u[1];return(0,r.LI)((()=>{(0,r.S6)(c.current,((e,t)=>{const n=c.current[t+(l?1:-1)];n?e.start({to:n.springs}):e.start()}))}),n),i||3==arguments.length?(c._getProps=(e,t,n)=>{const o=r.is.fun(e)?e(n,t):e;if(o){const e=c.current[n+(o.reverse?1:-1)];return e&&(o.to=e.springs),o}},u):(c.start=e=>{const t=[];return(0,r.S6)(c.current,((n,o)=>{const i=r.is.fun(e)?e(o,n):e,a=c.current[o+(l?1:-1)];a?t.push(n.start(s({},i,{to:a.springs}))):t.push(n.start(s({},i)))})),t},u[0])}let Re;function Me(e,t,n){const i=r.is.fun(t)&&t,{reset:a,sort:l,trail:u=0,expires:f=!0,exitBeforeEnter:p=!1,onDestroyed:d,ref:h,config:b}=i?i():t,y=(0,o.useMemo)((()=>i||3==arguments.length?Ce():void 0),[]),v=(0,r.qo)(e),_=[],S=(0,o.useRef)(null),k=a?null:S.current;(0,r.LI)((()=>{S.current=_})),(0,r.tf)((()=>((0,r.S6)(_,(e=>{null==y||y.add(e.ctrl),e.ctrl.ref=y})),()=>{(0,r.S6)(S.current,(e=>{e.expired&&clearTimeout(e.expirationId),x(e.ctrl,y),e.ctrl.stop(!0)}))})));const j=Ie(v,i?i():t,k),C=a&&S.current||[];(0,r.LI)((()=>(0,r.S6)(C,(({ctrl:e,item:t,key:n})=>{x(e,y),c(d,t,n)}))));const E=[];if(k&&(0,r.S6)(k,((e,t)=>{e.expired?(clearTimeout(e.expirationId),C.push(e)):~(t=E[t]=j.indexOf(e.key))&&(_[t]=e)})),(0,r.S6)(v,((e,t)=>{_[t]||(_[t]={key:j[t],item:e,phase:Re.MOUNT,ctrl:new de},_[t].ctrl.item=e)})),E.length){let e=-1;const{leave:n}=i?i():t;(0,r.S6)(E,((t,r)=>{const o=k[r];~t?(e=_.indexOf(o),_[e]=s({},o,{item:v[t]})):n&&_.splice(++e,0,o)}))}r.is.fun(l)&&_.sort(((e,t)=>l(e.item,t.item)));let P=-u;const A=(0,r.NW)(),T=m(t),L=new Map,R=(0,o.useRef)(new Map),M=(0,o.useRef)(!1);(0,r.S6)(_,((e,n)=>{const o=e.key,a=e.phase,l=i?i():t;let d,m,y=c(l.delay||0,o);if(a==Re.MOUNT)d=l.enter,m=Re.ENTER;else{const e=j.indexOf(o)<0;if(a!=Re.LEAVE)if(e)d=l.leave,m=Re.LEAVE;else{if(!(d=l.update))return;m=Re.UPDATE}else{if(e)return;d=l.enter,m=Re.ENTER}}if(d=c(d,e.item,n),d=r.is.obj(d)?g(d):{to:d},!d.config){const t=b||T.config;d.config=c(t,e.item,n,m)}P+=u;const v=s({},T,{delay:y+P,ref:h,immediate:l.immediate,reset:!1},d);if(m==Re.ENTER&&r.is.und(v.from)){const o=i?i():t,a=r.is.und(o.initial)||k?o.from:o.initial;v.from=c(a,e.item,n)}const{onResolve:w}=v;v.onResolve=e=>{c(w,e);const t=S.current,n=t.find((e=>e.key===o));if(n&&(!e.cancelled||n.phase==Re.UPDATE)&&n.ctrl.idle){const e=t.every((e=>e.ctrl.idle));if(n.phase==Re.LEAVE){const t=c(f,n.item);if(!1!==t){const r=!0===t?0:t;if(n.expired=!0,!e&&r>0)return void(r<=2147483647&&(n.expirationId=setTimeout(A,r)))}}e&&t.some((e=>e.expired))&&(R.current.delete(n),p&&(M.current=!0),A())}};const _=be(e.ctrl,v);m===Re.LEAVE&&p?R.current.set(e,{phase:m,springs:_,payload:v}):L.set(e,{phase:m,springs:_,payload:v})}));const D=(0,o.useContext)(Oe),I=(0,r.zH)(D),F=D!==I&&w(D);(0,r.LI)((()=>{F&&(0,r.S6)(_,(e=>{e.ctrl.start({default:D})}))}),[D]),(0,r.S6)(L,((e,t)=>{if(R.current.size){const e=_.findIndex((e=>e.key===t.key));_.splice(e,1)}})),(0,r.LI)((()=>{(0,r.S6)(R.current.size?R.current:L,(({phase:e,payload:t},n)=>{const{ctrl:r}=n;n.phase=e,null==y||y.add(r),F&&e==Re.ENTER&&r.start({default:D}),t&&(O(r,t.ref),!r.ref&&!y||M.current?(r.start(t),M.current&&(M.current=!1)):r.update(t))}))}),a?void 0:n);const N=e=>o.createElement(o.Fragment,null,_.map(((t,n)=>{const{springs:i}=L.get(t)||t.ctrl,a=e(s({},i),t.item,t,n);return a&&a.type?o.createElement(a.type,s({},a.props,{key:r.is.str(t.key)||r.is.num(t.key)?t.key:t.ctrl.id,ref:a.ref})):a})));return y?[N,y]:N}!function(e){e.MOUNT="mount",e.ENTER="enter",e.UPDATE="update",e.LEAVE="leave"}(Re||(Re={}));let De=1;function Ie(e,{key:t,keys:n=t},o){if(null===n){const t=new Set;return e.map((e=>{const n=o&&o.find((n=>n.item===e&&n.phase!==Re.LEAVE&&!t.has(n)));return n?(t.add(n),n.key):De++}))}return r.is.und(n)?e:r.is.fun(n)?e.map(n):(0,r.qo)(n)}const Fe=["children"];function Ne(e){let{children:t}=e;return t(Pe(_e(e,Fe)))}const ze=["items","children"];function qe(e){let{items:t,children:n}=e,o=_e(e,ze);const i=Le(t.length,o);return t.map(((e,t)=>{const o=n(e,t);return r.is.fun(o)?o(i[t]):o}))}const $e=["items","children"];function Be(e){let{items:t,children:n}=e;return Me(t,_e(e,$e))(n)}class Ue extends Q{constructor(e,t){super(),this.key=void 0,this.idle=!0,this.calc=void 0,this._active=new Set,this.source=e,this.calc=(0,r.mD)(...t);const n=this._get(),o=(0,i.sb)(n);(0,i.f3)(this,o.create(n))}advance(e){const t=this._get(),n=this.get();(0,r.Xy)(t,n)||((0,i.ys)(this).setValue(t),this._onChange(t,this.idle)),!this.idle&&We(this._active)&&He(this)}_get(){const e=r.is.arr(this.source)?this.source.map(r.je):(0,r.qo)((0,r.je)(this.source));return this.calc(...e)}_start(){this.idle&&!We(this._active)&&(this.idle=!1,(0,r.S6)((0,i.He)(this),(e=>{e.done=!1})),r.OH.skipAnimation?(r.Wn.batchedUpdates((()=>this.advance())),He(this)):r.fT.start(this))}_attach(){let e=1;(0,r.S6)((0,r.qo)(this.source),(t=>{(0,r.j$)(t)&&(0,r.UI)(t,this),Z(t)&&(t.idle||this._active.add(t),e=Math.max(e,t.priority+1))})),this.priority=e,this._start()}_detach(){(0,r.S6)((0,r.qo)(this.source),(e=>{(0,r.j$)(e)&&(0,r.iL)(e,this)})),this._active.clear(),He(this)}eventObserved(e){"change"==e.type?e.idle?this.advance():(this._active.add(e.parent),this._start()):"idle"==e.type?this._active.delete(e.parent):"priority"==e.type&&(this.priority=(0,r.qo)(this.source).reduce(((e,t)=>Math.max(e,(Z(t)?t.priority:0)+1)),0))}}function Ve(e){return!1!==e.idle}function We(e){return!e.size||Array.from(e).every(Ve)}function He(e){e.idle||(e.idle=!0,(0,r.S6)((0,i.He)(e),(e=>{e.done=!0})),(0,r.k0)(e,{type:"idle",parent:e}))}const Ze=(e,...t)=>new Ue(e,t),Ke=(e,...t)=>((0,r.LW)(),new Ue(e,t));r.OH.assign({createStringInterpolator:r.qS,to:(e,t)=>new Ue(e,t)});const Qe=r.fT.advance},4813:(e,t,n)=>{"use strict";n.d(t,{B0:()=>_e,OH:()=>N,UI:()=>Oe,k0:()=>we,O9:()=>K,mD:()=>de,qS:()=>De,dE:()=>O,ZR:()=>$e,LW:()=>ze,S6:()=>j,rU:()=>C,yl:()=>P,bl:()=>A,fT:()=>U,Ll:()=>ve,je:()=>ge,j$:()=>ye,is:()=>S,Df:()=>Be,Xy:()=>k,ZT:()=>x,Wn:()=>o,iL:()=>Se,qo:()=>E,NW:()=>Ve,LI:()=>Ue,Pr:()=>We,tf:()=>He,zH:()=>Ke,JZ:()=>Qe});let r=v();const o=e=>m(e,r);let i=v();o.write=e=>m(e,i);let a=v();o.onStart=e=>m(e,a);let l=v();o.onFrame=e=>m(e,l);let u=v();o.onFinish=e=>m(e,u);let s=[];o.setTimeout=(e,t)=>{let n=o.now()+t,r=()=>{let e=s.findIndex((e=>e.cancel==r));~e&&s.splice(e,1),d-=~e?1:0},i={time:n,handler:e,cancel:r};return s.splice(c(n),0,i),d+=1,b(),i};let c=e=>~(~s.findIndex((t=>t.time>e))||~s.length);o.cancel=e=>{a.delete(e),l.delete(e),u.delete(e),r.delete(e),i.delete(e)},o.sync=e=>{h=!0,o.batchedUpdates(e),h=!1},o.throttle=e=>{let t;function n(){try{e(...t)}finally{t=null}}function r(...e){t=e,o.onStart(n)}return r.handler=e,r.cancel=()=>{a.delete(n),t=null},r};let f="undefined"!=typeof window?window.requestAnimationFrame:()=>{};o.use=e=>f=e,o.now="undefined"!=typeof performance?()=>performance.now():Date.now,o.batchedUpdates=e=>e(),o.catch=console.error,o.frameLoop="always",o.advance=()=>{"demand"!==o.frameLoop?console.warn("Cannot call the manual advancement of rafz whilst frameLoop is not set as demand"):g()};let p=-1,d=0,h=!1;function m(e,t){h?(t.delete(e),e(0)):(t.add(e),b())}function b(){p<0&&(p=0,"demand"!==o.frameLoop&&f(y))}function y(){~p&&(f(y),o.batchedUpdates(g))}function g(){let e=p;p=o.now();let t=c(p);t&&(w(s.splice(0,t),(e=>e.handler())),d-=t),d?(a.flush(),r.flush(e?Math.min(64,p-e):16.667),l.flush(),i.flush(),u.flush()):p=-1}function v(){let e=new Set,t=e;return{add(n){d+=t!=e||e.has(n)?0:1,e.add(n)},delete:n=>(d-=t==e&&e.has(n)?1:0,e.delete(n)),flush(n){t.size&&(e=new Set,d-=t.size,w(t,(t=>t(n)&&e.add(t))),d+=e.size,t=e)}}}function w(e,t){e.forEach((e=>{try{t(e)}catch(e){o.catch(e)}}))}var _=n(7294);function x(){}const O=(e,t,n)=>Object.defineProperty(e,t,{value:n,writable:!0,configurable:!0}),S={arr:Array.isArray,obj:e=>!!e&&"Object"===e.constructor.name,fun:e=>"function"==typeof e,str:e=>"string"==typeof e,num:e=>"number"==typeof e,und:e=>void 0===e};function k(e,t){if(S.arr(e)){if(!S.arr(t)||e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}return e===t}const j=(e,t)=>e.forEach(t);function C(e,t,n){if(S.arr(e))for(let r=0;r<e.length;r++)t.call(n,e[r],`${r}`);else for(const r in e)e.hasOwnProperty(r)&&t.call(n,e[r],r)}const E=e=>S.und(e)?[]:S.arr(e)?e:[e];function P(e,t){if(e.size){const n=Array.from(e);e.clear(),j(n,t)}}const A=(e,...t)=>P(e,(e=>e(...t))),T=()=>"undefined"==typeof window||!window.navigator||/ServerSideRendering|^Deno\//.test(window.navigator.userAgent);let L,R,M=null,D=!1,I=x;const F=e=>{e.to&&(R=e.to),e.now&&(o.now=e.now),void 0!==e.colors&&(M=e.colors),null!=e.skipAnimation&&(D=e.skipAnimation),e.createStringInterpolator&&(L=e.createStringInterpolator),e.requestAnimationFrame&&o.use(e.requestAnimationFrame),e.batchedUpdates&&(o.batchedUpdates=e.batchedUpdates),e.willAdvance&&(I=e.willAdvance),e.frameLoop&&(o.frameLoop=e.frameLoop)};var N=Object.freeze({__proto__:null,get createStringInterpolator(){return L},get to(){return R},get colors(){return M},get skipAnimation(){return D},get willAdvance(){return I},assign:F});const z=new Set;let q=[],$=[],B=0;const U={get idle(){return!z.size&&!q.length},start(e){B>e.priority?(z.add(e),o.onStart(V)):(W(e),o(Z))},advance:Z,sort(e){if(B)o.onFrame((()=>U.sort(e)));else{const t=q.indexOf(e);~t&&(q.splice(t,1),H(e))}},clear(){q=[],z.clear()}};function V(){z.forEach(W),z.clear(),o(Z)}function W(e){q.includes(e)||H(e)}function H(e){q.splice(function(t,n){const r=t.findIndex((t=>t.priority>e.priority));return r<0?t.length:r}(q),0,e)}function Z(e){const t=$;for(let n=0;n<q.length;n++){const r=q[n];B=r.priority,r.idle||(I(r),r.advance(e),r.idle||t.push(r))}return B=0,$=q,$.length=0,q=t,q.length>0}const K={transparent:0,aliceblue:4042850303,antiquewhite:4209760255,aqua:16777215,aquamarine:2147472639,azure:4043309055,beige:4126530815,bisque:4293182719,black:255,blanchedalmond:4293643775,blue:65535,blueviolet:2318131967,brown:2771004159,burlywood:3736635391,burntsienna:3934150143,cadetblue:1604231423,chartreuse:2147418367,chocolate:3530104575,coral:4286533887,cornflowerblue:1687547391,cornsilk:4294499583,crimson:3692313855,cyan:16777215,darkblue:35839,darkcyan:9145343,darkgoldenrod:3095792639,darkgray:2846468607,darkgreen:6553855,darkgrey:2846468607,darkkhaki:3182914559,darkmagenta:2332068863,darkolivegreen:1433087999,darkorange:4287365375,darkorchid:2570243327,darkred:2332033279,darksalmon:3918953215,darkseagreen:2411499519,darkslateblue:1211993087,darkslategray:793726975,darkslategrey:793726975,darkturquoise:13554175,darkviolet:2483082239,deeppink:4279538687,deepskyblue:12582911,dimgray:1768516095,dimgrey:1768516095,dodgerblue:512819199,firebrick:2988581631,floralwhite:4294635775,forestgreen:579543807,fuchsia:4278255615,gainsboro:3705462015,ghostwhite:4177068031,gold:4292280575,goldenrod:3668254975,gray:2155905279,green:8388863,greenyellow:2919182335,grey:2155905279,honeydew:4043305215,hotpink:4285117695,indianred:3445382399,indigo:1258324735,ivory:4294963455,khaki:4041641215,lavender:3873897215,lavenderblush:4293981695,lawngreen:2096890111,lemonchiffon:4294626815,lightblue:2916673279,lightcoral:4034953471,lightcyan:3774873599,lightgoldenrodyellow:4210742015,lightgray:3553874943,lightgreen:2431553791,lightgrey:3553874943,lightpink:4290167295,lightsalmon:4288707327,lightseagreen:548580095,lightskyblue:2278488831,lightslategray:2005441023,lightslategrey:2005441023,lightsteelblue:2965692159,lightyellow:4294959359,lime:16711935,limegreen:852308735,linen:4210091775,magenta:4278255615,maroon:2147483903,mediumaquamarine:1724754687,mediumblue:52735,mediumorchid:3126187007,mediumpurple:2473647103,mediumseagreen:1018393087,mediumslateblue:2070474495,mediumspringgreen:16423679,mediumturquoise:1221709055,mediumvioletred:3340076543,midnightblue:421097727,mintcream:4127193855,mistyrose:4293190143,moccasin:4293178879,navajowhite:4292783615,navy:33023,oldlace:4260751103,olive:2155872511,olivedrab:1804477439,orange:4289003775,orangered:4282712319,orchid:3664828159,palegoldenrod:4008225535,palegreen:2566625535,paleturquoise:2951671551,palevioletred:3681588223,papayawhip:4293907967,peachpuff:4292524543,peru:3448061951,pink:4290825215,plum:3718307327,powderblue:2967529215,purple:2147516671,rebeccapurple:1714657791,red:4278190335,rosybrown:3163525119,royalblue:1097458175,saddlebrown:2336560127,salmon:4202722047,sandybrown:4104413439,seagreen:780883967,seashell:4294307583,sienna:2689740287,silver:3233857791,skyblue:2278484991,slateblue:1784335871,slategray:1887473919,slategrey:1887473919,snow:4294638335,springgreen:16744447,steelblue:1182971135,tan:3535047935,teal:8421631,thistle:3636451583,tomato:4284696575,turquoise:1088475391,violet:4001558271,wheat:4125012991,white:4294967295,whitesmoke:4126537215,yellow:4294902015,yellowgreen:2597139199},Q="[-+]?\\d*\\.?\\d+",G=Q+"%";function X(...e){return"\\(\\s*("+e.join(")\\s*,\\s*(")+")\\s*\\)"}const Y=new RegExp("rgb"+X(Q,Q,Q)),J=new RegExp("rgba"+X(Q,Q,Q,Q)),ee=new RegExp("hsl"+X(Q,G,G)),te=new RegExp("hsla"+X(Q,G,G,Q)),ne=/^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,re=/^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,oe=/^#([0-9a-fA-F]{6})$/,ie=/^#([0-9a-fA-F]{8})$/;function ae(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}function le(e,t,n){const r=n<.5?n*(1+t):n+t-n*t,o=2*n-r,i=ae(o,r,e+1/3),a=ae(o,r,e),l=ae(o,r,e-1/3);return Math.round(255*i)<<24|Math.round(255*a)<<16|Math.round(255*l)<<8}function ue(e){const t=parseInt(e,10);return t<0?0:t>255?255:t}function se(e){return(parseFloat(e)%360+360)%360/360}function ce(e){const t=parseFloat(e);return t<0?0:t>1?255:Math.round(255*t)}function fe(e){const t=parseFloat(e);return t<0?0:t>100?1:t/100}function pe(e){let t=function(e){let t;return"number"==typeof e?e>>>0===e&&e>=0&&e<=4294967295?e:null:(t=oe.exec(e))?parseInt(t[1]+"ff",16)>>>0:M&&void 0!==M[e]?M[e]:(t=Y.exec(e))?(ue(t[1])<<24|ue(t[2])<<16|ue(t[3])<<8|255)>>>0:(t=J.exec(e))?(ue(t[1])<<24|ue(t[2])<<16|ue(t[3])<<8|ce(t[4]))>>>0:(t=ne.exec(e))?parseInt(t[1]+t[1]+t[2]+t[2]+t[3]+t[3]+"ff",16)>>>0:(t=ie.exec(e))?parseInt(t[1],16)>>>0:(t=re.exec(e))?parseInt(t[1]+t[1]+t[2]+t[2]+t[3]+t[3]+t[4]+t[4],16)>>>0:(t=ee.exec(e))?(255|le(se(t[1]),fe(t[2]),fe(t[3])))>>>0:(t=te.exec(e))?(le(se(t[1]),fe(t[2]),fe(t[3]))|ce(t[4]))>>>0:null}(e);return null===t?e:(t=t||0,`rgba(${(4278190080&t)>>>24}, ${(16711680&t)>>>16}, ${(65280&t)>>>8}, ${(255&t)/255})`)}const de=(e,t,n)=>{if(S.fun(e))return e;if(S.arr(e))return de({range:e,output:t,extrapolate:n});if(S.str(e.output[0]))return L(e);const r=e,o=r.output,i=r.range||[0,1],a=r.extrapolateLeft||r.extrapolate||"extend",l=r.extrapolateRight||r.extrapolate||"extend",u=r.easing||(e=>e);return e=>{const t=function(e,t){for(var n=1;n<t.length-1&&!(t[n]>=e);++n);return n-1}(e,i);return function(e,t,n,r,o,i,a,l,u){let s=u?u(e):e;if(s<t){if("identity"===a)return s;"clamp"===a&&(s=t)}if(s>n){if("identity"===l)return s;"clamp"===l&&(s=n)}return r===o?r:t===n?e<=t?r:o:(t===-1/0?s=-s:n===1/0?s-=t:s=(s-t)/(n-t),s=i(s),r===-1/0?s=-s:o===1/0?s+=r:s=s*(o-r)+r,s)}(e,i[t],i[t+1],o[t],o[t+1],u,a,l,r.map)}};function he(){return he=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},he.apply(this,arguments)}const me=Symbol.for("FluidValue.get"),be=Symbol.for("FluidValue.observers"),ye=e=>Boolean(e&&e[me]),ge=e=>e&&e[me]?e[me]():e,ve=e=>e[be]||null;function we(e,t){let n=e[be];n&&n.forEach((e=>{!function(e,t){e.eventObserved?e.eventObserved(t):e(t)}(e,t)}))}class _e{constructor(e){if(this[me]=void 0,this[be]=void 0,!e&&!(e=this.get))throw Error("Unknown getter");xe(this,e)}}const xe=(e,t)=>ke(e,me,t);function Oe(e,t){if(e[me]){let n=e[be];n||ke(e,be,n=new Set),n.has(t)||(n.add(t),e.observerAdded&&e.observerAdded(n.size,t))}return t}function Se(e,t){let n=e[be];if(n&&n.has(t)){const r=n.size-1;r?n.delete(t):e[be]=null,e.observerRemoved&&e.observerRemoved(r,t)}}const ke=(e,t,n)=>Object.defineProperty(e,t,{value:n,writable:!0,configurable:!0}),je=/[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,Ce=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi,Ee=new RegExp(`(${je.source})(%|[a-z]+)`,"i"),Pe=/rgba\(([0-9\.-]+), ([0-9\.-]+), ([0-9\.-]+), ([0-9\.-]+)\)/gi,Ae=/var\((--[a-zA-Z0-9-_]+),? ?([a-zA-Z0-9 ()%#.,-]+)?\)/,Te=e=>{const[t,n]=Le(e);if(!t||T())return e;const r=window.getComputedStyle(document.documentElement).getPropertyValue(t);if(r)return r.trim();if(n&&n.startsWith("--")){return window.getComputedStyle(document.documentElement).getPropertyValue(n)||e}return n&&Ae.test(n)?Te(n):n||e},Le=e=>{const t=Ae.exec(e);if(!t)return[,];const[,n,r]=t;return[n,r]};let Re;const Me=(e,t,n,r,o)=>`rgba(${Math.round(t)}, ${Math.round(n)}, ${Math.round(r)}, ${o})`,De=e=>{Re||(Re=M?new RegExp(`(${Object.keys(M).join("|")})(?!\\w)`,"g"):/^\b$/);const t=e.output.map((e=>ge(e).replace(Ae,Te).replace(Ce,pe).replace(Re,pe))),n=t.map((e=>e.match(je).map(Number))),r=n[0].map(((e,t)=>n.map((e=>{if(!(t in e))throw Error('The arity of each "output" value must be equal');return e[t]})))).map((t=>de(he({},e,{output:t}))));return e=>{var n;const o=!Ee.test(t[0])&&(null==(n=t.find((e=>Ee.test(e))))?void 0:n.replace(je,""));let i=0;return t[0].replace(je,(()=>`${r[i++](e)}${o||""}`)).replace(Pe,Me)}},Ie="react-spring: ",Fe=e=>{const t=e;let n=!1;if("function"!=typeof t)throw new TypeError(`${Ie}once requires a function parameter`);return(...e)=>{n||(t(...e),n=!0)}},Ne=Fe(console.warn);function ze(){Ne(`${Ie}The "interpolate" function is deprecated in v9 (use "to" instead)`)}const qe=Fe(console.warn);function $e(){qe(`${Ie}Directly calling start instead of using the api object is deprecated in v9 (use ".start" instead), this will be removed in later 0.X.0 versions`)}function Be(e){return S.str(e)&&("#"==e[0]||/\d/.test(e)||!T()&&Ae.test(e)||e in(M||{}))}const Ue=T()?_.useEffect:_.useLayoutEffect;function Ve(){const e=(0,_.useState)()[1],t=(()=>{const e=(0,_.useRef)(!1);return Ue((()=>(e.current=!0,()=>{e.current=!1})),[]),e})();return()=>{t.current&&e(Math.random())}}function We(e,t){const[n]=(0,_.useState)((()=>({inputs:t,result:e()}))),r=(0,_.useRef)(),o=r.current;let i=o;return i?Boolean(t&&i.inputs&&function(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}(t,i.inputs))||(i={inputs:t,result:e()}):i=n,(0,_.useEffect)((()=>{r.current=i,o==n&&(n.inputs=n.result=void 0)}),[i]),i.result}const He=e=>(0,_.useEffect)(e,Ze),Ze=[];function Ke(e){const t=(0,_.useRef)();return(0,_.useEffect)((()=>{t.current=e})),t.current}const Qe=()=>{const[e,t]=(0,_.useState)(null);return Ue((()=>{const e=window.matchMedia("(prefers-reduced-motion)"),n=e=>{t(e.matches),F({skipAnimation:e.matches})};return n(e),e.addEventListener("change",n),()=>{e.removeEventListener("change",n)}}),[]),e}},6233:()=>{},8716:()=>{},1472:(e,t,n)=>{"use strict";n.r(t),n.d(t,{a:()=>S,animated:()=>S});var r=n(4928),o={};for(const e in r)["default","a","animated"].indexOf(e)<0&&(o[e]=()=>r[e]);n.d(t,o);var i=n(3935),a=n(4813),l=n(1314);function u(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}const s=["style","children","scrollTop","scrollLeft"],c=/^--/;function f(e,t){return null==t||"boolean"==typeof t||""===t?"":"number"!=typeof t||0===t||c.test(e)||d.hasOwnProperty(e)&&d[e]?(""+t).trim():t+"px"}const p={};let d={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0};const h=["Webkit","Ms","Moz","O"];d=Object.keys(d).reduce(((e,t)=>(h.forEach((n=>e[((e,t)=>e+t.charAt(0).toUpperCase()+t.substring(1))(n,t)]=e[t])),e)),d);const m=["x","y","z"],b=/^(matrix|translate|scale|rotate|skew)/,y=/^(translate)/,g=/^(rotate|skew)/,v=(e,t)=>a.is.num(e)&&0!==e?e+t:e,w=(e,t)=>a.is.arr(e)?e.every((e=>w(e,t))):a.is.num(e)?e===t:parseFloat(e)===t;class _ extends l.rS{constructor(e){let{x:t,y:n,z:r}=e,o=u(e,m);const i=[],l=[];(t||n||r)&&(i.push([t||0,n||0,r||0]),l.push((e=>[`translate3d(${e.map((e=>v(e,"px"))).join(",")})`,w(e,0)]))),(0,a.rU)(o,((e,t)=>{if("transform"===t)i.push([e||""]),l.push((e=>[e,""===e]));else if(b.test(t)){if(delete o[t],a.is.und(e))return;const n=y.test(t)?"px":g.test(t)?"deg":"";i.push((0,a.qo)(e)),l.push("rotate3d"===t?([e,t,r,o])=>[`rotate3d(${e},${t},${r},${v(o,n)})`,w(o,0)]:e=>[`${t}(${e.map((e=>v(e,n))).join(",")})`,w(e,t.startsWith("scale")?1:0)])}})),i.length&&(o.transform=new x(i,l)),super(o)}}class x extends a.B0{constructor(e,t){super(),this._value=null,this.inputs=e,this.transforms=t}get(){return this._value||(this._value=this._get())}_get(){let e="",t=!0;return(0,a.S6)(this.inputs,((n,r)=>{const o=(0,a.je)(n[0]),[i,l]=this.transforms[r](a.is.arr(o)?o:n.map(a.je));e+=" "+i,t=t&&l})),t?"none":e}observerAdded(e){1==e&&(0,a.S6)(this.inputs,(e=>(0,a.S6)(e,(e=>(0,a.j$)(e)&&(0,a.UI)(e,this)))))}observerRemoved(e){0==e&&(0,a.S6)(this.inputs,(e=>(0,a.S6)(e,(e=>(0,a.j$)(e)&&(0,a.iL)(e,this)))))}eventObserved(e){"change"==e.type&&(this._value=null),(0,a.k0)(this,e)}}const O=["scrollTop","scrollLeft"];r.Globals.assign({batchedUpdates:i.unstable_batchedUpdates,createStringInterpolator:a.qS,colors:a.O9});const S=(0,l.Ld)(["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr","circle","clipPath","defs","ellipse","foreignObject","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","svg","text","tspan"],{applyAnimatedValues:function(e,t){if(!e.nodeType||!e.setAttribute)return!1;const n="filter"===e.nodeName||e.parentNode&&"filter"===e.parentNode.nodeName,r=t,{style:o,children:i,scrollTop:a,scrollLeft:l}=r,d=u(r,s),h=Object.values(d),m=Object.keys(d).map((t=>n||e.hasAttribute(t)?t:p[t]||(p[t]=t.replace(/([A-Z])/g,(e=>"-"+e.toLowerCase())))));void 0!==i&&(e.textContent=i);for(let t in o)if(o.hasOwnProperty(t)){const n=f(t,o[t]);c.test(t)?e.style.setProperty(t,n):e.style[t]=n}m.forEach(((t,n)=>{e.setAttribute(t,h[n])})),void 0!==a&&(e.scrollTop=a),void 0!==l&&(e.scrollLeft=l)},createAnimatedStyle:e=>new _(e),getComponentProps:e=>u(e,O)}).animated},2599:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(this,arguments)}var o;n.d(t,{RQ:()=>g,Zn:()=>d,Zq:()=>b,aU:()=>o,cP:()=>c,kG:()=>h,lX:()=>a,pC:()=>y}),function(e){e.Pop="POP",e.Push="PUSH",e.Replace="REPLACE"}(o||(o={}));const i="popstate";function a(e){return void 0===e&&(e={}),function(e,t,n,a){void 0===a&&(a={});let{window:c=document.defaultView,v5Compat:p=!1}=a,d=c.history,h=o.Pop,m=null;function b(){h=o.Pop,m&&m({action:h,location:y.location})}let y={get action(){return h},get location(){return e(c,d)},listen(e){if(m)throw new Error("A history only accepts one active listener");return c.addEventListener(i,b),m=e,()=>{c.removeEventListener(i,b),m=null}},createHref:e=>t(c,e),encodeLocation(e){let t=f(s(e));return r({},e,{pathname:t.pathname,search:t.search,hash:t.hash})},push:function(e,t){h=o.Push;let r=u(y.location,e,t);n&&n(r,e);let i=l(r),a=y.createHref(r);try{d.pushState(i,"",a)}catch(e){c.location.assign(a)}p&&m&&m({action:h,location:y.location})},replace:function(e,t){h=o.Replace;let r=u(y.location,e,t);n&&n(r,e);let i=l(r),a=y.createHref(r);d.replaceState(i,"",a),p&&m&&m({action:h,location:y.location})},go:e=>d.go(e)};return y}((function(e,t){let{pathname:n,search:r,hash:o}=e.location;return u("",{pathname:n,search:r,hash:o},t.state&&t.state.usr||null,t.state&&t.state.key||"default")}),(function(e,t){return"string"==typeof t?t:s(t)}),null,e)}function l(e){return{usr:e.state,key:e.key}}function u(e,t,n,o){return void 0===n&&(n=null),r({pathname:"string"==typeof e?e:e.pathname,search:"",hash:""},"string"==typeof t?c(t):t,{state:n,key:t&&t.key||o||Math.random().toString(36).substr(2,8)})}function s(e){let{pathname:t="/",search:n="",hash:r=""}=e;return n&&"?"!==n&&(t+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(t+="#"===r.charAt(0)?r:"#"+r),t}function c(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substr(n),e=e.substr(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substr(r),e=e.substr(0,r)),e&&(t.pathname=e)}return t}function f(e){let t="undefined"!=typeof window&&void 0!==window.location&&"null"!==window.location.origin?window.location.origin:"unknown://unknown",n="string"==typeof e?e:s(e);return new URL(n,t)}var p;function d(e,t){if("/"===t)return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&"/"!==r?null:e.slice(n)||"/"}function h(e,t){if(!1===e||null==e)throw new Error(t)}function m(e,t,n,r){return"Cannot include a '"+e+"' character in a manually specified `to."+t+"` field ["+JSON.stringify(r)+"].  Please separate it out to the `to."+n+'` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.'}function b(e){return e.filter(((e,t)=>0===t||e.route.path&&e.route.path.length>0))}function y(e,t,n,o){let i;void 0===o&&(o=!1),"string"==typeof e?i=c(e):(i=r({},e),h(!i.pathname||!i.pathname.includes("?"),m("?","pathname","search",i)),h(!i.pathname||!i.pathname.includes("#"),m("#","pathname","hash",i)),h(!i.search||!i.search.includes("#"),m("#","search","hash",i)));let a,l=""===e||""===i.pathname,u=l?"/":i.pathname;if(o||null==u)a=n;else{let e=t.length-1;if(u.startsWith("..")){let t=u.split("/");for(;".."===t[0];)t.shift(),e-=1;i.pathname=t.join("/")}a=e>=0?t[e]:"/"}let s=function(e,t){void 0===t&&(t="/");let{pathname:n,search:r="",hash:o=""}="string"==typeof e?c(e):e,i=n?n.startsWith("/")?n:function(e,t){let n=t.replace(/\/+$/,"").split("/");return e.split("/").forEach((e=>{".."===e?n.length>1&&n.pop():"."!==e&&n.push(e)})),n.length>1?n.join("/"):"/"}(n,t):t;return{pathname:i,search:v(r),hash:w(o)}}(i,a),f=u&&"/"!==u&&u.endsWith("/"),p=(l||"."===u)&&n.endsWith("/");return s.pathname.endsWith("/")||!f&&!p||(s.pathname+="/"),s}!function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"}(p||(p={}));const g=e=>e.join("/").replace(/\/\/+/g,"/"),v=e=>e&&"?"!==e?e.startsWith("?")?e:"?"+e:"",w=e=>e&&"#"!==e?e.startsWith("#")?e:"#"+e:"";class _ extends Error{}"undefined"!=typeof window&&void 0!==window.document&&window.document.createElement;const x=new Set(["POST","PUT","PATCH","DELETE"]);new Set(["GET","HEAD",...x])},7924:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=31)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},31:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),i=n(1),a=n(8),l=n.n(a);function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}function s(e){return o.a.createElement(l.a,u({screenReaderText:Object(i._)("(Menu)")},e))}},8:function(e,t){e.exports=n(2357)}})},4789:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=50)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},2:function(e,t){e.exports=n(2472)},50:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),i=n(1),a=n(2),l=n.n(a);function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}function s(e){return o.a.createElement(l.a,u({screenReaderText:Object(i._)("Clear")},e),o.a.createElement("path",{d:"M918.315 750.645L1500 1332.33 1332.33 1500 750.645 918.315 167.67 1500 0 1332.33l581.685-582.975L0 167.67 167.67 0l582.975 581.685L1332.33 0 1500 167.67"}))}}})},1476:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=54)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},4:function(e,t){e.exports=n(4789)},54:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),i=n(1),a=n(4),l=n.n(a);function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}function s(e){return o.a.createElement(l.a,u({screenReaderText:Object(i._)("Close")},e))}}})},6054:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=66)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},2:function(e,t){e.exports=n(2472)},66:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),i=n(1),a=n(2),l=n.n(a);function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}function s(e){return o.a.createElement(l.a,u({screenReaderText:Object(i._)("Error")},e,{viewBox:"0 0 1375 1500"}),o.a.createElement("path",{d:"M187.5 61.5h1000c103.553 0 187.5 83.947 187.5 187.5v1000c0 103.553-83.947 187.5-187.5 187.5h-1000C83.947 1436.5 0 1352.553 0 1249V249C0 145.447 83.947 61.5 187.5 61.5zm400.79 413.083l32.145 257.167c4.908 39.264 34.086 74.685 69.815 91.187 36.612-16.018 64.87-50.826 69.914-91.187l32.146-257.167C799.18 419.623 759.582 374 703.7 374h-26.8c-55.908 0-95.555 45.033-88.61 100.583zm101.293 644.209c63.283 0 114.584-51.301 114.584-114.584 0-63.282-51.301-114.583-114.584-114.583-63.282 0-114.583 51.3-114.583 114.583s51.3 114.584 114.583 114.584z"}))}}})},5175:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=68)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},2:function(e,t){e.exports=n(2472)},68:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),i=n(1),a=n(2),l=n.n(a);function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}function s(e){return o.a.createElement(l.a,u({screenReaderText:Object(i._)("External"),viewBox:"0 0 1500 1499"},e),o.a.createElement("path",{d:"M1500 1125h-189.04v185.96H189.04V189.04H375V0H0v1500h1500v-375zm0-1125H723.288v190.068h469.52l-666.78 648.288 133.56 134.59 650.344-665.754v469.52l189.04 1.028L1500 0z"}))}}})},2708:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=88)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},2:function(e,t){e.exports=n(2472)},88:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),i=n(1),a=n(2),l=n.n(a);function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}function s(e){return o.a.createElement(l.a,u({screenReaderText:Object(i._)("Info Circle")},e),o.a.createElement("path",{d:"M843.75 750v-93.75H562.5V750h93.75v281.25H562.5V1125h375v-93.75h-93.75V750zM750 1500C335.786 1500 0 1164.214 0 750S335.786 0 750 0s750 335.786 750 750-335.786 750-750 750zm0-937.5c51.777 0 93.75-41.973 93.75-93.75S801.777 375 750 375s-93.75 41.973-93.75 93.75S698.223 562.5 750 562.5z"}))}}})},6817:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=140)}({0:function(e,t){e.exports=n(7294)},140:function(e,t,n){"use strict";n.r(t);var r=n(0),o=n.n(r),i=n(3),a=n.n(i),l=n(6),u=n(5),s=n.n(u);function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}var f=s.a.svg.withConfig({displayName:"SVG__InlineSVG",componentId:"sc-13m0oii-0"})(["display:inline-block;flex:0 0 auto;overflow:visible;vertical-align:middle;"]),p=s.a.svg.withConfig({displayName:"SVG__BlockSVG",componentId:"sc-13m0oii-1"})(["display:block;flex:0 0 auto;margin:0 auto;overflow:visible;"]),d={children:a.a.node,height:a.a.oneOfType([a.a.number,a.a.string]),hideDefaultTooltip:a.a.bool,inline:a.a.bool,screenReaderText:a.a.oneOfType([a.a.string,a.a.oneOf(["null"])]),size:a.a.oneOfType([a.a.number,a.a.string]),width:a.a.oneOfType([a.a.number,a.a.string]),viewBox:a.a.string.isRequired,preserveAspectRatio:a.a.oneOf(["none","xMinYMin","xMidYMin","xMaxYMin","xMinYMid","xMidYMid","xMaxYMid","xMinYMax","xMidYMax","xMaxYMax"])};function h(e){var t=e.children,n=e.height,r=e.hideDefaultTooltip,i=void 0!==r&&r,a=e.inline,u=void 0===a||a,s=e.preserveAspectRatio,d=void 0===s?"xMidYMid":s,h=e.screenReaderText,m=e.size,b=void 0===m?.75:m,y=e.viewBox,g=e.width,v=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","height","hideDefaultTooltip","inline","preserveAspectRatio","screenReaderText","size","viewBox","width"]),w="number"!=typeof b?parseFloat(b):b,_=Object(l.isString)(b)?b.match(/[^\d]+/):"em",x=parseFloat(y.split(" ")[3]),O=parseFloat(y.split(" ")[2]),S=Math.max(O,x),k=Object(l.isUndefined)(n)?x/S*w:n,j=Object(l.isUndefined)(g)?O/S*w:g,C=u?f:p,E=h&&!i;return o.a.createElement(C,c({focusable:"false",height:Object(l.isString)(k)?k:"".concat(k.toFixed(4)).concat(_),width:Object(l.isString)(j)?j:"".concat(j.toFixed(4)).concat(_),viewBox:y,"aria-label":i&&null!=h?h:void 0,"aria-hidden":!h,preserveAspectRatio:d,xmlns:"http://www.w3.org/2000/svg"},v),E&&o.a.createElement("title",null,h),t)}h.propTypes=d,t.default=h},3:function(e,t){e.exports=n(1581)},5:function(e,t){e.exports=n(2788)},6:function(e,t){e.exports=n(5220)}})},2472:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=141)}({0:function(e,t){e.exports=n(7294)},13:function(e,t){e.exports=n(6817)},141:function(e,t,n){"use strict";n.r(t);var r=n(0),o=n.n(r),i=n(3),a=n.n(i),l=n(5),u=n.n(l),s=n(13),c=n.n(s);function f(){return f=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},f.apply(this,arguments)}var p=u()(c.a).withConfig({displayName:"SVGInternal__StyledSVG",componentId:"ksy9g7-0"})(["circle,ellipse,path,polygon,rect{fill:currentColor;}"]),d={viewBox:a.a.string};function h(e){var t=e.viewBox,n=void 0===t?"0 0 1500 1500":t,r=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["viewBox"]);return o.a.createElement(p,f({viewBox:n},r))}h.propTypes=d,t.default=h},3:function(e,t){e.exports=n(1581)},5:function(e,t){e.exports=n(2788)}})},3940:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=157)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},157:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),i=n(1),a=n(2),l=n.n(a);function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}function s(e){return o.a.createElement(l.a,u({screenReaderText:Object(i._)("Success")},e),o.a.createElement("path",{d:"M750 1500C335.786 1500 0 1164.214 0 750S335.786 0 750 0s750 335.786 750 750-335.786 750-750 750zm-138.327-414.388l511.677-511.677-105.185-105.185L611.53 875.385 453.004 716.573 347.819 821.76l263.854 263.853z"}))}},2:function(e,t){e.exports=n(2472)}})},2357:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=168)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},168:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),i=n(1),a=n(2),l=n.n(a);function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}function s(e){return o.a.createElement(l.a,u({screenReaderText:Object(i._)("Triangle Down Small"),viewBox:"0 0 1063 677"},e),o.a.createElement("path",{d:"M458.024 633l-397-458c-35-41-61-72-61-102-1-43 30-73 73-73h918c43 0 71 30 71 73 0 30-13 58-43 94l-415 466c-32 35-47 44-73 44-22 0-37-9-73-44z"}))}},2:function(e,t){e.exports=n(2472)}})},4003:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=177)}({0:function(e,t){e.exports=n(7294)},1:function(e,t){e.exports=n(6219)},177:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return s}));var r=n(0),o=n.n(r),i=n(1),a=n(2),l=n.n(a);function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}function s(e){return o.a.createElement(l.a,u({screenReaderText:Object(i._)("Warning"),viewBox:"0 0 1500 1313"},e),o.a.createElement("path",{d:"M.956 1196.326l668.58-1144.89C689.395 17.736 718.71 0 749.916 0c31.207 0 59.577 15.963 80.382 51.436l668.58 1144.89c7.565 12.416-23.642 116.174-77.544 116.174H85.474c-53.902 0-92.083-102.872-84.518-116.174zm643.333-684.743l32.146 257.167c4.908 39.264 34.086 74.685 69.815 91.187 36.612-16.018 64.87-50.826 69.914-91.187l32.146-257.167C855.18 456.623 815.582 411 759.7 411h-26.8c-55.908 0-95.555 45.033-88.61 100.583zm101.294 644.209c63.283 0 114.584-51.301 114.584-114.584 0-63.282-51.301-114.583-114.584-114.583-63.282 0-114.583 51.3-114.583 114.583s51.3 114.584 114.583 114.584z"}))}},2:function(e,t){e.exports=n(2472)}})},1625:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=11)}([function(e,t){e.exports=n(7294)},function(e,t){e.exports=n(5947)},function(e,t){e.exports=n(2788)},function(e,t){e.exports=n(3935)},function(e,t){e.exports=n(5266)},function(e,t){e.exports=n(1581)},function(e,t){e.exports=n(5277)},function(e,t){e.exports=n(5451)},function(e,t){e.exports=n(7212)},function(e,t){e.exports=n(5766)},function(e,t){e.exports=n(6219)},function(e,t,n){"use strict";n.r(t);var r=n(0),o=n.n(r),i=n(3),a=n(6),l=n.n(a),u=n(7),s=n(8),c=n(4),f=n.n(c),p=n(5),d=n.n(p),h=n(9),m=n.n(h),b=n(10),y=n(2),g=n.n(y),v=n(1);function w(){var e=j(["\n    animation-name: ",";\n    animation-duration: 1.4s;\n    animation-iteration-count: infinite;\n    animation-fill-mode: both;\n    background-color: ",";\n    width: 10px;\n    height: 10px;\n    border-radius: 5px;\n    display: inline-block;\n    margin-right: ",";\n\n    &:nth-child(2) {\n        animation-delay: 0.2s;\n    }\n\n    &:nth-child(3) {\n        animation-delay: 0.4s;\n    }\n"]);return w=function(){return e},e}function _(){var e=j(["\n    color: ",";\n    padding-top: 30vh;\n    text-align: center;\n    min-height: 400px;\n"]);return _=function(){return e},e}function x(){var e=j(["\n    background-color: ",";\n    min-height: 44px;\n"]);return x=function(){return e},e}function O(){var e=j(["\n    padding: 0;\n    background-color: ",";\n    height: 34px;\n"]);return O=function(){return e},e}function S(){var e=j(["\n    background-color: ",";\n    position: fixed;\n    opacity: 1;\n    z-index: 10000;\n    top: 0;\n    bottom: 0;\n    left: 0;\n    right: 0;\n"]);return S=function(){return e},e}function k(){var e=j(["\n    0% {\n        opacity: 0.2;\n    }\n\n    20% {\n        opacity: 1;\n    }\n\n    100% {\n        opacity: 0.2;\n    }\n"]);return k=function(){return e},e}function j(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}var C=Object(y.keyframes)(k()),E=g.a.div(S(),v.variables.backgroundColorPage),P=g.a.div(O(),Object(v.pick)({prisma:v.variables.backgroundColorSection,enterprise:v.variables.gray20})),A=g.a.div(x(),Object(v.pick)({prisma:v.variables.backgroundColorPopup,enterprise:v.variables.gray30})),T=g.a.div(_(),v.variables.contentColorInverted),L=g.a.div(w(),C,v.variables.neutral500,Object(v.pick)({prisma:v.variables.spacingMedium,enterprise:v.variables.spacingHalf})),R={hideAppBar:d.a.bool,hideChrome:d.a.bool,hideSplunkBar:d.a.bool};function M(e){var t=e.hideAppBar,n=e.hideChrome,r=e.hideSplunkBar;return o.a.createElement(E,null,!n&&!r&&o.a.createElement(P,null),!n&&!t&&o.a.createElement(A,null),o.a.createElement(T,null,o.a.createElement(L,null),o.a.createElement(L,null),o.a.createElement(L,null),o.a.createElement(m.a,null,Object(b._)("Loading"))))}M.propTypes=R,M.defaultProps={hideAppBar:!1,hideChrome:!1,hideSplunkBar:!1};var D=M;function I(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function F(e,t){var n="dark"===e?"build/api/layout-dark.js":"build/api/layout.js",r=Object(s.createStaticURL)(n);l()(r,(function(){t(window.__splunk_layout__)}))}t.default=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.useGlobalLayerStack,r=void 0===n||n,a=t.pageTitle,l=t.theme,s=void 0===l?"light":l,c=I(t,["useGlobalLayerStack","pageTitle","theme"]);a&&(document.title=a);var p=document.createElement("div"),d="light"===s||"enterprise"===s?"light":"dark",h={family:"enterprise",colorScheme:d,density:"comfortable"};document.body.appendChild(p),Object(i.render)(o.a.createElement(f.a,h,o.a.createElement(D,c)),p),F(s,(function(t){var n;t?(n=t.create(c).getContainerElement(),"fixed"===c.layout&&(n.style.flex&&"1 0 0px"!==n.style.flex||(n.style.flex="1 0 0%"),n.style.overflow||(n.style.overflow="hidden"),n.style.width||(n.style.width="100vw"))):(console.error("Unable to load layout."),n=document.createElement("div"),document.body.appendChild(n)),setTimeout((function(){Object(i.unmountComponentAtNode)(p),p.parentNode.removeChild(p);var t=r?o.a.createElement(u.LayerStackGlobalProvider,null,o.a.createElement(f.a,h,e)):o.a.createElement(f.a,h,e);Object(i.render)(t,n)}),30)}))}}])},4310:e=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([,function(e,t,n){"use strict";n.r(t),n.d(t,"TOAST_TYPES",(function(){return r})),n.d(t,"TOAST_POSITIONS",(function(){return o}));var r={INFO:"info",WARNING:"warning",SUCCESS:"success",ERROR:"error"},o={TOP_LEFT:"top-left",TOP_CENTER:"top-center",TOP_RIGHT:"top-right",BOTTOM_LEFT:"bottom-left",BOTTOM_CENTER:"bottom-center",BOTTOM_RIGHT:"bottom-right"}}])},2034:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=21)}({19:function(e,t){e.exports=n(9726)},20:function(e,t){e.exports=n(7187)},21:function(e,t,n){"use strict";n.r(t),n.d(t,"makeCreateToast",(function(){return g}));var r=n(19),o=n(20);function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){h(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function u(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function c(e,t){return c=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},c(e,t)}function f(e,t){return!t||"object"!==i(t)&&"function"!=typeof t?p(e):t}function p(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function d(e){return d=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},d(e)}function h(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var m="toast_create",b=[],y=!1,g=function(e){return function(t){e.create(t)}},v=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&c(e,t)}(g,e);var t,n,o,i,a=(o=g,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=d(o);if(i){var n=d(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return f(this,e)});function g(){var e;u(this,g);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return h(p(e=a.call.apply(a,[this].concat(n))),"validateToastProps",(function(e){if(!e.message)return"No toast message";if(!e.type)return"No toast type";if(e.action){if(!e.action.label)return"Toast with action has no label";if(!e.action.callback)return"Toast with action has no callback"}return null})),e}return t=g,(n=[{key:"create",value:function(e){var t=this.validateToastProps(e);if(t)console.warn("Cannot create toast: ".concat(t));else{var n=l(l({},e),{},{id:Object(r.createGUID)(),timeOut:e.timeout||5e3});this.emitCreate(n)}}},{key:"emitCreate",value:function(e){y?this.emit(m,e):b.push(e)}},{key:"addCreateListener",value:function(e){var t=this;y=!0,this.addListener(m,e),b.forEach((function(e){t.emitCreate(e)})),b=[]}},{key:"removeCreateListener",value:function(e){y=!1,this.removeListener(m,e)}}])&&s(t.prototype,n),g}(o.EventEmitter);t.default=new v}})},2640:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=182)}({182:function(e,t,n){"use strict";n.r(t),n.d(t,"Spring",(function(){return s})),n.d(t,"Transition",(function(){return c}));var r=n(21),o=n(38);function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){l(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function s(e){var t=e.children,n=e.immediate,i=u(e,["children","immediate"]),l=Object(o.useAnimationToggle)();return t(Object(r.useSpring)(a({immediate:n||"on"!==l},i)))}function c(e){var t=e.items,n=e.children,i=e.immediate,l=u(e,["items","children","immediate"]),s=Object(o.useAnimationToggle)();return Object(r.useTransition)(t,a({immediate:i||"on"!==s},l))(n)}},21:function(e,t){e.exports=n(9920)},38:function(e,t){e.exports=n(6603)}})},6603:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=134)}({1:function(e,t){e.exports=n(1581)},134:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return p})),n.d(t,"AnimationToggleContext",(function(){return l})),n.d(t,"AnimationToggleProvider",(function(){return h})),n.d(t,"useAnimationToggle",(function(){return s}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=o.a.createContext(!0);function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var s=function(){var e,t,n=Object(r.useContext)(l),o="screen and (prefers-reduced-motion: reduce)",i="undefined"!=typeof window&&!!window.matchMedia,a=(e=Object(r.useState)(i&&window.matchMedia(o).matches),t=2,function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,i=void 0;try{for(var a,l=e[Symbol.iterator]();!(r=(a=l.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){o=!0,i=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw i}}return n}}(e,t)||function(e,t){if(e){if("string"==typeof e)return u(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?u(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),s=a[0],c=a[1];return Object(r.useEffect)((function(){if(i){var e=window.matchMedia(o),t=function(){c(e.matches)};return e.addListener(t),function(){e.removeListener(t)}}}),[i,o]),n?s?"reduced":"on":"off"},c={on:a.a.oneOfType([a.a.node,a.a.func]).isRequired,off:a.a.oneOfType([a.a.node,a.a.func]).isRequired,reduced:a.a.oneOfType([a.a.node,a.a.func])};function f(e){var t,n=e.on,r=e.off,o=e.reduced,i=s();return"function"==typeof(t="on"===i?n:"reduced"===i&&o?o:r)?t():t}f.propTypes=c;var p=f,d={children:a.a.node,enabled:a.a.bool},h=function(e){var t=e.children,n=e.enabled,r=void 0!==n&&n;return o.a.createElement(l.Provider,{value:r},t)};h.propTypes=d},2:function(e,t){e.exports=n(7294)}})},6493:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=154)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},154:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return h}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(3),u=n.n(l),s=n(0),c=u.a.div.withConfig({displayName:"BoxStyles__Styled",componentId:"sc-1h4b5f6-0"})(["",";align-items:stretch;align-content:stretch;flex-flow:row nowrap;flex-grow:0;flex-shrink:0;justify-content:flex-start;width:auto;max-width:100%;@media all and (-ms-high-contrast:none){max-width:calc(100% - 0.01px);}&[data-inline]{display:inline-block;vertical-align:middle;}&[data-flex]{display:flex;}&[data-flex][data-inline]{display:inline-flex;}"],s.mixins.reset("block"));function f(){return f=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},f.apply(this,arguments)}var p={children:a.a.node,elementRef:a.a.oneOfType([a.a.func,a.a.object]),flex:a.a.bool,inline:a.a.bool};function d(e){var t=e.children,n=e.elementRef,r=e.flex,i=void 0!==r&&r,a=e.inline,l=void 0!==a&&a,u=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","elementRef","flex","inline"]);return o.a.createElement(c,f({ref:n},u,{"data-inline":l||void 0,"data-flex":i||void 0}),t)}d.propTypes=p;var h=d},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)}})},6416:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=140)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},140:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return q}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(4),u=n(5),s=n(20),c=n(32),f=n(40),p=n(61),d=n.n(p),h=n(7),m=n(6);function b(){return b=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},b.apply(this,arguments)}function y(e){var t=b({},e);return o.a.createElement(m.a,b({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M3 4.10623C3 3.51257 3.47768 3.00623 4.09895 3.00623H7.49725C8.04954 3.00623 8.49725 3.45394 8.49725 4.00623C8.49725 4.55851 8.04954 5.00623 7.49725 5.00623H5V18.9937H18.9874V16.4964C18.9874 15.9441 19.4352 15.4964 19.9874 15.4964C20.5397 15.4964 20.9874 15.9441 20.9874 16.4964V19.8937C20.9874 20.5012 20.495 20.9937 19.8874 20.9937H4.1C3.49248 20.9937 3 20.5012 3 19.8937V4.10623ZM19.0002 6.42035L10.6109 14.8096C10.2204 15.2002 9.58722 15.2002 9.1967 14.8096C8.80618 14.4191 8.80618 13.7859 9.1967 13.3954L17.5859 5.00623H13.6592C13.1069 5.00623 12.6592 4.55851 12.6592 4.00623C12.6592 3.45394 13.1069 3.00623 13.6592 3.00623H19.5002C20.3287 3.00623 21.0002 3.6778 21.0002 4.50623V10.3117C21.0002 10.864 20.5525 11.3117 20.0002 11.3117C19.4479 11.3117 19.0002 10.864 19.0002 10.3117V6.42035Z",fill:"currentColor"}))}function g(e){return o.a.createElement(h.a,b({Enterprise:d.a,Prisma24:y},e))}var v=n(3),w=n.n(v),_=n(48),x=n.n(_),O=n(0),S=w.a.span.withConfig({displayName:"ButtonStyles__StyledIcon",componentId:"eqxqs2-0"})(["display:flex;align-items:center;flex-shrink:0;font-size:",";",";"],Object(O.pick)({enterprise:"inherit",prisma:{comfortable:"21px",compact:"16px"}}),Object(O.pickVariant)("$isIconOnly",{false:{enterprise:Object(v.css)(["padding-right:3px;"]),prisma:Object(v.css)(["padding-right:8px;"])}})),k=w()(x.a).withConfig({displayName:"ButtonStyles__StyledButtonSimple",componentId:"eqxqs2-1"})(["text-align:center;vertical-align:middle;text-decoration:none;white-space:nowrap;flex-grow:1;min-width:0;max-width:100%;line-height:",";min-height:",";padding:",";"," "," &[data-inline]{display:inline-block;vertical-align:middle;"," [data-inline] + &{margin-bottom:0;","}}"],O.variables.lineHeight,O.variables.inputHeight,Object(O.pick)({enterprise:{comfortable:"5px 14px",compact:"2px 14px"},prisma:{comfortable:function(e){return e.$hasPrismaIcon?"7px 18px":"9px 18px"},compact:function(e){return e.$isMenu?"5px 8px 5px 16px":"5px 16px"}}}),(function(e){var t=e.$inline,n=e.append,r=e.prepend;return!t&&!n&&!r&&Object(v.css)(["width:100%;"])}),(function(e){return e.$isIconOnly&&Object(v.css)(["box-sizing:border-box;padding:",";width:",";min-width:",";"],Object(O.pick)({enterprise:{comfortable:"0 5px",compact:"0 2px"},prisma:{comfortable:Object(v.css)(["0px calc("," / 2 - 1px)"],O.variables.inputHeight),compact:Object(v.css)(["0px calc("," / 2 - 1px)"],O.variables.inputHeight)}}),O.variables.inputHeight,O.variables.inputHeight)}),(function(e){return e.$isIconOnly?null:Object(v.css)(["width:auto;"])}),(function(e){return!e.prepend&&Object(v.css)(["margin-left:",";"],Object(O.pick)({enterprise:O.variables.spacingHalf,prisma:O.variables.spacingSmall}))})),j=w.a.span.withConfig({displayName:"ButtonStyles__StyledContentWrapper",componentId:"eqxqs2-2"})(["display:flex;flex-direction:row;justify-content:center;align-items:center;max-width:100%;padding:",";"],Object(O.pick)({enterprise:Object(O.pickVariant)("$error",{true:"1px",false:Object(O.pickVariant)("$appearance",{default:"0",secondary:"0",destructive:"0",primary:"1px",pill:"0",toggle:"0",flat:"0"})}),prisma:Object(O.pickVariant)("$appearance",{default:0,secondary:"1px 0",primary:"1px 0",destructive:"1px 0",pill:"1px 0",toggle:"0",flat:"1px 0"})})),C=w.a.span.withConfig({displayName:"ButtonStyles__StyledLabel",componentId:"eqxqs2-3"})(["text-overflow:ellipsis;overflow:hidden;flex:0 1 auto;&:not(:last-child){padding-right:",";}",""],Object(O.pick)({enterprise:"3px",prisma:"10px"}),(function(e){return e.$isMenu&&Object(v.css)(["flex:1 1 auto;text-align:left;"])})),E=w.a.span.withConfig({displayName:"ButtonStyles__StyledCaretWrapper",componentId:"eqxqs2-4"})(["display:inline-flex;",""],Object(O.pickVariant)("$disabled",{false:{prisma:Object(O.pickVariant)("$primary",{true:Object(v.css)(["color:",";"],O.variables.contentColorInverted),false:Object(v.css)(["color:",";",":hover > * > &,",":active > * > &,{color:",";}"],O.variables.contentColorDefault,k,k,O.variables.contentColorDefault)})}}));function P(e){return P="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},P(e)}function A(){return A=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},A.apply(this,arguments)}function T(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function L(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function R(e,t){return R=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},R(e,t)}function M(e,t){return!t||"object"!==P(t)&&"function"!=typeof t?D(e):t}function D(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function I(e){return I=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},I(e)}function F(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var N={action:a.a.string,appearance:a.a.oneOf(["default","secondary","primary","destructive","pill","toggle","flat"]),append:a.a.bool,children:a.a.node,classNamePrivate:a.a.string,disabled:a.a.bool,elementRef:a.a.oneOfType([a.a.func,a.a.object]),error:a.a.bool,icon:a.a.node,inline:a.a.bool,isMenu:a.a.bool,label:a.a.node,onClick:a.a.func,openInNewContext:a.a.bool,prepend:a.a.bool,selected:a.a.bool,to:a.a.string,value:a.a.any},z=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&R(e,t)}(s,e);var t,n,r,i,a=(r=s,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=I(r);if(i){var n=I(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return M(this,e)});function s(){var e;T(this,s);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return F(D(e=a.call.apply(a,[this].concat(n))),"component",null),F(D(e),"handleClick",(function(t){var n=e.props,r=n.label,o=n.icon,i=n.value,a=n.action,l=n.onClick;null==l||l(t,{label:r,icon:o,value:i,action:a})})),F(D(e),"handleMount",(function(t){e.component=t})),e}return t=s,(n=[{key:"focus",value:function(){var e;null===(e=this.component)||void 0===e||e.focus()}},{key:"render",value:function(){var e=this.props,t=e.action,n=e.appearance,r=e.append,i=e.className,a=e.classNamePrivate,s=e.disabled,p=e.error,d=e.icon,h=e.inline,m=e.isMenu,b=e.onClick,y=e.openInNewContext,v=e.prepend,w=e.to,_=e.value,x=this.props,O=x.children,P=x.label;!P&&Object(l.isString)(O)&&(P=O,O=null);var T=!(!d||P||m||O),L=w&&y||m||!!d;return o.a.createElement(k,A({"aria-haspopup":m||void 0,"aria-invalid":p||void 0,"data-test":"button"},this.props,{className:Object(c.toClassName)(i,a),"data-action":t,"data-inline":h||null,disabled:s,append:r,prepend:v,$inline:h,$hasPrismaIcon:L,$isIconOnly:T,$isMenu:m,status:p?"error":"normal",value:_,onClick:b?this.handleClick:void 0,ref:this.handleMount,openInNewContext:y,appearance:n}),o.a.createElement(j,{$appearance:n,$error:p},d&&o.a.createElement(S,{$isIconOnly:T},d),P&&o.a.createElement(C,{"data-test":"label",$isMenu:m},P),O,m&&o.a.createElement(E,{$disabled:s,$primary:"primary"===n},o.a.createElement(f.a,{enterpriseSize:.5})),y&&o.a.createElement(g,{screenReaderText:Object(u._)("Open externally"),enterpriseSize:.8,style:{verticalAlign:"baseline"}})))}}])&&L(t.prototype,n),s}(r.Component);F(z,"propTypes",N),F(z,"defaultProps",{appearance:"default",append:!1,disabled:!1,error:!1,inline:!0,isMenu:!1,openInNewContext:!1,prepend:!1,selected:!1}),F(z,s.legacyRefMode,!0);var q=z},2:function(e,t){e.exports=n(7294)},20:function(e,t){e.exports=n(6635)},3:function(e,t){e.exports=n(2788)},32:function(e,t){e.exports=n(9867)},4:function(e,t){e.exports=n(5220)},40:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),i=n(41),a=n.n(i),l=n(7),u=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M7.2788 9.00002C6.84609 9.00002 6.61768 9.51239 6.90691 9.83423L11.4078 14.8426C11.6065 15.0637 11.953 15.0636 12.1517 14.8425L16.6499 9.8341C16.939 9.51223 16.7106 9 16.2779 9L7.2788 9.00002Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:a.a,Prisma24:c},e))}},41:function(e,t){e.exports=n(7924)},48:function(e,t){e.exports=n(2254)},5:function(e,t){e.exports=n(6219)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return u}));var r=n(2),o=n.n(r),i=n(3);function a(){return a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}var l=n.n(i).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function u(e){return o.a.createElement(l,a({xmlns:"http://www.w3.org/2000/svg"},e))}},61:function(e,t){e.exports=n(5175)},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return h}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(0);function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}var f={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},p={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:a.a.func,enterpriseSize:a.a.oneOfType([a.a.number,a.a.string]),enterpriseWidth:a.a.oneOfType([a.a.number,a.a.string]),enterpriseHeight:a.a.oneOfType([a.a.number,a.a.string]),Prisma24:a.a.func.isRequired,Prisma20:a.a.func,Prisma16:a.a.func,prismaSize:a.a.oneOf(["medium","small"]),inline:a.a.bool,screenReaderText:a.a.string};function h(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,i=e.Prisma16,a=e.prismaSize,d=e.inline,h=e.enterpriseSize,m=e.enterpriseWidth,b=e.enterpriseHeight,y=e.screenReaderText,g=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),v=Object(l.useSplunkTheme)(),w=v.family,_=v.density;if("enterprise"===w)return o.a.createElement(t,c({size:h,width:m,height:b,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},g));var x=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?u(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):u(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?f:p},g);if("small"===a){var O=i||n;return o.a.createElement(O,c({width:"16",height:"16"},x))}if("compact"===_){var S=r||n;return o.a.createElement(S,c({width:"20",height:"20"},x))}return o.a.createElement(n,c({width:"24",height:"24"},x))}h.propTypes=d,h.defaultProps={inline:!0,prismaSize:"medium"}}})},2254:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=135)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},12:function(e,t){e.exports=n(5917)},135:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return W}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(5),u=n(0),s=n(14),c=n.n(s),f=n(3),p=n.n(f),d=n(12),h=n.n(d),m=Object(f.css)([""," cursor:pointer;position:relative;border-radius:",";&:focus,&:hover{z-index:3;}"],u.mixins.reset("block"),u.variables.borderRadius),b=Object(f.css)([""," ",""],(function(e){return e.$append&&Object(f.css)(["border-top-right-radius:0.1px;border-bottom-right-radius:0.1px;border-right:none;"])}),(function(e){return e.$prepend&&Object(f.css)(["border-top-left-radius:0.1px;border-bottom-left-radius:0.1px;"])})),y=Object(f.css)([""," "," "," &:not([disabled]){color:",";transition:background-color 0.2s,border 0.2s,box-shadow 0.2s,text-decoration 0.2s;&:hover{background-color:",";border-color:",";","}"," "," &:active{background-color:",";transition:none;}&:focus{background-color:",";"," &:active{background-color:",";}}}&[disabled]{border-color:",";color:",";cursor:not-allowed;","}"],m,Object(u.pickVariant)("$variant",{prismaSecondary:Object(f.css)(["font-weight:",";"],u.variables.fontWeightSemiBold),prismaDefault:Object(f.css)(["border:1px solid ",";font-weight:",";"],u.variables.interactiveColorBorder,u.variables.fontWeightSemiBold),prismaToggle:Object(f.css)(["border:1px solid ",";font-weight:normal;"],u.variables.interactiveColorBorder)}),b,u.variables.contentColorActive,u.variables.interactiveColorOverlayHover,u.variables.interactiveColorBorderHover,Object(u.pickVariant)("$variant",{prismaSecondary:Object(f.css)(["box-shadow:",";"],u.variables.hoverShadow),prismaDefault:Object(f.css)(["box-shadow:",";"],u.variables.hoverShadow)}),(function(e){return e.$selected&&Object(f.css)(["background-color:",";border-color:",";&:hover{background-color:",";}"],u.variables.interactiveColorOverlaySelected,u.variables.interactiveColorBorderDisabled,u.mixins.overlayColors(u.variables.interactiveColorOverlaySelected,u.variables.interactiveColorOverlayHover))}),(function(e){return e.$error&&Object(f.css)(["border-color:",";&:hover{border-color:",";}"],u.variables.accentColorNegative,u.variables.accentColorNegative)}),u.variables.interactiveColorOverlayActive,u.variables.interactiveColorOverlayHover,Object(u.pickVariant)("$variant",{prismaSecondary:Object(f.css)(["box-shadow:",";"],u.variables.focusShadow),prismaDefault:Object(f.css)(["box-shadow:",";"],u.variables.focusShadow),prismaToggle:Object(f.css)(["border-color:",";"],u.variables.interactiveColorPrimary)}),u.variables.interactiveColorOverlayActive,u.variables.interactiveColorBorderDisabled,u.variables.contentColorDisabled,(function(e){return e.$selected&&Object(f.css)(["background-color:",";"],u.mixins.overlayColors(u.variables.interactiveColorBackgroundDisabled,u.variables.interactiveColorOverlaySelected))})),g=Object(f.css)(["&[disabled]{border-color:",";color:",";background-color:",";cursor:not-allowed;","}"],u.variables.interactiveColorBorderDisabled,u.variables.contentColorDisabled,u.variables.interactiveColorBackgroundDisabled,(function(e){return e&&Object(f.css)(["background-color:",";"],u.mixins.overlayColors(u.variables.interactiveColorBackgroundDisabled,u.variables.interactiveColorOverlaySelected))})),v=Object(f.css)([""," font-weight:",";border-radius:",";"," &:not([disabled]){color:",";transition:background-color 0.2s,box-shadow 0.2s,text-decoration 0.2s;background-color:",";&:hover,&:focus{background-color:",";}&:hover{box-shadow:",";}&:focus{box-shadow:",";}&:active{background-color:",";transition:none;}}",""],m,u.variables.fontWeightSemiBold,u.variables.borderRadius,b,u.variables.contentColorInverted,Object(u.pickVariant)("$selected",{false:Object(u.pickVariant)("$variant",{prismaPrimary:u.variables.interactiveColorPrimary,prismaDestructive:u.variables.accentColorNegative}),true:Object(u.pickVariant)("$variant",{prismaPrimary:u.mixins.overlayColors(u.variables.interactiveColorPrimary,u.variables.interactiveColorOverlaySelected),prismaDestructive:u.mixins.overlayColors(u.variables.accentColorNegative,u.variables.interactiveColorOverlaySelected)})}),Object(u.pickVariant)("$variant",{prismaPrimary:u.mixins.overlayColors(u.variables.interactiveColorPrimary,u.variables.interactiveColorOverlayHover),prismaDestructive:u.mixins.overlayColors(u.variables.accentColorNegative,u.variables.interactiveColorOverlayHover)}),u.variables.hoverShadow,u.variables.focusShadow,Object(u.pickVariant)("$variant",{prismaPrimary:u.mixins.overlayColors(u.variables.interactiveColorPrimary,u.variables.interactiveColorOverlayActive),prismaDestructive:u.mixins.overlayColors(u.variables.accentColorNegative,u.variables.interactiveColorOverlayActive)}),g),w=Object(f.css)([""," font-weight:",";border-radius:",";"," &:not([disabled]){color:",";background-color:",";transition:background-color 0.2s,box-shadow 0.2s,text-decoration 0.2s;"," &:hover{background-color:",";box-shadow:",";}&:active{background-color:",";transition:none;}&:focus{box-shadow:",";background-color:",";}}",""],m,u.variables.fontWeightSemiBold,u.variables.borderRadius,b,u.variables.contentColorActive,u.variables.interactiveColorBackground,(function(e){return e&&Object(f.css)(["background-color:",";"],u.mixins.overlayColors(u.variables.interactiveColorBackground,u.variables.interactiveColorOverlaySelected))}),u.mixins.overlayColors(u.variables.interactiveColorBackground,u.variables.interactiveColorOverlayHover),u.variables.hoverShadow,u.mixins.overlayColors(u.variables.interactiveColorBackground,u.variables.interactiveColorOverlayActive),u.variables.focusShadow,u.mixins.overlayColors(u.variables.interactiveColorBackground,u.variables.interactiveColorOverlayHover),g),_="#1A8929",x=Object(f.css)([""," border-radius:",";cursor:pointer;position:relative;&:focus{z-index:3;}"],u.mixins.reset("block"),u.variables.borderRadius),O=Object(f.css)([""," ",""],(function(e){return e.$append&&Object(f.css)(["border-top-right-radius:0;border-bottom-right-radius:0;border-right:none;"])}),(function(e){return e.$prepend&&Object(f.css)(["border-top-left-radius:0;border-bottom-left-radius:0;"])})),S="inset 0 -1px 0 rgba(0, 0, 0, 0.1)",k="inset 0 1px 0 rgba(0, 0, 0, 0.1)",j=Object(f.css)(["",";border:",";",";font-weight:",";&:not([disabled]){background-color:",";color:",";transition:background-image 0.2s,border 0.2s,box-shadow 0.2s,text-decoration 0.2s;",";"," &:hover{background-color:",";box-shadow:",";}&:active{transition:none;background-color:",";border-color:",";",";}&:focus{box-shadow:",",",";"," ","}}&[disabled]{cursor:not-allowed;color:",";background-color:",";border-color:",";","}"],x,Object(u.pick)({light:Object(f.css)(["1px solid ",""],u.variables.gray60),dark:u.variables.border}),O,Object(u.pickVariant)("$variant",{enterpriseDefault:"normal",enterpriseSecondary:u.variables.fontWeightSemiBold}),Object(u.pick)({light:u.variables.gray98,dark:u.variables.gray45}),Object(u.pick)({light:u.variables.gray45,dark:u.variables.white}),Object(u.pick)({light:Object(f.css)(["box-shadow:",";"],S),dark:Object(f.css)(["box-shadow:inset 0 -1px 0 ",";"],u.variables.gray30)}),(function(e){return e.$selected&&Object(f.css)(["box-shadow:",";background-color:",";border-color:",";"],Object(u.pick)({light:k,dark:Object(f.css)(["inset 0 1px 0 ",""],u.variables.black)}),Object(u.pick)({light:u.variables.gray92,dark:u.variables.gray22}),Object(u.pick)({light:u.variables.gray60,dark:u.variables.gray20}))}),Object(u.pick)({light:"#ebeeef",dark:u.variables.gray30}),Object(u.pick)({light:S,dark:Object(f.css)(["inset 0 -1px 0 ",""],u.variables.gray25)}),Object(u.pick)({light:u.variables.gray92,dark:u.variables.gray22}),Object(u.pick)({light:u.variables.gray60,dark:u.variables.gray20}),Object(u.pick)({dark:Object(f.css)(["box-shadow:inset 0 -1px 0 ",";"],u.variables.gray22)}),Object(u.pick)({light:S,dark:Object(f.css)(["inset 0 -1px 0 ",""],u.variables.gray30)}),u.variables.focusShadow,(function(e){return e.$append&&Object(f.css)(["box-shadow:",",",",inset -1px 0 0 ",";"],Object(u.pick)({light:S,dark:Object(f.css)(["inset 0 -1px 0 ",""],u.variables.gray30)}),u.variables.focusShadow,u.variables.borderColor)}),(function(e){var t=e.$append,n=e.$selected;return t&&n&&Object(u.pick)({light:Object(f.css)(["box-shadow:",",",",",",inset -1px 0 0 ",";"],S,k,u.variables.focusShadow,u.variables.borderColor),dark:Object(f.css)(["box-shadow:inset 0 1px 0 ",",",",inset -1px 0 0 ",";"],u.variables.black,u.variables.focusShadow,u.variables.borderColor)})}),u.variables.textDisabledColor,Object(u.pick)({light:u.variables.gray96,dark:u.variables.gray30}),Object(u.pick)({light:u.variables.borderLightColor,dark:u.variables.gray30}),(function(e){return e.$selected&&Object(u.pick)({light:Object(f.css)(["box-shadow:",";background-color:",";border-color:",";"],k,u.variables.gray92,u.variables.gray80),dark:Object(f.css)(["box-shadow:inset 0 1px 0 ",";background-color:",";border-color:",";"],u.variables.black,u.variables.gray22,u.variables.gray20)})})),C="inset 0 -2px 0 rgba(0, 0, 0, 0.1)",E="inset 0 2px 0 rgba(0, 0, 0, 0.1)",P=Object(f.css)(["",";font-weight:",";"," &:not([disabled]){background-color:",";color:",";box-shadow:",";transition:background-image 0.2s,border 0.2s,box-shadow 0.2s,text-decoration 0.2s;"," "," &:hover{background-color:",";}&:active{background-color:",";transition:none;}&:focus{box-shadow:",",",";&:active{background-color:",";transition:none;}}}&[disabled]{color:",";background-color:",";cursor:not-allowed;","}"],x,u.variables.fontWeightSemiBold,O,_,u.variables.white,C,(function(e){return e.$selected&&Object(f.css)(["box-shadow:",";background-color:",";"],E,"#235823")}),(function(e){return e.$prepend&&Object(f.css)(["border-left:1px solid ",";"],_)}),u.variables.brandColorD50,u.variables.brandColorD30,C,u.variables.focusShadow,u.variables.brandColorD30,u.variables.brandColorL30,u.variables.brandColorL10,(function(e){return e.$selected&&Object(f.css)(["box-shadow:",";background-color:",";"],E,u.variables.brandColorD20)})),A=Object(f.css)(["",";font-weight:",";"," &:not([disabled]){background-color:",";color:",";box-shadow:",";transition:background-image 0.2s,border 0.2s,box-shadow 0.2s,text-decoration 0.2s;"," "," &:hover{background-color:",";}&:active{background-color:",";transition:none;}&:focus{box-shadow:",",",";&:active{background-color:",";transition:none;}}}&[disabled]{color:",";background-color:",";cursor:not-allowed;","}"],x,u.variables.fontWeightSemiBold,O,u.variables.errorColor,u.variables.white,C,(function(e){return e.$selected&&Object(f.css)(["box-shadow:",";background-color:",";"],E,u.variables.errorColorD20)}),(function(e){return e.$prepend&&Object(f.css)(["border-left:1px solid ",";"],u.variables.errorColorD20)}),u.variables.errorColorD20,u.variables.errorColorD30,C,u.variables.focusShadow,u.variables.errorColorD30,u.variables.errorColorL30,u.variables.errorColorL10,(function(e){return e.$selected&&Object(f.css)(["box-shadow:",";background-color:",";"],E,u.variables.errorColorD20)})),T=Object(f.css)(["",";color:",";border:1px solid transparent;&:not([disabled]){transition:background-color 0.2s,border 0.2s,box-shadow 0.2s,text-decoration 0.2s;"," &:hover{color:",";background-color:",";border-color:",";}"," &:focus{color:",";box-shadow:",";}&:active,&[aria-expanded='true']{background-color:",";transition:none;}}&[disabled]{color:",";cursor:not-allowed;","}"],x,Object(u.pick)({light:u.variables.gray45,dark:u.variables.white}),(function(e){return e.$selected&&Object(f.css)(["border-color:",";"],u.variables.accentColor)}),Object(u.pick)({light:u.variables.linkColor,dark:u.variables.white}),u.variables.backgroundColorHover,Object(u.pick)({light:u.variables.gray60,dark:u.variables.borderColor}),(function(e){return e.$error&&Object(f.css)(["&,&:hover{color:",";}"],u.variables.errorColor)}),Object(u.pick)({light:u.variables.linkColor,dark:u.variables.white}),u.variables.focusShadow,Object(u.pick)({light:u.variables.gray92,dark:u.variables.gray22}),u.variables.textDisabledColor,(function(e){return e.$selected&&Object(f.css)(["border-color:",";"],u.variables.borderLightColor)})),L=p()(h.a).withConfig({displayName:"ButtonSimpleStyles__StyledClickable",componentId:"vlarwe-0"})(["",""],Object(u.pickVariant)("$variant",{enterpriseDefault:j,enterpriseSecondary:j,enterprisePrimary:P,enterpriseError:A,enterprisePill:T,prismaDefault:y,prismaDestructive:v,prismaPrimary:v,prismaSecondary:y,prismaToggle:y,prismaFlat:w}));function R(e){return R="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},R(e)}function M(){return M=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},M.apply(this,arguments)}function D(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function I(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function F(e,t){return F=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},F(e,t)}function N(e,t){return!t||"object"!==R(t)&&"function"!=typeof t?z(e):t}function z(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function q(e){return q=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},q(e)}function $(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var B={action:a.a.string,appearance:a.a.oneOf(["default","secondary","primary","destructive","pill","toggle","flat"]),append:a.a.bool,children:a.a.node,disabled:a.a.bool,elementRef:a.a.oneOfType([a.a.func,a.a.object]),inline:a.a.bool,openInNewContext:a.a.bool,prepend:a.a.bool,selected:a.a.bool,splunkTheme:a.a.object,status:a.a.oneOf(["normal","error"]),to:a.a.string},U=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&F(e,t)}(u,e);var t,n,r,i,a=(r=u,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=q(r);if(i){var n=q(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return N(this,e)});function u(){var e;D(this,u);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return $(z(e=a.call.apply(a,[this].concat(n))),"component",null),$(z(e),"handleMount",(function(t){e.component=t})),e}return t=u,(n=[{key:"focus",value:function(){var e;null===(e=this.component)||void 0===e||e.focus()}},{key:"mapVariant",value:function(){var e=this.props,t=e.splunkTheme,n=e.appearance,r=e.status;return"enterprise"===t.family?"error"===r?"enterpriseError":{default:"enterpriseDefault",destructive:"enterpriseDefault",primary:"enterprisePrimary",secondary:"enterpriseSecondary",pill:"enterprisePill",toggle:"enterpriseDefault",flat:"enterpriseDefault"}[n]:{default:"prismaDefault",destructive:"prismaDestructive",primary:"prismaPrimary",secondary:"prismaSecondary",pill:"prismaSecondary",toggle:"prismaToggle",flat:"prismaFlat"}[n]}},{key:"render",value:function(){var e=this.props,t=e.append,n=e.children,r=e.prepend,i=e.selected,a=e.status,u=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["append","children","prepend","selected","status"]);return o.a.createElement(L,M({"aria-invalid":"error"===a||void 0,"data-test":"button-simple",ref:this.handleMount,$variant:this.mapVariant(),$error:"error"===a,$append:t,$prepend:r,$selected:i},u),n,i&&o.a.createElement(c.a,null,Object(l._)("Selected")))}}])&&I(t.prototype,n),u}(r.Component);$(U,"defaultProps",{appearance:"default",append:!1,disabled:!1,inline:!0,openInNewContext:!1,prepend:!1,selected:!1,status:"normal"}),$(U,"propTypes",B);var V=Object(u.withSplunkTheme)(U);V.propTypes=U.propTypes;var W=V},14:function(e,t){e.exports=n(5766)},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)},5:function(e,t){e.exports=n(6219)}})},5917:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=141)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},10:function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},141:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return M})),n.d(t,"isInternalLink",(function(){return P})),n.d(t,"NavigationContext",(function(){return h})),n.d(t,"NavigationProvider",(function(){return m}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(4),u=n(20),s=n(3),c=n.n(s),f=n(0),p=c.a.a.withConfig({displayName:"ClickableStyles__StyledA",componentId:"sc-7al1vw-0"})([""," cursor:pointer;&[disabled]{cursor:not-allowed;color:",";}&::-moz-focus-inner{border:0;padding:0;}"],f.mixins.reset("inline"),f.variables.contentColorDisabled),d={children:a.a.node,onClick:a.a.func,prefix:a.a.string},h=o.a.createContext({});function m(e){var t=e.children,n=e.onClick,r=e.prefix;return o.a.createElement(h.Provider,{value:{onClick:n,prefix:r}},t)}m.propTypes=d;var b=n(10);function y(e){return y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},y(e)}function g(){return g=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},g.apply(this,arguments)}function v(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function w(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function _(e,t){return _=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},_(e,t)}function x(e,t){return!t||"object"!==y(t)&&"function"!=typeof t?O(e):t}function O(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function S(e){return S=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},S(e)}function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var j=/^[a-z0-9]+:/,C=/^\/\//,E=/^\//,P=function(e){return null!=e&&!j.test(e)&&!C.test(e)},A={allowDisabledLink:a.a.bool,children:a.a.node,disabled:a.a.bool,elementRef:a.a.oneOfType([a.a.func,a.a.object]),onClick:a.a.func,openInNewContext:a.a.bool,navigationLabel:a.a.string,to:a.a.string};function T(e){return!!e.to&&!e.disabled}function L(e,t){return null!=t&&P(e)&&E.test(e)?"".concat(t).concat(e):e}var R=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&_(e,t)}(u,e);var t,n,r,i,a=(r=u,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=S(r);if(i){var n=S(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return x(this,e)});function u(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,u),k(O(t=a.call(this,e)),"el",null),k(O(t),"handleMount",(function(e){t.el=e,Object(b.a)(t.props.elementRef,e)})),k(O(t),"createHandleOnClick",(function(e){return function(n){if(!T(t.props)||!n.metaKey&&!n.ctrlKey||!t.props.to)if(t.props.onClick)t.props.onClick(n);else if(T(t.props)&&e){var r=t.context.prefix,o=t.props.navigationLabel;!o&&Object(l.isString)(t.props.children)&&(o=t.props.children),e(n,{to:L(t.props.to,r),originalTo:t.props.to,openInNewContext:t.props.openInNewContext,label:o})}}})),t}return t=u,(n=[{key:"focus",value:function(){var e;null===(e=this.el)||void 0===e||e.focus()}},{key:"render",value:function(){var e=this.context,t=e.onClick,n=e.prefix,r=this.createHandleOnClick(t);if(T(this.props)){var i=this.props,a=i.children,u=i.openInNewContext,s=i.to,c=v(i,["children","openInNewContext","to"]),f=u?"_blank":void 0,d=u&&P(s)?"noopener noreferrer":void 0;return o.a.createElement(p,g({"data-test":"clickable",ref:this.handleMount,href:L(this.props.to,n),target:f,rel:d,onClick:r},Object(l.omit)(c,"disabled","elementRef","onClick")),a)}if(this.props.allowDisabledLink){var h=this.props,m=h.children,b=v(h,["children"]);if(this.props.disabled&&null!=this.props.to)return o.a.createElement(p,g({"data-test":"clickable",ref:this.handleMount},Object(l.omit)(b,"href","elementRef","onClick")),m)}var y=this.props,w=y.children,_=y.type,x=v(y,["children","type"]);return o.a.createElement(p,g({as:"button","data-test":"clickable",ref:this.handleMount,type:_||"button",onClick:r},Object(l.omit)(x,"elementRef","onClick","openInNewContext","to")),w)}}])&&w(t.prototype,n),u}(r.Component);k(R,"contextType",h),k(R,"propTypes",A),k(R,"defaultProps",{disabled:!1,openInNewContext:!1}),k(R,u.legacyRefMode,!0);var M=R},2:function(e,t){e.exports=n(7294)},20:function(e,t){e.exports=n(6635)},3:function(e,t){e.exports=n(2788)},4:function(e,t){e.exports=n(5220)}})},1983:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=158)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},158:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return g}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(5),u=n(22),s=n(3),c=n.n(s),f=n(48),p=n.n(f),d=n(0),h=c()(p.a).withConfig({displayName:"CloseButtonStyles__StyledButtonSimple",componentId:"b3h40f-0"})(["float:right;width:",";height:",";text-align:center;"],d.variables.inputHeight,d.variables.inputHeight);function m(){return m=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},m.apply(this,arguments)}var b={disabled:a.a.bool,elementRef:a.a.oneOfType([a.a.func,a.a.object]),screenReaderText:a.a.string};function y(e){var t=e.disabled,n=void 0!==t&&t,r=e.screenReaderText,i=void 0===r?Object(l._)("Close"):r,a=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["disabled","screenReaderText"]);return o.a.createElement(h,m({appearance:"pill",disabled:n},a),o.a.createElement(u.a,{enterpriseSize:"13px",screenReaderText:i,inline:!1}))}y.propTypes=b;var g=y},2:function(e,t){e.exports=n(7294)},22:function(e,t,n){"use strict";n.d(t,"a",(function(){return p}));var r=n(2),o=n.n(r),i=n(23),a=n.n(i),l=n(7),u=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L10.5858 12L5.2929 17.2929C4.90238 17.6834 4.90238 18.3166 5.2929 18.7071C5.68342 19.0976 6.31659 19.0976 6.70711 18.7071L12 13.4142L17.2929 18.7071C17.6834 19.0976 18.3166 19.0976 18.7071 18.7071C19.0976 18.3166 19.0976 17.6834 18.7071 17.2929L13.4142 12L18.7071 6.70711C19.0976 6.31658 19.0976 5.68342 18.7071 5.29289C18.3166 4.90237 17.6834 4.90237 17.2929 5.29289L12 10.5858L6.70711 5.29289Z",fill:"currentColor"}))}function f(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M12.2024 2.69009C12.5092 2.38325 13.0067 2.38325 13.3136 2.69009C13.6204 2.99693 13.6204 3.49442 13.3136 3.80126L9.11721 7.99762L13.3114 12.1918C13.6206 12.501 13.6206 13.0023 13.3114 13.3114C13.0023 13.6206 12.501 13.6206 12.1918 13.3114L7.99762 9.11721L3.885 13.2298C3.57816 13.5367 3.08067 13.5367 2.77383 13.2298C2.46699 12.923 2.46699 12.4255 2.77383 12.1187L6.88645 8.00604L2.69183 3.81142C2.38267 3.50226 2.38267 3.001 2.69183 2.69183C3.001 2.38267 3.50226 2.38267 3.81142 2.69183L8.00604 6.88646L12.2024 2.69009Z",fill:"currentColor"}))}function p(e){return o.a.createElement(l.a,s({Enterprise:a.a,Prisma16:f,Prisma24:c},e))}},23:function(e,t){e.exports=n(1476)},3:function(e,t){e.exports=n(2788)},48:function(e,t){e.exports=n(2254)},5:function(e,t){e.exports=n(6219)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return u}));var r=n(2),o=n.n(r),i=n(3);function a(){return a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}var l=n.n(i).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function u(e){return o.a.createElement(l,a({xmlns:"http://www.w3.org/2000/svg"},e))}},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return h}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(0);function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}var f={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},p={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:a.a.func,enterpriseSize:a.a.oneOfType([a.a.number,a.a.string]),enterpriseWidth:a.a.oneOfType([a.a.number,a.a.string]),enterpriseHeight:a.a.oneOfType([a.a.number,a.a.string]),Prisma24:a.a.func.isRequired,Prisma20:a.a.func,Prisma16:a.a.func,prismaSize:a.a.oneOf(["medium","small"]),inline:a.a.bool,screenReaderText:a.a.string};function h(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,i=e.Prisma16,a=e.prismaSize,d=e.inline,h=e.enterpriseSize,m=e.enterpriseWidth,b=e.enterpriseHeight,y=e.screenReaderText,g=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),v=Object(l.useSplunkTheme)(),w=v.family,_=v.density;if("enterprise"===w)return o.a.createElement(t,c({size:h,width:m,height:b,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},g));var x=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?u(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):u(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?f:p},g);if("small"===a){var O=i||n;return o.a.createElement(O,c({width:"16",height:"16"},x))}if("compact"===_){var S=r||n;return o.a.createElement(S,c({width:"20",height:"20"},x))}return o.a.createElement(n,c({width:"24",height:"24"},x))}h.propTypes=d,h.defaultProps={inline:!0,prismaSize:"medium"}}})},8119:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=162)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},162:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return h}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(3),u=n.n(l),s=n(0),c=u.a.hr.withConfig({displayName:"DividerStyles__StyledRule",componentId:"gl6kyz-0"})(["",";",";border-color:",";"],s.mixins.reset("block"),Object(s.pickVariant)("$orientation",{horizontal:Object(l.css)(["border-top-style:solid;border-width:1px;"]),vertical:Object(l.css)(["display:inline;border-left-style:solid;border-width:1px;"])}),Object(s.pick)({enterprise:s.variables.borderColor,prisma:s.variables.neutral200}));function f(){return f=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},f.apply(this,arguments)}var p={elementRef:a.a.oneOfType([a.a.func,a.a.object]),orientation:a.a.oneOf(["horizontal","vertical"])};function d(e){var t=e.elementRef,n=e.orientation,r=void 0===n?"horizontal":n,i=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["elementRef","orientation"]);return o.a.createElement(c,f({"data-test":"divider",ref:t,"aria-orientation":r,$orientation:r},i))}d.propTypes=p;var h=d},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)}})},6635:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=183)}({1:function(e,t){e.exports=n(1581)},10:function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},11:function(e,t){e.exports=n(9726)},18:function(e,t){e.exports=n(9016)},183:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return k})),n.d(t,"legacyRefMode",(function(){return O}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(4),u=n(11),s=n(18),c=n.n(s),f=n(10);function p(e){return p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},p(e)}function d(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function h(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function m(e,t){return m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},m(e,t)}function b(e,t){return!t||"object"!==p(t)&&"function"!=typeof t?y(e):t}function y(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function g(e){return g=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},g(e)}function v(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var w=["clickAway","contentClick","escapeKey","offScreen","tabKey","toggleClick"],_={align:a.a.oneOf(["center","edge","theme","end"]),canCoverAnchor:a.a.bool,children:a.a.oneOfType([a.a.node,a.a.func]),closeReasons:a.a.arrayOf(a.a.oneOf(w)),defaultPlacement:a.a.oneOf(["above","below","left","right","vertical","horizontal"]),elementRef:a.a.oneOfType([a.a.func,a.a.object]),focusToggleReasons:a.a.arrayOf(a.a.oneOf(w)),inputId:a.a.string,onRequestClose:a.a.func,onRequestOpen:a.a.func,open:a.a.bool,repositionMode:a.a.oneOf(["none","flip","any"]),retainFocus:a.a.bool,takeFocus:a.a.bool,toggle:a.a.element.isRequired},x={align:"theme",canCoverAnchor:!0,closeReasons:w,defaultPlacement:"below",focusToggleReasons:["contentClick","escapeKey","tabKey","toggleClick"],repositionMode:"flip",retainFocus:!1,takeFocus:!0},O=Symbol("Dropdown legacy ref mode marker"),S=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&m(e,t)}(p,e);var t,n,i,a,s=(i=p,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=g(i);if(a){var n=g(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return b(this,e)});function p(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,p),v(y(t=s.call(this,e)),"controlledExternally",void 0),v(y(t),"popoverId",void 0),v(y(t),"toggleRef",null),v(y(t),"toggleId",void 0),v(y(t),"handleToggleMount",(function(e){t.toggleRef=e,t.setState({anchor:e}),t.props.toggle.type[O]?Object(f.a)(t.props.toggle.props.elementRef,e):Object(f.a)(t.props.toggle.ref,e)})),v(y(t),"handleToggleClick",(function(e){var n,r,o,i;null===(n=(r=t.props.toggle.props).onClick)||void 0===n||n.call(r,e),t.isOpen()?t.handleRequestClose({reason:"toggleClick",event:e}):(null===(o=(i=t.props).onRequestOpen)||void 0===o||o.call(i,e,{reason:"toggleClick"}),t.isControlled()||t.setState({open:!0}))})),v(y(t),"handleRequestClose",(function(e){var n=e.event,r=e.reason,o=t.props,i=o.closeReasons,a=o.focusToggleReasons,u=o.onRequestClose;if(n&&"clickAway"===r)for(var s=n.target,c=t.props.inputId||t.props.toggle.props.id||t.toggleId;s;){if(s.id===c)return;s=s.parentNode}t.isOpen()&&Object(l.includes)(i,r)&&(Object(l.includes)(a,r)&&t.focus(),t.isControlled()||t.setState({open:!1}),null==u||u(e))})),v(y(t),"handleContentClick",(function(e){t.handleRequestClose({reason:"contentClick",event:e})})),t.state={anchor:null,open:!1},t.controlledExternally=Object(l.has)(e,"open"),t.popoverId=Object(u.createDOMID)("popover"),t.toggleId=Object(u.createDOMID)("toggle"),t}return t=p,n=[{key:"componentDidUpdate",value:function(){!function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?d(Object(n),!0).forEach((function(t){v(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):d(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}}({},Object(l.omit)(this.props,Object(l.keys)(p.propTypes),"value","id"))}},{key:"isOpen",value:function(){return this.isControlled()?this.props.open:this.state.open}},{key:"focus",value:function(){var e;null===(e=this.toggleRef)||void 0===e||e.focus()}},{key:"isControlled",value:function(){return this.controlledExternally}},{key:"renderToggle",value:function(){var e;return Object(r.cloneElement)(this.props.toggle,(v(e={onClick:this.handleToggleClick},this.props.toggle.type[O]?"elementRef":"ref",this.handleToggleMount),v(e,"aria-controls",this.isOpen()?this.popoverId:void 0),v(e,"aria-haspopup",!0),v(e,"aria-expanded",this.isOpen()),v(e,"data-test",this.props.toggle.props["data-test"]||"dropdown"),v(e,"data-test-popover-id",this.popoverId),v(e,"id",this.props.inputId||this.props.toggle.props.id||this.toggleId),e))}},{key:"render",value:function(){var e=this.props,t=e.align,n=e.canCoverAnchor,r=e.children,i=e.closeReasons,a=e.defaultPlacement,u=e.elementRef,s=e.repositionMode,f=e.retainFocus,p=e.takeFocus,d=this.state.anchor,h=this.handleRequestClose,m=this.handleContentClick,b=this.renderToggle();return o.a.createElement(o.a.Fragment,null,b,o.a.createElement(c.a,{align:t,open:!!d&&this.isOpen(),autoCloseWhenOffScreen:Object(l.includes)(i,"offScreen"),anchor:d,canCoverAnchor:n,elementRef:u,retainFocus:f,defaultPlacement:a,onRequestClose:h,repositionMode:s,id:this.popoverId,"aria-labelledby":this.props.inputId||this.props.toggle.props.id||this.toggleId,takeFocus:p},Object(l.isFunction)(r)?function(){return o.a.createElement("div",{onClick:m},r.apply(void 0,arguments))}:o.a.createElement("div",{onClick:m},r)))}}],n&&h(t.prototype,n),p}(r.Component);v(S,"possibleCloseReasons",w),v(S,"propTypes",_),v(S,"defaultProps",x);var k=S},2:function(e,t){e.exports=n(7294)},4:function(e,t){e.exports=n(5220)}})},9213:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=184)}({1:function(e,t){e.exports=n(1581)},184:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return f}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(89),u=n.n(l),s={children:a.a.node,target:a.a.oneOfType([a.a.object,a.a.string]),eventType:a.a.any,listener:a.a.func,options:a.a.oneOfType([a.a.object,a.a.bool])};function c(e){var t=e.children,n=e.target,r=e.eventType,i=e.listener,a=e.options;return u()(n,r,i,a),o.a.createElement(o.a.Fragment,null,t||null)}c.propTypes=s;var f=c},2:function(e,t){e.exports=n(7294)},89:function(e,t){e.exports=n(7979)}})},5451:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=165)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},113:function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},15:function(e,t){e.exports=n(9213)},165:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return P})),n.d(t,"LayerStackContext",(function(){return p.b})),n.d(t,"LayerContext",(function(){return p.a})),n.d(t,"LayerStackGlobalProvider",(function(){return p.c}));var r=n(2),o=n.n(r),i=n(70),a=n(1),l=n.n(a),u=n(4),s=n(9),c=n(15),f=n.n(c),p=n(71),d=n(3),h=n.n(d),m=n(0),b=h.a.div.withConfig({displayName:"LayerStyles__StyledLayer",componentId:"ii6psl-0"})(["",""],(function(e){return e.$separateStackingContexts&&Object(d.css)(["isolation:isolate;z-index:",";"],m.variables.zindexLayer)})),y=n(27);function g(e){return g="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},g(e)}function v(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function w(e,t){return w=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},w(e,t)}function _(e,t){return!t||"object"!==g(t)&&"function"!=typeof t?x(e):t}function x(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function O(e){return O=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},O(e)}function S(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var k=["clickAway","escapeKey"],j={children:l.a.node,closeReasons:l.a.arrayOf(l.a.oneOf(k)),onRequestClose:l.a.func,open:l.a.bool},C={closeReasons:k,open:!1},E=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&w(e,t)}(c,e);var t,n,r,a,l=(r=c,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=O(r);if(a){var n=O(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return _(this,e)});function c(e){var t;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,c),S(x(t=l.call(this,e)),"layerClickEvent",null),S(x(t),"handleClickOnLayer",(function(e){var n=e.nativeEvent;t.layerClickEvent=n})),S(x(t),"handleClickOnWindow",(function(e){var n,r;t.props.open&&Object(u.includes)(t.props.closeReasons,"clickAway")&&t.layerClickEvent!==e&&(null===(n=(r=t.props).onRequestClose)||void 0===n||n.call(r,{event:e,reason:"clickAway"}))})),S(x(t),"handleKeyDownOnWindow",(function(e){var n,r;t.props.open&&"esc"===Object(s.keycode)(e)&&Object(u.last)(t.getLayerStack())===x(t)&&Object(u.includes)(t.props.closeReasons,"escapeKey")&&(null===(n=(r=t.props).onRequestClose)||void 0===n||n.call(r,{event:e,reason:"escapeKey"}))}));var n=Object(y.a)();return c.layerContainer||(c.layerContainer=n.createElement("div"),c.layerContainer.setAttribute("data-test","layer-container"),n.body.appendChild(c.layerContainer)),t}return t=c,(n=[{key:"componentDidMount",value:function(){this.props.open&&this.getLayerStack().push(this)}},{key:"componentDidUpdate",value:function(e){!e.open&&this.props.open?this.getLayerStack().push(this):e.open&&!this.props.open&&Object(u.pull)(this.getLayerStack(),this)}},{key:"componentWillUnmount",value:function(){Object(u.pull)(this.getLayerStack(),this)}},{key:"getLayerStack",value:function(){return this.context}},{key:"render",value:function(){var e=this,t=this.props,n=t.children;if(t.open){var r=Object(i.createPortal)(o.a.createElement(p.a.Consumer,null,(function(t){var r=t.separateStackingContexts,i=void 0!==r&&r;return o.a.createElement(b,{$separateStackingContexts:i,"data-test":"layer",onMouseDown:e.handleClickOnLayer,onTouchStart:e.handleClickOnLayer},n)})),c.layerContainer);return o.a.createElement(o.a.Fragment,null,o.a.createElement(f.a,{target:window,eventType:"keydown",listener:this.handleKeyDownOnWindow,key:"eventListenerKeydown"}),o.a.createElement(f.a,{target:window,eventType:"mousedown",listener:this.handleClickOnWindow,key:"eventListenerMouseDown"}),o.a.createElement(f.a,{target:window,eventType:"touchstart",listener:this.handleClickOnWindow,key:"eventListenerTouchStart",options:{passive:!0}}),r)}return null}}])&&v(t.prototype,n),c}(r.Component);S(E,"layerContainer",null),S(E,"possibleCloseReasons",k),S(E,"propTypes",j),S(E,"defaultProps",C),S(E,"contextType",p.b);var P=E},2:function(e,t){e.exports=n(7294)},27:function(e,t,n){"use strict";n.d(t,"a",(function(){return o})),n.d(t,"b",(function(){return r}));var r={body:{appendChild:function(){return[]}},addEventListener:function(){},removeEventListener:function(){},activeElement:{blur:function(){},nodeName:""},querySelector:function(){return null},querySelectorAll:function(){return[]},getElementById:function(){return null},createEvent:function(){return{initEvent:function(){}}},createElement:function(){return{children:[],childNodes:[],style:{},setAttribute:function(){},getElementsByTagName:function(){return[]}}},createElementNS:function(){return{}},importNode:function(){return null},location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""}};function o(){return"undefined"!=typeof document?document:r}},3:function(e,t){e.exports=n(2788)},4:function(e,t){e.exports=n(5220)},70:function(e,t){e.exports=n(3935)},71:function(e,t,n){"use strict";(function(e){n.d(t,"b",(function(){return l})),n.d(t,"a",(function(){return u})),n.d(t,"c",(function(){return c}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=o.a.createContext([]),u=o.a.createContext({}),s={children:a.a.node,name:a.a.string,scope:a.a.object,separateStackingContexts:a.a.bool};function c(t){var n=t.children,r=t.name,i=void 0===r?"__splunkui_layer_instances__":r,a=t.scope,s=void 0===a?"undefined"!=typeof window?window:e:a,c=t.separateStackingContexts,f=void 0!==c&&c;return s[i]||(s[i]=[]),o.a.createElement(l.Provider,{value:s[i]},o.a.createElement(u.Provider,{value:{separateStackingContexts:f}},n))}c.propTypes=s}).call(this,n(113))},9:function(e,t){e.exports=n(2916)}})},6206:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=166)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},12:function(e,t){e.exports=n(5917)},166:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return P}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(20),u=n(5),s=n(3),c=n.n(s),f=n(61),p=n.n(f),d=n(12),h=n.n(d),m=n(0),b=c()(h.a).withConfig({displayName:"LinkStyles__StyledClickable",componentId:"sc-1hhltcf-0"})(["",";color:",";text-decoration:none;font-size:inherit;font-weight:inherit;line-height:inherit;border-radius:",";&:not([disabled]){cursor:pointer;",";&:focus{box-shadow:",";outline:0;&:active{box-shadow:none;}}}&[disabled]{color:",";}&::-moz-focus-inner{border:0;padding:0;}"],m.mixins.reset("inline"),Object(m.pick)({enterprise:m.variables.linkColor,prisma:m.variables.interactiveColorPrimary}),Object(m.pick)({enterprise:0,prisma:"1px"}),Object(m.pick)({enterprise:Object(s.css)(["&:hover{text-decoration:underline;}"]),prisma:Object(s.css)(["&:hover:not(:focus),&:active{text-decoration:underline;text-underline-position:under;}"])}),m.variables.focusShadow,m.variables.contentColorDisabled),y=c()(p.a).withConfig({displayName:"LinkStyles__StyledExternal",componentId:"sc-1hhltcf-1"})(["vertical-align:baseline;margin:",";"],Object(m.pick)({enterprise:"0 0 0 3px",prisma:"0 0 0 4px"}));function g(e){return g="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},g(e)}function v(){return v=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},v.apply(this,arguments)}function w(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function x(e,t){return x=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},x(e,t)}function O(e,t){return!t||"object"!==g(t)&&"function"!=typeof t?S(e):t}function S(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function k(e){return k=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},k(e)}function j(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var C={children:a.a.node,disabled:a.a.bool,elementRef:a.a.oneOfType([a.a.func,a.a.object]),openInNewContext:a.a.bool,to:a.a.string},E=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&x(e,t)}(l,e);var t,n,r,i,a=(r=l,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=k(r);if(i){var n=k(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return O(this,e)});function l(){var e;w(this,l);for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return j(S(e=a.call.apply(a,[this].concat(n))),"component",null),j(S(e),"handleMount",(function(t){e.component=t})),e}return t=l,(n=[{key:"focus",value:function(){var e;null===(e=this.component)||void 0===e||e.focus()}},{key:"render",value:function(){var e=this.props,t=e.children,n=e.openInNewContext,r=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","openInNewContext"]);return o.a.createElement(b,v({"data-test":"link",ref:this.handleMount,openInNewContext:n},r),t,n&&o.a.createElement(y,{screenReaderText:Object(u._)("Open externally"),size:.8}))}}])&&_(t.prototype,n),l}(r.Component);j(E,"propTypes",C),j(E,"defaultProps",{disabled:!1,openInNewContext:!1}),j(E,l.legacyRefMode,!0);var P=E},2:function(e,t){e.exports=n(7294)},20:function(e,t){e.exports=n(6635)},3:function(e,t){e.exports=n(2788)},5:function(e,t){e.exports=n(6219)},61:function(e,t){e.exports=n(5175)}})},8689:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=128)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},100:function(e,t){e.exports=n(1456)},12:function(e,t){e.exports=n(5917)},128:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return z})),n.d(t,"Link",(function(){return b}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(100),u=n.n(l),s=n(3),c=n.n(s),f=n(33),p=n.n(f),d=c()(p.a).withConfig({displayName:"LinkStyles__StyledLink",componentId:"w06zjv-0"})([""]);var h={children:a.a.node,elementRef:a.a.oneOfType([a.a.func,a.a.object]),openInNewContext:a.a.bool,to:a.a.string};function m(e){var t=e.children,n=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children"]);return o.a.createElement(d,n,t)}m.propTypes=h;var b=m,y=n(0),g=c.a.p.withConfig({displayName:"TitleStyles__StyledTitle",componentId:"sc-6gbjha-0"})([""," ",""],y.mixins.reset("block"),Object(y.pick)({prisma:Object(s.css)(["font-size:14px;line-height:20px;"])}));var v={children:a.a.node};function w(e){var t=e.children,n=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children"]);return o.a.createElement(g,n,t)}w.propTypes=v;var _=w,x=n(8),O=n.n(x),S=n(12),k=n.n(S),j=c.a.div.withConfig({displayName:"MessageStyles__StyledContent",componentId:"eg66af-0"})(["",";",""],y.mixins.reset("inline"),Object(y.pick)({prisma:Object(s.css)(["color:",";"],y.variables.contentColorActive)})),C=c()(k.a).withConfig({displayName:"MessageStyles__StyledRemove",componentId:"eg66af-1"})(["",";border:1px solid transparent;border-radius:",";color:",";",";cursor:pointer;position:absolute;"," padding:",";&:hover,&:focus{background:",";border:",";color:",";}&:active{",";}",""],y.mixins.reset("flex"),Object(y.pick)({prisma:"50%",enterprise:y.variables.borderRadius}),Object(y.pick)({prisma:y.variables.contentColorMuted,enterprise:{dark:y.variables.gray96,light:y.variables.gray45}}),(function(e){return"banner"===e.$appearance&&Object(y.pick)({prisma:Object(s.css)(["color:",";"],y.variables.contentColorInverted)})}),Object(y.pick)({prisma:Object(s.css)(["top:1px;right:2px;"]),enterprise:Object(s.css)(["top:6px;right:8px;"])}),Object(y.pick)({prisma:"10px",enterprise:"8px"}),Object(y.pick)({prisma:y.variables.interactiveColorOverlayHover,enterprise:{dark:y.variables.gray30,light:y.variables.gray92}}),Object(y.pick)({prisma:Object(s.css)(["1px solid inherit"]),enterprise:Object(s.css)(["1px solid ",""],y.variables.gray80)}),Object(y.pick)({enterprise:{dark:y.variables.gray96,light:y.variables.linkColor},prisma:y.variables.contentColorActive}),Object(y.pick)({prisma:Object(s.css)(["background:",";"],y.variables.interactiveColorOverlayActive),enterprise:Object(s.css)(["box-shadow:",";"],y.variables.focusShadow)}),Object(y.pick)({prisma:Object(s.css)(["&:focus{box-shadow:0 0 0 3px ",";}"],y.variables.focusColor)})),E=c.a.span.withConfig({displayName:"MessageStyles__StyledIconWrapper",componentId:"eg66af-2"})(["position:absolute;top:",";left:0;width:",";height:calc(100% - 8px);text-align:center;color:",";"," border-top-left-radius:inherit;border-bottom-left-radius:inherit;"," ",";"],Object(y.pick)({prisma:"0px",enterprise:"7px"}),Object(y.pick)({prisma:"24px",enterprise:"25px"}),y.variables.white,Object(y.pick)({prisma:Object(s.css)(["padding-top:8px;"])}),Object(y.pickVariant)("$type",{info:Object(s.css)(["color:",";"],Object(y.pick)({prisma:y.variables.contentColorMuted,enterprise:y.variables.infoColor})),success:Object(s.css)(["color:",";"],y.variables.accentColorPositive),warning:Object(s.css)(["color:",";"],y.variables.accentColorWarning),error:Object(s.css)(["color:",";"],y.variables.accentColorNegative)}),(function(e){return e.$fillStyle&&Object(y.pick)({prisma:Object(s.css)(["background-color:",";"],Object(y.pickVariant)("$type",{info:y.variables.contentColorActive,success:y.variables.accentColorPositive,warning:y.variables.accentColorWarning,error:y.variables.accentColorNegative}))})})),P=c()(O.a).withConfig({displayName:"MessageStyles__StyledBox",componentId:"eg66af-3"})(["",";position:relative;border-radius:",";margin-bottom:",";padding:",";word-wrap:break-word;"," ",""],y.mixins.reset("block"),Object(y.pick)({prisma:y.variables.borderRadius,enterprise:"5px"}),y.variables.spacingSmall,Object(y.pickVariant)("$hasRemoveIcon",{true:{prisma:"10px 40px 10px 36px",enterprise:"10px 40px 10px 40px"},false:{prisma:"10px 8px 10px 36px",enterprise:"10px 10px 10px 40px"}}),(function(e){return e.$fillStyle&&Object(y.pick)({enterprise:Object(s.css)(["& > ","{left:",";}",""],E,y.variables.spacingXSmall,Object(y.pickVariant)("$type",{info:Object(s.css)(["",""],Object(y.pick)({light:Object(s.css)(["background-color:",";border:1px solid ",";"],y.variables.infoColorL50,y.variables.infoColor),dark:Object(s.css)(["background-color:",";"],y.mixins.colorWithAlpha(y.variables.infoColor,.5))})),success:Object(s.css)(["",""],Object(y.pick)({light:Object(s.css)(["background-color:",";border:1px solid ",";"],y.variables.successColorL50,y.variables.successColor),dark:Object(s.css)(["background-color:",";"],y.mixins.colorWithAlpha(y.variables.successColor,.5))})),warning:Object(s.css)(["",""],Object(y.pick)({light:Object(s.css)(["background-color:",";border:1px solid ",";"],y.variables.warningColorL50,y.variables.warningColor),dark:Object(s.css)(["background-color:",";"],y.mixins.colorWithAlpha(y.variables.warningColor,.5))})),error:Object(s.css)(["",""],Object(y.pick)({light:Object(s.css)(["background-color:",";border:1px solid ",";"],y.variables.errorColorL50,y.variables.errorColor),dark:Object(s.css)(["background-color:",";"],y.mixins.colorWithAlpha(y.variables.errorColor,.5))}))})),prisma:Object(s.css)(["border:1px solid transparent;background-color:",";box-shadow:",";& > ","{color:",";}"],y.variables.backgroundColorPopup,y.variables.embossShadow,E,y.variables.backgroundColorPopup)})}),Object(y.pick)({prisma:Object(s.css)(["& ","{color:",";}"],g,Object(y.pickVariant)("$type",{info:y.variables.contentColorActive,warning:y.variables.accentColorWarning,error:y.variables.accentColorNegative,success:y.variables.accentColorPositive}))})),A=n(73),T=n(22),L=n(74),R=n(76),M=n(77);function D(){return D=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},D.apply(this,arguments)}var I={appearance:a.a.oneOf(["default","fill","banner"]),children:a.a.node,elementRef:a.a.oneOfType([a.a.func,a.a.object]),onRequestRemove:a.a.func,type:a.a.oneOf(["info","success","warning","error"])},F=Object.freeze({info:L.a,warning:M.a,error:A.a,success:R.a});function N(e){var t=e.appearance,n=void 0===t?"default":t,i=e.children,a=e.type,l=void 0===a?"warning":a,s=e.onRequestRemove,c=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["appearance","children","type","onRequestRemove"]),f=Object(r.useCallback)((function(e){null==s||s(e)}),[s]);if("banner"===n)return o.a.createElement(u.a,D({type:l,"data-test":"banner",onRequestClose:f},c),i);var p=F[l],d="fill"===n,h="default"===n||"fill"===n;return o.a.createElement(P,D({$appearance:n,$fillStyle:d,$hasRemoveIcon:!!s,$type:l,"data-test-type":l,"data-test":"message"},c),h&&o.a.createElement(E,{$fillStyle:d,$type:l},o.a.createElement(p,{prismaSize:"small",enterpriseWidth:"24px",enterpriseHeight:"24px"})),o.a.createElement(j,{"data-test":"content",$fillStyle:d},i),s&&o.a.createElement(C,{"data-test":"remove",onClick:f,$appearance:n},o.a.createElement(T.a,{prismaSize:"small",enterpriseHeight:"12px",enterpriseWidth:"12px"})))}N.propTypes=I,N.Title=_,N.Link=b;var z=N},2:function(e,t){e.exports=n(7294)},22:function(e,t,n){"use strict";n.d(t,"a",(function(){return p}));var r=n(2),o=n.n(r),i=n(23),a=n.n(i),l=n(7),u=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L10.5858 12L5.2929 17.2929C4.90238 17.6834 4.90238 18.3166 5.2929 18.7071C5.68342 19.0976 6.31659 19.0976 6.70711 18.7071L12 13.4142L17.2929 18.7071C17.6834 19.0976 18.3166 19.0976 18.7071 18.7071C19.0976 18.3166 19.0976 17.6834 18.7071 17.2929L13.4142 12L18.7071 6.70711C19.0976 6.31658 19.0976 5.68342 18.7071 5.29289C18.3166 4.90237 17.6834 4.90237 17.2929 5.29289L12 10.5858L6.70711 5.29289Z",fill:"currentColor"}))}function f(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M12.2024 2.69009C12.5092 2.38325 13.0067 2.38325 13.3136 2.69009C13.6204 2.99693 13.6204 3.49442 13.3136 3.80126L9.11721 7.99762L13.3114 12.1918C13.6206 12.501 13.6206 13.0023 13.3114 13.3114C13.0023 13.6206 12.501 13.6206 12.1918 13.3114L7.99762 9.11721L3.885 13.2298C3.57816 13.5367 3.08067 13.5367 2.77383 13.2298C2.46699 12.923 2.46699 12.4255 2.77383 12.1187L6.88645 8.00604L2.69183 3.81142C2.38267 3.50226 2.38267 3.001 2.69183 2.69183C3.001 2.38267 3.50226 2.38267 3.81142 2.69183L8.00604 6.88646L12.2024 2.69009Z",fill:"currentColor"}))}function p(e){return o.a.createElement(l.a,s({Enterprise:a.a,Prisma16:f,Prisma24:c},e))}},23:function(e,t){e.exports=n(1476)},3:function(e,t){e.exports=n(2788)},33:function(e,t){e.exports=n(6206)},53:function(e,t){e.exports=n(6054)},54:function(e,t){e.exports=n(3940)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return u}));var r=n(2),o=n.n(r),i=n(3);function a(){return a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}var l=n.n(i).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function u(e){return o.a.createElement(l,a({xmlns:"http://www.w3.org/2000/svg"},e))}},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return h}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(0);function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}var f={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},p={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:a.a.func,enterpriseSize:a.a.oneOfType([a.a.number,a.a.string]),enterpriseWidth:a.a.oneOfType([a.a.number,a.a.string]),enterpriseHeight:a.a.oneOfType([a.a.number,a.a.string]),Prisma24:a.a.func.isRequired,Prisma20:a.a.func,Prisma16:a.a.func,prismaSize:a.a.oneOf(["medium","small"]),inline:a.a.bool,screenReaderText:a.a.string};function h(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,i=e.Prisma16,a=e.prismaSize,d=e.inline,h=e.enterpriseSize,m=e.enterpriseWidth,b=e.enterpriseHeight,y=e.screenReaderText,g=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),v=Object(l.useSplunkTheme)(),w=v.family,_=v.density;if("enterprise"===w)return o.a.createElement(t,c({size:h,width:m,height:b,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},g));var x=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?u(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):u(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?f:p},g);if("small"===a){var O=i||n;return o.a.createElement(O,c({width:"16",height:"16"},x))}if("compact"===_){var S=r||n;return o.a.createElement(S,c({width:"20",height:"20"},x))}return o.a.createElement(n,c({width:"24",height:"24"},x))}h.propTypes=d,h.defaultProps={inline:!0,prismaSize:"medium"}},73:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),i=n(53),a=n.n(i),l=n(7),u=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12ZM11.0001 7.9906V12.0001C11.0001 12.5524 11.4478 13.0001 12.0001 13.0001C12.5524 13.0001 13.0001 12.5524 13.0001 12.0001V7.9906C13.0001 7.43832 12.5524 6.9906 12.0001 6.9906C11.4478 6.9906 11.0001 7.43832 11.0001 7.9906ZM12.0001 17.0001C12.6628 17.0001 13.2001 16.4628 13.2001 15.8001C13.2001 15.1374 12.6628 14.6001 12.0001 14.6001C11.3373 14.6001 10.8001 15.1374 10.8001 15.8001C10.8001 16.4628 11.3373 17.0001 12.0001 17.0001Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:a.a,Prisma24:c},e))}},74:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),i=n(75),a=n.n(i),l=n(7),u=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM11.0001 16.0094V11.9999C11.0001 11.4476 11.4478 10.9999 12.0001 10.9999C12.5524 10.9999 13.0001 11.4476 13.0001 11.9999V16.0094C13.0001 16.5617 12.5524 17.0094 12.0001 17.0094C11.4478 17.0094 11.0001 16.5617 11.0001 16.0094ZM12 6.9999C12.6628 6.9999 13.2 7.53716 13.2 8.1999C13.2 8.86264 12.6628 9.3999 12 9.3999C11.3373 9.3999 10.8 8.86264 10.8 8.1999C10.8 7.53716 11.3373 6.9999 12 6.9999Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:a.a,Prisma24:c},e))}},75:function(e,t){e.exports=n(2708)},76:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),i=n(54),a=n.n(i),l=n(7),u=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM16.8738 8.62627C17.2643 9.01679 17.2643 9.64996 16.8738 10.0405L11.5853 15.329C10.9996 15.9147 10.0499 15.9148 9.46414 15.3291L7.12637 12.9921C6.73579 12.6016 6.7357 11.9684 7.12616 11.5779C7.51663 11.1873 8.1498 11.1872 8.54038 11.5776L10.5246 13.5613L15.4596 8.62627C15.8501 8.23574 16.4833 8.23574 16.8738 8.62627Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:a.a,Prisma24:c},e))}},77:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),i=n(78),a=n.n(i),l=n(7),u=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M10.6827 2.82369C11.2341 1.72544 12.7659 1.72544 13.3173 2.82369L21.8338 19.7867C22.3412 20.7973 21.6254 22 20.5165 22H3.48349C2.37462 22 1.65878 20.7973 2.16616 19.7867L10.6827 2.82369ZM11.0002 13.6618V11.0133C11.0002 10.461 11.4479 10.0133 12.0002 10.0133C12.5525 10.0133 13.0002 10.461 13.0002 11.0133V13.6618C13.0002 14.2141 12.5525 14.6618 12.0002 14.6618C11.4479 14.6618 11.0002 14.2141 11.0002 13.6618ZM13.2002 16.9347C13.2002 17.5975 12.6629 18.1347 12.0002 18.1347C11.3374 18.1347 10.8002 17.5975 10.8002 16.9347C10.8002 16.272 11.3374 15.7347 12.0002 15.7347C12.6629 15.7347 13.2002 16.272 13.2002 16.9347Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:a.a,Prisma24:c},e))}},78:function(e,t){e.exports=n(4003)},8:function(e,t){e.exports=n(6493)}})},1456:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=167)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},12:function(e,t){e.exports=n(5917)},14:function(e,t){e.exports=n(5766)},167:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return T}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(5),u=n(14),s=n.n(u),c=n(73),f=n(22),p=n(74),d=n(76),h=n(77),m=n(3),b=n.n(m),y=n(8),g=n.n(y),v=n(12),w=n.n(v),_=n(0),x=b.a.div.withConfig({displayName:"MessageBarStyles__MessageBarContent",componentId:"sc-1uyhzza-0"})(["",";color:inherit;padding:0 8px;text-align:center;margin-right:auto;& a{display:inline-block;color:inherit;text-decoration:underline;text-underline-position:under;padding:0 3px 2px 3px;&:not([disabled]):focus{border-radius:",";outline:0;box-shadow:",";}}"],_.mixins.reset("inline"),_.variables.borderRadius,Object(_.pick)({enterprise:{dark:Object(m.css)(["0 0 0 2px ",""],_.variables.gray80),light:Object(m.css)(["0 0 0 2px ",""],_.variables.gray25)},prisma:{light:Object(_.pickVariant)("$type",{info:Object(m.css)(["0 0 0 3px ",""],_.variables.black),warning:Object(m.css)(["0 0 0 3px ",""],_.variables.black),error:Object(m.css)(["0 0 0 3px ",""],_.variables.white),success:Object(m.css)(["0 0 0 3px ",""],_.variables.white)}),dark:Object(m.css)(["0 0 0 3px ",""],_.variables.black)}})),O=b()(w.a).withConfig({displayName:"MessageBarStyles__MessageBarCloseWrapper",componentId:"sc-1uyhzza-1"})(["",";border:1px solid transparent;border-radius:",";color:inherit;cursor:pointer;padding:",";"," &:hover,&:focus{background:",";border:",";color:",";}&:active{",";}",""],_.mixins.reset("flex"),_.variables.borderRadius,_.variables.spacingXSmall,Object(_.pick)({enterprise:Object(m.css)(["margin-top:1px;"])}),Object(_.pick)({prisma:_.variables.interactiveColorOverlayHover,enterprise:{dark:_.variables.gray30,light:_.variables.gray92}}),Object(_.pick)({prisma:Object(m.css)(["1px solid inherit"]),enterprise:Object(m.css)(["1px solid ",""],_.variables.gray80)}),Object(_.pick)({enterprise:{dark:_.variables.gray96,light:_.variables.linkColor}}),Object(_.pick)({prisma:Object(m.css)(["background:",";"],_.variables.interactiveColorOverlayActive),enterprise:Object(m.css)(["box-shadow:",";"],_.variables.focusShadow)}),Object(_.pick)({prisma:Object(m.css)(["&:focus{border-radius:",";box-shadow:",";}"],_.variables.borderRadius,Object(_.pick)({light:Object(_.pickVariant)("$type",{info:Object(m.css)(["0 0 0 3px ",""],_.variables.black),warning:Object(m.css)(["0 0 0 3px ",""],_.variables.black),error:Object(m.css)(["0 0 0 3px ",""],_.variables.white),success:Object(m.css)(["0 0 0 3px ",""],_.variables.white)}),dark:Object(m.css)(["0 0 0 3px ",""],_.variables.black)}))})),S=b.a.div.withConfig({displayName:"MessageBarStyles__MessageBarIconWrapper",componentId:"sc-1uyhzza-2"})(["margin-left:auto;",""],Object(_.pick)({enterprise:Object(m.css)(["color:",";"],Object(_.pickVariant)("$type",{info:_.variables.infoColor,success:_.variables.successColor,warning:_.variables.warningColor,error:_.variables.errorColor}))})),k=b()(g.a).withConfig({displayName:"MessageBarStyles__MessageBarWrapper",componentId:"sc-1uyhzza-3"})(["",";display:flex;align-items:center;justify-content:center;min-height:40px;margin-bottom:",";",";word-wrap:break-word;color:",";",";"],_.mixins.reset("block"),_.variables.spacingSmall,(function(e){return e.$hasCloseButton?Object(m.css)(["",""],Object(_.pick)({prisma:Object(m.css)(["padding:0 8px 0 32px;"]),enterprise:Object(m.css)(["padding:0 8px 0 38px;"])})):Object(m.css)(["",""],Object(_.pick)({prisma:Object(m.css)(["padding:0 33px 0 32px;"]),enterprise:Object(m.css)(["padding:0 26px 0 32px;"])}))}),Object(_.pick)({prisma:Object(_.pickVariant)("$type",{info:{light:_.variables.contentColorActive,dark:_.variables.contentColorInverted},success:_.variables.contentColorInverted,warning:{light:_.variables.contentColorActive,dark:_.variables.contentColorInverted},error:_.variables.contentColorInverted}),enterprise:{dark:_.variables.gray96,light:_.variables.gray25}}),Object(_.pickVariant)("$type",{info:Object(m.css)(["background-color:",";"],Object(_.pick)({prisma:{dark:_.variables.white,light:_.variables.neutral200},enterprise:{dark:_.mixins.colorWithAlpha(_.variables.infoColor,.5),light:_.variables.infoColorL50}})),success:Object(m.css)(["background-color:",";"],Object(_.pick)({prisma:_.variables.accentColorPositive,enterprise:{dark:_.mixins.colorWithAlpha(_.variables.successColor,.5),light:_.variables.successColorL50}})),warning:Object(m.css)(["background-color:",";"],Object(_.pick)({prisma:_.variables.accentColorWarning,enterprise:{dark:_.mixins.colorWithAlpha(_.variables.warningColor,.5),light:_.variables.warningColorL50}})),error:Object(m.css)(["background-color:",";"],Object(_.pick)({prisma:_.variables.accentColorNegative,enterprise:{dark:_.mixins.colorWithAlpha(_.variables.errorColor,.5),light:_.variables.errorColorL50}}))}));function j(){return j=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},j.apply(this,arguments)}var C={children:a.a.node.isRequired,onRequestClose:a.a.func,type:a.a.oneOf(["info","success","warning","error"]).isRequired},E=Object.freeze({info:p.a,warning:h.a,error:c.a,success:d.a}),P=Object.freeze({info:Object(l._)("Info"),warning:Object(l._)("Warning"),error:Object(l._)("Alert"),success:Object(l._)("Success")});function A(e){var t=e.children,n=e.type,r=e.onRequestClose,i=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","type","onRequestClose"]),a=E[n];return o.a.createElement(k,j({$type:n,"data-test":"message-bar","data-test-type":n},i,{role:"region",$hasCloseButton:Boolean(r)}),o.a.createElement(S,{$type:n},o.a.createElement(a,{"aria-hidden":"true",enterpriseSize:"24px","data-test":"icon"}),o.a.createElement(s.a,null,P[n])),o.a.createElement(x,{$type:n,"data-test":"content"},t),r&&o.a.createElement(O,{$type:n,onClick:r},o.a.createElement(f.a,{"aria-hidden":"true",prismaSize:"small",enterpriseSize:"12px"}),o.a.createElement(s.a,null,Object(l._)("Close"))))}A.propTypes=C;var T=A},2:function(e,t){e.exports=n(7294)},22:function(e,t,n){"use strict";n.d(t,"a",(function(){return p}));var r=n(2),o=n.n(r),i=n(23),a=n.n(i),l=n(7),u=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{d:"M6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L10.5858 12L5.2929 17.2929C4.90238 17.6834 4.90238 18.3166 5.2929 18.7071C5.68342 19.0976 6.31659 19.0976 6.70711 18.7071L12 13.4142L17.2929 18.7071C17.6834 19.0976 18.3166 19.0976 18.7071 18.7071C19.0976 18.3166 19.0976 17.6834 18.7071 17.2929L13.4142 12L18.7071 6.70711C19.0976 6.31658 19.0976 5.68342 18.7071 5.29289C18.3166 4.90237 17.6834 4.90237 17.2929 5.29289L12 10.5858L6.70711 5.29289Z",fill:"currentColor"}))}function f(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 16 16"},t),o.a.createElement("path",{d:"M12.2024 2.69009C12.5092 2.38325 13.0067 2.38325 13.3136 2.69009C13.6204 2.99693 13.6204 3.49442 13.3136 3.80126L9.11721 7.99762L13.3114 12.1918C13.6206 12.501 13.6206 13.0023 13.3114 13.3114C13.0023 13.6206 12.501 13.6206 12.1918 13.3114L7.99762 9.11721L3.885 13.2298C3.57816 13.5367 3.08067 13.5367 2.77383 13.2298C2.46699 12.923 2.46699 12.4255 2.77383 12.1187L6.88645 8.00604L2.69183 3.81142C2.38267 3.50226 2.38267 3.001 2.69183 2.69183C3.001 2.38267 3.50226 2.38267 3.81142 2.69183L8.00604 6.88646L12.2024 2.69009Z",fill:"currentColor"}))}function p(e){return o.a.createElement(l.a,s({Enterprise:a.a,Prisma16:f,Prisma24:c},e))}},23:function(e,t){e.exports=n(1476)},3:function(e,t){e.exports=n(2788)},5:function(e,t){e.exports=n(6219)},53:function(e,t){e.exports=n(6054)},54:function(e,t){e.exports=n(3940)},6:function(e,t,n){"use strict";n.d(t,"a",(function(){return u}));var r=n(2),o=n.n(r),i=n(3);function a(){return a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}var l=n.n(i).a.svg.withConfig({displayName:"SVG__Styled",componentId:"sc-1bz0ryh-0"})(["flex:0 0 auto;"]);function u(e){return o.a.createElement(l,a({xmlns:"http://www.w3.org/2000/svg"},e))}},7:function(e,t,n){"use strict";n.d(t,"a",(function(){return h}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(0);function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},c.apply(this,arguments)}var f={display:"inline-block",flex:"0 0 auto",overflow:"visible",verticalAlign:"middle"},p={display:"block",flex:"0 0 auto",margin:"0 auto",overflow:"visible"},d={Enterprise:a.a.func,enterpriseSize:a.a.oneOfType([a.a.number,a.a.string]),enterpriseWidth:a.a.oneOfType([a.a.number,a.a.string]),enterpriseHeight:a.a.oneOfType([a.a.number,a.a.string]),Prisma24:a.a.func.isRequired,Prisma20:a.a.func,Prisma16:a.a.func,prismaSize:a.a.oneOf(["medium","small"]),inline:a.a.bool,screenReaderText:a.a.string};function h(e){var t=e.Enterprise,n=e.Prisma24,r=e.Prisma20,i=e.Prisma16,a=e.prismaSize,d=e.inline,h=e.enterpriseSize,m=e.enterpriseWidth,b=e.enterpriseHeight,y=e.screenReaderText,g=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["Enterprise","Prisma24","Prisma20","Prisma16","prismaSize","inline","enterpriseSize","enterpriseWidth","enterpriseHeight","screenReaderText"]),v=Object(l.useSplunkTheme)(),w=v.family,_=v.density;if("enterprise"===w)return o.a.createElement(t,c({size:h,width:m,height:b,screenReaderText:y||null,hideDefaultTooltip:!0,inline:d},g));var x=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?u(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):u(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({"aria-label":y,style:d?f:p},g);if("small"===a){var O=i||n;return o.a.createElement(O,c({width:"16",height:"16"},x))}if("compact"===_){var S=r||n;return o.a.createElement(S,c({width:"20",height:"20"},x))}return o.a.createElement(n,c({width:"24",height:"24"},x))}h.propTypes=d,h.defaultProps={inline:!0,prismaSize:"medium"}},73:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),i=n(53),a=n.n(i),l=n(7),u=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12ZM11.0001 7.9906V12.0001C11.0001 12.5524 11.4478 13.0001 12.0001 13.0001C12.5524 13.0001 13.0001 12.5524 13.0001 12.0001V7.9906C13.0001 7.43832 12.5524 6.9906 12.0001 6.9906C11.4478 6.9906 11.0001 7.43832 11.0001 7.9906ZM12.0001 17.0001C12.6628 17.0001 13.2001 16.4628 13.2001 15.8001C13.2001 15.1374 12.6628 14.6001 12.0001 14.6001C11.3373 14.6001 10.8001 15.1374 10.8001 15.8001C10.8001 16.4628 11.3373 17.0001 12.0001 17.0001Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:a.a,Prisma24:c},e))}},74:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),i=n(75),a=n.n(i),l=n(7),u=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM11.0001 16.0094V11.9999C11.0001 11.4476 11.4478 10.9999 12.0001 10.9999C12.5524 10.9999 13.0001 11.4476 13.0001 11.9999V16.0094C13.0001 16.5617 12.5524 17.0094 12.0001 17.0094C11.4478 17.0094 11.0001 16.5617 11.0001 16.0094ZM12 6.9999C12.6628 6.9999 13.2 7.53716 13.2 8.1999C13.2 8.86264 12.6628 9.3999 12 9.3999C11.3373 9.3999 10.8 8.86264 10.8 8.1999C10.8 7.53716 11.3373 6.9999 12 6.9999Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:a.a,Prisma24:c},e))}},75:function(e,t){e.exports=n(2708)},76:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),i=n(54),a=n.n(i),l=n(7),u=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM16.8738 8.62627C17.2643 9.01679 17.2643 9.64996 16.8738 10.0405L11.5853 15.329C10.9996 15.9147 10.0499 15.9148 9.46414 15.3291L7.12637 12.9921C6.73579 12.6016 6.7357 11.9684 7.12616 11.5779C7.51663 11.1873 8.1498 11.1872 8.54038 11.5776L10.5246 13.5613L15.4596 8.62627C15.8501 8.23574 16.4833 8.23574 16.8738 8.62627Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:a.a,Prisma24:c},e))}},77:function(e,t,n){"use strict";n.d(t,"a",(function(){return f}));var r=n(2),o=n.n(r),i=n(78),a=n.n(i),l=n(7),u=n(6);function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}function c(e){var t=s({},e);return o.a.createElement(u.a,s({viewBox:"0 0 24 24"},t),o.a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M10.6827 2.82369C11.2341 1.72544 12.7659 1.72544 13.3173 2.82369L21.8338 19.7867C22.3412 20.7973 21.6254 22 20.5165 22H3.48349C2.37462 22 1.65878 20.7973 2.16616 19.7867L10.6827 2.82369ZM11.0002 13.6618V11.0133C11.0002 10.461 11.4479 10.0133 12.0002 10.0133C12.5525 10.0133 13.0002 10.461 13.0002 11.0133V13.6618C13.0002 14.2141 12.5525 14.6618 12.0002 14.6618C11.4479 14.6618 11.0002 14.2141 11.0002 13.6618ZM13.2002 16.9347C13.2002 17.5975 12.6629 18.1347 12.0002 18.1347C11.3374 18.1347 10.8002 17.5975 10.8002 16.9347C10.8002 16.272 11.3374 15.7347 12.0002 15.7347C12.6629 15.7347 13.2002 16.272 13.2002 16.9347Z",fill:"currentColor"}))}function f(e){return o.a.createElement(l.a,s({Enterprise:a.a,Prisma24:c},e))}},78:function(e,t){e.exports=n(4003)},8:function(e,t){e.exports=n(6493)}})},1158:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=119)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},11:function(e,t){e.exports=n(9726)},119:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return ae})),n.d(t,"Body",(function(){return O})),n.d(t,"Header",(function(){return V})),n.d(t,"Footer",(function(){return T}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(4),u=n(79),s=n.n(u),c=n(28),f=n(11),p=n(39),d=n(3),h=n.n(d),m=n(8),b=n.n(m),y=n(0),g=h()(b.a).withConfig({displayName:"BodyStyles__StyledBox",componentId:"lv54z7-0"})(["background-color:",";"," flex:0 1 auto;overflow:auto;@media all and (-ms-high-contrast:none){*::-ms-backdrop,&{max-height:calc(100vh - 180px);}}"],Object(y.pick)({enterprise:y.variables.backgroundColor,prisma:y.variables.backgroundColorDialog}),Object(y.pick)({enterprise:{comfortable:Object(d.css)(["padding:28px;"]),compact:Object(d.css)(["padding:24px;"])},prisma:{comfortable:Object(d.css)(["padding:12px 24px;&:first-child{padding-top:36px;}&:last-child{padding-bottom:36px;}"]),compact:Object(d.css)(["padding:8px 24px;&:first-child{padding-top:26px;}&:last-child{padding-bottom:26px;}"])}}));function v(){return v=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},v.apply(this,arguments)}function w(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var _={children:a.a.node};function x(e){var t,n,i=e.children,a=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children"]),l=(t=Object(r.useState)(),n=2,function(e){if(Array.isArray(e))return e}(t)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,i=void 0;try{for(var a,l=e[Symbol.iterator]();!(r=(a=l.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){o=!0,i=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw i}}return n}}(t,n)||function(e,t){if(e){if("string"==typeof e)return w(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?w(e,t):void 0}}(t,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),u=l[0],s=l[1],c=Object(r.useCallback)((function(e){s(e)}),[]);return o.a.createElement(g,v({"data-test":"body"},a,{elementRef:c}),o.a.createElement(p.ScrollContainerProvider,{value:u},i))}x.propTypes=_;var O=x,S=n(83),k=n.n(S),j=h()(b.a).withConfig({displayName:"FooterStyles__StyledBox",componentId:"yszcmv-0"})(["flex:0 0 auto;text-align:right;padding:",";background-color:",";& > button{min-width:80px;}"],Object(y.pick)({enterprise:y.variables.spacing,prisma:{comfortable:"24px",compact:"18px 24px"}}),Object(y.pick)({enterprise:y.variables.backgroundColor,prisma:y.variables.backgroundColorDialog})),C=Object(r.createContext)({});function E(){return E=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},E.apply(this,arguments)}var P={children:a.a.node};function A(e){var t=e.children,n=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children"]),i=Object(r.useContext)(C).divider,a="both"===i||"footer"===i;return o.a.createElement(o.a.Fragment,null,a&&o.a.createElement(k.a,{"aria-hidden":!0}),o.a.createElement(j,E({"data-test":"footer"},n),t))}A.propTypes=P;var T=A,L=n(69),R=n.n(L),M=h()(b.a).withConfig({displayName:"HeaderStyles__StyledBox",componentId:"sc-1y722ut-0"})(["",";flex:0 0 auto;position:relative;min-height:",";background-color:",";padding:",";align-items:center;padding-right:",";"],y.mixins.reset("flex"),Object(y.pick)({enterprise:"30px",prisma:{comfortable:"60px",compact:"52px"}}),Object(y.pick)({enterprise:y.variables.backgroundColor,prisma:y.variables.backgroundColorDialog}),Object(y.pick)({enterprise:"25px 28px",prisma:{comfortable:"18px 24px",compact:"14px 24px"}}),(function(e){return e.$close&&Object(y.pick)({enterprise:"54px",prisma:{comfortable:"64px",compact:"56px"}})})),D=h.a.div.withConfig({displayName:"HeaderStyles__StyledTitleWrapper",componentId:"sc-1y722ut-1"})(["",";flex-direction:column;"],y.mixins.reset("flex")),I=h.a.div.withConfig({displayName:"HeaderStyles__StyledIcon",componentId:"sc-1y722ut-2"})(["",";align-items:center;justify-content:center;margin-right:",";"," width:",";height:",";flex-shrink:0;"],y.mixins.reset("inline-flex"),y.variables.spacingLarge,Object(y.pick)({prisma:Object(d.css)(["background-color:",";"],y.variables.transparent)}),Object(y.pick)({comfortable:"40px",compact:"32px"}),Object(y.pick)({comfortable:"40px",compact:"32px"})),F=h.a.div.withConfig({displayName:"HeaderStyles__StyledTitle",componentId:"sc-1y722ut-3"})(["",";font-size:20px;margin:0;overflow-wrap:break-word;font-weight:",";",""],y.mixins.reset("block"),y.variables.fontWeightSemiBold,Object(y.pick)({enterprise:Object(d.css)(["line-height:22px;"]),prisma:Object(d.css)(["color:",";line-height:24px;"],y.variables.contentColorActive)})),N=h.a.div.withConfig({displayName:"HeaderStyles__StyledSubtitle",componentId:"sc-1y722ut-4"})(["",";font-size:14px;overflow-wrap:break-word;line-height:",";"],y.mixins.reset("block"),Object(y.pick)({enterprise:y.variables.lineHeight,prisma:"20px"})),z=h.a.div.withConfig({displayName:"HeaderStyles__StyledButtonsWrapper",componentId:"sc-1y722ut-5"})(["",";position:absolute;top:",";right:",";bottom:50%;"," max-height:35px;transform-origin:bottom right;transform:rotate(-90deg) translateX(100%);"],y.mixins.reset("block"),Object(y.pick)({enterprise:0,prisma:{comfortable:"-2px",compact:"-6px"}}),Object(y.pick)({enterprise:0,prisma:{comfortable:"-2px",compact:"-6px"}}),Object(y.pick)({prisma:{comfortable:Object(d.css)(["min-height:35px;"]),compact:Object(d.css)(["min-height:30px;"])}})),q=h.a.div.withConfig({displayName:"HeaderStyles__StyledClose",componentId:"sc-1y722ut-6"})(["",";position:absolute;right:0;top:0;transform:rotate(90deg) translate(-50%,-50%);"],y.mixins.reset("block"));function $(){return $=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},$.apply(this,arguments)}var B={children:a.a.node,icon:a.a.node,onRequestClose:a.a.func,subtitle:a.a.node,title:a.a.string};function U(e){var t=e.children,n=e.icon,i=e.onRequestClose,a=e.subtitle,l=e.title,u=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","icon","onRequestClose","subtitle","title"]),s=Object(r.useContext)(C),c=s.titleId,f=s.divider,p="both"===f||"header"===f;return o.a.createElement(o.a.Fragment,null,o.a.createElement(M,$({$close:!!i,"data-test":"header"},u),n&&o.a.createElement(I,null,n),l?o.a.createElement(D,null,l&&o.a.createElement(F,{id:c,"data-test":"title"},l),a&&o.a.createElement(N,{"data-test":"subtitle"},a)):t,i&&o.a.createElement(z,null,i&&o.a.createElement(q,null,o.a.createElement(R.a,{onClick:i,"data-test":"close"})))),p&&o.a.createElement(k.a,{"aria-hidden":!0}))}U.propTypes=B;var V=U,W=n(21),H=h()(W.animated.div).withConfig({displayName:"ModalStyles__Styled",componentId:"sc-5fn8ds-0"})(["",";flex-direction:column;position:fixed;left:50%;transform:translateX(-50%);z-index:",";",""],y.mixins.reset("flex"),y.variables.zindexModal,Object(y.pick)({enterprise:Object(d.css)(["box-shadow:0 1px 5px ",";max-height:calc(100vh - "," * 4);max-width:calc(100vw - "," * 4);"],y.variables.black,y.variables.spacing,y.variables.spacing),prisma:Object(d.css)(["box-shadow:",";max-height:calc(100vh - "," * 4);max-width:calc(100vw - "," * 4);border-radius:",";overflow:hidden;"],y.variables.modalShadow,y.variables.spacingXLarge,y.variables.spacingXLarge,y.variables.borderRadius)}));function Z(){return Z=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Z.apply(this,arguments)}function K(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Q(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function G(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Q(Object(n),!0).forEach((function(t){re(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Q(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function X(e){return X="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},X(e)}function Y(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function J(e,t){return J=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},J(e,t)}function ee(e,t){return!t||"object"!==X(t)&&"function"!=typeof t?te(e):t}function te(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function ne(e){return ne=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},ne(e)}function re(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var oe={children:a.a.node,initialFocus:a.a.oneOfType([a.a.object,a.a.oneOf(["first","container"])]),onRequestClose:a.a.func,open:a.a.bool,divider:a.a.oneOf(["header","footer","both","none"])},ie=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&J(e,t)}(p,e);var t,n,i,a,u=(i=p,a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=ne(i);if(a){var n=ne(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return ee(this,e)});function p(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,p),re(te(t=u.call(this,e)),"el",null),re(te(t),"initialFocusTimeoutId",void 0),re(te(t),"initialFocus",null),re(te(t),"headerTitleId",void 0),re(te(t),"getDefaultMotionStyle",(function(){return{top:0}})),re(te(t),"getMotionStyle",(function(){return t.props.open?{top:40}:{top:0}})),re(te(t),"handleInitialFocus",(function(){var e=t.props,n=e.initialFocus;e.open?t.initialFocusTimeoutId=Object(l.defer)((function(){var e;t.initialFocus!==n&&("first"===n?t.el&&(e=Object(c.getSortedTabbableElements)(t.el)[0]):"container"===n?e=t.el:"object"===X(n)&&(e=n),null!=e&&"focus"in e&&e.focus(),t.initialFocus=n)})):(t.initialFocus=null,clearTimeout(t.initialFocusTimeoutId))})),re(te(t),"handleModalMount",(function(e){t.el=e})),re(te(t),"handleModalKeyDown",(function(e){null!==t.el&&Object(c.handleTab)(t.el,e.nativeEvent)})),re(te(t),"handleRequestClose",(function(e){var n,r;t.initialFocus=null,null===(n=(r=t.props).onRequestClose)||void 0===n||n.call(r,e)})),re(te(t),"renderModal",(function(e){var n,i=t.props,a=i.style,u=i.children,s=i.divider,c=e.top,f=e.opacity,d=r.Children.toArray(u).filter(r.isValidElement);return o.a.createElement(H,Z({ref:t.handleModalMount,"data-test":"modal",style:G(G({},a),{},{top:c,opacity:f}),tabIndex:-1,onKeyDown:t.handleModalKeyDown,role:"dialog","aria-labelledby":t.headerTitleId},Object(l.omit)(t.props,[].concat(function(e){if(Array.isArray(e))return K(e)}(n=Object(l.keys)(p.propTypes))||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(n)||function(e,t){if(e){if("string"==typeof e)return K(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?K(e,t):void 0}}(n)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),["style"]))),o.a.createElement(C.Provider,{value:{titleId:t.headerTitleId,divider:s}},d))})),t.headerTitleId=Object(f.createDOMID)("titleId"),t}return t=p,(n=[{key:"componentDidMount",value:function(){this.handleInitialFocus()}},{key:"componentDidUpdate",value:function(e){var t=this.props.initialFocus;e.initialFocus!==t&&clearTimeout(this.initialFocusTimeoutId),this.handleInitialFocus()}},{key:"render",value:function(){return o.a.createElement(s.a,{open:this.props.open,getDefaultMotionStyle:this.getDefaultMotionStyle,renderModal:this.renderModal,getMotionStyle:this.getMotionStyle,onRequestClose:this.handleRequestClose})}}])&&Y(t.prototype,n),p}(r.Component);re(ie,"propTypes",oe),re(ie,"defaultProps",{initialFocus:"first",open:!1,divider:"both"}),re(ie,"Header",V),re(ie,"Body",O),re(ie,"Footer",T);var ae=ie},2:function(e,t){e.exports=n(7294)},21:function(e,t){e.exports=n(9920)},28:function(e,t){e.exports=n(8568)},3:function(e,t){e.exports=n(2788)},39:function(e,t){e.exports=n(7009)},4:function(e,t){e.exports=n(5220)},69:function(e,t){e.exports=n(1983)},79:function(e,t){e.exports=n(3620)},8:function(e,t){e.exports=n(6493)},83:function(e,t){e.exports=n(8119)}})},3620:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=168)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},168:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return C}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(34),u=n(60),s=n.n(u),c=n(3),f=n.n(c),p=n(21),d=n(0),h=Object(c.css)(["",";position:fixed;top:0;right:0;bottom:0;left:0;"],d.mixins.reset("block")),m=f()(p.animated.div).withConfig({displayName:"ModalLayerStyles__StyledClickAwayOverlay",componentId:"sc-1sa3n1j-0"})(["",";background-color:",";z-index:",";"],h,d.variables.backgroundColorScrim,d.variables.zindexModalBackdrop);function b(e){return b="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},b(e)}function y(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function g(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?y(Object(n),!0).forEach((function(t){S(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):y(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function v(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function w(e,t){return w=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},w(e,t)}function _(e,t){return!t||"object"!==b(t)&&"function"!=typeof t?x(e):t}function x(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function O(e){return O=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},O(e)}function S(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var k={childrenInAnimation:a.a.bool,getDefaultMotionStyle:a.a.func,getMotionStyle:a.a.func,onRequestClose:a.a.func,open:a.a.bool,renderModal:a.a.func.isRequired,useLayerForClickAway:a.a.bool},j=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&w(e,t)}(u,e);var t,n,r,i,a=(r=u,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=O(r);if(i){var n=O(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return _(this,e)});function u(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,u),S(x(t=a.call(this,e)),"allowAnimationUpdates",!0),S(x(t),"handleClickAway",(function(e){var n,r;null===(n=(r=t.props).onRequestClose)||void 0===n||n.call(r,{reason:"clickAway",event:e})})),S(x(t),"handleAnimationEnd",(function(){t.allowAnimationUpdates&&t.setState({animating:!1})})),S(x(t),"renderLayer",(function(){var e=t.props,n=e.getDefaultMotionStyle,r=e.getMotionStyle,i=e.renderModal,a=e.useLayerForClickAway,u=t.props.open||t.state.animating;return o.a.createElement(l.Spring,{from:g(g({},null==n?void 0:n()),{},{overlayOpacity:0,opacity:0}),to:g(g({},null==r?void 0:r()),{},{overlayOpacity:t.props.open?1:0,opacity:t.props.open?1:0}),onRest:t.handleAnimationEnd},(function(e){return o.a.createElement("div",null,i(e),u&&a&&o.a.createElement(m,{"data-test":"modal-overlay",onMouseDown:t.handleClickAway,key:"clickAway",style:{opacity:e.overlayOpacity}}))}))})),t.state={animating:!1,prevOpen:e.open},t}return t=u,(n=[{key:"componentWillUnmount",value:function(){this.allowAnimationUpdates=!1}},{key:"render",value:function(){var e=this.props.open||this.state.animating||this.props.childrenInAnimation;return o.a.createElement(s.a,{open:e,closeReasons:["escapeKey"],onRequestClose:this.props.onRequestClose},e&&this.renderLayer())}}])&&v(t.prototype,n),u}(r.Component);S(j,"propTypes",k),S(j,"defaultProps",{childrenInAnimation:!1,open:!1,useLayerForClickAway:!0}),S(j,"getDerivedStateFromProps",(function(e,t){return e.open!==t.prevOpen?{animating:!0,prevOpen:e.open}:null}));var C=j},2:function(e,t){e.exports=n(7294)},21:function(e,t){e.exports=n(9920)},3:function(e,t){e.exports=n(2788)},34:function(e,t){e.exports=n(2640)},60:function(e,t){e.exports=n(5451)}})},9016:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=138)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},10:function(e,t,n){"use strict";function r(e,t){e&&("function"==typeof e?e(t):e.current=t)}n.d(t,"a",(function(){return r}))},138:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return J})),n.d(t,"PopoverContext",(function(){return x}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(70),u=n(4),s=n(0),c=n(34),f=n(15),p=n.n(f),d=n(60),h=n.n(d),m=n(39),b=n.n(m),y=n(28);function g(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function v(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?g(Object(n),!0).forEach((function(t){w(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):g(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function w(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _(e){var t=e.align,n=e.anchorPos,r=e.scrollContainerPos,o=e.canCoverAnchor,i=e.defaultPlacement,a=e.outerContainerEl,l=e.padding,u=e.repositionMode,s=e.windowHeight,c=e.windowWidth,f="any"===u,p="flip"===u||f,d=e.placement||i;"vertical"===i?d=n.top>s-n.bottom?"above":"below":"horizontal"===i&&(d=n.left>c-n.right?"left":"right");var h=d,m=function(e){var t=e.align,n=e.anchorPos,r=e.outerContainerEl,o=e.padding,i=e.placement;switch(i){case"above":return{top:n.top-r.offsetHeight,left:"edge"===t?n.left-o:n.middle-r.offsetWidth/2};case"below":return"end"===t?{top:n.bottom,left:n.right-r.offsetWidth+o}:{top:n.bottom,left:"edge"===t?n.left-o:n.middle-r.offsetWidth/2};case"left":return{top:"edge"===t?n.top-o:n.center-r.offsetHeight/2,left:n.left-r.offsetWidth};case"right":return{top:"edge"===t?n.top-o:n.center-r.offsetHeight/2,left:n.right};default:throw new Error("".concat(i," is not a valid placement value. Valid options are: 'above', 'below', 'left', or 'right'"))}}({align:t,anchorPos:n,outerContainerEl:a,padding:l,placement:h}),b=m.top,y=m.left,g="auto",w=c,x=s,O=h,S=n.top-a.offsetHeight>0,k=n.bottom+a.offsetHeight<s,j=n.left-a.offsetWidth>0,C=n.right+a.offsetWidth<c,E=.7*n.top>s-n.bottom,P=("edge"===t?n.left+a.offsetWidth-l:n.middle+a.offsetWidth/2)>c,A=("edge"===t?n.left-l:n.middle-a.offsetWidth/2)<0,T=("edge"===t?n.top-l:n.top-a.offsetHeight/2)<0,L=("edge"===t?n.top+a.offsetHeight-l:n.bottom+a.offsetHeight/2)>s;if("above"===O){if(!S&&p){if(k)return _(v(v({},e),{},{placement:"below"}));if(f&&C)return _(v(v({},e),{},{placement:"right"}));if(f&&j)return _(v(v({},e),{},{placement:"left"}));o&&(O="misaligned",b=0)}"misaligned"!==O&&(g=s-b-a.offsetHeight,r&&(g=Math.min(g,s-r.top)),b="auto"),P?y=Math.max(c-a.offsetWidth,0):A&&(y=0),o||(x=n.top)}if("below"===O){if(!k&&p){if(S&&E)return _(v(v({},e),{},{placement:"above"}));if(f&&C)return _(v(v({},e),{},{placement:"right"}));if(f&&j)return _(v(v({},e),{},{placement:"left"}));o&&(O="misaligned",b=0)}r&&(b=Math.min(b,r.bottom)),P?y=Math.max(c-a.offsetWidth,0):A&&(y=0),o||(x=s-n.bottom)}if("left"===O){if(!j&&p){if(C)return _(v(v({},e),{},{placement:"right"}));if(f&&k)return _(v(v({},e),{},{placement:"below"}));if(f&&S)return _(v(v({},e),{},{placement:"above"}));o&&(O="misaligned",b=0)}T?b=0:L&&(b=Math.max(s-a.offsetHeight,0)),o||(w=n.left)}if("right"===O){if(!C&&p){if(j)return _(v(v({},e),{},{placement:"left"}));if(f&&k)return _(v(v({},e),{},{placement:"below"}));if(f&&S)return _(v(v({},e),{},{placement:"above"}));o&&(O="misaligned",b=0)}T?b=0:L&&(b=Math.max(s-a.offsetHeight,0)),o||(w=c-n.left)}return{placement:O,maxHeight:x,maxWidth:w,outerContainerStyle:{top:b,left:y,bottom:g}}}var x=Object(r.createContext)({}),O=n(21),S=n(3),k=n.n(S),j=Object(s.pick)({enterprise:"8px",prisma:0}),C=k()(O.animated.div).withConfig({displayName:"PopoverStyles__Styled",componentId:"sc-1nahsvw-0"})(["position:fixed;z-index:",";left:-300%;top:-300%;"],s.variables.zindexPopover),E=k.a.div.withConfig({displayName:"PopoverStyles__StyledBox",componentId:"sc-1nahsvw-1"})(["",";",";"],s.mixins.reset("block"),(function(e){return"none"!==e.$appearance&&Object(S.css)(["padding:8px;"])})),P=k.a.div.withConfig({displayName:"PopoverStyles__StyledContent",componentId:"sc-1nahsvw-2"})(["",""],Object(s.pickVariant)("$appearance",{normal:Object(S.css)(["background-color:",";color:",";border:",";box-shadow:",";border-radius:",";"],s.variables.backgroundColorPopup,s.variables.contentColorDefault,Object(s.pick)({enterprise:{light:s.variables.border,dark:s.variables.border},prisma:"none"}),Object(s.pick)({enterprise:{light:Object(S.css)(["0 2px 2px ",""],s.mixins.colorWithAlpha(s.variables.gray20,.1)),dark:"0 1px 2px #000"},prisma:s.variables.overlayShadow}),s.variables.borderRadius),inverted:Object(S.css)(["background-color:",";color:",";"],Object(s.pick)({light:s.variables.gray20,dark:s.variables.white}),Object(s.pick)({light:s.variables.white,dark:s.variables.gray30}))})),A=k.a.div.withConfig({displayName:"PopoverStyles__StyledArrow",componentId:"sc-1nahsvw-3"})(["width:0;height:0;border-left:"," solid transparent;border-right:"," solid transparent;position:absolute;border-bottom-width:",";border-bottom-style:solid;",""],j,j,j,Object(s.pickVariant)("$appearance",{normal:Object(S.css)(["border-bottom-color:",";&::before{content:'';display:block;width:0;height:0;border-left:"," solid transparent;border-right:"," solid transparent;border-bottom:"," solid ",";position:absolute;top:1px;left:0;margin-left:-",";}"],Object(s.pick)({light:s.variables.borderColor,dark:s.variables.black}),j,j,j,s.variables.backgroundColor,j),inverted:Object(S.css)(["border-bottom-color:",";"],Object(s.pick)({light:s.variables.gray20,dark:s.variables.white}))})),T=k.a.div.withConfig({displayName:"PopoverStyles__StyledLowerRightCorner",componentId:"sc-1nahsvw-4"})(["position:fixed;right:0;bottom:0;"]),L=n(10),R=n(19);function M(e){return M="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},M(e)}function D(){return D=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},D.apply(this,arguments)}function I(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function F(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?I(Object(n),!0).forEach((function(t){H(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):I(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function N(e,t){if(e){if("string"==typeof e)return z(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?z(e,t):void 0}}function z(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function q(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function $(e,t,n){return t&&q(e.prototype,t),n&&q(e,n),e}function B(e,t){return B=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},B(e,t)}function U(e,t){return!t||"object"!==M(t)&&"function"!=typeof t?V(e):t}function V(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function W(e){return W=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},W(e)}function H(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var Z=["clickAway","escapeKey","offScreen","tabKey"],K={align:a.a.oneOf(["center","edge","theme","end"]),anchor:a.a.object,animation:a.a.bool,appearance:a.a.oneOf(["normal","inverted","none"]),autoCloseWhenOffScreen:a.a.bool,canCoverAnchor:a.a.bool,children:a.a.oneOfType([a.a.node,a.a.func]),closeReasons:a.a.arrayOf(a.a.oneOf(Z)),defaultPlacement:a.a.oneOf(["above","below","left","right","vertical","horizontal"]),elementRef:a.a.oneOfType([a.a.func,a.a.object]),id:a.a.string,onRequestClose:a.a.func,open:a.a.bool,pointTo:a.a.shape({x:a.a.number,y:a.a.number}),repositionMode:a.a.oneOf(["none","flip","any"]),retainFocus:a.a.bool,takeFocus:a.a.bool,splunkTheme:a.a.object},Q={align:"theme",animation:!0,appearance:"normal",autoCloseWhenOffScreen:!0,canCoverAnchor:!1,closeReasons:Z,defaultPlacement:"below",open:!1,repositionMode:"flip",retainFocus:!0,takeFocus:!1};function G(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1;return!!e&&!!t&&Object(u.every)(e,(function(e,r){return Object(u.isFinite)(e)?Math.abs(t[r]-e)<=n:t[r]===e}))}var X=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&B(e,t)}(i,e);var t,n,r=(t=i,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=W(t);if(n){var o=W(this).constructor;e=Reflect.construct(r,arguments,o)}else e=r.apply(this,arguments);return U(this,e)});function i(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,i),H(V(t=r.call(this,e)),"outerContainerEl",null),H(V(t),"innerContainerEl",null),H(V(t),"arrow",null),H(V(t),"windowSizeMeasurementEl",null),H(V(t),"handleScroll",void 0),H(V(t),"handleWindowScroll",void 0),H(V(t),"allowAnimationUpdates",!0),H(V(t),"getElPosition",(function(e){var n=e.getBoundingClientRect(),r={width:e.offsetWidth,height:e.offsetHeight},o=t.props.pointTo,i=o&&Object(u.has)(o,"x"),a=o&&Object(u.has)(o,"y");return r.left=i?n.left+((null==o?void 0:o.x)||0):n.left,r.top=a?n.top+((null==o?void 0:o.y)||0):n.top,r.right=i?r.left+r.width:n.left+r.width||n.right,r.bottom=a?r.top+r.height:n.top+r.height||n.bottom,r.middle=i?r.left:n.left+(r.right-n.left)/2,r.center=a?r.top:n.top+(r.bottom-n.top)/2,r})),H(V(t),"setPlacement",(function(e){var n=Object(R.a)();t.setState((function(r){var o,a=t.props,l=a.align,s=a.anchor,c=a.autoCloseWhenOffScreen,f=a.canCoverAnchor,p=a.defaultPlacement,d=a.open,h=a.repositionMode,m=a.splunkTheme,b=t.context||n,y=m.isPrisma;if(!(d&&t.outerContainerEl&&s&&r.anchorEl&&t.windowSizeMeasurementEl))return null;var g=t.getElPosition(r.anchorEl),v=b!==n?t.getElPosition(b):void 0;if(e&&c&&t.autoCloseWhenOffScreen(g,v))return null;var w,x,O=y?0:8,S=_({align:"theme"===l?y?"edge":"center":l,anchorPos:g,scrollContainerPos:v,canCoverAnchor:f,defaultPlacement:p,repositionMode:h,outerContainerEl:t.outerContainerEl,padding:8,windowWidth:t.windowSizeMeasurementEl.offsetLeft,windowHeight:t.windowSizeMeasurementEl.offsetTop}),k=S.placement,j=S.outerContainerStyle,C=S.maxHeight,E=S.maxWidth,P=(w=t.arrow?i.getArrowStyle({anchorPos:g,arrowHeight:O,outerContainerStyle:j,placement:k,outerContainerEl:t.outerContainerEl}):[],x=2,function(e){if(Array.isArray(e))return e}(w)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,i=void 0;try{for(var a,l=e[Symbol.iterator]();!(r=(a=l.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){o=!0,i=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw i}}return n}}(w,x)||N(w,x)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),A=P[0],T=P[1],L="none"!==t.props.appearance&&!y,R=G(g,r.anchorPos)&&G(j,r.outerContainerStyle)&&k===r.placement&&C===r.maxHeight&&E===r.maxWidth,M=G(Object(u.omit)(A,"transform"),Object(u.omit)(r.arrowStyle,"transform"))&&G(null!=T?T:{},null!==(o=r.arrowStyleTransformMeta)&&void 0!==o?o:{});return R&&(!L||L&&M)?null:{anchorPos:g,arrowStyle:A,arrowStyleTransformMeta:T,outerContainerStyle:j,placement:k,maxHeight:C,maxWidth:E}}))})),H(V(t),"handleNewAnchor",(function(e){var n,r=(n=!e||e instanceof HTMLElement?null!=e?e:void 0:Object(l.findDOMNode)(e))?t.getElPosition(n):void 0;t.setState({anchorEl:n,anchorPos:r})})),H(V(t),"handleInnerContainerMount",(function(e){t.innerContainerEl=e,e&&t.props.takeFocus&&Object(u.defer)(y.takeFocus,e),Object(L.a)(t.props.elementRef,e)})),H(V(t),"handleTab",(function(e){if(t.innerContainerEl)if(t.props.retainFocus)Object(y.handleTab)(t.innerContainerEl,e);else if(Object(y.isTabKey)(e)){var n=Object(y.getSortedTabbableElements)(t.innerContainerEl);n.length>0&&(e.shiftKey?n[0]:n[n.length-1])===e.target&&t.handleRequestClose({event:e,reason:"tabKey"})}})),H(V(t),"handleRequestClose",(function(e){t.props.open&&t.requestClose(e)})),H(V(t),"handleAnimationEnd",(function(){t.allowAnimationUpdates&&t.setState({animating:!1})})),H(V(t),"renderLayer",(function(){var e=t.props,n=e.animation,r=e.appearance,a=e.children,l=e.id,s=e.open,f=e.retainFocus,p=e.splunkTheme,d=t.state,h=d.anchorPos,m=d.arrowStyle,b=d.outerContainerStyle,y=d.placement,g=p.isPrisma,v=g&&"inverted"===r?"normal":r,w=t.state,_=w.maxHeight,O=w.maxWidth;"none"!==r&&(Object(u.isFinite)(_)&&(_-=20),Object(u.isFinite)(O)&&(O-=20));var S={anchorHeight:h?h.height:null,anchorWidth:h?h.width:null,placement:y||null,maxHeight:_||null,maxWidth:O||null},k=n?{opacity:s?1:0}:{opacity:1};return o.a.createElement(c.Spring,{from:{opacity:n?0:1},to:k,config:{tension:300,friction:40},onRest:t.handleAnimationEnd},(function(e){return o.a.createElement(C,{"data-test":"outer-popover",style:F(F({},b),e),ref:function(e){t.outerContainerEl=e}},(s||t.state.animating)&&o.a.createElement(E,D({$appearance:v,"data-test":"popover",ref:t.handleInnerContainerMount,tabIndex:-1,id:l,onKeyDown:t.handleTab},Object(u.omit)(t.props,["anchor"].concat(function(e){if(Array.isArray(e))return z(e)}(n=Object(u.keys)(i.propTypes))||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(n)||N(n)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()))),o.a.createElement(x.Provider,{value:{retainFocus:f}},"none"===r&&a,"none"!==r&&!g&&o.a.createElement(A,{$appearance:v,ref:function(e){t.arrow=e},style:m}),"none"!==r&&o.a.createElement(P,{$appearance:v},Object(u.isFunction)(a)?a(S):a))),o.a.createElement(T,{ref:function(e){t.windowSizeMeasurementEl=e}}));var n}))})),t.handleScroll=Object(u.throttle)(t.setPlacement.bind(V(t),!0),0),t.handleWindowScroll=Object(u.throttle)(t.setPlacement.bind(V(t),!0),0),t.setPlacement=Object(u.throttle)(t.setPlacement,0,{leading:!1}),t.state={animating:!1,prevOpen:e.open},t}return $(i,null,[{key:"getArrowStyle",value:function(e){var t=e.anchorPos,n=e.arrowHeight,r=e.placement,o=e.outerContainerStyle,i=e.outerContainerEl;if("misaligned"===r)return[{display:"none"}];var a={display:"block"},l=i.offsetHeight/2-22,s=-(i.offsetHeight/2-15),c=t.center-(o.top+i.offsetHeight/2)-n/2,f=Object(u.clamp)(c,s,l),p=t.middle-(o.left+i.offsetWidth/2)-n,d={left:{translateX:n/2,translateY:f,rotate:90},right:{translateX:-n/2,translateY:f,rotate:-90},above:{translateX:p,translateY:0,rotate:180},below:{translateX:p,translateY:0,rotate:0}}[r];return a.transform="translate(".concat(d.translateX,"px, ").concat(d.translateY,"px) rotate(").concat(d.rotate,"deg)"),a[{left:"right",right:"left",above:"bottom",below:"top"}[r]]="1px",a[{left:"top",right:"top",above:"left",below:"left"}[r]]="50%",[a,d]}}]),$(i,[{key:"componentDidMount",value:function(){this.handleNewAnchor(this.props.anchor)}},{key:"componentDidUpdate",value:function(e){e.anchor!==this.props.anchor&&this.handleNewAnchor(this.props.anchor),this.innerContainerEl&&(this.props.open||this.state.animating)&&(this.setPlacement(),!e.open&&this.props.open&&this.props.takeFocus&&Object(y.takeFocus)(this.innerContainerEl))}},{key:"componentWillUnmount",value:function(){this.setPlacement.cancel(),this.handleScroll.cancel(),this.allowAnimationUpdates=!1}},{key:"autoCloseWhenOffScreen",value:function(e,t){var n=Object(R.a)();return(e.top<0||e.top>n.innerHeight||e.left<0||e.left>n.innerWidth||!(!t||!(e.height+e.top<t.top||e.top>t.bottom||e.width+e.left<t.left||e.left>t.right)))&&(this.requestClose({reason:"offScreen"}),!0)}},{key:"requestClose",value:function(e){var t,n;Object(u.includes)(this.props.closeReasons,e.reason)&&(null===(t=(n=this.props).onRequestClose)||void 0===t||t.call(n,e))}},{key:"render",value:function(){var e=Object(R.a)(),t=this.props.open||this.state.animating,n=this.context||e;return[n!==e&&o.a.createElement(p.a,{target:n,eventType:"scroll",listener:this.handleScroll,options:{passive:!1,capture:!0},key:"eventListener"}),o.a.createElement(p.a,{target:e,eventType:"resize",listener:this.setPlacement,key:"eventListenerOnWindowResize"}),o.a.createElement(p.a,{target:e,eventType:"scroll",listener:this.handleWindowScroll,options:{passive:!1,capture:!0},key:"eventListenerOnWindowScroll"}),o.a.createElement(h.a,{closeReasons:Object(u.intersection)(this.props.closeReasons.filter((function(e){return"offScreen"!==e})),h.a.possibleCloseReasons),open:t,onRequestClose:this.handleRequestClose,key:"Layer"},t&&this.renderLayer())]}}]),i}(r.Component);H(X,"contextType",b.a),H(X,"defaultProps",Q),H(X,"propTypes",K),H(X,"getDerivedStateFromProps",(function(e,t){return e.open!==t.prevOpen?{animating:e.animation,prevOpen:e.open}:null}));var Y=Object(s.withSplunkTheme)(X);Y.propTypes=X.propTypes;var J=Y},15:function(e,t){e.exports=n(9213)},19:function(e,t,n){"use strict";n.d(t,"a",(function(){return o}));var r={document:n(27).b,navigator:{userAgent:""},location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""},history:{replaceState:function(){},pushState:function(){},go:function(){},back:function(){}},CustomEvent:function(){return this},addEventListener:function(){},removeEventListener:function(){},getComputedStyle:function(){return{getPropertyValue:function(){return""}}},Image:function(){},Date:function(){},screen:{},setTimeout:function(){},clearTimeout:function(){},matchMedia:function(){return{}},requestAnimationFrame:function(e){return"undefined"==typeof setTimeout?(e(),null):setTimeout(e,0)},cancelAnimationFrame:function(e){"undefined"!=typeof setTimeout&&clearTimeout(e)}};function o(){return"undefined"!=typeof window?window:r}},2:function(e,t){e.exports=n(7294)},21:function(e,t){e.exports=n(9920)},27:function(e,t,n){"use strict";n.d(t,"a",(function(){return o})),n.d(t,"b",(function(){return r}));var r={body:{appendChild:function(){return[]}},addEventListener:function(){},removeEventListener:function(){},activeElement:{blur:function(){},nodeName:""},querySelector:function(){return null},querySelectorAll:function(){return[]},getElementById:function(){return null},createEvent:function(){return{initEvent:function(){}}},createElement:function(){return{children:[],childNodes:[],style:{},setAttribute:function(){},getElementsByTagName:function(){return[]}}},createElementNS:function(){return{}},importNode:function(){return null},location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""}};function o(){return"undefined"!=typeof document?document:r}},28:function(e,t){e.exports=n(8568)},3:function(e,t){e.exports=n(2788)},34:function(e,t){e.exports=n(2640)},39:function(e,t){e.exports=n(7009)},4:function(e,t){e.exports=n(5220)},60:function(e,t){e.exports=n(5451)},70:function(e,t){e.exports=n(3935)}})},5766:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=174)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},174:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return h}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(3),u=n.n(l),s=n(0),c=u.a.span.withConfig({displayName:"ScreenReaderContentStyles__Styled",componentId:"sc-1lnohwp-0"})(["",";"],s.mixins.screenReaderContent());function f(){return f=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},f.apply(this,arguments)}var p={children:a.a.node.isRequired,elementRef:a.a.oneOfType([a.a.func,a.a.object])};function d(e){var t=e.children,n=e.elementRef,r=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["children","elementRef"]);return o.a.createElement(c,f({"data-test":"screen-reader-content",ref:n},r),t)}d.propTypes=p;var h=d},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)}})},7009:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=185)}({185:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return u})),n.d(t,"ScrollContainerContext",(function(){return a})),n.d(t,"ScrollContainerProvider",(function(){return l}));var r=n(2),o=n.n(r),i=n(19),a=o.a.createContext(Object(i.a)()),l=a.Provider,u=a},19:function(e,t,n){"use strict";n.d(t,"a",(function(){return o}));var r={document:n(27).b,navigator:{userAgent:""},location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""},history:{replaceState:function(){},pushState:function(){},go:function(){},back:function(){}},CustomEvent:function(){return this},addEventListener:function(){},removeEventListener:function(){},getComputedStyle:function(){return{getPropertyValue:function(){return""}}},Image:function(){},Date:function(){},screen:{},setTimeout:function(){},clearTimeout:function(){},matchMedia:function(){return{}},requestAnimationFrame:function(e){return"undefined"==typeof setTimeout?(e(),null):setTimeout(e,0)},cancelAnimationFrame:function(e){"undefined"!=typeof setTimeout&&clearTimeout(e)}};function o(){return"undefined"!=typeof window?window:r}},2:function(e,t){e.exports=n(7294)},27:function(e,t,n){"use strict";n.d(t,"a",(function(){return o})),n.d(t,"b",(function(){return r}));var r={body:{appendChild:function(){return[]}},addEventListener:function(){},removeEventListener:function(){},activeElement:{blur:function(){},nodeName:""},querySelector:function(){return null},querySelectorAll:function(){return[]},getElementById:function(){return null},createEvent:function(){return{initEvent:function(){}}},createElement:function(){return{children:[],childNodes:[],style:{},setAttribute:function(){},getElementsByTagName:function(){return[]}}},createElementNS:function(){return{}},importNode:function(){return null},location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""}};function o(){return"undefined"!=typeof document?document:r}}})},5414:(e,t,n)=>{e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=181)}({0:function(e,t){e.exports=n(5947)},1:function(e,t){e.exports=n(1581)},181:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return k}));var r=n(2),o=n.n(r),i=n(1),a=n.n(i),l=n(38),u=n(0),s=n(5),c=n(3),f=n.n(c),p=f.a.div.withConfig({displayName:"WaitSpinnerStyles__Styled",componentId:"sc-1nu971z-0"})(["",";"],u.mixins.reset("inline")),d=Object(c.keyframes)(["100%{transform:rotate(360deg);}"]),h=Object(c.keyframes)(["0%{transform:scale(0);opacity:0;}100%{transform:scale(1);opacity:1;}"]),m="2.07s",b=f.a.svg.withConfig({displayName:"WaitSpinnerStyles__StyledSvg",componentId:"sc-1nu971z-1"})([""," ",""],Object(u.pickVariant)("$size",{small:{enterprise:Object(c.css)(["width:14px;height:14px;"]),prisma:Object(c.css)(["width:16px;height:16px;"])},medium:{enterprise:Object(c.css)(["width:19px;height:19px;"]),prisma:Object(c.css)(["width:24px;height:24px;"])},large:{enterprise:Object(c.css)(["width:19px;height:19px;"]),prisma:Object(c.css)(["width:40px;height:40px;"])}}),(function(e){return e.$animated&&Object(u.pick)({enterprise:Object(c.css)(["transform-origin:center;animation:"," 1.2s steps(64) infinite;"],d),prisma:Object(c.css)(["animation:"," "," infinite linear,"," 500ms cubic-bezier(0.01,0,0,1);"],d,m,h)})})),y=Object(c.keyframes)(["0%{stroke-dasharray:110 10;stroke-dashoffset:-5.5;animation-timing-function:cubic-bezier(0.8,0,0.83,1);}50%{stroke-dasharray:26 94;stroke-dashoffset:-152;}100%{stroke-dasharray:110 10;stroke-dashoffset:-246.5;animation-timing-function:cubic-bezier(0.33,0,0.67,1);}"]),g=Object(c.keyframes)(["0%{stroke-dasharray:7 113;stroke-dashoffset:3;animation-timing-function:cubic-bezier(0.8,0,0.83,1);}50%{stroke-dasharray:90 30;stroke-dashoffset:-60;}100%{stroke-dasharray:7 113;stroke-dashoffset:-238;animation-timing-function:cubic-bezier(0.33,0,0.67,1);}"]),v=f.a.circle.withConfig({displayName:"WaitSpinnerStyles__StyledPrismaBasePath",componentId:"sc-1nu971z-2"})(["stroke:",";stroke-width:2;fill:transparent;"," stroke-dasharray:110 10;stroke-dashoffset:-5.5;"],u.variables.contentColorDisabled,(function(e){return e.$animated&&Object(c.css)(["animation:"," "," infinite;animation-fill-mode:backwards;"],y,m)})),w=f.a.circle.withConfig({displayName:"WaitSpinnerStyles__StyledPrismaFillPath",componentId:"sc-1nu971z-3"})(["fill:transparent;stroke-width:2;stroke:",";stroke-dasharray:7 113;stroke-dashoffset:3;",""],Object(u.pickVariant)("$size",{small:u.variables.contentColorDefault,medium:u.variables.contentColorDefault,large:u.variables.interactiveColorPrimary}),(function(e){return e.$animated&&Object(c.css)(["animation:"," "," infinite;"],g,m)})),_=f.a.circle.withConfig({displayName:"WaitSpinnerStyles__StyledEnterpriseCircle",componentId:"sc-1nu971z-4"})(["fill:transparent;stroke:",";stroke-width:2px;",""],Object(u.pick)({enterprise:{dark:u.variables.white,light:u.variables.gray60},prisma:u.variables.contentColorMuted}),Object(u.pick)({enterprise:Object(c.css)(["stroke-dasharray:34 19;"])}));function x(){return x=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},x.apply(this,arguments)}var O={elementRef:a.a.oneOfType([a.a.func,a.a.object]),screenReaderText:a.a.string,size:a.a.oneOf(["small","medium","large"])};function S(e){var t=e.elementRef,n=e.screenReaderText,r=void 0===n?Object(s._)("Waiting"):n,i=e.size,a=void 0===i?"small":i,c=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["elementRef","screenReaderText","size"]),f="on"===Object(l.useAnimationToggle)(),d=Object(u.useSplunkTheme)().isPrisma,h=d?"0 0 40 40":"0 0 19 19";return o.a.createElement(p,x({"data-test":"wait-spinner"},c),o.a.createElement(b,{viewBox:h,version:"1.1",xmlns:"http://www.w3.org/2000/svg",ref:t,$animated:f,$size:a},r&&o.a.createElement("title",null,r),o.a.createElement("g",null,d?o.a.createElement(o.a.Fragment,null,o.a.createElement(v,{r:"19",cx:"20",cy:"20",$animated:f,$size:a}),o.a.createElement(w,{r:"19",cx:"20",cy:"20",$animated:f,$size:a})):o.a.createElement(_,{cx:"9.5",cy:"9.5",r:"8.5"}))))}S.propTypes=O;var k=S},2:function(e,t){e.exports=n(7294)},3:function(e,t){e.exports=n(2788)},38:function(e,t){e.exports=n(6603)},5:function(e,t){e.exports=n(6219)}})},2411:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.extractAppName=s,t.versionLabel=t.username=t.splunkdPath=t.serverTimezoneInfo=t.rootPath=t.portNumber=t.locale=t.config=t.buildPushNumber=t.buildNumber=t.appBuild=t.app=t.isAvailable=t.CSRFToken=void 0;var r=n(5220),o=n(9327),i="undefined"==typeof window?n.g:window;function a(e){return(0,r.get)(i,["$C",e])}var l=(0,o.getEntry)("splunkweb_csrf_token_".concat(a("MRSPARKLE_PORT_NUMBER")));t.CSRFToken=l;var u=!!a("SPLUNKD_PATH");function s(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:(0,r.get)(i,["document","location","pathname"],""),t=e.match(/\w\w.\w\w\/(app|manager)\/([^/]+)/);return t?t[2]:void 0}t.isAvailable=u;var c=s();t.app=c;var f=a("APP_BUILD");t.appBuild=f;var p=a("BUILD_NUMBER");t.buildNumber=p;var d=a("BUILD_PUSH_NUMBER");t.buildPushNumber=d;var h=(0,r.get)(i,"$C");t.config=h;var m=a("LOCALE");t.locale=m;var b=a("MRSPARKLE_PORT_NUMBER");t.portNumber=b;var y=a("MRSPARKLE_ROOT_PATH");t.rootPath=y;var g=a("SERVER_ZONEINFO");t.serverTimezoneInfo=g;var v=a("SPLUNKD_PATH");t.splunkdPath=v;var w=a("USERNAME");t.username=w;var _=a("VERSION_LABEL");t.versionLabel=_},3718:(e,t,n)=>{"use strict";t.uH=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"undefined"!=typeof window?window:null;if(!e)return"enterprise";var t=e.__splunkd_partials__&&e.__splunkd_partials__["/services/server/info"]&&e.__splunkd_partials__["/services/server/info"].entry[0].content.product_type,n=e.__splunk_ui_theme__,r=e.$C&&e.$C.SPLUNK_UI_THEME;return n||r||t||"enterprise"};var r;(r=n(5277))&&r.__esModule,n(7212)},7212:(e,t,n)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.withConfig=s,t.insertCacheBuster=t.createURL=t.createStaticURL=t.createRESTURL=t.createDocsURL=t.createAppDocsURL=void 0;var o=n(7673);function i(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return i=function(){return e},e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){u(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e){var t=e.appBuild,n=e.buildNumber,r=e.buildPushNumber,i=e.locale,a=e.rootPath,u=e.splunkdPath;function s(e){var o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=l({appBuild:t,buildPushNumber:r,buildNumber:n},o),a=e.match(/(^|\w\w-\w\w\/)static\//);if(!a)return e;var u=a.index+a[0].length-1,s=e.match(/(^|\w\w-\w\w|)static\/app/),c=s?":".concat(i.appBuild||0):"",f=i.buildPushNumber?".".concat(i.buildPushNumber):"",p="/@".concat(i.buildNumber).concat(f).concat(c),d=e.substr(0,u),h=e.substr(u);return"".concat(d).concat(p).concat(h)}function c(e,u){var c=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},f=l({appBuild:t,buildPushNumber:r,buildNumber:n,rootPath:a,locale:i},c),p=e||"/",d=u?"?".concat((0,o.stringify)(u)):"";return"/"!==p.charAt(0)&&(p="/".concat(p)),s(p="".concat(f.rootPath||"","/").concat(f.locale).concat(p).concat(d),f)}function f(e,t){return c("/help",e,t)}return{createAppDocsURL:function(e,t,n){var r=t.appName,o=t.appVersion;return f({location:"[".concat(r,":").concat(o,"]").concat(e)},n)},createDocsURL:function(e,t){return f({location:e},t)},createRESTURL:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(/^http[s]?:\/\//.test(e))return e;var r,o,i=n.splunkdPath||u||"";return/^\/.*/.test(e)?/^\/services/.test(e)?"".concat(i).concat(e):e:t.app||t.owner?(r=t.sharing?"nobody":t.owner?encodeURIComponent(t.owner):"-",o="system"===t.sharing?"system":t.app?encodeURIComponent(t.app):"-","".concat(i,"/servicesNS/").concat(r,"/").concat(o,"/").concat(e)):"".concat(i,"/services/").concat(e)},createStaticURL:function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];return c.apply(void 0,["static/".concat(e)].concat(n))},createURL:c,insertCacheBuster:s}}var c=s(function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var t=i();if(t&&t.has(e))return t.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if(Object.prototype.hasOwnProperty.call(e,a)){var l=o?Object.getOwnPropertyDescriptor(e,a):null;l&&(l.get||l.set)?Object.defineProperty(n,a,l):n[a]=e[a]}return n.default=e,t&&t.set(e,n),n}(n(2411))),f=c.createAppDocsURL,p=c.createDocsURL,d=c.createRESTURL,h=c.createStaticURL,m=c.createURL,b=c.insertCacheBuster;t.insertCacheBuster=b,t.createURL=m,t.createStaticURL=h,t.createRESTURL=d,t.createDocsURL=p,t.createAppDocsURL=f},5266:(e,t,n)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=e.family,n=e.colorScheme,r=e.density,a=e.additionalThemeProperties,u=e.customizeTheme,c=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["family","colorScheme","density","additionalThemeProperties","customizeTheme"]),f=((0,o.useContext)(i.ThemeContext)||{}).splunkThemeV1,p=void 0===f?{}:f,d=s(s({},a),{},{splunkThemeV1:{family:t||p.family||"prisma",colorScheme:n||p.colorScheme||"dark",density:r||p.density||"comfortable",customizer:u||p.customizer}});return o.default.createElement(i.ThemeProvider,l({theme:d},c))};var o=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var t=a();if(t&&t.has(e))return t.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if(Object.prototype.hasOwnProperty.call(e,i)){var l=o?Object.getOwnPropertyDescriptor(e,i):null;l&&(l.get||l.set)?Object.defineProperty(n,i,l):n[i]=e[i]}return n.default=e,t&&t.set(e,n),n}(n(7294)),i=n(2788);function a(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return a=function(){return e},e}function l(){return l=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l.apply(this,arguments)}function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?u(Object(n),!0).forEach((function(t){c(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):u(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},1578:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={spacingQuarter:"5px",spacingHalf:"10px",spacing:"20px",fontSizeSmall:"12px",fontSize:"14px",fontSizeLarge:"16px",fontSizeXLarge:"18px",fontSizeXXLarge:"24px",lineHeight:"20px",inputHeight:"32px",borderRadius:"3px"}},6175:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={spacingQuarter:"5px",spacingHalf:"10px",spacing:"20px",fontSizeSmall:"12px",fontSize:"12px",fontSizeLarge:"16px",fontSizeXLarge:"18px",fontSizeXXLarge:"24px",lineHeight:"20px",inputHeight:"28px",borderRadius:"3px"}},652:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r,o=(r=n(5697))&&r.__esModule?r:{default:r};function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){l(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var u={backgroundColor:o.default.gray20,backgroundColorHover:o.default.gray30,borderColor:o.default.gray22,borderDarkColor:o.default.black,borderLightColor:o.default.gray60,textColor:o.default.white,textGray:o.default.gray92,textDisabledColor:o.default.gray45,linkColor:o.default.accentColorL10,linkColorHover:o.default.accentColorL20,border:"1px solid ".concat(o.default.gray22),borderDark:"1px solid ".concat(o.default.black),borderLight:"1px solid ".concat(o.default.gray60),focusShadowInset:"inset 0 0 1px 1px ".concat(o.default.gray25,", inset 0 0 0 3px ").concat(o.default.focusColor),draggableBackground:"url('data:image/png;base64,".concat("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAA1SURBVHgB7dKhEQAgDAPAhHmwSKZHYtmHVtZVVNTkXS53UeG57yPYazLmrB8o6h8QgPqBOAOboRAPJUGIOAAAAABJRU5ErkJggg==","') 0 0 / 8px 8px repeat")},s=a(a({},o.default),u);t.default=s},9098:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=u(n(5697)),o=u(n(652)),i=u(n(6175)),a=u(n(1578)),l=u(n(2829));function u(e){return e&&e.__esModule?e:{default:e}}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){f(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function f(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}t.default=function(e){var t=e.colorScheme,n=e.density,u={light:r.default,dark:o.default}[t],s={compact:i.default,comfortable:a.default}[n],f=(0,l.default)({colorScheme:t,density:n});return c(c(c({},u),s),f)}},5697:(e,t)=>{"use strict";function n(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function r(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i={white:"#ffffff",gray98:"#f7f8fa",gray96:"#f2f4f5",gray92:"#e1e6eb",gray80:"#c3cbd4",gray60:"#818d99",gray45:"#5c6773",gray30:"#3c444d",gray25:"#31373e",gray22:"#2b3033",gray20:"#171d21",black:"#000000"},a={accentColorL50:"#ecf8ff",accentColorL40:"#bfe9ff",accentColorL30:"#7ed2ff",accentColorL20:"#3ebcff",accentColorL10:"#00a4fd",accentColor:"#007abd",accentColorD10:"#006eaa",accentColorD20:"#006297",accentColorD30:"#005684",accentColorD40:"#004a71",accentColorD50:"#003d5e"},l={textColor:i.gray30,textGray:"#6b7785",textDisabledColor:i.gray80,linkColor:a.accentColorD10,linkColorHover:a.accentColor,borderLightColor:i.gray92,borderColor:i.gray80,focusColor:a.accentColorD10,backgroundColorHover:i.gray96,backgroundColor:i.white,transparent:"transparent"},u={focusShadow:"0 0 1px 3px ".concat(l.focusColor),focusShadowInset:"inset 0 0 1px 1px ".concat(i.white,", inset 0 0 0 3px ").concat(l.focusColor),overlayShadow:"0 4px 8px rgba(0, 0, 0, 0.2)"},s={draggableBackground:"url('data:image/png;base64,".concat("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAA2SURBVHgB7dKhEQAgDAPAhDnxDMAcDIBnT1pZV1FRk3e53EWFc+2P4N3DmLN+oKh/QADqB+IMUKEQD/CeueAAAAAASUVORK5CYII=","') 0 0 / 8px 8px repeat")},c={borderRadius:"3px",border:"1px solid ".concat(l.borderColor)},f="'Splunk Platform Sans', 'Proxima Nova', Roboto, Droid, 'Helvetica Neue', Helvetica, Arial, sans-serif",p={sansFontFamily:f,serifFontFamily:"Georgia, 'Times New Roman', Times, serif",monoFontFamily:"'Splunk Platform Mono', Inconsolata, Consolas, 'Droid Sans Mono', Monaco, 'Courier New', Courier, monospace",fontFamily:f,fontWeightBold:"700",fontWeightSemiBold:"500"},d=r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r({},{brandColorL50:"#f5fbf5",brandColorL40:"#dff2df",brandColorL30:"#bee6be",brandColorL20:"#9ed99e",brandColorL10:"#7ecd7e",brandColor:"#5cc05c",brandColorD10:"#49b849",brandColorD20:"#40a540",brandColorD30:"#389038",brandColorD40:"#307b30",brandColorD50:"#286728"}),i),a),{errorColorL50:"#fcedec",errorColorL40:"#f8dcd9",errorColorL30:"#f1b9b3",errorColorL20:"#ea958d",errorColorL10:"#e37267",errorColor:"#dc4e41",errorColorD10:"#c84535",errorColorD20:"#b23d30",errorColorD30:"#9c3529",errorColorD40:"#852d24",errorColorD50:"#6f261d"}),{alertColorL50:"#fef3ec",alertColorL40:"#fde6d9",alertColorL30:"#facdb3",alertColorL20:"#f7b48c",alertColorL10:"#f49b66",alertColor:"#f1813f",alertColorD10:"#da742e",alertColorD20:"#c2672a",alertColorD30:"#aa5a25",alertColorD40:"#914d1f",alertColorD50:"#79401a"}),{warningColorL50:"#fff9eb",warningColorL40:"#fef2d7",warningColorL30:"#fde5ae",warningColorL20:"#fbd886",warningColorL10:"#facb5d",warningColor:"#f8be34",warningColorD10:"#e0ac16",warningColorD20:"#c79915",warningColorD30:"#ae8613",warningColorD40:"#957312",warningColorD50:"#7d600f"}),{successColorL50:"#eef6ee",successColorL40:"#ddecdd",successColorL30:"#bbd9ba",successColorL20:"#98c697",successColorL10:"#76b374",successColor:"#53a051",successColorD10:"#479144",successColorD20:"#40813d",successColorD30:"#387135",successColorD40:"#2f612e",successColorD50:"#275126"}),{infoColorL50:"#e5f0f5",infoColorL40:"#cce2eb",infoColorL30:"#99c5d7",infoColorL20:"#66a7c4",infoColorL10:"#338ab0",infoColor:"#006d9c",infoColorD10:"#00577c",infoColorD20:"#004c6c",infoColorD30:"#00415d",infoColorD40:"#00364d",infoColorD50:"#002b3e"}),{cat1Color:"#297ba5",cat1ColorL:"#78b9d6",cat2Color:"#4fa484",cat2ColorL:"#74d5c2",cat3Color:"#b6c75a",cat3ColorL:"#dce6a5",cat4Color:"#3c6188",cat4ColorL:"#a0b2ca",cat5Color:"#ec9960",cat5ColorL:"#fac9a7",cat6Color:"#a65c7d",cat6ColorL:"#d3a7ba",cat7Color:"#708794",cat7ColorL:"#b2c0c8",cat8Color:"#38b8bf",cat8ColorL:"#92dde2",cat9Color:"#ffde63",cat9ColorL:"#ffeeae",cat10Color:"#c19975",cat10ColorL:"#d7bfab",cat11Color:"#5a4575",cat11ColorL:"#b7acca",cat12Color:"#7ea77b",cat12ColorL:"#b2cab0",cat13Color:"#576d83",cat13ColorL:"#a5b2bf",cat14Color:"#d7c6b7",cat14ColorL:"#e9ddd4",cat15Color:"#339bb2",cat15ColorL:"#66c3d0",cat16Color:"#236d9b",cat16ColorL:"#66a7c2",cat17Color:"#e5dc80",cat17ColorL:"#f1eab7",cat18Color:"#96907f",cat18ColorL:"#c1bcb3",cat19Color:"#87bc65",cat19ColorL:"#b6d7a3",cat20Color:"#cf7e60",cat20ColorL:"#e1b2a1",cat21Color:"#7b5547",cat21ColorL:"#dec4ba",cat22Color:"#77d6d8",cat22ColorL:"#abe6e8",cat23Color:"#4a7f2c",cat23ColorL:"#91b282",cat24Color:"#f589ad",cat24ColorL:"#f8b7ce",cat25Color:"#6a2c5d",cat25ColorL:"#cba3c2",cat26Color:"#aaabae",cat26ColorL:"#cccdce",cat27Color:"#9a7438",cat27ColorL:"#c3ab89",cat28Color:"#a4d563",cat28ColorL:"#c7e6a3",cat29Color:"#7672a4",cat29ColorL:"#ada9c8",cat30Color:"#184b81",cat30ColorL:"#a4bbe0"}),{diverging1ColorA:"#006d9c",diverging1ColorB:"#ec9960",diverging2ColorA:"#af575a",diverging2ColorB:"#62b3b2",diverging3ColorA:"#4fa484",diverging3ColorB:"#f8be34",diverging4ColorA:"#5a4575",diverging4ColorB:"#708794",diverging5ColorA:"#294e70",diverging5ColorB:"#b6c75a"}),{syntaxBlue:"#2662fc",syntaxBlueLight:"#006d9c",syntaxBrown:"#a67f59",syntaxGray:"#8293a7",syntaxGreen:"#5ca300",syntaxGreenLight:"#5ba383",syntaxOrange:"#f58220",syntaxPink:"#cf00cf",syntaxPurple:"#7738ff",syntaxPurpleLight:"#b19cd9",syntaxRed:"#d90700",syntaxRedLight:"#af575a",syntaxTeal:"#00a8ab"}),p),l),s),u),c),{zindexLayer:1e3,zindexFixedNavbar:1030,zindexModalBackdrop:1040,zindexModal:1050,zindexPopover:1060,zindexToastMessages:2e3});t.default=d},2829:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=u(n(7621)),o=u(n(5697)),i=u(n(652)),a=u(n(6175)),l=u(n(1578));function u(e){return e&&e.__esModule?e:{default:e}}t.default=function(e){var t=e.colorScheme,n=e.density,u={light:o.default,dark:i.default}[t],s={compact:a.default,comfortable:l.default}[n];return{accentColorPositive:u.successColor,accentColorWarning:u.warningColor,accentColorAlert:u.alertColor,accentColorNegative:u.errorColor,statusColorInfo:u.infoColorL10,statusColorNormal:u.successColorL10,statusColorLow:u.warningColorL10,statusColorMedium:u.alertColorL10,statusColorHigh:u.errorColorL10,statusColorCritical:u.errorColorD20,embossShadow:u.overlayShadow,dragShadow:u.overlayShadow,modalShadow:u.overlayShadow,backgroundColorPopup:u.backgroundColor,backgroundColorSection:u.backgroundColor,backgroundColorSidebar:u.backgroundColor,backgroundColorPage:u.backgroundColor,backgroundColorNavigation:u.backgroundColor,backgroundColorFloating:u.backgroundColor,backgroundColorDialog:u.backgroundColor,backgroundColorScrim:(0,r.default)(u.gray30).setAlpha(.8).toRgbString(),contentColorActive:u.textColor,contentColorDefault:u.textColor,contentColorMuted:u.textGray,contentColorDisabled:u.textDisabledColor,contentColorInverted:u.gray30,neutral100:"dark"===t?u.gray25:u.gray98,neutral200:"dark"===t?u.gray30:u.gray96,neutral300:"dark"===t?u.gray45:u.gray92,neutral400:"dark"===t?u.gray60:r.default.mix(u.gray92,u.gray80).toRgbString(),neutral500:u.gray80,interactiveColorPrimary:u.brandColor,interactiveColorBorder:u.borderColor,spacingXSmall:s.spacingQuarter,spacingSmall:s.spacingHalf,spacingMedium:"calc(".concat(s.spacing," * 0.75)"),spacingLarge:s.spacing,spacingXLarge:"calc(".concat(s.spacing," * 1.5)"),spacingXXLarge:"calc(".concat(s.spacing," * 2)"),spacingXXXLarge:"calc(".concat(s.spacing," * 2.5)")}}},463:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=n(5525);t.default=function(e){var t,n=(null===(t=e.theme)||void 0===t?void 0:t.splunkThemeV1)||{},o=n.family,i=n.colorScheme,a=n.density;return(0,r.addThemeDefaults)({family:o,colorScheme:i,density:a})}},5580:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.clearGetThemeCache=t.default=void 0;var r=l(n(9776)),o=l(n(9098)),i=l(n(7633)),a=n(5525);function l(e){return e&&e.__esModule?e:{default:e}}function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?u(Object(n),!0).forEach((function(t){c(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):u(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var f=(0,r.default)((function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=(0,a.addThemeDefaults)(e),n=t.family,r=t.colorScheme,l=t.density,u="prisma"===n,c="enterprise"===n,f="comfortable"===l,p="compact"===l,d="dark"===r,h="light"===r;return Object.freeze(s({colorScheme:r,density:l,family:n,isPrisma:u,isEnterprise:c,isComfortable:f,isCompact:p,isDark:d,isLight:h},"enterprise"===n?(0,o.default)({colorScheme:r,density:l}):(0,i.default)({colorScheme:r,density:l})))}),(function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.family,n=e.colorScheme,r=e.density;return"".concat(t).concat(n).concat(r)}));t.clearGetThemeCache=function(){var e,t;return null===(e=(t=f.cache).clear)||void 0===e?void 0:e.call(t)};var p=f;t.default=p},5947:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r={getSettingsFromThemedProps:!0,getTheme:!0,mixins:!0,pick:!0,pickVariant:!0,SplunkThemeProvider:!0,useSplunkTheme:!0,withSplunkTheme:!0,variables:!0};Object.defineProperty(t,"getSettingsFromThemedProps",{enumerable:!0,get:function(){return o.default}}),Object.defineProperty(t,"getTheme",{enumerable:!0,get:function(){return i.default}}),Object.defineProperty(t,"mixins",{enumerable:!0,get:function(){return a.default}}),Object.defineProperty(t,"pick",{enumerable:!0,get:function(){return l.default}}),Object.defineProperty(t,"pickVariant",{enumerable:!0,get:function(){return u.default}}),Object.defineProperty(t,"SplunkThemeProvider",{enumerable:!0,get:function(){return s.default}}),Object.defineProperty(t,"useSplunkTheme",{enumerable:!0,get:function(){return c.default}}),Object.defineProperty(t,"withSplunkTheme",{enumerable:!0,get:function(){return f.default}}),Object.defineProperty(t,"variables",{enumerable:!0,get:function(){return p.default}});var o=h(n(463)),i=h(n(5580)),a=h(n(9482)),l=h(n(7209)),u=h(n(3928)),s=h(n(5266)),c=h(n(1093)),f=h(n(4409)),p=h(n(669)),d=n(9092);function h(e){return e&&e.__esModule?e:{default:e}}Object.keys(d).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||Object.defineProperty(t,e,{enumerable:!0,get:function(){return d[e]}}))}))},9482:(e,t,n)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0});var o={typography:!0};Object.defineProperty(t,"typography",{enumerable:!0,get:function(){return a.default}}),t.default=void 0;var i=u(n(711));Object.keys(i).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(o,e)||Object.defineProperty(t,e,{enumerable:!0,get:function(){return i[e]}}))}));var a=u(n(4120));function l(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return l=function(){return e},e}function u(e){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var t=l();if(t&&t.has(e))return t.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if(Object.prototype.hasOwnProperty.call(e,i)){var a=o?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(n,i,a):n[i]=e[i]}return n.default=e,t&&t.set(e,n),n}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){f(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function f(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.keys(a).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(o,e)||Object.defineProperty(t,e,{enumerable:!0,get:function(){return a[e]}}))}));var p=c(c({},i.default),{},{typography:a.default});t.default=p},4120:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.typographyVariants=t.default=void 0;var r,o=n(2788),i=n(5220),a=(r=n(669))&&r.__esModule?r:{default:r};function l(){var e=s(["\n                    margin: 0;\n                    padding: 0;\n                "]);return l=function(){return e},e}function u(){var e=s(["\n        ","\n\n        color: ",";\n        font-family: ",";\n        font-size: ",";\n        font-weight: ",";\n        line-height: ",";\n    "]);return u=function(){return e},e}function s(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function f(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){p(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function p(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function d(e){return d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},d(e)}var h=["body","title1","title2","title3","title4","title5","title6","title7","largeBody","smallBody","footnote","monoBody","monoSmallBody"];t.typographyVariants=h;var m={active:a.default.contentColorActive,default:a.default.contentColorDefault,disabled:a.default.contentColorDisabled,inverted:a.default.contentColorInverted,muted:a.default.contentColorMuted},b={sansSerif:a.default.sansFontFamily,monospace:a.default.monoFontFamily};t.default=function(e,t){var n,r,s="string"==typeof(n=e)&&h.includes(n)?e:void 0;r=s&&void 0!==t?t:void 0===s&&"object"===d(e)&&void 0===t?e:{};var c=s?function(e){var t=a.default.contentColorDefault,n=a.default.fontFamily,r=a.default.lineHeight,o=a.default.fontSize,i="normal";switch(e){case"title1":t=a.default.contentColorActive,r="40px",o="36px",i=a.default.fontWeightBold;break;case"title2":t=a.default.contentColorActive,r="48px",o=a.default.fontSizeXXLarge,i=a.default.fontWeightBold;break;case"title3":t=a.default.contentColorActive,r="24px",o="20px",i=a.default.fontWeightBold;break;case"title4":t=a.default.contentColorActive,r="22px",o=a.default.fontSizeLarge,i=a.default.fontWeightBold;break;case"title5":t=a.default.contentColorActive,r=a.default.lineHeight,o=a.default.fontSize,i=a.default.fontWeightBold;break;case"title6":t=a.default.contentColorActive,r=a.default.lineHeight,o=a.default.fontSize,i=a.default.fontWeightSemiBold;break;case"title7":t=a.default.contentColorActive,r="16px",o=a.default.fontSizeSmall,i=a.default.fontWeightSemiBold;break;case"largeBody":t=a.default.contentColorDefault,r="24px",o=a.default.fontSizeLarge,i="normal";break;case"smallBody":t=a.default.contentColorDefault,r="16px",o=a.default.fontSizeSmall,i="normal";break;case"footnote":t=a.default.contentColorDefault,r="13px",o="10px",i="normal";break;case"monoBody":n=a.default.monoFontFamily;break;case"monoSmallBody":t=a.default.contentColorDefault,n=a.default.monoFontFamily,r="16px",o=a.default.fontSizeSmall,i="normal";break;case"body":break;default:return e}return{color:t,family:n,size:o,weight:i,lineHeight:r,withReset:!0}}(s):{},p=f(f({},r),{},{size:r.size?"".concat(r.size,"px"):void 0,lineHeight:r.lineHeight?"".concat(r.lineHeight,"px"):void 0,color:r.color?m[r.color]:void 0,family:r.family?b[r.family]:void 0}),y={color:a.default.contentColorDefault,family:a.default.fontFamily,size:a.default.fontSize,weight:"normal",lineHeight:a.default.lineHeight,withReset:!1},g=(0,i.merge)(y,c,p);return function(){return(0,o.css)(u(),(function(){return g.withReset&&(0,o.css)(l())}),g.color,g.family,g.size,g.weight,g.lineHeight)}}},711:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.clearfix=f,t.ellipsis=p,t.printWidth100Percent=d,t.printHide=h,t.printNoBackground=m,t.printWrapAll=b,t.screenReaderContent=y,t.overlayColors=g,t.colorWithAlpha=v,t.default=t.reset=void 0;var r=u(n(7621)),o=n(2788),i=n(691),a=u(n(669)),l=u(n(7209));function u(e){return e&&e.__esModule?e:{default:e}}function s(){var e,t,n=(e=["\n        /* Generic resets */\n        animation: none 0s ease 0s 1 normal none running;\n        backface-visibility: visible;\n        background: transparent none repeat 0 0 / auto auto padding-box border-box scroll;\n        border: medium none currentColor;\n        border-collapse: separate;\n        border-image: none;\n        border-radius: 0;\n        border-spacing: 0;\n        bottom: auto;\n        box-shadow: none;\n        caption-side: top;\n        clear: none;\n        clip: auto;\n        columns: auto;\n        column-count: auto;\n        column-fill: balance;\n        column-gap: normal;\n        column-rule: medium none currentColor;\n        column-span: 1;\n        column-width: auto;\n        content: normal;\n        counter-increment: none;\n        counter-reset: none;\n        empty-cells: show;\n        float: none;\n        font-style: normal;\n        font-variant: normal;\n        font-weight: normal;\n        font-stretch: normal;\n        height: auto;\n        hyphens: none;\n        left: auto;\n        letter-spacing: normal;\n        list-style: disc outside none;\n        margin: 0;\n        max-height: none;\n        max-width: none;\n        min-height: 0;\n        min-width: 0;\n        opacity: 1;\n        orphans: 2;\n        overflow: visible;\n        overflow-x: visible;\n        overflow-y: visible;\n        padding: 0;\n        page-break-after: auto;\n        page-break-before: auto;\n        page-break-inside: auto;\n        perspective: none;\n        perspective-origin: 50% 50%;\n        pointer-events: auto;\n        position: static;\n        right: auto;\n        tab-size: 8;\n        table-layout: auto;\n        text-align: left;\n        text-align-last: auto;\n        text-decoration: none;\n        text-indent: 0;\n        text-shadow: none;\n        text-transform: none;\n        top: auto;\n        transform: none;\n        transform-origin: 50% 50% 0;\n        transform-style: flat;\n        transition: none 0s ease 0s;\n        user-select: auto;\n        vertical-align: baseline;\n        white-space: normal;\n        widows: 2;\n        width: auto;\n        word-spacing: normal;\n        z-index: auto;\n        /* Splunk-specific resets */\n        border-width: 1px;\n        box-sizing: border-box;\n        color: ",";\n        cursor: inherit;\n        display: ",";\n        font-family: ",";\n        font-size: ",";\n        line-height: ",";\n        outline: medium none ",";\n        visibility: inherit;\n    "],t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}})));return s=function(){return n},n}var c=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"inline";return function(){return(0,o.css)(s(),(0,l.default)({enterprise:a.default.textColor,prisma:a.default.contentColorDefault}),e,a.default.fontFamily,a.default.fontSize,a.default.lineHeight,a.default.focusColor)}};function f(){return{"&::after":{display:"table",content:'""',clear:"both"}}}function p(){return{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}function d(){return{maxWidth:"100% !important",width:"100% !important",overflow:"hidden !important"}}function h(){return{display:"none !important"}}function m(){return{background:"none !important"}}function b(){return{wordBreak:"break-all !important",wordWrap:"break-word !important",overflowWrap:"break-word !important",whiteSpace:"normal !important"}}function y(){return{position:"absolute",overflow:"hidden",clip:"rect(0 0 0 0)",height:"1px",width:"1px",margin:"-1px",padding:0,border:0}}function g(e,t){return function(n){var o="function"==typeof e?e(n):e,a="function"==typeof t?t(n):t,l=(0,i.normal)((0,r.default)(o).toRgb(),(0,r.default)(a).toRgb());return(0,r.default)(l).toRgbString()}}function v(e,t){return function(n){var o="function"==typeof e?e(n):e;return(0,r.default)(o).setAlpha(t).toRgbString()}}t.reset=c;var w={reset:c,clearfix:f,ellipsis:p,printWidth100Percent:d,printHide:h,printNoBackground:m,printWrapAll:b,screenReaderContent:y,colorWithAlpha:v,overlayColors:g};t.default=w},7209:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isInterpolationResult=a,t.default=t.getThemeVariant=void 0;var r=n(5525);function o(e){return o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o(e)}var i={enterprise:"family",prisma:"family",light:"colorScheme",dark:"colorScheme",compact:"density",comfortable:"density"};function a(e){return"object"!==o(e)||Array.isArray(e)||null===e}var l=function e(t,n){var r=Object.keys(t).shift();if(!r)throw new Error("A pick tree cannot be empty.");var o=i[r];if(!o)throw new Error("Invalid pick tree key: ".concat(r));var l=t[n[o]];return a(l)?l:e(l,n)};t.getThemeVariant=l;t.default=function(e){return function(t){var n=t.theme,o=(0,r.addThemeDefaults)(null==n?void 0:n.splunkThemeV1);return l(e,o)}}},3928:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=n(7209),o=n(5525);t.default=function(e,t){return function(n){var i,a=n[e],l=t[a];if((0,r.isInterpolationResult)(l))return l;var u=(0,o.addThemeDefaults)(null===(i=n.theme)||void 0===i?void 0:i.splunkThemeV1);return(0,r.getThemeVariant)(l,u)}}},4160:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=l(n(7621)),o=l(n(3061)),i=l(n(1502)),a=l(n(3276));function l(e){return e&&e.__esModule?e:{default:e}}function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?u(Object(n),!0).forEach((function(t){c(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):u(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}t.default=function(e){var t=e.colorScheme,n={light:i.default,dark:a.default}[t],l={focusColor:(0,r.default)(n.interactiveColorPrimary).setAlpha(.7).toRgbString(),transparent:"transparent",linkColor:n.interactiveColorPrimary},u={hoverShadow:"0 0 0 2px ".concat(n.backgroundColorPage,", 0 0 0 5px ").concat(n.interactiveColorOverlayHover),focusShadow:"0 0 0 2px ".concat(n.backgroundColorPage,", 0 0 0 5px ").concat(l.focusColor),focusShadowInset:"inset 0 0 0 3px ".concat(l.focusColor)},c={draggableBackground:"radial-gradient(circle at 1px 1px, ".concat(n.contentColorMuted,", ").concat(n.contentColorMuted," 1px, transparent 1px) 0 0 / 4px 6px")},f="'Splunk Platform Sans', 'Splunk Data Sans', Roboto, Droid, 'Helvetica Neue', Helvetica, Arial, sans-serif";return s(s(s(s(s(s({},{sansFontFamily:f,serifFontFamily:"Georgia, 'Times New Roman', Times, serif",monoFontFamily:"'Splunk Platform Mono', 'Roboto Mono', Consolas, 'Droid Sans Mono', Monaco, 'Courier New', Courier, monospace",fontFamily:f,fontWeightBold:"700",fontWeightSemiBold:"500"}),l),o.default),u),c),{zindexLayer:1e3,zindexFixedNavbar:1030,zindexModalBackdrop:1040,zindexModal:1050,zindexPopover:1060,zindexToastMessages:2e3})}},4301:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={spacingXSmall:"4px",spacingSmall:"8px",spacingMedium:"12px",spacingLarge:"16px",spacingXLarge:"24px",spacingXXLarge:"32px",spacingXXXLarge:"40px",fontSizeSmall:"12px",fontSize:"14px",fontSizeLarge:"16px",fontSizeXLarge:"18px",fontSizeXXLarge:"24px",lineHeight:"20px",inputHeight:"40px",borderRadius:"4px"}},5841:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={spacingXSmall:"4px",spacingSmall:"8px",spacingMedium:"12px",spacingLarge:"16px",spacingXLarge:"24px",spacingXXLarge:"32px",spacingXXXLarge:"40px",fontSizeSmall:"12px",fontSize:"14px",fontSizeLarge:"16px",fontSizeXLarge:"18px",fontSizeXXLarge:"24px",lineHeight:"20px",inputHeight:"32px",borderRadius:"4px"}},3276:(e,t)=>{"use strict";function n(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function r(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i=r(r(r(r(r(r(r(r({},{accentColorPositive:"#85f415",accentColorWarning:"#f49106",accentColorAlert:"#f0581f",accentColorNegative:"#ff4242"}),{statusColorInfo:"#61cafa",statusColorNormal:"#85f415",statusColorLow:"#2cbda3",statusColorMedium:"#f49106",statusColorHigh:"#ff4242",statusColorCritical:"#ff3361"}),{embossShadow:"0px 1px 5px rgba(0, 0, 0, 0.35), 0px 0px 1px rgba(0, 0, 0, 0.35)",overlayShadow:"0px 26px 103px rgba(0, 0, 0, 0.64), 0px 11px 18px rgba(0, 0, 0, 0.32), 0px 3px 6px rgba(0, 0, 0, 0.3)",dragShadow:"0px 26px 103px rgba(0, 0, 0, 0.64), 0px 11px 18px rgba(0, 0, 0, 0.32), 0px 3px 6px rgba(0, 0, 0, 0.3)",modalShadow:"0px 50px 200px #000000, 0px 29px 66px rgba(0, 0, 0, 0.41), 0px 14px 47px rgba(0, 0, 0, 0.17), 0px 5px 10px rgba(0, 0, 0, 0.15)"}),{backgroundColorPopup:"#27292e",backgroundColorSection:"#1a1c20",backgroundColorSidebar:"#0b0c0e",backgroundColorPage:"#111215",backgroundColorNavigation:"#08090a",backgroundColorFloating:"#ffffff",backgroundColorDialog:"#1e2024",backgroundColorScrim:"rgba(0, 0, 0, 0.8)"}),{contentColorActive:"#fafafa",contentColorDefault:"#b5b5b5",contentColorDisabled:"#6b6b6b",contentColorInverted:"#000000",contentColorMuted:"#909090"}),{black:"#000000",neutral100:"#33343b",neutral200:"#43454b",neutral300:"#505158",neutral400:"#818285",neutral500:"#acacad",white:"#ffffff"}),{interactiveColorPrimary:"#3993FF",interactiveColorBorder:"rgba(255, 255, 255, 0.5)",interactiveColorBorderHover:"rgba(255, 255, 255, 0.7)",interactiveColorBorderDisabled:"rgba(255, 255, 255, 0.30)",interactiveColorOverlaySelected:"rgba(255, 255, 255, 0.1)",interactiveColorOverlayHover:"rgba(255, 255, 255, 0.05)",interactiveColorOverlayActive:"rgba(0, 0, 0, 0.2)",interactiveColorOverlayDrag:"rgba(57, 147, 255, 0.16)",interactiveColorBackground:"#272a2f",interactiveColorBackgroundDisabled:"rgba(255, 255, 255, 0.15)"}),{syntaxBlue:"#6cd0f0",syntaxBrown:"#fccf87",syntaxGray:"#7d7d7d",syntaxGreen:"#cef06c",syntaxOrange:"#f7933f",syntaxPink:"#f494e5",syntaxPurple:"#a870ef",syntaxRed:"#e85b79",syntaxTeal:"#45d4ba"});t.default=i},3061:(e,t)=>{"use strict";function n(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function r(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.highLow=t.sequential=t.divergent=t.categorical=t.staticColors=void 0;var i={static1:"#7B56DB",static2:"#009CEB",static3:"#00CDAF",static4:"#DD9900",static5:"#FF677B",static6:"#CB2196",static7:"#813193",static8:"#0051B5",static9:"#008C80",static10:"#99B100",static11:"#FFA476",static12:"#FF6ACE",static13:"#AE8CFF",static14:"#00689D",static15:"#00490A",static16:"#465D00",static17:"#9D6300",static18:"#F6540B",static19:"#FF969E",static20:"#E47BFE"};t.staticColors=i;var a=r(r(r(r({},{categorical1D1:"#5C33FF",categorical1D2:"#207865",categorical1D3:"#AD3F20",categorical1D4:"#003E80",categorical1D5:"#78062A",categorical1D6:"#2F8811",categorical1D7:"#555555"}),{categorical1L1:"#9980FF",categorical1L2:"#45D4BA",categorical1L3:"#FB865C",categorical1L4:"#66AAF9",categorical1L5:"#E85B79",categorical1L6:"#88EE66",categorical1L7:"#F0B000"}),{categorical2D1:"#1F4D5B",categorical2D2:"#CC0AD6",categorical2D3:"#017FA2",categorical2D4:"#D81E5B",categorical2D5:"#621FFF",categorical2D6:"#348350",categorical2D7:"#555555"}),{categorical2L1:"#5599BE",categorical2L2:"#FB9DFB",categorical2L3:"#00BBEE",categorical2L4:"#EE3399",categorical2L5:"#9980FF",categorical2L6:"#5FBF7F",categorical2L7:"#F58B00"});t.categorical=a;var l=r(r(r(r(r(r(r(r({},{divergent1D1:"#118832",divergent1D2:"#1C6B2D",divergent1D3:"#284D27",divergent1D4:"#333022",divergent1D5:"#692A21",divergent1D6:"#9E2520",divergent1D7:"#D41F1F"}),{divergent1L1:"#08AE37",divergent1L2:"#55C169",divergent1L3:"#A1D59C",divergent1L4:"#EEE8CE",divergent1L5:"#F4BAA9",divergent1L6:"#F98C83",divergent1L7:"#FF5E5E"}),{divergent2D1:"#0070F3",divergent2D2:"#115BAD",divergent2D3:"#224468",divergent2D4:"#333022",divergent2D5:"#692A21",divergent2D6:"#9E2520",divergent2D7:"#D41F1F"}),{divergent2L1:"#2A99FF",divergent2L2:"#6BB3EE",divergent2L3:"#ADCCDD",divergent2L4:"#EEE8CE",divergent2L5:"#F4BAA9",divergent2L6:"#F98C83",divergent2L7:"#FF5E5E"}),{divergent3D1:"#299986",divergent3D2:"#277C52",divergent3D3:"#24551F",divergent3D4:"#333022",divergent3D5:"#422879",divergent3D6:"#602CA1",divergent3D7:"#8747DA"}),{divergent3L1:"#14846C",divergent3L2:"#45D4BA",divergent3L3:"#9ADEC4",divergent3L4:"#EEE8CE",divergent3L5:"#D7BEE4",divergent3L6:"#C093F9",divergent3L7:"#9156DD"}),{divergent4D1:"#0D8387",divergent4D2:"#1A6765",divergent4D3:"#264C44",divergent4D4:"#333022",divergent4D5:"#693623",divergent4D6:"#9F3B23",divergent4D7:"#D54124"}),{divergent4L1:"#008287",divergent4L2:"#2EA39B",divergent4L3:"#5CC3AF",divergent4L4:"#EEE8CE",divergent4L5:"#ECA14E",divergent4L6:"#E3723A",divergent4L7:"#DA4325"});t.divergent=l;var u=r(r(r(r(r(r(r(r(r(r(r(r({},{sequential1D1:"#118832",sequential1D2:"#669922",sequential1D3:"#9D9F0D",sequential1D4:"#CBA700",sequential1D5:"#D97A0D",sequential1D6:"#D94E17",sequential1D7:"#D41F1F"}),{sequential1L1:"#088F44",sequential1L2:"#2EB82E",sequential1L3:"#C3CC33",sequential1L4:"#FFD442",sequential1L5:"#FFA857",sequential1L6:"#FF7149",sequential1L7:"#FE3A3A"}),{sequential2D1:"#333022",sequential2D2:"#3D2830",sequential2D3:"#562E4C",sequential2D4:"#6F3468",sequential2D5:"#873A83",sequential2D6:"#A0409F",sequential2D7:"#B846BB"}),{sequential2L1:"#EEE8CE",sequential2L2:"#E8C7CE",sequential2L3:"#E1A6CD",sequential2L4:"#DB86CD",sequential2L5:"#D465CD",sequential2L6:"#CE44CC",sequential2L7:"#C723CC"}),{sequential3D1:"#333022",sequential3D2:"#253223",sequential3D3:"#244333",sequential3D4:"#245442",sequential3D5:"#246451",sequential3D6:"#237561",sequential3D7:"#238570"}),{sequential3L1:"#EEE8CE",sequential3L2:"#B6ECD4",sequential3L3:"#7EEFDA",sequential3L4:"#45D4BA",sequential3L5:"#35B9A0",sequential3L6:"#249F86",sequential3L7:"#14846C"}),{sequential4D1:"#333022",sequential4D2:"#442519",sequential4D3:"#64271F",sequential4D4:"#832A24",sequential4D5:"#A0312E",sequential4D6:"#BD3737",sequential4D7:"#DA3B30"}),{sequential4L1:"#EEE8CE",sequential4L2:"#F5CEBF",sequential4L3:"#FCB4B0",sequential4L4:"#F99C96",sequential4L5:"#F6847C",sequential4L6:"#DF564D",sequential4L7:"#DD2E2E"}),{sequential5D1:"#2E2E55",sequential5D2:"#4B1773",sequential5D3:"#77136A",sequential5D4:"#A81A45",sequential5D5:"#D24620",sequential5D6:"#D97A0D",sequential5D7:"#CBA700"}),{sequential5L1:"#EEE8CE",sequential5L2:"#F2DD88",sequential5L3:"#FFC355",sequential5L4:"#FF9D66",sequential5L5:"#FF7777",sequential5L6:"#EE4477",sequential5L7:"#DD22BB"}),{sequential6D1:"#1C3355",sequential6D2:"#005580",sequential6D3:"#007575",sequential6D4:"#118832",sequential6D5:"#669922",sequential6D6:"#9D9F0D",sequential6D7:"#CBA700"}),{sequential6L1:"#EEE8CE",sequential6L2:"#E7E755",sequential6L3:"#A3E052",sequential6L4:"#0AD647",sequential6L5:"#00BBBB",sequential6L6:"#1182F3",sequential6L7:"#6666DD"});t.sequential=u;var s=r(r(r(r(r(r(r(r({},{highLow1DHigh:"#1C6B2D",highLow1DLow:"#9E2520"}),{highLow1LHigh:"#55C169",highLow1LLow:"#F98C83"}),{highLow2DHigh:"#115BAD",highLow2DLow:"#9E2520"}),{highLow2LHigh:"#6BB3EE",highLow2LLow:"#F98C83"}),{highLow3DHigh:"#277C52",highLow3DLow:"#602CA1"}),{highLow3LHigh:"#45D4BA",highLow3LLow:"#C093F9"}),{highLow4DHigh:"#1A6765",highLow4DLow:"#9F3B23"}),{highLow4LHigh:"#2EA39B",highLow4LLow:"#E3723A"});t.highLow=s;var c=r(r(r(r(r({},i),a),l),u),s);t.default=c},7633:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=u(n(1502)),o=u(n(3276)),i=u(n(5841)),a=u(n(4301)),l=u(n(4160));function u(e){return e&&e.__esModule?e:{default:e}}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){f(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function f(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}t.default=function(e){var t=e.colorScheme,n=e.density,u={light:r.default,dark:o.default}[t],s={compact:i.default,comfortable:a.default}[n];return c(c(c({},(0,l.default)({colorScheme:t})),u),s)}},1502:(e,t)=>{"use strict";function n(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function r(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i=r(r(r(r(r(r(r(r({},{accentColorPositive:"#407a06",accentColorWarning:"#c97705",accentColorAlert:"#c6400d",accentColorNegative:"#e00000"}),{statusColorInfo:"#006be5",statusColorNormal:"#407a06",statusColorLow:"#155a4e",statusColorMedium:"#c97705",statusColorHigh:"#e00000",statusColorCritical:"#9e1534"}),{embossShadow:" 0px 1px 5px rgba(0, 0, 0, 0.07), 0px 0px 1px rgba(0, 0, 0, 0.07)",overlayShadow:"0px 26px 103px rgba(0, 0, 0, 0.13), 0px 11px 18px rgba(0, 0, 0, 0.06), 0px 3px 6px rgba(0, 0, 0, 0.06)",dragShadow:"0px 26px 103px rgba(0, 0, 0, 0.13), 0px 11px 18px rgba(0, 0, 0, 0.06), 0px 3px 6px rgba(0, 0, 0, 0.06)",modalShadow:"0px 50px 200px rgba(0, 0, 0, 0.3), 0px 29px 66px rgba(0, 0, 0, 0.08), 0px 29px 47px rgba(0, 0, 0, 0.08), 0px 5px 10px rgba(0, 0, 0, 0.03)"}),{backgroundColorPopup:"#ffffff",backgroundColorSection:"#ffffff",backgroundColorSidebar:"#f8f8f8",backgroundColorPage:"#f9f9f9",backgroundColorNavigation:"#f7f7f7",backgroundColorFloating:"#000000",backgroundColorDialog:"#ffffff",backgroundColorScrim:"rgba(255, 255, 255, 0.75)"}),{contentColorActive:"#2c2c2c",contentColorDefault:"#4d4d4d",contentColorDisabled:"#878787",contentColorInverted:"#ffffff",contentColorMuted:"#6b6b6b"}),{white:"#ffffff",neutral100:"#f0f0f0",neutral200:"#e6e6e6",neutral300:"#dddddd",neutral400:"#cacaca",neutral500:"#b8b8b8",black:"#000000"}),{interactiveColorPrimary:"#0264d7",interactiveColorBorder:"rgba(0, 0, 0, 0.4)",interactiveColorBorderHover:"rgba(0, 0, 0, 0.6)",interactiveColorBorderDisabled:"rgba(0, 0, 0, 0.3)",interactiveColorOverlaySelected:"rgba(0, 0, 0, 0.04)",interactiveColorOverlayHover:"rgba(0, 0, 0, 0.03)",interactiveColorOverlayActive:"rgba(0, 0, 0, 0.07)",interactiveColorOverlayDrag:"rgba(2, 100, 215, 0.16)",interactiveColorBackground:"#eeeeee",interactiveColorBackgroundDisabled:"rgba(0, 0, 0, 0.1)"}),{syntaxBlue:"#107d9f",syntaxBrown:"#a26604",syntaxGray:"#737373",syntaxGreen:"#607d0d",syntaxOrange:"#b75808",syntaxPink:"#d015b2",syntaxPurple:"#7f52f5",syntaxRed:"#df1f48",syntaxTeal:"#1e816f"});t.default=i},9092:()=>{},1093:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=n(7294),o=n(2788),i=n(5525);function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){u(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}t.default=function(){var e=(0,r.useContext)(o.ThemeContext)||{},t=e.splunkThemeV1,n=void 0===t?{}:t,a=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["splunkThemeV1"]),u=n.family,s=n.colorScheme,c=n.density,f=n.customizer;return l(l({},a),(0,i.getCustomizedTheme)({family:u,colorScheme:s,density:c},f))}},5525:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getCustomizedTheme=t.addThemeDefaults=void 0;var r,o=n(5220),i=(r=n(5580))&&r.__esModule?r:{default:r};t.addThemeDefaults=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.family,n=void 0===t?"prisma":t,r=e.colorScheme,o=void 0===r?"dark":r,i=e.density,a=void 0===i?"comfortable":i,l=e.isPrisma,u=void 0===l||l,s=e.isEnterprise,c=void 0!==s&&s,f=e.isComfortable,p=void 0===f||f,d=e.isCompact,h=void 0!==d&&d,m=e.isDark,b=void 0===m||m,y=e.isLight,g=void 0!==y&&y;return{family:n,colorScheme:o,density:a,isPrisma:u,isEnterprise:c,isComfortable:p,isCompact:h,isDark:b,isLight:g}};var a=(0,o.memoize)((function(e,t){var n=(0,i.default)(e);return t?t(n):n}),(function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.family,n=e.colorScheme,r=e.density,o=arguments.length>1?arguments[1]:void 0;return"".concat(t,"-").concat(n,"-").concat(r,"-").concat(!!o)}));t.getCustomizedTheme=a},669:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.clearVariablesCache=t.default=void 0;var r=a(n(9776)),o=a(n(5580)),i=n(5525);function a(e){return e&&e.__esModule?e:{default:e}}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function u(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var c=(0,r.default)((function(e,t,n){return(0,i.getCustomizedTheme)(t,n)[e]}),(function(e,t,n){var r=t.family,o=t.colorScheme,i=t.density;return"".concat(e,"-").concat(r,"-").concat(o,"-").concat(i,"-").concat(!!n)}));t.clearVariablesCache=function(){var e,t;return null===(e=(t=c.cache).clear)||void 0===e?void 0:e.call(t)};var f=Object.keys(u(u({},(0,o.default)({family:"prisma"})),(0,o.default)({family:"enterprise"}))).reduce((function(e,t){var n;return Object.defineProperty(e,t,{value:(n=t,function(e){var t=e.theme,r=(t=void 0===t?{}:t).splunkThemeV1||{},o=r.family,i=r.colorScheme,a=r.density,l=r.customizer;return c(n,{family:o,colorScheme:i,density:a},l)})}),e}),{});t.default=f},4409:(e,t,n)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var t=l();if(t&&t.has(e))return t.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if(Object.prototype.hasOwnProperty.call(e,i)){var a=o?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(n,i,a):n[i]=e[i]}return n.default=e,t&&t.set(e,n),n}(n(7294)),i=n(2788),a=n(5525);function l(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return l=function(){return e},e}function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){f(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function f(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}t.default=function(e){var t=o.default.forwardRef((function(t,n){var r=(0,o.useContext)(i.ThemeContext)||{},l=r.splunkThemeV1,s=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(r,["splunkThemeV1"]),f=l||{},p=f.family,d=f.colorScheme,h=f.density,m=f.customizer,b=(0,a.addThemeDefaults)({family:p,colorScheme:d,density:h}),y=c(c({},s),(0,a.getCustomizedTheme)(b,m));return o.default.createElement(e,u({},t,{ref:n,splunkTheme:y}))})),n=e.displayName||e.name||"Component";return t.displayName="withSplunkTheme(".concat(n,")"),t}},9327:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getEntry=function(e){if("undefined"==typeof document)return null;var t=new RegExp("(^|; ?)".concat(e,"=([^;]+)")),n=null;try{var r=document.cookie.match(t);n=r?r[2]:null}catch(e){}return n}},8568:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getSortedTabbableElements=i,t.isTabKey=a,t.handleTab=function(e,t){if(!e.contains(document.activeElement))return null;if(!a(t))return null;var n=i(e);if(0===n.length)return document.activeElement===e?(t.preventDefault(),e):null;var r=t&&t.target||e.querySelector(":focus"),o=n.indexOf(r);return-1===o&&(o=t.shiftKey?0:n.length-1),t.shiftKey?n.unshift(n.pop()):n.push(n.shift()),t.preventDefault(),n[o].focus(),n[o]},t.takeFocus=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"first",n=e.querySelector(":focus");if(n)return n;if("first"===t){var r=i(e)[0];if(r)return(0,o.defer)((function(){return r.focus()})),r}return e.hasAttribute("tabIndex")?((0,o.defer)((function(){return e.focus()})),e):null};var r=n(2916),o=n(5220);function i(e){var t=e.querySelectorAll("a[href], input:not([disabled]), select:not([disabled]),\n     textarea:not([disabled]), button:not([disabled]), [tabindex], [contenteditable]"),n=(0,o.filter)(t,(function(e){return!(!((t=e).offsetWidth||t.offsetHeight||t.getClientRects().length>0)||"hidden"===getComputedStyle(t).visibility)&&e.tabIndex>=0||e===document.activeElement;var t})).reduce((function(e,t){var n=e[e.length-1],r="radio"===(null==n?void 0:n.getAttribute("type")),o="radio"===t.getAttribute("type"),i=t.getAttribute("name")===(null==n?void 0:n.getAttribute("name"));return r&&o&&i?t.checked&&(e.pop(),e.push(t)):e.push(t),e}),[]);return(0,o.sortBy)(n,(function(e){return e.tabIndex>0?-1/e.tabIndex:0}))}function a(e){return!("tab"!==(0,r.keycode)(e)||e.metaKey||e.altKey||e.controlKey)}},6219:(e,t)=>{"use strict";var n;function r(e){n=e}function o(){r("undefined"!=typeof window&&window.gettext||function(e){return e})}Object.defineProperty(t,"__esModule",{value:!0}),t.gettext=function(){return n.apply(void 0,arguments)},t._=function(){return n.apply(void 0,arguments)},t.setSharedTranslator=r,t.resetSharedTranslator=o,o()},9726:(e,t)=>{"use strict";function n(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(e){var t=Math.floor(16*Math.random());return("x"===e?t:t%4+8).toString(16)}))}Object.defineProperty(t,"__esModule",{value:!0}),t.createGUID=n,t.createDOMID=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"id";if(e.match(/^[a-zA-Z][\w-]*$/))return"".concat(e,"-").concat(n());throw new Error("createDOMID: Prefix must start with a letter and may only contain letters, digits, hyphens and underscores")}},2916:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isNumber=u,t.isDecimal=s,t.isMinus=c,t.isNumeric=function(e,t){return u(e)||s(e,t)||c(e)},t.addsCharacter=function(e){var t=e.key;if(l(t))return 1===t.length||["Add","Decimal","Divide","Multiply","Spacebar","Subtract"].indexOf(t)>=0},t.keycode=void 0;var r,o=(r=n(7537))&&r.__esModule?r:{default:r},i=n(5220),a=o.default;function l(e){return!(0,i.isUndefined)(e)&&"Unidentified"!==e}function u(e){var t=e.key,n=e.keyCode;return l(t)?["1","2","3","4","5","6","7","8","9","0"].indexOf(t)>=0:n>=48&&n<=57||n>=96&&n<=105}function s(e){var t=e.key,n=e.keyCode,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=r.locale,i=void 0===o?"en-US":o,u=new Intl.NumberFormat(i.replace("_","-")).format(1.2),s=u.indexOf(",")>-1?",":".";return l(t)?t===s||"Decimal"===t:"."===s&&n===a("numpad .")||n===a(s)}function c(e){var t=e.key,n=e.keyCode;return l(t)?"-"===t||"Subtract"===t:n===a("numpad -")||n===a("-")}t.keycode=a},9867:(e,t)=>{"use strict";function n(e){return function(e){if(Array.isArray(e))return r(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function o(e){return o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.toClassName=function e(){for(var t=arguments.length,r=new Array(t),i=0;i<t;i++)r[i]=arguments[i];return r.reduce((function(t,r){if(!r)return t;var i=o(r);if("string"===i)t.push(r);else if(Array.isArray(r))t.push(e.apply(void 0,n(r)));else if("object"===i)return t.concat(Object.keys(r).filter((function(e){return r[e]})));return t}),[]).join(" ")}},6070:(e,t,n)=>{"use strict";n.d(t,{Pd:()=>g,XE:()=>b,fh:()=>y,xV:()=>m});var r,o,i,a,l,u=n(168),s=n(2788),c=n(6416),f=n.n(c),p=n(5947),d=n(5414),h=n.n(d),m=(0,s.default)(f())(r||(r=(0,u.Z)(["\n    margin: 0px 1px;\n    border: none;\n"]))),b=(0,s.default)(h())(o||(o=(0,u.Z)(["\n    position: fixed;\n    top: 50%;\n    left: 50%;\n"]))),y=(s.default.div(i||(i=(0,u.Z)(["\n    text-align: left;\n"]))),s.default.span(a||(a=(0,u.Z)(["\n    button {\n        margin-left: 80px;\n        min-width: 100px;\n    }\n"])))),g=s.default.div(l||(l=(0,u.Z)(["\n    font-size: ",";\n    text-align: center;\n"])),p.variables.fontSize)},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r={0:"Field {{args[0]}} is required",1:"Field {{args[0]}} must be a string",2:"{{args[0]}} {{args[1]}} is already in use",3:'"default", ".", "..", string started with "_" and string including any one of ["*", "\\", "[", "]", "(", ")", "?", ":"] are reserved value which cannot be used for field {{args[0]}}',5:"Field {{args[0]}} should be a positive number",6:"Field {{args[0]}} is required",7:"Field {{args[0]}} is not a valid regular expression",8:"Field {{args[0]}} should be within the range of [{{args[1]}} and {{args[2]}}]",9:"Field {{args[0]}} should be greater than or equal to {{args[1]}}",10:"Field {{args[0]}} should be less than or equal to {{args[1]}}",11:"{{args[0]}} is not a function",12:"{{args[0]}} is not a valid regular expression",13:"{{args[0]}} is not a valid number range",14:"minLength cannot be greater than maxLength",15:"Field {{args[0]}} does not match regular expression {{args[1]}}",16:"Field {{args[0]}} is not a number",17:"Length of {{args[0]}} should be greater than or equal to {{args[1]}}",18:"Length of {{args[0]}} should be less than or equal to {{args[1]}}",19:"Field {{args[0]}} is not a valid {{args[1]}}",20:"configuration file should be pure JSON",21:"duplicate {{args[0]}} keys is not allowed",22:"Field {{args[0]}} must be less than 1024 characters",23:'"name" feild must be provided for {{args[0]}} \'s entity in configuration file',24:"The file must be in {{args[0]}} format",25:"The file size should not exceed {{args[0]}}",26:"Invalid JSON file",100:"Create New Input",101:"Delete Confirmation",102:'Are you sure you want to delete "{{args[0]}}" {{args[1]}}? Ensure that no input is configured with "{{args[0]}}" as this will stop data collection for that input.',103:'Are you sure you want to delete "{{args[0]}}" {{args[1]}}?',104:"Error Message",105:"Warning",106:"Input Type",107:"Items",108:"Saving",109:"Failed to load index",110:"Internal configuration file error. Something wrong within the package or installation step. Contact your administrator for support. Detail: {{args[0]}}",111:"URL",112:"email address",113:"IPV4 address",114:"date in ISO 8601 format",115:"Loading",116:"Inputs",117:"Configuration",118:"configuration file not found",unknown:"An unknown error occurred"}},4843:(e,t,n)=>{"use strict";n.d(t,{b:()=>r,y:()=>o});var r="inputs",o="configuration"},9609:(e,t,n)=>{"use strict";n.d(t,{P:()=>a,n:()=>l});var r=n(5220),o=n(6219),i=n(723),a=function(e,t){var n=i.Z[e]||i.Z.unknown;return n=(0,o._)(n),r.template(n,{escape:/\{\{(.+?)\}\}/g})({args:t})},l=function(e){var t,n="";try{var r=e.response.data.messages[0].text;if((t=/.+"REST Error \[[\d]+\]:\s+.+\s+--\s+([\s\S]*)"\.\s*See splunkd\.log(\/python.log)? for more details\./.exec(r))&&t[1])try{var i=JSON.parse(t[1]);n=String(i.messages[0].text)}catch(e){n=t[1]}else n=r}catch(e){n=(0,o._)("Error in processing the request")}return n}},4266:(e,t,n)=>{"use strict";n.d(t,{a:()=>tt,E:()=>nt});var r=n(1002),o=n(1721);function i(e){return null==e}var a={isNothing:i,isObject:function(e){return"object"==typeof e&&null!==e},toArray:function(e){return Array.isArray(e)?e:i(e)?[]:[e]},repeat:function(e,t){var n,r="";for(n=0;n<t;n+=1)r+=e;return r},isNegativeZero:function(e){return 0===e&&Number.NEGATIVE_INFINITY===1/e},extend:function(e,t){var n,r,o,i;if(t)for(n=0,r=(i=Object.keys(t)).length;n<r;n+=1)e[o=i[n]]=t[o];return e}};function l(e,t){var n="",r=e.reason||"(unknown reason)";return e.mark?(e.mark.name&&(n+='in "'+e.mark.name+'" '),n+="("+(e.mark.line+1)+":"+(e.mark.column+1)+")",!t&&e.mark.snippet&&(n+="\n\n"+e.mark.snippet),r+" "+n):r}function u(e,t){Error.call(this),this.name="YAMLException",this.reason=e,this.mark=t,this.message=l(this,!1),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||""}u.prototype=Object.create(Error.prototype),u.prototype.constructor=u,u.prototype.toString=function(e){return this.name+": "+l(this,e)};var s=u;function c(e,t,n,r,o){var i="",a="",l=Math.floor(o/2)-1;return r-t>l&&(t=r-l+(i=" ... ").length),n-r>l&&(n=r+l-(a=" ...").length),{str:i+e.slice(t,n).replace(/\t/g,"→")+a,pos:r-t+i.length}}function f(e,t){return a.repeat(" ",t-e.length)+e}var p=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],d=["scalar","sequence","mapping"],h=function(e,t){if(t=t||{},Object.keys(t).forEach((function(t){if(-1===p.indexOf(t))throw new s('Unknown option "'+t+'" is met in definition of "'+e+'" YAML type.')})),this.options=t,this.tag=e,this.kind=t.kind||null,this.resolve=t.resolve||function(){return!0},this.construct=t.construct||function(e){return e},this.instanceOf=t.instanceOf||null,this.predicate=t.predicate||null,this.represent=t.represent||null,this.representName=t.representName||null,this.defaultStyle=t.defaultStyle||null,this.multi=t.multi||!1,this.styleAliases=function(e){var t={};return null!==e&&Object.keys(e).forEach((function(n){e[n].forEach((function(e){t[String(e)]=n}))})),t}(t.styleAliases||null),-1===d.indexOf(this.kind))throw new s('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')};function m(e,t){var n=[];return e[t].forEach((function(e){var t=n.length;n.forEach((function(n,r){n.tag===e.tag&&n.kind===e.kind&&n.multi===e.multi&&(t=r)})),n[t]=e})),n}function b(e){return this.extend(e)}b.prototype.extend=function(e){var t=[],n=[];if(e instanceof h)n.push(e);else if(Array.isArray(e))n=n.concat(e);else{if(!e||!Array.isArray(e.implicit)&&!Array.isArray(e.explicit))throw new s("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");e.implicit&&(t=t.concat(e.implicit)),e.explicit&&(n=n.concat(e.explicit))}t.forEach((function(e){if(!(e instanceof h))throw new s("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(e.loadKind&&"scalar"!==e.loadKind)throw new s("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(e.multi)throw new s("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")})),n.forEach((function(e){if(!(e instanceof h))throw new s("Specified list of YAML types (or a single Type object) contains a non-Type object.")}));var r=Object.create(b.prototype);return r.implicit=(this.implicit||[]).concat(t),r.explicit=(this.explicit||[]).concat(n),r.compiledImplicit=m(r,"implicit"),r.compiledExplicit=m(r,"explicit"),r.compiledTypeMap=function(){var e,t,n={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}};function r(e){e.multi?(n.multi[e.kind].push(e),n.multi.fallback.push(e)):n[e.kind][e.tag]=n.fallback[e.tag]=e}for(e=0,t=arguments.length;e<t;e+=1)arguments[e].forEach(r);return n}(r.compiledImplicit,r.compiledExplicit),r};var y=b,g=new h("tag:yaml.org,2002:str",{kind:"scalar",construct:function(e){return null!==e?e:""}}),v=new h("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(e){return null!==e?e:[]}}),w=new h("tag:yaml.org,2002:map",{kind:"mapping",construct:function(e){return null!==e?e:{}}}),_=new y({explicit:[g,v,w]}),x=new h("tag:yaml.org,2002:null",{kind:"scalar",resolve:function(e){if(null===e)return!0;var t=e.length;return 1===t&&"~"===e||4===t&&("null"===e||"Null"===e||"NULL"===e)},construct:function(){return null},predicate:function(e){return null===e},represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"},empty:function(){return""}},defaultStyle:"lowercase"}),O=new h("tag:yaml.org,2002:bool",{kind:"scalar",resolve:function(e){if(null===e)return!1;var t=e.length;return 4===t&&("true"===e||"True"===e||"TRUE"===e)||5===t&&("false"===e||"False"===e||"FALSE"===e)},construct:function(e){return"true"===e||"True"===e||"TRUE"===e},predicate:function(e){return"[object Boolean]"===Object.prototype.toString.call(e)},represent:{lowercase:function(e){return e?"true":"false"},uppercase:function(e){return e?"TRUE":"FALSE"},camelcase:function(e){return e?"True":"False"}},defaultStyle:"lowercase"});function S(e){return 48<=e&&e<=55}function k(e){return 48<=e&&e<=57}var j=new h("tag:yaml.org,2002:int",{kind:"scalar",resolve:function(e){if(null===e)return!1;var t,n,r=e.length,o=0,i=!1;if(!r)return!1;if("-"!==(t=e[o])&&"+"!==t||(t=e[++o]),"0"===t){if(o+1===r)return!0;if("b"===(t=e[++o])){for(o++;o<r;o++)if("_"!==(t=e[o])){if("0"!==t&&"1"!==t)return!1;i=!0}return i&&"_"!==t}if("x"===t){for(o++;o<r;o++)if("_"!==(t=e[o])){if(!(48<=(n=e.charCodeAt(o))&&n<=57||65<=n&&n<=70||97<=n&&n<=102))return!1;i=!0}return i&&"_"!==t}if("o"===t){for(o++;o<r;o++)if("_"!==(t=e[o])){if(!S(e.charCodeAt(o)))return!1;i=!0}return i&&"_"!==t}}if("_"===t)return!1;for(;o<r;o++)if("_"!==(t=e[o])){if(!k(e.charCodeAt(o)))return!1;i=!0}return!(!i||"_"===t)},construct:function(e){var t,n=e,r=1;if(-1!==n.indexOf("_")&&(n=n.replace(/_/g,"")),"-"!==(t=n[0])&&"+"!==t||("-"===t&&(r=-1),t=(n=n.slice(1))[0]),"0"===n)return 0;if("0"===t){if("b"===n[1])return r*parseInt(n.slice(2),2);if("x"===n[1])return r*parseInt(n.slice(2),16);if("o"===n[1])return r*parseInt(n.slice(2),8)}return r*parseInt(n,10)},predicate:function(e){return"[object Number]"===Object.prototype.toString.call(e)&&e%1==0&&!a.isNegativeZero(e)},represent:{binary:function(e){return e>=0?"0b"+e.toString(2):"-0b"+e.toString(2).slice(1)},octal:function(e){return e>=0?"0o"+e.toString(8):"-0o"+e.toString(8).slice(1)},decimal:function(e){return e.toString(10)},hexadecimal:function(e){return e>=0?"0x"+e.toString(16).toUpperCase():"-0x"+e.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),C=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),E=/^[-+]?[0-9]+e/,P=new h("tag:yaml.org,2002:float",{kind:"scalar",resolve:function(e){return null!==e&&!(!C.test(e)||"_"===e[e.length-1])},construct:function(e){var t,n;return n="-"===(t=e.replace(/_/g,"").toLowerCase())[0]?-1:1,"+-".indexOf(t[0])>=0&&(t=t.slice(1)),".inf"===t?1===n?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===t?NaN:n*parseFloat(t,10)},predicate:function(e){return"[object Number]"===Object.prototype.toString.call(e)&&(e%1!=0||a.isNegativeZero(e))},represent:function(e,t){var n;if(isNaN(e))switch(t){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===e)switch(t){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===e)switch(t){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(a.isNegativeZero(e))return"-0.0";return n=e.toString(10),E.test(n)?n.replace("e",".e"):n},defaultStyle:"lowercase"}),A=_.extend({implicit:[x,O,j,P]}),T=A,L=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),R=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$"),M=new h("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:function(e){return null!==e&&(null!==L.exec(e)||null!==R.exec(e))},construct:function(e){var t,n,r,o,i,a,l,u,s=0,c=null;if(null===(t=L.exec(e))&&(t=R.exec(e)),null===t)throw new Error("Date resolve error");if(n=+t[1],r=+t[2]-1,o=+t[3],!t[4])return new Date(Date.UTC(n,r,o));if(i=+t[4],a=+t[5],l=+t[6],t[7]){for(s=t[7].slice(0,3);s.length<3;)s+="0";s=+s}return t[9]&&(c=6e4*(60*+t[10]+ +(t[11]||0)),"-"===t[9]&&(c=-c)),u=new Date(Date.UTC(n,r,o,i,a,l,s)),c&&u.setTime(u.getTime()-c),u},instanceOf:Date,represent:function(e){return e.toISOString()}}),D=new h("tag:yaml.org,2002:merge",{kind:"scalar",resolve:function(e){return"<<"===e||null===e}}),I="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r",F=new h("tag:yaml.org,2002:binary",{kind:"scalar",resolve:function(e){if(null===e)return!1;var t,n,r=0,o=e.length,i=I;for(n=0;n<o;n++)if(!((t=i.indexOf(e.charAt(n)))>64)){if(t<0)return!1;r+=6}return r%8==0},construct:function(e){var t,n,r=e.replace(/[\r\n=]/g,""),o=r.length,i=I,a=0,l=[];for(t=0;t<o;t++)t%4==0&&t&&(l.push(a>>16&255),l.push(a>>8&255),l.push(255&a)),a=a<<6|i.indexOf(r.charAt(t));return 0==(n=o%4*6)?(l.push(a>>16&255),l.push(a>>8&255),l.push(255&a)):18===n?(l.push(a>>10&255),l.push(a>>2&255)):12===n&&l.push(a>>4&255),new Uint8Array(l)},predicate:function(e){return"[object Uint8Array]"===Object.prototype.toString.call(e)},represent:function(e){var t,n,r="",o=0,i=e.length,a=I;for(t=0;t<i;t++)t%3==0&&t&&(r+=a[o>>18&63],r+=a[o>>12&63],r+=a[o>>6&63],r+=a[63&o]),o=(o<<8)+e[t];return 0==(n=i%3)?(r+=a[o>>18&63],r+=a[o>>12&63],r+=a[o>>6&63],r+=a[63&o]):2===n?(r+=a[o>>10&63],r+=a[o>>4&63],r+=a[o<<2&63],r+=a[64]):1===n&&(r+=a[o>>2&63],r+=a[o<<4&63],r+=a[64],r+=a[64]),r}}),N=Object.prototype.hasOwnProperty,z=Object.prototype.toString,q=new h("tag:yaml.org,2002:omap",{kind:"sequence",resolve:function(e){if(null===e)return!0;var t,n,r,o,i,a=[],l=e;for(t=0,n=l.length;t<n;t+=1){if(r=l[t],i=!1,"[object Object]"!==z.call(r))return!1;for(o in r)if(N.call(r,o)){if(i)return!1;i=!0}if(!i)return!1;if(-1!==a.indexOf(o))return!1;a.push(o)}return!0},construct:function(e){return null!==e?e:[]}}),$=Object.prototype.toString,B=new h("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:function(e){if(null===e)return!0;var t,n,r,o,i,a=e;for(i=new Array(a.length),t=0,n=a.length;t<n;t+=1){if(r=a[t],"[object Object]"!==$.call(r))return!1;if(1!==(o=Object.keys(r)).length)return!1;i[t]=[o[0],r[o[0]]]}return!0},construct:function(e){if(null===e)return[];var t,n,r,o,i,a=e;for(i=new Array(a.length),t=0,n=a.length;t<n;t+=1)r=a[t],o=Object.keys(r),i[t]=[o[0],r[o[0]]];return i}}),U=Object.prototype.hasOwnProperty,V=new h("tag:yaml.org,2002:set",{kind:"mapping",resolve:function(e){if(null===e)return!0;var t,n=e;for(t in n)if(U.call(n,t)&&null!==n[t])return!1;return!0},construct:function(e){return null!==e?e:{}}}),W=T.extend({implicit:[M,D],explicit:[F,q,B,V]}),H=Object.prototype.hasOwnProperty,Z=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,K=/[\x85\u2028\u2029]/,Q=/[,\[\]\{\}]/,G=/^(?:!|!!|![a-z\-]+!)$/i,X=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function Y(e){return Object.prototype.toString.call(e)}function J(e){return 10===e||13===e}function ee(e){return 9===e||32===e}function te(e){return 9===e||32===e||10===e||13===e}function ne(e){return 44===e||91===e||93===e||123===e||125===e}function re(e){var t;return 48<=e&&e<=57?e-48:97<=(t=32|e)&&t<=102?t-97+10:-1}function oe(e){return 48===e?"\0":97===e?"":98===e?"\b":116===e||9===e?"\t":110===e?"\n":118===e?"\v":102===e?"\f":114===e?"\r":101===e?"":32===e?" ":34===e?'"':47===e?"/":92===e?"\\":78===e?"…":95===e?" ":76===e?"\u2028":80===e?"\u2029":""}function ie(e){return e<=65535?String.fromCharCode(e):String.fromCharCode(55296+(e-65536>>10),56320+(e-65536&1023))}for(var ae=new Array(256),le=new Array(256),ue=0;ue<256;ue++)ae[ue]=oe(ue)?1:0,le[ue]=oe(ue);function se(e,t){this.input=e,this.filename=t.filename||null,this.schema=t.schema||W,this.onWarning=t.onWarning||null,this.legacy=t.legacy||!1,this.json=t.json||!1,this.listener=t.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=e.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function ce(e,t){var n={name:e.filename,buffer:e.input.slice(0,-1),position:e.position,line:e.line,column:e.position-e.lineStart};return n.snippet=function(e,t){if(t=Object.create(t||null),!e.buffer)return null;t.maxLength||(t.maxLength=79),"number"!=typeof t.indent&&(t.indent=1),"number"!=typeof t.linesBefore&&(t.linesBefore=3),"number"!=typeof t.linesAfter&&(t.linesAfter=2);for(var n,r=/\r?\n|\r|\0/g,o=[0],i=[],l=-1;n=r.exec(e.buffer);)i.push(n.index),o.push(n.index+n[0].length),e.position<=n.index&&l<0&&(l=o.length-2);l<0&&(l=o.length-1);var u,s,p="",d=Math.min(e.line+t.linesAfter,i.length).toString().length,h=t.maxLength-(t.indent+d+3);for(u=1;u<=t.linesBefore&&!(l-u<0);u++)s=c(e.buffer,o[l-u],i[l-u],e.position-(o[l]-o[l-u]),h),p=a.repeat(" ",t.indent)+f((e.line-u+1).toString(),d)+" | "+s.str+"\n"+p;for(s=c(e.buffer,o[l],i[l],e.position,h),p+=a.repeat(" ",t.indent)+f((e.line+1).toString(),d)+" | "+s.str+"\n",p+=a.repeat("-",t.indent+d+3+s.pos)+"^\n",u=1;u<=t.linesAfter&&!(l+u>=i.length);u++)s=c(e.buffer,o[l+u],i[l+u],e.position-(o[l]-o[l+u]),h),p+=a.repeat(" ",t.indent)+f((e.line+u+1).toString(),d)+" | "+s.str+"\n";return p.replace(/\n$/,"")}(n),new s(t,n)}function fe(e,t){throw ce(e,t)}function pe(e,t){e.onWarning&&e.onWarning.call(null,ce(e,t))}var de={YAML:function(e,t,n){var r,o,i;null!==e.version&&fe(e,"duplication of %YAML directive"),1!==n.length&&fe(e,"YAML directive accepts exactly one argument"),null===(r=/^([0-9]+)\.([0-9]+)$/.exec(n[0]))&&fe(e,"ill-formed argument of the YAML directive"),o=parseInt(r[1],10),i=parseInt(r[2],10),1!==o&&fe(e,"unacceptable YAML version of the document"),e.version=n[0],e.checkLineBreaks=i<2,1!==i&&2!==i&&pe(e,"unsupported YAML version of the document")},TAG:function(e,t,n){var r,o;2!==n.length&&fe(e,"TAG directive accepts exactly two arguments"),r=n[0],o=n[1],G.test(r)||fe(e,"ill-formed tag handle (first argument) of the TAG directive"),H.call(e.tagMap,r)&&fe(e,'there is a previously declared suffix for "'+r+'" tag handle'),X.test(o)||fe(e,"ill-formed tag prefix (second argument) of the TAG directive");try{o=decodeURIComponent(o)}catch(t){fe(e,"tag prefix is malformed: "+o)}e.tagMap[r]=o}};function he(e,t,n,r){var o,i,a,l;if(t<n){if(l=e.input.slice(t,n),r)for(o=0,i=l.length;o<i;o+=1)9===(a=l.charCodeAt(o))||32<=a&&a<=1114111||fe(e,"expected valid JSON character");else Z.test(l)&&fe(e,"the stream contains non-printable characters");e.result+=l}}function me(e,t,n,r){var o,i,l,u;for(a.isObject(n)||fe(e,"cannot merge mappings; the provided source object is unacceptable"),l=0,u=(o=Object.keys(n)).length;l<u;l+=1)i=o[l],H.call(t,i)||(t[i]=n[i],r[i]=!0)}function be(e,t,n,r,o,i,a,l,u){var s,c;if(Array.isArray(o))for(s=0,c=(o=Array.prototype.slice.call(o)).length;s<c;s+=1)Array.isArray(o[s])&&fe(e,"nested arrays are not supported inside keys"),"object"==typeof o&&"[object Object]"===Y(o[s])&&(o[s]="[object Object]");if("object"==typeof o&&"[object Object]"===Y(o)&&(o="[object Object]"),o=String(o),null===t&&(t={}),"tag:yaml.org,2002:merge"===r)if(Array.isArray(i))for(s=0,c=i.length;s<c;s+=1)me(e,t,i[s],n);else me(e,t,i,n);else e.json||H.call(n,o)||!H.call(t,o)||(e.line=a||e.line,e.lineStart=l||e.lineStart,e.position=u||e.position,fe(e,"duplicated mapping key")),"__proto__"===o?Object.defineProperty(t,o,{configurable:!0,enumerable:!0,writable:!0,value:i}):t[o]=i,delete n[o];return t}function ye(e){var t;10===(t=e.input.charCodeAt(e.position))?e.position++:13===t?(e.position++,10===e.input.charCodeAt(e.position)&&e.position++):fe(e,"a line break is expected"),e.line+=1,e.lineStart=e.position,e.firstTabInLine=-1}function ge(e,t,n){for(var r=0,o=e.input.charCodeAt(e.position);0!==o;){for(;ee(o);)9===o&&-1===e.firstTabInLine&&(e.firstTabInLine=e.position),o=e.input.charCodeAt(++e.position);if(t&&35===o)do{o=e.input.charCodeAt(++e.position)}while(10!==o&&13!==o&&0!==o);if(!J(o))break;for(ye(e),o=e.input.charCodeAt(e.position),r++,e.lineIndent=0;32===o;)e.lineIndent++,o=e.input.charCodeAt(++e.position)}return-1!==n&&0!==r&&e.lineIndent<n&&pe(e,"deficient indentation"),r}function ve(e){var t,n=e.position;return!(45!==(t=e.input.charCodeAt(n))&&46!==t||t!==e.input.charCodeAt(n+1)||t!==e.input.charCodeAt(n+2)||(n+=3,0!==(t=e.input.charCodeAt(n))&&!te(t)))}function we(e,t){1===t?e.result+=" ":t>1&&(e.result+=a.repeat("\n",t-1))}function _e(e,t){var n,r,o=e.tag,i=e.anchor,a=[],l=!1;if(-1!==e.firstTabInLine)return!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=a),r=e.input.charCodeAt(e.position);0!==r&&(-1!==e.firstTabInLine&&(e.position=e.firstTabInLine,fe(e,"tab characters must not be used in indentation")),45===r)&&te(e.input.charCodeAt(e.position+1));)if(l=!0,e.position++,ge(e,!0,-1)&&e.lineIndent<=t)a.push(null),r=e.input.charCodeAt(e.position);else if(n=e.line,Se(e,t,3,!1,!0),a.push(e.result),ge(e,!0,-1),r=e.input.charCodeAt(e.position),(e.line===n||e.lineIndent>t)&&0!==r)fe(e,"bad indentation of a sequence entry");else if(e.lineIndent<t)break;return!!l&&(e.tag=o,e.anchor=i,e.kind="sequence",e.result=a,!0)}function xe(e){var t,n,r,o,i=!1,a=!1;if(33!==(o=e.input.charCodeAt(e.position)))return!1;if(null!==e.tag&&fe(e,"duplication of a tag property"),60===(o=e.input.charCodeAt(++e.position))?(i=!0,o=e.input.charCodeAt(++e.position)):33===o?(a=!0,n="!!",o=e.input.charCodeAt(++e.position)):n="!",t=e.position,i){do{o=e.input.charCodeAt(++e.position)}while(0!==o&&62!==o);e.position<e.length?(r=e.input.slice(t,e.position),o=e.input.charCodeAt(++e.position)):fe(e,"unexpected end of the stream within a verbatim tag")}else{for(;0!==o&&!te(o);)33===o&&(a?fe(e,"tag suffix cannot contain exclamation marks"):(n=e.input.slice(t-1,e.position+1),G.test(n)||fe(e,"named tag handle cannot contain such characters"),a=!0,t=e.position+1)),o=e.input.charCodeAt(++e.position);r=e.input.slice(t,e.position),Q.test(r)&&fe(e,"tag suffix cannot contain flow indicator characters")}r&&!X.test(r)&&fe(e,"tag name cannot contain such characters: "+r);try{r=decodeURIComponent(r)}catch(t){fe(e,"tag name is malformed: "+r)}return i?e.tag=r:H.call(e.tagMap,n)?e.tag=e.tagMap[n]+r:"!"===n?e.tag="!"+r:"!!"===n?e.tag="tag:yaml.org,2002:"+r:fe(e,'undeclared tag handle "'+n+'"'),!0}function Oe(e){var t,n;if(38!==(n=e.input.charCodeAt(e.position)))return!1;for(null!==e.anchor&&fe(e,"duplication of an anchor property"),n=e.input.charCodeAt(++e.position),t=e.position;0!==n&&!te(n)&&!ne(n);)n=e.input.charCodeAt(++e.position);return e.position===t&&fe(e,"name of an anchor node must contain at least one character"),e.anchor=e.input.slice(t,e.position),!0}function Se(e,t,n,r,o){var i,l,u,s,c,f,p,d,h,m=1,b=!1,y=!1;if(null!==e.listener&&e.listener("open",e),e.tag=null,e.anchor=null,e.kind=null,e.result=null,i=l=u=4===n||3===n,r&&ge(e,!0,-1)&&(b=!0,e.lineIndent>t?m=1:e.lineIndent===t?m=0:e.lineIndent<t&&(m=-1)),1===m)for(;xe(e)||Oe(e);)ge(e,!0,-1)?(b=!0,u=i,e.lineIndent>t?m=1:e.lineIndent===t?m=0:e.lineIndent<t&&(m=-1)):u=!1;if(u&&(u=b||o),1!==m&&4!==n||(d=1===n||2===n?t:t+1,h=e.position-e.lineStart,1===m?u&&(_e(e,h)||function(e,t,n){var r,o,i,a,l,u,s,c=e.tag,f=e.anchor,p={},d=Object.create(null),h=null,m=null,b=null,y=!1,g=!1;if(-1!==e.firstTabInLine)return!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=p),s=e.input.charCodeAt(e.position);0!==s;){if(y||-1===e.firstTabInLine||(e.position=e.firstTabInLine,fe(e,"tab characters must not be used in indentation")),r=e.input.charCodeAt(e.position+1),i=e.line,63!==s&&58!==s||!te(r)){if(a=e.line,l=e.lineStart,u=e.position,!Se(e,n,2,!1,!0))break;if(e.line===i){for(s=e.input.charCodeAt(e.position);ee(s);)s=e.input.charCodeAt(++e.position);if(58===s)te(s=e.input.charCodeAt(++e.position))||fe(e,"a whitespace character is expected after the key-value separator within a block mapping"),y&&(be(e,p,d,h,m,null,a,l,u),h=m=b=null),g=!0,y=!1,o=!1,h=e.tag,m=e.result;else{if(!g)return e.tag=c,e.anchor=f,!0;fe(e,"can not read an implicit mapping pair; a colon is missed")}}else{if(!g)return e.tag=c,e.anchor=f,!0;fe(e,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===s?(y&&(be(e,p,d,h,m,null,a,l,u),h=m=b=null),g=!0,y=!0,o=!0):y?(y=!1,o=!0):fe(e,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),e.position+=1,s=r;if((e.line===i||e.lineIndent>t)&&(y&&(a=e.line,l=e.lineStart,u=e.position),Se(e,t,4,!0,o)&&(y?m=e.result:b=e.result),y||(be(e,p,d,h,m,b,a,l,u),h=m=b=null),ge(e,!0,-1),s=e.input.charCodeAt(e.position)),(e.line===i||e.lineIndent>t)&&0!==s)fe(e,"bad indentation of a mapping entry");else if(e.lineIndent<t)break}return y&&be(e,p,d,h,m,null,a,l,u),g&&(e.tag=c,e.anchor=f,e.kind="mapping",e.result=p),g}(e,h,d))||function(e,t){var n,r,o,i,a,l,u,s,c,f,p,d,h=!0,m=e.tag,b=e.anchor,y=Object.create(null);if(91===(d=e.input.charCodeAt(e.position)))a=93,s=!1,i=[];else{if(123!==d)return!1;a=125,s=!0,i={}}for(null!==e.anchor&&(e.anchorMap[e.anchor]=i),d=e.input.charCodeAt(++e.position);0!==d;){if(ge(e,!0,t),(d=e.input.charCodeAt(e.position))===a)return e.position++,e.tag=m,e.anchor=b,e.kind=s?"mapping":"sequence",e.result=i,!0;h?44===d&&fe(e,"expected the node content, but found ','"):fe(e,"missed comma between flow collection entries"),p=null,l=u=!1,63===d&&te(e.input.charCodeAt(e.position+1))&&(l=u=!0,e.position++,ge(e,!0,t)),n=e.line,r=e.lineStart,o=e.position,Se(e,t,1,!1,!0),f=e.tag,c=e.result,ge(e,!0,t),d=e.input.charCodeAt(e.position),!u&&e.line!==n||58!==d||(l=!0,d=e.input.charCodeAt(++e.position),ge(e,!0,t),Se(e,t,1,!1,!0),p=e.result),s?be(e,i,y,f,c,p,n,r,o):l?i.push(be(e,null,y,f,c,p,n,r,o)):i.push(c),ge(e,!0,t),44===(d=e.input.charCodeAt(e.position))?(h=!0,d=e.input.charCodeAt(++e.position)):h=!1}fe(e,"unexpected end of the stream within a flow collection")}(e,d)?y=!0:(l&&function(e,t){var n,r,o,i,l,u=1,s=!1,c=!1,f=t,p=0,d=!1;if(124===(i=e.input.charCodeAt(e.position)))r=!1;else{if(62!==i)return!1;r=!0}for(e.kind="scalar",e.result="";0!==i;)if(43===(i=e.input.charCodeAt(++e.position))||45===i)1===u?u=43===i?3:2:fe(e,"repeat of a chomping mode identifier");else{if(!((o=48<=(l=i)&&l<=57?l-48:-1)>=0))break;0===o?fe(e,"bad explicit indentation width of a block scalar; it cannot be less than one"):c?fe(e,"repeat of an indentation width identifier"):(f=t+o-1,c=!0)}if(ee(i)){do{i=e.input.charCodeAt(++e.position)}while(ee(i));if(35===i)do{i=e.input.charCodeAt(++e.position)}while(!J(i)&&0!==i)}for(;0!==i;){for(ye(e),e.lineIndent=0,i=e.input.charCodeAt(e.position);(!c||e.lineIndent<f)&&32===i;)e.lineIndent++,i=e.input.charCodeAt(++e.position);if(!c&&e.lineIndent>f&&(f=e.lineIndent),J(i))p++;else{if(e.lineIndent<f){3===u?e.result+=a.repeat("\n",s?1+p:p):1===u&&s&&(e.result+="\n");break}for(r?ee(i)?(d=!0,e.result+=a.repeat("\n",s?1+p:p)):d?(d=!1,e.result+=a.repeat("\n",p+1)):0===p?s&&(e.result+=" "):e.result+=a.repeat("\n",p):e.result+=a.repeat("\n",s?1+p:p),s=!0,c=!0,p=0,n=e.position;!J(i)&&0!==i;)i=e.input.charCodeAt(++e.position);he(e,n,e.position,!1)}}return!0}(e,d)||function(e,t){var n,r,o;if(39!==(n=e.input.charCodeAt(e.position)))return!1;for(e.kind="scalar",e.result="",e.position++,r=o=e.position;0!==(n=e.input.charCodeAt(e.position));)if(39===n){if(he(e,r,e.position,!0),39!==(n=e.input.charCodeAt(++e.position)))return!0;r=e.position,e.position++,o=e.position}else J(n)?(he(e,r,o,!0),we(e,ge(e,!1,t)),r=o=e.position):e.position===e.lineStart&&ve(e)?fe(e,"unexpected end of the document within a single quoted scalar"):(e.position++,o=e.position);fe(e,"unexpected end of the stream within a single quoted scalar")}(e,d)||function(e,t){var n,r,o,i,a,l,u;if(34!==(l=e.input.charCodeAt(e.position)))return!1;for(e.kind="scalar",e.result="",e.position++,n=r=e.position;0!==(l=e.input.charCodeAt(e.position));){if(34===l)return he(e,n,e.position,!0),e.position++,!0;if(92===l){if(he(e,n,e.position,!0),J(l=e.input.charCodeAt(++e.position)))ge(e,!1,t);else if(l<256&&ae[l])e.result+=le[l],e.position++;else if((a=120===(u=l)?2:117===u?4:85===u?8:0)>0){for(o=a,i=0;o>0;o--)(a=re(l=e.input.charCodeAt(++e.position)))>=0?i=(i<<4)+a:fe(e,"expected hexadecimal character");e.result+=ie(i),e.position++}else fe(e,"unknown escape sequence");n=r=e.position}else J(l)?(he(e,n,r,!0),we(e,ge(e,!1,t)),n=r=e.position):e.position===e.lineStart&&ve(e)?fe(e,"unexpected end of the document within a double quoted scalar"):(e.position++,r=e.position)}fe(e,"unexpected end of the stream within a double quoted scalar")}(e,d)?y=!0:function(e){var t,n,r;if(42!==(r=e.input.charCodeAt(e.position)))return!1;for(r=e.input.charCodeAt(++e.position),t=e.position;0!==r&&!te(r)&&!ne(r);)r=e.input.charCodeAt(++e.position);return e.position===t&&fe(e,"name of an alias node must contain at least one character"),n=e.input.slice(t,e.position),H.call(e.anchorMap,n)||fe(e,'unidentified alias "'+n+'"'),e.result=e.anchorMap[n],ge(e,!0,-1),!0}(e)?(y=!0,null===e.tag&&null===e.anchor||fe(e,"alias node should not have any properties")):function(e,t,n){var r,o,i,a,l,u,s,c,f=e.kind,p=e.result;if(te(c=e.input.charCodeAt(e.position))||ne(c)||35===c||38===c||42===c||33===c||124===c||62===c||39===c||34===c||37===c||64===c||96===c)return!1;if((63===c||45===c)&&(te(r=e.input.charCodeAt(e.position+1))||n&&ne(r)))return!1;for(e.kind="scalar",e.result="",o=i=e.position,a=!1;0!==c;){if(58===c){if(te(r=e.input.charCodeAt(e.position+1))||n&&ne(r))break}else if(35===c){if(te(e.input.charCodeAt(e.position-1)))break}else{if(e.position===e.lineStart&&ve(e)||n&&ne(c))break;if(J(c)){if(l=e.line,u=e.lineStart,s=e.lineIndent,ge(e,!1,-1),e.lineIndent>=t){a=!0,c=e.input.charCodeAt(e.position);continue}e.position=i,e.line=l,e.lineStart=u,e.lineIndent=s;break}}a&&(he(e,o,i,!1),we(e,e.line-l),o=i=e.position,a=!1),ee(c)||(i=e.position+1),c=e.input.charCodeAt(++e.position)}return he(e,o,i,!1),!!e.result||(e.kind=f,e.result=p,!1)}(e,d,1===n)&&(y=!0,null===e.tag&&(e.tag="?")),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):0===m&&(y=u&&_e(e,h))),null===e.tag)null!==e.anchor&&(e.anchorMap[e.anchor]=e.result);else if("?"===e.tag){for(null!==e.result&&"scalar"!==e.kind&&fe(e,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+e.kind+'"'),s=0,c=e.implicitTypes.length;s<c;s+=1)if((p=e.implicitTypes[s]).resolve(e.result)){e.result=p.construct(e.result),e.tag=p.tag,null!==e.anchor&&(e.anchorMap[e.anchor]=e.result);break}}else if("!"!==e.tag){if(H.call(e.typeMap[e.kind||"fallback"],e.tag))p=e.typeMap[e.kind||"fallback"][e.tag];else for(p=null,s=0,c=(f=e.typeMap.multi[e.kind||"fallback"]).length;s<c;s+=1)if(e.tag.slice(0,f[s].tag.length)===f[s].tag){p=f[s];break}p||fe(e,"unknown tag !<"+e.tag+">"),null!==e.result&&p.kind!==e.kind&&fe(e,"unacceptable node kind for !<"+e.tag+'> tag; it should be "'+p.kind+'", not "'+e.kind+'"'),p.resolve(e.result,e.tag)?(e.result=p.construct(e.result,e.tag),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):fe(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")}return null!==e.listener&&e.listener("close",e),null!==e.tag||null!==e.anchor||y}function ke(e){var t,n,r,o,i=e.position,a=!1;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap=Object.create(null),e.anchorMap=Object.create(null);0!==(o=e.input.charCodeAt(e.position))&&(ge(e,!0,-1),o=e.input.charCodeAt(e.position),!(e.lineIndent>0||37!==o));){for(a=!0,o=e.input.charCodeAt(++e.position),t=e.position;0!==o&&!te(o);)o=e.input.charCodeAt(++e.position);for(r=[],(n=e.input.slice(t,e.position)).length<1&&fe(e,"directive name must not be less than one character in length");0!==o;){for(;ee(o);)o=e.input.charCodeAt(++e.position);if(35===o){do{o=e.input.charCodeAt(++e.position)}while(0!==o&&!J(o));break}if(J(o))break;for(t=e.position;0!==o&&!te(o);)o=e.input.charCodeAt(++e.position);r.push(e.input.slice(t,e.position))}0!==o&&ye(e),H.call(de,n)?de[n](e,n,r):pe(e,'unknown document directive "'+n+'"')}ge(e,!0,-1),0===e.lineIndent&&45===e.input.charCodeAt(e.position)&&45===e.input.charCodeAt(e.position+1)&&45===e.input.charCodeAt(e.position+2)?(e.position+=3,ge(e,!0,-1)):a&&fe(e,"directives end mark is expected"),Se(e,e.lineIndent-1,4,!1,!0),ge(e,!0,-1),e.checkLineBreaks&&K.test(e.input.slice(i,e.position))&&pe(e,"non-ASCII line breaks are interpreted as content"),e.documents.push(e.result),e.position===e.lineStart&&ve(e)?46===e.input.charCodeAt(e.position)&&(e.position+=3,ge(e,!0,-1)):e.position<e.length-1&&fe(e,"end of the stream or a document separator is expected")}function je(e,t){t=t||{},0!==(e=String(e)).length&&(10!==e.charCodeAt(e.length-1)&&13!==e.charCodeAt(e.length-1)&&(e+="\n"),65279===e.charCodeAt(0)&&(e=e.slice(1)));var n=new se(e,t),r=e.indexOf("\0");for(-1!==r&&(n.position=r,fe(n,"null byte is not allowed in input")),n.input+="\0";32===n.input.charCodeAt(n.position);)n.lineIndent+=1,n.position+=1;for(;n.position<n.length-1;)ke(n);return n.documents}var Ce={loadAll:function(e,t,n){null!==t&&"object"==typeof t&&void 0===n&&(n=t,t=null);var r=je(e,n);if("function"!=typeof t)return r;for(var o=0,i=r.length;o<i;o+=1)t(r[o])},load:function(e,t){var n=je(e,t);if(0!==n.length){if(1===n.length)return n[0];throw new s("expected a single document in the stream, but found more")}}},Ee=Object.prototype.toString,Pe=Object.prototype.hasOwnProperty,Ae=65279,Te={0:"\\0",7:"\\a",8:"\\b",9:"\\t",10:"\\n",11:"\\v",12:"\\f",13:"\\r",27:"\\e",34:'\\"',92:"\\\\",133:"\\N",160:"\\_",8232:"\\L",8233:"\\P"},Le=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"],Re=/^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/;function Me(e){var t,n,r;if(t=e.toString(16).toUpperCase(),e<=255)n="x",r=2;else if(e<=65535)n="u",r=4;else{if(!(e<=4294967295))throw new s("code point within a string may not be greater than 0xFFFFFFFF");n="U",r=8}return"\\"+n+a.repeat("0",r-t.length)+t}function De(e){this.schema=e.schema||W,this.indent=Math.max(1,e.indent||2),this.noArrayIndent=e.noArrayIndent||!1,this.skipInvalid=e.skipInvalid||!1,this.flowLevel=a.isNothing(e.flowLevel)?-1:e.flowLevel,this.styleMap=function(e,t){var n,r,o,i,a,l,u;if(null===t)return{};for(n={},o=0,i=(r=Object.keys(t)).length;o<i;o+=1)a=r[o],l=String(t[a]),"!!"===a.slice(0,2)&&(a="tag:yaml.org,2002:"+a.slice(2)),(u=e.compiledTypeMap.fallback[a])&&Pe.call(u.styleAliases,l)&&(l=u.styleAliases[l]),n[a]=l;return n}(this.schema,e.styles||null),this.sortKeys=e.sortKeys||!1,this.lineWidth=e.lineWidth||80,this.noRefs=e.noRefs||!1,this.noCompatMode=e.noCompatMode||!1,this.condenseFlow=e.condenseFlow||!1,this.quotingType='"'===e.quotingType?2:1,this.forceQuotes=e.forceQuotes||!1,this.replacer="function"==typeof e.replacer?e.replacer:null,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function Ie(e,t){for(var n,r=a.repeat(" ",t),o=0,i=-1,l="",u=e.length;o<u;)-1===(i=e.indexOf("\n",o))?(n=e.slice(o),o=u):(n=e.slice(o,i+1),o=i+1),n.length&&"\n"!==n&&(l+=r),l+=n;return l}function Fe(e,t){return"\n"+a.repeat(" ",e.indent*t)}function Ne(e){return 32===e||9===e}function ze(e){return 32<=e&&e<=126||161<=e&&e<=55295&&8232!==e&&8233!==e||57344<=e&&e<=65533&&e!==Ae||65536<=e&&e<=1114111}function qe(e){return ze(e)&&e!==Ae&&13!==e&&10!==e}function $e(e,t,n){var r=qe(e),o=r&&!Ne(e);return(n?r:r&&44!==e&&91!==e&&93!==e&&123!==e&&125!==e)&&35!==e&&!(58===t&&!o)||qe(t)&&!Ne(t)&&35===e||58===t&&o}function Be(e,t){var n,r=e.charCodeAt(t);return r>=55296&&r<=56319&&t+1<e.length&&(n=e.charCodeAt(t+1))>=56320&&n<=57343?1024*(r-55296)+n-56320+65536:r}function Ue(e){return/^\n* /.test(e)}function Ve(e,t,n,r,o){e.dump=function(){if(0===t.length)return 2===e.quotingType?'""':"''";if(!e.noCompatMode&&(-1!==Le.indexOf(t)||Re.test(t)))return 2===e.quotingType?'"'+t+'"':"'"+t+"'";var i=e.indent*Math.max(1,n),a=-1===e.lineWidth?-1:Math.max(Math.min(e.lineWidth,40),e.lineWidth-i),l=r||e.flowLevel>-1&&n>=e.flowLevel;switch(function(e,t,n,r,o,i,a,l){var u,s,c=0,f=null,p=!1,d=!1,h=-1!==r,m=-1,b=ze(s=Be(e,0))&&s!==Ae&&!Ne(s)&&45!==s&&63!==s&&58!==s&&44!==s&&91!==s&&93!==s&&123!==s&&125!==s&&35!==s&&38!==s&&42!==s&&33!==s&&124!==s&&61!==s&&62!==s&&39!==s&&34!==s&&37!==s&&64!==s&&96!==s&&function(e){return!Ne(e)&&58!==e}(Be(e,e.length-1));if(t||a)for(u=0;u<e.length;c>=65536?u+=2:u++){if(!ze(c=Be(e,u)))return 5;b=b&&$e(c,f,l),f=c}else{for(u=0;u<e.length;c>=65536?u+=2:u++){if(10===(c=Be(e,u)))p=!0,h&&(d=d||u-m-1>r&&" "!==e[m+1],m=u);else if(!ze(c))return 5;b=b&&$e(c,f,l),f=c}d=d||h&&u-m-1>r&&" "!==e[m+1]}return p||d?n>9&&Ue(e)?5:a?2===i?5:2:d?4:3:!b||a||o(e)?2===i?5:2:1}(t,l,e.indent,a,(function(t){return function(e,t){var n,r;for(n=0,r=e.implicitTypes.length;n<r;n+=1)if(e.implicitTypes[n].resolve(t))return!0;return!1}(e,t)}),e.quotingType,e.forceQuotes&&!r,o)){case 1:return t;case 2:return"'"+t.replace(/'/g,"''")+"'";case 3:return"|"+We(t,e.indent)+He(Ie(t,i));case 4:return">"+We(t,e.indent)+He(Ie(function(e,t){for(var n,r,o,i=/(\n+)([^\n]*)/g,a=(o=-1!==(o=e.indexOf("\n"))?o:e.length,i.lastIndex=o,Ze(e.slice(0,o),t)),l="\n"===e[0]||" "===e[0];r=i.exec(e);){var u=r[1],s=r[2];n=" "===s[0],a+=u+(l||n||""===s?"":"\n")+Ze(s,t),l=n}return a}(t,a),i));case 5:return'"'+function(e){for(var t,n="",r=0,o=0;o<e.length;r>=65536?o+=2:o++)r=Be(e,o),!(t=Te[r])&&ze(r)?(n+=e[o],r>=65536&&(n+=e[o+1])):n+=t||Me(r);return n}(t)+'"';default:throw new s("impossible error: invalid scalar style")}}()}function We(e,t){var n=Ue(e)?String(t):"",r="\n"===e[e.length-1];return n+(!r||"\n"!==e[e.length-2]&&"\n"!==e?r?"":"-":"+")+"\n"}function He(e){return"\n"===e[e.length-1]?e.slice(0,-1):e}function Ze(e,t){if(""===e||" "===e[0])return e;for(var n,r,o=/ [^ ]/g,i=0,a=0,l=0,u="";n=o.exec(e);)(l=n.index)-i>t&&(r=a>i?a:l,u+="\n"+e.slice(i,r),i=r+1),a=l;return u+="\n",e.length-i>t&&a>i?u+=e.slice(i,a)+"\n"+e.slice(a+1):u+=e.slice(i),u.slice(1)}function Ke(e,t,n,r){var o,i,a,l="",u=e.tag;for(o=0,i=n.length;o<i;o+=1)a=n[o],e.replacer&&(a=e.replacer.call(n,String(o),a)),(Ge(e,t+1,a,!0,!0,!1,!0)||void 0===a&&Ge(e,t+1,null,!0,!0,!1,!0))&&(r&&""===l||(l+=Fe(e,t)),e.dump&&10===e.dump.charCodeAt(0)?l+="-":l+="- ",l+=e.dump);e.tag=u,e.dump=l||"[]"}function Qe(e,t,n){var r,o,i,a,l,u;for(i=0,a=(o=n?e.explicitTypes:e.implicitTypes).length;i<a;i+=1)if(((l=o[i]).instanceOf||l.predicate)&&(!l.instanceOf||"object"==typeof t&&t instanceof l.instanceOf)&&(!l.predicate||l.predicate(t))){if(n?l.multi&&l.representName?e.tag=l.representName(t):e.tag=l.tag:e.tag="?",l.represent){if(u=e.styleMap[l.tag]||l.defaultStyle,"[object Function]"===Ee.call(l.represent))r=l.represent(t,u);else{if(!Pe.call(l.represent,u))throw new s("!<"+l.tag+'> tag resolver accepts not "'+u+'" style');r=l.represent[u](t,u)}e.dump=r}return!0}return!1}function Ge(e,t,n,r,o,i,a){e.tag=null,e.dump=n,Qe(e,n,!1)||Qe(e,n,!0);var l,u=Ee.call(e.dump),c=r;r&&(r=e.flowLevel<0||e.flowLevel>t);var f,p,d="[object Object]"===u||"[object Array]"===u;if(d&&(p=-1!==(f=e.duplicates.indexOf(n))),(null!==e.tag&&"?"!==e.tag||p||2!==e.indent&&t>0)&&(o=!1),p&&e.usedDuplicates[f])e.dump="*ref_"+f;else{if(d&&p&&!e.usedDuplicates[f]&&(e.usedDuplicates[f]=!0),"[object Object]"===u)r&&0!==Object.keys(e.dump).length?(function(e,t,n,r){var o,i,a,l,u,c,f="",p=e.tag,d=Object.keys(n);if(!0===e.sortKeys)d.sort();else if("function"==typeof e.sortKeys)d.sort(e.sortKeys);else if(e.sortKeys)throw new s("sortKeys must be a boolean or a function");for(o=0,i=d.length;o<i;o+=1)c="",r&&""===f||(c+=Fe(e,t)),l=n[a=d[o]],e.replacer&&(l=e.replacer.call(n,a,l)),Ge(e,t+1,a,!0,!0,!0)&&((u=null!==e.tag&&"?"!==e.tag||e.dump&&e.dump.length>1024)&&(e.dump&&10===e.dump.charCodeAt(0)?c+="?":c+="? "),c+=e.dump,u&&(c+=Fe(e,t)),Ge(e,t+1,l,!0,u)&&(e.dump&&10===e.dump.charCodeAt(0)?c+=":":c+=": ",f+=c+=e.dump));e.tag=p,e.dump=f||"{}"}(e,t,e.dump,o),p&&(e.dump="&ref_"+f+e.dump)):(function(e,t,n){var r,o,i,a,l,u="",s=e.tag,c=Object.keys(n);for(r=0,o=c.length;r<o;r+=1)l="",""!==u&&(l+=", "),e.condenseFlow&&(l+='"'),a=n[i=c[r]],e.replacer&&(a=e.replacer.call(n,i,a)),Ge(e,t,i,!1,!1)&&(e.dump.length>1024&&(l+="? "),l+=e.dump+(e.condenseFlow?'"':"")+":"+(e.condenseFlow?"":" "),Ge(e,t,a,!1,!1)&&(u+=l+=e.dump));e.tag=s,e.dump="{"+u+"}"}(e,t,e.dump),p&&(e.dump="&ref_"+f+" "+e.dump));else if("[object Array]"===u)r&&0!==e.dump.length?(e.noArrayIndent&&!a&&t>0?Ke(e,t-1,e.dump,o):Ke(e,t,e.dump,o),p&&(e.dump="&ref_"+f+e.dump)):(function(e,t,n){var r,o,i,a="",l=e.tag;for(r=0,o=n.length;r<o;r+=1)i=n[r],e.replacer&&(i=e.replacer.call(n,String(r),i)),(Ge(e,t,i,!1,!1)||void 0===i&&Ge(e,t,null,!1,!1))&&(""!==a&&(a+=","+(e.condenseFlow?"":" ")),a+=e.dump);e.tag=l,e.dump="["+a+"]"}(e,t,e.dump),p&&(e.dump="&ref_"+f+" "+e.dump));else{if("[object String]"!==u){if("[object Undefined]"===u)return!1;if(e.skipInvalid)return!1;throw new s("unacceptable kind of an object to dump "+u)}"?"!==e.tag&&Ve(e,e.dump,t,i,c)}null!==e.tag&&"?"!==e.tag&&(l=encodeURI("!"===e.tag[0]?e.tag.slice(1):e.tag).replace(/!/g,"%21"),l="!"===e.tag[0]?"!"+l:"tag:yaml.org,2002:"===l.slice(0,18)?"!!"+l.slice(18):"!<"+l+">",e.dump=l+" "+e.dump)}return!0}function Xe(e,t){var n,r,o=[],i=[];for(Ye(e,o,i),n=0,r=i.length;n<r;n+=1)t.duplicates.push(o[i[n]]);t.usedDuplicates=new Array(r)}function Ye(e,t,n){var r,o,i;if(null!==e&&"object"==typeof e)if(-1!==(o=t.indexOf(e)))-1===n.indexOf(o)&&n.push(o);else if(t.push(e),Array.isArray(e))for(o=0,i=e.length;o<i;o+=1)Ye(e[o],t,n);else for(o=0,i=(r=Object.keys(e)).length;o<i;o+=1)Ye(e[r[o]],t,n)}function Je(e,t){return function(){throw new Error("Function yaml."+e+" is removed in js-yaml 4. Use yaml."+t+" instead, which is now safe by default.")}}const et={Type:h,Schema:y,FAILSAFE_SCHEMA:_,JSON_SCHEMA:A,CORE_SCHEMA:T,DEFAULT_SCHEMA:W,load:Ce.load,loadAll:Ce.loadAll,dump:function(e,t){var n=new De(t=t||{});n.noRefs||Xe(e,n);var r=e;return n.replacer&&(r=n.replacer.call({"":r},"",r)),Ge(n,0,r,!0,!0)?n.dump+"\n":""},YAMLException:s,types:{binary:F,float:P,map:w,null:x,pairs:B,set:V,timestamp:M,bool:O,int:j,merge:D,omap:q,seq:v,str:g},safeLoad:Je("safeLoad","load"),safeLoadAll:Je("safeLoadAll","loadAll"),safeDump:Je("safeDump","dump")};function tt(){for(var e=document.getElementsByTagName("script"),t=e.length,n=0;n<t;n+=1){var r=e[n];if(r.src&&r.src.match(/js\/build/)){var o=r.src.lastIndexOf("/");return r.src.slice(0,o)}}return""}function nt(){return o.ZP.get("".concat(tt(),"/globalConfig.json")).then((function(e){return"object"===(0,r.Z)(e.data)?e.data:JSON.parse(e.data)})).catch((function(){return o.ZP.get("".concat(tt(),"/globalConfig.yaml")).then((function(e){return"object"===(0,r.Z)(e.data)?e.data:et.load(e.data)}))}))}},4317:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";__webpack_require__.d(__webpack_exports__,{Fv:()=>validateSchema,GE:()=>parseFileValidator,IX:()=>parseFunctionRawStr,LE:()=>parseStringValidator,en:()=>parseRegexRawStr,nC:()=>parseNumberValidator});var lodash__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(5220),lodash__WEBPACK_IMPORTED_MODULE_0___default=__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_0__),jsonschema__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(660),_messageUtil__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(9609),_schema_schema_json__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(552),appendError=function(e,t,n){t&&e.push(new Error(t,n))},parseRegexRawStr=function(e){var t,n;try{n=new RegExp(e)}catch(n){t=(0,_messageUtil__WEBPACK_IMPORTED_MODULE_2__.P)(12,e)}return{error:t,result:n}},parseArrForDupKeys=function(e,t){var n=lodash__WEBPACK_IMPORTED_MODULE_0__.uniqBy(e,(function(e){return lodash__WEBPACK_IMPORTED_MODULE_0__.isString(e[t])?e[t].toLowerCase():e[t]})).length;return e.length!==n&&(0,_messageUtil__WEBPACK_IMPORTED_MODULE_2__.P)(21,t)},parseNumberValidator=function(e){return{error:2===e.length&&lodash__WEBPACK_IMPORTED_MODULE_0__.isNumber(e[0])&&lodash__WEBPACK_IMPORTED_MODULE_0__.isNumber(e[1])&&e[0]<=e[1]?void 0:(0,_messageUtil__WEBPACK_IMPORTED_MODULE_2__.P)(13,JSON.stringify(e))}},parseStringValidator=function(e,t){return{error:t>=e?void 0:(0,_messageUtil__WEBPACK_IMPORTED_MODULE_2__.P)(14)}},parseFunctionRawStr=function parseFunctionRawStr(rawStr){var error,result;try{result=eval("(".concat(rawStr,")"))}catch(e){error=(0,_messageUtil__WEBPACK_IMPORTED_MODULE_2__.P)(11,rawStr)}return{error,result}},parseFileValidator=function(e,t){var n=e.fileName,r=e.fileSize,o=e.fileContent,i=n.split(".").pop(),a=-1!==t.findIndex((function(e){return e===i})),l=!0;try{JSON.parse(o)}catch(e){l=!1}return{isValidExtension:a,fileSize:r,isValidContent:l}},checkDupKeyValues=function(e,t,n){var r,o,i=lodash__WEBPACK_IMPORTED_MODULE_0__.get(e,t?"services":"tabs"),a=[];return i&&(o="".concat(n,".").concat(t?"services":"tabs"),["name","title"].forEach((function(e){r=parseArrForDupKeys(i,e),appendError(a,r,o)})),i.forEach((function(e,t){var n="".concat(o,"[").concat(t,"].entity");e.entity&&(["field","label"].forEach((function(t,o){r=parseArrForDupKeys(e.entity,t),appendError(a,r,"".concat(n,"[").concat(o,"]"))})),e.entity.forEach((function(e,t){!function(e,t){var n=e.options;if(n){var o=n.items,i=n.autoCompleteFields;if(o&&["label","value"].forEach((function(e){r=parseArrForDupKeys(o,e),appendError(a,r,"".concat(t,".options.items"))})),i){var l=!!i[0].children;(l?i.map((function(e){return e.children})):[i]).forEach((function(e){r=parseArrForDupKeys(e,"label"),appendError(a,r,"".concat(t,".options.autoCompleteFields"))})),l&&(i=lodash__WEBPACK_IMPORTED_MODULE_0__.flatten(lodash__WEBPACK_IMPORTED_MODULE_0__.union(i.map((function(e){return e.children}))))),r=parseArrForDupKeys(i,"value"),appendError(a,r,"".concat(t,".options.autoCompleteFields"))}}}(e,"".concat(n,"[").concat(t,"]"))})))}))),a},checkConfigDetails=function(e){var t,n=e.pages,r=n.configuration,o=n.inputs,i=[],a="instantce.pages",l=function(e,t){lodash__WEBPACK_IMPORTED_MODULE_0__.values(e).forEach((function(e,n){var r=parseFunctionRawStr(e).err;appendError(i,r,"".concat(t,"[").concat(n,"]"))}))},u=function(e,n,r){var o=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];lodash__WEBPACK_IMPORTED_MODULE_0__.values(e).forEach((function(e,n){var o=e.validators,a=e.options;lodash__WEBPACK_IMPORTED_MODULE_0__.values(o).forEach((function(e,o){switch(e.type){case"string":t=parseStringValidator(e.minLength,e.maxLength).error;break;case"number":t=parseNumberValidator(e.range).error;break;case"regex":t=parseRegexRawStr(e.pattern).error}appendError(i,t,"".concat(r,"[").concat(n,"].validators[").concat(o,"]"))})),lodash__WEBPACK_IMPORTED_MODULE_0__.forEach(["denyList","allowList"],(function(e){a&&a[e]&&(t=parseRegexRawStr(a[e]).error,appendError(i,t,"".concat(r,"[").concat(n,"].options.").concat(e)))}))})),o&&lodash__WEBPACK_IMPORTED_MODULE_0__.every(lodash__WEBPACK_IMPORTED_MODULE_0__.values(e),(function(e){return"name"!==e.field}))&&appendError(i,(0,_messageUtil__WEBPACK_IMPORTED_MODULE_2__.P)(23,n))};return o&&(o.services.forEach((function(e,t){var n=e.entity,r=e.options,o=e.name;l(r,"".concat(a,".inputs.services[").concat(t,"].options")),u(n,o,"".concat(a,".inputs.services[").concat(t,"].entity"))})),i=i.concat(checkDupKeyValues(o,!0,"".concat(a,".inputs")))),r&&(r.tabs.forEach((function(e,t){var n=e.entity,r=e.options,o=e.name;l(r,"".concat(a,".configuration.tabs[").concat(t,"].options")),u(n,o,"".concat(a,".configuration.tabs[").concat(t,"].entity"),!1)})),i=i.concat(checkDupKeyValues(r,!1,"".concat(a,".configuration")))),i},validateSchema=function(e){var t=(new jsonschema__WEBPACK_IMPORTED_MODULE_1__.Validator).validate(e,_schema_schema_json__WEBPACK_IMPORTED_MODULE_3__);return t.errors.length||(t.errors=checkConfigDetails(e)),{failed:!!t.errors.length,errors:t.errors}}},4255:(e,t,n)=>{"use strict";n.d(t,{Ke:()=>h,YK:()=>p,Zv:()=>f,gB:()=>m,mA:()=>u,oA:()=>s,w:()=>l,w3:()=>c});var r=n(4310),o=n(2034),i=n.n(o),a=null;function l(e){}function u(e){return["0","FALSE","F","N","NO","NONE",""].includes(e.toString().toUpperCase())}function s(e){return["1","TRUE","T","Y","YES"].includes(e.toString().toUpperCase())}function c(e){return"".concat(a.meta.restRoot,"_").concat(e)}function f(e){a=e}function p(){return a}var d=(0,o.makeCreateToast)(i()),h=function(e,t){var n,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;switch(t){case"success":n=r.TOAST_TYPES.SUCCESS;break;case"error":case"warning":n=r.TOAST_TYPES.ERROR;break;default:n=r.TOAST_TYPES.INFO}d({type:n,message:e,autoDismiss:!0,dismissOnActionClick:!0,showAction:Boolean(o),action:o||void 0})};function m(e,t,n,r){var o=e.map((function(e){var n;return{label:t?null===(n=e.content)||void 0===n?void 0:n[t]:e.name,value:e.name}}));return n&&(o=function(e,t){var n=new RegExp(t);return e.filter((function(e){return n.test(e.value)}))}(o,n)),r&&(o=function(e,t){var n=new RegExp(t);return e.filter((function(e){return!n.test(e.value)}))}(o,r)),o}},6201:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l});var r=n(8081),o=n.n(r),i=n(3645),a=n.n(i)()(o());a.push([e.id,'/*\n * Copyright 2021 Splunk Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may 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, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nbody {\n    min-width: 960px;\n}\n',""]);const l=a},3645:e=>{"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n="",r=void 0!==t[5];return t[4]&&(n+="@supports (".concat(t[4],") {")),t[2]&&(n+="@media ".concat(t[2]," {")),r&&(n+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),n+=e(t),r&&(n+="}"),t[2]&&(n+="}"),t[4]&&(n+="}"),n})).join("")},t.i=function(e,n,r,o,i){"string"==typeof e&&(e=[[null,e,void 0]]);var a={};if(r)for(var l=0;l<this.length;l++){var u=this[l][0];null!=u&&(a[u]=!0)}for(var s=0;s<e.length;s++){var c=[].concat(e[s]);r&&a[c[0]]||(void 0!==i&&(void 0===c[5]||(c[1]="@layer".concat(c[5].length>0?" ".concat(c[5]):""," {").concat(c[1],"}")),c[5]=i),n&&(c[2]?(c[1]="@media ".concat(c[2]," {").concat(c[1],"}"),c[2]=n):c[2]=n),o&&(c[4]?(c[1]="@supports (".concat(c[4],") {").concat(c[1],"}"),c[4]=o):c[4]="".concat(o)),t.push(c))}},t}},8081:e=>{"use strict";e.exports=function(e){return e[1]}},7187:e=>{"use strict";var t,n="object"==typeof Reflect?Reflect:null,r=n&&"function"==typeof n.apply?n.apply:function(e,t,n){return Function.prototype.apply.call(e,t,n)};t=n&&"function"==typeof n.ownKeys?n.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var o=Number.isNaN||function(e){return e!=e};function i(){i.init.call(this)}e.exports=i,e.exports.once=function(e,t){return new Promise((function(n,r){function o(n){e.removeListener(t,i),r(n)}function i(){"function"==typeof e.removeListener&&e.removeListener("error",o),n([].slice.call(arguments))}m(e,t,i,{once:!0}),"error"!==t&&function(e,t,n){"function"==typeof e.on&&m(e,"error",t,{once:!0})}(e,o)}))},i.EventEmitter=i,i.prototype._events=void 0,i.prototype._eventsCount=0,i.prototype._maxListeners=void 0;var a=10;function l(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function u(e){return void 0===e._maxListeners?i.defaultMaxListeners:e._maxListeners}function s(e,t,n,r){var o,i,a,s;if(l(n),void 0===(i=e._events)?(i=e._events=Object.create(null),e._eventsCount=0):(void 0!==i.newListener&&(e.emit("newListener",t,n.listener?n.listener:n),i=e._events),a=i[t]),void 0===a)a=i[t]=n,++e._eventsCount;else if("function"==typeof a?a=i[t]=r?[n,a]:[a,n]:r?a.unshift(n):a.push(n),(o=u(e))>0&&a.length>o&&!a.warned){a.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=a.length,s=c,console&&console.warn&&console.warn(s)}return e}function c(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function f(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=c.bind(r);return o.listener=n,r.wrapFn=o,o}function p(e,t,n){var r=e._events;if(void 0===r)return[];var o=r[t];return void 0===o?[]:"function"==typeof o?n?[o.listener||o]:[o]:n?function(e){for(var t=new Array(e.length),n=0;n<t.length;++n)t[n]=e[n].listener||e[n];return t}(o):h(o,o.length)}function d(e){var t=this._events;if(void 0!==t){var n=t[e];if("function"==typeof n)return 1;if(void 0!==n)return n.length}return 0}function h(e,t){for(var n=new Array(t),r=0;r<t;++r)n[r]=e[r];return n}function m(e,t,n,r){if("function"==typeof e.on)r.once?e.once(t,n):e.on(t,n);else{if("function"!=typeof e.addEventListener)throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type '+typeof e);e.addEventListener(t,(function o(i){r.once&&e.removeEventListener(t,o),n(i)}))}}Object.defineProperty(i,"defaultMaxListeners",{enumerable:!0,get:function(){return a},set:function(e){if("number"!=typeof e||e<0||o(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");a=e}}),i.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},i.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||o(e))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+e+".");return this._maxListeners=e,this},i.prototype.getMaxListeners=function(){return u(this)},i.prototype.emit=function(e){for(var t=[],n=1;n<arguments.length;n++)t.push(arguments[n]);var o="error"===e,i=this._events;if(void 0!==i)o=o&&void 0===i.error;else if(!o)return!1;if(o){var a;if(t.length>0&&(a=t[0]),a instanceof Error)throw a;var l=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw l.context=a,l}var u=i[e];if(void 0===u)return!1;if("function"==typeof u)r(u,this,t);else{var s=u.length,c=h(u,s);for(n=0;n<s;++n)r(c[n],this,t)}return!0},i.prototype.addListener=function(e,t){return s(this,e,t,!1)},i.prototype.on=i.prototype.addListener,i.prototype.prependListener=function(e,t){return s(this,e,t,!0)},i.prototype.once=function(e,t){return l(t),this.on(e,f(this,e,t)),this},i.prototype.prependOnceListener=function(e,t){return l(t),this.prependListener(e,f(this,e,t)),this},i.prototype.removeListener=function(e,t){var n,r,o,i,a;if(l(t),void 0===(r=this._events))return this;if(void 0===(n=r[e]))return this;if(n===t||n.listener===t)0==--this._eventsCount?this._events=Object.create(null):(delete r[e],r.removeListener&&this.emit("removeListener",e,n.listener||t));else if("function"!=typeof n){for(o=-1,i=n.length-1;i>=0;i--)if(n[i]===t||n[i].listener===t){a=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1<e.length;t++)e[t]=e[t+1];e.pop()}(n,o),1===n.length&&(r[e]=n[0]),void 0!==r.removeListener&&this.emit("removeListener",e,a||t)}return this},i.prototype.off=i.prototype.removeListener,i.prototype.removeAllListeners=function(e){var t,n,r;if(void 0===(n=this._events))return this;if(void 0===n.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==n[e]&&(0==--this._eventsCount?this._events=Object.create(null):delete n[e]),this;if(0===arguments.length){var o,i=Object.keys(n);for(r=0;r<i.length;++r)"removeListener"!==(o=i[r])&&this.removeAllListeners(o);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(t=n[e]))this.removeListener(e,t);else if(void 0!==t)for(r=t.length-1;r>=0;r--)this.removeListener(e,t[r]);return this},i.prototype.listeners=function(e){return p(this,e,!0)},i.prototype.rawListeners=function(e){return p(this,e,!1)},i.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):d.call(e,t)},i.prototype.listenerCount=d,i.prototype.eventNames=function(){return this._eventsCount>0?t(this._events):[]}},6230:e=>{e.exports="object"==typeof self?self.FormData:window.FormData},8679:(e,t,n)=>{"use strict";var r=n(9864),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},i={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},a={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function u(e){return r.isMemo(e)?a:l[e.$$typeof]||o}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=a;var s=Object.defineProperty,c=Object.getOwnPropertyNames,f=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,d=Object.getPrototypeOf,h=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(h){var o=d(n);o&&o!==h&&e(t,o,r)}var a=c(n);f&&(a=a.concat(f(n)));for(var l=u(t),m=u(n),b=0;b<a.length;++b){var y=a[b];if(!(i[y]||r&&r[y]||m&&m[y]||l&&l[y])){var g=p(n,y);try{s(t,y,g)}catch(e){}}}}return t}},361:(e,t,n)=>{var r=n(2427),o=n(8003),i=n(7407),a=n(2536),l=n(9097);function u(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}u.prototype.clear=r,u.prototype.delete=o,u.prototype.get=i,u.prototype.has=a,u.prototype.set=l,e.exports=u},259:(e,t,n)=>{var r=n(4958),o=n(7975),i=n(5139),a=n(6774),l=n(7230);function u(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}u.prototype.clear=r,u.prototype.delete=o,u.prototype.get=i,u.prototype.has=a,u.prototype.set=l,e.exports=u},6299:(e,t,n)=>{var r=n(3446)(n(6695),"Map");e.exports=r},3209:(e,t,n)=>{var r=n(6975),o=n(7899),i=n(8554),a=n(1029),l=n(6053);function u(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}u.prototype.clear=r,u.prototype.delete=o,u.prototype.get=i,u.prototype.has=a,u.prototype.set=l,e.exports=u},4380:(e,t,n)=>{var r=n(6695).Symbol;e.exports=r},2112:(e,t,n)=>{var r=n(4904);e.exports=function(e,t){for(var n=e.length;n--;)if(r(e[n][0],t))return n;return-1}},7486:(e,t,n)=>{var r=n(4380),o=n(9527),i=n(5736),a=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":a&&a in Object(e)?o(e):i(e)}},1326:(e,t,n)=>{var r=n(9657),o=n(5070),i=n(4538),a=n(6154),l=/^\[object .+?Constructor\]$/,u=Function.prototype,s=Object.prototype,c=u.toString,f=s.hasOwnProperty,p=RegExp("^"+c.call(f).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");e.exports=function(e){return!(!i(e)||o(e))&&(r(e)?p:l).test(a(e))}},8793:(e,t,n)=>{var r=n(6695)["__core-js_shared__"];e.exports=r},8552:(e,t,n)=>{var r="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g;e.exports=r},8561:(e,t,n)=>{var r=n(3766);e.exports=function(e,t){var n=e.__data__;return r(t)?n["string"==typeof t?"string":"hash"]:n.map}},3446:(e,t,n)=>{var r=n(1326),o=n(7983);e.exports=function(e,t){var n=o(e,t);return r(n)?n:void 0}},9527:(e,t,n)=>{var r=n(4380),o=Object.prototype,i=o.hasOwnProperty,a=o.toString,l=r?r.toStringTag:void 0;e.exports=function(e){var t=i.call(e,l),n=e[l];try{e[l]=void 0;var r=!0}catch(e){}var o=a.call(e);return r&&(t?e[l]=n:delete e[l]),o}},7983:e=>{e.exports=function(e,t){return null==e?void 0:e[t]}},2427:(e,t,n)=>{var r=n(1027);e.exports=function(){this.__data__=r?r(null):{},this.size=0}},8003:e=>{e.exports=function(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}},7407:(e,t,n)=>{var r=n(1027),o=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;if(r){var n=t[e];return"__lodash_hash_undefined__"===n?void 0:n}return o.call(t,e)?t[e]:void 0}},2536:(e,t,n)=>{var r=n(1027),o=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;return r?void 0!==t[e]:o.call(t,e)}},9097:(e,t,n)=>{var r=n(1027);e.exports=function(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=r&&void 0===t?"__lodash_hash_undefined__":t,this}},3766:e=>{e.exports=function(e){var t=typeof e;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==e:null===e}},5070:(e,t,n)=>{var r,o=n(8793),i=(r=/[^.]+$/.exec(o&&o.keys&&o.keys.IE_PROTO||""))?"Symbol(src)_1."+r:"";e.exports=function(e){return!!i&&i in e}},4958:e=>{e.exports=function(){this.__data__=[],this.size=0}},7975:(e,t,n)=>{var r=n(2112),o=Array.prototype.splice;e.exports=function(e){var t=this.__data__,n=r(t,e);return!(n<0||(n==t.length-1?t.pop():o.call(t,n,1),--this.size,0))}},5139:(e,t,n)=>{var r=n(2112);e.exports=function(e){var t=this.__data__,n=r(t,e);return n<0?void 0:t[n][1]}},6774:(e,t,n)=>{var r=n(2112);e.exports=function(e){return r(this.__data__,e)>-1}},7230:(e,t,n)=>{var r=n(2112);e.exports=function(e,t){var n=this.__data__,o=r(n,e);return o<0?(++this.size,n.push([e,t])):n[o][1]=t,this}},6975:(e,t,n)=>{var r=n(361),o=n(259),i=n(6299);e.exports=function(){this.size=0,this.__data__={hash:new r,map:new(i||o),string:new r}}},7899:(e,t,n)=>{var r=n(8561);e.exports=function(e){var t=r(this,e).delete(e);return this.size-=t?1:0,t}},8554:(e,t,n)=>{var r=n(8561);e.exports=function(e){return r(this,e).get(e)}},1029:(e,t,n)=>{var r=n(8561);e.exports=function(e){return r(this,e).has(e)}},6053:(e,t,n)=>{var r=n(8561);e.exports=function(e,t){var n=r(this,e),o=n.size;return n.set(e,t),this.size+=n.size==o?0:1,this}},1027:(e,t,n)=>{var r=n(3446)(Object,"create");e.exports=r},5736:e=>{var t=Object.prototype.toString;e.exports=function(e){return t.call(e)}},6695:(e,t,n)=>{var r=n(8552),o="object"==typeof self&&self&&self.Object===Object&&self,i=r||o||Function("return this")();e.exports=i},6154:e=>{var t=Function.prototype.toString;e.exports=function(e){if(null!=e){try{return t.call(e)}catch(e){}try{return e+""}catch(e){}}return""}},4904:e=>{e.exports=function(e,t){return e===t||e!=e&&t!=t}},9657:(e,t,n)=>{var r=n(7486),o=n(4538);e.exports=function(e){if(!o(e))return!1;var t=r(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t}},4538:e=>{e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},5220:function(e,t,n){e=n.nmd(e),function(){var r,o="Expected a function",i="__lodash_hash_undefined__",a="__lodash_placeholder__",l=32,u=128,s=1/0,c=9007199254740991,f=NaN,p=4294967295,d=[["ary",u],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",l],["partialRight",64],["rearg",256]],h="[object Arguments]",m="[object Array]",b="[object Boolean]",y="[object Date]",g="[object Error]",v="[object Function]",w="[object GeneratorFunction]",_="[object Map]",x="[object Number]",O="[object Object]",S="[object Promise]",k="[object RegExp]",j="[object Set]",C="[object String]",E="[object Symbol]",P="[object WeakMap]",A="[object ArrayBuffer]",T="[object DataView]",L="[object Float32Array]",R="[object Float64Array]",M="[object Int8Array]",D="[object Int16Array]",I="[object Int32Array]",F="[object Uint8Array]",N="[object Uint8ClampedArray]",z="[object Uint16Array]",q="[object Uint32Array]",$=/\b__p \+= '';/g,B=/\b(__p \+=) '' \+/g,U=/(__e\(.*?\)|\b__t\)) \+\n'';/g,V=/&(?:amp|lt|gt|quot|#39);/g,W=/[&<>"']/g,H=RegExp(V.source),Z=RegExp(W.source),K=/<%-([\s\S]+?)%>/g,Q=/<%([\s\S]+?)%>/g,G=/<%=([\s\S]+?)%>/g,X=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Y=/^\w*$/,J=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,ee=/[\\^$.*+?()[\]{}|]/g,te=RegExp(ee.source),ne=/^\s+/,re=/\s/,oe=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,ie=/\{\n\/\* \[wrapped with (.+)\] \*/,ae=/,? & /,le=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,ue=/[()=,{}\[\]\/\s]/,se=/\\(\\)?/g,ce=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,fe=/\w*$/,pe=/^[-+]0x[0-9a-f]+$/i,de=/^0b[01]+$/i,he=/^\[object .+?Constructor\]$/,me=/^0o[0-7]+$/i,be=/^(?:0|[1-9]\d*)$/,ye=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,ge=/($^)/,ve=/['\n\r\u2028\u2029\\]/g,we="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",_e="a-z\\xdf-\\xf6\\xf8-\\xff",xe="A-Z\\xc0-\\xd6\\xd8-\\xde",Oe="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",Se="["+Oe+"]",ke="["+we+"]",je="\\d+",Ce="["+_e+"]",Ee="[^\\ud800-\\udfff"+Oe+je+"\\u2700-\\u27bf"+_e+xe+"]",Pe="\\ud83c[\\udffb-\\udfff]",Ae="[^\\ud800-\\udfff]",Te="(?:\\ud83c[\\udde6-\\uddff]){2}",Le="[\\ud800-\\udbff][\\udc00-\\udfff]",Re="["+xe+"]",Me="(?:"+Ce+"|"+Ee+")",De="(?:"+Re+"|"+Ee+")",Ie="(?:['’](?:d|ll|m|re|s|t|ve))?",Fe="(?:['’](?:D|LL|M|RE|S|T|VE))?",Ne="(?:"+ke+"|"+Pe+")?",ze="[\\ufe0e\\ufe0f]?",qe=ze+Ne+"(?:\\u200d(?:"+[Ae,Te,Le].join("|")+")"+ze+Ne+")*",$e="(?:"+["[\\u2700-\\u27bf]",Te,Le].join("|")+")"+qe,Be="(?:"+[Ae+ke+"?",ke,Te,Le,"[\\ud800-\\udfff]"].join("|")+")",Ue=RegExp("['’]","g"),Ve=RegExp(ke,"g"),We=RegExp(Pe+"(?="+Pe+")|"+Be+qe,"g"),He=RegExp([Re+"?"+Ce+"+"+Ie+"(?="+[Se,Re,"$"].join("|")+")",De+"+"+Fe+"(?="+[Se,Re+Me,"$"].join("|")+")",Re+"?"+Me+"+"+Ie,Re+"+"+Fe,"\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",je,$e].join("|"),"g"),Ze=RegExp("[\\u200d\\ud800-\\udfff"+we+"\\ufe0e\\ufe0f]"),Ke=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Qe=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],Ge=-1,Xe={};Xe[L]=Xe[R]=Xe[M]=Xe[D]=Xe[I]=Xe[F]=Xe[N]=Xe[z]=Xe[q]=!0,Xe[h]=Xe[m]=Xe[A]=Xe[b]=Xe[T]=Xe[y]=Xe[g]=Xe[v]=Xe[_]=Xe[x]=Xe[O]=Xe[k]=Xe[j]=Xe[C]=Xe[P]=!1;var Ye={};Ye[h]=Ye[m]=Ye[A]=Ye[T]=Ye[b]=Ye[y]=Ye[L]=Ye[R]=Ye[M]=Ye[D]=Ye[I]=Ye[_]=Ye[x]=Ye[O]=Ye[k]=Ye[j]=Ye[C]=Ye[E]=Ye[F]=Ye[N]=Ye[z]=Ye[q]=!0,Ye[g]=Ye[v]=Ye[P]=!1;var Je={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},et=parseFloat,tt=parseInt,nt="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g,rt="object"==typeof self&&self&&self.Object===Object&&self,ot=nt||rt||Function("return this")(),it=t&&!t.nodeType&&t,at=it&&e&&!e.nodeType&&e,lt=at&&at.exports===it,ut=lt&&nt.process,st=function(){try{return at&&at.require&&at.require("util").types||ut&&ut.binding&&ut.binding("util")}catch(e){}}(),ct=st&&st.isArrayBuffer,ft=st&&st.isDate,pt=st&&st.isMap,dt=st&&st.isRegExp,ht=st&&st.isSet,mt=st&&st.isTypedArray;function bt(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)}function yt(e,t,n,r){for(var o=-1,i=null==e?0:e.length;++o<i;){var a=e[o];t(r,a,n(a),e)}return r}function gt(e,t){for(var n=-1,r=null==e?0:e.length;++n<r&&!1!==t(e[n],n,e););return e}function vt(e,t){for(var n=null==e?0:e.length;n--&&!1!==t(e[n],n,e););return e}function wt(e,t){for(var n=-1,r=null==e?0:e.length;++n<r;)if(!t(e[n],n,e))return!1;return!0}function _t(e,t){for(var n=-1,r=null==e?0:e.length,o=0,i=[];++n<r;){var a=e[n];t(a,n,e)&&(i[o++]=a)}return i}function xt(e,t){return!(null==e||!e.length)&&Lt(e,t,0)>-1}function Ot(e,t,n){for(var r=-1,o=null==e?0:e.length;++r<o;)if(n(t,e[r]))return!0;return!1}function St(e,t){for(var n=-1,r=null==e?0:e.length,o=Array(r);++n<r;)o[n]=t(e[n],n,e);return o}function kt(e,t){for(var n=-1,r=t.length,o=e.length;++n<r;)e[o+n]=t[n];return e}function jt(e,t,n,r){var o=-1,i=null==e?0:e.length;for(r&&i&&(n=e[++o]);++o<i;)n=t(n,e[o],o,e);return n}function Ct(e,t,n,r){var o=null==e?0:e.length;for(r&&o&&(n=e[--o]);o--;)n=t(n,e[o],o,e);return n}function Et(e,t){for(var n=-1,r=null==e?0:e.length;++n<r;)if(t(e[n],n,e))return!0;return!1}var Pt=It("length");function At(e,t,n){var r;return n(e,(function(e,n,o){if(t(e,n,o))return r=n,!1})),r}function Tt(e,t,n,r){for(var o=e.length,i=n+(r?1:-1);r?i--:++i<o;)if(t(e[i],i,e))return i;return-1}function Lt(e,t,n){return t==t?function(e,t,n){for(var r=n-1,o=e.length;++r<o;)if(e[r]===t)return r;return-1}(e,t,n):Tt(e,Mt,n)}function Rt(e,t,n,r){for(var o=n-1,i=e.length;++o<i;)if(r(e[o],t))return o;return-1}function Mt(e){return e!=e}function Dt(e,t){var n=null==e?0:e.length;return n?zt(e,t)/n:f}function It(e){return function(t){return null==t?r:t[e]}}function Ft(e){return function(t){return null==e?r:e[t]}}function Nt(e,t,n,r,o){return o(e,(function(e,o,i){n=r?(r=!1,e):t(n,e,o,i)})),n}function zt(e,t){for(var n,o=-1,i=e.length;++o<i;){var a=t(e[o]);a!==r&&(n=n===r?a:n+a)}return n}function qt(e,t){for(var n=-1,r=Array(e);++n<e;)r[n]=t(n);return r}function $t(e){return e?e.slice(0,an(e)+1).replace(ne,""):e}function Bt(e){return function(t){return e(t)}}function Ut(e,t){return St(t,(function(t){return e[t]}))}function Vt(e,t){return e.has(t)}function Wt(e,t){for(var n=-1,r=e.length;++n<r&&Lt(t,e[n],0)>-1;);return n}function Ht(e,t){for(var n=e.length;n--&&Lt(t,e[n],0)>-1;);return n}function Zt(e,t){for(var n=e.length,r=0;n--;)e[n]===t&&++r;return r}var Kt=Ft({À:"A",Á:"A",Â:"A",Ã:"A",Ä:"A",Å:"A",à:"a",á:"a",â:"a",ã:"a",ä:"a",å:"a",Ç:"C",ç:"c",Ð:"D",ð:"d",È:"E",É:"E",Ê:"E",Ë:"E",è:"e",é:"e",ê:"e",ë:"e",Ì:"I",Í:"I",Î:"I",Ï:"I",ì:"i",í:"i",î:"i",ï:"i",Ñ:"N",ñ:"n",Ò:"O",Ó:"O",Ô:"O",Õ:"O",Ö:"O",Ø:"O",ò:"o",ó:"o",ô:"o",õ:"o",ö:"o",ø:"o",Ù:"U",Ú:"U",Û:"U",Ü:"U",ù:"u",ú:"u",û:"u",ü:"u",Ý:"Y",ý:"y",ÿ:"y",Æ:"Ae",æ:"ae",Þ:"Th",þ:"th",ß:"ss",Ā:"A",Ă:"A",Ą:"A",ā:"a",ă:"a",ą:"a",Ć:"C",Ĉ:"C",Ċ:"C",Č:"C",ć:"c",ĉ:"c",ċ:"c",č:"c",Ď:"D",Đ:"D",ď:"d",đ:"d",Ē:"E",Ĕ:"E",Ė:"E",Ę:"E",Ě:"E",ē:"e",ĕ:"e",ė:"e",ę:"e",ě:"e",Ĝ:"G",Ğ:"G",Ġ:"G",Ģ:"G",ĝ:"g",ğ:"g",ġ:"g",ģ:"g",Ĥ:"H",Ħ:"H",ĥ:"h",ħ:"h",Ĩ:"I",Ī:"I",Ĭ:"I",Į:"I",İ:"I",ĩ:"i",ī:"i",ĭ:"i",į:"i",ı:"i",Ĵ:"J",ĵ:"j",Ķ:"K",ķ:"k",ĸ:"k",Ĺ:"L",Ļ:"L",Ľ:"L",Ŀ:"L",Ł:"L",ĺ:"l",ļ:"l",ľ:"l",ŀ:"l",ł:"l",Ń:"N",Ņ:"N",Ň:"N",Ŋ:"N",ń:"n",ņ:"n",ň:"n",ŋ:"n",Ō:"O",Ŏ:"O",Ő:"O",ō:"o",ŏ:"o",ő:"o",Ŕ:"R",Ŗ:"R",Ř:"R",ŕ:"r",ŗ:"r",ř:"r",Ś:"S",Ŝ:"S",Ş:"S",Š:"S",ś:"s",ŝ:"s",ş:"s",š:"s",Ţ:"T",Ť:"T",Ŧ:"T",ţ:"t",ť:"t",ŧ:"t",Ũ:"U",Ū:"U",Ŭ:"U",Ů:"U",Ű:"U",Ų:"U",ũ:"u",ū:"u",ŭ:"u",ů:"u",ű:"u",ų:"u",Ŵ:"W",ŵ:"w",Ŷ:"Y",ŷ:"y",Ÿ:"Y",Ź:"Z",Ż:"Z",Ž:"Z",ź:"z",ż:"z",ž:"z",IJ:"IJ",ij:"ij",Œ:"Oe",œ:"oe",ʼn:"'n",ſ:"s"}),Qt=Ft({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"});function Gt(e){return"\\"+Je[e]}function Xt(e){return Ze.test(e)}function Yt(e){var t=-1,n=Array(e.size);return e.forEach((function(e,r){n[++t]=[r,e]})),n}function Jt(e,t){return function(n){return e(t(n))}}function en(e,t){for(var n=-1,r=e.length,o=0,i=[];++n<r;){var l=e[n];l!==t&&l!==a||(e[n]=a,i[o++]=n)}return i}function tn(e){var t=-1,n=Array(e.size);return e.forEach((function(e){n[++t]=e})),n}function nn(e){var t=-1,n=Array(e.size);return e.forEach((function(e){n[++t]=[e,e]})),n}function rn(e){return Xt(e)?function(e){for(var t=We.lastIndex=0;We.test(e);)++t;return t}(e):Pt(e)}function on(e){return Xt(e)?function(e){return e.match(We)||[]}(e):function(e){return e.split("")}(e)}function an(e){for(var t=e.length;t--&&re.test(e.charAt(t)););return t}var ln=Ft({"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"}),un=function e(t){var n,re=(t=null==t?ot:un.defaults(ot.Object(),t,un.pick(ot,Qe))).Array,we=t.Date,_e=t.Error,xe=t.Function,Oe=t.Math,Se=t.Object,ke=t.RegExp,je=t.String,Ce=t.TypeError,Ee=re.prototype,Pe=xe.prototype,Ae=Se.prototype,Te=t["__core-js_shared__"],Le=Pe.toString,Re=Ae.hasOwnProperty,Me=0,De=(n=/[^.]+$/.exec(Te&&Te.keys&&Te.keys.IE_PROTO||""))?"Symbol(src)_1."+n:"",Ie=Ae.toString,Fe=Le.call(Se),Ne=ot._,ze=ke("^"+Le.call(Re).replace(ee,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),qe=lt?t.Buffer:r,$e=t.Symbol,Be=t.Uint8Array,We=qe?qe.allocUnsafe:r,Ze=Jt(Se.getPrototypeOf,Se),Je=Se.create,nt=Ae.propertyIsEnumerable,rt=Ee.splice,it=$e?$e.isConcatSpreadable:r,at=$e?$e.iterator:r,ut=$e?$e.toStringTag:r,st=function(){try{var e=ci(Se,"defineProperty");return e({},"",{}),e}catch(e){}}(),Pt=t.clearTimeout!==ot.clearTimeout&&t.clearTimeout,Ft=we&&we.now!==ot.Date.now&&we.now,sn=t.setTimeout!==ot.setTimeout&&t.setTimeout,cn=Oe.ceil,fn=Oe.floor,pn=Se.getOwnPropertySymbols,dn=qe?qe.isBuffer:r,hn=t.isFinite,mn=Ee.join,bn=Jt(Se.keys,Se),yn=Oe.max,gn=Oe.min,vn=we.now,wn=t.parseInt,_n=Oe.random,xn=Ee.reverse,On=ci(t,"DataView"),Sn=ci(t,"Map"),kn=ci(t,"Promise"),jn=ci(t,"Set"),Cn=ci(t,"WeakMap"),En=ci(Se,"create"),Pn=Cn&&new Cn,An={},Tn=zi(On),Ln=zi(Sn),Rn=zi(kn),Mn=zi(jn),Dn=zi(Cn),In=$e?$e.prototype:r,Fn=In?In.valueOf:r,Nn=In?In.toString:r;function zn(e){if(nl(e)&&!Wa(e)&&!(e instanceof Un)){if(e instanceof Bn)return e;if(Re.call(e,"__wrapped__"))return qi(e)}return new Bn(e)}var qn=function(){function e(){}return function(t){if(!tl(t))return{};if(Je)return Je(t);e.prototype=t;var n=new e;return e.prototype=r,n}}();function $n(){}function Bn(e,t){this.__wrapped__=e,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=r}function Un(e){this.__wrapped__=e,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=p,this.__views__=[]}function Vn(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}function Wn(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}function Hn(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}function Zn(e){var t=-1,n=null==e?0:e.length;for(this.__data__=new Hn;++t<n;)this.add(e[t])}function Kn(e){var t=this.__data__=new Wn(e);this.size=t.size}function Qn(e,t){var n=Wa(e),r=!n&&Va(e),o=!n&&!r&&Qa(e),i=!n&&!r&&!o&&cl(e),a=n||r||o||i,l=a?qt(e.length,je):[],u=l.length;for(var s in e)!t&&!Re.call(e,s)||a&&("length"==s||o&&("offset"==s||"parent"==s)||i&&("buffer"==s||"byteLength"==s||"byteOffset"==s)||yi(s,u))||l.push(s);return l}function Gn(e){var t=e.length;return t?e[Hr(0,t-1)]:r}function Xn(e,t){return Mi(Eo(e),ar(t,0,e.length))}function Yn(e){return Mi(Eo(e))}function Jn(e,t,n){(n!==r&&!$a(e[t],n)||n===r&&!(t in e))&&or(e,t,n)}function er(e,t,n){var o=e[t];Re.call(e,t)&&$a(o,n)&&(n!==r||t in e)||or(e,t,n)}function tr(e,t){for(var n=e.length;n--;)if($a(e[n][0],t))return n;return-1}function nr(e,t,n,r){return fr(e,(function(e,o,i){t(r,e,n(e),i)})),r}function rr(e,t){return e&&Po(t,Ll(t),e)}function or(e,t,n){"__proto__"==t&&st?st(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0}):e[t]=n}function ir(e,t){for(var n=-1,o=t.length,i=re(o),a=null==e;++n<o;)i[n]=a?r:Cl(e,t[n]);return i}function ar(e,t,n){return e==e&&(n!==r&&(e=e<=n?e:n),t!==r&&(e=e>=t?e:t)),e}function lr(e,t,n,o,i,a){var l,u=1&t,s=2&t,c=4&t;if(n&&(l=i?n(e,o,i,a):n(e)),l!==r)return l;if(!tl(e))return e;var f=Wa(e);if(f){if(l=function(e){var t=e.length,n=new e.constructor(t);return t&&"string"==typeof e[0]&&Re.call(e,"index")&&(n.index=e.index,n.input=e.input),n}(e),!u)return Eo(e,l)}else{var p=di(e),d=p==v||p==w;if(Qa(e))return xo(e,u);if(p==O||p==h||d&&!i){if(l=s||d?{}:mi(e),!u)return s?function(e,t){return Po(e,pi(e),t)}(e,function(e,t){return e&&Po(t,Rl(t),e)}(l,e)):function(e,t){return Po(e,fi(e),t)}(e,rr(l,e))}else{if(!Ye[p])return i?e:{};l=function(e,t,n){var r,o=e.constructor;switch(t){case A:return Oo(e);case b:case y:return new o(+e);case T:return function(e,t){var n=t?Oo(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.byteLength)}(e,n);case L:case R:case M:case D:case I:case F:case N:case z:case q:return So(e,n);case _:return new o;case x:case C:return new o(e);case k:return function(e){var t=new e.constructor(e.source,fe.exec(e));return t.lastIndex=e.lastIndex,t}(e);case j:return new o;case E:return r=e,Fn?Se(Fn.call(r)):{}}}(e,p,u)}}a||(a=new Kn);var m=a.get(e);if(m)return m;a.set(e,l),ll(e)?e.forEach((function(r){l.add(lr(r,t,n,r,e,a))})):rl(e)&&e.forEach((function(r,o){l.set(o,lr(r,t,n,o,e,a))}));var g=f?r:(c?s?ri:ni:s?Rl:Ll)(e);return gt(g||e,(function(r,o){g&&(r=e[o=r]),er(l,o,lr(r,t,n,o,e,a))})),l}function ur(e,t,n){var o=n.length;if(null==e)return!o;for(e=Se(e);o--;){var i=n[o],a=t[i],l=e[i];if(l===r&&!(i in e)||!a(l))return!1}return!0}function sr(e,t,n){if("function"!=typeof e)throw new Ce(o);return Ai((function(){e.apply(r,n)}),t)}function cr(e,t,n,r){var o=-1,i=xt,a=!0,l=e.length,u=[],s=t.length;if(!l)return u;n&&(t=St(t,Bt(n))),r?(i=Ot,a=!1):t.length>=200&&(i=Vt,a=!1,t=new Zn(t));e:for(;++o<l;){var c=e[o],f=null==n?c:n(c);if(c=r||0!==c?c:0,a&&f==f){for(var p=s;p--;)if(t[p]===f)continue e;u.push(c)}else i(t,f,r)||u.push(c)}return u}zn.templateSettings={escape:K,evaluate:Q,interpolate:G,variable:"",imports:{_:zn}},zn.prototype=$n.prototype,zn.prototype.constructor=zn,Bn.prototype=qn($n.prototype),Bn.prototype.constructor=Bn,Un.prototype=qn($n.prototype),Un.prototype.constructor=Un,Vn.prototype.clear=function(){this.__data__=En?En(null):{},this.size=0},Vn.prototype.delete=function(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t},Vn.prototype.get=function(e){var t=this.__data__;if(En){var n=t[e];return n===i?r:n}return Re.call(t,e)?t[e]:r},Vn.prototype.has=function(e){var t=this.__data__;return En?t[e]!==r:Re.call(t,e)},Vn.prototype.set=function(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=En&&t===r?i:t,this},Wn.prototype.clear=function(){this.__data__=[],this.size=0},Wn.prototype.delete=function(e){var t=this.__data__,n=tr(t,e);return!(n<0||(n==t.length-1?t.pop():rt.call(t,n,1),--this.size,0))},Wn.prototype.get=function(e){var t=this.__data__,n=tr(t,e);return n<0?r:t[n][1]},Wn.prototype.has=function(e){return tr(this.__data__,e)>-1},Wn.prototype.set=function(e,t){var n=this.__data__,r=tr(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this},Hn.prototype.clear=function(){this.size=0,this.__data__={hash:new Vn,map:new(Sn||Wn),string:new Vn}},Hn.prototype.delete=function(e){var t=ui(this,e).delete(e);return this.size-=t?1:0,t},Hn.prototype.get=function(e){return ui(this,e).get(e)},Hn.prototype.has=function(e){return ui(this,e).has(e)},Hn.prototype.set=function(e,t){var n=ui(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this},Zn.prototype.add=Zn.prototype.push=function(e){return this.__data__.set(e,i),this},Zn.prototype.has=function(e){return this.__data__.has(e)},Kn.prototype.clear=function(){this.__data__=new Wn,this.size=0},Kn.prototype.delete=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n},Kn.prototype.get=function(e){return this.__data__.get(e)},Kn.prototype.has=function(e){return this.__data__.has(e)},Kn.prototype.set=function(e,t){var n=this.__data__;if(n instanceof Wn){var r=n.__data__;if(!Sn||r.length<199)return r.push([e,t]),this.size=++n.size,this;n=this.__data__=new Hn(r)}return n.set(e,t),this.size=n.size,this};var fr=Lo(vr),pr=Lo(wr,!0);function dr(e,t){var n=!0;return fr(e,(function(e,r,o){return n=!!t(e,r,o)})),n}function hr(e,t,n){for(var o=-1,i=e.length;++o<i;){var a=e[o],l=t(a);if(null!=l&&(u===r?l==l&&!sl(l):n(l,u)))var u=l,s=a}return s}function mr(e,t){var n=[];return fr(e,(function(e,r,o){t(e,r,o)&&n.push(e)})),n}function br(e,t,n,r,o){var i=-1,a=e.length;for(n||(n=bi),o||(o=[]);++i<a;){var l=e[i];t>0&&n(l)?t>1?br(l,t-1,n,r,o):kt(o,l):r||(o[o.length]=l)}return o}var yr=Ro(),gr=Ro(!0);function vr(e,t){return e&&yr(e,t,Ll)}function wr(e,t){return e&&gr(e,t,Ll)}function _r(e,t){return _t(t,(function(t){return Ya(e[t])}))}function xr(e,t){for(var n=0,o=(t=go(t,e)).length;null!=e&&n<o;)e=e[Ni(t[n++])];return n&&n==o?e:r}function Or(e,t,n){var r=t(e);return Wa(e)?r:kt(r,n(e))}function Sr(e){return null==e?e===r?"[object Undefined]":"[object Null]":ut&&ut in Se(e)?function(e){var t=Re.call(e,ut),n=e[ut];try{e[ut]=r;var o=!0}catch(e){}var i=Ie.call(e);return o&&(t?e[ut]=n:delete e[ut]),i}(e):function(e){return Ie.call(e)}(e)}function kr(e,t){return e>t}function jr(e,t){return null!=e&&Re.call(e,t)}function Cr(e,t){return null!=e&&t in Se(e)}function Er(e,t,n){for(var o=n?Ot:xt,i=e[0].length,a=e.length,l=a,u=re(a),s=1/0,c=[];l--;){var f=e[l];l&&t&&(f=St(f,Bt(t))),s=gn(f.length,s),u[l]=!n&&(t||i>=120&&f.length>=120)?new Zn(l&&f):r}f=e[0];var p=-1,d=u[0];e:for(;++p<i&&c.length<s;){var h=f[p],m=t?t(h):h;if(h=n||0!==h?h:0,!(d?Vt(d,m):o(c,m,n))){for(l=a;--l;){var b=u[l];if(!(b?Vt(b,m):o(e[l],m,n)))continue e}d&&d.push(m),c.push(h)}}return c}function Pr(e,t,n){var o=null==(e=ji(e,t=go(t,e)))?e:e[Ni(Xi(t))];return null==o?r:bt(o,e,n)}function Ar(e){return nl(e)&&Sr(e)==h}function Tr(e,t,n,o,i){return e===t||(null==e||null==t||!nl(e)&&!nl(t)?e!=e&&t!=t:function(e,t,n,o,i,a){var l=Wa(e),u=Wa(t),s=l?m:di(e),c=u?m:di(t),f=(s=s==h?O:s)==O,p=(c=c==h?O:c)==O,d=s==c;if(d&&Qa(e)){if(!Qa(t))return!1;l=!0,f=!1}if(d&&!f)return a||(a=new Kn),l||cl(e)?ei(e,t,n,o,i,a):function(e,t,n,r,o,i,a){switch(n){case T:if(e.byteLength!=t.byteLength||e.byteOffset!=t.byteOffset)return!1;e=e.buffer,t=t.buffer;case A:return!(e.byteLength!=t.byteLength||!i(new Be(e),new Be(t)));case b:case y:case x:return $a(+e,+t);case g:return e.name==t.name&&e.message==t.message;case k:case C:return e==t+"";case _:var l=Yt;case j:var u=1&r;if(l||(l=tn),e.size!=t.size&&!u)return!1;var s=a.get(e);if(s)return s==t;r|=2,a.set(e,t);var c=ei(l(e),l(t),r,o,i,a);return a.delete(e),c;case E:if(Fn)return Fn.call(e)==Fn.call(t)}return!1}(e,t,s,n,o,i,a);if(!(1&n)){var v=f&&Re.call(e,"__wrapped__"),w=p&&Re.call(t,"__wrapped__");if(v||w){var S=v?e.value():e,P=w?t.value():t;return a||(a=new Kn),i(S,P,n,o,a)}}return!!d&&(a||(a=new Kn),function(e,t,n,o,i,a){var l=1&n,u=ni(e),s=u.length;if(s!=ni(t).length&&!l)return!1;for(var c=s;c--;){var f=u[c];if(!(l?f in t:Re.call(t,f)))return!1}var p=a.get(e),d=a.get(t);if(p&&d)return p==t&&d==e;var h=!0;a.set(e,t),a.set(t,e);for(var m=l;++c<s;){var b=e[f=u[c]],y=t[f];if(o)var g=l?o(y,b,f,t,e,a):o(b,y,f,e,t,a);if(!(g===r?b===y||i(b,y,n,o,a):g)){h=!1;break}m||(m="constructor"==f)}if(h&&!m){var v=e.constructor,w=t.constructor;v==w||!("constructor"in e)||!("constructor"in t)||"function"==typeof v&&v instanceof v&&"function"==typeof w&&w instanceof w||(h=!1)}return a.delete(e),a.delete(t),h}(e,t,n,o,i,a))}(e,t,n,o,Tr,i))}function Lr(e,t,n,o){var i=n.length,a=i,l=!o;if(null==e)return!a;for(e=Se(e);i--;){var u=n[i];if(l&&u[2]?u[1]!==e[u[0]]:!(u[0]in e))return!1}for(;++i<a;){var s=(u=n[i])[0],c=e[s],f=u[1];if(l&&u[2]){if(c===r&&!(s in e))return!1}else{var p=new Kn;if(o)var d=o(c,f,s,e,t,p);if(!(d===r?Tr(f,c,3,o,p):d))return!1}}return!0}function Rr(e){return!(!tl(e)||(t=e,De&&De in t))&&(Ya(e)?ze:he).test(zi(e));var t}function Mr(e){return"function"==typeof e?e:null==e?ou:"object"==typeof e?Wa(e)?zr(e[0],e[1]):Nr(e):du(e)}function Dr(e){if(!xi(e))return bn(e);var t=[];for(var n in Se(e))Re.call(e,n)&&"constructor"!=n&&t.push(n);return t}function Ir(e,t){return e<t}function Fr(e,t){var n=-1,r=Za(e)?re(e.length):[];return fr(e,(function(e,o,i){r[++n]=t(e,o,i)})),r}function Nr(e){var t=si(e);return 1==t.length&&t[0][2]?Si(t[0][0],t[0][1]):function(n){return n===e||Lr(n,e,t)}}function zr(e,t){return vi(e)&&Oi(t)?Si(Ni(e),t):function(n){var o=Cl(n,e);return o===r&&o===t?El(n,e):Tr(t,o,3)}}function qr(e,t,n,o,i){e!==t&&yr(t,(function(a,l){if(i||(i=new Kn),tl(a))!function(e,t,n,o,i,a,l){var u=Ei(e,n),s=Ei(t,n),c=l.get(s);if(c)Jn(e,n,c);else{var f=a?a(u,s,n+"",e,t,l):r,p=f===r;if(p){var d=Wa(s),h=!d&&Qa(s),m=!d&&!h&&cl(s);f=s,d||h||m?Wa(u)?f=u:Ka(u)?f=Eo(u):h?(p=!1,f=xo(s,!0)):m?(p=!1,f=So(s,!0)):f=[]:il(s)||Va(s)?(f=u,Va(u)?f=gl(u):tl(u)&&!Ya(u)||(f=mi(s))):p=!1}p&&(l.set(s,f),i(f,s,o,a,l),l.delete(s)),Jn(e,n,f)}}(e,t,l,n,qr,o,i);else{var u=o?o(Ei(e,l),a,l+"",e,t,i):r;u===r&&(u=a),Jn(e,l,u)}}),Rl)}function $r(e,t){var n=e.length;if(n)return yi(t+=t<0?n:0,n)?e[t]:r}function Br(e,t,n){t=t.length?St(t,(function(e){return Wa(e)?function(t){return xr(t,1===e.length?e[0]:e)}:e})):[ou];var r=-1;t=St(t,Bt(li()));var o=Fr(e,(function(e,n,o){var i=St(t,(function(t){return t(e)}));return{criteria:i,index:++r,value:e}}));return function(e,t){var r=e.length;for(e.sort((function(e,t){return function(e,t,n){for(var r=-1,o=e.criteria,i=t.criteria,a=o.length,l=n.length;++r<a;){var u=ko(o[r],i[r]);if(u)return r>=l?u:u*("desc"==n[r]?-1:1)}return e.index-t.index}(e,t,n)}));r--;)e[r]=e[r].value;return e}(o)}function Ur(e,t,n){for(var r=-1,o=t.length,i={};++r<o;){var a=t[r],l=xr(e,a);n(l,a)&&Xr(i,go(a,e),l)}return i}function Vr(e,t,n,r){var o=r?Rt:Lt,i=-1,a=t.length,l=e;for(e===t&&(t=Eo(t)),n&&(l=St(e,Bt(n)));++i<a;)for(var u=0,s=t[i],c=n?n(s):s;(u=o(l,c,u,r))>-1;)l!==e&&rt.call(l,u,1),rt.call(e,u,1);return e}function Wr(e,t){for(var n=e?t.length:0,r=n-1;n--;){var o=t[n];if(n==r||o!==i){var i=o;yi(o)?rt.call(e,o,1):so(e,o)}}return e}function Hr(e,t){return e+fn(_n()*(t-e+1))}function Zr(e,t){var n="";if(!e||t<1||t>c)return n;do{t%2&&(n+=e),(t=fn(t/2))&&(e+=e)}while(t);return n}function Kr(e,t){return Ti(ki(e,t,ou),e+"")}function Qr(e){return Gn($l(e))}function Gr(e,t){var n=$l(e);return Mi(n,ar(t,0,n.length))}function Xr(e,t,n,o){if(!tl(e))return e;for(var i=-1,a=(t=go(t,e)).length,l=a-1,u=e;null!=u&&++i<a;){var s=Ni(t[i]),c=n;if("__proto__"===s||"constructor"===s||"prototype"===s)return e;if(i!=l){var f=u[s];(c=o?o(f,s,u):r)===r&&(c=tl(f)?f:yi(t[i+1])?[]:{})}er(u,s,c),u=u[s]}return e}var Yr=Pn?function(e,t){return Pn.set(e,t),e}:ou,Jr=st?function(e,t){return st(e,"toString",{configurable:!0,enumerable:!1,value:tu(t),writable:!0})}:ou;function eo(e){return Mi($l(e))}function to(e,t,n){var r=-1,o=e.length;t<0&&(t=-t>o?0:o+t),(n=n>o?o:n)<0&&(n+=o),o=t>n?0:n-t>>>0,t>>>=0;for(var i=re(o);++r<o;)i[r]=e[r+t];return i}function no(e,t){var n;return fr(e,(function(e,r,o){return!(n=t(e,r,o))})),!!n}function ro(e,t,n){var r=0,o=null==e?r:e.length;if("number"==typeof t&&t==t&&o<=2147483647){for(;r<o;){var i=r+o>>>1,a=e[i];null!==a&&!sl(a)&&(n?a<=t:a<t)?r=i+1:o=i}return o}return oo(e,t,ou,n)}function oo(e,t,n,o){var i=0,a=null==e?0:e.length;if(0===a)return 0;for(var l=(t=n(t))!=t,u=null===t,s=sl(t),c=t===r;i<a;){var f=fn((i+a)/2),p=n(e[f]),d=p!==r,h=null===p,m=p==p,b=sl(p);if(l)var y=o||m;else y=c?m&&(o||d):u?m&&d&&(o||!h):s?m&&d&&!h&&(o||!b):!h&&!b&&(o?p<=t:p<t);y?i=f+1:a=f}return gn(a,4294967294)}function io(e,t){for(var n=-1,r=e.length,o=0,i=[];++n<r;){var a=e[n],l=t?t(a):a;if(!n||!$a(l,u)){var u=l;i[o++]=0===a?0:a}}return i}function ao(e){return"number"==typeof e?e:sl(e)?f:+e}function lo(e){if("string"==typeof e)return e;if(Wa(e))return St(e,lo)+"";if(sl(e))return Nn?Nn.call(e):"";var t=e+"";return"0"==t&&1/e==-1/0?"-0":t}function uo(e,t,n){var r=-1,o=xt,i=e.length,a=!0,l=[],u=l;if(n)a=!1,o=Ot;else if(i>=200){var s=t?null:Ko(e);if(s)return tn(s);a=!1,o=Vt,u=new Zn}else u=t?[]:l;e:for(;++r<i;){var c=e[r],f=t?t(c):c;if(c=n||0!==c?c:0,a&&f==f){for(var p=u.length;p--;)if(u[p]===f)continue e;t&&u.push(f),l.push(c)}else o(u,f,n)||(u!==l&&u.push(f),l.push(c))}return l}function so(e,t){return null==(e=ji(e,t=go(t,e)))||delete e[Ni(Xi(t))]}function co(e,t,n,r){return Xr(e,t,n(xr(e,t)),r)}function fo(e,t,n,r){for(var o=e.length,i=r?o:-1;(r?i--:++i<o)&&t(e[i],i,e););return n?to(e,r?0:i,r?i+1:o):to(e,r?i+1:0,r?o:i)}function po(e,t){var n=e;return n instanceof Un&&(n=n.value()),jt(t,(function(e,t){return t.func.apply(t.thisArg,kt([e],t.args))}),n)}function ho(e,t,n){var r=e.length;if(r<2)return r?uo(e[0]):[];for(var o=-1,i=re(r);++o<r;)for(var a=e[o],l=-1;++l<r;)l!=o&&(i[o]=cr(i[o]||a,e[l],t,n));return uo(br(i,1),t,n)}function mo(e,t,n){for(var o=-1,i=e.length,a=t.length,l={};++o<i;){var u=o<a?t[o]:r;n(l,e[o],u)}return l}function bo(e){return Ka(e)?e:[]}function yo(e){return"function"==typeof e?e:ou}function go(e,t){return Wa(e)?e:vi(e,t)?[e]:Fi(vl(e))}var vo=Kr;function wo(e,t,n){var o=e.length;return n=n===r?o:n,!t&&n>=o?e:to(e,t,n)}var _o=Pt||function(e){return ot.clearTimeout(e)};function xo(e,t){if(t)return e.slice();var n=e.length,r=We?We(n):new e.constructor(n);return e.copy(r),r}function Oo(e){var t=new e.constructor(e.byteLength);return new Be(t).set(new Be(e)),t}function So(e,t){var n=t?Oo(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.length)}function ko(e,t){if(e!==t){var n=e!==r,o=null===e,i=e==e,a=sl(e),l=t!==r,u=null===t,s=t==t,c=sl(t);if(!u&&!c&&!a&&e>t||a&&l&&s&&!u&&!c||o&&l&&s||!n&&s||!i)return 1;if(!o&&!a&&!c&&e<t||c&&n&&i&&!o&&!a||u&&n&&i||!l&&i||!s)return-1}return 0}function jo(e,t,n,r){for(var o=-1,i=e.length,a=n.length,l=-1,u=t.length,s=yn(i-a,0),c=re(u+s),f=!r;++l<u;)c[l]=t[l];for(;++o<a;)(f||o<i)&&(c[n[o]]=e[o]);for(;s--;)c[l++]=e[o++];return c}function Co(e,t,n,r){for(var o=-1,i=e.length,a=-1,l=n.length,u=-1,s=t.length,c=yn(i-l,0),f=re(c+s),p=!r;++o<c;)f[o]=e[o];for(var d=o;++u<s;)f[d+u]=t[u];for(;++a<l;)(p||o<i)&&(f[d+n[a]]=e[o++]);return f}function Eo(e,t){var n=-1,r=e.length;for(t||(t=re(r));++n<r;)t[n]=e[n];return t}function Po(e,t,n,o){var i=!n;n||(n={});for(var a=-1,l=t.length;++a<l;){var u=t[a],s=o?o(n[u],e[u],u,n,e):r;s===r&&(s=e[u]),i?or(n,u,s):er(n,u,s)}return n}function Ao(e,t){return function(n,r){var o=Wa(n)?yt:nr,i=t?t():{};return o(n,e,li(r,2),i)}}function To(e){return Kr((function(t,n){var o=-1,i=n.length,a=i>1?n[i-1]:r,l=i>2?n[2]:r;for(a=e.length>3&&"function"==typeof a?(i--,a):r,l&&gi(n[0],n[1],l)&&(a=i<3?r:a,i=1),t=Se(t);++o<i;){var u=n[o];u&&e(t,u,o,a)}return t}))}function Lo(e,t){return function(n,r){if(null==n)return n;if(!Za(n))return e(n,r);for(var o=n.length,i=t?o:-1,a=Se(n);(t?i--:++i<o)&&!1!==r(a[i],i,a););return n}}function Ro(e){return function(t,n,r){for(var o=-1,i=Se(t),a=r(t),l=a.length;l--;){var u=a[e?l:++o];if(!1===n(i[u],u,i))break}return t}}function Mo(e){return function(t){var n=Xt(t=vl(t))?on(t):r,o=n?n[0]:t.charAt(0),i=n?wo(n,1).join(""):t.slice(1);return o[e]()+i}}function Do(e){return function(t){return jt(Yl(Vl(t).replace(Ue,"")),e,"")}}function Io(e){return function(){var t=arguments;switch(t.length){case 0:return new e;case 1:return new e(t[0]);case 2:return new e(t[0],t[1]);case 3:return new e(t[0],t[1],t[2]);case 4:return new e(t[0],t[1],t[2],t[3]);case 5:return new e(t[0],t[1],t[2],t[3],t[4]);case 6:return new e(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new e(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var n=qn(e.prototype),r=e.apply(n,t);return tl(r)?r:n}}function Fo(e){return function(t,n,o){var i=Se(t);if(!Za(t)){var a=li(n,3);t=Ll(t),n=function(e){return a(i[e],e,i)}}var l=e(t,n,o);return l>-1?i[a?t[l]:l]:r}}function No(e){return ti((function(t){var n=t.length,i=n,a=Bn.prototype.thru;for(e&&t.reverse();i--;){var l=t[i];if("function"!=typeof l)throw new Ce(o);if(a&&!u&&"wrapper"==ii(l))var u=new Bn([],!0)}for(i=u?i:n;++i<n;){var s=ii(l=t[i]),c="wrapper"==s?oi(l):r;u=c&&wi(c[0])&&424==c[1]&&!c[4].length&&1==c[9]?u[ii(c[0])].apply(u,c[3]):1==l.length&&wi(l)?u[s]():u.thru(l)}return function(){var e=arguments,r=e[0];if(u&&1==e.length&&Wa(r))return u.plant(r).value();for(var o=0,i=n?t[o].apply(this,e):r;++o<n;)i=t[o].call(this,i);return i}}))}function zo(e,t,n,o,i,a,l,s,c,f){var p=t&u,d=1&t,h=2&t,m=24&t,b=512&t,y=h?r:Io(e);return function r(){for(var u=arguments.length,g=re(u),v=u;v--;)g[v]=arguments[v];if(m)var w=ai(r),_=Zt(g,w);if(o&&(g=jo(g,o,i,m)),a&&(g=Co(g,a,l,m)),u-=_,m&&u<f){var x=en(g,w);return Ho(e,t,zo,r.placeholder,n,g,x,s,c,f-u)}var O=d?n:this,S=h?O[e]:e;return u=g.length,s?g=Ci(g,s):b&&u>1&&g.reverse(),p&&c<u&&(g.length=c),this&&this!==ot&&this instanceof r&&(S=y||Io(S)),S.apply(O,g)}}function qo(e,t){return function(n,r){return function(e,t,n,r){return vr(e,(function(e,o,i){t(r,n(e),o,i)})),r}(n,e,t(r),{})}}function $o(e,t){return function(n,o){var i;if(n===r&&o===r)return t;if(n!==r&&(i=n),o!==r){if(i===r)return o;"string"==typeof n||"string"==typeof o?(n=lo(n),o=lo(o)):(n=ao(n),o=ao(o)),i=e(n,o)}return i}}function Bo(e){return ti((function(t){return t=St(t,Bt(li())),Kr((function(n){var r=this;return e(t,(function(e){return bt(e,r,n)}))}))}))}function Uo(e,t){var n=(t=t===r?" ":lo(t)).length;if(n<2)return n?Zr(t,e):t;var o=Zr(t,cn(e/rn(t)));return Xt(t)?wo(on(o),0,e).join(""):o.slice(0,e)}function Vo(e){return function(t,n,o){return o&&"number"!=typeof o&&gi(t,n,o)&&(n=o=r),t=hl(t),n===r?(n=t,t=0):n=hl(n),function(e,t,n,r){for(var o=-1,i=yn(cn((t-e)/(n||1)),0),a=re(i);i--;)a[r?i:++o]=e,e+=n;return a}(t,n,o=o===r?t<n?1:-1:hl(o),e)}}function Wo(e){return function(t,n){return"string"==typeof t&&"string"==typeof n||(t=yl(t),n=yl(n)),e(t,n)}}function Ho(e,t,n,o,i,a,u,s,c,f){var p=8&t;t|=p?l:64,4&(t&=~(p?64:l))||(t&=-4);var d=[e,t,i,p?a:r,p?u:r,p?r:a,p?r:u,s,c,f],h=n.apply(r,d);return wi(e)&&Pi(h,d),h.placeholder=o,Li(h,e,t)}function Zo(e){var t=Oe[e];return function(e,n){if(e=yl(e),(n=null==n?0:gn(ml(n),292))&&hn(e)){var r=(vl(e)+"e").split("e");return+((r=(vl(t(r[0]+"e"+(+r[1]+n)))+"e").split("e"))[0]+"e"+(+r[1]-n))}return t(e)}}var Ko=jn&&1/tn(new jn([,-0]))[1]==s?function(e){return new jn(e)}:su;function Qo(e){return function(t){var n=di(t);return n==_?Yt(t):n==j?nn(t):function(e,t){return St(t,(function(t){return[t,e[t]]}))}(t,e(t))}}function Go(e,t,n,i,s,c,f,p){var d=2&t;if(!d&&"function"!=typeof e)throw new Ce(o);var h=i?i.length:0;if(h||(t&=-97,i=s=r),f=f===r?f:yn(ml(f),0),p=p===r?p:ml(p),h-=s?s.length:0,64&t){var m=i,b=s;i=s=r}var y=d?r:oi(e),g=[e,t,n,i,s,m,b,c,f,p];if(y&&function(e,t){var n=e[1],r=t[1],o=n|r,i=o<131,l=r==u&&8==n||r==u&&256==n&&e[7].length<=t[8]||384==r&&t[7].length<=t[8]&&8==n;if(!i&&!l)return e;1&r&&(e[2]=t[2],o|=1&n?0:4);var s=t[3];if(s){var c=e[3];e[3]=c?jo(c,s,t[4]):s,e[4]=c?en(e[3],a):t[4]}(s=t[5])&&(c=e[5],e[5]=c?Co(c,s,t[6]):s,e[6]=c?en(e[5],a):t[6]),(s=t[7])&&(e[7]=s),r&u&&(e[8]=null==e[8]?t[8]:gn(e[8],t[8])),null==e[9]&&(e[9]=t[9]),e[0]=t[0],e[1]=o}(g,y),e=g[0],t=g[1],n=g[2],i=g[3],s=g[4],!(p=g[9]=g[9]===r?d?0:e.length:yn(g[9]-h,0))&&24&t&&(t&=-25),t&&1!=t)v=8==t||16==t?function(e,t,n){var o=Io(e);return function i(){for(var a=arguments.length,l=re(a),u=a,s=ai(i);u--;)l[u]=arguments[u];var c=a<3&&l[0]!==s&&l[a-1]!==s?[]:en(l,s);return(a-=c.length)<n?Ho(e,t,zo,i.placeholder,r,l,c,r,r,n-a):bt(this&&this!==ot&&this instanceof i?o:e,this,l)}}(e,t,p):t!=l&&33!=t||s.length?zo.apply(r,g):function(e,t,n,r){var o=1&t,i=Io(e);return function t(){for(var a=-1,l=arguments.length,u=-1,s=r.length,c=re(s+l),f=this&&this!==ot&&this instanceof t?i:e;++u<s;)c[u]=r[u];for(;l--;)c[u++]=arguments[++a];return bt(f,o?n:this,c)}}(e,t,n,i);else var v=function(e,t,n){var r=1&t,o=Io(e);return function t(){return(this&&this!==ot&&this instanceof t?o:e).apply(r?n:this,arguments)}}(e,t,n);return Li((y?Yr:Pi)(v,g),e,t)}function Xo(e,t,n,o){return e===r||$a(e,Ae[n])&&!Re.call(o,n)?t:e}function Yo(e,t,n,o,i,a){return tl(e)&&tl(t)&&(a.set(t,e),qr(e,t,r,Yo,a),a.delete(t)),e}function Jo(e){return il(e)?r:e}function ei(e,t,n,o,i,a){var l=1&n,u=e.length,s=t.length;if(u!=s&&!(l&&s>u))return!1;var c=a.get(e),f=a.get(t);if(c&&f)return c==t&&f==e;var p=-1,d=!0,h=2&n?new Zn:r;for(a.set(e,t),a.set(t,e);++p<u;){var m=e[p],b=t[p];if(o)var y=l?o(b,m,p,t,e,a):o(m,b,p,e,t,a);if(y!==r){if(y)continue;d=!1;break}if(h){if(!Et(t,(function(e,t){if(!Vt(h,t)&&(m===e||i(m,e,n,o,a)))return h.push(t)}))){d=!1;break}}else if(m!==b&&!i(m,b,n,o,a)){d=!1;break}}return a.delete(e),a.delete(t),d}function ti(e){return Ti(ki(e,r,Hi),e+"")}function ni(e){return Or(e,Ll,fi)}function ri(e){return Or(e,Rl,pi)}var oi=Pn?function(e){return Pn.get(e)}:su;function ii(e){for(var t=e.name+"",n=An[t],r=Re.call(An,t)?n.length:0;r--;){var o=n[r],i=o.func;if(null==i||i==e)return o.name}return t}function ai(e){return(Re.call(zn,"placeholder")?zn:e).placeholder}function li(){var e=zn.iteratee||iu;return e=e===iu?Mr:e,arguments.length?e(arguments[0],arguments[1]):e}function ui(e,t){var n,r,o=e.__data__;return("string"==(r=typeof(n=t))||"number"==r||"symbol"==r||"boolean"==r?"__proto__"!==n:null===n)?o["string"==typeof t?"string":"hash"]:o.map}function si(e){for(var t=Ll(e),n=t.length;n--;){var r=t[n],o=e[r];t[n]=[r,o,Oi(o)]}return t}function ci(e,t){var n=function(e,t){return null==e?r:e[t]}(e,t);return Rr(n)?n:r}var fi=pn?function(e){return null==e?[]:(e=Se(e),_t(pn(e),(function(t){return nt.call(e,t)})))}:bu,pi=pn?function(e){for(var t=[];e;)kt(t,fi(e)),e=Ze(e);return t}:bu,di=Sr;function hi(e,t,n){for(var r=-1,o=(t=go(t,e)).length,i=!1;++r<o;){var a=Ni(t[r]);if(!(i=null!=e&&n(e,a)))break;e=e[a]}return i||++r!=o?i:!!(o=null==e?0:e.length)&&el(o)&&yi(a,o)&&(Wa(e)||Va(e))}function mi(e){return"function"!=typeof e.constructor||xi(e)?{}:qn(Ze(e))}function bi(e){return Wa(e)||Va(e)||!!(it&&e&&e[it])}function yi(e,t){var n=typeof e;return!!(t=null==t?c:t)&&("number"==n||"symbol"!=n&&be.test(e))&&e>-1&&e%1==0&&e<t}function gi(e,t,n){if(!tl(n))return!1;var r=typeof t;return!!("number"==r?Za(n)&&yi(t,n.length):"string"==r&&t in n)&&$a(n[t],e)}function vi(e,t){if(Wa(e))return!1;var n=typeof e;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=e&&!sl(e))||Y.test(e)||!X.test(e)||null!=t&&e in Se(t)}function wi(e){var t=ii(e),n=zn[t];if("function"!=typeof n||!(t in Un.prototype))return!1;if(e===n)return!0;var r=oi(n);return!!r&&e===r[0]}(On&&di(new On(new ArrayBuffer(1)))!=T||Sn&&di(new Sn)!=_||kn&&di(kn.resolve())!=S||jn&&di(new jn)!=j||Cn&&di(new Cn)!=P)&&(di=function(e){var t=Sr(e),n=t==O?e.constructor:r,o=n?zi(n):"";if(o)switch(o){case Tn:return T;case Ln:return _;case Rn:return S;case Mn:return j;case Dn:return P}return t});var _i=Te?Ya:yu;function xi(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||Ae)}function Oi(e){return e==e&&!tl(e)}function Si(e,t){return function(n){return null!=n&&n[e]===t&&(t!==r||e in Se(n))}}function ki(e,t,n){return t=yn(t===r?e.length-1:t,0),function(){for(var r=arguments,o=-1,i=yn(r.length-t,0),a=re(i);++o<i;)a[o]=r[t+o];o=-1;for(var l=re(t+1);++o<t;)l[o]=r[o];return l[t]=n(a),bt(e,this,l)}}function ji(e,t){return t.length<2?e:xr(e,to(t,0,-1))}function Ci(e,t){for(var n=e.length,o=gn(t.length,n),i=Eo(e);o--;){var a=t[o];e[o]=yi(a,n)?i[a]:r}return e}function Ei(e,t){if(("constructor"!==t||"function"!=typeof e[t])&&"__proto__"!=t)return e[t]}var Pi=Ri(Yr),Ai=sn||function(e,t){return ot.setTimeout(e,t)},Ti=Ri(Jr);function Li(e,t,n){var r=t+"";return Ti(e,function(e,t){var n=t.length;if(!n)return e;var r=n-1;return t[r]=(n>1?"& ":"")+t[r],t=t.join(n>2?", ":" "),e.replace(oe,"{\n/* [wrapped with "+t+"] */\n")}(r,function(e,t){return gt(d,(function(n){var r="_."+n[0];t&n[1]&&!xt(e,r)&&e.push(r)})),e.sort()}(function(e){var t=e.match(ie);return t?t[1].split(ae):[]}(r),n)))}function Ri(e){var t=0,n=0;return function(){var o=vn(),i=16-(o-n);if(n=o,i>0){if(++t>=800)return arguments[0]}else t=0;return e.apply(r,arguments)}}function Mi(e,t){var n=-1,o=e.length,i=o-1;for(t=t===r?o:t;++n<t;){var a=Hr(n,i),l=e[a];e[a]=e[n],e[n]=l}return e.length=t,e}var Di,Ii,Fi=(Di=Da((function(e){var t=[];return 46===e.charCodeAt(0)&&t.push(""),e.replace(J,(function(e,n,r,o){t.push(r?o.replace(se,"$1"):n||e)})),t}),(function(e){return 500===Ii.size&&Ii.clear(),e})),Ii=Di.cache,Di);function Ni(e){if("string"==typeof e||sl(e))return e;var t=e+"";return"0"==t&&1/e==-1/0?"-0":t}function zi(e){if(null!=e){try{return Le.call(e)}catch(e){}try{return e+""}catch(e){}}return""}function qi(e){if(e instanceof Un)return e.clone();var t=new Bn(e.__wrapped__,e.__chain__);return t.__actions__=Eo(e.__actions__),t.__index__=e.__index__,t.__values__=e.__values__,t}var $i=Kr((function(e,t){return Ka(e)?cr(e,br(t,1,Ka,!0)):[]})),Bi=Kr((function(e,t){var n=Xi(t);return Ka(n)&&(n=r),Ka(e)?cr(e,br(t,1,Ka,!0),li(n,2)):[]})),Ui=Kr((function(e,t){var n=Xi(t);return Ka(n)&&(n=r),Ka(e)?cr(e,br(t,1,Ka,!0),r,n):[]}));function Vi(e,t,n){var r=null==e?0:e.length;if(!r)return-1;var o=null==n?0:ml(n);return o<0&&(o=yn(r+o,0)),Tt(e,li(t,3),o)}function Wi(e,t,n){var o=null==e?0:e.length;if(!o)return-1;var i=o-1;return n!==r&&(i=ml(n),i=n<0?yn(o+i,0):gn(i,o-1)),Tt(e,li(t,3),i,!0)}function Hi(e){return null!=e&&e.length?br(e,1):[]}function Zi(e){return e&&e.length?e[0]:r}var Ki=Kr((function(e){var t=St(e,bo);return t.length&&t[0]===e[0]?Er(t):[]})),Qi=Kr((function(e){var t=Xi(e),n=St(e,bo);return t===Xi(n)?t=r:n.pop(),n.length&&n[0]===e[0]?Er(n,li(t,2)):[]})),Gi=Kr((function(e){var t=Xi(e),n=St(e,bo);return(t="function"==typeof t?t:r)&&n.pop(),n.length&&n[0]===e[0]?Er(n,r,t):[]}));function Xi(e){var t=null==e?0:e.length;return t?e[t-1]:r}var Yi=Kr(Ji);function Ji(e,t){return e&&e.length&&t&&t.length?Vr(e,t):e}var ea=ti((function(e,t){var n=null==e?0:e.length,r=ir(e,t);return Wr(e,St(t,(function(e){return yi(e,n)?+e:e})).sort(ko)),r}));function ta(e){return null==e?e:xn.call(e)}var na=Kr((function(e){return uo(br(e,1,Ka,!0))})),ra=Kr((function(e){var t=Xi(e);return Ka(t)&&(t=r),uo(br(e,1,Ka,!0),li(t,2))})),oa=Kr((function(e){var t=Xi(e);return t="function"==typeof t?t:r,uo(br(e,1,Ka,!0),r,t)}));function ia(e){if(!e||!e.length)return[];var t=0;return e=_t(e,(function(e){if(Ka(e))return t=yn(e.length,t),!0})),qt(t,(function(t){return St(e,It(t))}))}function aa(e,t){if(!e||!e.length)return[];var n=ia(e);return null==t?n:St(n,(function(e){return bt(t,r,e)}))}var la=Kr((function(e,t){return Ka(e)?cr(e,t):[]})),ua=Kr((function(e){return ho(_t(e,Ka))})),sa=Kr((function(e){var t=Xi(e);return Ka(t)&&(t=r),ho(_t(e,Ka),li(t,2))})),ca=Kr((function(e){var t=Xi(e);return t="function"==typeof t?t:r,ho(_t(e,Ka),r,t)})),fa=Kr(ia),pa=Kr((function(e){var t=e.length,n=t>1?e[t-1]:r;return n="function"==typeof n?(e.pop(),n):r,aa(e,n)}));function da(e){var t=zn(e);return t.__chain__=!0,t}function ha(e,t){return t(e)}var ma=ti((function(e){var t=e.length,n=t?e[0]:0,o=this.__wrapped__,i=function(t){return ir(t,e)};return!(t>1||this.__actions__.length)&&o instanceof Un&&yi(n)?((o=o.slice(n,+n+(t?1:0))).__actions__.push({func:ha,args:[i],thisArg:r}),new Bn(o,this.__chain__).thru((function(e){return t&&!e.length&&e.push(r),e}))):this.thru(i)})),ba=Ao((function(e,t,n){Re.call(e,n)?++e[n]:or(e,n,1)})),ya=Fo(Vi),ga=Fo(Wi);function va(e,t){return(Wa(e)?gt:fr)(e,li(t,3))}function wa(e,t){return(Wa(e)?vt:pr)(e,li(t,3))}var _a=Ao((function(e,t,n){Re.call(e,n)?e[n].push(t):or(e,n,[t])})),xa=Kr((function(e,t,n){var r=-1,o="function"==typeof t,i=Za(e)?re(e.length):[];return fr(e,(function(e){i[++r]=o?bt(t,e,n):Pr(e,t,n)})),i})),Oa=Ao((function(e,t,n){or(e,n,t)}));function Sa(e,t){return(Wa(e)?St:Fr)(e,li(t,3))}var ka=Ao((function(e,t,n){e[n?0:1].push(t)}),(function(){return[[],[]]})),ja=Kr((function(e,t){if(null==e)return[];var n=t.length;return n>1&&gi(e,t[0],t[1])?t=[]:n>2&&gi(t[0],t[1],t[2])&&(t=[t[0]]),Br(e,br(t,1),[])})),Ca=Ft||function(){return ot.Date.now()};function Ea(e,t,n){return t=n?r:t,t=e&&null==t?e.length:t,Go(e,u,r,r,r,r,t)}function Pa(e,t){var n;if("function"!=typeof t)throw new Ce(o);return e=ml(e),function(){return--e>0&&(n=t.apply(this,arguments)),e<=1&&(t=r),n}}var Aa=Kr((function(e,t,n){var r=1;if(n.length){var o=en(n,ai(Aa));r|=l}return Go(e,r,t,n,o)})),Ta=Kr((function(e,t,n){var r=3;if(n.length){var o=en(n,ai(Ta));r|=l}return Go(t,r,e,n,o)}));function La(e,t,n){var i,a,l,u,s,c,f=0,p=!1,d=!1,h=!0;if("function"!=typeof e)throw new Ce(o);function m(t){var n=i,o=a;return i=a=r,f=t,u=e.apply(o,n)}function b(e){return f=e,s=Ai(g,t),p?m(e):u}function y(e){var n=e-c;return c===r||n>=t||n<0||d&&e-f>=l}function g(){var e=Ca();if(y(e))return v(e);s=Ai(g,function(e){var n=t-(e-c);return d?gn(n,l-(e-f)):n}(e))}function v(e){return s=r,h&&i?m(e):(i=a=r,u)}function w(){var e=Ca(),n=y(e);if(i=arguments,a=this,c=e,n){if(s===r)return b(c);if(d)return _o(s),s=Ai(g,t),m(c)}return s===r&&(s=Ai(g,t)),u}return t=yl(t)||0,tl(n)&&(p=!!n.leading,l=(d="maxWait"in n)?yn(yl(n.maxWait)||0,t):l,h="trailing"in n?!!n.trailing:h),w.cancel=function(){s!==r&&_o(s),f=0,i=c=a=s=r},w.flush=function(){return s===r?u:v(Ca())},w}var Ra=Kr((function(e,t){return sr(e,1,t)})),Ma=Kr((function(e,t,n){return sr(e,yl(t)||0,n)}));function Da(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new Ce(o);var n=function(){var r=arguments,o=t?t.apply(this,r):r[0],i=n.cache;if(i.has(o))return i.get(o);var a=e.apply(this,r);return n.cache=i.set(o,a)||i,a};return n.cache=new(Da.Cache||Hn),n}function Ia(e){if("function"!=typeof e)throw new Ce(o);return function(){var t=arguments;switch(t.length){case 0:return!e.call(this);case 1:return!e.call(this,t[0]);case 2:return!e.call(this,t[0],t[1]);case 3:return!e.call(this,t[0],t[1],t[2])}return!e.apply(this,t)}}Da.Cache=Hn;var Fa=vo((function(e,t){var n=(t=1==t.length&&Wa(t[0])?St(t[0],Bt(li())):St(br(t,1),Bt(li()))).length;return Kr((function(r){for(var o=-1,i=gn(r.length,n);++o<i;)r[o]=t[o].call(this,r[o]);return bt(e,this,r)}))})),Na=Kr((function(e,t){var n=en(t,ai(Na));return Go(e,l,r,t,n)})),za=Kr((function(e,t){var n=en(t,ai(za));return Go(e,64,r,t,n)})),qa=ti((function(e,t){return Go(e,256,r,r,r,t)}));function $a(e,t){return e===t||e!=e&&t!=t}var Ba=Wo(kr),Ua=Wo((function(e,t){return e>=t})),Va=Ar(function(){return arguments}())?Ar:function(e){return nl(e)&&Re.call(e,"callee")&&!nt.call(e,"callee")},Wa=re.isArray,Ha=ct?Bt(ct):function(e){return nl(e)&&Sr(e)==A};function Za(e){return null!=e&&el(e.length)&&!Ya(e)}function Ka(e){return nl(e)&&Za(e)}var Qa=dn||yu,Ga=ft?Bt(ft):function(e){return nl(e)&&Sr(e)==y};function Xa(e){if(!nl(e))return!1;var t=Sr(e);return t==g||"[object DOMException]"==t||"string"==typeof e.message&&"string"==typeof e.name&&!il(e)}function Ya(e){if(!tl(e))return!1;var t=Sr(e);return t==v||t==w||"[object AsyncFunction]"==t||"[object Proxy]"==t}function Ja(e){return"number"==typeof e&&e==ml(e)}function el(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=c}function tl(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}function nl(e){return null!=e&&"object"==typeof e}var rl=pt?Bt(pt):function(e){return nl(e)&&di(e)==_};function ol(e){return"number"==typeof e||nl(e)&&Sr(e)==x}function il(e){if(!nl(e)||Sr(e)!=O)return!1;var t=Ze(e);if(null===t)return!0;var n=Re.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&Le.call(n)==Fe}var al=dt?Bt(dt):function(e){return nl(e)&&Sr(e)==k},ll=ht?Bt(ht):function(e){return nl(e)&&di(e)==j};function ul(e){return"string"==typeof e||!Wa(e)&&nl(e)&&Sr(e)==C}function sl(e){return"symbol"==typeof e||nl(e)&&Sr(e)==E}var cl=mt?Bt(mt):function(e){return nl(e)&&el(e.length)&&!!Xe[Sr(e)]},fl=Wo(Ir),pl=Wo((function(e,t){return e<=t}));function dl(e){if(!e)return[];if(Za(e))return ul(e)?on(e):Eo(e);if(at&&e[at])return function(e){for(var t,n=[];!(t=e.next()).done;)n.push(t.value);return n}(e[at]());var t=di(e);return(t==_?Yt:t==j?tn:$l)(e)}function hl(e){return e?(e=yl(e))===s||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}function ml(e){var t=hl(e),n=t%1;return t==t?n?t-n:t:0}function bl(e){return e?ar(ml(e),0,p):0}function yl(e){if("number"==typeof e)return e;if(sl(e))return f;if(tl(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=tl(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=$t(e);var n=de.test(e);return n||me.test(e)?tt(e.slice(2),n?2:8):pe.test(e)?f:+e}function gl(e){return Po(e,Rl(e))}function vl(e){return null==e?"":lo(e)}var wl=To((function(e,t){if(xi(t)||Za(t))Po(t,Ll(t),e);else for(var n in t)Re.call(t,n)&&er(e,n,t[n])})),_l=To((function(e,t){Po(t,Rl(t),e)})),xl=To((function(e,t,n,r){Po(t,Rl(t),e,r)})),Ol=To((function(e,t,n,r){Po(t,Ll(t),e,r)})),Sl=ti(ir),kl=Kr((function(e,t){e=Se(e);var n=-1,o=t.length,i=o>2?t[2]:r;for(i&&gi(t[0],t[1],i)&&(o=1);++n<o;)for(var a=t[n],l=Rl(a),u=-1,s=l.length;++u<s;){var c=l[u],f=e[c];(f===r||$a(f,Ae[c])&&!Re.call(e,c))&&(e[c]=a[c])}return e})),jl=Kr((function(e){return e.push(r,Yo),bt(Dl,r,e)}));function Cl(e,t,n){var o=null==e?r:xr(e,t);return o===r?n:o}function El(e,t){return null!=e&&hi(e,t,Cr)}var Pl=qo((function(e,t,n){null!=t&&"function"!=typeof t.toString&&(t=Ie.call(t)),e[t]=n}),tu(ou)),Al=qo((function(e,t,n){null!=t&&"function"!=typeof t.toString&&(t=Ie.call(t)),Re.call(e,t)?e[t].push(n):e[t]=[n]}),li),Tl=Kr(Pr);function Ll(e){return Za(e)?Qn(e):Dr(e)}function Rl(e){return Za(e)?Qn(e,!0):function(e){if(!tl(e))return function(e){var t=[];if(null!=e)for(var n in Se(e))t.push(n);return t}(e);var t=xi(e),n=[];for(var r in e)("constructor"!=r||!t&&Re.call(e,r))&&n.push(r);return n}(e)}var Ml=To((function(e,t,n){qr(e,t,n)})),Dl=To((function(e,t,n,r){qr(e,t,n,r)})),Il=ti((function(e,t){var n={};if(null==e)return n;var r=!1;t=St(t,(function(t){return t=go(t,e),r||(r=t.length>1),t})),Po(e,ri(e),n),r&&(n=lr(n,7,Jo));for(var o=t.length;o--;)so(n,t[o]);return n})),Fl=ti((function(e,t){return null==e?{}:function(e,t){return Ur(e,t,(function(t,n){return El(e,n)}))}(e,t)}));function Nl(e,t){if(null==e)return{};var n=St(ri(e),(function(e){return[e]}));return t=li(t),Ur(e,n,(function(e,n){return t(e,n[0])}))}var zl=Qo(Ll),ql=Qo(Rl);function $l(e){return null==e?[]:Ut(e,Ll(e))}var Bl=Do((function(e,t,n){return t=t.toLowerCase(),e+(n?Ul(t):t)}));function Ul(e){return Xl(vl(e).toLowerCase())}function Vl(e){return(e=vl(e))&&e.replace(ye,Kt).replace(Ve,"")}var Wl=Do((function(e,t,n){return e+(n?"-":"")+t.toLowerCase()})),Hl=Do((function(e,t,n){return e+(n?" ":"")+t.toLowerCase()})),Zl=Mo("toLowerCase"),Kl=Do((function(e,t,n){return e+(n?"_":"")+t.toLowerCase()})),Ql=Do((function(e,t,n){return e+(n?" ":"")+Xl(t)})),Gl=Do((function(e,t,n){return e+(n?" ":"")+t.toUpperCase()})),Xl=Mo("toUpperCase");function Yl(e,t,n){return e=vl(e),(t=n?r:t)===r?function(e){return Ke.test(e)}(e)?function(e){return e.match(He)||[]}(e):function(e){return e.match(le)||[]}(e):e.match(t)||[]}var Jl=Kr((function(e,t){try{return bt(e,r,t)}catch(e){return Xa(e)?e:new _e(e)}})),eu=ti((function(e,t){return gt(t,(function(t){t=Ni(t),or(e,t,Aa(e[t],e))})),e}));function tu(e){return function(){return e}}var nu=No(),ru=No(!0);function ou(e){return e}function iu(e){return Mr("function"==typeof e?e:lr(e,1))}var au=Kr((function(e,t){return function(n){return Pr(n,e,t)}})),lu=Kr((function(e,t){return function(n){return Pr(e,n,t)}}));function uu(e,t,n){var r=Ll(t),o=_r(t,r);null!=n||tl(t)&&(o.length||!r.length)||(n=t,t=e,e=this,o=_r(t,Ll(t)));var i=!(tl(n)&&"chain"in n&&!n.chain),a=Ya(e);return gt(o,(function(n){var r=t[n];e[n]=r,a&&(e.prototype[n]=function(){var t=this.__chain__;if(i||t){var n=e(this.__wrapped__),o=n.__actions__=Eo(this.__actions__);return o.push({func:r,args:arguments,thisArg:e}),n.__chain__=t,n}return r.apply(e,kt([this.value()],arguments))})})),e}function su(){}var cu=Bo(St),fu=Bo(wt),pu=Bo(Et);function du(e){return vi(e)?It(Ni(e)):function(e){return function(t){return xr(t,e)}}(e)}var hu=Vo(),mu=Vo(!0);function bu(){return[]}function yu(){return!1}var gu,vu=$o((function(e,t){return e+t}),0),wu=Zo("ceil"),_u=$o((function(e,t){return e/t}),1),xu=Zo("floor"),Ou=$o((function(e,t){return e*t}),1),Su=Zo("round"),ku=$o((function(e,t){return e-t}),0);return zn.after=function(e,t){if("function"!=typeof t)throw new Ce(o);return e=ml(e),function(){if(--e<1)return t.apply(this,arguments)}},zn.ary=Ea,zn.assign=wl,zn.assignIn=_l,zn.assignInWith=xl,zn.assignWith=Ol,zn.at=Sl,zn.before=Pa,zn.bind=Aa,zn.bindAll=eu,zn.bindKey=Ta,zn.castArray=function(){if(!arguments.length)return[];var e=arguments[0];return Wa(e)?e:[e]},zn.chain=da,zn.chunk=function(e,t,n){t=(n?gi(e,t,n):t===r)?1:yn(ml(t),0);var o=null==e?0:e.length;if(!o||t<1)return[];for(var i=0,a=0,l=re(cn(o/t));i<o;)l[a++]=to(e,i,i+=t);return l},zn.compact=function(e){for(var t=-1,n=null==e?0:e.length,r=0,o=[];++t<n;){var i=e[t];i&&(o[r++]=i)}return o},zn.concat=function(){var e=arguments.length;if(!e)return[];for(var t=re(e-1),n=arguments[0],r=e;r--;)t[r-1]=arguments[r];return kt(Wa(n)?Eo(n):[n],br(t,1))},zn.cond=function(e){var t=null==e?0:e.length,n=li();return e=t?St(e,(function(e){if("function"!=typeof e[1])throw new Ce(o);return[n(e[0]),e[1]]})):[],Kr((function(n){for(var r=-1;++r<t;){var o=e[r];if(bt(o[0],this,n))return bt(o[1],this,n)}}))},zn.conforms=function(e){return function(e){var t=Ll(e);return function(n){return ur(n,e,t)}}(lr(e,1))},zn.constant=tu,zn.countBy=ba,zn.create=function(e,t){var n=qn(e);return null==t?n:rr(n,t)},zn.curry=function e(t,n,o){var i=Go(t,8,r,r,r,r,r,n=o?r:n);return i.placeholder=e.placeholder,i},zn.curryRight=function e(t,n,o){var i=Go(t,16,r,r,r,r,r,n=o?r:n);return i.placeholder=e.placeholder,i},zn.debounce=La,zn.defaults=kl,zn.defaultsDeep=jl,zn.defer=Ra,zn.delay=Ma,zn.difference=$i,zn.differenceBy=Bi,zn.differenceWith=Ui,zn.drop=function(e,t,n){var o=null==e?0:e.length;return o?to(e,(t=n||t===r?1:ml(t))<0?0:t,o):[]},zn.dropRight=function(e,t,n){var o=null==e?0:e.length;return o?to(e,0,(t=o-(t=n||t===r?1:ml(t)))<0?0:t):[]},zn.dropRightWhile=function(e,t){return e&&e.length?fo(e,li(t,3),!0,!0):[]},zn.dropWhile=function(e,t){return e&&e.length?fo(e,li(t,3),!0):[]},zn.fill=function(e,t,n,o){var i=null==e?0:e.length;return i?(n&&"number"!=typeof n&&gi(e,t,n)&&(n=0,o=i),function(e,t,n,o){var i=e.length;for((n=ml(n))<0&&(n=-n>i?0:i+n),(o=o===r||o>i?i:ml(o))<0&&(o+=i),o=n>o?0:bl(o);n<o;)e[n++]=t;return e}(e,t,n,o)):[]},zn.filter=function(e,t){return(Wa(e)?_t:mr)(e,li(t,3))},zn.flatMap=function(e,t){return br(Sa(e,t),1)},zn.flatMapDeep=function(e,t){return br(Sa(e,t),s)},zn.flatMapDepth=function(e,t,n){return n=n===r?1:ml(n),br(Sa(e,t),n)},zn.flatten=Hi,zn.flattenDeep=function(e){return null!=e&&e.length?br(e,s):[]},zn.flattenDepth=function(e,t){return null!=e&&e.length?br(e,t=t===r?1:ml(t)):[]},zn.flip=function(e){return Go(e,512)},zn.flow=nu,zn.flowRight=ru,zn.fromPairs=function(e){for(var t=-1,n=null==e?0:e.length,r={};++t<n;){var o=e[t];r[o[0]]=o[1]}return r},zn.functions=function(e){return null==e?[]:_r(e,Ll(e))},zn.functionsIn=function(e){return null==e?[]:_r(e,Rl(e))},zn.groupBy=_a,zn.initial=function(e){return null!=e&&e.length?to(e,0,-1):[]},zn.intersection=Ki,zn.intersectionBy=Qi,zn.intersectionWith=Gi,zn.invert=Pl,zn.invertBy=Al,zn.invokeMap=xa,zn.iteratee=iu,zn.keyBy=Oa,zn.keys=Ll,zn.keysIn=Rl,zn.map=Sa,zn.mapKeys=function(e,t){var n={};return t=li(t,3),vr(e,(function(e,r,o){or(n,t(e,r,o),e)})),n},zn.mapValues=function(e,t){var n={};return t=li(t,3),vr(e,(function(e,r,o){or(n,r,t(e,r,o))})),n},zn.matches=function(e){return Nr(lr(e,1))},zn.matchesProperty=function(e,t){return zr(e,lr(t,1))},zn.memoize=Da,zn.merge=Ml,zn.mergeWith=Dl,zn.method=au,zn.methodOf=lu,zn.mixin=uu,zn.negate=Ia,zn.nthArg=function(e){return e=ml(e),Kr((function(t){return $r(t,e)}))},zn.omit=Il,zn.omitBy=function(e,t){return Nl(e,Ia(li(t)))},zn.once=function(e){return Pa(2,e)},zn.orderBy=function(e,t,n,o){return null==e?[]:(Wa(t)||(t=null==t?[]:[t]),Wa(n=o?r:n)||(n=null==n?[]:[n]),Br(e,t,n))},zn.over=cu,zn.overArgs=Fa,zn.overEvery=fu,zn.overSome=pu,zn.partial=Na,zn.partialRight=za,zn.partition=ka,zn.pick=Fl,zn.pickBy=Nl,zn.property=du,zn.propertyOf=function(e){return function(t){return null==e?r:xr(e,t)}},zn.pull=Yi,zn.pullAll=Ji,zn.pullAllBy=function(e,t,n){return e&&e.length&&t&&t.length?Vr(e,t,li(n,2)):e},zn.pullAllWith=function(e,t,n){return e&&e.length&&t&&t.length?Vr(e,t,r,n):e},zn.pullAt=ea,zn.range=hu,zn.rangeRight=mu,zn.rearg=qa,zn.reject=function(e,t){return(Wa(e)?_t:mr)(e,Ia(li(t,3)))},zn.remove=function(e,t){var n=[];if(!e||!e.length)return n;var r=-1,o=[],i=e.length;for(t=li(t,3);++r<i;){var a=e[r];t(a,r,e)&&(n.push(a),o.push(r))}return Wr(e,o),n},zn.rest=function(e,t){if("function"!=typeof e)throw new Ce(o);return Kr(e,t=t===r?t:ml(t))},zn.reverse=ta,zn.sampleSize=function(e,t,n){return t=(n?gi(e,t,n):t===r)?1:ml(t),(Wa(e)?Xn:Gr)(e,t)},zn.set=function(e,t,n){return null==e?e:Xr(e,t,n)},zn.setWith=function(e,t,n,o){return o="function"==typeof o?o:r,null==e?e:Xr(e,t,n,o)},zn.shuffle=function(e){return(Wa(e)?Yn:eo)(e)},zn.slice=function(e,t,n){var o=null==e?0:e.length;return o?(n&&"number"!=typeof n&&gi(e,t,n)?(t=0,n=o):(t=null==t?0:ml(t),n=n===r?o:ml(n)),to(e,t,n)):[]},zn.sortBy=ja,zn.sortedUniq=function(e){return e&&e.length?io(e):[]},zn.sortedUniqBy=function(e,t){return e&&e.length?io(e,li(t,2)):[]},zn.split=function(e,t,n){return n&&"number"!=typeof n&&gi(e,t,n)&&(t=n=r),(n=n===r?p:n>>>0)?(e=vl(e))&&("string"==typeof t||null!=t&&!al(t))&&!(t=lo(t))&&Xt(e)?wo(on(e),0,n):e.split(t,n):[]},zn.spread=function(e,t){if("function"!=typeof e)throw new Ce(o);return t=null==t?0:yn(ml(t),0),Kr((function(n){var r=n[t],o=wo(n,0,t);return r&&kt(o,r),bt(e,this,o)}))},zn.tail=function(e){var t=null==e?0:e.length;return t?to(e,1,t):[]},zn.take=function(e,t,n){return e&&e.length?to(e,0,(t=n||t===r?1:ml(t))<0?0:t):[]},zn.takeRight=function(e,t,n){var o=null==e?0:e.length;return o?to(e,(t=o-(t=n||t===r?1:ml(t)))<0?0:t,o):[]},zn.takeRightWhile=function(e,t){return e&&e.length?fo(e,li(t,3),!1,!0):[]},zn.takeWhile=function(e,t){return e&&e.length?fo(e,li(t,3)):[]},zn.tap=function(e,t){return t(e),e},zn.throttle=function(e,t,n){var r=!0,i=!0;if("function"!=typeof e)throw new Ce(o);return tl(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),La(e,t,{leading:r,maxWait:t,trailing:i})},zn.thru=ha,zn.toArray=dl,zn.toPairs=zl,zn.toPairsIn=ql,zn.toPath=function(e){return Wa(e)?St(e,Ni):sl(e)?[e]:Eo(Fi(vl(e)))},zn.toPlainObject=gl,zn.transform=function(e,t,n){var r=Wa(e),o=r||Qa(e)||cl(e);if(t=li(t,4),null==n){var i=e&&e.constructor;n=o?r?new i:[]:tl(e)&&Ya(i)?qn(Ze(e)):{}}return(o?gt:vr)(e,(function(e,r,o){return t(n,e,r,o)})),n},zn.unary=function(e){return Ea(e,1)},zn.union=na,zn.unionBy=ra,zn.unionWith=oa,zn.uniq=function(e){return e&&e.length?uo(e):[]},zn.uniqBy=function(e,t){return e&&e.length?uo(e,li(t,2)):[]},zn.uniqWith=function(e,t){return t="function"==typeof t?t:r,e&&e.length?uo(e,r,t):[]},zn.unset=function(e,t){return null==e||so(e,t)},zn.unzip=ia,zn.unzipWith=aa,zn.update=function(e,t,n){return null==e?e:co(e,t,yo(n))},zn.updateWith=function(e,t,n,o){return o="function"==typeof o?o:r,null==e?e:co(e,t,yo(n),o)},zn.values=$l,zn.valuesIn=function(e){return null==e?[]:Ut(e,Rl(e))},zn.without=la,zn.words=Yl,zn.wrap=function(e,t){return Na(yo(t),e)},zn.xor=ua,zn.xorBy=sa,zn.xorWith=ca,zn.zip=fa,zn.zipObject=function(e,t){return mo(e||[],t||[],er)},zn.zipObjectDeep=function(e,t){return mo(e||[],t||[],Xr)},zn.zipWith=pa,zn.entries=zl,zn.entriesIn=ql,zn.extend=_l,zn.extendWith=xl,uu(zn,zn),zn.add=vu,zn.attempt=Jl,zn.camelCase=Bl,zn.capitalize=Ul,zn.ceil=wu,zn.clamp=function(e,t,n){return n===r&&(n=t,t=r),n!==r&&(n=(n=yl(n))==n?n:0),t!==r&&(t=(t=yl(t))==t?t:0),ar(yl(e),t,n)},zn.clone=function(e){return lr(e,4)},zn.cloneDeep=function(e){return lr(e,5)},zn.cloneDeepWith=function(e,t){return lr(e,5,t="function"==typeof t?t:r)},zn.cloneWith=function(e,t){return lr(e,4,t="function"==typeof t?t:r)},zn.conformsTo=function(e,t){return null==t||ur(e,t,Ll(t))},zn.deburr=Vl,zn.defaultTo=function(e,t){return null==e||e!=e?t:e},zn.divide=_u,zn.endsWith=function(e,t,n){e=vl(e),t=lo(t);var o=e.length,i=n=n===r?o:ar(ml(n),0,o);return(n-=t.length)>=0&&e.slice(n,i)==t},zn.eq=$a,zn.escape=function(e){return(e=vl(e))&&Z.test(e)?e.replace(W,Qt):e},zn.escapeRegExp=function(e){return(e=vl(e))&&te.test(e)?e.replace(ee,"\\$&"):e},zn.every=function(e,t,n){var o=Wa(e)?wt:dr;return n&&gi(e,t,n)&&(t=r),o(e,li(t,3))},zn.find=ya,zn.findIndex=Vi,zn.findKey=function(e,t){return At(e,li(t,3),vr)},zn.findLast=ga,zn.findLastIndex=Wi,zn.findLastKey=function(e,t){return At(e,li(t,3),wr)},zn.floor=xu,zn.forEach=va,zn.forEachRight=wa,zn.forIn=function(e,t){return null==e?e:yr(e,li(t,3),Rl)},zn.forInRight=function(e,t){return null==e?e:gr(e,li(t,3),Rl)},zn.forOwn=function(e,t){return e&&vr(e,li(t,3))},zn.forOwnRight=function(e,t){return e&&wr(e,li(t,3))},zn.get=Cl,zn.gt=Ba,zn.gte=Ua,zn.has=function(e,t){return null!=e&&hi(e,t,jr)},zn.hasIn=El,zn.head=Zi,zn.identity=ou,zn.includes=function(e,t,n,r){e=Za(e)?e:$l(e),n=n&&!r?ml(n):0;var o=e.length;return n<0&&(n=yn(o+n,0)),ul(e)?n<=o&&e.indexOf(t,n)>-1:!!o&&Lt(e,t,n)>-1},zn.indexOf=function(e,t,n){var r=null==e?0:e.length;if(!r)return-1;var o=null==n?0:ml(n);return o<0&&(o=yn(r+o,0)),Lt(e,t,o)},zn.inRange=function(e,t,n){return t=hl(t),n===r?(n=t,t=0):n=hl(n),function(e,t,n){return e>=gn(t,n)&&e<yn(t,n)}(e=yl(e),t,n)},zn.invoke=Tl,zn.isArguments=Va,zn.isArray=Wa,zn.isArrayBuffer=Ha,zn.isArrayLike=Za,zn.isArrayLikeObject=Ka,zn.isBoolean=function(e){return!0===e||!1===e||nl(e)&&Sr(e)==b},zn.isBuffer=Qa,zn.isDate=Ga,zn.isElement=function(e){return nl(e)&&1===e.nodeType&&!il(e)},zn.isEmpty=function(e){if(null==e)return!0;if(Za(e)&&(Wa(e)||"string"==typeof e||"function"==typeof e.splice||Qa(e)||cl(e)||Va(e)))return!e.length;var t=di(e);if(t==_||t==j)return!e.size;if(xi(e))return!Dr(e).length;for(var n in e)if(Re.call(e,n))return!1;return!0},zn.isEqual=function(e,t){return Tr(e,t)},zn.isEqualWith=function(e,t,n){var o=(n="function"==typeof n?n:r)?n(e,t):r;return o===r?Tr(e,t,r,n):!!o},zn.isError=Xa,zn.isFinite=function(e){return"number"==typeof e&&hn(e)},zn.isFunction=Ya,zn.isInteger=Ja,zn.isLength=el,zn.isMap=rl,zn.isMatch=function(e,t){return e===t||Lr(e,t,si(t))},zn.isMatchWith=function(e,t,n){return n="function"==typeof n?n:r,Lr(e,t,si(t),n)},zn.isNaN=function(e){return ol(e)&&e!=+e},zn.isNative=function(e){if(_i(e))throw new _e("Unsupported core-js use. Try https://npms.io/search?q=ponyfill.");return Rr(e)},zn.isNil=function(e){return null==e},zn.isNull=function(e){return null===e},zn.isNumber=ol,zn.isObject=tl,zn.isObjectLike=nl,zn.isPlainObject=il,zn.isRegExp=al,zn.isSafeInteger=function(e){return Ja(e)&&e>=-9007199254740991&&e<=c},zn.isSet=ll,zn.isString=ul,zn.isSymbol=sl,zn.isTypedArray=cl,zn.isUndefined=function(e){return e===r},zn.isWeakMap=function(e){return nl(e)&&di(e)==P},zn.isWeakSet=function(e){return nl(e)&&"[object WeakSet]"==Sr(e)},zn.join=function(e,t){return null==e?"":mn.call(e,t)},zn.kebabCase=Wl,zn.last=Xi,zn.lastIndexOf=function(e,t,n){var o=null==e?0:e.length;if(!o)return-1;var i=o;return n!==r&&(i=(i=ml(n))<0?yn(o+i,0):gn(i,o-1)),t==t?function(e,t,n){for(var r=n+1;r--;)if(e[r]===t)return r;return r}(e,t,i):Tt(e,Mt,i,!0)},zn.lowerCase=Hl,zn.lowerFirst=Zl,zn.lt=fl,zn.lte=pl,zn.max=function(e){return e&&e.length?hr(e,ou,kr):r},zn.maxBy=function(e,t){return e&&e.length?hr(e,li(t,2),kr):r},zn.mean=function(e){return Dt(e,ou)},zn.meanBy=function(e,t){return Dt(e,li(t,2))},zn.min=function(e){return e&&e.length?hr(e,ou,Ir):r},zn.minBy=function(e,t){return e&&e.length?hr(e,li(t,2),Ir):r},zn.stubArray=bu,zn.stubFalse=yu,zn.stubObject=function(){return{}},zn.stubString=function(){return""},zn.stubTrue=function(){return!0},zn.multiply=Ou,zn.nth=function(e,t){return e&&e.length?$r(e,ml(t)):r},zn.noConflict=function(){return ot._===this&&(ot._=Ne),this},zn.noop=su,zn.now=Ca,zn.pad=function(e,t,n){e=vl(e);var r=(t=ml(t))?rn(e):0;if(!t||r>=t)return e;var o=(t-r)/2;return Uo(fn(o),n)+e+Uo(cn(o),n)},zn.padEnd=function(e,t,n){e=vl(e);var r=(t=ml(t))?rn(e):0;return t&&r<t?e+Uo(t-r,n):e},zn.padStart=function(e,t,n){e=vl(e);var r=(t=ml(t))?rn(e):0;return t&&r<t?Uo(t-r,n)+e:e},zn.parseInt=function(e,t,n){return n||null==t?t=0:t&&(t=+t),wn(vl(e).replace(ne,""),t||0)},zn.random=function(e,t,n){if(n&&"boolean"!=typeof n&&gi(e,t,n)&&(t=n=r),n===r&&("boolean"==typeof t?(n=t,t=r):"boolean"==typeof e&&(n=e,e=r)),e===r&&t===r?(e=0,t=1):(e=hl(e),t===r?(t=e,e=0):t=hl(t)),e>t){var o=e;e=t,t=o}if(n||e%1||t%1){var i=_n();return gn(e+i*(t-e+et("1e-"+((i+"").length-1))),t)}return Hr(e,t)},zn.reduce=function(e,t,n){var r=Wa(e)?jt:Nt,o=arguments.length<3;return r(e,li(t,4),n,o,fr)},zn.reduceRight=function(e,t,n){var r=Wa(e)?Ct:Nt,o=arguments.length<3;return r(e,li(t,4),n,o,pr)},zn.repeat=function(e,t,n){return t=(n?gi(e,t,n):t===r)?1:ml(t),Zr(vl(e),t)},zn.replace=function(){var e=arguments,t=vl(e[0]);return e.length<3?t:t.replace(e[1],e[2])},zn.result=function(e,t,n){var o=-1,i=(t=go(t,e)).length;for(i||(i=1,e=r);++o<i;){var a=null==e?r:e[Ni(t[o])];a===r&&(o=i,a=n),e=Ya(a)?a.call(e):a}return e},zn.round=Su,zn.runInContext=e,zn.sample=function(e){return(Wa(e)?Gn:Qr)(e)},zn.size=function(e){if(null==e)return 0;if(Za(e))return ul(e)?rn(e):e.length;var t=di(e);return t==_||t==j?e.size:Dr(e).length},zn.snakeCase=Kl,zn.some=function(e,t,n){var o=Wa(e)?Et:no;return n&&gi(e,t,n)&&(t=r),o(e,li(t,3))},zn.sortedIndex=function(e,t){return ro(e,t)},zn.sortedIndexBy=function(e,t,n){return oo(e,t,li(n,2))},zn.sortedIndexOf=function(e,t){var n=null==e?0:e.length;if(n){var r=ro(e,t);if(r<n&&$a(e[r],t))return r}return-1},zn.sortedLastIndex=function(e,t){return ro(e,t,!0)},zn.sortedLastIndexBy=function(e,t,n){return oo(e,t,li(n,2),!0)},zn.sortedLastIndexOf=function(e,t){if(null!=e&&e.length){var n=ro(e,t,!0)-1;if($a(e[n],t))return n}return-1},zn.startCase=Ql,zn.startsWith=function(e,t,n){return e=vl(e),n=null==n?0:ar(ml(n),0,e.length),t=lo(t),e.slice(n,n+t.length)==t},zn.subtract=ku,zn.sum=function(e){return e&&e.length?zt(e,ou):0},zn.sumBy=function(e,t){return e&&e.length?zt(e,li(t,2)):0},zn.template=function(e,t,n){var o=zn.templateSettings;n&&gi(e,t,n)&&(t=r),e=vl(e),t=xl({},t,o,Xo);var i,a,l=xl({},t.imports,o.imports,Xo),u=Ll(l),s=Ut(l,u),c=0,f=t.interpolate||ge,p="__p += '",d=ke((t.escape||ge).source+"|"+f.source+"|"+(f===G?ce:ge).source+"|"+(t.evaluate||ge).source+"|$","g"),h="//# sourceURL="+(Re.call(t,"sourceURL")?(t.sourceURL+"").replace(/\s/g," "):"lodash.templateSources["+ ++Ge+"]")+"\n";e.replace(d,(function(t,n,r,o,l,u){return r||(r=o),p+=e.slice(c,u).replace(ve,Gt),n&&(i=!0,p+="' +\n__e("+n+") +\n'"),l&&(a=!0,p+="';\n"+l+";\n__p += '"),r&&(p+="' +\n((__t = ("+r+")) == null ? '' : __t) +\n'"),c=u+t.length,t})),p+="';\n";var m=Re.call(t,"variable")&&t.variable;if(m){if(ue.test(m))throw new _e("Invalid `variable` option passed into `_.template`")}else p="with (obj) {\n"+p+"\n}\n";p=(a?p.replace($,""):p).replace(B,"$1").replace(U,"$1;"),p="function("+(m||"obj")+") {\n"+(m?"":"obj || (obj = {});\n")+"var __t, __p = ''"+(i?", __e = _.escape":"")+(a?", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n":";\n")+p+"return __p\n}";var b=Jl((function(){return xe(u,h+"return "+p).apply(r,s)}));if(b.source=p,Xa(b))throw b;return b},zn.times=function(e,t){if((e=ml(e))<1||e>c)return[];var n=p,r=gn(e,p);t=li(t),e-=p;for(var o=qt(r,t);++n<e;)t(n);return o},zn.toFinite=hl,zn.toInteger=ml,zn.toLength=bl,zn.toLower=function(e){return vl(e).toLowerCase()},zn.toNumber=yl,zn.toSafeInteger=function(e){return e?ar(ml(e),-9007199254740991,c):0===e?e:0},zn.toString=vl,zn.toUpper=function(e){return vl(e).toUpperCase()},zn.trim=function(e,t,n){if((e=vl(e))&&(n||t===r))return $t(e);if(!e||!(t=lo(t)))return e;var o=on(e),i=on(t);return wo(o,Wt(o,i),Ht(o,i)+1).join("")},zn.trimEnd=function(e,t,n){if((e=vl(e))&&(n||t===r))return e.slice(0,an(e)+1);if(!e||!(t=lo(t)))return e;var o=on(e);return wo(o,0,Ht(o,on(t))+1).join("")},zn.trimStart=function(e,t,n){if((e=vl(e))&&(n||t===r))return e.replace(ne,"");if(!e||!(t=lo(t)))return e;var o=on(e);return wo(o,Wt(o,on(t))).join("")},zn.truncate=function(e,t){var n=30,o="...";if(tl(t)){var i="separator"in t?t.separator:i;n="length"in t?ml(t.length):n,o="omission"in t?lo(t.omission):o}var a=(e=vl(e)).length;if(Xt(e)){var l=on(e);a=l.length}if(n>=a)return e;var u=n-rn(o);if(u<1)return o;var s=l?wo(l,0,u).join(""):e.slice(0,u);if(i===r)return s+o;if(l&&(u+=s.length-u),al(i)){if(e.slice(u).search(i)){var c,f=s;for(i.global||(i=ke(i.source,vl(fe.exec(i))+"g")),i.lastIndex=0;c=i.exec(f);)var p=c.index;s=s.slice(0,p===r?u:p)}}else if(e.indexOf(lo(i),u)!=u){var d=s.lastIndexOf(i);d>-1&&(s=s.slice(0,d))}return s+o},zn.unescape=function(e){return(e=vl(e))&&H.test(e)?e.replace(V,ln):e},zn.uniqueId=function(e){var t=++Me;return vl(e)+t},zn.upperCase=Gl,zn.upperFirst=Xl,zn.each=va,zn.eachRight=wa,zn.first=Zi,uu(zn,(gu={},vr(zn,(function(e,t){Re.call(zn.prototype,t)||(gu[t]=e)})),gu),{chain:!1}),zn.VERSION="4.17.21",gt(["bind","bindKey","curry","curryRight","partial","partialRight"],(function(e){zn[e].placeholder=zn})),gt(["drop","take"],(function(e,t){Un.prototype[e]=function(n){n=n===r?1:yn(ml(n),0);var o=this.__filtered__&&!t?new Un(this):this.clone();return o.__filtered__?o.__takeCount__=gn(n,o.__takeCount__):o.__views__.push({size:gn(n,p),type:e+(o.__dir__<0?"Right":"")}),o},Un.prototype[e+"Right"]=function(t){return this.reverse()[e](t).reverse()}})),gt(["filter","map","takeWhile"],(function(e,t){var n=t+1,r=1==n||3==n;Un.prototype[e]=function(e){var t=this.clone();return t.__iteratees__.push({iteratee:li(e,3),type:n}),t.__filtered__=t.__filtered__||r,t}})),gt(["head","last"],(function(e,t){var n="take"+(t?"Right":"");Un.prototype[e]=function(){return this[n](1).value()[0]}})),gt(["initial","tail"],(function(e,t){var n="drop"+(t?"":"Right");Un.prototype[e]=function(){return this.__filtered__?new Un(this):this[n](1)}})),Un.prototype.compact=function(){return this.filter(ou)},Un.prototype.find=function(e){return this.filter(e).head()},Un.prototype.findLast=function(e){return this.reverse().find(e)},Un.prototype.invokeMap=Kr((function(e,t){return"function"==typeof e?new Un(this):this.map((function(n){return Pr(n,e,t)}))})),Un.prototype.reject=function(e){return this.filter(Ia(li(e)))},Un.prototype.slice=function(e,t){e=ml(e);var n=this;return n.__filtered__&&(e>0||t<0)?new Un(n):(e<0?n=n.takeRight(-e):e&&(n=n.drop(e)),t!==r&&(n=(t=ml(t))<0?n.dropRight(-t):n.take(t-e)),n)},Un.prototype.takeRightWhile=function(e){return this.reverse().takeWhile(e).reverse()},Un.prototype.toArray=function(){return this.take(p)},vr(Un.prototype,(function(e,t){var n=/^(?:filter|find|map|reject)|While$/.test(t),o=/^(?:head|last)$/.test(t),i=zn[o?"take"+("last"==t?"Right":""):t],a=o||/^find/.test(t);i&&(zn.prototype[t]=function(){var t=this.__wrapped__,l=o?[1]:arguments,u=t instanceof Un,s=l[0],c=u||Wa(t),f=function(e){var t=i.apply(zn,kt([e],l));return o&&p?t[0]:t};c&&n&&"function"==typeof s&&1!=s.length&&(u=c=!1);var p=this.__chain__,d=!!this.__actions__.length,h=a&&!p,m=u&&!d;if(!a&&c){t=m?t:new Un(this);var b=e.apply(t,l);return b.__actions__.push({func:ha,args:[f],thisArg:r}),new Bn(b,p)}return h&&m?e.apply(this,l):(b=this.thru(f),h?o?b.value()[0]:b.value():b)})})),gt(["pop","push","shift","sort","splice","unshift"],(function(e){var t=Ee[e],n=/^(?:push|sort|unshift)$/.test(e)?"tap":"thru",r=/^(?:pop|shift)$/.test(e);zn.prototype[e]=function(){var e=arguments;if(r&&!this.__chain__){var o=this.value();return t.apply(Wa(o)?o:[],e)}return this[n]((function(n){return t.apply(Wa(n)?n:[],e)}))}})),vr(Un.prototype,(function(e,t){var n=zn[t];if(n){var r=n.name+"";Re.call(An,r)||(An[r]=[]),An[r].push({name:t,func:n})}})),An[zo(r,2).name]=[{name:"wrapper",func:r}],Un.prototype.clone=function(){var e=new Un(this.__wrapped__);return e.__actions__=Eo(this.__actions__),e.__dir__=this.__dir__,e.__filtered__=this.__filtered__,e.__iteratees__=Eo(this.__iteratees__),e.__takeCount__=this.__takeCount__,e.__views__=Eo(this.__views__),e},Un.prototype.reverse=function(){if(this.__filtered__){var e=new Un(this);e.__dir__=-1,e.__filtered__=!0}else(e=this.clone()).__dir__*=-1;return e},Un.prototype.value=function(){var e=this.__wrapped__.value(),t=this.__dir__,n=Wa(e),r=t<0,o=n?e.length:0,i=function(e,t,n){for(var r=-1,o=n.length;++r<o;){var i=n[r],a=i.size;switch(i.type){case"drop":e+=a;break;case"dropRight":t-=a;break;case"take":t=gn(t,e+a);break;case"takeRight":e=yn(e,t-a)}}return{start:e,end:t}}(0,o,this.__views__),a=i.start,l=i.end,u=l-a,s=r?l:a-1,c=this.__iteratees__,f=c.length,p=0,d=gn(u,this.__takeCount__);if(!n||!r&&o==u&&d==u)return po(e,this.__actions__);var h=[];e:for(;u--&&p<d;){for(var m=-1,b=e[s+=t];++m<f;){var y=c[m],g=y.iteratee,v=y.type,w=g(b);if(2==v)b=w;else if(!w){if(1==v)continue e;break e}}h[p++]=b}return h},zn.prototype.at=ma,zn.prototype.chain=function(){return da(this)},zn.prototype.commit=function(){return new Bn(this.value(),this.__chain__)},zn.prototype.next=function(){this.__values__===r&&(this.__values__=dl(this.value()));var e=this.__index__>=this.__values__.length;return{done:e,value:e?r:this.__values__[this.__index__++]}},zn.prototype.plant=function(e){for(var t,n=this;n instanceof $n;){var o=qi(n);o.__index__=0,o.__values__=r,t?i.__wrapped__=o:t=o;var i=o;n=n.__wrapped__}return i.__wrapped__=e,t},zn.prototype.reverse=function(){var e=this.__wrapped__;if(e instanceof Un){var t=e;return this.__actions__.length&&(t=new Un(this)),(t=t.reverse()).__actions__.push({func:ha,args:[ta],thisArg:r}),new Bn(t,this.__chain__)}return this.thru(ta)},zn.prototype.toJSON=zn.prototype.valueOf=zn.prototype.value=function(){return po(this.__wrapped__,this.__actions__)},zn.prototype.first=zn.prototype.head,at&&(zn.prototype[at]=function(){return this}),zn}();at?((at.exports=un)._=un,it._=un):ot._=un}.call(this)},9776:(e,t,n)=>{var r=n(3209);function o(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new TypeError("Expected a function");var n=function(){var r=arguments,o=t?t.apply(this,r):r[0],i=n.cache;if(i.has(o))return i.get(o);var a=e.apply(this,r);return n.cache=i.set(o,a)||i,a};return n.cache=new(o.Cache||r),n}o.Cache=r,e.exports=o},6481:(e,t,n)=>{"use strict";var r=n(9177),o=r.ValidatorResult,i=r.SchemaError,a={ignoreProperties:{id:!0,default:!0,description:!0,title:!0,additionalItems:!0,then:!0,else:!0,$schema:!0,$ref:!0,extends:!0}},l=a.validators={};function u(e,t,n,r,o){var i=t.throwError,a=t.throwAll;t.throwError=!1,t.throwAll=!1;var l=this.validateSchema(e,o,t,n);return t.throwError=i,t.throwAll=a,!l.valid&&r instanceof Function&&r(l),l.valid}function s(e,t){if(Object.hasOwnProperty.call(e,t))return e[t];if(t in e)for(;e=Object.getPrototypeOf(e);)if(Object.propertyIsEnumerable.call(e,t))return e[t]}function c(e,t,n,r,o,i){if(this.types.object(e)&&(!t.properties||void 0===t.properties[o]))if(!1===t.additionalProperties)i.addError({name:"additionalProperties",argument:o,message:"is not allowed to have the additional property "+JSON.stringify(o)});else{var a=t.additionalProperties||{};"function"==typeof n.preValidateProperty&&n.preValidateProperty(e,o,a,n,r);var l=this.validateSchema(e[o],a,n,r.makeChild(a,o));l.instance!==i.instance[o]&&(i.instance[o]=l.instance),i.importErrors(l)}}l.type=function(e,t,n,r){if(void 0===e)return null;var i=new o(e,t,n,r),a=Array.isArray(t.type)?t.type:[t.type];if(!a.some(this.testType.bind(this,e,t,n,r))){var l=a.map((function(e){if(e){var t=e.$id||e.id;return t?"<"+t+">":e+""}}));i.addError({name:"type",argument:l,message:"is not of a type(s) "+l})}return i},l.anyOf=function(e,t,n,r){if(void 0===e)return null;var a=new o(e,t,n,r),l=new o(e,t,n,r);if(!Array.isArray(t.anyOf))throw new i("anyOf must be an array");if(!t.anyOf.some(u.bind(this,e,n,r,(function(e){l.importErrors(e)})))){var s=t.anyOf.map((function(e,t){var n=e.$id||e.id;return n?"<"+n+">":e.title&&JSON.stringify(e.title)||e.$ref&&"<"+e.$ref+">"||"[subschema "+t+"]"}));n.nestedErrors&&a.importErrors(l),a.addError({name:"anyOf",argument:s,message:"is not any of "+s.join(",")})}return a},l.allOf=function(e,t,n,r){if(void 0===e)return null;if(!Array.isArray(t.allOf))throw new i("allOf must be an array");var a=new o(e,t,n,r),l=this;return t.allOf.forEach((function(t,o){var i=l.validateSchema(e,t,n,r);if(!i.valid){var u=t.$id||t.id||t.title&&JSON.stringify(t.title)||t.$ref&&"<"+t.$ref+">"||"[subschema "+o+"]";a.addError({name:"allOf",argument:{id:u,length:i.errors.length,valid:i},message:"does not match allOf schema "+u+" with "+i.errors.length+" error[s]:"}),a.importErrors(i)}})),a},l.oneOf=function(e,t,n,r){if(void 0===e)return null;if(!Array.isArray(t.oneOf))throw new i("oneOf must be an array");var a=new o(e,t,n,r),l=new o(e,t,n,r),s=t.oneOf.filter(u.bind(this,e,n,r,(function(e){l.importErrors(e)}))).length,c=t.oneOf.map((function(e,t){return e.$id||e.id||e.title&&JSON.stringify(e.title)||e.$ref&&"<"+e.$ref+">"||"[subschema "+t+"]"}));return 1!==s&&(n.nestedErrors&&a.importErrors(l),a.addError({name:"oneOf",argument:c,message:"is not exactly one from "+c.join(",")})),a},l.if=function(e,t,n,i){if(void 0===e)return null;if(!r.isSchema(t.if))throw new Error('Expected "if" keyword to be a schema');var a,l=u.call(this,e,n,i,null,t.if),s=new o(e,t,n,i);if(l){if(void 0===t.then)return;if(!r.isSchema(t.then))throw new Error('Expected "then" keyword to be a schema');a=this.validateSchema(e,t.then,n,i.makeChild(t.then)),s.importErrors(a)}else{if(void 0===t.else)return;if(!r.isSchema(t.else))throw new Error('Expected "else" keyword to be a schema');a=this.validateSchema(e,t.else,n,i.makeChild(t.else)),s.importErrors(a)}return s},l.propertyNames=function(e,t,n,a){if(this.types.object(e)){var l=new o(e,t,n,a),u=void 0!==t.propertyNames?t.propertyNames:{};if(!r.isSchema(u))throw new i('Expected "propertyNames" to be a schema (object or boolean)');for(var c in e)if(void 0!==s(e,c)){var f=this.validateSchema(c,u,n,a.makeChild(u));l.importErrors(f)}return l}},l.properties=function(e,t,n,r){if(this.types.object(e)){var a=new o(e,t,n,r),l=t.properties||{};for(var u in l){var c=l[u];if(void 0!==c){if(null===c)throw new i('Unexpected null, expected schema in "properties"');"function"==typeof n.preValidateProperty&&n.preValidateProperty(e,u,c,n,r);var f=s(e,u),p=this.validateSchema(f,c,n,r.makeChild(c,u));p.instance!==a.instance[u]&&(a.instance[u]=p.instance),a.importErrors(p)}}return a}},l.patternProperties=function(e,t,n,r){if(this.types.object(e)){var a=new o(e,t,n,r),l=t.patternProperties||{};for(var u in e){var s=!0;for(var f in l){var p=l[f];if(void 0!==p){if(null===p)throw new i('Unexpected null, expected schema in "patternProperties"');try{var d=new RegExp(f,"u")}catch(e){d=new RegExp(f)}if(d.test(u)){s=!1,"function"==typeof n.preValidateProperty&&n.preValidateProperty(e,u,p,n,r);var h=this.validateSchema(e[u],p,n,r.makeChild(p,u));h.instance!==a.instance[u]&&(a.instance[u]=h.instance),a.importErrors(h)}}}s&&c.call(this,e,t,n,r,u,a)}return a}},l.additionalProperties=function(e,t,n,r){if(this.types.object(e)){if(t.patternProperties)return null;var i=new o(e,t,n,r);for(var a in e)c.call(this,e,t,n,r,a,i);return i}},l.minProperties=function(e,t,n,r){if(this.types.object(e)){var i=new o(e,t,n,r);return Object.keys(e).length>=t.minProperties||i.addError({name:"minProperties",argument:t.minProperties,message:"does not meet minimum property length of "+t.minProperties}),i}},l.maxProperties=function(e,t,n,r){if(this.types.object(e)){var i=new o(e,t,n,r);return Object.keys(e).length<=t.maxProperties||i.addError({name:"maxProperties",argument:t.maxProperties,message:"does not meet maximum property length of "+t.maxProperties}),i}},l.items=function(e,t,n,r){var i=this;if(this.types.array(e)&&void 0!==t.items){var a=new o(e,t,n,r);return e.every((function(e,o){if(Array.isArray(t.items))var l=void 0===t.items[o]?t.additionalItems:t.items[o];else l=t.items;if(void 0===l)return!0;if(!1===l)return a.addError({name:"items",message:"additionalItems not permitted"}),!1;var u=i.validateSchema(e,l,n,r.makeChild(l,o));return u.instance!==a.instance[o]&&(a.instance[o]=u.instance),a.importErrors(u),!0})),a}},l.contains=function(e,t,n,i){var a=this;if(this.types.array(e)&&void 0!==t.contains){if(!r.isSchema(t.contains))throw new Error('Expected "contains" keyword to be a schema');var l=new o(e,t,n,i);return!1===e.some((function(e,r){return 0===a.validateSchema(e,t.contains,n,i.makeChild(t.contains,r)).errors.length}))&&l.addError({name:"contains",argument:t.contains,message:"must contain an item matching given schema"}),l}},l.minimum=function(e,t,n,r){if(this.types.number(e)){var i=new o(e,t,n,r);return t.exclusiveMinimum&&!0===t.exclusiveMinimum?e>t.minimum||i.addError({name:"minimum",argument:t.minimum,message:"must be greater than "+t.minimum}):e>=t.minimum||i.addError({name:"minimum",argument:t.minimum,message:"must be greater than or equal to "+t.minimum}),i}},l.maximum=function(e,t,n,r){if(this.types.number(e)){var i=new o(e,t,n,r);return t.exclusiveMaximum&&!0===t.exclusiveMaximum?e<t.maximum||i.addError({name:"maximum",argument:t.maximum,message:"must be less than "+t.maximum}):e<=t.maximum||i.addError({name:"maximum",argument:t.maximum,message:"must be less than or equal to "+t.maximum}),i}},l.exclusiveMinimum=function(e,t,n,r){if("boolean"!=typeof t.exclusiveMinimum&&this.types.number(e)){var i=new o(e,t,n,r);return e>t.exclusiveMinimum||i.addError({name:"exclusiveMinimum",argument:t.exclusiveMinimum,message:"must be strictly greater than "+t.exclusiveMinimum}),i}},l.exclusiveMaximum=function(e,t,n,r){if("boolean"!=typeof t.exclusiveMaximum&&this.types.number(e)){var i=new o(e,t,n,r);return e<t.exclusiveMaximum||i.addError({name:"exclusiveMaximum",argument:t.exclusiveMaximum,message:"must be strictly less than "+t.exclusiveMaximum}),i}};var f=function(e,t,n,a,l,u){if(this.types.number(e)){var s=t[l];if(0==s)throw new i(l+" cannot be zero");var c=new o(e,t,n,a),f=r.getDecimalPlaces(e),p=r.getDecimalPlaces(s),d=Math.max(f,p),h=Math.pow(10,d);return Math.round(e*h)%Math.round(s*h)!=0&&c.addError({name:l,argument:s,message:u+JSON.stringify(s)}),c}};function p(e,t,n){var o,i=n.length;for(o=t+1;o<i;o++)if(r.deepCompareStrict(e,n[o]))return!1;return!0}l.multipleOf=function(e,t,n,r){return f.call(this,e,t,n,r,"multipleOf","is not a multiple of (divisible by) ")},l.divisibleBy=function(e,t,n,r){return f.call(this,e,t,n,r,"divisibleBy","is not divisible by (multiple of) ")},l.required=function(e,t,n,r){var i=new o(e,t,n,r);return void 0===e&&!0===t.required?i.addError({name:"required",message:"is required"}):this.types.object(e)&&Array.isArray(t.required)&&t.required.forEach((function(t){void 0===s(e,t)&&i.addError({name:"required",argument:t,message:"requires property "+JSON.stringify(t)})})),i},l.pattern=function(e,t,n,r){if(this.types.string(e)){var i=new o(e,t,n,r),a=t.pattern;try{var l=new RegExp(a,"u")}catch(e){l=new RegExp(a)}return e.match(l)||i.addError({name:"pattern",argument:t.pattern,message:"does not match pattern "+JSON.stringify(t.pattern.toString())}),i}},l.format=function(e,t,n,i){if(void 0!==e){var a=new o(e,t,n,i);return a.disableFormat||r.isFormat(e,t.format,this)||a.addError({name:"format",argument:t.format,message:"does not conform to the "+JSON.stringify(t.format)+" format"}),a}},l.minLength=function(e,t,n,r){if(this.types.string(e)){var i=new o(e,t,n,r),a=e.match(/[\uDC00-\uDFFF]/g);return e.length-(a?a.length:0)>=t.minLength||i.addError({name:"minLength",argument:t.minLength,message:"does not meet minimum length of "+t.minLength}),i}},l.maxLength=function(e,t,n,r){if(this.types.string(e)){var i=new o(e,t,n,r),a=e.match(/[\uDC00-\uDFFF]/g);return e.length-(a?a.length:0)<=t.maxLength||i.addError({name:"maxLength",argument:t.maxLength,message:"does not meet maximum length of "+t.maxLength}),i}},l.minItems=function(e,t,n,r){if(this.types.array(e)){var i=new o(e,t,n,r);return e.length>=t.minItems||i.addError({name:"minItems",argument:t.minItems,message:"does not meet minimum length of "+t.minItems}),i}},l.maxItems=function(e,t,n,r){if(this.types.array(e)){var i=new o(e,t,n,r);return e.length<=t.maxItems||i.addError({name:"maxItems",argument:t.maxItems,message:"does not meet maximum length of "+t.maxItems}),i}},l.uniqueItems=function(e,t,n,r){if(!0===t.uniqueItems&&this.types.array(e)){var i=new o(e,t,n,r);return e.every(p)||i.addError({name:"uniqueItems",message:"contains duplicate item"}),i}},l.dependencies=function(e,t,n,r){if(this.types.object(e)){var i=new o(e,t,n,r);for(var a in t.dependencies)if(void 0!==e[a]){var l=t.dependencies[a],u=r.makeChild(l,a);if("string"==typeof l&&(l=[l]),Array.isArray(l))l.forEach((function(t){void 0===e[t]&&i.addError({name:"dependencies",argument:u.propertyPath,message:"property "+t+" not found, required by "+u.propertyPath})}));else{var s=this.validateSchema(e,l,n,u);i.instance!==s.instance&&(i.instance=s.instance),s&&s.errors.length&&(i.addError({name:"dependencies",argument:u.propertyPath,message:"does not meet dependency required by "+u.propertyPath}),i.importErrors(s))}}return i}},l.enum=function(e,t,n,a){if(void 0===e)return null;if(!Array.isArray(t.enum))throw new i("enum expects an array",t);var l=new o(e,t,n,a);return t.enum.some(r.deepCompareStrict.bind(null,e))||l.addError({name:"enum",argument:t.enum,message:"is not one of enum values: "+t.enum.map(String).join(",")}),l},l.const=function(e,t,n,i){if(void 0===e)return null;var a=new o(e,t,n,i);return r.deepCompareStrict(t.const,e)||a.addError({name:"const",argument:t.const,message:"does not exactly match expected constant: "+t.const}),a},l.not=l.disallow=function(e,t,n,r){var i=this;if(void 0===e)return null;var a=new o(e,t,n,r),l=t.not||t.disallow;return l?(Array.isArray(l)||(l=[l]),l.forEach((function(o){if(i.testType(e,t,n,r,o)){var l=o&&(o.$id||o.id)||o;a.addError({name:"not",argument:l,message:"is of prohibited type "+l})}})),a):null},e.exports=a},9177:(e,t,n)=>{"use strict";var r=n(8575),o=t.ValidationError=function(e,t,n,r,o,i){if(Array.isArray(r)?(this.path=r,this.property=r.reduce((function(e,t){return e+f(t)}),"instance")):void 0!==r&&(this.property=r),e&&(this.message=e),n){var a=n.$id||n.id;this.schema=a||n}void 0!==t&&(this.instance=t),this.name=o,this.argument=i,this.stack=this.toString()};o.prototype.toString=function(){return this.property+" "+this.message};var i=t.ValidatorResult=function(e,t,n,r){this.instance=e,this.schema=t,this.options=n,this.path=r.path,this.propertyPath=r.propertyPath,this.errors=[],this.throwError=n&&n.throwError,this.throwFirst=n&&n.throwFirst,this.throwAll=n&&n.throwAll,this.disableFormat=n&&!0===n.disableFormat};function a(e,t){return t+": "+e.toString()+"\n"}function l(e){Error.captureStackTrace&&Error.captureStackTrace(this,l),this.instance=e.instance,this.schema=e.schema,this.options=e.options,this.errors=e.errors}i.prototype.addError=function(e){var t;if("string"==typeof e)t=new o(e,this.instance,this.schema,this.path);else{if(!e)throw new Error("Missing error detail");if(!e.message)throw new Error("Missing error message");if(!e.name)throw new Error("Missing validator type");t=new o(e.message,this.instance,this.schema,this.path,e.name,e.argument)}if(this.errors.push(t),this.throwFirst)throw new l(this);if(this.throwError)throw t;return t},i.prototype.importErrors=function(e){"string"==typeof e||e&&e.validatorType?this.addError(e):e&&e.errors&&(this.errors=this.errors.concat(e.errors))},i.prototype.toString=function(e){return this.errors.map(a).join("")},Object.defineProperty(i.prototype,"valid",{get:function(){return!this.errors.length}}),e.exports.ValidatorResultError=l,l.prototype=new Error,l.prototype.constructor=l,l.prototype.name="Validation Error";var u=t.SchemaError=function e(t,n){this.message=t,this.schema=n,Error.call(this,t),Error.captureStackTrace(this,e)};u.prototype=Object.create(Error.prototype,{constructor:{value:u,enumerable:!1},name:{value:"SchemaError",enumerable:!1}});var s=t.SchemaContext=function(e,t,n,r,o){this.schema=e,this.options=t,Array.isArray(n)?(this.path=n,this.propertyPath=n.reduce((function(e,t){return e+f(t)}),"instance")):this.propertyPath=n,this.base=r,this.schemas=o};s.prototype.resolve=function(e){return r.resolve(this.base,e)},s.prototype.makeChild=function(e,t){var n=void 0===t?this.path:this.path.concat([t]),o=e.$id||e.id,i=r.resolve(this.base,o||""),a=new s(e,this.options,n,i,Object.create(this.schemas));return o&&!a.schemas[i]&&(a.schemas[i]=e),a};var c=t.FORMAT_REGEXPS={"date-time":/^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-(3[01]|0[1-9]|[12][0-9])[tT ](2[0-4]|[01][0-9]):([0-5][0-9]):(60|[0-5][0-9])(\.\d+)?([zZ]|[+-]([0-5][0-9]):(60|[0-5][0-9]))$/,date:/^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-(3[01]|0[1-9]|[12][0-9])$/,time:/^(2[0-4]|[01][0-9]):([0-5][0-9]):(60|[0-5][0-9])$/,duration:/P(T\d+(H(\d+M(\d+S)?)?|M(\d+S)?|S)|\d+(D|M(\d+D)?|Y(\d+M(\d+D)?)?)(T\d+(H(\d+M(\d+S)?)?|M(\d+S)?|S))?|\d+W)/i,email:/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/,"idn-email":/^("(?:[!#-\[\]-\u{10FFFF}]|\\[\t -\u{10FFFF}])*"|[!#-'*+\-/-9=?A-Z\^-\u{10FFFF}](?:\.?[!#-'*+\-/-9=?A-Z\^-\u{10FFFF}])*)@([!#-'*+\-/-9=?A-Z\^-\u{10FFFF}](?:\.?[!#-'*+\-/-9=?A-Z\^-\u{10FFFF}])*|\[[!-Z\^-\u{10FFFF}]*\])$/u,"ip-address":/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,ipv6:/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/,uri:/^[a-zA-Z][a-zA-Z0-9+.-]*:[^\s]*$/,"uri-reference":/^(((([A-Za-z][+\-.0-9A-Za-z]*(:%[0-9A-Fa-f]{2}|:[!$&-.0-;=?-Z_a-z~]|[/?])|\?)(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*|([A-Za-z][+\-.0-9A-Za-z]*:?)?)|([A-Za-z][+\-.0-9A-Za-z]*:)?\/((%[0-9A-Fa-f]{2}|\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?[/?]|[!$&-.0-;=?-Z_a-z~])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*|(\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?)?))#(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*|(([A-Za-z][+\-.0-9A-Za-z]*)?%[0-9A-Fa-f]{2}|[!$&-.0-9;=@_~]|[A-Za-z][+\-.0-9A-Za-z]*[!$&-*,;=@_~])(%[0-9A-Fa-f]{2}|[!$&-.0-9;=@-Z_a-z~])*((([/?](%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*)?#|[/?])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*)?|([A-Za-z][+\-.0-9A-Za-z]*(:%[0-9A-Fa-f]{2}|:[!$&-.0-;=?-Z_a-z~]|[/?])|\?)(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*|([A-Za-z][+\-.0-9A-Za-z]*:)?\/((%[0-9A-Fa-f]{2}|\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?[/?]|[!$&-.0-;=?-Z_a-z~])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*|\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~])+(:\d*)?|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?:\d*|\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?)?|[A-Za-z][+\-.0-9A-Za-z]*:?)?$/,iri:/^[a-zA-Z][a-zA-Z0-9+.-]*:[^\s]*$/,"iri-reference":/^(((([A-Za-z][+\-.0-9A-Za-z]*(:%[0-9A-Fa-f]{2}|:[!$&-.0-;=?-Z_a-z~-\u{10FFFF}]|[/?])|\?)(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*|([A-Za-z][+\-.0-9A-Za-z]*:?)?)|([A-Za-z][+\-.0-9A-Za-z]*:)?\/((%[0-9A-Fa-f]{2}|\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~-\u{10FFFF}])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~-\u{10FFFF}]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?[/?]|[!$&-.0-;=?-Z_a-z~-\u{10FFFF}])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*|(\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~-\u{10FFFF}])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~-\u{10FFFF}]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?)?))#(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*|(([A-Za-z][+\-.0-9A-Za-z]*)?%[0-9A-Fa-f]{2}|[!$&-.0-9;=@_~-\u{10FFFF}]|[A-Za-z][+\-.0-9A-Za-z]*[!$&-*,;=@_~-\u{10FFFF}])(%[0-9A-Fa-f]{2}|[!$&-.0-9;=@-Z_a-z~-\u{10FFFF}])*((([/?](%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*)?#|[/?])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*)?|([A-Za-z][+\-.0-9A-Za-z]*(:%[0-9A-Fa-f]{2}|:[!$&-.0-;=?-Z_a-z~-\u{10FFFF}]|[/?])|\?)(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*|([A-Za-z][+\-.0-9A-Za-z]*:)?\/((%[0-9A-Fa-f]{2}|\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~-\u{10FFFF}])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~-\u{10FFFF}]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?[/?]|[!$&-.0-;=?-Z_a-z~-\u{10FFFF}])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*|\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~-\u{10FFFF}])+(:\d*)?|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~-\u{10FFFF}]+)?|[.0-:A-Fa-f]+)\])?:\d*|\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~-\u{10FFFF}]+)?|[.0-:A-Fa-f]+)\])?)?|[A-Za-z][+\-.0-9A-Za-z]*:?)?$/u,uuid:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i,"uri-template":/(%[0-9a-f]{2}|[!#$&(-;=?@\[\]_a-z~]|\{[!#&+,./;=?@|]?(%[0-9a-f]{2}|[0-9_a-z])(\.?(%[0-9a-f]{2}|[0-9_a-z]))*(:[1-9]\d{0,3}|\*)?(,(%[0-9a-f]{2}|[0-9_a-z])(\.?(%[0-9a-f]{2}|[0-9_a-z]))*(:[1-9]\d{0,3}|\*)?)*\})*/iu,"json-pointer":/^(\/([\x00-\x2e0-@\[-}\x7f]|~[01])*)*$/iu,"relative-json-pointer":/^\d+(#|(\/([\x00-\x2e0-@\[-}\x7f]|~[01])*)*)$/iu,hostname:/^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?)*\.?$/,"host-name":/^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?)*\.?$/,"utc-millisec":function(e){return"string"==typeof e&&parseFloat(e)===parseInt(e,10)&&!isNaN(e)},regex:function(e){var t=!0;try{new RegExp(e)}catch(e){t=!1}return t},style:/[\r\n\t ]*[^\r\n\t ][^:]*:[\r\n\t ]*[^\r\n\t ;]*[\r\n\t ]*;?/,color:/^(#?([0-9A-Fa-f]{3}){1,2}\b|aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow|(rgb\(\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*\))|(rgb\(\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*\)))$/,phone:/^\+(?:[0-9] ?){6,14}[0-9]$/,alpha:/^[a-zA-Z]+$/,alphanumeric:/^[a-zA-Z0-9]+$/};c.regexp=c.regex,c.pattern=c.regex,c.ipv4=c["ip-address"],t.isFormat=function(e,t,n){if("string"==typeof e&&void 0!==c[t]){if(c[t]instanceof RegExp)return c[t].test(e);if("function"==typeof c[t])return c[t](e)}else if(n&&n.customFormats&&"function"==typeof n.customFormats[t])return n.customFormats[t](e);return!0};var f=t.makeSuffix=function(e){return(e=e.toString()).match(/[.\s\[\]]/)||e.match(/^[\d]/)?e.match(/^\d+$/)?"["+e+"]":"["+JSON.stringify(e)+"]":"."+e};function p(e,t,n,r){"object"==typeof n?t[r]=m(e[r],n):-1===e.indexOf(n)&&t.push(n)}function d(e,t,n){t[n]=e[n]}function h(e,t,n,r){"object"==typeof t[r]&&t[r]&&e[r]?n[r]=m(e[r],t[r]):n[r]=t[r]}function m(e,t){var n=Array.isArray(t),r=n&&[]||{};return n?(e=e||[],r=r.concat(e),t.forEach(p.bind(null,e,r))):(e&&"object"==typeof e&&Object.keys(e).forEach(d.bind(null,e,r)),Object.keys(t).forEach(h.bind(null,e,t,r))),r}function b(e){return"/"+encodeURIComponent(e).replace(/~/g,"%7E")}t.deepCompareStrict=function e(t,n){if(typeof t!=typeof n)return!1;if(Array.isArray(t))return!!Array.isArray(n)&&t.length===n.length&&t.every((function(r,o){return e(t[o],n[o])}));if("object"==typeof t){if(!t||!n)return t===n;var r=Object.keys(t),o=Object.keys(n);return r.length===o.length&&r.every((function(r){return e(t[r],n[r])}))}return t===n},e.exports.deepMerge=m,t.objectGetPath=function(e,t){for(var n,r=t.split("/").slice(1);"string"==typeof(n=r.shift());){var o=decodeURIComponent(n.replace(/~0/,"~").replace(/~1/g,"/"));if(!(o in e))return;e=e[o]}return e},t.encodePath=function(e){return e.map(b).join("")},t.getDecimalPlaces=function(e){var t=0;if(isNaN(e))return t;"number"!=typeof e&&(e=Number(e));var n=e.toString().split("e");if(2===n.length){if("-"!==n[1][0])return t;t=Number(n[1].slice(1))}var r=n[0].split(".");return 2===r.length&&(t+=r[1].length),t},t.isSchema=function(e){return"object"==typeof e&&e||"boolean"==typeof e}},660:(e,t,n)=>{"use strict";e.exports.Validator=n(3058);n(9177).ValidatorResult,n(9177).ValidatorResultError,n(9177).ValidationError,n(9177).SchemaError,n(1287),n(1287).R},1287:(e,t,n)=>{"use strict";var r=n(8575),o=n(9177);function i(e,t){this.id=e,this.ref=t}e.exports.R=function(e,t){function n(e,t){if(t&&"object"==typeof t)if(t.$ref){var i=r.resolve(e,t.$ref);s[i]=s[i]?s[i]+1:0}else{var c=t.$id||t.id,f=c?r.resolve(e,c):e;if(f){if(f.indexOf("#")<0&&(f+="#"),u[f]){if(!o.deepCompareStrict(u[f],t))throw new Error("Schema <"+f+"> already exists with different definition");return u[f]}u[f]=t,"#"==f[f.length-1]&&(u[f.substring(0,f.length-1)]=t)}a(f+"/items",Array.isArray(t.items)?t.items:[t.items]),a(f+"/extends",Array.isArray(t.extends)?t.extends:[t.extends]),n(f+"/additionalItems",t.additionalItems),l(f+"/properties",t.properties),n(f+"/additionalProperties",t.additionalProperties),l(f+"/definitions",t.definitions),l(f+"/patternProperties",t.patternProperties),l(f+"/dependencies",t.dependencies),a(f+"/disallow",t.disallow),a(f+"/allOf",t.allOf),a(f+"/anyOf",t.anyOf),a(f+"/oneOf",t.oneOf),n(f+"/not",t.not)}}function a(e,t){if(Array.isArray(t))for(var r=0;r<t.length;r++)n(e+"/"+r,t[r])}function l(e,t){if(t&&"object"==typeof t)for(var r in t)n(e+"/"+r,t[r])}var u={},s={};return n(e,t),new i(u,s)}},3058:(e,t,n)=>{"use strict";var r=n(8575),o=n(6481),i=n(9177),a=n(1287).R,l=i.ValidatorResult,u=i.ValidatorResultError,s=i.SchemaError,c=i.SchemaContext,f=function e(){this.customFormats=Object.create(e.prototype.customFormats),this.schemas={},this.unresolvedRefs=[],this.types=Object.create(d),this.attributes=Object.create(o.validators)};function p(e){var t="string"==typeof e?e:e.$ref;return"string"==typeof t&&t}f.prototype.customFormats={},f.prototype.schemas=null,f.prototype.types=null,f.prototype.attributes=null,f.prototype.unresolvedRefs=null,f.prototype.addSchema=function(e,t){var n=this;if(!e)return null;var r=a(t||"/",e),o=t||e.$id||e.id;for(var i in r.id)this.schemas[i]=r.id[i];for(var i in r.ref)this.unresolvedRefs.push(i);return this.unresolvedRefs=this.unresolvedRefs.filter((function(e){return void 0===n.schemas[e]})),this.schemas[o]},f.prototype.addSubSchemaArray=function(e,t){if(Array.isArray(t))for(var n=0;n<t.length;n++)this.addSubSchema(e,t[n])},f.prototype.addSubSchemaObject=function(e,t){if(t&&"object"==typeof t)for(var n in t)this.addSubSchema(e,t[n])},f.prototype.setSchemas=function(e){this.schemas=e},f.prototype.getSchema=function(e){return this.schemas[e]},f.prototype.validate=function(e,t,n,o){if("boolean"!=typeof t&&"object"!=typeof t||null===t)throw new s("Expected `schema` to be an object or boolean");n||(n={});var i,f=t.$id||t.id,p=r.resolve(n.base||"/",f||"");if(!o){(o=new c(t,n,[],p,Object.create(this.schemas))).schemas[p]||(o.schemas[p]=t);var d=a(p,t);for(var h in d.id){var m=d.id[h];o.schemas[h]=m}}if(n.required&&void 0===e)return(i=new l(e,t,n,o)).addError("is required, but is undefined"),i;if(!(i=this.validateSchema(e,t,n,o)))throw new Error("Result undefined");if(n.throwAll&&i.errors.length)throw new u(i);return i},f.prototype.validateSchema=function(e,t,n,r){var a=new l(e,t,n,r);if("boolean"==typeof t)!0===t?t={}:!1===t&&(t={type:[]});else if(!t)throw new Error("schema is undefined");if(t.extends)if(Array.isArray(t.extends)){var u={schema:t,ctx:r};t.extends.forEach(this.schemaTraverser.bind(this,u)),t=u.schema,u.schema=null,u.ctx=null,u=null}else t=i.deepMerge(t,this.superResolve(t.extends,r));var f=p(t);if(f){var d=this.resolve(t,f,r),h=new c(d.subschema,n,r.path,d.switchSchema,r.schemas);return this.validateSchema(e,d.subschema,n,h)}var m=n&&n.skipAttributes||[];for(var b in t)if(!o.ignoreProperties[b]&&m.indexOf(b)<0){var y=null,g=this.attributes[b];if(g)y=g.call(this,e,t,n,r);else if(!1===n.allowUnknownAttributes)throw new s("Unsupported attribute: "+b,t);y&&a.importErrors(y)}if("function"==typeof n.rewrite){var v=n.rewrite.call(this,e,t,n,r);a.instance=v}return a},f.prototype.schemaTraverser=function(e,t){e.schema=i.deepMerge(e.schema,this.superResolve(t,e.ctx))},f.prototype.superResolve=function(e,t){var n=p(e);return n?this.resolve(e,n,t).subschema:e},f.prototype.resolve=function(e,t,n){if(t=n.resolve(t),n.schemas[t])return{subschema:n.schemas[t],switchSchema:t};var o=r.parse(t),a=o&&o.hash,l=a&&a.length&&t.substr(0,t.length-a.length);if(!l||!n.schemas[l])throw new s("no such schema <"+t+">",e);var u=i.objectGetPath(n.schemas[l],a.substr(1));if(void 0===u)throw new s("no such schema "+a+" located in <"+l+">",e);return{subschema:u,switchSchema:t}},f.prototype.testType=function(e,t,n,r,o){if(void 0!==o){if(null===o)throw new s('Unexpected null in "type" keyword');if("function"==typeof this.types[o])return this.types[o].call(this,e);if(o&&"object"==typeof o){var i=this.validateSchema(e,o,n,r);return void 0===i||!(i&&i.errors.length)}return!0}};var d=f.prototype.types={};d.string=function(e){return"string"==typeof e},d.number=function(e){return"number"==typeof e&&isFinite(e)},d.integer=function(e){return"number"==typeof e&&e%1==0},d.boolean=function(e){return"boolean"==typeof e},d.array=function(e){return Array.isArray(e)},d.null=function(e){return null===e},d.date=function(e){return e instanceof Date},d.any=function(e){return!0},d.object=function(e){return e&&"object"==typeof e&&!Array.isArray(e)&&!(e instanceof Date)},e.exports=f},7537:(e,t)=>{function n(e){if(e&&"object"==typeof e){var t=e.which||e.keyCode||e.charCode;t&&(e=t)}if("number"==typeof e)return a[e];var n,i=String(e);return(n=r[i.toLowerCase()])?n:(n=o[i.toLowerCase()])||(1===i.length?i.charCodeAt(0):void 0)}n.isEventKey=function(e,t){if(e&&"object"==typeof e){var n=e.which||e.keyCode||e.charCode;if(null==n)return!1;if("string"==typeof t){var i;if(i=r[t.toLowerCase()])return i===n;if(i=o[t.toLowerCase()])return i===n}else if("number"==typeof t)return t===n;return!1}};var r=(t=e.exports=n).code=t.codes={backspace:8,tab:9,enter:13,shift:16,ctrl:17,alt:18,"pause/break":19,"caps lock":20,esc:27,space:32,"page up":33,"page down":34,end:35,home:36,left:37,up:38,right:39,down:40,insert:45,delete:46,command:91,"left command":91,"right command":93,"numpad *":106,"numpad +":107,"numpad -":109,"numpad .":110,"numpad /":111,"num lock":144,"scroll lock":145,"my computer":182,"my calculator":183,";":186,"=":187,",":188,"-":189,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222},o=t.aliases={windows:91,"⇧":16,"⌥":18,"⌃":17,"⌘":91,ctl:17,control:17,option:18,pause:19,break:19,caps:20,return:13,escape:27,spc:32,spacebar:32,pgup:33,pgdn:34,ins:45,del:46,cmd:91};for(i=97;i<123;i++)r[String.fromCharCode(i)]=i-32;for(var i=48;i<58;i++)r[i-48]=i;for(i=1;i<13;i++)r["f"+i]=i+111;for(i=0;i<10;i++)r["numpad "+i]=i+96;var a=t.names=t.title={};for(i in r)a[r[i]]=i;for(var l in o)r[l]=o[l]},7418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;function o(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,i){for(var a,l,u=o(e),s=1;s<arguments.length;s++){for(var c in a=Object(arguments[s]))n.call(a,c)&&(u[c]=a[c]);if(t){l=t(a);for(var f=0;f<l.length;f++)r.call(a,l[f])&&(u[l[f]]=a[l[f]])}}return u}},2703:(e,t,n)=>{"use strict";var r=n(414);function o(){}function i(){}i.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,i,a){if(a!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:i,resetWarningCache:o};return n.PropTypes=n,n}},1581:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4971:function(e,t,n){var r;e=n.nmd(e),function(o){t&&t.nodeType,e&&e.nodeType;var i="object"==typeof n.g&&n.g;i.global!==i&&i.window!==i&&i.self;var a,l=2147483647,u=36,s=/^xn--/,c=/[^\x20-\x7E]/,f=/[\x2E\u3002\uFF0E\uFF61]/g,p={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},d=Math.floor,h=String.fromCharCode;function m(e){throw RangeError(p[e])}function b(e,t){for(var n=e.length,r=[];n--;)r[n]=t(e[n]);return r}function y(e,t){var n=e.split("@"),r="";return n.length>1&&(r=n[0]+"@",e=n[1]),r+b((e=e.replace(f,".")).split("."),t).join(".")}function g(e){for(var t,n,r=[],o=0,i=e.length;o<i;)(t=e.charCodeAt(o++))>=55296&&t<=56319&&o<i?56320==(64512&(n=e.charCodeAt(o++)))?r.push(((1023&t)<<10)+(1023&n)+65536):(r.push(t),o--):r.push(t);return r}function v(e){return b(e,(function(e){var t="";return e>65535&&(t+=h((e-=65536)>>>10&1023|55296),e=56320|1023&e),t+h(e)})).join("")}function w(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function _(e,t,n){var r=0;for(e=n?d(e/700):e>>1,e+=d(e/t);e>455;r+=u)e=d(e/35);return d(r+36*e/(e+38))}function x(e){var t,n,r,o,i,a,s,c,f,p,h,b=[],y=e.length,g=0,w=128,x=72;for((n=e.lastIndexOf("-"))<0&&(n=0),r=0;r<n;++r)e.charCodeAt(r)>=128&&m("not-basic"),b.push(e.charCodeAt(r));for(o=n>0?n+1:0;o<y;){for(i=g,a=1,s=u;o>=y&&m("invalid-input"),((c=(h=e.charCodeAt(o++))-48<10?h-22:h-65<26?h-65:h-97<26?h-97:u)>=u||c>d((l-g)/a))&&m("overflow"),g+=c*a,!(c<(f=s<=x?1:s>=x+26?26:s-x));s+=u)a>d(l/(p=u-f))&&m("overflow"),a*=p;x=_(g-i,t=b.length+1,0==i),d(g/t)>l-w&&m("overflow"),w+=d(g/t),g%=t,b.splice(g++,0,w)}return v(b)}function O(e){var t,n,r,o,i,a,s,c,f,p,b,y,v,x,O,S=[];for(y=(e=g(e)).length,t=128,n=0,i=72,a=0;a<y;++a)(b=e[a])<128&&S.push(h(b));for(r=o=S.length,o&&S.push("-");r<y;){for(s=l,a=0;a<y;++a)(b=e[a])>=t&&b<s&&(s=b);for(s-t>d((l-n)/(v=r+1))&&m("overflow"),n+=(s-t)*v,t=s,a=0;a<y;++a)if((b=e[a])<t&&++n>l&&m("overflow"),b==t){for(c=n,f=u;!(c<(p=f<=i?1:f>=i+26?26:f-i));f+=u)O=c-p,x=u-p,S.push(h(w(p+O%x,0))),c=d(O/x);S.push(h(w(c,0))),i=_(n,v,r==o),n=0,++r}++n,++t}return S.join("")}a={version:"1.3.2",ucs2:{decode:g,encode:v},decode:x,encode:O,toASCII:function(e){return y(e,(function(e){return c.test(e)?"xn--"+O(e):e}))},toUnicode:function(e){return y(e,(function(e){return s.test(e)?x(e.slice(4).toLowerCase()):e}))}},void 0===(r=function(){return a}.call(t,n,t,e))||(e.exports=r)}()},2587:e=>{"use strict";function t(e,t){return Object.prototype.hasOwnProperty.call(e,t)}e.exports=function(e,n,r,o){n=n||"&",r=r||"=";var i={};if("string"!=typeof e||0===e.length)return i;var a=/\+/g;e=e.split(n);var l=1e3;o&&"number"==typeof o.maxKeys&&(l=o.maxKeys);var u=e.length;l>0&&u>l&&(u=l);for(var s=0;s<u;++s){var c,f,p,d,h=e[s].replace(a,"%20"),m=h.indexOf(r);m>=0?(c=h.substr(0,m),f=h.substr(m+1)):(c=h,f=""),p=decodeURIComponent(c),d=decodeURIComponent(f),t(i,p)?Array.isArray(i[p])?i[p].push(d):i[p]=[i[p],d]:i[p]=d}return i}},2361:e=>{"use strict";var t=function(e){switch(typeof e){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return""}};e.exports=function(e,n,r,o){return n=n||"&",r=r||"=",null===e&&(e=void 0),"object"==typeof e?Object.keys(e).map((function(o){var i=encodeURIComponent(t(o))+r;return Array.isArray(e[o])?e[o].map((function(e){return i+encodeURIComponent(t(e))})).join(n):i+encodeURIComponent(t(e[o]))})).join(n):o?encodeURIComponent(t(o))+r+encodeURIComponent(t(e)):""}},7673:(e,t,n)=>{"use strict";t.decode=t.parse=n(2587),t.encode=t.stringify=n(2361)},4448:(e,t,n)=>{"use strict";var r=n(7294),o=n(7418),i=n(3840);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(a(227));function l(e,t,n,r,o,i,a,l,u){var s=Array.prototype.slice.call(arguments,3);try{t.apply(n,s)}catch(e){this.onError(e)}}var u=!1,s=null,c=!1,f=null,p={onError:function(e){u=!0,s=e}};function d(e,t,n,r,o,i,a,c,f){u=!1,s=null,l.apply(p,arguments)}var h=null,m=null,b=null;function y(e,t,n){var r=e.type||"unknown-event";e.currentTarget=b(n),function(e,t,n,r,o,i,l,p,h){if(d.apply(this,arguments),u){if(!u)throw Error(a(198));var m=s;u=!1,s=null,c||(c=!0,f=m)}}(r,t,void 0,e),e.currentTarget=null}var g=null,v={};function w(){if(g)for(var e in v){var t=v[e],n=g.indexOf(e);if(!(-1<n))throw Error(a(96,e));if(!x[n]){if(!t.extractEvents)throw Error(a(97,e));for(var r in x[n]=t,n=t.eventTypes){var o=void 0,i=n[r],l=t,u=r;if(O.hasOwnProperty(u))throw Error(a(99,u));O[u]=i;var s=i.phasedRegistrationNames;if(s){for(o in s)s.hasOwnProperty(o)&&_(s[o],l,u);o=!0}else i.registrationName?(_(i.registrationName,l,u),o=!0):o=!1;if(!o)throw Error(a(98,r,e))}}}}function _(e,t,n){if(S[e])throw Error(a(100,e));S[e]=t,k[e]=t.eventTypes[n].dependencies}var x=[],O={},S={},k={};function j(e){var t,n=!1;for(t in e)if(e.hasOwnProperty(t)){var r=e[t];if(!v.hasOwnProperty(t)||v[t]!==r){if(v[t])throw Error(a(102,t));v[t]=r,n=!0}}n&&w()}var C=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),E=null,P=null,A=null;function T(e){if(e=m(e)){if("function"!=typeof E)throw Error(a(280));var t=e.stateNode;t&&(t=h(t),E(e.stateNode,e.type,t))}}function L(e){P?A?A.push(e):A=[e]:P=e}function R(){if(P){var e=P,t=A;if(A=P=null,T(e),t)for(e=0;e<t.length;e++)T(t[e])}}function M(e,t){return e(t)}function D(e,t,n,r,o){return e(t,n,r,o)}function I(){}var F=M,N=!1,z=!1;function q(){null===P&&null===A||(I(),R())}function $(e,t,n){if(z)return e(t,n);z=!0;try{return F(e,t,n)}finally{z=!1,q()}}var B=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,U=Object.prototype.hasOwnProperty,V={},W={};function H(e,t,n,r,o,i){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=i}var Z={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){Z[e]=new H(e,0,!1,e,null,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];Z[t]=new H(t,1,!1,e[1],null,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){Z[e]=new H(e,2,!1,e.toLowerCase(),null,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){Z[e]=new H(e,2,!1,e,null,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){Z[e]=new H(e,3,!1,e.toLowerCase(),null,!1)})),["checked","multiple","muted","selected"].forEach((function(e){Z[e]=new H(e,3,!0,e,null,!1)})),["capture","download"].forEach((function(e){Z[e]=new H(e,4,!1,e,null,!1)})),["cols","rows","size","span"].forEach((function(e){Z[e]=new H(e,6,!1,e,null,!1)})),["rowSpan","start"].forEach((function(e){Z[e]=new H(e,5,!1,e.toLowerCase(),null,!1)}));var K=/[\-:]([a-z])/g;function Q(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(K,Q);Z[t]=new H(t,1,!1,e,null,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(K,Q);Z[t]=new H(t,1,!1,e,"http://www.w3.org/1999/xlink",!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(K,Q);Z[t]=new H(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1)})),["tabIndex","crossOrigin"].forEach((function(e){Z[e]=new H(e,1,!1,e.toLowerCase(),null,!1)})),Z.xlinkHref=new H("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0),["src","href","action","formAction"].forEach((function(e){Z[e]=new H(e,1,!1,e.toLowerCase(),null,!0)}));var G=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function X(e,t,n,r){var o=Z.hasOwnProperty(t)?Z[t]:null;(null!==o?0===o.type:!r&&2<t.length&&("o"===t[0]||"O"===t[0])&&("n"===t[1]||"N"===t[1]))||(function(e,t,n,r){if(null==t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,o,r)&&(n=null),r||null===o?function(e){return!!U.call(W,e)||!U.call(V,e)&&(B.test(e)?W[e]=!0:(V[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):o.mustUseProperty?e[o.propertyName]=null===n?3!==o.type&&"":n:(t=o.attributeName,r=o.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(o=o.type)||4===o&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}G.hasOwnProperty("ReactCurrentDispatcher")||(G.ReactCurrentDispatcher={current:null}),G.hasOwnProperty("ReactCurrentBatchConfig")||(G.ReactCurrentBatchConfig={suspense:null});var Y=/^(.*)[\\\/]/,J="function"==typeof Symbol&&Symbol.for,ee=J?Symbol.for("react.element"):60103,te=J?Symbol.for("react.portal"):60106,ne=J?Symbol.for("react.fragment"):60107,re=J?Symbol.for("react.strict_mode"):60108,oe=J?Symbol.for("react.profiler"):60114,ie=J?Symbol.for("react.provider"):60109,ae=J?Symbol.for("react.context"):60110,le=J?Symbol.for("react.concurrent_mode"):60111,ue=J?Symbol.for("react.forward_ref"):60112,se=J?Symbol.for("react.suspense"):60113,ce=J?Symbol.for("react.suspense_list"):60120,fe=J?Symbol.for("react.memo"):60115,pe=J?Symbol.for("react.lazy"):60116,de=J?Symbol.for("react.block"):60121,he="function"==typeof Symbol&&Symbol.iterator;function me(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=he&&e[he]||e["@@iterator"])?e:null}function be(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case ne:return"Fragment";case te:return"Portal";case oe:return"Profiler";case re:return"StrictMode";case se:return"Suspense";case ce:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case ae:return"Context.Consumer";case ie:return"Context.Provider";case ue:var t=e.render;return t=t.displayName||t.name||"",e.displayName||(""!==t?"ForwardRef("+t+")":"ForwardRef");case fe:return be(e.type);case de:return be(e.render);case pe:if(e=1===e._status?e._result:null)return be(e)}return null}function ye(e){var t="";do{e:switch(e.tag){case 3:case 4:case 6:case 7:case 10:case 9:var n="";break e;default:var r=e._debugOwner,o=e._debugSource,i=be(e.type);n=null,r&&(n=be(r.type)),r=i,i="",o?i=" (at "+o.fileName.replace(Y,"")+":"+o.lineNumber+")":n&&(i=" (created by "+n+")"),n="\n    in "+(r||"Unknown")+i}t+=n,e=e.return}while(e);return t}function ge(e){switch(typeof e){case"boolean":case"number":case"object":case"string":case"undefined":return e;default:return""}}function ve(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function we(e){e._valueTracker||(e._valueTracker=function(e){var t=ve(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var o=n.get,i=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(e){r=""+e,i.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function _e(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=ve(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function xe(e,t){var n=t.checked;return o({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function Oe(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=ge(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function Se(e,t){null!=(t=t.checked)&&X(e,"checked",t,!1)}function ke(e,t){Se(e,t);var n=ge(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?Ce(e,t.type,n):t.hasOwnProperty("defaultValue")&&Ce(e,t.type,ge(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function je(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function Ce(e,t,n){"number"===t&&e.ownerDocument.activeElement===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}function Ee(e,t){return e=o({children:void 0},t),(t=function(e){var t="";return r.Children.forEach(e,(function(e){null!=e&&(t+=e)})),t}(t.children))&&(e.children=t),e}function Pe(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o<n.length;o++)t["$"+n[o]]=!0;for(n=0;n<e.length;n++)o=t.hasOwnProperty("$"+e[n].value),e[n].selected!==o&&(e[n].selected=o),o&&r&&(e[n].defaultSelected=!0)}else{for(n=""+ge(n),t=null,o=0;o<e.length;o++){if(e[o].value===n)return e[o].selected=!0,void(r&&(e[o].defaultSelected=!0));null!==t||e[o].disabled||(t=e[o])}null!==t&&(t.selected=!0)}}function Ae(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(a(91));return o({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function Te(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(a(92));if(Array.isArray(n)){if(!(1>=n.length))throw Error(a(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:ge(n)}}function Le(e,t){var n=ge(t.value),r=ge(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function Re(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}function Me(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function De(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?Me(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var Ie,Fe,Ne=(Fe=function(e,t){if("http://www.w3.org/2000/svg"!==e.namespaceURI||"innerHTML"in e)e.innerHTML=t;else{for((Ie=Ie||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=Ie.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return Fe(e,t)}))}:Fe);function ze(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}function qe(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var $e={animationend:qe("Animation","AnimationEnd"),animationiteration:qe("Animation","AnimationIteration"),animationstart:qe("Animation","AnimationStart"),transitionend:qe("Transition","TransitionEnd")},Be={},Ue={};function Ve(e){if(Be[e])return Be[e];if(!$e[e])return e;var t,n=$e[e];for(t in n)if(n.hasOwnProperty(t)&&t in Ue)return Be[e]=n[t];return e}C&&(Ue=document.createElement("div").style,"AnimationEvent"in window||(delete $e.animationend.animation,delete $e.animationiteration.animation,delete $e.animationstart.animation),"TransitionEvent"in window||delete $e.transitionend.transition);var We=Ve("animationend"),He=Ve("animationiteration"),Ze=Ve("animationstart"),Ke=Ve("transitionend"),Qe="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Ge=new("function"==typeof WeakMap?WeakMap:Map);function Xe(e){var t=Ge.get(e);return void 0===t&&(t=new Map,Ge.set(e,t)),t}function Ye(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{0!=(1026&(t=e).effectTag)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Je(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&null!==(e=e.alternate)&&(t=e.memoizedState),null!==t)return t.dehydrated}return null}function et(e){if(Ye(e)!==e)throw Error(a(188))}function tt(e){if(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ye(e)))throw Error(a(188));return t!==e?null:e}for(var n=e,r=t;;){var o=n.return;if(null===o)break;var i=o.alternate;if(null===i){if(null!==(r=o.return)){n=r;continue}break}if(o.child===i.child){for(i=o.child;i;){if(i===n)return et(o),e;if(i===r)return et(o),t;i=i.sibling}throw Error(a(188))}if(n.return!==r.return)n=o,r=i;else{for(var l=!1,u=o.child;u;){if(u===n){l=!0,n=o,r=i;break}if(u===r){l=!0,r=o,n=i;break}u=u.sibling}if(!l){for(u=i.child;u;){if(u===n){l=!0,n=i,r=o;break}if(u===r){l=!0,r=i,n=o;break}u=u.sibling}if(!l)throw Error(a(189))}}if(n.alternate!==r)throw Error(a(190))}if(3!==n.tag)throw Error(a(188));return n.stateNode.current===n?e:t}(e),!e)return null;for(var t=e;;){if(5===t.tag||6===t.tag)return t;if(t.child)t.child.return=t,t=t.child;else{if(t===e)break;for(;!t.sibling;){if(!t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function nt(e,t){if(null==t)throw Error(a(30));return null==e?t:Array.isArray(e)?Array.isArray(t)?(e.push.apply(e,t),e):(e.push(t),e):Array.isArray(t)?[e].concat(t):[e,t]}function rt(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)}var ot=null;function it(e){if(e){var t=e._dispatchListeners,n=e._dispatchInstances;if(Array.isArray(t))for(var r=0;r<t.length&&!e.isPropagationStopped();r++)y(e,t[r],n[r]);else t&&y(e,t,n);e._dispatchListeners=null,e._dispatchInstances=null,e.isPersistent()||e.constructor.release(e)}}function at(e){if(null!==e&&(ot=nt(ot,e)),e=ot,ot=null,e){if(rt(e,it),ot)throw Error(a(95));if(c)throw e=f,c=!1,f=null,e}}function lt(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}function ut(e){if(!C)return!1;var t=(e="on"+e)in document;return t||((t=document.createElement("div")).setAttribute(e,"return;"),t="function"==typeof t[e]),t}var st=[];function ct(e){e.topLevelType=null,e.nativeEvent=null,e.targetInst=null,e.ancestors.length=0,10>st.length&&st.push(e)}function ft(e,t,n,r){if(st.length){var o=st.pop();return o.topLevelType=e,o.eventSystemFlags=r,o.nativeEvent=t,o.targetInst=n,o}return{topLevelType:e,eventSystemFlags:r,nativeEvent:t,targetInst:n,ancestors:[]}}function pt(e){var t=e.targetInst,n=t;do{if(!n){e.ancestors.push(n);break}var r=n;if(3===r.tag)r=r.stateNode.containerInfo;else{for(;r.return;)r=r.return;r=3!==r.tag?null:r.stateNode.containerInfo}if(!r)break;5!==(t=n.tag)&&6!==t||e.ancestors.push(n),n=Pn(r)}while(n);for(n=0;n<e.ancestors.length;n++){t=e.ancestors[n];var o=lt(e.nativeEvent);r=e.topLevelType;var i=e.nativeEvent,a=e.eventSystemFlags;0===n&&(a|=64);for(var l=null,u=0;u<x.length;u++){var s=x[u];s&&(s=s.extractEvents(r,t,i,o,a))&&(l=nt(l,s))}at(l)}}function dt(e,t,n){if(!n.has(e)){switch(e){case"scroll":Zt(t,"scroll",!0);break;case"focus":case"blur":Zt(t,"focus",!0),Zt(t,"blur",!0),n.set("blur",null),n.set("focus",null);break;case"cancel":case"close":ut(e)&&Zt(t,e,!0);break;case"invalid":case"submit":case"reset":break;default:-1===Qe.indexOf(e)&&Ht(e,t)}n.set(e,null)}}var ht,mt,bt,yt=!1,gt=[],vt=null,wt=null,_t=null,xt=new Map,Ot=new Map,St=[],kt="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput close cancel copy cut paste click change contextmenu reset submit".split(" "),jt="focus blur dragenter dragleave mouseover mouseout pointerover pointerout gotpointercapture lostpointercapture".split(" ");function Ct(e,t,n,r,o){return{blockedOn:e,topLevelType:t,eventSystemFlags:32|n,nativeEvent:o,container:r}}function Et(e,t){switch(e){case"focus":case"blur":vt=null;break;case"dragenter":case"dragleave":wt=null;break;case"mouseover":case"mouseout":_t=null;break;case"pointerover":case"pointerout":xt.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":Ot.delete(t.pointerId)}}function Pt(e,t,n,r,o,i){return null===e||e.nativeEvent!==i?(e=Ct(t,n,r,o,i),null!==t&&null!==(t=An(t))&&mt(t),e):(e.eventSystemFlags|=r,e)}function At(e){var t=Pn(e.target);if(null!==t){var n=Ye(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Je(n)))return e.blockedOn=t,void i.unstable_runWithPriority(e.priority,(function(){bt(n)}))}else if(3===t&&n.stateNode.hydrate)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function Tt(e){if(null!==e.blockedOn)return!1;var t=Xt(e.topLevelType,e.eventSystemFlags,e.container,e.nativeEvent);if(null!==t){var n=An(t);return null!==n&&mt(n),e.blockedOn=t,!1}return!0}function Lt(e,t,n){Tt(e)&&n.delete(t)}function Rt(){for(yt=!1;0<gt.length;){var e=gt[0];if(null!==e.blockedOn){null!==(e=An(e.blockedOn))&&ht(e);break}var t=Xt(e.topLevelType,e.eventSystemFlags,e.container,e.nativeEvent);null!==t?e.blockedOn=t:gt.shift()}null!==vt&&Tt(vt)&&(vt=null),null!==wt&&Tt(wt)&&(wt=null),null!==_t&&Tt(_t)&&(_t=null),xt.forEach(Lt),Ot.forEach(Lt)}function Mt(e,t){e.blockedOn===t&&(e.blockedOn=null,yt||(yt=!0,i.unstable_scheduleCallback(i.unstable_NormalPriority,Rt)))}function Dt(e){function t(t){return Mt(t,e)}if(0<gt.length){Mt(gt[0],e);for(var n=1;n<gt.length;n++){var r=gt[n];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==vt&&Mt(vt,e),null!==wt&&Mt(wt,e),null!==_t&&Mt(_t,e),xt.forEach(t),Ot.forEach(t),n=0;n<St.length;n++)(r=St[n]).blockedOn===e&&(r.blockedOn=null);for(;0<St.length&&null===(n=St[0]).blockedOn;)At(n),null===n.blockedOn&&St.shift()}var It={},Ft=new Map,Nt=new Map,zt=["abort","abort",We,"animationEnd",He,"animationIteration",Ze,"animationStart","canplay","canPlay","canplaythrough","canPlayThrough","durationchange","durationChange","emptied","emptied","encrypted","encrypted","ended","ended","error","error","gotpointercapture","gotPointerCapture","load","load","loadeddata","loadedData","loadedmetadata","loadedMetadata","loadstart","loadStart","lostpointercapture","lostPointerCapture","playing","playing","progress","progress","seeking","seeking","stalled","stalled","suspend","suspend","timeupdate","timeUpdate",Ke,"transitionEnd","waiting","waiting"];function qt(e,t){for(var n=0;n<e.length;n+=2){var r=e[n],o=e[n+1],i="on"+(o[0].toUpperCase()+o.slice(1));i={phasedRegistrationNames:{bubbled:i,captured:i+"Capture"},dependencies:[r],eventPriority:t},Nt.set(r,t),Ft.set(r,i),It[o]=i}}qt("blur blur cancel cancel click click close close contextmenu contextMenu copy copy cut cut auxclick auxClick dblclick doubleClick dragend dragEnd dragstart dragStart drop drop focus focus input input invalid invalid keydown keyDown keypress keyPress keyup keyUp mousedown mouseDown mouseup mouseUp paste paste pause pause play play pointercancel pointerCancel pointerdown pointerDown pointerup pointerUp ratechange rateChange reset reset seeked seeked submit submit touchcancel touchCancel touchend touchEnd touchstart touchStart volumechange volumeChange".split(" "),0),qt("drag drag dragenter dragEnter dragexit dragExit dragleave dragLeave dragover dragOver mousemove mouseMove mouseout mouseOut mouseover mouseOver pointermove pointerMove pointerout pointerOut pointerover pointerOver scroll scroll toggle toggle touchmove touchMove wheel wheel".split(" "),1),qt(zt,2);for(var $t="change selectionchange textInput compositionstart compositionend compositionupdate".split(" "),Bt=0;Bt<$t.length;Bt++)Nt.set($t[Bt],0);var Ut=i.unstable_UserBlockingPriority,Vt=i.unstable_runWithPriority,Wt=!0;function Ht(e,t){Zt(t,e,!1)}function Zt(e,t,n){var r=Nt.get(t);switch(void 0===r?2:r){case 0:r=Kt.bind(null,t,1,e);break;case 1:r=Qt.bind(null,t,1,e);break;default:r=Gt.bind(null,t,1,e)}n?e.addEventListener(t,r,!0):e.addEventListener(t,r,!1)}function Kt(e,t,n,r){N||I();var o=Gt,i=N;N=!0;try{D(o,e,t,n,r)}finally{(N=i)||q()}}function Qt(e,t,n,r){Vt(Ut,Gt.bind(null,e,t,n,r))}function Gt(e,t,n,r){if(Wt)if(0<gt.length&&-1<kt.indexOf(e))e=Ct(null,e,t,n,r),gt.push(e);else{var o=Xt(e,t,n,r);if(null===o)Et(e,r);else if(-1<kt.indexOf(e))e=Ct(o,e,t,n,r),gt.push(e);else if(!function(e,t,n,r,o){switch(t){case"focus":return vt=Pt(vt,e,t,n,r,o),!0;case"dragenter":return wt=Pt(wt,e,t,n,r,o),!0;case"mouseover":return _t=Pt(_t,e,t,n,r,o),!0;case"pointerover":var i=o.pointerId;return xt.set(i,Pt(xt.get(i)||null,e,t,n,r,o)),!0;case"gotpointercapture":return i=o.pointerId,Ot.set(i,Pt(Ot.get(i)||null,e,t,n,r,o)),!0}return!1}(o,e,t,n,r)){Et(e,r),e=ft(e,r,null,t);try{$(pt,e)}finally{ct(e)}}}}function Xt(e,t,n,r){if(null!==(n=Pn(n=lt(r)))){var o=Ye(n);if(null===o)n=null;else{var i=o.tag;if(13===i){if(null!==(n=Je(o)))return n;n=null}else if(3===i){if(o.stateNode.hydrate)return 3===o.tag?o.stateNode.containerInfo:null;n=null}else o!==n&&(n=null)}}e=ft(e,r,n,t);try{$(pt,e)}finally{ct(e)}return null}var Yt={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Jt=["Webkit","ms","Moz","O"];function en(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||Yt.hasOwnProperty(e)&&Yt[e]?(""+t).trim():t+"px"}function tn(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),o=en(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}Object.keys(Yt).forEach((function(e){Jt.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Yt[t]=Yt[e]}))}));var nn=o({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function rn(e,t){if(t){if(nn[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(a(137,e,""));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(a(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(a(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(a(62,""))}}function on(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var an="http://www.w3.org/1999/xhtml";function ln(e,t){var n=Xe(e=9===e.nodeType||11===e.nodeType?e:e.ownerDocument);t=k[t];for(var r=0;r<t.length;r++)dt(t[r],e,n)}function un(){}function sn(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function cn(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function fn(e,t){var n,r=cn(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=cn(r)}}function pn(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?pn(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function dn(){for(var e=window,t=sn();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(e){n=!1}if(!n)break;t=sn((e=t.contentWindow).document)}return t}function hn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}var mn="$?",bn="$!",yn=null,gn=null;function vn(e,t){switch(e){case"button":case"input":case"select":case"textarea":return!!t.autoFocus}return!1}function wn(e,t){return"textarea"===e||"option"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var _n="function"==typeof setTimeout?setTimeout:void 0,xn="function"==typeof clearTimeout?clearTimeout:void 0;function On(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break}return e}function Sn(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||n===bn||n===mn){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var kn=Math.random().toString(36).slice(2),jn="__reactInternalInstance$"+kn,Cn="__reactEventHandlers$"+kn,En="__reactContainere$"+kn;function Pn(e){var t=e[jn];if(t)return t;for(var n=e.parentNode;n;){if(t=n[En]||n[jn]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=Sn(e);null!==e;){if(n=e[jn])return n;e=Sn(e)}return t}n=(e=n).parentNode}return null}function An(e){return!(e=e[jn]||e[En])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function Tn(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(a(33))}function Ln(e){return e[Cn]||null}function Rn(e){do{e=e.return}while(e&&5!==e.tag);return e||null}function Mn(e,t){var n=e.stateNode;if(!n)return null;var r=h(n);if(!r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(a(231,t,typeof n));return n}function Dn(e,t,n){(t=Mn(e,n.dispatchConfig.phasedRegistrationNames[t]))&&(n._dispatchListeners=nt(n._dispatchListeners,t),n._dispatchInstances=nt(n._dispatchInstances,e))}function In(e){if(e&&e.dispatchConfig.phasedRegistrationNames){for(var t=e._targetInst,n=[];t;)n.push(t),t=Rn(t);for(t=n.length;0<t--;)Dn(n[t],"captured",e);for(t=0;t<n.length;t++)Dn(n[t],"bubbled",e)}}function Fn(e,t,n){e&&n&&n.dispatchConfig.registrationName&&(t=Mn(e,n.dispatchConfig.registrationName))&&(n._dispatchListeners=nt(n._dispatchListeners,t),n._dispatchInstances=nt(n._dispatchInstances,e))}function Nn(e){e&&e.dispatchConfig.registrationName&&Fn(e._targetInst,null,e)}function zn(e){rt(e,In)}var qn=null,$n=null,Bn=null;function Un(){if(Bn)return Bn;var e,t,n=$n,r=n.length,o="value"in qn?qn.value:qn.textContent,i=o.length;for(e=0;e<r&&n[e]===o[e];e++);var a=r-e;for(t=1;t<=a&&n[r-t]===o[i-t];t++);return Bn=o.slice(e,1<t?1-t:void 0)}function Vn(){return!0}function Wn(){return!1}function Hn(e,t,n,r){for(var o in this.dispatchConfig=e,this._targetInst=t,this.nativeEvent=n,e=this.constructor.Interface)e.hasOwnProperty(o)&&((t=e[o])?this[o]=t(n):"target"===o?this.target=r:this[o]=n[o]);return this.isDefaultPrevented=(null!=n.defaultPrevented?n.defaultPrevented:!1===n.returnValue)?Vn:Wn,this.isPropagationStopped=Wn,this}function Zn(e,t,n,r){if(this.eventPool.length){var o=this.eventPool.pop();return this.call(o,e,t,n,r),o}return new this(e,t,n,r)}function Kn(e){if(!(e instanceof this))throw Error(a(279));e.destructor(),10>this.eventPool.length&&this.eventPool.push(e)}function Qn(e){e.eventPool=[],e.getPooled=Zn,e.release=Kn}o(Hn.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=Vn)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=Vn)},persist:function(){this.isPersistent=Vn},isPersistent:Wn,destructor:function(){var e,t=this.constructor.Interface;for(e in t)this[e]=null;this.nativeEvent=this._targetInst=this.dispatchConfig=null,this.isPropagationStopped=this.isDefaultPrevented=Wn,this._dispatchInstances=this._dispatchListeners=null}}),Hn.Interface={type:null,target:null,currentTarget:function(){return null},eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null},Hn.extend=function(e){function t(){}function n(){return r.apply(this,arguments)}var r=this;t.prototype=r.prototype;var i=new t;return o(i,n.prototype),n.prototype=i,n.prototype.constructor=n,n.Interface=o({},r.Interface,e),n.extend=r.extend,Qn(n),n},Qn(Hn);var Gn=Hn.extend({data:null}),Xn=Hn.extend({data:null}),Yn=[9,13,27,32],Jn=C&&"CompositionEvent"in window,er=null;C&&"documentMode"in document&&(er=document.documentMode);var tr=C&&"TextEvent"in window&&!er,nr=C&&(!Jn||er&&8<er&&11>=er),rr=String.fromCharCode(32),or={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["compositionend","keypress","textInput","paste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:"blur compositionend keydown keypress keyup mousedown".split(" ")},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:"blur compositionstart keydown keypress keyup mousedown".split(" ")},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:"blur compositionupdate keydown keypress keyup mousedown".split(" ")}},ir=!1;function ar(e,t){switch(e){case"keyup":return-1!==Yn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"blur":return!0;default:return!1}}function lr(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var ur=!1,sr={eventTypes:or,extractEvents:function(e,t,n,r){var o;if(Jn)e:{switch(e){case"compositionstart":var i=or.compositionStart;break e;case"compositionend":i=or.compositionEnd;break e;case"compositionupdate":i=or.compositionUpdate;break e}i=void 0}else ur?ar(e,n)&&(i=or.compositionEnd):"keydown"===e&&229===n.keyCode&&(i=or.compositionStart);return i?(nr&&"ko"!==n.locale&&(ur||i!==or.compositionStart?i===or.compositionEnd&&ur&&(o=Un()):($n="value"in(qn=r)?qn.value:qn.textContent,ur=!0)),i=Gn.getPooled(i,t,n,r),(o||null!==(o=lr(n)))&&(i.data=o),zn(i),o=i):o=null,(e=tr?function(e,t){switch(e){case"compositionend":return lr(t);case"keypress":return 32!==t.which?null:(ir=!0,rr);case"textInput":return(e=t.data)===rr&&ir?null:e;default:return null}}(e,n):function(e,t){if(ur)return"compositionend"===e||!Jn&&ar(e,t)?(e=Un(),Bn=$n=qn=null,ur=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return nr&&"ko"!==t.locale?null:t.data}}(e,n))?((t=Xn.getPooled(or.beforeInput,t,n,r)).data=e,zn(t)):t=null,null===o?t:null===t?o:[o,t]}},cr={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function fr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!cr[e.type]:"textarea"===t}var pr={change:{phasedRegistrationNames:{bubbled:"onChange",captured:"onChangeCapture"},dependencies:"blur change click focus input keydown keyup selectionchange".split(" ")}};function dr(e,t,n){return(e=Hn.getPooled(pr.change,e,t,n)).type="change",L(n),zn(e),e}var hr=null,mr=null;function br(e){at(e)}function yr(e){if(_e(Tn(e)))return e}function gr(e,t){if("change"===e)return t}var vr=!1;function wr(){hr&&(hr.detachEvent("onpropertychange",_r),mr=hr=null)}function _r(e){if("value"===e.propertyName&&yr(mr))if(e=dr(mr,e,lt(e)),N)at(e);else{N=!0;try{M(br,e)}finally{N=!1,q()}}}function xr(e,t,n){"focus"===e?(wr(),mr=n,(hr=t).attachEvent("onpropertychange",_r)):"blur"===e&&wr()}function Or(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return yr(mr)}function Sr(e,t){if("click"===e)return yr(t)}function kr(e,t){if("input"===e||"change"===e)return yr(t)}C&&(vr=ut("input")&&(!document.documentMode||9<document.documentMode));var jr={eventTypes:pr,_isInputEventSupported:vr,extractEvents:function(e,t,n,r){var o=t?Tn(t):window,i=o.nodeName&&o.nodeName.toLowerCase();if("select"===i||"input"===i&&"file"===o.type)var a=gr;else if(fr(o))if(vr)a=kr;else{a=Or;var l=xr}else(i=o.nodeName)&&"input"===i.toLowerCase()&&("checkbox"===o.type||"radio"===o.type)&&(a=Sr);if(a&&(a=a(e,t)))return dr(a,n,r);l&&l(e,o,t),"blur"===e&&(e=o._wrapperState)&&e.controlled&&"number"===o.type&&Ce(o,"number",o.value)}},Cr=Hn.extend({view:null,detail:null}),Er={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Pr(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=Er[e])&&!!t[e]}function Ar(){return Pr}var Tr=0,Lr=0,Rr=!1,Mr=!1,Dr=Cr.extend({screenX:null,screenY:null,clientX:null,clientY:null,pageX:null,pageY:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,getModifierState:Ar,button:null,buttons:null,relatedTarget:function(e){return e.relatedTarget||(e.fromElement===e.srcElement?e.toElement:e.fromElement)},movementX:function(e){if("movementX"in e)return e.movementX;var t=Tr;return Tr=e.screenX,Rr?"mousemove"===e.type?e.screenX-t:0:(Rr=!0,0)},movementY:function(e){if("movementY"in e)return e.movementY;var t=Lr;return Lr=e.screenY,Mr?"mousemove"===e.type?e.screenY-t:0:(Mr=!0,0)}}),Ir=Dr.extend({pointerId:null,width:null,height:null,pressure:null,tangentialPressure:null,tiltX:null,tiltY:null,twist:null,pointerType:null,isPrimary:null}),Fr={mouseEnter:{registrationName:"onMouseEnter",dependencies:["mouseout","mouseover"]},mouseLeave:{registrationName:"onMouseLeave",dependencies:["mouseout","mouseover"]},pointerEnter:{registrationName:"onPointerEnter",dependencies:["pointerout","pointerover"]},pointerLeave:{registrationName:"onPointerLeave",dependencies:["pointerout","pointerover"]}},Nr={eventTypes:Fr,extractEvents:function(e,t,n,r,o){var i="mouseover"===e||"pointerover"===e,a="mouseout"===e||"pointerout"===e;if(i&&0==(32&o)&&(n.relatedTarget||n.fromElement)||!a&&!i)return null;if(i=r.window===r?r:(i=r.ownerDocument)?i.defaultView||i.parentWindow:window,a?(a=t,null!==(t=(t=n.relatedTarget||n.toElement)?Pn(t):null)&&(t!==Ye(t)||5!==t.tag&&6!==t.tag)&&(t=null)):a=null,a===t)return null;if("mouseout"===e||"mouseover"===e)var l=Dr,u=Fr.mouseLeave,s=Fr.mouseEnter,c="mouse";else"pointerout"!==e&&"pointerover"!==e||(l=Ir,u=Fr.pointerLeave,s=Fr.pointerEnter,c="pointer");if(e=null==a?i:Tn(a),i=null==t?i:Tn(t),(u=l.getPooled(u,a,n,r)).type=c+"leave",u.target=e,u.relatedTarget=i,(n=l.getPooled(s,t,n,r)).type=c+"enter",n.target=i,n.relatedTarget=e,c=t,(r=a)&&c)e:{for(s=c,a=0,e=l=r;e;e=Rn(e))a++;for(e=0,t=s;t;t=Rn(t))e++;for(;0<a-e;)l=Rn(l),a--;for(;0<e-a;)s=Rn(s),e--;for(;a--;){if(l===s||l===s.alternate)break e;l=Rn(l),s=Rn(s)}l=null}else l=null;for(s=l,l=[];r&&r!==s&&(null===(a=r.alternate)||a!==s);)l.push(r),r=Rn(r);for(r=[];c&&c!==s&&(null===(a=c.alternate)||a!==s);)r.push(c),c=Rn(c);for(c=0;c<l.length;c++)Fn(l[c],"bubbled",u);for(c=r.length;0<c--;)Fn(r[c],"captured",n);return 0==(64&o)?[u]:[u,n]}},zr="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},qr=Object.prototype.hasOwnProperty;function $r(e,t){if(zr(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++)if(!qr.call(t,n[r])||!zr(e[n[r]],t[n[r]]))return!1;return!0}var Br=C&&"documentMode"in document&&11>=document.documentMode,Ur={select:{phasedRegistrationNames:{bubbled:"onSelect",captured:"onSelectCapture"},dependencies:"blur contextmenu dragend focus keydown keyup mousedown mouseup selectionchange".split(" ")}},Vr=null,Wr=null,Hr=null,Zr=!1;function Kr(e,t){var n=t.window===t?t.document:9===t.nodeType?t:t.ownerDocument;return Zr||null==Vr||Vr!==sn(n)?null:(n="selectionStart"in(n=Vr)&&hn(n)?{start:n.selectionStart,end:n.selectionEnd}:{anchorNode:(n=(n.ownerDocument&&n.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:n.anchorOffset,focusNode:n.focusNode,focusOffset:n.focusOffset},Hr&&$r(Hr,n)?null:(Hr=n,(e=Hn.getPooled(Ur.select,Wr,e,t)).type="select",e.target=Vr,zn(e),e))}var Qr={eventTypes:Ur,extractEvents:function(e,t,n,r,o,i){if(!(i=!(o=i||(r.window===r?r.document:9===r.nodeType?r:r.ownerDocument)))){e:{o=Xe(o),i=k.onSelect;for(var a=0;a<i.length;a++)if(!o.has(i[a])){o=!1;break e}o=!0}i=!o}if(i)return null;switch(o=t?Tn(t):window,e){case"focus":(fr(o)||"true"===o.contentEditable)&&(Vr=o,Wr=t,Hr=null);break;case"blur":Hr=Wr=Vr=null;break;case"mousedown":Zr=!0;break;case"contextmenu":case"mouseup":case"dragend":return Zr=!1,Kr(n,r);case"selectionchange":if(Br)break;case"keydown":case"keyup":return Kr(n,r)}return null}},Gr=Hn.extend({animationName:null,elapsedTime:null,pseudoElement:null}),Xr=Hn.extend({clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),Yr=Cr.extend({relatedTarget:null});function Jr(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}var eo={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},to={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},no=Cr.extend({key:function(e){if(e.key){var t=eo[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=Jr(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?to[e.keyCode]||"Unidentified":""},location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:Ar,charCode:function(e){return"keypress"===e.type?Jr(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?Jr(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),ro=Dr.extend({dataTransfer:null}),oo=Cr.extend({touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:Ar}),io=Hn.extend({propertyName:null,elapsedTime:null,pseudoElement:null}),ao=Dr.extend({deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:null,deltaMode:null}),lo={eventTypes:It,extractEvents:function(e,t,n,r){var o=Ft.get(e);if(!o)return null;switch(e){case"keypress":if(0===Jr(n))return null;case"keydown":case"keyup":e=no;break;case"blur":case"focus":e=Yr;break;case"click":if(2===n.button)return null;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":e=Dr;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":e=ro;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":e=oo;break;case We:case He:case Ze:e=Gr;break;case Ke:e=io;break;case"scroll":e=Cr;break;case"wheel":e=ao;break;case"copy":case"cut":case"paste":e=Xr;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":e=Ir;break;default:e=Hn}return zn(t=e.getPooled(o,t,n,r)),t}};if(g)throw Error(a(101));g=Array.prototype.slice.call("ResponderEventPlugin SimpleEventPlugin EnterLeaveEventPlugin ChangeEventPlugin SelectEventPlugin BeforeInputEventPlugin".split(" ")),w(),h=Ln,m=An,b=Tn,j({SimpleEventPlugin:lo,EnterLeaveEventPlugin:Nr,ChangeEventPlugin:jr,SelectEventPlugin:Qr,BeforeInputEventPlugin:sr});var uo=[],so=-1;function co(e){0>so||(e.current=uo[so],uo[so]=null,so--)}function fo(e,t){so++,uo[so]=e.current,e.current=t}var po={},ho={current:po},mo={current:!1},bo=po;function yo(e,t){var n=e.type.contextTypes;if(!n)return po;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o,i={};for(o in n)i[o]=t[o];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=i),i}function go(e){return null!=e.childContextTypes}function vo(){co(mo),co(ho)}function wo(e,t,n){if(ho.current!==po)throw Error(a(168));fo(ho,t),fo(mo,n)}function _o(e,t,n){var r=e.stateNode;if(e=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var i in r=r.getChildContext())if(!(i in e))throw Error(a(108,be(t)||"Unknown",i));return o({},n,{},r)}function xo(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||po,bo=ho.current,fo(ho,e),fo(mo,mo.current),!0}function Oo(e,t,n){var r=e.stateNode;if(!r)throw Error(a(169));n?(e=_o(e,t,bo),r.__reactInternalMemoizedMergedChildContext=e,co(mo),co(ho),fo(ho,e)):co(mo),fo(mo,n)}var So=i.unstable_runWithPriority,ko=i.unstable_scheduleCallback,jo=i.unstable_cancelCallback,Co=i.unstable_requestPaint,Eo=i.unstable_now,Po=i.unstable_getCurrentPriorityLevel,Ao=i.unstable_ImmediatePriority,To=i.unstable_UserBlockingPriority,Lo=i.unstable_NormalPriority,Ro=i.unstable_LowPriority,Mo=i.unstable_IdlePriority,Do={},Io=i.unstable_shouldYield,Fo=void 0!==Co?Co:function(){},No=null,zo=null,qo=!1,$o=Eo(),Bo=1e4>$o?Eo:function(){return Eo()-$o};function Uo(){switch(Po()){case Ao:return 99;case To:return 98;case Lo:return 97;case Ro:return 96;case Mo:return 95;default:throw Error(a(332))}}function Vo(e){switch(e){case 99:return Ao;case 98:return To;case 97:return Lo;case 96:return Ro;case 95:return Mo;default:throw Error(a(332))}}function Wo(e,t){return e=Vo(e),So(e,t)}function Ho(e,t,n){return e=Vo(e),ko(e,t,n)}function Zo(e){return null===No?(No=[e],zo=ko(Ao,Qo)):No.push(e),Do}function Ko(){if(null!==zo){var e=zo;zo=null,jo(e)}Qo()}function Qo(){if(!qo&&null!==No){qo=!0;var e=0;try{var t=No;Wo(99,(function(){for(;e<t.length;e++){var n=t[e];do{n=n(!0)}while(null!==n)}})),No=null}catch(t){throw null!==No&&(No=No.slice(e+1)),ko(Ao,Ko),t}finally{qo=!1}}}function Go(e,t,n){return 1073741821-(1+((1073741821-e+t/10)/(n/=10)|0))*n}function Xo(e,t){if(e&&e.defaultProps)for(var n in t=o({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}var Yo={current:null},Jo=null,ei=null,ti=null;function ni(){ti=ei=Jo=null}function ri(e){var t=Yo.current;co(Yo),e.type._context._currentValue=t}function oi(e,t){for(;null!==e;){var n=e.alternate;if(e.childExpirationTime<t)e.childExpirationTime=t,null!==n&&n.childExpirationTime<t&&(n.childExpirationTime=t);else{if(!(null!==n&&n.childExpirationTime<t))break;n.childExpirationTime=t}e=e.return}}function ii(e,t){Jo=e,ti=ei=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(e.expirationTime>=t&&(La=!0),e.firstContext=null)}function ai(e,t){if(ti!==e&&!1!==t&&0!==t)if("number"==typeof t&&1073741823!==t||(ti=e,t=1073741823),t={context:e,observedBits:t,next:null},null===ei){if(null===Jo)throw Error(a(308));ei=t,Jo.dependencies={expirationTime:0,firstContext:t,responders:null}}else ei=ei.next=t;return e._currentValue}var li=!1;function ui(e){e.updateQueue={baseState:e.memoizedState,baseQueue:null,shared:{pending:null},effects:null}}function si(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,baseQueue:e.baseQueue,shared:e.shared,effects:e.effects})}function ci(e,t){return(e={expirationTime:e,suspenseConfig:t,tag:0,payload:null,callback:null,next:null}).next=e}function fi(e,t){if(null!==(e=e.updateQueue)){var n=(e=e.shared).pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}}function pi(e,t){var n=e.alternate;null!==n&&si(n,e),null===(n=(e=e.updateQueue).baseQueue)?(e.baseQueue=t.next=t,t.next=t):(t.next=n.next,n.next=t)}function di(e,t,n,r){var i=e.updateQueue;li=!1;var a=i.baseQueue,l=i.shared.pending;if(null!==l){if(null!==a){var u=a.next;a.next=l.next,l.next=u}a=l,i.shared.pending=null,null!==(u=e.alternate)&&null!==(u=u.updateQueue)&&(u.baseQueue=l)}if(null!==a){u=a.next;var s=i.baseState,c=0,f=null,p=null,d=null;if(null!==u)for(var h=u;;){if((l=h.expirationTime)<r){var m={expirationTime:h.expirationTime,suspenseConfig:h.suspenseConfig,tag:h.tag,payload:h.payload,callback:h.callback,next:null};null===d?(p=d=m,f=s):d=d.next=m,l>c&&(c=l)}else{null!==d&&(d=d.next={expirationTime:1073741823,suspenseConfig:h.suspenseConfig,tag:h.tag,payload:h.payload,callback:h.callback,next:null}),su(l,h.suspenseConfig);e:{var b=e,y=h;switch(l=t,m=n,y.tag){case 1:if("function"==typeof(b=y.payload)){s=b.call(m,s,l);break e}s=b;break e;case 3:b.effectTag=-4097&b.effectTag|64;case 0:if(null==(l="function"==typeof(b=y.payload)?b.call(m,s,l):b))break e;s=o({},s,l);break e;case 2:li=!0}}null!==h.callback&&(e.effectTag|=32,null===(l=i.effects)?i.effects=[h]:l.push(h))}if(null===(h=h.next)||h===u){if(null===(l=i.shared.pending))break;h=a.next=l.next,l.next=u,i.baseQueue=a=l,i.shared.pending=null}}null===d?f=s:d.next=p,i.baseState=f,i.baseQueue=d,cu(c),e.expirationTime=c,e.memoizedState=s}}function hi(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var r=e[t],o=r.callback;if(null!==o){if(r.callback=null,r=o,o=n,"function"!=typeof r)throw Error(a(191,r));r.call(o)}}}var mi=G.ReactCurrentBatchConfig,bi=(new r.Component).refs;function yi(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:o({},t,n),e.memoizedState=n,0===e.expirationTime&&(e.updateQueue.baseState=n)}var gi={isMounted:function(e){return!!(e=e._reactInternalFiber)&&Ye(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternalFiber;var r=Gl(),o=mi.suspense;(o=ci(r=Xl(r,e,o),o)).payload=t,null!=n&&(o.callback=n),fi(e,o),Yl(e,r)},enqueueReplaceState:function(e,t,n){e=e._reactInternalFiber;var r=Gl(),o=mi.suspense;(o=ci(r=Xl(r,e,o),o)).tag=1,o.payload=t,null!=n&&(o.callback=n),fi(e,o),Yl(e,r)},enqueueForceUpdate:function(e,t){e=e._reactInternalFiber;var n=Gl(),r=mi.suspense;(r=ci(n=Xl(n,e,r),r)).tag=2,null!=t&&(r.callback=t),fi(e,r),Yl(e,n)}};function vi(e,t,n,r,o,i,a){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,i,a):!(t.prototype&&t.prototype.isPureReactComponent&&$r(n,r)&&$r(o,i))}function wi(e,t,n){var r=!1,o=po,i=t.contextType;return"object"==typeof i&&null!==i?i=ai(i):(o=go(t)?bo:ho.current,i=(r=null!=(r=t.contextTypes))?yo(e,o):po),t=new t(n,i),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=gi,e.stateNode=t,t._reactInternalFiber=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=o,e.__reactInternalMemoizedMaskedChildContext=i),t}function _i(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&gi.enqueueReplaceState(t,t.state,null)}function xi(e,t,n,r){var o=e.stateNode;o.props=n,o.state=e.memoizedState,o.refs=bi,ui(e);var i=t.contextType;"object"==typeof i&&null!==i?o.context=ai(i):(i=go(t)?bo:ho.current,o.context=yo(e,i)),di(e,n,o,r),o.state=e.memoizedState,"function"==typeof(i=t.getDerivedStateFromProps)&&(yi(e,t,i,n),o.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof o.getSnapshotBeforeUpdate||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||(t=o.state,"function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),t!==o.state&&gi.enqueueReplaceState(o,o.state,null),di(e,n,o,r),o.state=e.memoizedState),"function"==typeof o.componentDidMount&&(e.effectTag|=4)}var Oi=Array.isArray;function Si(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(a(309));var r=n.stateNode}if(!r)throw Error(a(147,e));var o=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===o?t.ref:(t=function(e){var t=r.refs;t===bi&&(t=r.refs={}),null===e?delete t[o]:t[o]=e},t._stringRef=o,t)}if("string"!=typeof e)throw Error(a(284));if(!n._owner)throw Error(a(290,e))}return e}function ki(e,t){if("textarea"!==e.type)throw Error(a(31,"[object Object]"===Object.prototype.toString.call(t)?"object with keys {"+Object.keys(t).join(", ")+"}":t,""))}function ji(e){function t(t,n){if(e){var r=t.lastEffect;null!==r?(r.nextEffect=n,t.lastEffect=n):t.firstEffect=t.lastEffect=n,n.nextEffect=null,n.effectTag=8}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function o(e,t){return(e=Au(e,t)).index=0,e.sibling=null,e}function i(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.effectTag=2,n):r:(t.effectTag=2,n):n}function l(t){return e&&null===t.alternate&&(t.effectTag=2),t}function u(e,t,n,r){return null===t||6!==t.tag?((t=Ru(n,e.mode,r)).return=e,t):((t=o(t,n)).return=e,t)}function s(e,t,n,r){return null!==t&&t.elementType===n.type?((r=o(t,n.props)).ref=Si(e,t,n),r.return=e,r):((r=Tu(n.type,n.key,n.props,null,e.mode,r)).ref=Si(e,t,n),r.return=e,r)}function c(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Mu(n,e.mode,r)).return=e,t):((t=o(t,n.children||[])).return=e,t)}function f(e,t,n,r,i){return null===t||7!==t.tag?((t=Lu(n,e.mode,r,i)).return=e,t):((t=o(t,n)).return=e,t)}function p(e,t,n){if("string"==typeof t||"number"==typeof t)return(t=Ru(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case ee:return(n=Tu(t.type,t.key,t.props,null,e.mode,n)).ref=Si(e,null,t),n.return=e,n;case te:return(t=Mu(t,e.mode,n)).return=e,t}if(Oi(t)||me(t))return(t=Lu(t,e.mode,n,null)).return=e,t;ki(e,t)}return null}function d(e,t,n,r){var o=null!==t?t.key:null;if("string"==typeof n||"number"==typeof n)return null!==o?null:u(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case ee:return n.key===o?n.type===ne?f(e,t,n.props.children,r,o):s(e,t,n,r):null;case te:return n.key===o?c(e,t,n,r):null}if(Oi(n)||me(n))return null!==o?null:f(e,t,n,r,null);ki(e,n)}return null}function h(e,t,n,r,o){if("string"==typeof r||"number"==typeof r)return u(t,e=e.get(n)||null,""+r,o);if("object"==typeof r&&null!==r){switch(r.$$typeof){case ee:return e=e.get(null===r.key?n:r.key)||null,r.type===ne?f(t,e,r.props.children,o,r.key):s(t,e,r,o);case te:return c(t,e=e.get(null===r.key?n:r.key)||null,r,o)}if(Oi(r)||me(r))return f(t,e=e.get(n)||null,r,o,null);ki(t,r)}return null}function m(o,a,l,u){for(var s=null,c=null,f=a,m=a=0,b=null;null!==f&&m<l.length;m++){f.index>m?(b=f,f=null):b=f.sibling;var y=d(o,f,l[m],u);if(null===y){null===f&&(f=b);break}e&&f&&null===y.alternate&&t(o,f),a=i(y,a,m),null===c?s=y:c.sibling=y,c=y,f=b}if(m===l.length)return n(o,f),s;if(null===f){for(;m<l.length;m++)null!==(f=p(o,l[m],u))&&(a=i(f,a,m),null===c?s=f:c.sibling=f,c=f);return s}for(f=r(o,f);m<l.length;m++)null!==(b=h(f,o,m,l[m],u))&&(e&&null!==b.alternate&&f.delete(null===b.key?m:b.key),a=i(b,a,m),null===c?s=b:c.sibling=b,c=b);return e&&f.forEach((function(e){return t(o,e)})),s}function b(o,l,u,s){var c=me(u);if("function"!=typeof c)throw Error(a(150));if(null==(u=c.call(u)))throw Error(a(151));for(var f=c=null,m=l,b=l=0,y=null,g=u.next();null!==m&&!g.done;b++,g=u.next()){m.index>b?(y=m,m=null):y=m.sibling;var v=d(o,m,g.value,s);if(null===v){null===m&&(m=y);break}e&&m&&null===v.alternate&&t(o,m),l=i(v,l,b),null===f?c=v:f.sibling=v,f=v,m=y}if(g.done)return n(o,m),c;if(null===m){for(;!g.done;b++,g=u.next())null!==(g=p(o,g.value,s))&&(l=i(g,l,b),null===f?c=g:f.sibling=g,f=g);return c}for(m=r(o,m);!g.done;b++,g=u.next())null!==(g=h(m,o,b,g.value,s))&&(e&&null!==g.alternate&&m.delete(null===g.key?b:g.key),l=i(g,l,b),null===f?c=g:f.sibling=g,f=g);return e&&m.forEach((function(e){return t(o,e)})),c}return function(e,r,i,u){var s="object"==typeof i&&null!==i&&i.type===ne&&null===i.key;s&&(i=i.props.children);var c="object"==typeof i&&null!==i;if(c)switch(i.$$typeof){case ee:e:{for(c=i.key,s=r;null!==s;){if(s.key===c){if(7===s.tag){if(i.type===ne){n(e,s.sibling),(r=o(s,i.props.children)).return=e,e=r;break e}}else if(s.elementType===i.type){n(e,s.sibling),(r=o(s,i.props)).ref=Si(e,s,i),r.return=e,e=r;break e}n(e,s);break}t(e,s),s=s.sibling}i.type===ne?((r=Lu(i.props.children,e.mode,u,i.key)).return=e,e=r):((u=Tu(i.type,i.key,i.props,null,e.mode,u)).ref=Si(e,r,i),u.return=e,e=u)}return l(e);case te:e:{for(s=i.key;null!==r;){if(r.key===s){if(4===r.tag&&r.stateNode.containerInfo===i.containerInfo&&r.stateNode.implementation===i.implementation){n(e,r.sibling),(r=o(r,i.children||[])).return=e,e=r;break e}n(e,r);break}t(e,r),r=r.sibling}(r=Mu(i,e.mode,u)).return=e,e=r}return l(e)}if("string"==typeof i||"number"==typeof i)return i=""+i,null!==r&&6===r.tag?(n(e,r.sibling),(r=o(r,i)).return=e,e=r):(n(e,r),(r=Ru(i,e.mode,u)).return=e,e=r),l(e);if(Oi(i))return m(e,r,i,u);if(me(i))return b(e,r,i,u);if(c&&ki(e,i),void 0===i&&!s)switch(e.tag){case 1:case 0:throw e=e.type,Error(a(152,e.displayName||e.name||"Component"))}return n(e,r)}}var Ci=ji(!0),Ei=ji(!1),Pi={},Ai={current:Pi},Ti={current:Pi},Li={current:Pi};function Ri(e){if(e===Pi)throw Error(a(174));return e}function Mi(e,t){switch(fo(Li,t),fo(Ti,e),fo(Ai,Pi),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:De(null,"");break;default:t=De(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}co(Ai),fo(Ai,t)}function Di(){co(Ai),co(Ti),co(Li)}function Ii(e){Ri(Li.current);var t=Ri(Ai.current),n=De(t,e.type);t!==n&&(fo(Ti,e),fo(Ai,n))}function Fi(e){Ti.current===e&&(co(Ai),co(Ti))}var Ni={current:0};function zi(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||n.data===mn||n.data===bn))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(64&t.effectTag))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}function qi(e,t){return{responder:e,props:t}}var $i=G.ReactCurrentDispatcher,Bi=G.ReactCurrentBatchConfig,Ui=0,Vi=null,Wi=null,Hi=null,Zi=!1;function Ki(){throw Error(a(321))}function Qi(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!zr(e[n],t[n]))return!1;return!0}function Gi(e,t,n,r,o,i){if(Ui=i,Vi=t,t.memoizedState=null,t.updateQueue=null,t.expirationTime=0,$i.current=null===e||null===e.memoizedState?va:wa,e=n(r,o),t.expirationTime===Ui){i=0;do{if(t.expirationTime=0,!(25>i))throw Error(a(301));i+=1,Hi=Wi=null,t.updateQueue=null,$i.current=_a,e=n(r,o)}while(t.expirationTime===Ui)}if($i.current=ga,t=null!==Wi&&null!==Wi.next,Ui=0,Hi=Wi=Vi=null,Zi=!1,t)throw Error(a(300));return e}function Xi(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===Hi?Vi.memoizedState=Hi=e:Hi=Hi.next=e,Hi}function Yi(){if(null===Wi){var e=Vi.alternate;e=null!==e?e.memoizedState:null}else e=Wi.next;var t=null===Hi?Vi.memoizedState:Hi.next;if(null!==t)Hi=t,Wi=e;else{if(null===e)throw Error(a(310));e={memoizedState:(Wi=e).memoizedState,baseState:Wi.baseState,baseQueue:Wi.baseQueue,queue:Wi.queue,next:null},null===Hi?Vi.memoizedState=Hi=e:Hi=Hi.next=e}return Hi}function Ji(e,t){return"function"==typeof t?t(e):t}function ea(e){var t=Yi(),n=t.queue;if(null===n)throw Error(a(311));n.lastRenderedReducer=e;var r=Wi,o=r.baseQueue,i=n.pending;if(null!==i){if(null!==o){var l=o.next;o.next=i.next,i.next=l}r.baseQueue=o=i,n.pending=null}if(null!==o){o=o.next,r=r.baseState;var u=l=i=null,s=o;do{var c=s.expirationTime;if(c<Ui){var f={expirationTime:s.expirationTime,suspenseConfig:s.suspenseConfig,action:s.action,eagerReducer:s.eagerReducer,eagerState:s.eagerState,next:null};null===u?(l=u=f,i=r):u=u.next=f,c>Vi.expirationTime&&(Vi.expirationTime=c,cu(c))}else null!==u&&(u=u.next={expirationTime:1073741823,suspenseConfig:s.suspenseConfig,action:s.action,eagerReducer:s.eagerReducer,eagerState:s.eagerState,next:null}),su(c,s.suspenseConfig),r=s.eagerReducer===e?s.eagerState:e(r,s.action);s=s.next}while(null!==s&&s!==o);null===u?i=r:u.next=l,zr(r,t.memoizedState)||(La=!0),t.memoizedState=r,t.baseState=i,t.baseQueue=u,n.lastRenderedState=r}return[t.memoizedState,n.dispatch]}function ta(e){var t=Yi(),n=t.queue;if(null===n)throw Error(a(311));n.lastRenderedReducer=e;var r=n.dispatch,o=n.pending,i=t.memoizedState;if(null!==o){n.pending=null;var l=o=o.next;do{i=e(i,l.action),l=l.next}while(l!==o);zr(i,t.memoizedState)||(La=!0),t.memoizedState=i,null===t.baseQueue&&(t.baseState=i),n.lastRenderedState=i}return[i,r]}function na(e){var t=Xi();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e=(e=t.queue={pending:null,dispatch:null,lastRenderedReducer:Ji,lastRenderedState:e}).dispatch=ya.bind(null,Vi,e),[t.memoizedState,e]}function ra(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=Vi.updateQueue)?(t={lastEffect:null},Vi.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function oa(){return Yi().memoizedState}function ia(e,t,n,r){var o=Xi();Vi.effectTag|=e,o.memoizedState=ra(1|t,n,void 0,void 0===r?null:r)}function aa(e,t,n,r){var o=Yi();r=void 0===r?null:r;var i=void 0;if(null!==Wi){var a=Wi.memoizedState;if(i=a.destroy,null!==r&&Qi(r,a.deps))return void ra(t,n,i,r)}Vi.effectTag|=e,o.memoizedState=ra(1|t,n,i,r)}function la(e,t){return ia(516,4,e,t)}function ua(e,t){return aa(516,4,e,t)}function sa(e,t){return aa(4,2,e,t)}function ca(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function fa(e,t,n){return n=null!=n?n.concat([e]):null,aa(4,2,ca.bind(null,t,e),n)}function pa(){}function da(e,t){return Xi().memoizedState=[e,void 0===t?null:t],e}function ha(e,t){var n=Yi();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&Qi(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function ma(e,t){var n=Yi();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&Qi(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function ba(e,t,n){var r=Uo();Wo(98>r?98:r,(function(){e(!0)})),Wo(97<r?97:r,(function(){var r=Bi.suspense;Bi.suspense=void 0===t?null:t;try{e(!1),n()}finally{Bi.suspense=r}}))}function ya(e,t,n){var r=Gl(),o=mi.suspense;o={expirationTime:r=Xl(r,e,o),suspenseConfig:o,action:n,eagerReducer:null,eagerState:null,next:null};var i=t.pending;if(null===i?o.next=o:(o.next=i.next,i.next=o),t.pending=o,i=e.alternate,e===Vi||null!==i&&i===Vi)Zi=!0,o.expirationTime=Ui,Vi.expirationTime=Ui;else{if(0===e.expirationTime&&(null===i||0===i.expirationTime)&&null!==(i=t.lastRenderedReducer))try{var a=t.lastRenderedState,l=i(a,n);if(o.eagerReducer=i,o.eagerState=l,zr(l,a))return}catch(e){}Yl(e,r)}}var ga={readContext:ai,useCallback:Ki,useContext:Ki,useEffect:Ki,useImperativeHandle:Ki,useLayoutEffect:Ki,useMemo:Ki,useReducer:Ki,useRef:Ki,useState:Ki,useDebugValue:Ki,useResponder:Ki,useDeferredValue:Ki,useTransition:Ki},va={readContext:ai,useCallback:da,useContext:ai,useEffect:la,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,ia(4,2,ca.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ia(4,2,e,t)},useMemo:function(e,t){var n=Xi();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=Xi();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e=(e=r.queue={pending:null,dispatch:null,lastRenderedReducer:e,lastRenderedState:t}).dispatch=ya.bind(null,Vi,e),[r.memoizedState,e]},useRef:function(e){return e={current:e},Xi().memoizedState=e},useState:na,useDebugValue:pa,useResponder:qi,useDeferredValue:function(e,t){var n=na(e),r=n[0],o=n[1];return la((function(){var n=Bi.suspense;Bi.suspense=void 0===t?null:t;try{o(e)}finally{Bi.suspense=n}}),[e,t]),r},useTransition:function(e){var t=na(!1),n=t[0];return t=t[1],[da(ba.bind(null,t,e),[t,e]),n]}},wa={readContext:ai,useCallback:ha,useContext:ai,useEffect:ua,useImperativeHandle:fa,useLayoutEffect:sa,useMemo:ma,useReducer:ea,useRef:oa,useState:function(){return ea(Ji)},useDebugValue:pa,useResponder:qi,useDeferredValue:function(e,t){var n=ea(Ji),r=n[0],o=n[1];return ua((function(){var n=Bi.suspense;Bi.suspense=void 0===t?null:t;try{o(e)}finally{Bi.suspense=n}}),[e,t]),r},useTransition:function(e){var t=ea(Ji),n=t[0];return t=t[1],[ha(ba.bind(null,t,e),[t,e]),n]}},_a={readContext:ai,useCallback:ha,useContext:ai,useEffect:ua,useImperativeHandle:fa,useLayoutEffect:sa,useMemo:ma,useReducer:ta,useRef:oa,useState:function(){return ta(Ji)},useDebugValue:pa,useResponder:qi,useDeferredValue:function(e,t){var n=ta(Ji),r=n[0],o=n[1];return ua((function(){var n=Bi.suspense;Bi.suspense=void 0===t?null:t;try{o(e)}finally{Bi.suspense=n}}),[e,t]),r},useTransition:function(e){var t=ta(Ji),n=t[0];return t=t[1],[ha(ba.bind(null,t,e),[t,e]),n]}},xa=null,Oa=null,Sa=!1;function ka(e,t){var n=Eu(5,null,null,0);n.elementType="DELETED",n.type="DELETED",n.stateNode=t,n.return=e,n.effectTag=8,null!==e.lastEffect?(e.lastEffect.nextEffect=n,e.lastEffect=n):e.firstEffect=e.lastEffect=n}function ja(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,!0);default:return!1}}function Ca(e){if(Sa){var t=Oa;if(t){var n=t;if(!ja(e,t)){if(!(t=On(n.nextSibling))||!ja(e,t))return e.effectTag=-1025&e.effectTag|2,Sa=!1,void(xa=e);ka(xa,n)}xa=e,Oa=On(t.firstChild)}else e.effectTag=-1025&e.effectTag|2,Sa=!1,xa=e}}function Ea(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;xa=e}function Pa(e){if(e!==xa)return!1;if(!Sa)return Ea(e),Sa=!0,!1;var t=e.type;if(5!==e.tag||"head"!==t&&"body"!==t&&!wn(t,e.memoizedProps))for(t=Oa;t;)ka(e,t),t=On(t.nextSibling);if(Ea(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(a(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){Oa=On(e.nextSibling);break e}t--}else"$"!==n&&n!==bn&&n!==mn||t++}e=e.nextSibling}Oa=null}}else Oa=xa?On(e.stateNode.nextSibling):null;return!0}function Aa(){Oa=xa=null,Sa=!1}var Ta=G.ReactCurrentOwner,La=!1;function Ra(e,t,n,r){t.child=null===e?Ei(t,null,n,r):Ci(t,e.child,n,r)}function Ma(e,t,n,r,o){n=n.render;var i=t.ref;return ii(t,o),r=Gi(e,t,n,r,i,o),null===e||La?(t.effectTag|=1,Ra(e,t,r,o),t.child):(t.updateQueue=e.updateQueue,t.effectTag&=-517,e.expirationTime<=o&&(e.expirationTime=0),Ga(e,t,o))}function Da(e,t,n,r,o,i){if(null===e){var a=n.type;return"function"!=typeof a||Pu(a)||void 0!==a.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Tu(n.type,null,r,null,t.mode,i)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=a,Ia(e,t,a,r,o,i))}return a=e.child,o<i&&(o=a.memoizedProps,(n=null!==(n=n.compare)?n:$r)(o,r)&&e.ref===t.ref)?Ga(e,t,i):(t.effectTag|=1,(e=Au(a,r)).ref=t.ref,e.return=t,t.child=e)}function Ia(e,t,n,r,o,i){return null!==e&&$r(e.memoizedProps,r)&&e.ref===t.ref&&(La=!1,o<i)?(t.expirationTime=e.expirationTime,Ga(e,t,i)):Na(e,t,n,r,i)}function Fa(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.effectTag|=128)}function Na(e,t,n,r,o){var i=go(n)?bo:ho.current;return i=yo(t,i),ii(t,o),n=Gi(e,t,n,r,i,o),null===e||La?(t.effectTag|=1,Ra(e,t,n,o),t.child):(t.updateQueue=e.updateQueue,t.effectTag&=-517,e.expirationTime<=o&&(e.expirationTime=0),Ga(e,t,o))}function za(e,t,n,r,o){if(go(n)){var i=!0;xo(t)}else i=!1;if(ii(t,o),null===t.stateNode)null!==e&&(e.alternate=null,t.alternate=null,t.effectTag|=2),wi(t,n,r),xi(t,n,r,o),r=!0;else if(null===e){var a=t.stateNode,l=t.memoizedProps;a.props=l;var u=a.context,s=n.contextType;s="object"==typeof s&&null!==s?ai(s):yo(t,s=go(n)?bo:ho.current);var c=n.getDerivedStateFromProps,f="function"==typeof c||"function"==typeof a.getSnapshotBeforeUpdate;f||"function"!=typeof a.UNSAFE_componentWillReceiveProps&&"function"!=typeof a.componentWillReceiveProps||(l!==r||u!==s)&&_i(t,a,r,s),li=!1;var p=t.memoizedState;a.state=p,di(t,r,a,o),u=t.memoizedState,l!==r||p!==u||mo.current||li?("function"==typeof c&&(yi(t,n,c,r),u=t.memoizedState),(l=li||vi(t,n,l,r,p,u,s))?(f||"function"!=typeof a.UNSAFE_componentWillMount&&"function"!=typeof a.componentWillMount||("function"==typeof a.componentWillMount&&a.componentWillMount(),"function"==typeof a.UNSAFE_componentWillMount&&a.UNSAFE_componentWillMount()),"function"==typeof a.componentDidMount&&(t.effectTag|=4)):("function"==typeof a.componentDidMount&&(t.effectTag|=4),t.memoizedProps=r,t.memoizedState=u),a.props=r,a.state=u,a.context=s,r=l):("function"==typeof a.componentDidMount&&(t.effectTag|=4),r=!1)}else a=t.stateNode,si(e,t),l=t.memoizedProps,a.props=t.type===t.elementType?l:Xo(t.type,l),u=a.context,s="object"==typeof(s=n.contextType)&&null!==s?ai(s):yo(t,s=go(n)?bo:ho.current),(f="function"==typeof(c=n.getDerivedStateFromProps)||"function"==typeof a.getSnapshotBeforeUpdate)||"function"!=typeof a.UNSAFE_componentWillReceiveProps&&"function"!=typeof a.componentWillReceiveProps||(l!==r||u!==s)&&_i(t,a,r,s),li=!1,u=t.memoizedState,a.state=u,di(t,r,a,o),p=t.memoizedState,l!==r||u!==p||mo.current||li?("function"==typeof c&&(yi(t,n,c,r),p=t.memoizedState),(c=li||vi(t,n,l,r,u,p,s))?(f||"function"!=typeof a.UNSAFE_componentWillUpdate&&"function"!=typeof a.componentWillUpdate||("function"==typeof a.componentWillUpdate&&a.componentWillUpdate(r,p,s),"function"==typeof a.UNSAFE_componentWillUpdate&&a.UNSAFE_componentWillUpdate(r,p,s)),"function"==typeof a.componentDidUpdate&&(t.effectTag|=4),"function"==typeof a.getSnapshotBeforeUpdate&&(t.effectTag|=256)):("function"!=typeof a.componentDidUpdate||l===e.memoizedProps&&u===e.memoizedState||(t.effectTag|=4),"function"!=typeof a.getSnapshotBeforeUpdate||l===e.memoizedProps&&u===e.memoizedState||(t.effectTag|=256),t.memoizedProps=r,t.memoizedState=p),a.props=r,a.state=p,a.context=s,r=c):("function"!=typeof a.componentDidUpdate||l===e.memoizedProps&&u===e.memoizedState||(t.effectTag|=4),"function"!=typeof a.getSnapshotBeforeUpdate||l===e.memoizedProps&&u===e.memoizedState||(t.effectTag|=256),r=!1);return qa(e,t,n,r,i,o)}function qa(e,t,n,r,o,i){Fa(e,t);var a=0!=(64&t.effectTag);if(!r&&!a)return o&&Oo(t,n,!1),Ga(e,t,i);r=t.stateNode,Ta.current=t;var l=a&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return t.effectTag|=1,null!==e&&a?(t.child=Ci(t,e.child,null,i),t.child=Ci(t,null,l,i)):Ra(e,t,l,i),t.memoizedState=r.state,o&&Oo(t,n,!0),t.child}function $a(e){var t=e.stateNode;t.pendingContext?wo(0,t.pendingContext,t.pendingContext!==t.context):t.context&&wo(0,t.context,!1),Mi(e,t.containerInfo)}var Ba,Ua,Va,Wa={dehydrated:null,retryTime:0};function Ha(e,t,n){var r,o=t.mode,i=t.pendingProps,a=Ni.current,l=!1;if((r=0!=(64&t.effectTag))||(r=0!=(2&a)&&(null===e||null!==e.memoizedState)),r?(l=!0,t.effectTag&=-65):null!==e&&null===e.memoizedState||void 0===i.fallback||!0===i.unstable_avoidThisFallback||(a|=1),fo(Ni,1&a),null===e){if(void 0!==i.fallback&&Ca(t),l){if(l=i.fallback,(i=Lu(null,o,0,null)).return=t,0==(2&t.mode))for(e=null!==t.memoizedState?t.child.child:t.child,i.child=e;null!==e;)e.return=i,e=e.sibling;return(n=Lu(l,o,n,null)).return=t,i.sibling=n,t.memoizedState=Wa,t.child=i,n}return o=i.children,t.memoizedState=null,t.child=Ei(t,null,o,n)}if(null!==e.memoizedState){if(o=(e=e.child).sibling,l){if(i=i.fallback,(n=Au(e,e.pendingProps)).return=t,0==(2&t.mode)&&(l=null!==t.memoizedState?t.child.child:t.child)!==e.child)for(n.child=l;null!==l;)l.return=n,l=l.sibling;return(o=Au(o,i)).return=t,n.sibling=o,n.childExpirationTime=0,t.memoizedState=Wa,t.child=n,o}return n=Ci(t,e.child,i.children,n),t.memoizedState=null,t.child=n}if(e=e.child,l){if(l=i.fallback,(i=Lu(null,o,0,null)).return=t,i.child=e,null!==e&&(e.return=i),0==(2&t.mode))for(e=null!==t.memoizedState?t.child.child:t.child,i.child=e;null!==e;)e.return=i,e=e.sibling;return(n=Lu(l,o,n,null)).return=t,i.sibling=n,n.effectTag|=2,i.childExpirationTime=0,t.memoizedState=Wa,t.child=i,n}return t.memoizedState=null,t.child=Ci(t,e,i.children,n)}function Za(e,t){e.expirationTime<t&&(e.expirationTime=t);var n=e.alternate;null!==n&&n.expirationTime<t&&(n.expirationTime=t),oi(e.return,t)}function Ka(e,t,n,r,o,i){var a=e.memoizedState;null===a?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailExpiration:0,tailMode:o,lastEffect:i}:(a.isBackwards=t,a.rendering=null,a.renderingStartTime=0,a.last=r,a.tail=n,a.tailExpiration=0,a.tailMode=o,a.lastEffect=i)}function Qa(e,t,n){var r=t.pendingProps,o=r.revealOrder,i=r.tail;if(Ra(e,t,r.children,n),0!=(2&(r=Ni.current)))r=1&r|2,t.effectTag|=64;else{if(null!==e&&0!=(64&e.effectTag))e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&Za(e,n);else if(19===e.tag)Za(e,n);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(fo(Ni,r),0==(2&t.mode))t.memoizedState=null;else switch(o){case"forwards":for(n=t.child,o=null;null!==n;)null!==(e=n.alternate)&&null===zi(e)&&(o=n),n=n.sibling;null===(n=o)?(o=t.child,t.child=null):(o=n.sibling,n.sibling=null),Ka(t,!1,o,n,i,t.lastEffect);break;case"backwards":for(n=null,o=t.child,t.child=null;null!==o;){if(null!==(e=o.alternate)&&null===zi(e)){t.child=o;break}e=o.sibling,o.sibling=n,n=o,o=e}Ka(t,!0,n,null,i,t.lastEffect);break;case"together":Ka(t,!1,null,null,void 0,t.lastEffect);break;default:t.memoizedState=null}return t.child}function Ga(e,t,n){null!==e&&(t.dependencies=e.dependencies);var r=t.expirationTime;if(0!==r&&cu(r),t.childExpirationTime<n)return null;if(null!==e&&t.child!==e.child)throw Error(a(153));if(null!==t.child){for(n=Au(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Au(e,e.pendingProps)).return=t;n.sibling=null}return t.child}function Xa(e,t){switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function Ya(e,t,n){var r=t.pendingProps;switch(t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return null;case 1:case 17:return go(t.type)&&vo(),null;case 3:return Di(),co(mo),co(ho),(n=t.stateNode).pendingContext&&(n.context=n.pendingContext,n.pendingContext=null),null!==e&&null!==e.child||!Pa(t)||(t.effectTag|=4),null;case 5:Fi(t),n=Ri(Li.current);var i=t.type;if(null!==e&&null!=t.stateNode)Ua(e,t,i,r,n),e.ref!==t.ref&&(t.effectTag|=128);else{if(!r){if(null===t.stateNode)throw Error(a(166));return null}if(e=Ri(Ai.current),Pa(t)){r=t.stateNode,i=t.type;var l=t.memoizedProps;switch(r[jn]=t,r[Cn]=l,i){case"iframe":case"object":case"embed":Ht("load",r);break;case"video":case"audio":for(e=0;e<Qe.length;e++)Ht(Qe[e],r);break;case"source":Ht("error",r);break;case"img":case"image":case"link":Ht("error",r),Ht("load",r);break;case"form":Ht("reset",r),Ht("submit",r);break;case"details":Ht("toggle",r);break;case"input":Oe(r,l),Ht("invalid",r),ln(n,"onChange");break;case"select":r._wrapperState={wasMultiple:!!l.multiple},Ht("invalid",r),ln(n,"onChange");break;case"textarea":Te(r,l),Ht("invalid",r),ln(n,"onChange")}for(var u in rn(i,l),e=null,l)if(l.hasOwnProperty(u)){var s=l[u];"children"===u?"string"==typeof s?r.textContent!==s&&(e=["children",s]):"number"==typeof s&&r.textContent!==""+s&&(e=["children",""+s]):S.hasOwnProperty(u)&&null!=s&&ln(n,u)}switch(i){case"input":we(r),je(r,l,!0);break;case"textarea":we(r),Re(r);break;case"select":case"option":break;default:"function"==typeof l.onClick&&(r.onclick=un)}n=e,t.updateQueue=n,null!==n&&(t.effectTag|=4)}else{switch(u=9===n.nodeType?n:n.ownerDocument,e===an&&(e=Me(i)),e===an?"script"===i?((e=u.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=u.createElement(i,{is:r.is}):(e=u.createElement(i),"select"===i&&(u=e,r.multiple?u.multiple=!0:r.size&&(u.size=r.size))):e=u.createElementNS(e,i),e[jn]=t,e[Cn]=r,Ba(e,t),t.stateNode=e,u=on(i,r),i){case"iframe":case"object":case"embed":Ht("load",e),s=r;break;case"video":case"audio":for(s=0;s<Qe.length;s++)Ht(Qe[s],e);s=r;break;case"source":Ht("error",e),s=r;break;case"img":case"image":case"link":Ht("error",e),Ht("load",e),s=r;break;case"form":Ht("reset",e),Ht("submit",e),s=r;break;case"details":Ht("toggle",e),s=r;break;case"input":Oe(e,r),s=xe(e,r),Ht("invalid",e),ln(n,"onChange");break;case"option":s=Ee(e,r);break;case"select":e._wrapperState={wasMultiple:!!r.multiple},s=o({},r,{value:void 0}),Ht("invalid",e),ln(n,"onChange");break;case"textarea":Te(e,r),s=Ae(e,r),Ht("invalid",e),ln(n,"onChange");break;default:s=r}rn(i,s);var c=s;for(l in c)if(c.hasOwnProperty(l)){var f=c[l];"style"===l?tn(e,f):"dangerouslySetInnerHTML"===l?null!=(f=f?f.__html:void 0)&&Ne(e,f):"children"===l?"string"==typeof f?("textarea"!==i||""!==f)&&ze(e,f):"number"==typeof f&&ze(e,""+f):"suppressContentEditableWarning"!==l&&"suppressHydrationWarning"!==l&&"autoFocus"!==l&&(S.hasOwnProperty(l)?null!=f&&ln(n,l):null!=f&&X(e,l,f,u))}switch(i){case"input":we(e),je(e,r,!1);break;case"textarea":we(e),Re(e);break;case"option":null!=r.value&&e.setAttribute("value",""+ge(r.value));break;case"select":e.multiple=!!r.multiple,null!=(n=r.value)?Pe(e,!!r.multiple,n,!1):null!=r.defaultValue&&Pe(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof s.onClick&&(e.onclick=un)}vn(i,r)&&(t.effectTag|=4)}null!==t.ref&&(t.effectTag|=128)}return null;case 6:if(e&&null!=t.stateNode)Va(0,t,e.memoizedProps,r);else{if("string"!=typeof r&&null===t.stateNode)throw Error(a(166));n=Ri(Li.current),Ri(Ai.current),Pa(t)?(n=t.stateNode,r=t.memoizedProps,n[jn]=t,n.nodeValue!==r&&(t.effectTag|=4)):((n=(9===n.nodeType?n:n.ownerDocument).createTextNode(r))[jn]=t,t.stateNode=n)}return null;case 13:return co(Ni),r=t.memoizedState,0!=(64&t.effectTag)?(t.expirationTime=n,t):(n=null!==r,r=!1,null===e?void 0!==t.memoizedProps.fallback&&Pa(t):(r=null!==(i=e.memoizedState),n||null===i||null!==(i=e.child.sibling)&&(null!==(l=t.firstEffect)?(t.firstEffect=i,i.nextEffect=l):(t.firstEffect=t.lastEffect=i,i.nextEffect=null),i.effectTag=8)),n&&!r&&0!=(2&t.mode)&&(null===e&&!0!==t.memoizedProps.unstable_avoidThisFallback||0!=(1&Ni.current)?Tl===Sl&&(Tl=kl):(Tl!==Sl&&Tl!==kl||(Tl=jl),0!==Il&&null!==El&&(Fu(El,Al),Nu(El,Il)))),(n||r)&&(t.effectTag|=4),null);case 4:return Di(),null;case 10:return ri(t),null;case 19:if(co(Ni),null===(r=t.memoizedState))return null;if(i=0!=(64&t.effectTag),null===(l=r.rendering)){if(i)Xa(r,!1);else if(Tl!==Sl||null!==e&&0!=(64&e.effectTag))for(l=t.child;null!==l;){if(null!==(e=zi(l))){for(t.effectTag|=64,Xa(r,!1),null!==(i=e.updateQueue)&&(t.updateQueue=i,t.effectTag|=4),null===r.lastEffect&&(t.firstEffect=null),t.lastEffect=r.lastEffect,r=t.child;null!==r;)l=n,(i=r).effectTag&=2,i.nextEffect=null,i.firstEffect=null,i.lastEffect=null,null===(e=i.alternate)?(i.childExpirationTime=0,i.expirationTime=l,i.child=null,i.memoizedProps=null,i.memoizedState=null,i.updateQueue=null,i.dependencies=null):(i.childExpirationTime=e.childExpirationTime,i.expirationTime=e.expirationTime,i.child=e.child,i.memoizedProps=e.memoizedProps,i.memoizedState=e.memoizedState,i.updateQueue=e.updateQueue,l=e.dependencies,i.dependencies=null===l?null:{expirationTime:l.expirationTime,firstContext:l.firstContext,responders:l.responders}),r=r.sibling;return fo(Ni,1&Ni.current|2),t.child}l=l.sibling}}else{if(!i)if(null!==(e=zi(l))){if(t.effectTag|=64,i=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.effectTag|=4),Xa(r,!0),null===r.tail&&"hidden"===r.tailMode&&!l.alternate)return null!==(t=t.lastEffect=r.lastEffect)&&(t.nextEffect=null),null}else 2*Bo()-r.renderingStartTime>r.tailExpiration&&1<n&&(t.effectTag|=64,i=!0,Xa(r,!1),t.expirationTime=t.childExpirationTime=n-1);r.isBackwards?(l.sibling=t.child,t.child=l):(null!==(n=r.last)?n.sibling=l:t.child=l,r.last=l)}return null!==r.tail?(0===r.tailExpiration&&(r.tailExpiration=Bo()+500),n=r.tail,r.rendering=n,r.tail=n.sibling,r.lastEffect=t.lastEffect,r.renderingStartTime=Bo(),n.sibling=null,t=Ni.current,fo(Ni,i?1&t|2:1&t),n):null}throw Error(a(156,t.tag))}function Ja(e){switch(e.tag){case 1:go(e.type)&&vo();var t=e.effectTag;return 4096&t?(e.effectTag=-4097&t|64,e):null;case 3:if(Di(),co(mo),co(ho),0!=(64&(t=e.effectTag)))throw Error(a(285));return e.effectTag=-4097&t|64,e;case 5:return Fi(e),null;case 13:return co(Ni),4096&(t=e.effectTag)?(e.effectTag=-4097&t|64,e):null;case 19:return co(Ni),null;case 4:return Di(),null;case 10:return ri(e),null;default:return null}}function el(e,t){return{value:e,source:t,stack:ye(t)}}Ba=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Ua=function(e,t,n,r,i){var a=e.memoizedProps;if(a!==r){var l,u,s=t.stateNode;switch(Ri(Ai.current),e=null,n){case"input":a=xe(s,a),r=xe(s,r),e=[];break;case"option":a=Ee(s,a),r=Ee(s,r),e=[];break;case"select":a=o({},a,{value:void 0}),r=o({},r,{value:void 0}),e=[];break;case"textarea":a=Ae(s,a),r=Ae(s,r),e=[];break;default:"function"!=typeof a.onClick&&"function"==typeof r.onClick&&(s.onclick=un)}for(l in rn(n,r),n=null,a)if(!r.hasOwnProperty(l)&&a.hasOwnProperty(l)&&null!=a[l])if("style"===l)for(u in s=a[l])s.hasOwnProperty(u)&&(n||(n={}),n[u]="");else"dangerouslySetInnerHTML"!==l&&"children"!==l&&"suppressContentEditableWarning"!==l&&"suppressHydrationWarning"!==l&&"autoFocus"!==l&&(S.hasOwnProperty(l)?e||(e=[]):(e=e||[]).push(l,null));for(l in r){var c=r[l];if(s=null!=a?a[l]:void 0,r.hasOwnProperty(l)&&c!==s&&(null!=c||null!=s))if("style"===l)if(s){for(u in s)!s.hasOwnProperty(u)||c&&c.hasOwnProperty(u)||(n||(n={}),n[u]="");for(u in c)c.hasOwnProperty(u)&&s[u]!==c[u]&&(n||(n={}),n[u]=c[u])}else n||(e||(e=[]),e.push(l,n)),n=c;else"dangerouslySetInnerHTML"===l?(c=c?c.__html:void 0,s=s?s.__html:void 0,null!=c&&s!==c&&(e=e||[]).push(l,c)):"children"===l?s===c||"string"!=typeof c&&"number"!=typeof c||(e=e||[]).push(l,""+c):"suppressContentEditableWarning"!==l&&"suppressHydrationWarning"!==l&&(S.hasOwnProperty(l)?(null!=c&&ln(i,l),e||s===c||(e=[])):(e=e||[]).push(l,c))}n&&(e=e||[]).push("style",n),i=e,(t.updateQueue=i)&&(t.effectTag|=4)}},Va=function(e,t,n,r){n!==r&&(t.effectTag|=4)};var tl="function"==typeof WeakSet?WeakSet:Set;function nl(e,t){var n=t.source,r=t.stack;null===r&&null!==n&&(r=ye(n)),null!==n&&be(n.type),t=t.value,null!==e&&1===e.tag&&be(e.type);try{console.error(t)}catch(e){setTimeout((function(){throw e}))}}function rl(e){var t=e.ref;if(null!==t)if("function"==typeof t)try{t(null)}catch(t){xu(e,t)}else t.current=null}function ol(e,t){switch(t.tag){case 0:case 11:case 15:case 22:case 3:case 5:case 6:case 4:case 17:return;case 1:if(256&t.effectTag&&null!==e){var n=e.memoizedProps,r=e.memoizedState;t=(e=t.stateNode).getSnapshotBeforeUpdate(t.elementType===t.type?n:Xo(t.type,n),r),e.__reactInternalSnapshotBeforeUpdate=t}return}throw Error(a(163))}function il(e,t){if(null!==(t=null!==(t=t.updateQueue)?t.lastEffect:null)){var n=t=t.next;do{if((n.tag&e)===e){var r=n.destroy;n.destroy=void 0,void 0!==r&&r()}n=n.next}while(n!==t)}}function al(e,t){if(null!==(t=null!==(t=t.updateQueue)?t.lastEffect:null)){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function ll(e,t,n){switch(n.tag){case 0:case 11:case 15:case 22:return void al(3,n);case 1:if(e=n.stateNode,4&n.effectTag)if(null===t)e.componentDidMount();else{var r=n.elementType===n.type?t.memoizedProps:Xo(n.type,t.memoizedProps);e.componentDidUpdate(r,t.memoizedState,e.__reactInternalSnapshotBeforeUpdate)}return void(null!==(t=n.updateQueue)&&hi(n,t,e));case 3:if(null!==(t=n.updateQueue)){if(e=null,null!==n.child)switch(n.child.tag){case 5:case 1:e=n.child.stateNode}hi(n,t,e)}return;case 5:return e=n.stateNode,void(null===t&&4&n.effectTag&&vn(n.type,n.memoizedProps)&&e.focus());case 6:case 4:case 12:case 19:case 17:case 20:case 21:return;case 13:return void(null===n.memoizedState&&(n=n.alternate,null!==n&&(n=n.memoizedState,null!==n&&(n=n.dehydrated,null!==n&&Dt(n)))))}throw Error(a(163))}function ul(e,t,n){switch("function"==typeof ju&&ju(t),t.tag){case 0:case 11:case 14:case 15:case 22:if(null!==(e=t.updateQueue)&&null!==(e=e.lastEffect)){var r=e.next;Wo(97<n?97:n,(function(){var e=r;do{var n=e.destroy;if(void 0!==n){var o=t;try{n()}catch(e){xu(o,e)}}e=e.next}while(e!==r)}))}break;case 1:rl(t),"function"==typeof(n=t.stateNode).componentWillUnmount&&function(e,t){try{t.props=e.memoizedProps,t.state=e.memoizedState,t.componentWillUnmount()}catch(t){xu(e,t)}}(t,n);break;case 5:rl(t);break;case 4:hl(e,t,n)}}function sl(e){var t=e.alternate;e.return=null,e.child=null,e.memoizedState=null,e.updateQueue=null,e.dependencies=null,e.alternate=null,e.firstEffect=null,e.lastEffect=null,e.pendingProps=null,e.memoizedProps=null,e.stateNode=null,null!==t&&sl(t)}function cl(e){return 5===e.tag||3===e.tag||4===e.tag}function fl(e){e:{for(var t=e.return;null!==t;){if(cl(t)){var n=t;break e}t=t.return}throw Error(a(160))}switch(t=n.stateNode,n.tag){case 5:var r=!1;break;case 3:case 4:t=t.containerInfo,r=!0;break;default:throw Error(a(161))}16&n.effectTag&&(ze(t,""),n.effectTag&=-17);e:t:for(n=e;;){for(;null===n.sibling;){if(null===n.return||cl(n.return)){n=null;break e}n=n.return}for(n.sibling.return=n.return,n=n.sibling;5!==n.tag&&6!==n.tag&&18!==n.tag;){if(2&n.effectTag)continue t;if(null===n.child||4===n.tag)continue t;n.child.return=n,n=n.child}if(!(2&n.effectTag)){n=n.stateNode;break e}}r?pl(e,n,t):dl(e,n,t)}function pl(e,t,n){var r=e.tag,o=5===r||6===r;if(o)e=o?e.stateNode:e.stateNode.instance,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=un));else if(4!==r&&null!==(e=e.child))for(pl(e,t,n),e=e.sibling;null!==e;)pl(e,t,n),e=e.sibling}function dl(e,t,n){var r=e.tag,o=5===r||6===r;if(o)e=o?e.stateNode:e.stateNode.instance,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(dl(e,t,n),e=e.sibling;null!==e;)dl(e,t,n),e=e.sibling}function hl(e,t,n){for(var r,o,i=t,l=!1;;){if(!l){l=i.return;e:for(;;){if(null===l)throw Error(a(160));switch(r=l.stateNode,l.tag){case 5:o=!1;break e;case 3:case 4:r=r.containerInfo,o=!0;break e}l=l.return}l=!0}if(5===i.tag||6===i.tag){e:for(var u=e,s=i,c=n,f=s;;)if(ul(u,f,c),null!==f.child&&4!==f.tag)f.child.return=f,f=f.child;else{if(f===s)break e;for(;null===f.sibling;){if(null===f.return||f.return===s)break e;f=f.return}f.sibling.return=f.return,f=f.sibling}o?(u=r,s=i.stateNode,8===u.nodeType?u.parentNode.removeChild(s):u.removeChild(s)):r.removeChild(i.stateNode)}else if(4===i.tag){if(null!==i.child){r=i.stateNode.containerInfo,o=!0,i.child.return=i,i=i.child;continue}}else if(ul(e,i,n),null!==i.child){i.child.return=i,i=i.child;continue}if(i===t)break;for(;null===i.sibling;){if(null===i.return||i.return===t)return;4===(i=i.return).tag&&(l=!1)}i.sibling.return=i.return,i=i.sibling}}function ml(e,t){switch(t.tag){case 0:case 11:case 14:case 15:case 22:return void il(3,t);case 1:case 12:case 17:return;case 5:var n=t.stateNode;if(null!=n){var r=t.memoizedProps,o=null!==e?e.memoizedProps:r;e=t.type;var i=t.updateQueue;if(t.updateQueue=null,null!==i){for(n[Cn]=r,"input"===e&&"radio"===r.type&&null!=r.name&&Se(n,r),on(e,o),t=on(e,r),o=0;o<i.length;o+=2){var l=i[o],u=i[o+1];"style"===l?tn(n,u):"dangerouslySetInnerHTML"===l?Ne(n,u):"children"===l?ze(n,u):X(n,l,u,t)}switch(e){case"input":ke(n,r);break;case"textarea":Le(n,r);break;case"select":t=n._wrapperState.wasMultiple,n._wrapperState.wasMultiple=!!r.multiple,null!=(e=r.value)?Pe(n,!!r.multiple,e,!1):t!==!!r.multiple&&(null!=r.defaultValue?Pe(n,!!r.multiple,r.defaultValue,!0):Pe(n,!!r.multiple,r.multiple?[]:"",!1))}}}return;case 6:if(null===t.stateNode)throw Error(a(162));return void(t.stateNode.nodeValue=t.memoizedProps);case 3:return void((t=t.stateNode).hydrate&&(t.hydrate=!1,Dt(t.containerInfo)));case 13:if(n=t,null===t.memoizedState?r=!1:(r=!0,n=t.child,Nl=Bo()),null!==n)e:for(e=n;;){if(5===e.tag)i=e.stateNode,r?"function"==typeof(i=i.style).setProperty?i.setProperty("display","none","important"):i.display="none":(i=e.stateNode,o=null!=(o=e.memoizedProps.style)&&o.hasOwnProperty("display")?o.display:null,i.style.display=en("display",o));else if(6===e.tag)e.stateNode.nodeValue=r?"":e.memoizedProps;else{if(13===e.tag&&null!==e.memoizedState&&null===e.memoizedState.dehydrated){(i=e.child.sibling).return=e,e=i;continue}if(null!==e.child){e.child.return=e,e=e.child;continue}}if(e===n)break;for(;null===e.sibling;){if(null===e.return||e.return===n)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}return void bl(t);case 19:return void bl(t)}throw Error(a(163))}function bl(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new tl),t.forEach((function(t){var r=Su.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))}))}}var yl="function"==typeof WeakMap?WeakMap:Map;function gl(e,t,n){(n=ci(n,null)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){ql||(ql=!0,$l=r),nl(e,t)},n}function vl(e,t,n){(n=ci(n,null)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var o=t.value;n.payload=function(){return nl(e,t),r(o)}}var i=e.stateNode;return null!==i&&"function"==typeof i.componentDidCatch&&(n.callback=function(){"function"!=typeof r&&(null===Bl?Bl=new Set([this]):Bl.add(this),nl(e,t));var n=t.stack;this.componentDidCatch(t.value,{componentStack:null!==n?n:""})}),n}var wl,_l=Math.ceil,xl=G.ReactCurrentDispatcher,Ol=G.ReactCurrentOwner,Sl=0,kl=3,jl=4,Cl=0,El=null,Pl=null,Al=0,Tl=Sl,Ll=null,Rl=1073741823,Ml=1073741823,Dl=null,Il=0,Fl=!1,Nl=0,zl=null,ql=!1,$l=null,Bl=null,Ul=!1,Vl=null,Wl=90,Hl=null,Zl=0,Kl=null,Ql=0;function Gl(){return 0!=(48&Cl)?1073741821-(Bo()/10|0):0!==Ql?Ql:Ql=1073741821-(Bo()/10|0)}function Xl(e,t,n){if(0==(2&(t=t.mode)))return 1073741823;var r=Uo();if(0==(4&t))return 99===r?1073741823:1073741822;if(0!=(16&Cl))return Al;if(null!==n)e=Go(e,0|n.timeoutMs||5e3,250);else switch(r){case 99:e=1073741823;break;case 98:e=Go(e,150,100);break;case 97:case 96:e=Go(e,5e3,250);break;case 95:e=2;break;default:throw Error(a(326))}return null!==El&&e===Al&&--e,e}function Yl(e,t){if(50<Zl)throw Zl=0,Kl=null,Error(a(185));if(null!==(e=Jl(e,t))){var n=Uo();1073741823===t?0!=(8&Cl)&&0==(48&Cl)?ru(e):(tu(e),0===Cl&&Ko()):tu(e),0==(4&Cl)||98!==n&&99!==n||(null===Hl?Hl=new Map([[e,t]]):(void 0===(n=Hl.get(e))||n>t)&&Hl.set(e,t))}}function Jl(e,t){e.expirationTime<t&&(e.expirationTime=t);var n=e.alternate;null!==n&&n.expirationTime<t&&(n.expirationTime=t);var r=e.return,o=null;if(null===r&&3===e.tag)o=e.stateNode;else for(;null!==r;){if(n=r.alternate,r.childExpirationTime<t&&(r.childExpirationTime=t),null!==n&&n.childExpirationTime<t&&(n.childExpirationTime=t),null===r.return&&3===r.tag){o=r.stateNode;break}r=r.return}return null!==o&&(El===o&&(cu(t),Tl===jl&&Fu(o,Al)),Nu(o,t)),o}function eu(e){var t=e.lastExpiredTime;if(0!==t)return t;if(!Iu(e,t=e.firstPendingTime))return t;var n=e.lastPingedTime;return 2>=(e=n>(e=e.nextKnownPendingLevel)?n:e)&&t!==e?0:e}function tu(e){if(0!==e.lastExpiredTime)e.callbackExpirationTime=1073741823,e.callbackPriority=99,e.callbackNode=Zo(ru.bind(null,e));else{var t=eu(e),n=e.callbackNode;if(0===t)null!==n&&(e.callbackNode=null,e.callbackExpirationTime=0,e.callbackPriority=90);else{var r=Gl();if(r=1073741823===t?99:1===t||2===t?95:0>=(r=10*(1073741821-t)-10*(1073741821-r))?99:250>=r?98:5250>=r?97:95,null!==n){var o=e.callbackPriority;if(e.callbackExpirationTime===t&&o>=r)return;n!==Do&&jo(n)}e.callbackExpirationTime=t,e.callbackPriority=r,t=1073741823===t?Zo(ru.bind(null,e)):Ho(r,nu.bind(null,e),{timeout:10*(1073741821-t)-Bo()}),e.callbackNode=t}}}function nu(e,t){if(Ql=0,t)return zu(e,t=Gl()),tu(e),null;var n=eu(e);if(0!==n){if(t=e.callbackNode,0!=(48&Cl))throw Error(a(327));if(vu(),e===El&&n===Al||au(e,n),null!==Pl){var r=Cl;Cl|=16;for(var o=uu();;)try{pu();break}catch(t){lu(e,t)}if(ni(),Cl=r,xl.current=o,1===Tl)throw t=Ll,au(e,n),Fu(e,n),tu(e),t;if(null===Pl)switch(o=e.finishedWork=e.current.alternate,e.finishedExpirationTime=n,r=Tl,El=null,r){case Sl:case 1:throw Error(a(345));case 2:zu(e,2<n?2:n);break;case kl:if(Fu(e,n),n===(r=e.lastSuspendedTime)&&(e.nextKnownPendingLevel=mu(o)),1073741823===Rl&&10<(o=Nl+500-Bo())){if(Fl){var i=e.lastPingedTime;if(0===i||i>=n){e.lastPingedTime=n,au(e,n);break}}if(0!==(i=eu(e))&&i!==n)break;if(0!==r&&r!==n){e.lastPingedTime=r;break}e.timeoutHandle=_n(bu.bind(null,e),o);break}bu(e);break;case jl:if(Fu(e,n),n===(r=e.lastSuspendedTime)&&(e.nextKnownPendingLevel=mu(o)),Fl&&(0===(o=e.lastPingedTime)||o>=n)){e.lastPingedTime=n,au(e,n);break}if(0!==(o=eu(e))&&o!==n)break;if(0!==r&&r!==n){e.lastPingedTime=r;break}if(1073741823!==Ml?r=10*(1073741821-Ml)-Bo():1073741823===Rl?r=0:(r=10*(1073741821-Rl)-5e3,0>(r=(o=Bo())-r)&&(r=0),(n=10*(1073741821-n)-o)<(r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*_l(r/1960))-r)&&(r=n)),10<r){e.timeoutHandle=_n(bu.bind(null,e),r);break}bu(e);break;case 5:if(1073741823!==Rl&&null!==Dl){i=Rl;var l=Dl;if(0>=(r=0|l.busyMinDurationMs)?r=0:(o=0|l.busyDelayMs,r=(i=Bo()-(10*(1073741821-i)-(0|l.timeoutMs||5e3)))<=o?0:o+r-i),10<r){Fu(e,n),e.timeoutHandle=_n(bu.bind(null,e),r);break}}bu(e);break;default:throw Error(a(329))}if(tu(e),e.callbackNode===t)return nu.bind(null,e)}}return null}function ru(e){var t=e.lastExpiredTime;if(t=0!==t?t:1073741823,0!=(48&Cl))throw Error(a(327));if(vu(),e===El&&t===Al||au(e,t),null!==Pl){var n=Cl;Cl|=16;for(var r=uu();;)try{fu();break}catch(t){lu(e,t)}if(ni(),Cl=n,xl.current=r,1===Tl)throw n=Ll,au(e,t),Fu(e,t),tu(e),n;if(null!==Pl)throw Error(a(261));e.finishedWork=e.current.alternate,e.finishedExpirationTime=t,El=null,bu(e),tu(e)}return null}function ou(e,t){var n=Cl;Cl|=1;try{return e(t)}finally{0===(Cl=n)&&Ko()}}function iu(e,t){var n=Cl;Cl&=-2,Cl|=8;try{return e(t)}finally{0===(Cl=n)&&Ko()}}function au(e,t){e.finishedWork=null,e.finishedExpirationTime=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,xn(n)),null!==Pl)for(n=Pl.return;null!==n;){var r=n;switch(r.tag){case 1:null!=(r=r.type.childContextTypes)&&vo();break;case 3:Di(),co(mo),co(ho);break;case 5:Fi(r);break;case 4:Di();break;case 13:case 19:co(Ni);break;case 10:ri(r)}n=n.return}El=e,Pl=Au(e.current,null),Al=t,Tl=Sl,Ll=null,Ml=Rl=1073741823,Dl=null,Il=0,Fl=!1}function lu(e,t){for(;;){try{if(ni(),$i.current=ga,Zi)for(var n=Vi.memoizedState;null!==n;){var r=n.queue;null!==r&&(r.pending=null),n=n.next}if(Ui=0,Hi=Wi=Vi=null,Zi=!1,null===Pl||null===Pl.return)return Tl=1,Ll=t,Pl=null;e:{var o=e,i=Pl.return,a=Pl,l=t;if(t=Al,a.effectTag|=2048,a.firstEffect=a.lastEffect=null,null!==l&&"object"==typeof l&&"function"==typeof l.then){var u=l;if(0==(2&a.mode)){var s=a.alternate;s?(a.updateQueue=s.updateQueue,a.memoizedState=s.memoizedState,a.expirationTime=s.expirationTime):(a.updateQueue=null,a.memoizedState=null)}var c=0!=(1&Ni.current),f=i;do{var p;if(p=13===f.tag){var d=f.memoizedState;if(null!==d)p=null!==d.dehydrated;else{var h=f.memoizedProps;p=void 0!==h.fallback&&(!0!==h.unstable_avoidThisFallback||!c)}}if(p){var m=f.updateQueue;if(null===m){var b=new Set;b.add(u),f.updateQueue=b}else m.add(u);if(0==(2&f.mode)){if(f.effectTag|=64,a.effectTag&=-2981,1===a.tag)if(null===a.alternate)a.tag=17;else{var y=ci(1073741823,null);y.tag=2,fi(a,y)}a.expirationTime=1073741823;break e}l=void 0,a=t;var g=o.pingCache;if(null===g?(g=o.pingCache=new yl,l=new Set,g.set(u,l)):void 0===(l=g.get(u))&&(l=new Set,g.set(u,l)),!l.has(a)){l.add(a);var v=Ou.bind(null,o,u,a);u.then(v,v)}f.effectTag|=4096,f.expirationTime=t;break e}f=f.return}while(null!==f);l=Error((be(a.type)||"A React component")+" suspended while rendering, but no fallback UI was specified.\n\nAdd a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display."+ye(a))}5!==Tl&&(Tl=2),l=el(l,a),f=i;do{switch(f.tag){case 3:u=l,f.effectTag|=4096,f.expirationTime=t,pi(f,gl(f,u,t));break e;case 1:u=l;var w=f.type,_=f.stateNode;if(0==(64&f.effectTag)&&("function"==typeof w.getDerivedStateFromError||null!==_&&"function"==typeof _.componentDidCatch&&(null===Bl||!Bl.has(_)))){f.effectTag|=4096,f.expirationTime=t,pi(f,vl(f,u,t));break e}}f=f.return}while(null!==f)}Pl=hu(Pl)}catch(e){t=e;continue}break}}function uu(){var e=xl.current;return xl.current=ga,null===e?ga:e}function su(e,t){e<Rl&&2<e&&(Rl=e),null!==t&&e<Ml&&2<e&&(Ml=e,Dl=t)}function cu(e){e>Il&&(Il=e)}function fu(){for(;null!==Pl;)Pl=du(Pl)}function pu(){for(;null!==Pl&&!Io();)Pl=du(Pl)}function du(e){var t=wl(e.alternate,e,Al);return e.memoizedProps=e.pendingProps,null===t&&(t=hu(e)),Ol.current=null,t}function hu(e){Pl=e;do{var t=Pl.alternate;if(e=Pl.return,0==(2048&Pl.effectTag)){if(t=Ya(t,Pl,Al),1===Al||1!==Pl.childExpirationTime){for(var n=0,r=Pl.child;null!==r;){var o=r.expirationTime,i=r.childExpirationTime;o>n&&(n=o),i>n&&(n=i),r=r.sibling}Pl.childExpirationTime=n}if(null!==t)return t;null!==e&&0==(2048&e.effectTag)&&(null===e.firstEffect&&(e.firstEffect=Pl.firstEffect),null!==Pl.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=Pl.firstEffect),e.lastEffect=Pl.lastEffect),1<Pl.effectTag&&(null!==e.lastEffect?e.lastEffect.nextEffect=Pl:e.firstEffect=Pl,e.lastEffect=Pl))}else{if(null!==(t=Ja(Pl)))return t.effectTag&=2047,t;null!==e&&(e.firstEffect=e.lastEffect=null,e.effectTag|=2048)}if(null!==(t=Pl.sibling))return t;Pl=e}while(null!==Pl);return Tl===Sl&&(Tl=5),null}function mu(e){var t=e.expirationTime;return t>(e=e.childExpirationTime)?t:e}function bu(e){var t=Uo();return Wo(99,yu.bind(null,e,t)),null}function yu(e,t){do{vu()}while(null!==Vl);if(0!=(48&Cl))throw Error(a(327));var n=e.finishedWork,r=e.finishedExpirationTime;if(null===n)return null;if(e.finishedWork=null,e.finishedExpirationTime=0,n===e.current)throw Error(a(177));e.callbackNode=null,e.callbackExpirationTime=0,e.callbackPriority=90,e.nextKnownPendingLevel=0;var o=mu(n);if(e.firstPendingTime=o,r<=e.lastSuspendedTime?e.firstSuspendedTime=e.lastSuspendedTime=e.nextKnownPendingLevel=0:r<=e.firstSuspendedTime&&(e.firstSuspendedTime=r-1),r<=e.lastPingedTime&&(e.lastPingedTime=0),r<=e.lastExpiredTime&&(e.lastExpiredTime=0),e===El&&(Pl=El=null,Al=0),1<n.effectTag?null!==n.lastEffect?(n.lastEffect.nextEffect=n,o=n.firstEffect):o=n:o=n.firstEffect,null!==o){var i=Cl;Cl|=32,Ol.current=null,yn=Wt;var l=dn();if(hn(l)){if("selectionStart"in l)var u={start:l.selectionStart,end:l.selectionEnd};else e:{var s=(u=(u=l.ownerDocument)&&u.defaultView||window).getSelection&&u.getSelection();if(s&&0!==s.rangeCount){u=s.anchorNode;var c=s.anchorOffset,f=s.focusNode;s=s.focusOffset;try{u.nodeType,f.nodeType}catch(e){u=null;break e}var p=0,d=-1,h=-1,m=0,b=0,y=l,g=null;t:for(;;){for(var v;y!==u||0!==c&&3!==y.nodeType||(d=p+c),y!==f||0!==s&&3!==y.nodeType||(h=p+s),3===y.nodeType&&(p+=y.nodeValue.length),null!==(v=y.firstChild);)g=y,y=v;for(;;){if(y===l)break t;if(g===u&&++m===c&&(d=p),g===f&&++b===s&&(h=p),null!==(v=y.nextSibling))break;g=(y=g).parentNode}y=v}u=-1===d||-1===h?null:{start:d,end:h}}else u=null}u=u||{start:0,end:0}}else u=null;gn={activeElementDetached:null,focusedElem:l,selectionRange:u},Wt=!1,zl=o;do{try{gu()}catch(e){if(null===zl)throw Error(a(330));xu(zl,e),zl=zl.nextEffect}}while(null!==zl);zl=o;do{try{for(l=e,u=t;null!==zl;){var w=zl.effectTag;if(16&w&&ze(zl.stateNode,""),128&w){var _=zl.alternate;if(null!==_){var x=_.ref;null!==x&&("function"==typeof x?x(null):x.current=null)}}switch(1038&w){case 2:fl(zl),zl.effectTag&=-3;break;case 6:fl(zl),zl.effectTag&=-3,ml(zl.alternate,zl);break;case 1024:zl.effectTag&=-1025;break;case 1028:zl.effectTag&=-1025,ml(zl.alternate,zl);break;case 4:ml(zl.alternate,zl);break;case 8:hl(l,c=zl,u),sl(c)}zl=zl.nextEffect}}catch(e){if(null===zl)throw Error(a(330));xu(zl,e),zl=zl.nextEffect}}while(null!==zl);if(x=gn,_=dn(),w=x.focusedElem,u=x.selectionRange,_!==w&&w&&w.ownerDocument&&pn(w.ownerDocument.documentElement,w)){null!==u&&hn(w)&&(_=u.start,void 0===(x=u.end)&&(x=_),"selectionStart"in w?(w.selectionStart=_,w.selectionEnd=Math.min(x,w.value.length)):(x=(_=w.ownerDocument||document)&&_.defaultView||window).getSelection&&(x=x.getSelection(),c=w.textContent.length,l=Math.min(u.start,c),u=void 0===u.end?l:Math.min(u.end,c),!x.extend&&l>u&&(c=u,u=l,l=c),c=fn(w,l),f=fn(w,u),c&&f&&(1!==x.rangeCount||x.anchorNode!==c.node||x.anchorOffset!==c.offset||x.focusNode!==f.node||x.focusOffset!==f.offset)&&((_=_.createRange()).setStart(c.node,c.offset),x.removeAllRanges(),l>u?(x.addRange(_),x.extend(f.node,f.offset)):(_.setEnd(f.node,f.offset),x.addRange(_))))),_=[];for(x=w;x=x.parentNode;)1===x.nodeType&&_.push({element:x,left:x.scrollLeft,top:x.scrollTop});for("function"==typeof w.focus&&w.focus(),w=0;w<_.length;w++)(x=_[w]).element.scrollLeft=x.left,x.element.scrollTop=x.top}Wt=!!yn,gn=yn=null,e.current=n,zl=o;do{try{for(w=e;null!==zl;){var O=zl.effectTag;if(36&O&&ll(w,zl.alternate,zl),128&O){_=void 0;var S=zl.ref;if(null!==S){var k=zl.stateNode;zl.tag,_=k,"function"==typeof S?S(_):S.current=_}}zl=zl.nextEffect}}catch(e){if(null===zl)throw Error(a(330));xu(zl,e),zl=zl.nextEffect}}while(null!==zl);zl=null,Fo(),Cl=i}else e.current=n;if(Ul)Ul=!1,Vl=e,Wl=t;else for(zl=o;null!==zl;)t=zl.nextEffect,zl.nextEffect=null,zl=t;if(0===(t=e.firstPendingTime)&&(Bl=null),1073741823===t?e===Kl?Zl++:(Zl=0,Kl=e):Zl=0,"function"==typeof ku&&ku(n.stateNode,r),tu(e),ql)throw ql=!1,e=$l,$l=null,e;return 0!=(8&Cl)||Ko(),null}function gu(){for(;null!==zl;){var e=zl.effectTag;0!=(256&e)&&ol(zl.alternate,zl),0==(512&e)||Ul||(Ul=!0,Ho(97,(function(){return vu(),null}))),zl=zl.nextEffect}}function vu(){if(90!==Wl){var e=97<Wl?97:Wl;return Wl=90,Wo(e,wu)}}function wu(){if(null===Vl)return!1;var e=Vl;if(Vl=null,0!=(48&Cl))throw Error(a(331));var t=Cl;for(Cl|=32,e=e.current.firstEffect;null!==e;){try{var n=e;if(0!=(512&n.effectTag))switch(n.tag){case 0:case 11:case 15:case 22:il(5,n),al(5,n)}}catch(t){if(null===e)throw Error(a(330));xu(e,t)}n=e.nextEffect,e.nextEffect=null,e=n}return Cl=t,Ko(),!0}function _u(e,t,n){fi(e,t=gl(e,t=el(n,t),1073741823)),null!==(e=Jl(e,1073741823))&&tu(e)}function xu(e,t){if(3===e.tag)_u(e,e,t);else for(var n=e.return;null!==n;){if(3===n.tag){_u(n,e,t);break}if(1===n.tag){var r=n.stateNode;if("function"==typeof n.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Bl||!Bl.has(r))){fi(n,e=vl(n,e=el(t,e),1073741823)),null!==(n=Jl(n,1073741823))&&tu(n);break}}n=n.return}}function Ou(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),El===e&&Al===n?Tl===jl||Tl===kl&&1073741823===Rl&&Bo()-Nl<500?au(e,Al):Fl=!0:Iu(e,n)&&(0!==(t=e.lastPingedTime)&&t<n||(e.lastPingedTime=n,tu(e)))}function Su(e,t){var n=e.stateNode;null!==n&&n.delete(t),0==(t=0)&&(t=Xl(t=Gl(),e,null)),null!==(e=Jl(e,t))&&tu(e)}wl=function(e,t,n){var r=t.expirationTime;if(null!==e){var o=t.pendingProps;if(e.memoizedProps!==o||mo.current)La=!0;else{if(r<n){switch(La=!1,t.tag){case 3:$a(t),Aa();break;case 5:if(Ii(t),4&t.mode&&1!==n&&o.hidden)return t.expirationTime=t.childExpirationTime=1,null;break;case 1:go(t.type)&&xo(t);break;case 4:Mi(t,t.stateNode.containerInfo);break;case 10:r=t.memoizedProps.value,o=t.type._context,fo(Yo,o._currentValue),o._currentValue=r;break;case 13:if(null!==t.memoizedState)return 0!==(r=t.child.childExpirationTime)&&r>=n?Ha(e,t,n):(fo(Ni,1&Ni.current),null!==(t=Ga(e,t,n))?t.sibling:null);fo(Ni,1&Ni.current);break;case 19:if(r=t.childExpirationTime>=n,0!=(64&e.effectTag)){if(r)return Qa(e,t,n);t.effectTag|=64}if(null!==(o=t.memoizedState)&&(o.rendering=null,o.tail=null),fo(Ni,Ni.current),!r)return null}return Ga(e,t,n)}La=!1}}else La=!1;switch(t.expirationTime=0,t.tag){case 2:if(r=t.type,null!==e&&(e.alternate=null,t.alternate=null,t.effectTag|=2),e=t.pendingProps,o=yo(t,ho.current),ii(t,n),o=Gi(null,t,r,e,o,n),t.effectTag|=1,"object"==typeof o&&null!==o&&"function"==typeof o.render&&void 0===o.$$typeof){if(t.tag=1,t.memoizedState=null,t.updateQueue=null,go(r)){var i=!0;xo(t)}else i=!1;t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,ui(t);var l=r.getDerivedStateFromProps;"function"==typeof l&&yi(t,r,l,e),o.updater=gi,t.stateNode=o,o._reactInternalFiber=t,xi(t,r,e,n),t=qa(null,t,r,!0,i,n)}else t.tag=0,Ra(null,t,o,n),t=t.child;return t;case 16:e:{if(o=t.elementType,null!==e&&(e.alternate=null,t.alternate=null,t.effectTag|=2),e=t.pendingProps,function(e){if(-1===e._status){e._status=0;var t=e._ctor;t=t(),e._result=t,t.then((function(t){0===e._status&&(t=t.default,e._status=1,e._result=t)}),(function(t){0===e._status&&(e._status=2,e._result=t)}))}}(o),1!==o._status)throw o._result;switch(o=o._result,t.type=o,i=t.tag=function(e){if("function"==typeof e)return Pu(e)?1:0;if(null!=e){if((e=e.$$typeof)===ue)return 11;if(e===fe)return 14}return 2}(o),e=Xo(o,e),i){case 0:t=Na(null,t,o,e,n);break e;case 1:t=za(null,t,o,e,n);break e;case 11:t=Ma(null,t,o,e,n);break e;case 14:t=Da(null,t,o,Xo(o.type,e),r,n);break e}throw Error(a(306,o,""))}return t;case 0:return r=t.type,o=t.pendingProps,Na(e,t,r,o=t.elementType===r?o:Xo(r,o),n);case 1:return r=t.type,o=t.pendingProps,za(e,t,r,o=t.elementType===r?o:Xo(r,o),n);case 3:if($a(t),r=t.updateQueue,null===e||null===r)throw Error(a(282));if(r=t.pendingProps,o=null!==(o=t.memoizedState)?o.element:null,si(e,t),di(t,r,null,n),(r=t.memoizedState.element)===o)Aa(),t=Ga(e,t,n);else{if((o=t.stateNode.hydrate)&&(Oa=On(t.stateNode.containerInfo.firstChild),xa=t,o=Sa=!0),o)for(n=Ei(t,null,r,n),t.child=n;n;)n.effectTag=-3&n.effectTag|1024,n=n.sibling;else Ra(e,t,r,n),Aa();t=t.child}return t;case 5:return Ii(t),null===e&&Ca(t),r=t.type,o=t.pendingProps,i=null!==e?e.memoizedProps:null,l=o.children,wn(r,o)?l=null:null!==i&&wn(r,i)&&(t.effectTag|=16),Fa(e,t),4&t.mode&&1!==n&&o.hidden?(t.expirationTime=t.childExpirationTime=1,t=null):(Ra(e,t,l,n),t=t.child),t;case 6:return null===e&&Ca(t),null;case 13:return Ha(e,t,n);case 4:return Mi(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=Ci(t,null,r,n):Ra(e,t,r,n),t.child;case 11:return r=t.type,o=t.pendingProps,Ma(e,t,r,o=t.elementType===r?o:Xo(r,o),n);case 7:return Ra(e,t,t.pendingProps,n),t.child;case 8:case 12:return Ra(e,t,t.pendingProps.children,n),t.child;case 10:e:{r=t.type._context,o=t.pendingProps,l=t.memoizedProps,i=o.value;var u=t.type._context;if(fo(Yo,u._currentValue),u._currentValue=i,null!==l)if(u=l.value,0==(i=zr(u,i)?0:0|("function"==typeof r._calculateChangedBits?r._calculateChangedBits(u,i):1073741823))){if(l.children===o.children&&!mo.current){t=Ga(e,t,n);break e}}else for(null!==(u=t.child)&&(u.return=t);null!==u;){var s=u.dependencies;if(null!==s){l=u.child;for(var c=s.firstContext;null!==c;){if(c.context===r&&0!=(c.observedBits&i)){1===u.tag&&((c=ci(n,null)).tag=2,fi(u,c)),u.expirationTime<n&&(u.expirationTime=n),null!==(c=u.alternate)&&c.expirationTime<n&&(c.expirationTime=n),oi(u.return,n),s.expirationTime<n&&(s.expirationTime=n);break}c=c.next}}else l=10===u.tag&&u.type===t.type?null:u.child;if(null!==l)l.return=u;else for(l=u;null!==l;){if(l===t){l=null;break}if(null!==(u=l.sibling)){u.return=l.return,l=u;break}l=l.return}u=l}Ra(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,r=(i=t.pendingProps).children,ii(t,n),r=r(o=ai(o,i.unstable_observedBits)),t.effectTag|=1,Ra(e,t,r,n),t.child;case 14:return i=Xo(o=t.type,t.pendingProps),Da(e,t,o,i=Xo(o.type,i),r,n);case 15:return Ia(e,t,t.type,t.pendingProps,r,n);case 17:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:Xo(r,o),null!==e&&(e.alternate=null,t.alternate=null,t.effectTag|=2),t.tag=1,go(r)?(e=!0,xo(t)):e=!1,ii(t,n),wi(t,r,o),xi(t,r,o,n),qa(null,t,r,!0,e,n);case 19:return Qa(e,t,n)}throw Error(a(156,t.tag))};var ku=null,ju=null;function Cu(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.effectTag=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childExpirationTime=this.expirationTime=0,this.alternate=null}function Eu(e,t,n,r){return new Cu(e,t,n,r)}function Pu(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Au(e,t){var n=e.alternate;return null===n?((n=Eu(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.effectTag=0,n.nextEffect=null,n.firstEffect=null,n.lastEffect=null),n.childExpirationTime=e.childExpirationTime,n.expirationTime=e.expirationTime,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{expirationTime:t.expirationTime,firstContext:t.firstContext,responders:t.responders},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Tu(e,t,n,r,o,i){var l=2;if(r=e,"function"==typeof e)Pu(e)&&(l=1);else if("string"==typeof e)l=5;else e:switch(e){case ne:return Lu(n.children,o,i,t);case le:l=8,o|=7;break;case re:l=8,o|=1;break;case oe:return(e=Eu(12,n,t,8|o)).elementType=oe,e.type=oe,e.expirationTime=i,e;case se:return(e=Eu(13,n,t,o)).type=se,e.elementType=se,e.expirationTime=i,e;case ce:return(e=Eu(19,n,t,o)).elementType=ce,e.expirationTime=i,e;default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case ie:l=10;break e;case ae:l=9;break e;case ue:l=11;break e;case fe:l=14;break e;case pe:l=16,r=null;break e;case de:l=22;break e}throw Error(a(130,null==e?e:typeof e,""))}return(t=Eu(l,n,t,o)).elementType=e,t.type=r,t.expirationTime=i,t}function Lu(e,t,n,r){return(e=Eu(7,e,r,t)).expirationTime=n,e}function Ru(e,t,n){return(e=Eu(6,e,null,t)).expirationTime=n,e}function Mu(e,t,n){return(t=Eu(4,null!==e.children?e.children:[],e.key,t)).expirationTime=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Du(e,t,n){this.tag=t,this.current=null,this.containerInfo=e,this.pingCache=this.pendingChildren=null,this.finishedExpirationTime=0,this.finishedWork=null,this.timeoutHandle=-1,this.pendingContext=this.context=null,this.hydrate=n,this.callbackNode=null,this.callbackPriority=90,this.lastExpiredTime=this.lastPingedTime=this.nextKnownPendingLevel=this.lastSuspendedTime=this.firstSuspendedTime=this.firstPendingTime=0}function Iu(e,t){var n=e.firstSuspendedTime;return e=e.lastSuspendedTime,0!==n&&n>=t&&e<=t}function Fu(e,t){var n=e.firstSuspendedTime,r=e.lastSuspendedTime;n<t&&(e.firstSuspendedTime=t),(r>t||0===n)&&(e.lastSuspendedTime=t),t<=e.lastPingedTime&&(e.lastPingedTime=0),t<=e.lastExpiredTime&&(e.lastExpiredTime=0)}function Nu(e,t){t>e.firstPendingTime&&(e.firstPendingTime=t);var n=e.firstSuspendedTime;0!==n&&(t>=n?e.firstSuspendedTime=e.lastSuspendedTime=e.nextKnownPendingLevel=0:t>=e.lastSuspendedTime&&(e.lastSuspendedTime=t+1),t>e.nextKnownPendingLevel&&(e.nextKnownPendingLevel=t))}function zu(e,t){var n=e.lastExpiredTime;(0===n||n>t)&&(e.lastExpiredTime=t)}function qu(e,t,n,r){var o=t.current,i=Gl(),l=mi.suspense;i=Xl(i,o,l);e:if(n){t:{if(Ye(n=n._reactInternalFiber)!==n||1!==n.tag)throw Error(a(170));var u=n;do{switch(u.tag){case 3:u=u.stateNode.context;break t;case 1:if(go(u.type)){u=u.stateNode.__reactInternalMemoizedMergedChildContext;break t}}u=u.return}while(null!==u);throw Error(a(171))}if(1===n.tag){var s=n.type;if(go(s)){n=_o(n,s,u);break e}}n=u}else n=po;return null===t.context?t.context=n:t.pendingContext=n,(t=ci(i,l)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),fi(o,t),Yl(o,i),i}function $u(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function Bu(e,t){null!==(e=e.memoizedState)&&null!==e.dehydrated&&e.retryTime<t&&(e.retryTime=t)}function Uu(e,t){Bu(e,t),(e=e.alternate)&&Bu(e,t)}function Vu(e,t,n){var r=new Du(e,t,n=null!=n&&!0===n.hydrate),o=Eu(3,null,null,2===t?7:1===t?3:0);r.current=o,o.stateNode=r,ui(o),e[En]=r.current,n&&0!==t&&function(e,t){var n=Xe(t);kt.forEach((function(e){dt(e,t,n)})),jt.forEach((function(e){dt(e,t,n)}))}(0,9===e.nodeType?e:e.ownerDocument),this._internalRoot=r}function Wu(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function Hu(e,t,n,r,o){var i=n._reactRootContainer;if(i){var a=i._internalRoot;if("function"==typeof o){var l=o;o=function(){var e=$u(a);l.call(e)}}qu(t,a,e,o)}else{if(i=n._reactRootContainer=function(e,t){if(t||(t=!(!(t=e?9===e.nodeType?e.documentElement:e.firstChild:null)||1!==t.nodeType||!t.hasAttribute("data-reactroot"))),!t)for(var n;n=e.lastChild;)e.removeChild(n);return new Vu(e,0,t?{hydrate:!0}:void 0)}(n,r),a=i._internalRoot,"function"==typeof o){var u=o;o=function(){var e=$u(a);u.call(e)}}iu((function(){qu(t,a,e,o)}))}return $u(a)}function Zu(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:te,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}function Ku(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!Wu(t))throw Error(a(200));return Zu(e,t,null,n)}Vu.prototype.render=function(e){qu(e,this._internalRoot,null,null)},Vu.prototype.unmount=function(){var e=this._internalRoot,t=e.containerInfo;qu(null,e,null,(function(){t[En]=null}))},ht=function(e){if(13===e.tag){var t=Go(Gl(),150,100);Yl(e,t),Uu(e,t)}},mt=function(e){13===e.tag&&(Yl(e,3),Uu(e,3))},bt=function(e){if(13===e.tag){var t=Gl();Yl(e,t=Xl(t,e,null)),Uu(e,t)}},E=function(e,t,n){switch(t){case"input":if(ke(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var o=Ln(r);if(!o)throw Error(a(90));_e(r),ke(r,o)}}}break;case"textarea":Le(e,n);break;case"select":null!=(t=n.value)&&Pe(e,!!n.multiple,t,!1)}},M=ou,D=function(e,t,n,r,o){var i=Cl;Cl|=4;try{return Wo(98,e.bind(null,t,n,r,o))}finally{0===(Cl=i)&&Ko()}},I=function(){0==(49&Cl)&&(function(){if(null!==Hl){var e=Hl;Hl=null,e.forEach((function(e,t){zu(t,e),tu(t)})),Ko()}}(),vu())},F=function(e,t){var n=Cl;Cl|=2;try{return e(t)}finally{0===(Cl=n)&&Ko()}};var Qu={Events:[An,Tn,Ln,j,O,zn,function(e){rt(e,Nn)},L,R,Gt,at,vu,{current:!1}]};!function(e){var t=e.findFiberByHostInstance;!function(e){if("undefined"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__)return!1;var t=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(t.isDisabled||!t.supportsFiber)return!0;try{var n=t.inject(e);ku=function(e){try{t.onCommitFiberRoot(n,e,void 0,64==(64&e.current.effectTag))}catch(e){}},ju=function(e){try{t.onCommitFiberUnmount(n,e)}catch(e){}}}catch(e){}}(o({},e,{overrideHookState:null,overrideProps:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:G.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=tt(e))?null:e.stateNode},findFiberByHostInstance:function(e){return t?t(e):null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null}))}({findFiberByHostInstance:Pn,bundleType:0,version:"16.14.0",rendererPackageName:"react-dom"}),t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=Qu,t.createPortal=Ku,t.findDOMNode=function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternalFiber;if(void 0===t){if("function"==typeof e.render)throw Error(a(188));throw Error(a(268,Object.keys(e)))}return null===(e=tt(t))?null:e.stateNode},t.flushSync=function(e,t){if(0!=(48&Cl))throw Error(a(187));var n=Cl;Cl|=1;try{return Wo(99,e.bind(null,t))}finally{Cl=n,Ko()}},t.hydrate=function(e,t,n){if(!Wu(t))throw Error(a(200));return Hu(null,e,t,!0,n)},t.render=function(e,t,n){if(!Wu(t))throw Error(a(200));return Hu(null,e,t,!1,n)},t.unmountComponentAtNode=function(e){if(!Wu(e))throw Error(a(40));return!!e._reactRootContainer&&(iu((function(){Hu(null,null,e,!1,(function(){e._reactRootContainer=null,e[En]=null}))})),!0)},t.unstable_batchedUpdates=ou,t.unstable_createPortal=function(e,t){return Ku(e,t,2<arguments.length&&void 0!==arguments[2]?arguments[2]:null)},t.unstable_renderSubtreeIntoContainer=function(e,t,n,r){if(!Wu(n))throw Error(a(200));if(null==e||void 0===e._reactInternalFiber)throw Error(a(38));return Hu(e,t,n,!1,r)},t.version="16.14.0"},3935:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(e){console.error(e)}}(),e.exports=n(4448)},9921:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,i=n?Symbol.for("react.fragment"):60107,a=n?Symbol.for("react.strict_mode"):60108,l=n?Symbol.for("react.profiler"):60114,u=n?Symbol.for("react.provider"):60109,s=n?Symbol.for("react.context"):60110,c=n?Symbol.for("react.async_mode"):60111,f=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,d=n?Symbol.for("react.suspense"):60113,h=n?Symbol.for("react.suspense_list"):60120,m=n?Symbol.for("react.memo"):60115,b=n?Symbol.for("react.lazy"):60116,y=n?Symbol.for("react.block"):60121,g=n?Symbol.for("react.fundamental"):60117,v=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function _(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case c:case f:case i:case l:case a:case d:return e;default:switch(e=e&&e.$$typeof){case s:case p:case b:case m:case u:return e;default:return t}}case o:return t}}}function x(e){return _(e)===f}t.AsyncMode=c,t.ConcurrentMode=f,t.ContextConsumer=s,t.ContextProvider=u,t.Element=r,t.ForwardRef=p,t.Fragment=i,t.Lazy=b,t.Memo=m,t.Portal=o,t.Profiler=l,t.StrictMode=a,t.Suspense=d,t.isAsyncMode=function(e){return x(e)||_(e)===c},t.isConcurrentMode=x,t.isContextConsumer=function(e){return _(e)===s},t.isContextProvider=function(e){return _(e)===u},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return _(e)===p},t.isFragment=function(e){return _(e)===i},t.isLazy=function(e){return _(e)===b},t.isMemo=function(e){return _(e)===m},t.isPortal=function(e){return _(e)===o},t.isProfiler=function(e){return _(e)===l},t.isStrictMode=function(e){return _(e)===a},t.isSuspense=function(e){return _(e)===d},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===i||e===f||e===l||e===a||e===d||e===h||"object"==typeof e&&null!==e&&(e.$$typeof===b||e.$$typeof===m||e.$$typeof===u||e.$$typeof===s||e.$$typeof===p||e.$$typeof===g||e.$$typeof===v||e.$$typeof===w||e.$$typeof===y)},t.typeOf=_},9864:(e,t,n)=>{"use strict";e.exports=n(9921)},9250:(e,t,n)=>{"use strict";var r;n.d(t,{F0:()=>w,TH:()=>h,s0:()=>m});var o=n(2599),i=n(7294);"function"==typeof Object.is&&Object.is;const{useState:a,useEffect:l,useLayoutEffect:u,useDebugValue:s}=r||(r=n.t(i,2));"undefined"==typeof window||void 0===window.document||window.document.createElement;const c=i.createContext(null),f=i.createContext(null),p=i.createContext({outlet:null,matches:[]});function d(){return null!=i.useContext(f)}function h(){return d()||(0,o.kG)(!1),i.useContext(f).location}function m(){d()||(0,o.kG)(!1);let{basename:e,navigator:t}=i.useContext(c),{matches:n}=i.useContext(p),{pathname:r}=h(),a=JSON.stringify((0,o.Zq)(n).map((e=>e.pathnameBase))),l=i.useRef(!1);return i.useEffect((()=>{l.current=!0})),i.useCallback((function(n,i){if(void 0===i&&(i={}),!l.current)return;if("number"==typeof n)return void t.go(n);let u=(0,o.pC)(n,JSON.parse(a),r,"path"===i.relative);"/"!==e&&(u.pathname="/"===u.pathname?e:(0,o.RQ)([e,u.pathname])),(i.replace?t.replace:t.push)(u,i.state,i)}),[e,t,a,r])}class b extends i.Component{constructor(e){super(e),this.state={location:e.location,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location?{error:e.error,location:e.location}:{error:e.error||t.error,location:t.location}}componentDidCatch(e,t){console.error("React Router caught the following error during render",e,t)}render(){return this.state.error?React.createElement(RouteErrorContext.Provider,{value:this.state.error,children:this.props.component}):this.props.children}}var y,g,v;function w(e){let{basename:t="/",children:n=null,location:r,navigationType:a=o.aU.Pop,navigator:l,static:u=!1}=e;d()&&(0,o.kG)(!1);let s=t.replace(/^\/*/,"/"),p=i.useMemo((()=>({basename:s,navigator:l,static:u})),[s,l,u]);"string"==typeof r&&(r=(0,o.cP)(r));let{pathname:h="/",search:m="",hash:b="",state:y=null,key:g="default"}=r,v=i.useMemo((()=>{let e=(0,o.Zn)(h,s);return null==e?null:{pathname:e,search:m,hash:b,state:y,key:g}}),[s,h,m,b,y,g]);return null==v?null:i.createElement(c.Provider,{value:p},i.createElement(f.Provider,{children:n,value:{location:v,navigationType:a}}))}!function(e){e.UseRevalidator="useRevalidator"}(y||(y={})),function(e){e.UseLoaderData="useLoaderData",e.UseActionData="useActionData",e.UseRouteError="useRouteError",e.UseNavigation="useNavigation",e.UseRouteLoaderData="useRouteLoaderData",e.UseMatches="useMatches",e.UseRevalidator="useRevalidator"}(g||(g={})),function(e){e[e.pending=0]="pending",e[e.success=1]="success",e[e.error=2]="error"}(v||(v={})),new Promise((()=>{}));class _ extends i.Component{constructor(e){super(e),this.state={error:null}}static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){console.error("<Await> caught the following error during render",e,t)}render(){let{children:e,errorElement:t,resolve:n}=this.props,r=null,o=v.pending;if(n instanceof Promise)if(this.state.error){v.error;let e=this.state.error;Promise.reject().catch((()=>{})),Object.defineProperty(r,"_tracked",{get:()=>!0}),Object.defineProperty(r,"_error",{get:()=>e})}else n._tracked?void 0!==r._error?v.error:void 0!==r._data?v.success:v.pending:(v.pending,Object.defineProperty(n,"_tracked",{get:()=>!0}),n.then((e=>Object.defineProperty(n,"_data",{get:()=>e})),(e=>Object.defineProperty(n,"_error",{get:()=>e}))));else v.success,Promise.resolve(),Object.defineProperty(r,"_tracked",{get:()=>!0}),Object.defineProperty(r,"_data",{get:()=>n});if(o===v.error&&r._error instanceof AbortedDeferredError)throw neverSettledPromise;if(o===v.error&&!t)throw r._error;if(o===v.error)return React.createElement(AwaitContext.Provider,{value:r,children:t});if(o===v.success)return React.createElement(AwaitContext.Provider,{value:r,children:e});throw r}}},9920:(e,t,n)=>{"use strict";n.r(t);var r=n(1472),o={};for(const e in r)"default"!==e&&(o[e]=()=>r[e]);n.d(t,o)},2408:(e,t,n)=>{"use strict";var r=n(7418),o="function"==typeof Symbol&&Symbol.for,i=o?Symbol.for("react.element"):60103,a=o?Symbol.for("react.portal"):60106,l=o?Symbol.for("react.fragment"):60107,u=o?Symbol.for("react.strict_mode"):60108,s=o?Symbol.for("react.profiler"):60114,c=o?Symbol.for("react.provider"):60109,f=o?Symbol.for("react.context"):60110,p=o?Symbol.for("react.forward_ref"):60112,d=o?Symbol.for("react.suspense"):60113,h=o?Symbol.for("react.memo"):60115,m=o?Symbol.for("react.lazy"):60116,b="function"==typeof Symbol&&Symbol.iterator;function y(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},v={};function w(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||g}function _(){}function x(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||g}w.prototype.isReactComponent={},w.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error(y(85));this.updater.enqueueSetState(this,e,t,"setState")},w.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},_.prototype=w.prototype;var O=x.prototype=new _;O.constructor=x,r(O,w.prototype),O.isPureReactComponent=!0;var S={current:null},k=Object.prototype.hasOwnProperty,j={key:!0,ref:!0,__self:!0,__source:!0};function C(e,t,n){var r,o={},a=null,l=null;if(null!=t)for(r in void 0!==t.ref&&(l=t.ref),void 0!==t.key&&(a=""+t.key),t)k.call(t,r)&&!j.hasOwnProperty(r)&&(o[r]=t[r]);var u=arguments.length-2;if(1===u)o.children=n;else if(1<u){for(var s=Array(u),c=0;c<u;c++)s[c]=arguments[c+2];o.children=s}if(e&&e.defaultProps)for(r in u=e.defaultProps)void 0===o[r]&&(o[r]=u[r]);return{$$typeof:i,type:e,key:a,ref:l,props:o,_owner:S.current}}function E(e){return"object"==typeof e&&null!==e&&e.$$typeof===i}var P=/\/+/g,A=[];function T(e,t,n,r){if(A.length){var o=A.pop();return o.result=e,o.keyPrefix=t,o.func=n,o.context=r,o.count=0,o}return{result:e,keyPrefix:t,func:n,context:r,count:0}}function L(e){e.result=null,e.keyPrefix=null,e.func=null,e.context=null,e.count=0,10>A.length&&A.push(e)}function R(e,t,n,r){var o=typeof e;"undefined"!==o&&"boolean"!==o||(e=null);var l=!1;if(null===e)l=!0;else switch(o){case"string":case"number":l=!0;break;case"object":switch(e.$$typeof){case i:case a:l=!0}}if(l)return n(r,e,""===t?"."+D(e,0):t),1;if(l=0,t=""===t?".":t+":",Array.isArray(e))for(var u=0;u<e.length;u++){var s=t+D(o=e[u],u);l+=R(o,s,n,r)}else if("function"==typeof(s=null===e||"object"!=typeof e?null:"function"==typeof(s=b&&e[b]||e["@@iterator"])?s:null))for(e=s.call(e),u=0;!(o=e.next()).done;)l+=R(o=o.value,s=t+D(o,u++),n,r);else if("object"===o)throw n=""+e,Error(y(31,"[object Object]"===n?"object with keys {"+Object.keys(e).join(", ")+"}":n,""));return l}function M(e,t,n){return null==e?0:R(e,"",t,n)}function D(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+(""+e).replace(/[=:]/g,(function(e){return t[e]}))}(e.key):t.toString(36)}function I(e,t){e.func.call(e.context,t,e.count++)}function F(e,t,n){var r=e.result,o=e.keyPrefix;e=e.func.call(e.context,t,e.count++),Array.isArray(e)?N(e,r,n,(function(e){return e})):null!=e&&(E(e)&&(e=function(e,t){return{$$typeof:i,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(e,o+(!e.key||t&&t.key===e.key?"":(""+e.key).replace(P,"$&/")+"/")+n)),r.push(e))}function N(e,t,n,r,o){var i="";null!=n&&(i=(""+n).replace(P,"$&/")+"/"),M(e,F,t=T(t,i,r,o)),L(t)}var z={current:null};function q(){var e=z.current;if(null===e)throw Error(y(321));return e}var $={ReactCurrentDispatcher:z,ReactCurrentBatchConfig:{suspense:null},ReactCurrentOwner:S,IsSomeRendererActing:{current:!1},assign:r};t.Children={map:function(e,t,n){if(null==e)return e;var r=[];return N(e,r,null,t,n),r},forEach:function(e,t,n){if(null==e)return e;M(e,I,t=T(null,null,t,n)),L(t)},count:function(e){return M(e,(function(){return null}),null)},toArray:function(e){var t=[];return N(e,t,null,(function(e){return e})),t},only:function(e){if(!E(e))throw Error(y(143));return e}},t.Component=w,t.Fragment=l,t.Profiler=s,t.PureComponent=x,t.StrictMode=u,t.Suspense=d,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=$,t.cloneElement=function(e,t,n){if(null==e)throw Error(y(267,e));var o=r({},e.props),a=e.key,l=e.ref,u=e._owner;if(null!=t){if(void 0!==t.ref&&(l=t.ref,u=S.current),void 0!==t.key&&(a=""+t.key),e.type&&e.type.defaultProps)var s=e.type.defaultProps;for(c in t)k.call(t,c)&&!j.hasOwnProperty(c)&&(o[c]=void 0===t[c]&&void 0!==s?s[c]:t[c])}var c=arguments.length-2;if(1===c)o.children=n;else if(1<c){s=Array(c);for(var f=0;f<c;f++)s[f]=arguments[f+2];o.children=s}return{$$typeof:i,type:e.type,key:a,ref:l,props:o,_owner:u}},t.createContext=function(e,t){return void 0===t&&(t=null),(e={$$typeof:f,_calculateChangedBits:t,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:c,_context:e},e.Consumer=e},t.createElement=C,t.createFactory=function(e){var t=C.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:p,render:e}},t.isValidElement=E,t.lazy=function(e){return{$$typeof:m,_ctor:e,_status:-1,_result:null}},t.memo=function(e,t){return{$$typeof:h,type:e,compare:void 0===t?null:t}},t.useCallback=function(e,t){return q().useCallback(e,t)},t.useContext=function(e,t){return q().useContext(e,t)},t.useDebugValue=function(){},t.useEffect=function(e,t){return q().useEffect(e,t)},t.useImperativeHandle=function(e,t,n){return q().useImperativeHandle(e,t,n)},t.useLayoutEffect=function(e,t){return q().useLayoutEffect(e,t)},t.useMemo=function(e,t){return q().useMemo(e,t)},t.useReducer=function(e,t,n){return q().useReducer(e,t,n)},t.useRef=function(e){return q().useRef(e)},t.useState=function(e){return q().useState(e)},t.version="16.14.0"},7294:(e,t,n)=>{"use strict";e.exports=n(2408)},53:(e,t)=>{"use strict";var n,r,o,i,a;if("undefined"==typeof window||"function"!=typeof MessageChannel){var l=null,u=null,s=function(){if(null!==l)try{var e=t.unstable_now();l(!0,e),l=null}catch(e){throw setTimeout(s,0),e}},c=Date.now();t.unstable_now=function(){return Date.now()-c},n=function(e){null!==l?setTimeout(n,0,e):(l=e,setTimeout(s,0))},r=function(e,t){u=setTimeout(e,t)},o=function(){clearTimeout(u)},i=function(){return!1},a=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,p=window.Date,d=window.setTimeout,h=window.clearTimeout;if("undefined"!=typeof console){var m=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof m&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var b=p.now();t.unstable_now=function(){return p.now()-b}}var y=!1,g=null,v=-1,w=5,_=0;i=function(){return t.unstable_now()>=_},a=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):w=0<e?Math.floor(1e3/e):5};var x=new MessageChannel,O=x.port2;x.port1.onmessage=function(){if(null!==g){var e=t.unstable_now();_=e+w;try{g(!0,e)?O.postMessage(null):(y=!1,g=null)}catch(e){throw O.postMessage(null),e}}else y=!1},n=function(e){g=e,y||(y=!0,O.postMessage(null))},r=function(e,n){v=d((function(){e(t.unstable_now())}),n)},o=function(){h(v),v=-1}}function S(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,o=e[r];if(!(void 0!==o&&0<C(o,t)))break e;e[r]=t,e[n]=o,n=r}}function k(e){return void 0===(e=e[0])?null:e}function j(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,o=e.length;r<o;){var i=2*(r+1)-1,a=e[i],l=i+1,u=e[l];if(void 0!==a&&0>C(a,n))void 0!==u&&0>C(u,a)?(e[r]=u,e[l]=n,r=l):(e[r]=a,e[i]=n,r=i);else{if(!(void 0!==u&&0>C(u,n)))break e;e[r]=u,e[l]=n,r=l}}}return t}return null}function C(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var E=[],P=[],A=1,T=null,L=3,R=!1,M=!1,D=!1;function I(e){for(var t=k(P);null!==t;){if(null===t.callback)j(P);else{if(!(t.startTime<=e))break;j(P),t.sortIndex=t.expirationTime,S(E,t)}t=k(P)}}function F(e){if(D=!1,I(e),!M)if(null!==k(E))M=!0,n(N);else{var t=k(P);null!==t&&r(F,t.startTime-e)}}function N(e,n){M=!1,D&&(D=!1,o()),R=!0;var a=L;try{for(I(n),T=k(E);null!==T&&(!(T.expirationTime>n)||e&&!i());){var l=T.callback;if(null!==l){T.callback=null,L=T.priorityLevel;var u=l(T.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?T.callback=u:T===k(E)&&j(E),I(n)}else j(E);T=k(E)}if(null!==T)var s=!0;else{var c=k(P);null!==c&&r(F,c.startTime-n),s=!1}return s}finally{T=null,L=a,R=!1}}function z(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var q=a;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){M||R||(M=!0,n(N))},t.unstable_getCurrentPriorityLevel=function(){return L},t.unstable_getFirstCallbackNode=function(){return k(E)},t.unstable_next=function(e){switch(L){case 1:case 2:case 3:var t=3;break;default:t=L}var n=L;L=t;try{return e()}finally{L=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=q,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=L;L=e;try{return t()}finally{L=n}},t.unstable_scheduleCallback=function(e,i,a){var l=t.unstable_now();if("object"==typeof a&&null!==a){var u=a.delay;u="number"==typeof u&&0<u?l+u:l,a="number"==typeof a.timeout?a.timeout:z(e)}else a=z(e),u=l;return e={id:A++,callback:i,priorityLevel:e,startTime:u,expirationTime:a=u+a,sortIndex:-1},u>l?(e.sortIndex=u,S(P,e),null===k(E)&&e===k(P)&&(D?o():D=!0,r(F,u-l))):(e.sortIndex=a,S(E,e),M||R||(M=!0,n(N))),e},t.unstable_shouldYield=function(){var e=t.unstable_now();I(e);var n=k(E);return n!==T&&null!==T&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime<T.expirationTime||i()},t.unstable_wrapCallback=function(e){var t=L;return function(){var n=L;L=t;try{return e.apply(this,arguments)}finally{L=n}}}},3840:(e,t,n)=>{"use strict";e.exports=n(53)},5277:(e,t,n)=>{var r,o,i;i=function(){var e,t,n=document,r=n.getElementsByTagName("head")[0],o={},i={},a={},l={};function u(e,t){for(var n=0,r=e.length;n<r;++n)if(!t(e[n]))return!1;return 1}function s(e,t){u(e,(function(e){return t(e),1}))}function c(t,n,r){t=t.push?t:[t];var p=n&&n.call,d=p?n:r,h=p?t.join(""):n,m=t.length;function b(e){return e.call?e():o[e]}function y(){if(!--m)for(var e in o[h]=1,d&&d(),a)u(e.split("|"),b)&&!s(a[e],b)&&(a[e]=[])}return setTimeout((function(){s(t,(function t(n,r){return null===n?y():(r||/^https?:\/\//.test(n)||!e||(n=-1===n.indexOf(".js")?e+n+".js":e+n),l[n]?(h&&(i[h]=1),2==l[n]?y():setTimeout((function(){t(n,!0)}),0)):(l[n]=1,h&&(i[h]=1),void f(n,y)))}))}),0),c}function f(e,o){var i,a=n.createElement("script");a.onload=a.onerror=a.onreadystatechange=function(){a.readyState&&!/^c|loade/.test(a.readyState)||i||(a.onload=a.onreadystatechange=null,i=1,l[e]=2,o())},a.async=1,a.src=t?e+(-1===e.indexOf("?")?"?":"&")+t:e,r.insertBefore(a,r.lastChild)}return c.get=f,c.order=function(e,t,n){!function r(o){o=e.shift(),e.length?c(o,r):c(o,t,n)}()},c.path=function(t){e=t},c.urlArgs=function(e){t=e},c.ready=function(e,t,n){e=e.push?e:[e];var r,i=[];return!s(e,(function(e){o[e]||i.push(e)}))&&u(e,(function(e){return o[e]}))?t():(r=e.join("|"),a[r]=a[r]||[],a[r].push(t),n&&n(i)),c},c.done=function(e){c([null],e)},c},e.exports?e.exports=i():void 0===(o="function"==typeof(r=i)?r.call(t,n,t,e):r)||(e.exports=o)},1032:e=>{e.exports=function(e,t,n,r){var o=n?n.call(r,e,t):void 0;if(void 0!==o)return!!o;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var i=Object.keys(e),a=Object.keys(t);if(i.length!==a.length)return!1;for(var l=Object.prototype.hasOwnProperty.bind(t),u=0;u<i.length;u++){var s=i[u];if(!l(s))return!1;var c=e[s],f=t[s];if(!1===(o=n?n.call(r,c,f,s):void 0)||void 0===o&&c!==f)return!1}return!0}},3379:e=>{"use strict";var t=[];function n(e){for(var n=-1,r=0;r<t.length;r++)if(t[r].identifier===e){n=r;break}return n}function r(e,r){for(var i={},a=[],l=0;l<e.length;l++){var u=e[l],s=r.base?u[0]+r.base:u[0],c=i[s]||0,f="".concat(s," ").concat(c);i[s]=c+1;var p=n(f),d={css:u[1],media:u[2],sourceMap:u[3],supports:u[4],layer:u[5]};if(-1!==p)t[p].references++,t[p].updater(d);else{var h=o(d,r);r.byIndex=l,t.splice(l,0,{identifier:f,updater:h,references:1})}a.push(f)}return a}function o(e,t){var n=t.domAPI(t);return n.update(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap&&t.supports===e.supports&&t.layer===e.layer)return;n.update(e=t)}else n.remove()}}e.exports=function(e,o){var i=r(e=e||[],o=o||{});return function(e){e=e||[];for(var a=0;a<i.length;a++){var l=n(i[a]);t[l].references--}for(var u=r(e,o),s=0;s<i.length;s++){var c=n(i[s]);0===t[c].references&&(t[c].updater(),t.splice(c,1))}i=u}}},569:e=>{"use strict";var t={};e.exports=function(e,n){var r=function(e){if(void 0===t[e]){var n=document.querySelector(e);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}t[e]=n}return t[e]}(e);if(!r)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");r.appendChild(n)}},9216:e=>{"use strict";e.exports=function(e){var t=document.createElement("style");return e.setAttributes(t,e.attributes),e.insert(t,e.options),t}},3565:(e,t,n)=>{"use strict";e.exports=function(e){var t=n.nc;t&&e.setAttribute("nonce",t)}},7795:e=>{"use strict";e.exports=function(e){var t=e.insertStyleElement(e);return{update:function(n){!function(e,t,n){var r="";n.supports&&(r+="@supports (".concat(n.supports,") {")),n.media&&(r+="@media ".concat(n.media," {"));var o=void 0!==n.layer;o&&(r+="@layer".concat(n.layer.length>0?" ".concat(n.layer):""," {")),r+=n.css,o&&(r+="}"),n.media&&(r+="}"),n.supports&&(r+="}");var i=n.sourceMap;i&&"undefined"!=typeof btoa&&(r+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(i))))," */")),t.styleTagTransform(r,e,t.options)}(t,e,n)},remove:function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(t)}}}},4589:e=>{"use strict";e.exports=function(e,t){if(t.styleSheet)t.styleSheet.cssText=e;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}}},2788:(e,t,n)=>{"use strict";n.r(t),n.d(t,{ServerStyleSheet:()=>qe,StyleSheetConsumer:()=>oe,StyleSheetContext:()=>re,StyleSheetManager:()=>ce,ThemeConsumer:()=>Le,ThemeContext:()=>Te,ThemeProvider:()=>Re,__PRIVATE__:()=>Ue,createGlobalStyle:()=>Ne,css:()=>we,default:()=>Ve,isStyledComponent:()=>w,keyframes:()=>ze,useTheme:()=>Be,version:()=>x,withTheme:()=>$e});var r=n(9864),o=n(7294),i=n(1032),a=n.n(i);const l=function(e){function t(e,r,u,s,p){for(var d,h,m,b,w,x=0,O=0,S=0,k=0,j=0,L=0,M=m=d=0,I=0,F=0,N=0,z=0,q=u.length,$=q-1,B="",U="",V="",W="";I<q;){if(h=u.charCodeAt(I),I===$&&0!==O+k+S+x&&(0!==O&&(h=47===O?10:47),k=S=x=0,q++,$++),0===O+k+S+x){if(I===$&&(0<F&&(B=B.replace(f,"")),0<B.trim().length)){switch(h){case 32:case 9:case 59:case 13:case 10:break;default:B+=u.charAt(I)}h=59}switch(h){case 123:for(d=(B=B.trim()).charCodeAt(0),m=1,z=++I;I<q;){switch(h=u.charCodeAt(I)){case 123:m++;break;case 125:m--;break;case 47:switch(h=u.charCodeAt(I+1)){case 42:case 47:e:{for(M=I+1;M<$;++M)switch(u.charCodeAt(M)){case 47:if(42===h&&42===u.charCodeAt(M-1)&&I+2!==M){I=M+1;break e}break;case 10:if(47===h){I=M+1;break e}}I=M}}break;case 91:h++;case 40:h++;case 34:case 39:for(;I++<$&&u.charCodeAt(I)!==h;);}if(0===m)break;I++}if(m=u.substring(z,I),0===d&&(d=(B=B.replace(c,"").trim()).charCodeAt(0)),64===d){switch(0<F&&(B=B.replace(f,"")),h=B.charCodeAt(1)){case 100:case 109:case 115:case 45:F=r;break;default:F=T}if(z=(m=t(r,F,m,h,p+1)).length,0<R&&(w=l(3,m,F=n(T,B,N),r,E,C,z,h,p,s),B=F.join(""),void 0!==w&&0===(z=(m=w.trim()).length)&&(h=0,m="")),0<z)switch(h){case 115:B=B.replace(_,a);case 100:case 109:case 45:m=B+"{"+m+"}";break;case 107:m=(B=B.replace(y,"$1 $2"))+"{"+m+"}",m=1===A||2===A&&i("@"+m,3)?"@-webkit-"+m+"@"+m:"@"+m;break;default:m=B+m,112===s&&(U+=m,m="")}else m=""}else m=t(r,n(r,B,N),m,s,p+1);V+=m,m=N=F=M=d=0,B="",h=u.charCodeAt(++I);break;case 125:case 59:if(1<(z=(B=(0<F?B.replace(f,""):B).trim()).length))switch(0===M&&(d=B.charCodeAt(0),45===d||96<d&&123>d)&&(z=(B=B.replace(" ",":")).length),0<R&&void 0!==(w=l(1,B,r,e,E,C,U.length,s,p,s))&&0===(z=(B=w.trim()).length)&&(B="\0\0"),d=B.charCodeAt(0),h=B.charCodeAt(1),d){case 0:break;case 64:if(105===h||99===h){W+=B+u.charAt(I);break}default:58!==B.charCodeAt(z-1)&&(U+=o(B,d,h,B.charCodeAt(2)))}N=F=M=d=0,B="",h=u.charCodeAt(++I)}}switch(h){case 13:case 10:47===O?O=0:0===1+d&&107!==s&&0<B.length&&(F=1,B+="\0"),0<R*D&&l(0,B,r,e,E,C,U.length,s,p,s),C=1,E++;break;case 59:case 125:if(0===O+k+S+x){C++;break}default:switch(C++,b=u.charAt(I),h){case 9:case 32:if(0===k+x+O)switch(j){case 44:case 58:case 9:case 32:b="";break;default:32!==h&&(b=" ")}break;case 0:b="\\0";break;case 12:b="\\f";break;case 11:b="\\v";break;case 38:0===k+O+x&&(F=N=1,b="\f"+b);break;case 108:if(0===k+O+x+P&&0<M)switch(I-M){case 2:112===j&&58===u.charCodeAt(I-3)&&(P=j);case 8:111===L&&(P=L)}break;case 58:0===k+O+x&&(M=I);break;case 44:0===O+S+k+x&&(F=1,b+="\r");break;case 34:case 39:0===O&&(k=k===h?0:0===k?h:k);break;case 91:0===k+O+S&&x++;break;case 93:0===k+O+S&&x--;break;case 41:0===k+O+x&&S--;break;case 40:0===k+O+x&&(0===d&&(2*j+3*L==533||(d=1)),S++);break;case 64:0===O+S+k+x+M+m&&(m=1);break;case 42:case 47:if(!(0<k+x+S))switch(O){case 0:switch(2*h+3*u.charCodeAt(I+1)){case 235:O=47;break;case 220:z=I,O=42}break;case 42:47===h&&42===j&&z+2!==I&&(33===u.charCodeAt(z+2)&&(U+=u.substring(z,I+1)),b="",O=0)}}0===O&&(B+=b)}L=j,j=h,I++}if(0<(z=U.length)){if(F=r,0<R&&void 0!==(w=l(2,U,F,e,E,C,z,s,p,s))&&0===(U=w).length)return W+U+V;if(U=F.join(",")+"{"+U+"}",0!=A*P){switch(2!==A||i(U,2)||(P=0),P){case 111:U=U.replace(v,":-moz-$1")+U;break;case 112:U=U.replace(g,"::-webkit-input-$1")+U.replace(g,"::-moz-$1")+U.replace(g,":-ms-input-$1")+U}P=0}}return W+U+V}function n(e,t,n){var o=t.trim().split(m);t=o;var i=o.length,a=e.length;switch(a){case 0:case 1:var l=0;for(e=0===a?"":e[0]+" ";l<i;++l)t[l]=r(e,t[l],n).trim();break;default:var u=l=0;for(t=[];l<i;++l)for(var s=0;s<a;++s)t[u++]=r(e[s]+" ",o[l],n).trim()}return t}function r(e,t,n){var r=t.charCodeAt(0);switch(33>r&&(r=(t=t.trim()).charCodeAt(0)),r){case 38:return t.replace(b,"$1"+e.trim());case 58:return e.trim()+t.replace(b,"$1"+e.trim());default:if(0<1*n&&0<t.indexOf("\f"))return t.replace(b,(58===e.charCodeAt(0)?"":"$1")+e.trim())}return e+t}function o(e,t,n,r){var a=e+";",l=2*t+3*n+4*r;if(944===l){e=a.indexOf(":",9)+1;var u=a.substring(e,a.length-1).trim();return u=a.substring(0,e).trim()+u+";",1===A||2===A&&i(u,1)?"-webkit-"+u+u:u}if(0===A||2===A&&!i(a,1))return a;switch(l){case 1015:return 97===a.charCodeAt(10)?"-webkit-"+a+a:a;case 951:return 116===a.charCodeAt(3)?"-webkit-"+a+a:a;case 963:return 110===a.charCodeAt(5)?"-webkit-"+a+a:a;case 1009:if(100!==a.charCodeAt(4))break;case 969:case 942:return"-webkit-"+a+a;case 978:return"-webkit-"+a+"-moz-"+a+a;case 1019:case 983:return"-webkit-"+a+"-moz-"+a+"-ms-"+a+a;case 883:if(45===a.charCodeAt(8))return"-webkit-"+a+a;if(0<a.indexOf("image-set(",11))return a.replace(j,"$1-webkit-$2")+a;break;case 932:if(45===a.charCodeAt(4))switch(a.charCodeAt(5)){case 103:return"-webkit-box-"+a.replace("-grow","")+"-webkit-"+a+"-ms-"+a.replace("grow","positive")+a;case 115:return"-webkit-"+a+"-ms-"+a.replace("shrink","negative")+a;case 98:return"-webkit-"+a+"-ms-"+a.replace("basis","preferred-size")+a}return"-webkit-"+a+"-ms-"+a+a;case 964:return"-webkit-"+a+"-ms-flex-"+a+a;case 1023:if(99!==a.charCodeAt(8))break;return"-webkit-box-pack"+(u=a.substring(a.indexOf(":",15)).replace("flex-","").replace("space-between","justify"))+"-webkit-"+a+"-ms-flex-pack"+u+a;case 1005:return d.test(a)?a.replace(p,":-webkit-")+a.replace(p,":-moz-")+a:a;case 1e3:switch(t=(u=a.substring(13).trim()).indexOf("-")+1,u.charCodeAt(0)+u.charCodeAt(t)){case 226:u=a.replace(w,"tb");break;case 232:u=a.replace(w,"tb-rl");break;case 220:u=a.replace(w,"lr");break;default:return a}return"-webkit-"+a+"-ms-"+u+a;case 1017:if(-1===a.indexOf("sticky",9))break;case 975:switch(t=(a=e).length-10,l=(u=(33===a.charCodeAt(t)?a.substring(0,t):a).substring(e.indexOf(":",7)+1).trim()).charCodeAt(0)+(0|u.charCodeAt(7))){case 203:if(111>u.charCodeAt(8))break;case 115:a=a.replace(u,"-webkit-"+u)+";"+a;break;case 207:case 102:a=a.replace(u,"-webkit-"+(102<l?"inline-":"")+"box")+";"+a.replace(u,"-webkit-"+u)+";"+a.replace(u,"-ms-"+u+"box")+";"+a}return a+";";case 938:if(45===a.charCodeAt(5))switch(a.charCodeAt(6)){case 105:return u=a.replace("-items",""),"-webkit-"+a+"-webkit-box-"+u+"-ms-flex-"+u+a;case 115:return"-webkit-"+a+"-ms-flex-item-"+a.replace(O,"")+a;default:return"-webkit-"+a+"-ms-flex-line-pack"+a.replace("align-content","").replace(O,"")+a}break;case 973:case 989:if(45!==a.charCodeAt(3)||122===a.charCodeAt(4))break;case 931:case 953:if(!0===k.test(e))return 115===(u=e.substring(e.indexOf(":")+1)).charCodeAt(0)?o(e.replace("stretch","fill-available"),t,n,r).replace(":fill-available",":stretch"):a.replace(u,"-webkit-"+u)+a.replace(u,"-moz-"+u.replace("fill-",""))+a;break;case 962:if(a="-webkit-"+a+(102===a.charCodeAt(5)?"-ms-"+a:"")+a,211===n+r&&105===a.charCodeAt(13)&&0<a.indexOf("transform",10))return a.substring(0,a.indexOf(";",27)+1).replace(h,"$1-webkit-$2")+a}return a}function i(e,t){var n=e.indexOf(1===t?":":"{"),r=e.substring(0,3!==t?n:10);return n=e.substring(n+1,e.length-1),M(2!==t?r:r.replace(S,"$1"),n,t)}function a(e,t){var n=o(t,t.charCodeAt(0),t.charCodeAt(1),t.charCodeAt(2));return n!==t+";"?n.replace(x," or ($1)").substring(4):"("+t+")"}function l(e,t,n,r,o,i,a,l,u,c){for(var f,p=0,d=t;p<R;++p)switch(f=L[p].call(s,e,d,n,r,o,i,a,l,u,c)){case void 0:case!1:case!0:case null:break;default:d=f}if(d!==t)return d}function u(e){return void 0!==(e=e.prefix)&&(M=null,e?"function"!=typeof e?A=1:(A=2,M=e):A=0),u}function s(e,n){var r=e;if(33>r.charCodeAt(0)&&(r=r.trim()),r=[r],0<R){var o=l(-1,n,r,r,E,C,0,0,0,0);void 0!==o&&"string"==typeof o&&(n=o)}var i=t(T,r,n,0,0);return 0<R&&void 0!==(o=l(-2,i,r,r,E,C,i.length,0,0,0))&&(i=o),P=0,C=E=1,i}var c=/^\0+/g,f=/[\0\r\f]/g,p=/: */g,d=/zoo|gra/,h=/([,: ])(transform)/g,m=/,\r+?/g,b=/([\t\r\n ])*\f?&/g,y=/@(k\w+)\s*(\S*)\s*/,g=/::(place)/g,v=/:(read-only)/g,w=/[svh]\w+-[tblr]{2}/,_=/\(\s*(.*)\s*\)/g,x=/([\s\S]*?);/g,O=/-self|flex-/g,S=/[^]*?(:[rp][el]a[\w-]+)[^]*/,k=/stretch|:\s*\w+\-(?:conte|avail)/,j=/([^-])(image-set\()/,C=1,E=1,P=0,A=1,T=[],L=[],R=0,M=null,D=0;return s.use=function e(t){switch(t){case void 0:case null:R=L.length=0;break;default:if("function"==typeof t)L[R++]=t;else if("object"==typeof t)for(var n=0,r=t.length;n<r;++n)e(t[n]);else D=0|!!t}return e},s.set=u,void 0!==e&&u(e),s},u={animationIterationCount:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1};var s=/^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|abbr|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|enterKeyHint|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|translate|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|incremental|fallback|inert|itemProp|itemScope|itemType|itemID|itemRef|on|option|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/;const c=function(e){var t=Object.create(null);return function(e){return void 0===t[e]&&(t[e]=(n=e,s.test(n)||111===n.charCodeAt(0)&&110===n.charCodeAt(1)&&n.charCodeAt(2)<91)),t[e];var n}}();var f=n(8679),p=n.n(f);function d(){return(d=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}var h=function(e,t){for(var n=[e[0]],r=0,o=t.length;r<o;r+=1)n.push(t[r],e[r+1]);return n},m=function(e){return null!==e&&"object"==typeof e&&"[object Object]"===(e.toString?e.toString():Object.prototype.toString.call(e))&&!(0,r.typeOf)(e)},b=Object.freeze([]),y=Object.freeze({});function g(e){return"function"==typeof e}function v(e){return e.displayName||e.name||"Component"}function w(e){return e&&"string"==typeof e.styledComponentId}var _="undefined"!=typeof process&&(process.env.REACT_APP_SC_ATTR||"sc479495239a9cf0ea")||"data-styled",x="5.3.6",O="undefined"!=typeof window&&"HTMLElement"in window,S=Boolean("boolean"==typeof SC_DISABLE_SPEEDY?SC_DISABLE_SPEEDY:"undefined"!=typeof process&&void 0!==process.env.REACT_APP_SC_DISABLE_SPEEDY&&""!==process.env.REACT_APP_SC_DISABLE_SPEEDY?"false"!==process.env.REACT_APP_SC_DISABLE_SPEEDY&&process.env.REACT_APP_SC_DISABLE_SPEEDY:"undefined"!=typeof process&&void 0!==process.env.SC_DISABLE_SPEEDY&&""!==process.env.SC_DISABLE_SPEEDY&&"false"!==process.env.SC_DISABLE_SPEEDY&&process.env.SC_DISABLE_SPEEDY),k={};function j(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];throw new Error("An error occurred. See https://git.io/JUIaE#"+e+" for more information."+(n.length>0?" Args: "+n.join(", "):""))}var C=function(){function e(e){this.groupSizes=new Uint32Array(512),this.length=512,this.tag=e}var t=e.prototype;return t.indexOfGroup=function(e){for(var t=0,n=0;n<e;n++)t+=this.groupSizes[n];return t},t.insertRules=function(e,t){if(e>=this.groupSizes.length){for(var n=this.groupSizes,r=n.length,o=r;e>=o;)(o<<=1)<0&&j(16,""+e);this.groupSizes=new Uint32Array(o),this.groupSizes.set(n),this.length=o;for(var i=r;i<o;i++)this.groupSizes[i]=0}for(var a=this.indexOfGroup(e+1),l=0,u=t.length;l<u;l++)this.tag.insertRule(a,t[l])&&(this.groupSizes[e]++,a++)},t.clearGroup=function(e){if(e<this.length){var t=this.groupSizes[e],n=this.indexOfGroup(e),r=n+t;this.groupSizes[e]=0;for(var o=n;o<r;o++)this.tag.deleteRule(n)}},t.getGroup=function(e){var t="";if(e>=this.length||0===this.groupSizes[e])return t;for(var n=this.groupSizes[e],r=this.indexOfGroup(e),o=r+n,i=r;i<o;i++)t+=this.tag.getRule(i)+"/*!sc*/\n";return t},e}(),E=new Map,P=new Map,A=1,T=function(e){if(E.has(e))return E.get(e);for(;P.has(A);)A++;var t=A++;return E.set(e,t),P.set(t,e),t},L=function(e){return P.get(e)},R=function(e,t){t>=A&&(A=t+1),E.set(e,t),P.set(t,e)},M="style["+_+'][data-styled-version="5.3.6"]',D=new RegExp("^"+_+'\\.g(\\d+)\\[id="([\\w\\d-]+)"\\].*?"([^"]*)'),I=function(e,t,n){for(var r,o=n.split(","),i=0,a=o.length;i<a;i++)(r=o[i])&&e.registerName(t,r)},F=function(e,t){for(var n=(t.textContent||"").split("/*!sc*/\n"),r=[],o=0,i=n.length;o<i;o++){var a=n[o].trim();if(a){var l=a.match(D);if(l){var u=0|parseInt(l[1],10),s=l[2];0!==u&&(R(s,u),I(e,s,l[3]),e.getTag().insertRules(u,r)),r.length=0}else r.push(a)}}},N=function(){return n.nc},z=function(e){var t=document.head,n=e||t,r=document.createElement("style"),o=function(e){for(var t=e.childNodes,n=t.length;n>=0;n--){var r=t[n];if(r&&1===r.nodeType&&r.hasAttribute(_))return r}}(n),i=void 0!==o?o.nextSibling:null;r.setAttribute(_,"active"),r.setAttribute("data-styled-version","5.3.6");var a=N();return a&&r.setAttribute("nonce",a),n.insertBefore(r,i),r},q=function(){function e(e){var t=this.element=z(e);t.appendChild(document.createTextNode("")),this.sheet=function(e){if(e.sheet)return e.sheet;for(var t=document.styleSheets,n=0,r=t.length;n<r;n++){var o=t[n];if(o.ownerNode===e)return o}j(17)}(t),this.length=0}var t=e.prototype;return t.insertRule=function(e,t){try{return this.sheet.insertRule(t,e),this.length++,!0}catch(e){return!1}},t.deleteRule=function(e){this.sheet.deleteRule(e),this.length--},t.getRule=function(e){var t=this.sheet.cssRules[e];return void 0!==t&&"string"==typeof t.cssText?t.cssText:""},e}(),$=function(){function e(e){var t=this.element=z(e);this.nodes=t.childNodes,this.length=0}var t=e.prototype;return t.insertRule=function(e,t){if(e<=this.length&&e>=0){var n=document.createTextNode(t),r=this.nodes[e];return this.element.insertBefore(n,r||null),this.length++,!0}return!1},t.deleteRule=function(e){this.element.removeChild(this.nodes[e]),this.length--},t.getRule=function(e){return e<this.length?this.nodes[e].textContent:""},e}(),B=function(){function e(e){this.rules=[],this.length=0}var t=e.prototype;return t.insertRule=function(e,t){return e<=this.length&&(this.rules.splice(e,0,t),this.length++,!0)},t.deleteRule=function(e){this.rules.splice(e,1),this.length--},t.getRule=function(e){return e<this.length?this.rules[e]:""},e}(),U=O,V={isServer:!O,useCSSOMInjection:!S},W=function(){function e(e,t,n){void 0===e&&(e=y),void 0===t&&(t={}),this.options=d({},V,{},e),this.gs=t,this.names=new Map(n),this.server=!!e.isServer,!this.server&&O&&U&&(U=!1,function(e){for(var t=document.querySelectorAll(M),n=0,r=t.length;n<r;n++){var o=t[n];o&&"active"!==o.getAttribute(_)&&(F(e,o),o.parentNode&&o.parentNode.removeChild(o))}}(this))}e.registerId=function(e){return T(e)};var t=e.prototype;return t.reconstructWithOptions=function(t,n){return void 0===n&&(n=!0),new e(d({},this.options,{},t),this.gs,n&&this.names||void 0)},t.allocateGSInstance=function(e){return this.gs[e]=(this.gs[e]||0)+1},t.getTag=function(){return this.tag||(this.tag=(n=(t=this.options).isServer,r=t.useCSSOMInjection,o=t.target,e=n?new B(o):r?new q(o):new $(o),new C(e)));var e,t,n,r,o},t.hasNameForId=function(e,t){return this.names.has(e)&&this.names.get(e).has(t)},t.registerName=function(e,t){if(T(e),this.names.has(e))this.names.get(e).add(t);else{var n=new Set;n.add(t),this.names.set(e,n)}},t.insertRules=function(e,t,n){this.registerName(e,t),this.getTag().insertRules(T(e),n)},t.clearNames=function(e){this.names.has(e)&&this.names.get(e).clear()},t.clearRules=function(e){this.getTag().clearGroup(T(e)),this.clearNames(e)},t.clearTag=function(){this.tag=void 0},t.toString=function(){return function(e){for(var t=e.getTag(),n=t.length,r="",o=0;o<n;o++){var i=L(o);if(void 0!==i){var a=e.names.get(i),l=t.getGroup(o);if(a&&l&&a.size){var u=_+".g"+o+'[id="'+i+'"]',s="";void 0!==a&&a.forEach((function(e){e.length>0&&(s+=e+",")})),r+=""+l+u+'{content:"'+s+'"}/*!sc*/\n'}}}return r}(this)},e}(),H=/(a)(d)/gi,Z=function(e){return String.fromCharCode(e+(e>25?39:97))};function K(e){var t,n="";for(t=Math.abs(e);t>52;t=t/52|0)n=Z(t%52)+n;return(Z(t%52)+n).replace(H,"$1-$2")}var Q=function(e,t){for(var n=t.length;n;)e=33*e^t.charCodeAt(--n);return e},G=function(e){return Q(5381,e)};function X(e){for(var t=0;t<e.length;t+=1){var n=e[t];if(g(n)&&!w(n))return!1}return!0}var Y=G("5.3.6"),J=function(){function e(e,t,n){this.rules=e,this.staticRulesId="",this.isStatic=(void 0===n||n.isStatic)&&X(e),this.componentId=t,this.baseHash=Q(Y,t),this.baseStyle=n,W.registerId(t)}return e.prototype.generateAndInjectStyles=function(e,t,n){var r=this.componentId,o=[];if(this.baseStyle&&o.push(this.baseStyle.generateAndInjectStyles(e,t,n)),this.isStatic&&!n.hash)if(this.staticRulesId&&t.hasNameForId(r,this.staticRulesId))o.push(this.staticRulesId);else{var i=ge(this.rules,e,t,n).join(""),a=K(Q(this.baseHash,i)>>>0);if(!t.hasNameForId(r,a)){var l=n(i,"."+a,void 0,r);t.insertRules(r,a,l)}o.push(a),this.staticRulesId=a}else{for(var u=this.rules.length,s=Q(this.baseHash,n.hash),c="",f=0;f<u;f++){var p=this.rules[f];if("string"==typeof p)c+=p;else if(p){var d=ge(p,e,t,n),h=Array.isArray(d)?d.join(""):d;s=Q(s,h+f),c+=h}}if(c){var m=K(s>>>0);if(!t.hasNameForId(r,m)){var b=n(c,"."+m,void 0,r);t.insertRules(r,m,b)}o.push(m)}}return o.join(" ")},e}(),ee=/^\s*\/\/.*$/gm,te=[":","[",".","#"];function ne(e){var t,n,r,o,i=void 0===e?y:e,a=i.options,u=void 0===a?y:a,s=i.plugins,c=void 0===s?b:s,f=new l(u),p=[],d=function(e){function t(t){if(t)try{e(t+"}")}catch(e){}}return function(n,r,o,i,a,l,u,s,c,f){switch(n){case 1:if(0===c&&64===r.charCodeAt(0))return e(r+";"),"";break;case 2:if(0===s)return r+"/*|*/";break;case 3:switch(s){case 102:case 112:return e(o[0]+r),"";default:return r+(0===f?"/*|*/":"")}case-2:r.split("/*|*/}").forEach(t)}}}((function(e){p.push(e)})),h=function(e,r,i){return 0===r&&-1!==te.indexOf(i[n.length])||i.match(o)?e:"."+t};function m(e,i,a,l){void 0===l&&(l="&");var u=e.replace(ee,""),s=i&&a?a+" "+i+" { "+u+" }":u;return t=l,n=i,r=new RegExp("\\"+n+"\\b","g"),o=new RegExp("(\\"+n+"\\b){2,}"),f(a||!i?"":i,s)}return f.use([].concat(c,[function(e,t,o){2===e&&o.length&&o[0].lastIndexOf(n)>0&&(o[0]=o[0].replace(r,h))},d,function(e){if(-2===e){var t=p;return p=[],t}}])),m.hash=c.length?c.reduce((function(e,t){return t.name||j(15),Q(e,t.name)}),5381).toString():"",m}var re=o.createContext(),oe=re.Consumer,ie=o.createContext(),ae=(ie.Consumer,new W),le=ne();function ue(){return(0,o.useContext)(re)||ae}function se(){return(0,o.useContext)(ie)||le}function ce(e){var t=(0,o.useState)(e.stylisPlugins),n=t[0],r=t[1],i=ue(),l=(0,o.useMemo)((function(){var t=i;return e.sheet?t=e.sheet:e.target&&(t=t.reconstructWithOptions({target:e.target},!1)),e.disableCSSOMInjection&&(t=t.reconstructWithOptions({useCSSOMInjection:!1})),t}),[e.disableCSSOMInjection,e.sheet,e.target]),u=(0,o.useMemo)((function(){return ne({options:{prefix:!e.disableVendorPrefixes},plugins:n})}),[e.disableVendorPrefixes,n]);return(0,o.useEffect)((function(){a()(n,e.stylisPlugins)||r(e.stylisPlugins)}),[e.stylisPlugins]),o.createElement(re.Provider,{value:l},o.createElement(ie.Provider,{value:u},e.children))}var fe=function(){function e(e,t){var n=this;this.inject=function(e,t){void 0===t&&(t=le);var r=n.name+t.hash;e.hasNameForId(n.id,r)||e.insertRules(n.id,r,t(n.rules,r,"@keyframes"))},this.toString=function(){return j(12,String(n.name))},this.name=e,this.id="sc-keyframes-"+e,this.rules=t}return e.prototype.getName=function(e){return void 0===e&&(e=le),this.name+e.hash},e}(),pe=/([A-Z])/,de=/([A-Z])/g,he=/^ms-/,me=function(e){return"-"+e.toLowerCase()};function be(e){return pe.test(e)?e.replace(de,me).replace(he,"-ms-"):e}var ye=function(e){return null==e||!1===e||""===e};function ge(e,t,n,r){if(Array.isArray(e)){for(var o,i=[],a=0,l=e.length;a<l;a+=1)""!==(o=ge(e[a],t,n,r))&&(Array.isArray(o)?i.push.apply(i,o):i.push(o));return i}return ye(e)?"":w(e)?"."+e.styledComponentId:g(e)?"function"!=typeof(s=e)||s.prototype&&s.prototype.isReactComponent||!t?e:ge(e(t),t,n,r):e instanceof fe?n?(e.inject(n,r),e.getName(r)):e:m(e)?function e(t,n){var r,o,i=[];for(var a in t)t.hasOwnProperty(a)&&!ye(t[a])&&(Array.isArray(t[a])&&t[a].isCss||g(t[a])?i.push(be(a)+":",t[a],";"):m(t[a])?i.push.apply(i,e(t[a],a)):i.push(be(a)+": "+(r=a,(null==(o=t[a])||"boolean"==typeof o||""===o?"":"number"!=typeof o||0===o||r in u?String(o).trim():o+"px")+";")));return n?[n+" {"].concat(i,["}"]):i}(e):e.toString();var s}var ve=function(e){return Array.isArray(e)&&(e.isCss=!0),e};function we(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];return g(e)||m(e)?ve(ge(h(b,[e].concat(n)))):0===n.length&&1===e.length&&"string"==typeof e[0]?e:ve(ge(h(e,n)))}new Set;var _e=function(e,t,n){return void 0===n&&(n=y),e.theme!==n.theme&&e.theme||t||n.theme},xe=/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~-]+/g,Oe=/(^-|-$)/g;function Se(e){return e.replace(xe,"-").replace(Oe,"")}var ke=function(e){return K(G(e)>>>0)};function je(e){return"string"==typeof e&&!0}var Ce=function(e){return"function"==typeof e||"object"==typeof e&&null!==e&&!Array.isArray(e)},Ee=function(e){return"__proto__"!==e&&"constructor"!==e&&"prototype"!==e};function Pe(e,t,n){var r=e[n];Ce(t)&&Ce(r)?Ae(r,t):e[n]=t}function Ae(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];for(var o=0,i=n;o<i.length;o++){var a=i[o];if(Ce(a))for(var l in a)Ee(l)&&Pe(e,a[l],l)}return e}var Te=o.createContext(),Le=Te.Consumer;function Re(e){var t=(0,o.useContext)(Te),n=(0,o.useMemo)((function(){return function(e,t){return e?g(e)?e(t):Array.isArray(e)||"object"!=typeof e?j(8):t?d({},t,{},e):e:j(14)}(e.theme,t)}),[e.theme,t]);return e.children?o.createElement(Te.Provider,{value:n},e.children):null}var Me={};function De(e,t,n){var r=w(e),i=!je(e),a=t.attrs,l=void 0===a?b:a,u=t.componentId,s=void 0===u?function(e,t){var n="string"!=typeof e?"sc":Se(e);Me[n]=(Me[n]||0)+1;var r=n+"-"+ke("5.3.6"+n+Me[n]);return t?t+"-"+r:r}(t.displayName,t.parentComponentId):u,f=t.displayName,h=void 0===f?function(e){return je(e)?"styled."+e:"Styled("+v(e)+")"}(e):f,m=t.displayName&&t.componentId?Se(t.displayName)+"-"+t.componentId:t.componentId||s,_=r&&e.attrs?Array.prototype.concat(e.attrs,l).filter(Boolean):l,x=t.shouldForwardProp;r&&e.shouldForwardProp&&(x=t.shouldForwardProp?function(n,r,o){return e.shouldForwardProp(n,r,o)&&t.shouldForwardProp(n,r,o)}:e.shouldForwardProp);var O,S=new J(n,m,r?e.componentStyle:void 0),k=S.isStatic&&0===l.length,j=function(e,t){return function(e,t,n,r){var i=e.attrs,a=e.componentStyle,l=e.defaultProps,u=e.foldedComponentIds,s=e.shouldForwardProp,f=e.styledComponentId,p=e.target,h=function(e,t,n){void 0===e&&(e=y);var r=d({},t,{theme:e}),o={};return n.forEach((function(e){var t,n,i,a=e;for(t in g(a)&&(a=a(r)),a)r[t]=o[t]="className"===t?(n=o[t],i=a[t],n&&i?n+" "+i:n||i):a[t]})),[r,o]}(_e(t,(0,o.useContext)(Te),l)||y,t,i),m=h[0],b=h[1],v=function(e,t,n,r){var o=ue(),i=se();return t?e.generateAndInjectStyles(y,o,i):e.generateAndInjectStyles(n,o,i)}(a,r,m),w=n,_=b.$as||t.$as||b.as||t.as||p,x=je(_),O=b!==t?d({},t,{},b):t,S={};for(var k in O)"$"!==k[0]&&"as"!==k&&("forwardedAs"===k?S.as=O[k]:(s?s(k,c,_):!x||c(k))&&(S[k]=O[k]));return t.style&&b.style!==t.style&&(S.style=d({},t.style,{},b.style)),S.className=Array.prototype.concat(u,f,v!==f?v:null,t.className,b.className).filter(Boolean).join(" "),S.ref=w,(0,o.createElement)(_,S)}(O,e,t,k)};return j.displayName=h,(O=o.forwardRef(j)).attrs=_,O.componentStyle=S,O.displayName=h,O.shouldForwardProp=x,O.foldedComponentIds=r?Array.prototype.concat(e.foldedComponentIds,e.styledComponentId):b,O.styledComponentId=m,O.target=r?e.target:e,O.withComponent=function(e){var r=t.componentId,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(t,["componentId"]),i=r&&r+"-"+(je(e)?e:Se(v(e)));return De(e,d({},o,{attrs:_,componentId:i}),n)},Object.defineProperty(O,"defaultProps",{get:function(){return this._foldedDefaultProps},set:function(t){this._foldedDefaultProps=r?Ae({},e.defaultProps,t):t}}),O.toString=function(){return"."+O.styledComponentId},i&&p()(O,e,{attrs:!0,componentStyle:!0,displayName:!0,foldedComponentIds:!0,shouldForwardProp:!0,styledComponentId:!0,target:!0,withComponent:!0}),O}var Ie=function(e){return function e(t,n,o){if(void 0===o&&(o=y),!(0,r.isValidElementType)(n))return j(1,String(n));var i=function(){return t(n,o,we.apply(void 0,arguments))};return i.withConfig=function(r){return e(t,n,d({},o,{},r))},i.attrs=function(r){return e(t,n,d({},o,{attrs:Array.prototype.concat(o.attrs,r).filter(Boolean)}))},i}(De,e)};["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","marquee","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr","circle","clipPath","defs","ellipse","foreignObject","g","image","line","linearGradient","marker","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","svg","text","textPath","tspan"].forEach((function(e){Ie[e]=Ie(e)}));var Fe=function(){function e(e,t){this.rules=e,this.componentId=t,this.isStatic=X(e),W.registerId(this.componentId+1)}var t=e.prototype;return t.createStyles=function(e,t,n,r){var o=r(ge(this.rules,t,n,r).join(""),""),i=this.componentId+e;n.insertRules(i,i,o)},t.removeStyles=function(e,t){t.clearRules(this.componentId+e)},t.renderStyles=function(e,t,n,r){e>2&&W.registerId(this.componentId+e),this.removeStyles(e,n),this.createStyles(e,t,n,r)},e}();function Ne(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];var i=we.apply(void 0,[e].concat(n)),a="sc-global-"+ke(JSON.stringify(i)),l=new Fe(i,a);function u(e){var t=ue(),n=se(),r=(0,o.useContext)(Te),i=(0,o.useRef)(t.allocateGSInstance(a)).current;return t.server&&s(i,e,t,r,n),(0,o.useLayoutEffect)((function(){if(!t.server)return s(i,e,t,r,n),function(){return l.removeStyles(i,t)}}),[i,e,t,r,n]),null}function s(e,t,n,r,o){if(l.isStatic)l.renderStyles(e,k,n,o);else{var i=d({},t,{theme:_e(t,r,u.defaultProps)});l.renderStyles(e,i,n,o)}}return o.memo(u)}function ze(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];var o=we.apply(void 0,[e].concat(n)).join(""),i=ke(o);return new fe(i,o)}var qe=function(){function e(){var e=this;this._emitSheetCSS=function(){var t=e.instance.toString();if(!t)return"";var n=N();return"<style "+[n&&'nonce="'+n+'"',_+'="true"','data-styled-version="5.3.6"'].filter(Boolean).join(" ")+">"+t+"</style>"},this.getStyleTags=function(){return e.sealed?j(2):e._emitSheetCSS()},this.getStyleElement=function(){var t;if(e.sealed)return j(2);var n=((t={})[_]="",t["data-styled-version"]="5.3.6",t.dangerouslySetInnerHTML={__html:e.instance.toString()},t),r=N();return r&&(n.nonce=r),[o.createElement("style",d({},n,{key:"sc-0-0"}))]},this.seal=function(){e.sealed=!0},this.instance=new W({isServer:!0}),this.sealed=!1}var t=e.prototype;return t.collectStyles=function(e){return this.sealed?j(2):o.createElement(ce,{sheet:this.instance},e)},t.interleaveWithNodeStream=function(e){return j(3)},e}(),$e=function(e){var t=o.forwardRef((function(t,n){var r=(0,o.useContext)(Te),i=e.defaultProps,a=_e(t,r,i);return o.createElement(e,d({},t,{theme:a,ref:n}))}));return p()(t,e),t.displayName="WithTheme("+v(e)+")",t},Be=function(){return(0,o.useContext)(Te)},Ue={StyleSheet:W,masterSheet:ae};const Ve=Ie},7621:(e,t,n)=>{var r;!function(o){var i=/^\s+/,a=/\s+$/,l=0,u=o.round,s=o.min,c=o.max,f=o.random;function p(e,t){if(t=t||{},(e=e||"")instanceof p)return e;if(!(this instanceof p))return new p(e,t);var n=function(e){var t,n,r,l={r:0,g:0,b:0},u=1,f=null,p=null,d=null,h=!1,m=!1;return"string"==typeof e&&(e=function(e){e=e.replace(i,"").replace(a,"").toLowerCase();var t,n=!1;if(A[e])e=A[e],n=!0;else if("transparent"==e)return{r:0,g:0,b:0,a:0,format:"name"};return(t=U.rgb.exec(e))?{r:t[1],g:t[2],b:t[3]}:(t=U.rgba.exec(e))?{r:t[1],g:t[2],b:t[3],a:t[4]}:(t=U.hsl.exec(e))?{h:t[1],s:t[2],l:t[3]}:(t=U.hsla.exec(e))?{h:t[1],s:t[2],l:t[3],a:t[4]}:(t=U.hsv.exec(e))?{h:t[1],s:t[2],v:t[3]}:(t=U.hsva.exec(e))?{h:t[1],s:t[2],v:t[3],a:t[4]}:(t=U.hex8.exec(e))?{r:D(t[1]),g:D(t[2]),b:D(t[3]),a:z(t[4]),format:n?"name":"hex8"}:(t=U.hex6.exec(e))?{r:D(t[1]),g:D(t[2]),b:D(t[3]),format:n?"name":"hex"}:(t=U.hex4.exec(e))?{r:D(t[1]+""+t[1]),g:D(t[2]+""+t[2]),b:D(t[3]+""+t[3]),a:z(t[4]+""+t[4]),format:n?"name":"hex8"}:!!(t=U.hex3.exec(e))&&{r:D(t[1]+""+t[1]),g:D(t[2]+""+t[2]),b:D(t[3]+""+t[3]),format:n?"name":"hex"}}(e)),"object"==typeof e&&(V(e.r)&&V(e.g)&&V(e.b)?(t=e.r,n=e.g,r=e.b,l={r:255*R(t,255),g:255*R(n,255),b:255*R(r,255)},h=!0,m="%"===String(e.r).substr(-1)?"prgb":"rgb"):V(e.h)&&V(e.s)&&V(e.v)?(f=F(e.s),p=F(e.v),l=function(e,t,n){e=6*R(e,360),t=R(t,100),n=R(n,100);var r=o.floor(e),i=e-r,a=n*(1-t),l=n*(1-i*t),u=n*(1-(1-i)*t),s=r%6;return{r:255*[n,l,a,a,u,n][s],g:255*[u,n,n,l,a,a][s],b:255*[a,a,u,n,n,l][s]}}(e.h,f,p),h=!0,m="hsv"):V(e.h)&&V(e.s)&&V(e.l)&&(f=F(e.s),d=F(e.l),l=function(e,t,n){var r,o,i;function a(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}if(e=R(e,360),t=R(t,100),n=R(n,100),0===t)r=o=i=n;else{var l=n<.5?n*(1+t):n+t-n*t,u=2*n-l;r=a(u,l,e+1/3),o=a(u,l,e),i=a(u,l,e-1/3)}return{r:255*r,g:255*o,b:255*i}}(e.h,f,d),h=!0,m="hsl"),e.hasOwnProperty("a")&&(u=e.a)),u=L(u),{ok:h,format:e.format||m,r:s(255,c(l.r,0)),g:s(255,c(l.g,0)),b:s(255,c(l.b,0)),a:u}}(e);this._originalInput=e,this._r=n.r,this._g=n.g,this._b=n.b,this._a=n.a,this._roundA=u(100*this._a)/100,this._format=t.format||n.format,this._gradientType=t.gradientType,this._r<1&&(this._r=u(this._r)),this._g<1&&(this._g=u(this._g)),this._b<1&&(this._b=u(this._b)),this._ok=n.ok,this._tc_id=l++}function d(e,t,n){e=R(e,255),t=R(t,255),n=R(n,255);var r,o,i=c(e,t,n),a=s(e,t,n),l=(i+a)/2;if(i==a)r=o=0;else{var u=i-a;switch(o=l>.5?u/(2-i-a):u/(i+a),i){case e:r=(t-n)/u+(t<n?6:0);break;case t:r=(n-e)/u+2;break;case n:r=(e-t)/u+4}r/=6}return{h:r,s:o,l}}function h(e,t,n){e=R(e,255),t=R(t,255),n=R(n,255);var r,o,i=c(e,t,n),a=s(e,t,n),l=i,u=i-a;if(o=0===i?0:u/i,i==a)r=0;else{switch(i){case e:r=(t-n)/u+(t<n?6:0);break;case t:r=(n-e)/u+2;break;case n:r=(e-t)/u+4}r/=6}return{h:r,s:o,v:l}}function m(e,t,n,r){var o=[I(u(e).toString(16)),I(u(t).toString(16)),I(u(n).toString(16))];return r&&o[0].charAt(0)==o[0].charAt(1)&&o[1].charAt(0)==o[1].charAt(1)&&o[2].charAt(0)==o[2].charAt(1)?o[0].charAt(0)+o[1].charAt(0)+o[2].charAt(0):o.join("")}function b(e,t,n,r){return[I(N(r)),I(u(e).toString(16)),I(u(t).toString(16)),I(u(n).toString(16))].join("")}function y(e,t){t=0===t?0:t||10;var n=p(e).toHsl();return n.s-=t/100,n.s=M(n.s),p(n)}function g(e,t){t=0===t?0:t||10;var n=p(e).toHsl();return n.s+=t/100,n.s=M(n.s),p(n)}function v(e){return p(e).desaturate(100)}function w(e,t){t=0===t?0:t||10;var n=p(e).toHsl();return n.l+=t/100,n.l=M(n.l),p(n)}function _(e,t){t=0===t?0:t||10;var n=p(e).toRgb();return n.r=c(0,s(255,n.r-u(-t/100*255))),n.g=c(0,s(255,n.g-u(-t/100*255))),n.b=c(0,s(255,n.b-u(-t/100*255))),p(n)}function x(e,t){t=0===t?0:t||10;var n=p(e).toHsl();return n.l-=t/100,n.l=M(n.l),p(n)}function O(e,t){var n=p(e).toHsl(),r=(n.h+t)%360;return n.h=r<0?360+r:r,p(n)}function S(e){var t=p(e).toHsl();return t.h=(t.h+180)%360,p(t)}function k(e){var t=p(e).toHsl(),n=t.h;return[p(e),p({h:(n+120)%360,s:t.s,l:t.l}),p({h:(n+240)%360,s:t.s,l:t.l})]}function j(e){var t=p(e).toHsl(),n=t.h;return[p(e),p({h:(n+90)%360,s:t.s,l:t.l}),p({h:(n+180)%360,s:t.s,l:t.l}),p({h:(n+270)%360,s:t.s,l:t.l})]}function C(e){var t=p(e).toHsl(),n=t.h;return[p(e),p({h:(n+72)%360,s:t.s,l:t.l}),p({h:(n+216)%360,s:t.s,l:t.l})]}function E(e,t,n){t=t||6,n=n||30;var r=p(e).toHsl(),o=360/n,i=[p(e)];for(r.h=(r.h-(o*t>>1)+720)%360;--t;)r.h=(r.h+o)%360,i.push(p(r));return i}function P(e,t){t=t||6;for(var n=p(e).toHsv(),r=n.h,o=n.s,i=n.v,a=[],l=1/t;t--;)a.push(p({h:r,s:o,v:i})),i=(i+l)%1;return a}p.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var e=this.toRgb();return(299*e.r+587*e.g+114*e.b)/1e3},getLuminance:function(){var e,t,n,r=this.toRgb();return e=r.r/255,t=r.g/255,n=r.b/255,.2126*(e<=.03928?e/12.92:o.pow((e+.055)/1.055,2.4))+.7152*(t<=.03928?t/12.92:o.pow((t+.055)/1.055,2.4))+.0722*(n<=.03928?n/12.92:o.pow((n+.055)/1.055,2.4))},setAlpha:function(e){return this._a=L(e),this._roundA=u(100*this._a)/100,this},toHsv:function(){var e=h(this._r,this._g,this._b);return{h:360*e.h,s:e.s,v:e.v,a:this._a}},toHsvString:function(){var e=h(this._r,this._g,this._b),t=u(360*e.h),n=u(100*e.s),r=u(100*e.v);return 1==this._a?"hsv("+t+", "+n+"%, "+r+"%)":"hsva("+t+", "+n+"%, "+r+"%, "+this._roundA+")"},toHsl:function(){var e=d(this._r,this._g,this._b);return{h:360*e.h,s:e.s,l:e.l,a:this._a}},toHslString:function(){var e=d(this._r,this._g,this._b),t=u(360*e.h),n=u(100*e.s),r=u(100*e.l);return 1==this._a?"hsl("+t+", "+n+"%, "+r+"%)":"hsla("+t+", "+n+"%, "+r+"%, "+this._roundA+")"},toHex:function(e){return m(this._r,this._g,this._b,e)},toHexString:function(e){return"#"+this.toHex(e)},toHex8:function(e){return function(e,t,n,r,o){var i=[I(u(e).toString(16)),I(u(t).toString(16)),I(u(n).toString(16)),I(N(r))];return o&&i[0].charAt(0)==i[0].charAt(1)&&i[1].charAt(0)==i[1].charAt(1)&&i[2].charAt(0)==i[2].charAt(1)&&i[3].charAt(0)==i[3].charAt(1)?i[0].charAt(0)+i[1].charAt(0)+i[2].charAt(0)+i[3].charAt(0):i.join("")}(this._r,this._g,this._b,this._a,e)},toHex8String:function(e){return"#"+this.toHex8(e)},toRgb:function(){return{r:u(this._r),g:u(this._g),b:u(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+u(this._r)+", "+u(this._g)+", "+u(this._b)+")":"rgba("+u(this._r)+", "+u(this._g)+", "+u(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:u(100*R(this._r,255))+"%",g:u(100*R(this._g,255))+"%",b:u(100*R(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+u(100*R(this._r,255))+"%, "+u(100*R(this._g,255))+"%, "+u(100*R(this._b,255))+"%)":"rgba("+u(100*R(this._r,255))+"%, "+u(100*R(this._g,255))+"%, "+u(100*R(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&(T[m(this._r,this._g,this._b,!0)]||!1)},toFilter:function(e){var t="#"+b(this._r,this._g,this._b,this._a),n=t,r=this._gradientType?"GradientType = 1, ":"";if(e){var o=p(e);n="#"+b(o._r,o._g,o._b,o._a)}return"progid:DXImageTransform.Microsoft.gradient("+r+"startColorstr="+t+",endColorstr="+n+")"},toString:function(e){var t=!!e;e=e||this._format;var n=!1,r=this._a<1&&this._a>=0;return t||!r||"hex"!==e&&"hex6"!==e&&"hex3"!==e&&"hex4"!==e&&"hex8"!==e&&"name"!==e?("rgb"===e&&(n=this.toRgbString()),"prgb"===e&&(n=this.toPercentageRgbString()),"hex"!==e&&"hex6"!==e||(n=this.toHexString()),"hex3"===e&&(n=this.toHexString(!0)),"hex4"===e&&(n=this.toHex8String(!0)),"hex8"===e&&(n=this.toHex8String()),"name"===e&&(n=this.toName()),"hsl"===e&&(n=this.toHslString()),"hsv"===e&&(n=this.toHsvString()),n||this.toHexString()):"name"===e&&0===this._a?this.toName():this.toRgbString()},clone:function(){return p(this.toString())},_applyModification:function(e,t){var n=e.apply(null,[this].concat([].slice.call(t)));return this._r=n._r,this._g=n._g,this._b=n._b,this.setAlpha(n._a),this},lighten:function(){return this._applyModification(w,arguments)},brighten:function(){return this._applyModification(_,arguments)},darken:function(){return this._applyModification(x,arguments)},desaturate:function(){return this._applyModification(y,arguments)},saturate:function(){return this._applyModification(g,arguments)},greyscale:function(){return this._applyModification(v,arguments)},spin:function(){return this._applyModification(O,arguments)},_applyCombination:function(e,t){return e.apply(null,[this].concat([].slice.call(t)))},analogous:function(){return this._applyCombination(E,arguments)},complement:function(){return this._applyCombination(S,arguments)},monochromatic:function(){return this._applyCombination(P,arguments)},splitcomplement:function(){return this._applyCombination(C,arguments)},triad:function(){return this._applyCombination(k,arguments)},tetrad:function(){return this._applyCombination(j,arguments)}},p.fromRatio=function(e,t){if("object"==typeof e){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]="a"===r?e[r]:F(e[r]));e=n}return p(e,t)},p.equals=function(e,t){return!(!e||!t)&&p(e).toRgbString()==p(t).toRgbString()},p.random=function(){return p.fromRatio({r:f(),g:f(),b:f()})},p.mix=function(e,t,n){n=0===n?0:n||50;var r=p(e).toRgb(),o=p(t).toRgb(),i=n/100;return p({r:(o.r-r.r)*i+r.r,g:(o.g-r.g)*i+r.g,b:(o.b-r.b)*i+r.b,a:(o.a-r.a)*i+r.a})},p.readability=function(e,t){var n=p(e),r=p(t);return(o.max(n.getLuminance(),r.getLuminance())+.05)/(o.min(n.getLuminance(),r.getLuminance())+.05)},p.isReadable=function(e,t,n){var r,o,i,a,l,u=p.readability(e,t);switch(o=!1,(i=n,"AA"!==(a=((i=i||{level:"AA",size:"small"}).level||"AA").toUpperCase())&&"AAA"!==a&&(a="AA"),"small"!==(l=(i.size||"small").toLowerCase())&&"large"!==l&&(l="small"),r={level:a,size:l}).level+r.size){case"AAsmall":case"AAAlarge":o=u>=4.5;break;case"AAlarge":o=u>=3;break;case"AAAsmall":o=u>=7}return o},p.mostReadable=function(e,t,n){var r,o,i,a,l=null,u=0;o=(n=n||{}).includeFallbackColors,i=n.level,a=n.size;for(var s=0;s<t.length;s++)(r=p.readability(e,t[s]))>u&&(u=r,l=p(t[s]));return p.isReadable(e,l,{level:i,size:a})||!o?l:(n.includeFallbackColors=!1,p.mostReadable(e,["#fff","#000"],n))};var A=p.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},T=p.hexNames=function(e){var t={};for(var n in e)e.hasOwnProperty(n)&&(t[e[n]]=n);return t}(A);function L(e){return e=parseFloat(e),(isNaN(e)||e<0||e>1)&&(e=1),e}function R(e,t){(function(e){return"string"==typeof e&&-1!=e.indexOf(".")&&1===parseFloat(e)})(e)&&(e="100%");var n=function(e){return"string"==typeof e&&-1!=e.indexOf("%")}(e);return e=s(t,c(0,parseFloat(e))),n&&(e=parseInt(e*t,10)/100),o.abs(e-t)<1e-6?1:e%t/parseFloat(t)}function M(e){return s(1,c(0,e))}function D(e){return parseInt(e,16)}function I(e){return 1==e.length?"0"+e:""+e}function F(e){return e<=1&&(e=100*e+"%"),e}function N(e){return o.round(255*parseFloat(e)).toString(16)}function z(e){return D(e)/255}var q,$,B,U=($="[\\s|\\(]+("+(q="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)")+")[,|\\s]+("+q+")[,|\\s]+("+q+")\\s*\\)?",B="[\\s|\\(]+("+q+")[,|\\s]+("+q+")[,|\\s]+("+q+")[,|\\s]+("+q+")\\s*\\)?",{CSS_UNIT:new RegExp(q),rgb:new RegExp("rgb"+$),rgba:new RegExp("rgba"+B),hsl:new RegExp("hsl"+$),hsla:new RegExp("hsla"+B),hsv:new RegExp("hsv"+$),hsva:new RegExp("hsva"+B),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/});function V(e){return!!U.CSS_UNIT.exec(e)}e.exports?e.exports=p:void 0===(r=function(){return p}.call(t,n,t,e))||(e.exports=r)}(Math)},8575:(e,t,n)=>{"use strict";var r=n(4971),o=n(2502);function i(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}t.parse=v,t.resolve=function(e,t){return v(e,!1,!0).resolve(t)},t.resolveObject=function(e,t){return e?v(e,!1,!0).resolveObject(t):t},t.format=function(e){return o.isString(e)&&(e=v(e)),e instanceof i?e.format():i.prototype.format.call(e)},t.Url=i;var a=/^([a-z0-9.+-]+:)/i,l=/:[0-9]*$/,u=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,s=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),c=["'"].concat(s),f=["%","/","?",";","#"].concat(c),p=["/","?","#"],d=/^[+a-z0-9A-Z_-]{0,63}$/,h=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,m={javascript:!0,"javascript:":!0},b={javascript:!0,"javascript:":!0},y={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},g=n(7673);function v(e,t,n){if(e&&o.isObject(e)&&e instanceof i)return e;var r=new i;return r.parse(e,t,n),r}i.prototype.parse=function(e,t,n){if(!o.isString(e))throw new TypeError("Parameter 'url' must be a string, not "+typeof e);var i=e.indexOf("?"),l=-1!==i&&i<e.indexOf("#")?"?":"#",s=e.split(l);s[0]=s[0].replace(/\\/g,"/");var v=e=s.join(l);if(v=v.trim(),!n&&1===e.split("#").length){var w=u.exec(v);if(w)return this.path=v,this.href=v,this.pathname=w[1],w[2]?(this.search=w[2],this.query=t?g.parse(this.search.substr(1)):this.search.substr(1)):t&&(this.search="",this.query={}),this}var _=a.exec(v);if(_){var x=(_=_[0]).toLowerCase();this.protocol=x,v=v.substr(_.length)}if(n||_||v.match(/^\/\/[^@\/]+@[^@\/]+/)){var O="//"===v.substr(0,2);!O||_&&b[_]||(v=v.substr(2),this.slashes=!0)}if(!b[_]&&(O||_&&!y[_])){for(var S,k,j=-1,C=0;C<p.length;C++)-1!==(E=v.indexOf(p[C]))&&(-1===j||E<j)&&(j=E);for(-1!==(k=-1===j?v.lastIndexOf("@"):v.lastIndexOf("@",j))&&(S=v.slice(0,k),v=v.slice(k+1),this.auth=decodeURIComponent(S)),j=-1,C=0;C<f.length;C++){var E;-1!==(E=v.indexOf(f[C]))&&(-1===j||E<j)&&(j=E)}-1===j&&(j=v.length),this.host=v.slice(0,j),v=v.slice(j),this.parseHost(),this.hostname=this.hostname||"";var P="["===this.hostname[0]&&"]"===this.hostname[this.hostname.length-1];if(!P)for(var A=this.hostname.split(/\./),T=(C=0,A.length);C<T;C++){var L=A[C];if(L&&!L.match(d)){for(var R="",M=0,D=L.length;M<D;M++)L.charCodeAt(M)>127?R+="x":R+=L[M];if(!R.match(d)){var I=A.slice(0,C),F=A.slice(C+1),N=L.match(h);N&&(I.push(N[1]),F.unshift(N[2])),F.length&&(v="/"+F.join(".")+v),this.hostname=I.join(".");break}}}this.hostname.length>255?this.hostname="":this.hostname=this.hostname.toLowerCase(),P||(this.hostname=r.toASCII(this.hostname));var z=this.port?":"+this.port:"",q=this.hostname||"";this.host=q+z,this.href+=this.host,P&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==v[0]&&(v="/"+v))}if(!m[x])for(C=0,T=c.length;C<T;C++){var $=c[C];if(-1!==v.indexOf($)){var B=encodeURIComponent($);B===$&&(B=escape($)),v=v.split($).join(B)}}var U=v.indexOf("#");-1!==U&&(this.hash=v.substr(U),v=v.slice(0,U));var V=v.indexOf("?");if(-1!==V?(this.search=v.substr(V),this.query=v.substr(V+1),t&&(this.query=g.parse(this.query)),v=v.slice(0,V)):t&&(this.search="",this.query={}),v&&(this.pathname=v),y[x]&&this.hostname&&!this.pathname&&(this.pathname="/"),this.pathname||this.search){z=this.pathname||"";var W=this.search||"";this.path=z+W}return this.href=this.format(),this},i.prototype.format=function(){var e=this.auth||"";e&&(e=(e=encodeURIComponent(e)).replace(/%3A/i,":"),e+="@");var t=this.protocol||"",n=this.pathname||"",r=this.hash||"",i=!1,a="";this.host?i=e+this.host:this.hostname&&(i=e+(-1===this.hostname.indexOf(":")?this.hostname:"["+this.hostname+"]"),this.port&&(i+=":"+this.port)),this.query&&o.isObject(this.query)&&Object.keys(this.query).length&&(a=g.stringify(this.query));var l=this.search||a&&"?"+a||"";return t&&":"!==t.substr(-1)&&(t+=":"),this.slashes||(!t||y[t])&&!1!==i?(i="//"+(i||""),n&&"/"!==n.charAt(0)&&(n="/"+n)):i||(i=""),r&&"#"!==r.charAt(0)&&(r="#"+r),l&&"?"!==l.charAt(0)&&(l="?"+l),t+i+(n=n.replace(/[?#]/g,(function(e){return encodeURIComponent(e)})))+(l=l.replace("#","%23"))+r},i.prototype.resolve=function(e){return this.resolveObject(v(e,!1,!0)).format()},i.prototype.resolveObject=function(e){if(o.isString(e)){var t=new i;t.parse(e,!1,!0),e=t}for(var n=new i,r=Object.keys(this),a=0;a<r.length;a++){var l=r[a];n[l]=this[l]}if(n.hash=e.hash,""===e.href)return n.href=n.format(),n;if(e.slashes&&!e.protocol){for(var u=Object.keys(e),s=0;s<u.length;s++){var c=u[s];"protocol"!==c&&(n[c]=e[c])}return y[n.protocol]&&n.hostname&&!n.pathname&&(n.path=n.pathname="/"),n.href=n.format(),n}if(e.protocol&&e.protocol!==n.protocol){if(!y[e.protocol]){for(var f=Object.keys(e),p=0;p<f.length;p++){var d=f[p];n[d]=e[d]}return n.href=n.format(),n}if(n.protocol=e.protocol,e.host||b[e.protocol])n.pathname=e.pathname;else{for(var h=(e.pathname||"").split("/");h.length&&!(e.host=h.shift()););e.host||(e.host=""),e.hostname||(e.hostname=""),""!==h[0]&&h.unshift(""),h.length<2&&h.unshift(""),n.pathname=h.join("/")}if(n.search=e.search,n.query=e.query,n.host=e.host||"",n.auth=e.auth,n.hostname=e.hostname||e.host,n.port=e.port,n.pathname||n.search){var m=n.pathname||"",g=n.search||"";n.path=m+g}return n.slashes=n.slashes||e.slashes,n.href=n.format(),n}var v=n.pathname&&"/"===n.pathname.charAt(0),w=e.host||e.pathname&&"/"===e.pathname.charAt(0),_=w||v||n.host&&e.pathname,x=_,O=n.pathname&&n.pathname.split("/")||[],S=(h=e.pathname&&e.pathname.split("/")||[],n.protocol&&!y[n.protocol]);if(S&&(n.hostname="",n.port=null,n.host&&(""===O[0]?O[0]=n.host:O.unshift(n.host)),n.host="",e.protocol&&(e.hostname=null,e.port=null,e.host&&(""===h[0]?h[0]=e.host:h.unshift(e.host)),e.host=null),_=_&&(""===h[0]||""===O[0])),w)n.host=e.host||""===e.host?e.host:n.host,n.hostname=e.hostname||""===e.hostname?e.hostname:n.hostname,n.search=e.search,n.query=e.query,O=h;else if(h.length)O||(O=[]),O.pop(),O=O.concat(h),n.search=e.search,n.query=e.query;else if(!o.isNullOrUndefined(e.search))return S&&(n.hostname=n.host=O.shift(),(P=!!(n.host&&n.host.indexOf("@")>0)&&n.host.split("@"))&&(n.auth=P.shift(),n.host=n.hostname=P.shift())),n.search=e.search,n.query=e.query,o.isNull(n.pathname)&&o.isNull(n.search)||(n.path=(n.pathname?n.pathname:"")+(n.search?n.search:"")),n.href=n.format(),n;if(!O.length)return n.pathname=null,n.search?n.path="/"+n.search:n.path=null,n.href=n.format(),n;for(var k=O.slice(-1)[0],j=(n.host||e.host||O.length>1)&&("."===k||".."===k)||""===k,C=0,E=O.length;E>=0;E--)"."===(k=O[E])?O.splice(E,1):".."===k?(O.splice(E,1),C++):C&&(O.splice(E,1),C--);if(!_&&!x)for(;C--;C)O.unshift("..");!_||""===O[0]||O[0]&&"/"===O[0].charAt(0)||O.unshift(""),j&&"/"!==O.join("/").substr(-1)&&O.push("");var P,A=""===O[0]||O[0]&&"/"===O[0].charAt(0);return S&&(n.hostname=n.host=A?"":O.length?O.shift():"",(P=!!(n.host&&n.host.indexOf("@")>0)&&n.host.split("@"))&&(n.auth=P.shift(),n.host=n.hostname=P.shift())),(_=_||n.host&&O.length)&&!A&&O.unshift(""),O.length?n.pathname=O.join("/"):(n.pathname=null,n.path=null),o.isNull(n.pathname)&&o.isNull(n.search)||(n.path=(n.pathname?n.pathname:"")+(n.search?n.search:"")),n.auth=e.auth||n.auth,n.slashes=n.slashes||e.slashes,n.href=n.format(),n},i.prototype.parseHost=function(){var e=this.host,t=l.exec(e);t&&(":"!==(t=t[0])&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)}},2502:e=>{"use strict";e.exports={isString:function(e){return"string"==typeof e},isObject:function(e){return"object"==typeof e&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}}},7979:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(7294);function o(e,t){var n,r;if(e===t)return!0;if(e&&t&&(n=e.constructor)===t.constructor){if(n===Date)return e.getTime()===t.getTime();if(n===RegExp)return e.toString()===t.toString();if(n===Array&&(r=e.length)===t.length){for(;r--&&o(e[r],t[r]););return-1===r}if(n===Object){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(r in e)if(!(r in t)||!o(e[r],t[r]))return!1;return!0}}return e!=e&&t!=t}function i(e){const t=r.useRef([]);return o(e,t.current)||(t.current=e),t.current}function a(e,t,n,o){const a=(0,r.useRef)(n);a.current=n;const l=(u=()=>o,s=[o],r.useMemo(u,i(s)));var u,s;(0,r.useEffect)((()=>{if(!e)return;const n=t=>a.current.call(e,t);return e.addEventListener(t,n,l),()=>{e.removeEventListener(t,n,l)}}),[e,t,l])}},907:(e,t,n)=>{"use strict";function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}n.d(t,{Z:()=>r})},7326:(e,t,n)=>{"use strict";function r(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}n.d(t,{Z:()=>r})},5671:(e,t,n)=>{"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}n.d(t,{Z:()=>r})},3144:(e,t,n)=>{"use strict";function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function o(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),Object.defineProperty(e,"prototype",{writable:!1}),e}n.d(t,{Z:()=>o})},1120:(e,t,n)=>{"use strict";function r(e){return r=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},r(e)}n.d(t,{Z:()=>r})},9340:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&r(e,t)}n.d(t,{Z:()=>o})},2963:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(1002),o=n(7326);function i(e,t){if(t&&("object"===(0,r.Z)(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return(0,o.Z)(e)}},885:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(181);function o(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,i=[],a=!0,l=!1;try{for(n=n.call(e);!(a=(r=n.next()).done)&&(i.push(r.value),!t||i.length!==t);a=!0);}catch(e){l=!0,o=e}finally{try{a||null==n.return||n.return()}finally{if(l)throw o}}return i}}(e,t)||(0,r.Z)(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}},168:(e,t,n)=>{"use strict";function r(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}n.d(t,{Z:()=>r})},1002:(e,t,n)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}n.d(t,{Z:()=>r})},181:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(907);function o(e,t){if(e){if("string"==typeof e)return(0,r.Z)(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?(0,r.Z)(e,t):void 0}}},1721:(e,t,n)=>{"use strict";function r(e,t){return function(){return e.apply(t,arguments)}}n.d(t,{ZP:()=>Ze});const{toString:o}=Object.prototype,{getPrototypeOf:i}=Object,a=(l=Object.create(null),e=>{const t=o.call(e);return l[t]||(l[t]=t.slice(8,-1).toLowerCase())});var l;const u=e=>(e=e.toLowerCase(),t=>a(t)===e),s=e=>t=>typeof t===e,{isArray:c}=Array,f=s("undefined"),p=u("ArrayBuffer"),d=s("string"),h=s("function"),m=s("number"),b=e=>null!==e&&"object"==typeof e,y=e=>{if("object"!==a(e))return!1;const t=i(e);return!(null!==t&&t!==Object.prototype&&null!==Object.getPrototypeOf(t)||Symbol.toStringTag in e||Symbol.iterator in e)},g=u("Date"),v=u("File"),w=u("Blob"),_=u("FileList"),x=u("URLSearchParams");function O(e,t,{allOwnKeys:n=!1}={}){if(null==e)return;let r,o;if("object"!=typeof e&&(e=[e]),c(e))for(r=0,o=e.length;r<o;r++)t.call(null,e[r],r,e);else{const o=n?Object.getOwnPropertyNames(e):Object.keys(e),i=o.length;let a;for(r=0;r<i;r++)a=o[r],t.call(null,e[a],a,e)}}const S=(k="undefined"!=typeof Uint8Array&&i(Uint8Array),e=>k&&e instanceof k);var k;const j=u("HTMLFormElement"),C=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),E=u("RegExp"),P=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),r={};O(n,((n,o)=>{!1!==t(n,o,e)&&(r[o]=n)})),Object.defineProperties(e,r)},A={isArray:c,isArrayBuffer:p,isBuffer:function(e){return null!==e&&!f(e)&&null!==e.constructor&&!f(e.constructor)&&h(e.constructor.isBuffer)&&e.constructor.isBuffer(e)},isFormData:e=>{const t="[object FormData]";return e&&("function"==typeof FormData&&e instanceof FormData||o.call(e)===t||h(e.toString)&&e.toString()===t)},isArrayBufferView:function(e){let t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&p(e.buffer),t},isString:d,isNumber:m,isBoolean:e=>!0===e||!1===e,isObject:b,isPlainObject:y,isUndefined:f,isDate:g,isFile:v,isBlob:w,isRegExp:E,isFunction:h,isStream:e=>b(e)&&h(e.pipe),isURLSearchParams:x,isTypedArray:S,isFileList:_,forEach:O,merge:function e(){const t={},n=(n,r)=>{y(t[r])&&y(n)?t[r]=e(t[r],n):y(n)?t[r]=e({},n):c(n)?t[r]=n.slice():t[r]=n};for(let e=0,t=arguments.length;e<t;e++)arguments[e]&&O(arguments[e],n);return t},extend:(e,t,n,{allOwnKeys:o}={})=>(O(t,((t,o)=>{n&&h(t)?e[o]=r(t,n):e[o]=t}),{allOwnKeys:o}),e),trim:e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),stripBOM:e=>(65279===e.charCodeAt(0)&&(e=e.slice(1)),e),inherits:(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},toFlatObject:(e,t,n,r)=>{let o,a,l;const u={};if(t=t||{},null==e)return t;do{for(o=Object.getOwnPropertyNames(e),a=o.length;a-- >0;)l=o[a],r&&!r(l,e,t)||u[l]||(t[l]=e[l],u[l]=!0);e=!1!==n&&i(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},kindOf:a,kindOfTest:u,endsWith:(e,t,n)=>{e=String(e),(void 0===n||n>e.length)&&(n=e.length),n-=t.length;const r=e.indexOf(t,n);return-1!==r&&r===n},toArray:e=>{if(!e)return null;if(c(e))return e;let t=e.length;if(!m(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},forEachEntry:(e,t)=>{const n=(e&&e[Symbol.iterator]).call(e);let r;for(;(r=n.next())&&!r.done;){const n=r.value;t.call(e,n[0],n[1])}},matchAll:(e,t)=>{let n;const r=[];for(;null!==(n=e.exec(t));)r.push(n);return r},isHTMLForm:j,hasOwnProperty:C,hasOwnProp:C,reduceDescriptors:P,freezeMethods:e=>{P(e,((t,n)=>{const r=e[n];h(r)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=()=>{throw Error("Can not read-only method '"+n+"'")}))}))},toObjectSet:(e,t)=>{const n={},r=e=>{e.forEach((e=>{n[e]=!0}))};return c(e)?r(e):r(String(e).split(t)),n},toCamelCase:e=>e.toLowerCase().replace(/[_-\s]([a-z\d])(\w*)/g,(function(e,t,n){return t.toUpperCase()+n})),noop:()=>{},toFiniteNumber:(e,t)=>(e=+e,Number.isFinite(e)?e:t)};function T(e,t,n,r,o){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),o&&(this.response=o)}A.inherits(T,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:this.config,code:this.code,status:this.response&&this.response.status?this.response.status:null}}});const L=T.prototype,R={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach((e=>{R[e]={value:e}})),Object.defineProperties(T,R),Object.defineProperty(L,"isAxiosError",{value:!0}),T.from=(e,t,n,r,o,i)=>{const a=Object.create(L);return A.toFlatObject(e,a,(function(e){return e!==Error.prototype}),(e=>"isAxiosError"!==e)),T.call(a,e.message,t,n,r,o),a.cause=e,a.name=e.name,i&&Object.assign(a,i),a};const M=T,D=n(6230);function I(e){return A.isPlainObject(e)||A.isArray(e)}function F(e){return A.endsWith(e,"[]")?e.slice(0,-2):e}function N(e,t,n){return e?e.concat(t).map((function(e,t){return e=F(e),!n&&t?"["+e+"]":e})).join(n?".":""):t}const z=A.toFlatObject(A,{},null,(function(e){return/^is[A-Z]/.test(e)})),q=function(e,t,n){if(!A.isObject(e))throw new TypeError("target must be an object");t=t||new(D||FormData);const r=(n=A.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,(function(e,t){return!A.isUndefined(t[e])}))).metaTokens,o=n.visitor||c,i=n.dots,a=n.indexes,l=(n.Blob||"undefined"!=typeof Blob&&Blob)&&(u=t)&&A.isFunction(u.append)&&"FormData"===u[Symbol.toStringTag]&&u[Symbol.iterator];var u;if(!A.isFunction(o))throw new TypeError("visitor must be a function");function s(e){if(null===e)return"";if(A.isDate(e))return e.toISOString();if(!l&&A.isBlob(e))throw new M("Blob is not supported. Use a Buffer instead.");return A.isArrayBuffer(e)||A.isTypedArray(e)?l&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function c(e,n,o){let l=e;if(e&&!o&&"object"==typeof e)if(A.endsWith(n,"{}"))n=r?n:n.slice(0,-2),e=JSON.stringify(e);else if(A.isArray(e)&&function(e){return A.isArray(e)&&!e.some(I)}(e)||A.isFileList(e)||A.endsWith(n,"[]")&&(l=A.toArray(e)))return n=F(n),l.forEach((function(e,r){!A.isUndefined(e)&&null!==e&&t.append(!0===a?N([n],r,i):null===a?n:n+"[]",s(e))})),!1;return!!I(e)||(t.append(N(o,n,i),s(e)),!1)}const f=[],p=Object.assign(z,{defaultVisitor:c,convertValue:s,isVisitable:I});if(!A.isObject(e))throw new TypeError("data must be an object");return function e(n,r){if(!A.isUndefined(n)){if(-1!==f.indexOf(n))throw Error("Circular reference detected in "+r.join("."));f.push(n),A.forEach(n,(function(n,i){!0===(!(A.isUndefined(n)||null===n)&&o.call(t,n,A.isString(i)?i.trim():i,r,p))&&e(n,r?r.concat(i):[i])})),f.pop()}}(e),t};function $(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,(function(e){return t[e]}))}function B(e,t){this._pairs=[],e&&q(e,this,t)}const U=B.prototype;U.append=function(e,t){this._pairs.push([e,t])},U.toString=function(e){const t=e?function(t){return e.call(this,t,$)}:$;return this._pairs.map((function(e){return t(e[0])+"="+t(e[1])}),"").join("&")};const V=B;function W(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function H(e,t,n){if(!t)return e;const r=n&&n.encode||W,o=n&&n.serialize;let i;if(i=o?o(t,n):A.isURLSearchParams(t)?t.toString():new V(t,n).toString(r),i){const t=e.indexOf("#");-1!==t&&(e=e.slice(0,t)),e+=(-1===e.indexOf("?")?"?":"&")+i}return e}const Z=class{constructor(){this.handlers=[]}use(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){A.forEach(this.handlers,(function(t){null!==t&&e(t)}))}},K={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},Q="undefined"!=typeof URLSearchParams?URLSearchParams:V,G=FormData,X=(()=>{let e;return("undefined"==typeof navigator||"ReactNative"!==(e=navigator.product)&&"NativeScript"!==e&&"NS"!==e)&&"undefined"!=typeof window&&"undefined"!=typeof document})(),Y={isBrowser:!0,classes:{URLSearchParams:Q,FormData:G,Blob},isStandardBrowserEnv:X,protocols:["http","https","file","blob","url","data"]},J=function(e){function t(e,n,r,o){let i=e[o++];const a=Number.isFinite(+i),l=o>=e.length;return i=!i&&A.isArray(r)?r.length:i,l?(A.hasOwnProp(r,i)?r[i]=[r[i],n]:r[i]=n,!a):(r[i]&&A.isObject(r[i])||(r[i]=[]),t(e,n,r[i],o)&&A.isArray(r[i])&&(r[i]=function(e){const t={},n=Object.keys(e);let r;const o=n.length;let i;for(r=0;r<o;r++)i=n[r],t[i]=e[i];return t}(r[i])),!a)}if(A.isFormData(e)&&A.isFunction(e.entries)){const n={};return A.forEachEntry(e,((e,r)=>{t(function(e){return A.matchAll(/\w+|\[(\w*)]/g,e).map((e=>"[]"===e[0]?"":e[1]||e[0]))}(e),r,n,0)})),n}return null},ee=Y.isStandardBrowserEnv?{write:function(e,t,n,r,o,i){const a=[];a.push(e+"="+encodeURIComponent(t)),A.isNumber(n)&&a.push("expires="+new Date(n).toGMTString()),A.isString(r)&&a.push("path="+r),A.isString(o)&&a.push("domain="+o),!0===i&&a.push("secure"),document.cookie=a.join("; ")},read:function(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}};function te(e,t){return e&&!/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t)?function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}(e,t):t}const ne=Y.isStandardBrowserEnv?function(){const e=/(msie|trident)/i.test(navigator.userAgent),t=document.createElement("a");let n;function r(n){let r=n;return e&&(t.setAttribute("href",r),r=t.href),t.setAttribute("href",r),{href:t.href,protocol:t.protocol?t.protocol.replace(/:$/,""):"",host:t.host,search:t.search?t.search.replace(/^\?/,""):"",hash:t.hash?t.hash.replace(/^#/,""):"",hostname:t.hostname,port:t.port,pathname:"/"===t.pathname.charAt(0)?t.pathname:"/"+t.pathname}}return n=r(window.location.href),function(e){const t=A.isString(e)?r(e):e;return t.protocol===n.protocol&&t.host===n.host}}():function(){return!0};function re(e,t,n){M.call(this,null==e?"canceled":e,M.ERR_CANCELED,t,n),this.name="CanceledError"}A.inherits(re,M,{__CANCEL__:!0});const oe=re,ie=A.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),ae=Symbol("internals"),le=Symbol("defaults");function ue(e){return e&&String(e).trim().toLowerCase()}function se(e){return!1===e||null==e?e:A.isArray(e)?e.map(se):String(e)}function ce(e,t,n,r){return A.isFunction(r)?r.call(this,t,n):A.isString(t)?A.isString(r)?-1!==t.indexOf(r):A.isRegExp(r)?r.test(t):void 0:void 0}function fe(e,t){t=t.toLowerCase();const n=Object.keys(e);let r,o=n.length;for(;o-- >0;)if(r=n[o],t===r.toLowerCase())return r;return null}function pe(e,t){e&&this.set(e),this[le]=t||null}Object.assign(pe.prototype,{set:function(e,t,n){const r=this;function o(e,t,n){const o=ue(t);if(!o)throw new Error("header name must be a non-empty string");const i=fe(r,o);(!i||!0===n||!1!==r[i]&&!1!==n)&&(r[i||t]=se(e))}return A.isPlainObject(e)?A.forEach(e,((e,n)=>{o(e,n,t)})):o(t,e,n),this},get:function(e,t){if(!(e=ue(e)))return;const n=fe(this,e);if(n){const e=this[n];if(!t)return e;if(!0===t)return function(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}(e);if(A.isFunction(t))return t.call(this,e,n);if(A.isRegExp(t))return t.exec(e);throw new TypeError("parser must be boolean|regexp|function")}},has:function(e,t){if(e=ue(e)){const n=fe(this,e);return!(!n||t&&!ce(0,this[n],n,t))}return!1},delete:function(e,t){const n=this;let r=!1;function o(e){if(e=ue(e)){const o=fe(n,e);!o||t&&!ce(0,n[o],o,t)||(delete n[o],r=!0)}}return A.isArray(e)?e.forEach(o):o(e),r},clear:function(){return Object.keys(this).forEach(this.delete.bind(this))},normalize:function(e){const t=this,n={};return A.forEach(this,((r,o)=>{const i=fe(n,o);if(i)return t[i]=se(r),void delete t[o];const a=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,((e,t,n)=>t.toUpperCase()+n))}(o):String(o).trim();a!==o&&delete t[o],t[a]=se(r),n[a]=!0})),this},toJSON:function(e){const t=Object.create(null);return A.forEach(Object.assign({},this[le]||null,this),((n,r)=>{null!=n&&!1!==n&&(t[r]=e&&A.isArray(n)?n.join(", "):n)})),t}}),Object.assign(pe,{from:function(e){return A.isString(e)?new this((e=>{const t={};let n,r,o;return e&&e.split("\n").forEach((function(e){o=e.indexOf(":"),n=e.substring(0,o).trim().toLowerCase(),r=e.substring(o+1).trim(),!n||t[n]&&ie[n]||("set-cookie"===n?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+", "+r:r)})),t})(e)):e instanceof this?e:new this(e)},accessor:function(e){const t=(this[ae]=this[ae]={accessors:{}}).accessors,n=this.prototype;function r(e){const r=ue(e);t[r]||(function(e,t){const n=A.toCamelCase(" "+t);["get","set","has"].forEach((r=>{Object.defineProperty(e,r+n,{value:function(e,n,o){return this[r].call(this,t,e,n,o)},configurable:!0})}))}(n,e),t[r]=!0)}return A.isArray(e)?e.forEach(r):r(e),this}}),pe.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent"]),A.freezeMethods(pe.prototype),A.freezeMethods(pe);const de=pe;function he(e,t){let n=0;const r=function(e,t){e=e||10;const n=new Array(e),r=new Array(e);let o,i=0,a=0;return t=void 0!==t?t:1e3,function(l){const u=Date.now(),s=r[a];o||(o=u),n[i]=l,r[i]=u;let c=a,f=0;for(;c!==i;)f+=n[c++],c%=e;if(i=(i+1)%e,i===a&&(a=(a+1)%e),u-o<t)return;const p=s&&u-s;return p?Math.round(1e3*f/p):void 0}}(50,250);return o=>{const i=o.loaded,a=o.lengthComputable?o.total:void 0,l=i-n,u=r(l);n=i;const s={loaded:i,total:a,progress:a?i/a:void 0,bytes:l,rate:u||void 0,estimated:u&&a&&i<=a?(a-i)/u:void 0};s[t?"download":"upload"]=!0,e(s)}}function me(e){return new Promise((function(t,n){let r=e.data;const o=de.from(e.headers).normalize(),i=e.responseType;let a;function l(){e.cancelToken&&e.cancelToken.unsubscribe(a),e.signal&&e.signal.removeEventListener("abort",a)}A.isFormData(r)&&Y.isStandardBrowserEnv&&o.setContentType(!1);let u=new XMLHttpRequest;if(e.auth){const t=e.auth.username||"",n=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";o.set("Authorization","Basic "+btoa(t+":"+n))}const s=te(e.baseURL,e.url);function c(){if(!u)return;const r=de.from("getAllResponseHeaders"in u&&u.getAllResponseHeaders());!function(e,t,n){const r=n.config.validateStatus;n.status&&r&&!r(n.status)?t(new M("Request failed with status code "+n.status,[M.ERR_BAD_REQUEST,M.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n)):e(n)}((function(e){t(e),l()}),(function(e){n(e),l()}),{data:i&&"text"!==i&&"json"!==i?u.response:u.responseText,status:u.status,statusText:u.statusText,headers:r,config:e,request:u}),u=null}if(u.open(e.method.toUpperCase(),H(s,e.params,e.paramsSerializer),!0),u.timeout=e.timeout,"onloadend"in u?u.onloadend=c:u.onreadystatechange=function(){u&&4===u.readyState&&(0!==u.status||u.responseURL&&0===u.responseURL.indexOf("file:"))&&setTimeout(c)},u.onabort=function(){u&&(n(new M("Request aborted",M.ECONNABORTED,e,u)),u=null)},u.onerror=function(){n(new M("Network Error",M.ERR_NETWORK,e,u)),u=null},u.ontimeout=function(){let t=e.timeout?"timeout of "+e.timeout+"ms exceeded":"timeout exceeded";const r=e.transitional||K;e.timeoutErrorMessage&&(t=e.timeoutErrorMessage),n(new M(t,r.clarifyTimeoutError?M.ETIMEDOUT:M.ECONNABORTED,e,u)),u=null},Y.isStandardBrowserEnv){const t=(e.withCredentials||ne(s))&&e.xsrfCookieName&&ee.read(e.xsrfCookieName);t&&o.set(e.xsrfHeaderName,t)}void 0===r&&o.setContentType(null),"setRequestHeader"in u&&A.forEach(o.toJSON(),(function(e,t){u.setRequestHeader(t,e)})),A.isUndefined(e.withCredentials)||(u.withCredentials=!!e.withCredentials),i&&"json"!==i&&(u.responseType=e.responseType),"function"==typeof e.onDownloadProgress&&u.addEventListener("progress",he(e.onDownloadProgress,!0)),"function"==typeof e.onUploadProgress&&u.upload&&u.upload.addEventListener("progress",he(e.onUploadProgress)),(e.cancelToken||e.signal)&&(a=t=>{u&&(n(!t||t.type?new oe(null,e,u):t),u.abort(),u=null)},e.cancelToken&&e.cancelToken.subscribe(a),e.signal&&(e.signal.aborted?a():e.signal.addEventListener("abort",a)));const f=function(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}(s);f&&-1===Y.protocols.indexOf(f)?n(new M("Unsupported protocol "+f+":",M.ERR_BAD_REQUEST,e)):u.send(r||null)}))}const be={http:me,xhr:me},ye=e=>{if(A.isString(e)){const t=be[e];if(!e)throw Error(A.hasOwnProp(e)?`Adapter '${e}' is not available in the build`:`Can not resolve adapter '${e}'`);return t}if(!A.isFunction(e))throw new TypeError("adapter is not a function");return e},ge={"Content-Type":"application/x-www-form-urlencoded"},ve={transitional:K,adapter:function(){let e;return"undefined"!=typeof XMLHttpRequest?e=ye("xhr"):"undefined"!=typeof process&&"process"===A.kindOf(process)&&(e=ye("http")),e}(),transformRequest:[function(e,t){const n=t.getContentType()||"",r=n.indexOf("application/json")>-1,o=A.isObject(e);if(o&&A.isHTMLForm(e)&&(e=new FormData(e)),A.isFormData(e))return r&&r?JSON.stringify(J(e)):e;if(A.isArrayBuffer(e)||A.isBuffer(e)||A.isStream(e)||A.isFile(e)||A.isBlob(e))return e;if(A.isArrayBufferView(e))return e.buffer;if(A.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let i;if(o){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return q(e,new Y.classes.URLSearchParams,Object.assign({visitor:function(e,t,n,r){return Y.isNode&&A.isBuffer(e)?(this.append(t,e.toString("base64")),!1):r.defaultVisitor.apply(this,arguments)}},t))}(e,this.formSerializer).toString();if((i=A.isFileList(e))||n.indexOf("multipart/form-data")>-1){const t=this.env&&this.env.FormData;return q(i?{"files[]":e}:e,t&&new t,this.formSerializer)}}return o||r?(t.setContentType("application/json",!1),function(e,t,n){if(A.isString(e))try{return(0,JSON.parse)(e),A.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(0,JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){const t=this.transitional||ve.transitional,n=t&&t.forcedJSONParsing,r="json"===this.responseType;if(e&&A.isString(e)&&(n&&!this.responseType||r)){const n=!(t&&t.silentJSONParsing)&&r;try{return JSON.parse(e)}catch(e){if(n){if("SyntaxError"===e.name)throw M.from(e,M.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:Y.classes.FormData,Blob:Y.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*"}}};A.forEach(["delete","get","head"],(function(e){ve.headers[e]={}})),A.forEach(["post","put","patch"],(function(e){ve.headers[e]=A.merge(ge)}));const we=ve;function _e(e,t){const n=this||we,r=t||n,o=de.from(r.headers);let i=r.data;return A.forEach(e,(function(e){i=e.call(n,i,o.normalize(),t?t.status:void 0)})),o.normalize(),i}function xe(e){return!(!e||!e.__CANCEL__)}function Oe(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new oe}function Se(e){return Oe(e),e.headers=de.from(e.headers),e.data=_e.call(e,e.transformRequest),(e.adapter||we.adapter)(e).then((function(t){return Oe(e),t.data=_e.call(e,e.transformResponse,t),t.headers=de.from(t.headers),t}),(function(t){return xe(t)||(Oe(e),t&&t.response&&(t.response.data=_e.call(e,e.transformResponse,t.response),t.response.headers=de.from(t.response.headers))),Promise.reject(t)}))}function ke(e,t){t=t||{};const n={};function r(e,t){return A.isPlainObject(e)&&A.isPlainObject(t)?A.merge(e,t):A.isPlainObject(t)?A.merge({},t):A.isArray(t)?t.slice():t}function o(n){return A.isUndefined(t[n])?A.isUndefined(e[n])?void 0:r(void 0,e[n]):r(e[n],t[n])}function i(e){if(!A.isUndefined(t[e]))return r(void 0,t[e])}function a(n){return A.isUndefined(t[n])?A.isUndefined(e[n])?void 0:r(void 0,e[n]):r(void 0,t[n])}function l(n){return n in t?r(e[n],t[n]):n in e?r(void 0,e[n]):void 0}const u={url:i,method:i,data:i,baseURL:a,transformRequest:a,transformResponse:a,paramsSerializer:a,timeout:a,timeoutMessage:a,withCredentials:a,adapter:a,responseType:a,xsrfCookieName:a,xsrfHeaderName:a,onUploadProgress:a,onDownloadProgress:a,decompress:a,maxContentLength:a,maxBodyLength:a,beforeRedirect:a,transport:a,httpAgent:a,httpsAgent:a,cancelToken:a,socketPath:a,responseEncoding:a,validateStatus:l};return A.forEach(Object.keys(e).concat(Object.keys(t)),(function(e){const t=u[e]||o,r=t(e);A.isUndefined(r)&&t!==l||(n[e]=r)})),n}const je={};["object","boolean","number","function","string","symbol"].forEach(((e,t)=>{je[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}}));const Ce={};je.transitional=function(e,t,n){function r(e,t){return"[Axios v1.1.3] Transitional option '"+e+"'"+t+(n?". "+n:"")}return(n,o,i)=>{if(!1===e)throw new M(r(o," has been removed"+(t?" in "+t:"")),M.ERR_DEPRECATED);return t&&!Ce[o]&&(Ce[o]=!0,console.warn(r(o," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(n,o,i)}};const Ee={assertOptions:function(e,t,n){if("object"!=typeof e)throw new M("options must be an object",M.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let o=r.length;for(;o-- >0;){const i=r[o],a=t[i];if(a){const t=e[i],n=void 0===t||a(t,i,e);if(!0!==n)throw new M("option "+i+" must be "+n,M.ERR_BAD_OPTION_VALUE)}else if(!0!==n)throw new M("Unknown option "+i,M.ERR_BAD_OPTION)}},validators:je},Pe=Ee.validators;class Ae{constructor(e){this.defaults=e,this.interceptors={request:new Z,response:new Z}}request(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{},t=ke(this.defaults,t);const{transitional:n,paramsSerializer:r}=t;void 0!==n&&Ee.assertOptions(n,{silentJSONParsing:Pe.transitional(Pe.boolean),forcedJSONParsing:Pe.transitional(Pe.boolean),clarifyTimeoutError:Pe.transitional(Pe.boolean)},!1),void 0!==r&&Ee.assertOptions(r,{encode:Pe.function,serialize:Pe.function},!0),t.method=(t.method||this.defaults.method||"get").toLowerCase();const o=t.headers&&A.merge(t.headers.common,t.headers[t.method]);o&&A.forEach(["delete","get","head","post","put","patch","common"],(function(e){delete t.headers[e]})),t.headers=new de(t.headers,o);const i=[];let a=!0;this.interceptors.request.forEach((function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(a=a&&e.synchronous,i.unshift(e.fulfilled,e.rejected))}));const l=[];let u;this.interceptors.response.forEach((function(e){l.push(e.fulfilled,e.rejected)}));let s,c=0;if(!a){const e=[Se.bind(this),void 0];for(e.unshift.apply(e,i),e.push.apply(e,l),s=e.length,u=Promise.resolve(t);c<s;)u=u.then(e[c++],e[c++]);return u}s=i.length;let f=t;for(c=0;c<s;){const e=i[c++],t=i[c++];try{f=e(f)}catch(e){t.call(this,e);break}}try{u=Se.call(this,f)}catch(e){return Promise.reject(e)}for(c=0,s=l.length;c<s;)u=u.then(l[c++],l[c++]);return u}getUri(e){return H(te((e=ke(this.defaults,e)).baseURL,e.url),e.params,e.paramsSerializer)}}A.forEach(["delete","get","head","options"],(function(e){Ae.prototype[e]=function(t,n){return this.request(ke(n||{},{method:e,url:t,data:(n||{}).data}))}})),A.forEach(["post","put","patch"],(function(e){function t(t){return function(n,r,o){return this.request(ke(o||{},{method:e,headers:t?{"Content-Type":"multipart/form-data"}:{},url:n,data:r}))}}Ae.prototype[e]=t(),Ae.prototype[e+"Form"]=t(!0)}));const Te=Ae;class Le{constructor(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");let t;this.promise=new Promise((function(e){t=e}));const n=this;this.promise.then((e=>{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null})),this.promise.then=e=>{let t;const r=new Promise((e=>{n.subscribe(e),t=e})).then(e);return r.cancel=function(){n.unsubscribe(t)},r},e((function(e,r,o){n.reason||(n.reason=new oe(e,r,o),t(n.reason))}))}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}static source(){let e;return{token:new Le((function(t){e=t})),cancel:e}}}const Re=Le,Me=function e(t){const n=new Te(t),o=r(Te.prototype.request,n);return A.extend(o,Te.prototype,n,{allOwnKeys:!0}),A.extend(o,n,null,{allOwnKeys:!0}),o.create=function(n){return e(ke(t,n))},o}(we);Me.Axios=Te,Me.CanceledError=oe,Me.CancelToken=Re,Me.isCancel=xe,Me.VERSION="1.1.3",Me.toFormData=q,Me.AxiosError=M,Me.Cancel=Me.CanceledError,Me.all=function(e){return Promise.all(e)},Me.spread=function(e){return function(t){return e.apply(null,t)}},Me.isAxiosError=function(e){return A.isObject(e)&&!0===e.isAxiosError},Me.formToJSON=e=>J(A.isHTMLForm(e)?new FormData(e):e);const De=Me,{Axios:Ie,AxiosError:Fe,CanceledError:Ne,isCancel:ze,CancelToken:qe,VERSION:$e,all:Be,Cancel:Ue,isAxiosError:Ve,spread:We,toFormData:He}=De,Ze=De},691:(e,t,n)=>{"use strict";function r(e,t,n){return{r:255*n(e.r/255,t.r/255),g:255*n(e.g/255,t.g/255),b:255*n(e.b/255,t.b/255)}}function o(e,t){return t}function i(e,t){return e*t}function a(e,t){return e+t-e*t}function l(e,t){return p(t,e)}function u(e,t){return Math.min(e,t)}function s(e,t){return Math.min(Math.max(e,t),1)}function c(e,t){return 0===e?0:1===t?1:Math.min(1,e/(1-t))}function f(e,t){return 1===e?1:0===t?0:1-Math.min(1,(1-e)/t)}function p(e,t){return t<=.5?i(e,2*t):a(e,2*t-1)}function d(e,t){return t<=.5?e-(1-2*t)*e*(1-e):e+(2*t-1)*((e<=.25?((16*e-12)*e+4)*e:Math.sqrt(e))-e)}function h(e,t){return Math.abs(e-t)}function m(e,t){return e+t-2*e*t}function b(e,t,n){return Math.min(Math.max(e,t),n)}function y(e){return{r:b(e.r,0,255),g:b(e.g,0,255),b:b(e.b,0,255),a:b(e.a,0,1)}}function g(e){return{r:255*e.r,g:255*e.g,b:255*e.b,a:e.a}}function v(e){return{r:e.r/255,g:e.g/255,b:e.b/255,a:e.a}}function w(e,t){void 0===t&&(t=0);var n=Math.pow(10,t);return{r:Math.round(e.r*n)/n,g:Math.round(e.g*n)/n,b:Math.round(e.b*n)/n,a:e.a}}function _(e,t,n,r,o,i){return(1-t/n)*r+t/n*Math.round((1-e)*o+e*i)}function x(e,t,n,r,o){void 0===o&&(o={unitInput:!1,unitOutput:!1,roundOutput:!0}),o.unitInput&&(e=g(e),t=g(t)),e=y(e);var i=(t=y(t)).a+e.a-t.a*e.a,a=n(e,t,r),l=y({r:_(e.a,t.a,i,e.r,t.r,a.r),g:_(e.a,t.a,i,e.g,t.g,a.g),b:_(e.a,t.a,i,e.b,t.b,a.b),a:i});return o.unitOutput?v(l):o.roundOutput?w(l):w(l,9)}function O(e,t,n){return g(n(v(e),v(t)))}function S(e){return.3*e.r+.59*e.g+.11*e.b}function k(e,t){var n=t-S(e);return function(e){var t=S(e),n=e.r,r=e.g,o=e.b,i=Math.min(n,r,o),a=Math.max(n,r,o);function l(e){return t+(e-t)*t/(t-i)}function u(e){return t+(e-t)*(1-t)/(a-t)}return i<0&&(n=l(n),r=l(r),o=l(o)),a>1&&(n=u(n),r=u(r),o=u(o)),{r:n,g:r,b:o}}({r:e.r+n,g:e.g+n,b:e.b+n})}function j(e){return Math.max(e.r,e.g,e.b)-Math.min(e.r,e.g,e.b)}function C(e,t){var n=["r","g","b"].sort((function(t,n){return e[t]-e[n]})),r=n[0],o=n[1],i=n[2],a={r:e.r,g:e.g,b:e.b};return a[i]>a[r]?(a[o]=(a[o]-a[r])*t/(a[i]-a[r]),a[i]=t):a[o]=a[i]=0,a[r]=0,a}function E(e,t){return k(C(t,j(e)),S(e))}function P(e,t){return k(C(e,j(t)),S(e))}function A(e,t){return k(t,S(e))}function T(e,t){return k(e,S(t))}function L(e,t){return x(e,t,r,o)}function R(e,t){return x(e,t,r,i)}function M(e,t){return x(e,t,r,a)}function D(e,t){return x(e,t,r,l)}function I(e,t){return x(e,t,r,u)}function F(e,t){return x(e,t,r,s)}function N(e,t){return x(e,t,r,c)}function z(e,t){return x(e,t,r,f)}function q(e,t){return x(e,t,r,p)}function $(e,t){return x(e,t,r,d)}function B(e,t){return x(e,t,r,h)}function U(e,t){return x(e,t,r,m)}function V(e,t){return x(e,t,O,E)}function W(e,t){return x(e,t,O,P)}function H(e,t){return x(e,t,O,A)}function Z(e,t){return x(e,t,O,T)}n.r(t),n.d(t,{color:()=>H,colorBurn:()=>z,colorDodge:()=>N,darken:()=>I,difference:()=>B,exclusion:()=>U,hardLight:()=>q,hue:()=>V,lighten:()=>F,luminosity:()=>Z,multiply:()=>R,normal:()=>L,overlay:()=>D,saturation:()=>W,screen:()=>M,softLight:()=>$})},552:e=>{"use strict";e.exports=JSON.parse('{"$schema":"http://json-schema.org/draft-04/schema#","definitions":{"AlertEntity":{"type":"object","properties":{"field":{"type":"string","pattern":"^\\\\w+$"},"label":{"type":"string","maxLength":30},"type":{"type":"string","enum":["text","singleSelect","checkbox","radio","singleSelectSplunkSearch"]},"help":{"type":"string","maxLength":200},"defaultValue":{"oneOf":[{"type":"number"},{"type":"string","maxLength":250},{"type":"boolean"}]},"required":{"type":"boolean"},"search":{"type":"string","maxLength":200},"valueField":{"type":"string","maxLength":200},"labelField":{"type":"string","maxLength":200},"options":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/definitions/ValueLabelPair"}}}}},"required":["field","label","type"],"additionalProperties":false},"Alerts":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-zA-Z0-9_]+$","maxLength":100},"label":{"type":"string","maxLength":100},"description":{"type":"string"},"activeResponse":{"type":"object","properties":{"task":{"type":"array","items":{"type":"string"},"minItems":1},"supportsAdhoc":{"type":"boolean"},"subject":{"type":"array","items":{"type":"string"},"minItems":1},"category":{"type":"array","items":{"type":"string"},"minItems":1},"technology":{"type":"array","items":{"$ref":"#/definitions/Technology"},"minItems":1},"drilldownUri":{"type":"string"},"sourcetype":{"type":"string","pattern":"^[a-zA-Z0-9:-_]+$","maxLength":50}},"required":["task","supportsAdhoc","subject","category","technology"]},"entity":{"type":"array","items":{"$ref":"#/definitions/AlertEntity"}}},"required":["name","label","description"],"additionalProperties":false},"ConfigurationEntity":{"type":"object","properties":{"field":{"type":"string","pattern":"(?!^(?:output_mode|output_field|owner|app|sharing)$)(?:^\\\\w+$)"},"label":{"type":"string","maxLength":30},"type":{"type":"string","enum":["custom","text","textarea","singleSelect","checkbox","multipleSelect","radio","placeholder","oauth","helpLink","file"]},"help":{"type":"string","maxLength":200},"tooltip":{"type":"string","maxLength":250},"defaultValue":{"oneOf":[{"type":"number"},{"type":"string","maxLength":250},{"type":"boolean"}]},"options":{"type":"object","properties":{"disableSearch":{"type":"boolean"},"autoCompleteFields":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","maxLength":150},"children":{"type":"array","items":{"$ref":"#/definitions/ValueLabelPair"}}},"required":["label","children"]}},{"type":"array","items":{"$ref":"#/definitions/ValueLabelPair"}}]},"endpointUrl":{"type":"string","maxLength":350},"fileSupportMessage":{"type":"string","maxLength":350},"denyList":{"type":"string","maxLength":350},"allowList":{"type":"string","maxLength":350},"delimiter":{"type":"string","maxLength":1},"items":{"type":"array","items":{"$ref":"#/definitions/ValueLabelPair"}},"referenceName":{"type":"string","maxLength":250},"enable":{"type":"boolean"},"placeholder":{"type":"string","maxLength":250},"display":{"type":"boolean"},"labelField":{"type":"string","maxLength":250},"src":{"type":"string","maxLength":250},"defaultValue":{"type":"string","maxLength":250},"disableonEdit":{"type":"boolean"},"basic":{"type":"array","items":{"$ref":"#/definitions/OAuthFields"}},"oauth":{"type":"array","items":{"$ref":"#/definitions/OAuthFields"}},"auth_type":{"type":"array","items":{"type":"string","maxLength":100}},"auth_label":{"type":"string","maxLength":250},"oauth_popup_width":{"type":"number"},"oauth_popup_height":{"type":"number"},"oauth_timeout":{"type":"number"},"auth_code_endpoint":{"type":"string","maxLength":350},"access_token_endpoint":{"type":"string","maxLength":350},"oauth_state_enabled":{"type":"boolean"},"text":{"type":"string","maxLength":50},"link":{"type":"string"},"rowsMin":{"type":"number"},"rowsMax":{"type":"number"}}},"required":{"type":"boolean"},"encrypted":{"type":"boolean"},"validators":{"type":"array","items":{"anyOf":[{"$ref":"#/definitions/StringValidator"},{"$ref":"#/definitions/NumberValidator"},{"$ref":"#/definitions/RegexValidator"},{"$ref":"#/definitions/EmailValidator"},{"$ref":"#/definitions/Ipv4Validator"},{"$ref":"#/definitions/UrlValidator"},{"$ref":"#/definitions/DateValidator"},{"$ref":"#/definitions/FileValidator"}]}}},"required":["field","label","type"],"additionalProperties":false},"ConfigurationPage":{"type":"object","properties":{"title":{"type":"string","maxLength":60},"description":{"type":"string","maxLength":200},"tabs":{"type":"array","items":{"$ref":"#/definitions/TabContent"},"minItems":1}},"required":["title","tabs"],"additionalProperties":false},"ConfigurationTable":{"type":"object","properties":{"moreInfo":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","pattern":"^\\\\w+$"},"label":{"type":"string","maxLength":30},"mapping":{"type":"object"}},"required":["field","label"]}},"header":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","pattern":"^\\\\w+$"},"label":{"type":"string","maxLength":30},"mapping":{"type":"object"},"customCell":{"type":"object"}},"required":["field","label"]}},"customRow":{"type":"object"},"actions":{"type":"array","items":{"type":"string","enum":["edit","delete","clone"]}}},"required":["header","actions"],"additionalProperties":false},"DateValidator":{"type":"object","properties":{"errorMsg":{"type":"string","maxLength":400},"type":{"const":"date"}},"required":["type"],"additionalProperties":false},"EmailValidator":{"type":"object","properties":{"errorMsg":{"type":"string","maxLength":400},"type":{"const":"email"}},"required":["type"],"additionalProperties":false},"Hooks":{"type":"object","properties":{"saveValidator":{"type":"string","maxLength":3000}},"additionalProperties":false},"InputsEntity":{"type":"object","properties":{"field":{"type":"string","pattern":"(?!^(?:persistentQueueSize|queueSize|start_by_shell|output_mode|output_field|owner|app|sharing)$)(?:^\\\\w+$)"},"label":{"type":"string","maxLength":30},"type":{"type":"string","enum":["custom","text","textarea","singleSelect","checkbox","multipleSelect","radio","placeholder","oauth","helpLink","file"]},"help":{"type":"string","maxLength":200},"tooltip":{"type":"string","maxLength":250},"defaultValue":{"oneOf":[{"type":"number"},{"type":"string","maxLength":250},{"type":"boolean"}]},"options":{"type":"object","properties":{"disableSearch":{"type":"boolean"},"autoCompleteFields":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","maxLength":150},"children":{"type":"array","items":{"$ref":"#/definitions/ValueLabelPair"}}},"required":["label","children"]}},{"type":"array","items":{"$ref":"#/definitions/ValueLabelPair"}}]},"endpointUrl":{"type":"string","maxLength":350},"denyList":{"type":"string","maxLength":350},"allowList":{"type":"string","maxLength":350},"delimiter":{"type":"string","maxLength":1},"items":{"type":"array","items":{"$ref":"#/definitions/ValueLabelPair"}},"referenceName":{"type":"string","maxLength":250},"enable":{"type":"boolean"},"placeholder":{"type":"string","maxLength":250},"display":{"type":"boolean"},"labelField":{"type":"string","maxLength":250},"src":{"type":"string","maxLength":250},"defaultValue":{"type":"string","maxLength":250},"disableonEdit":{"type":"boolean"},"basic":{"type":"array","items":{"$ref":"#/definitions/OAuthFields"}},"oauth":{"type":"array","items":{"$ref":"#/definitions/OAuthFields"}},"auth_type":{"type":"array","items":{"type":"string","maxLength":100}},"auth_label":{"type":"string","maxLength":250},"oauth_popup_width":{"type":"number"},"oauth_popup_height":{"type":"number"},"oauth_timeout":{"type":"number"},"auth_code_endpoint":{"type":"string","maxLength":350},"access_token_endpoint":{"type":"string","maxLength":350},"text":{"type":"string","maxLength":50},"link":{"type":"string"},"rowsMin":{"type":"number"},"rowsMax":{"type":"number"}}},"required":{"type":"boolean"},"encrypted":{"type":"boolean"},"validators":{"type":"array","items":{"anyOf":[{"$ref":"#/definitions/StringValidator"},{"$ref":"#/definitions/NumberValidator"},{"$ref":"#/definitions/RegexValidator"},{"$ref":"#/definitions/EmailValidator"},{"$ref":"#/definitions/Ipv4Validator"},{"$ref":"#/definitions/UrlValidator"},{"$ref":"#/definitions/DateValidator"},{"$ref":"#/definitions/FileValidator"}]}}},"required":["field","label","type"],"additionalProperties":false},"InputsPage":{"oneOf":[{"type":"object","properties":{"title":{"type":"string","maxLength":60},"description":{"type":"string","maxLength":200},"menu":{"type":"object"},"table":{"$ref":"#/definitions/InputsTable"},"groupsMenu":{"type":"array","items":{"type":"object","properties":{"groupName":{"type":"string","pattern":"^[0-9a-zA-Z][\\\\w-]*$","maxLength":50},"groupTitle":{"type":"string","maxLength":100},"groupServices":{"type":"array","items":{"type":"string","pattern":"^[0-9a-zA-Z][\\\\w-]*$","maxLength":50}}},"required":["groupTitle","groupName"]}},"services":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","pattern":"^[0-9a-zA-Z][\\\\w-]*$","maxLength":50},"title":{"type":"string","maxLength":100},"entity":{"type":"array","items":{"$ref":"#/definitions/InputsEntity"}},"options":{"$ref":"#/definitions/Hooks"},"groups":{"type":"array","items":{"type":"object","properties":{"options":{"type":"object","properties":{"isExpandable":{"type":"boolean"},"expand":{"type":"boolean"}}},"label":{"type":"string","maxLength":100},"field":{"type":"array","items":{"type":"string","pattern":"^\\\\w+$"}}},"required":["label"]}},"style":{"type":"string","enum":["page","dialog"]},"hook":{"type":"object"},"conf":{"type":"string","maxLength":100},"restHandlerName":{"type":"string","maxLength":100},"restHandlerModule":{"type":"string","maxLength":100},"restHandlerClass":{"type":"string","maxLength":100}},"not":{"required":["table"]},"required":["name","title","entity"]}}},"required":["title","table","services"],"additionalProperties":false},{"type":"object","properties":{"title":{"type":"string","maxLength":60},"services":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","pattern":"^[0-9a-zA-Z][0-9a-zA-Z_-]*$","maxLength":50},"title":{"type":"string","maxLength":100},"description":{"type":"string","maxLength":200},"table":{"$ref":"#/definitions/InputsTable"},"entity":{"type":"array","items":{"$ref":"#/definitions/InputsEntity"}},"options":{"$ref":"#/definitions/Hooks"},"groups":{"type":"array","items":{"type":"object","properties":{"options":{"type":"object","properties":{"isExpandable":{"type":"boolean"},"expand":{"type":"boolean"}}},"label":{"type":"string","maxLength":100},"field":{"type":"array","items":{"type":"string","pattern":"^\\\\w+$"}}},"required":["label"]}},"style":{"type":"string","enum":["page","dialog"]},"hook":{"type":"object"},"conf":{"type":"string","maxLength":100},"restHandlerName":{"type":"string","maxLength":100},"restHandlerModule":{"type":"string","maxLength":100},"restHandlerClass":{"type":"string","maxLength":100}},"required":["name","title","table","entity"]}}},"required":["title","services"],"additionalProperties":false}]},"InputsTable":{"type":"object","properties":{"moreInfo":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","pattern":"^\\\\w+$"},"label":{"type":"string","maxLength":30},"mapping":{"type":"object"}},"required":["field","label"]}},"header":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","pattern":"^\\\\w+$"},"label":{"type":"string","maxLength":30},"mapping":{"type":"object"},"customCell":{"type":"object"}},"required":["field","label"]}},"customRow":{"type":"object"},"actions":{"type":"array","items":{"type":"string","enum":["edit","delete","clone","enable"]}}},"required":["header","actions"],"additionalProperties":false},"Ipv4Validator":{"type":"object","properties":{"errorMsg":{"type":"string","maxLength":400},"type":{"const":"ipv4"}},"required":["type"],"additionalProperties":false},"Meta":{"type":"object","properties":{"displayName":{"type":"string","maxLength":200},"name":{"type":"string","pattern":"^[^<>\\\\:\\"\\\\/\\\\\\\\|\\\\?\\\\*]+$"},"restRoot":{"type":"string","pattern":"^\\\\w+$"},"apiVersion":{"type":"string","pattern":"^(?:\\\\d{1,3}\\\\.){2}\\\\d{1,3}$"},"version":{"type":"string"},"schemaVersion":{"type":"string","pattern":"^(?:\\\\d{1,3}\\\\.){2}\\\\d{1,3}$"}},"required":["displayName","name","restRoot","version"],"additionalProperties":false},"NumberValidator":{"type":"object","properties":{"errorMsg":{"type":"string","maxLength":400},"type":{"const":"number"},"range":{"type":"array","items":{"type":"number"}}},"required":["type","range"],"additionalProperties":false},"FileValidator":{"type":"object","properties":{"errorMsg":{"type":"string","maxLength":400},"type":{"const":"file"},"supportedFileTypes":{"type":"array","items":{"type":"string"}}},"additionalProperties":false},"OAuthFields":{"type":"object","properties":{"oauth_field":{"type":"string","maxLength":100},"label":{"type":"string","maxLength":100},"field":{"type":"string","maxLength":100},"help":{"type":"string","maxLength":200},"encrypted":{"type":"boolean"},"required":{"type":"boolean"},"options":{"type":"object","properties":{"placeholder":{"type":"string","maxLength":250}},"additionalProperties":false}},"additionalProperties":false},"Pages":{"type":"object","properties":{"configuration":{"$ref":"#/definitions/ConfigurationPage"},"inputs":{"$ref":"#/definitions/InputsPage"}},"additionalProperties":false},"RegexValidator":{"type":"object","properties":{"errorMsg":{"type":"string","maxLength":400},"type":{"const":"regex"},"pattern":{"type":"string"}},"required":["type","pattern"],"additionalProperties":false},"StringValidator":{"type":"object","properties":{"errorMsg":{"type":"string","maxLength":400},"type":{"const":"string"},"minLength":{"type":"number","minimum":0},"maxLength":{"type":"number","minimum":0}},"required":["type","minLength","maxLength"],"additionalProperties":false},"TabContent":{"type":"object","properties":{"entity":{"type":"array","items":{"$ref":"#/definitions/ConfigurationEntity"}},"name":{"type":"string","pattern":"^[\\\\/\\\\w]+$","maxLength":250},"title":{"type":"string","maxLength":50},"options":{"$ref":"#/definitions/Hooks"},"table":{"$ref":"#/definitions/ConfigurationTable"},"style":{"type":"string","enum":["page","dialog"]},"conf":{"type":"string","maxLength":100},"restHandlerName":{"type":"string","maxLength":100},"restHandlerModule":{"type":"string","maxLength":100},"restHandlerClass":{"type":"string","maxLength":100},"hook":{"type":"object"}},"required":["entity","name","title"],"additionalProperties":false},"Technology":{"type":"object","properties":{"version":{"type":"array","items":{"type":"string","pattern":"^\\\\d+(?:\\\\.\\\\d+)*$"},"minItems":1},"product":{"type":"string","maxLength":100},"vendor":{"type":"string","maxLength":100}},"required":["version","product","vendor"],"additionalProperties":false},"UrlValidator":{"type":"object","properties":{"errorMsg":{"type":"string","maxLength":400},"type":{"const":"url"}},"required":["type"],"additionalProperties":false},"ValueLabelPair":{"type":"object","properties":{"value":{"oneOf":[{"type":"number"},{"type":"string","maxLength":250},{"type":"boolean"}]},"label":{"type":"string","maxLength":100}},"required":["label"],"additionalProperties":false}},"type":"object","properties":{"meta":{"$ref":"#/definitions/Meta"},"pages":{"$ref":"#/definitions/Pages"},"alerts":{"type":"array","items":{"$ref":"#/definitions/Alerts"},"minItems":1}},"required":["meta","pages"],"additionalProperties":false}')}},__webpack_module_cache__={},deferred,leafPrototypes,getProto,inProgress,dataWebpackPrefix;function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.m=__webpack_modules__,deferred=[],__webpack_require__.O=(e,t,n,r)=>{if(!t){var o=1/0;for(u=0;u<deferred.length;u++){for(var[t,n,r]=deferred[u],i=!0,a=0;a<t.length;a++)(!1&r||o>=r)&&Object.keys(__webpack_require__.O).every((e=>__webpack_require__.O[e](t[a])))?t.splice(a--,1):(i=!1,r<o&&(o=r));if(i){deferred.splice(u--,1);var l=n();void 0!==l&&(e=l)}}return e}r=r||0;for(var u=deferred.length;u>0&&deferred[u-1][2]>r;u--)deferred[u]=deferred[u-1];deferred[u]=[t,n,r]},__webpack_require__.F={},__webpack_require__.E=e=>{Object.keys(__webpack_require__.F).map((t=>{__webpack_require__.F[t](e)}))},__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},getProto=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,__webpack_require__.t=function(e,t){if(1&t&&(e=this(e)),8&t)return e;if("object"==typeof e&&e){if(4&t&&e.__esModule)return e;if(16&t&&"function"==typeof e.then)return e}var n=Object.create(null);__webpack_require__.r(n);var r={};leafPrototypes=leafPrototypes||[null,getProto({}),getProto([]),getProto(getProto)];for(var o=2&t&&e;"object"==typeof o&&!~leafPrototypes.indexOf(o);o=getProto(o))Object.getOwnPropertyNames(o).forEach((t=>r[t]=()=>e[t]));return r.default=()=>e,__webpack_require__.d(n,r),n},__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.f={},__webpack_require__.e=e=>Promise.all(Object.keys(__webpack_require__.f).reduce(((t,n)=>(__webpack_require__.f[n](e,t),t)),[])),__webpack_require__.u=e=>e+".js",__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),inProgress={},dataWebpackPrefix="@splunk/ucc_ui_lib:",__webpack_require__.l=(e,t,n,r)=>{if(inProgress[e])inProgress[e].push(t);else{var o,i;if(void 0!==n)for(var a=document.getElementsByTagName("script"),l=0;l<a.length;l++){var u=a[l];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==dataWebpackPrefix+n){o=u;break}}o||(i=!0,(o=document.createElement("script")).charset="utf-8",o.timeout=120,__webpack_require__.nc&&o.setAttribute("nonce",__webpack_require__.nc),o.setAttribute("data-webpack",dataWebpackPrefix+n),o.src=e),inProgress[e]=[t];var s=(t,n)=>{o.onerror=o.onload=null,clearTimeout(c);var r=inProgress[e];if(delete inProgress[e],o.parentNode&&o.parentNode.removeChild(o),r&&r.forEach((e=>e(n))),t)return t(n)},c=setTimeout(s.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=s.bind(null,o.onerror),o.onload=s.bind(null,o.onload),i&&document.head.appendChild(o)}},__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;__webpack_require__.g.importScripts&&(e=__webpack_require__.g.location+"");var t=__webpack_require__.g.document;if(!e&&t&&(t.currentScript&&(e=t.currentScript.src),!e)){var n=t.getElementsByTagName("script");n.length&&(e=n[n.length-1].src)}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),__webpack_require__.p=e})(),(()=>{var e={141:0};__webpack_require__.f.j=(t,n)=>{var r=__webpack_require__.o(e,t)?e[t]:void 0;if(0!==r)if(r)n.push(r[2]);else{var o=new Promise(((n,o)=>r=e[t]=[n,o]));n.push(r[2]=o);var i=__webpack_require__.p+__webpack_require__.u(t),a=new Error;__webpack_require__.l(i,(n=>{if(__webpack_require__.o(e,t)&&(0!==(r=e[t])&&(e[t]=void 0),r)){var o=n&&("load"===n.type?"missing":n.type),i=n&&n.target&&n.target.src;a.message="Loading chunk "+t+" failed.\n("+o+": "+i+")",a.name="ChunkLoadError",a.type=o,a.request=i,r[1](a)}}),"chunk-"+t,t)}},__webpack_require__.F.j=t=>{if(!__webpack_require__.o(e,t)||void 0===e[t]){e[t]=null;var n=document.createElement("link");__webpack_require__.nc&&n.setAttribute("nonce",__webpack_require__.nc),n.rel="prefetch",n.as="script",n.href=__webpack_require__.p+__webpack_require__.u(t),document.head.appendChild(n)}},__webpack_require__.O.j=t=>0===e[t];var t=(t,n)=>{var r,o,[i,a,l]=n,u=0;if(i.some((t=>0!==e[t]))){for(r in a)__webpack_require__.o(a,r)&&(__webpack_require__.m[r]=a[r]);if(l)var s=l(__webpack_require__)}for(t&&t(n);u<i.length;u++)o=i[u],__webpack_require__.o(e,o)&&e[o]&&e[o][0](),e[o]=0;return __webpack_require__.O(s)},n=self.webpackChunk_splunk_ucc_ui_lib=self.webpackChunk_splunk_ucc_ui_lib||[];n.forEach(t.bind(null,0)),n.push=t.bind(null,n.push.bind(n))})(),__webpack_require__.nc=void 0,__webpack_require__.O(0,[141],(()=>{[309,354,656,895,772].map(__webpack_require__.E)}),5);var __webpack_exports__={};(()=>{"use strict";var e,t,n=__webpack_require__(5671),r=__webpack_require__(3144),o=__webpack_require__(9340),i=__webpack_require__(2963),a=__webpack_require__(1120),l=__webpack_require__(7294),u=__webpack_require__(1625),s=__webpack_require__.n(u),c=__webpack_require__(9250),f=__webpack_require__(2599);function p(e){let{basename:t,children:n,window:r}=e,o=l.useRef();null==o.current&&(o.current=(0,f.lX)({window:r,v5Compat:!0}));let i=o.current,[a,u]=l.useState({action:i.action,location:i.location});return l.useLayoutEffect((()=>i.listen(u)),[i]),l.createElement(c.F0,{basename:t,children:n,location:a.location,navigationType:a.action,navigator:i})}(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmitImpl="useSubmitImpl",e.UseFetcher="useFetcher"})(e||(e={})),function(e){e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"}(t||(t={}));var d,h,m,b=__webpack_require__(5947),y=__webpack_require__(6070),g=__webpack_require__(168),v=__webpack_require__(2788),w=__webpack_require__(3718),_=v.default.div(d||(d=(0,g.Z)(["\n    ",";\n    display: block;\n    font-size: ",";\n    line-height: 200%;\n    margin: calc("," * 1) calc("," * 1);\n"])),b.mixins.reset("inline"),b.variables.fontSizeLarge,b.variables.spacing,b.variables.spacing),x=(v.default.div(h||(h=(0,g.Z)(["\n    font-weight: bold;\n    color: ",";\n    font-size: ",";\n"])),b.variables.infoColor,b.variables.fontSizeXXLarge),{enterprise:{family:"enterprise",colorScheme:"light",density:"comfortable"},enterpriseDark:{family:"enterprise",colorScheme:"dark",density:"comfortable"},lite:{family:"enterprise",colorScheme:"light",density:"comfortable"}}),O=x[(0,w.uH)()]||x.enterprise,S=__webpack_require__(4843),k=__webpack_require__(5220),j=__webpack_require__(1581),C=__webpack_require__.n(j),E=__webpack_require__(4317),P=__webpack_require__(9609),A=__webpack_require__(4255),T=__webpack_require__(4266),L=__webpack_require__(885),R=__webpack_require__(6416),M=__webpack_require__.n(R),D=__webpack_require__(1158),I=__webpack_require__.n(D),F=__webpack_require__(8689),N=__webpack_require__.n(F),z=(0,v.default)(I())(m||(m=(0,g.Z)(["\n    width: 600px;\n"])));function q(e){var t=(0,l.useState)(e.open),n=(0,L.Z)(t,2),r=n[0],o=n[1],i=function(){o(!1)};return l.createElement(z,{open:r},l.createElement(I().Header,{onRequestClose:i,title:(0,P.P)(104)}),l.createElement(I().Body,null,l.createElement(N(),{appearance:"fill",type:"error"},e.message)),l.createElement(I().Footer,null,l.createElement(M(),{appearance:"primary",onClick:i,label:"OK"})))}q.propTypes={message:C().string,open:C().string};const $=q;var B=function(e){(0,o.Z)(c,e);var t,u,s=(t=c,u=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,n=(0,a.Z)(t);if(u){var r=(0,a.Z)(this).constructor;e=Reflect.construct(n,arguments,r)}else e=n.apply(this,arguments);return(0,i.Z)(this,e)});function c(e){var t;return(0,n.Z)(this,c),(t=s.call(this,e)).state={unifiedConfig:{},validationResult:{},appData:{},loading:!0,syntaxError:!1},t}return(0,r.Z)(c,[{key:"componentDidMount",value:function(){var e=this;this.setState({loading:!0}),(0,T.E)().then((function(t){e.attchPropertie(t)})).catch((function(t){t&&"SyntaxError"===t.name?e.setState({syntaxError:!0,loading:!1}):t&&t.response&&404===t.response.status?e.setState({fileNotFoundError:!0,loading:!1}):console.error("Error [configManager.js] [35]: ",t)}))}},{key:"attchPropertie",value:function(e){var t=(0,E.Fv)(e),n=e.meta,r={app:n.name,custom_rest:n.restRoot,nullStr:"NULL",stanzaPrefix:n.restRoot};(0,A.Zv)(e),(0,A.w)(r),this.setState({appData:r,validationResult:t,unifiedConfig:e,loading:!1})}},{key:"renderComponents",value:function(){return this.state.validationResult.failed?l.createElement($,{message:(0,P.P)(110,[k.unescape(this.state.validationResult.errors[0].stack)]),open:!0}):this.state.syntaxError?l.createElement($,{message:(0,P.P)(110,[(0,P.P)(20)]),open:!0}):this.state.fileNotFoundError?l.createElement($,{message:(0,P.P)(110,[(0,P.P)(118)]),open:!0}):this.props.children(this.state)}},{key:"render",value:function(){return!this.state.loading&&this.renderComponents()}}]),c}(l.Component);B.propTypes={children:C().any};const U=B;var V=__webpack_require__(723),W=__webpack_require__(3379),H=__webpack_require__.n(W),Z=__webpack_require__(7795),K=__webpack_require__.n(Z),Q=__webpack_require__(569),G=__webpack_require__.n(Q),X=__webpack_require__(3565),Y=__webpack_require__.n(X),J=__webpack_require__(9216),ee=__webpack_require__.n(J),te=__webpack_require__(4589),ne=__webpack_require__.n(te),re=__webpack_require__(6201),oe={};oe.styleTagTransform=ne(),oe.setAttributes=Y(),oe.insert=G().bind(null,"head"),oe.domAPI=K(),oe.insertStyleElement=ee(),H()(re.Z,oe),re.Z&&re.Z.locals&&re.Z.locals,__webpack_require__.p="".concat((0,T.a)(),"/");var ie=l.lazy((function(){return Promise.all([__webpack_require__.e(309),__webpack_require__.e(354),__webpack_require__.e(656),__webpack_require__.e(895)]).then(__webpack_require__.bind(__webpack_require__,895))})),ae=l.lazy((function(){return Promise.all([__webpack_require__.e(309),__webpack_require__.e(656),__webpack_require__.e(772)]).then(__webpack_require__.bind(__webpack_require__,6772))}));function le(e){var t=function(t){(0,o.Z)(f,t);var u,s,c=(u=f,s=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=(0,a.Z)(u);if(s){var n=(0,a.Z)(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return(0,i.Z)(this,e)});function f(){return(0,n.Z)(this,f),c.apply(this,arguments)}return(0,r.Z)(f,[{key:"render",value:function(){var t=this;return l.createElement(b.SplunkThemeProvider,O,l.createElement(_,null,l.createElement(p,null,l.createElement(U,null,(function(n){var r=n.loading,o=n.appData;return!r&&o&&l.createElement(l.Suspense,{fallback:l.createElement(y.XE,null)},l.createElement(e,t.props))})))))}}]),f}(l.Component);return t}var ue=le(ie),se=le(ae),ce=window.location.pathname.substring(1).split("/"),fe=ce[ce.length-1];fe===S.b?s()(l.createElement(ue,null),{pageTitle:V.Z[116]}):fe===S.y&&s()(l.createElement(se,null),{pageTitle:V.Z[117]})})(),__webpack_exports__=__webpack_require__.O(__webpack_exports__)})();
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/js/build/globalConfig.json b/deployment-apps/metricator-for-nmon/appserver/static/js/build/globalConfig.json
    new file mode 100644
    index 0000000..68f93df
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/js/build/globalConfig.json
    @@ -0,0 +1,54 @@
    +{
    +    "pages": {
    +        "configuration": {
    +            "tabs": [
    +                {
    +                    "name": "logging",
    +                    "entity": [
    +                        {
    +                            "type": "singleSelect",
    +                            "label": "Log level",
    +                            "options": {
    +                                "disableSearch": true,
    +                                "autoCompleteFields": [
    +                                    {
    +                                        "value": "DEBUG",
    +                                        "label": "DEBUG"
    +                                    },
    +                                    {
    +                                        "value": "INFO",
    +                                        "label": "INFO"
    +                                    },
    +                                    {
    +                                        "value": "WARNING",
    +                                        "label": "WARNING"
    +                                    },
    +                                    {
    +                                        "value": "ERROR",
    +                                        "label": "ERROR"
    +                                    },
    +                                    {
    +                                        "value": "CRITICAL",
    +                                        "label": "CRITICAL"
    +                                    }
    +                                ]
    +                            },
    +                            "defaultValue": "INFO",
    +                            "field": "loglevel"
    +                        }
    +                    ],
    +                    "title": "Logging"
    +                }
    +            ],
    +            "title": "Configuration",
    +            "description": "Configure Metricator"
    +        }
    +    },
    +    "meta": {
    +        "name": "metricator-for-nmon",
    +        "restRoot": "metricator_for_nmon",
    +        "version": "2.0.0",
    +        "displayName": "METRICATOR for Nmon",
    +        "schemaVersion": "0.0.3"
    +    }
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/AIX_48px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/AIX_48px.png
    new file mode 100644
    index 0000000..a5360c6
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/AIX_48px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/AIX_72px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/AIX_72px.png
    new file mode 100644
    index 0000000..10b8ab0
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/AIX_72px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/linux_48px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/linux_48px.png
    new file mode 100644
    index 0000000..045ca33
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/linux_48px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/linux_72px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/linux_72px.png
    new file mode 100644
    index 0000000..0d93ea7
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/linux_72px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/linux_alt_128px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/linux_alt_128px.png
    new file mode 100644
    index 0000000..aac5ccf
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/linux_alt_128px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/linux_alt_72px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/linux_alt_72px.png
    new file mode 100644
    index 0000000..0506202
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/linux_alt_72px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/solaris_48px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/solaris_48px.png
    new file mode 100644
    index 0000000..2f147fe
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/solaris_48px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/solaris_72px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/solaris_72px.png
    new file mode 100644
    index 0000000..938b6bc
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/solaris_72px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/solaris_alt_48px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/solaris_alt_48px.png
    new file mode 100644
    index 0000000..852c346
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/solaris_alt_48px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/solaris_alt_72px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/solaris_alt_72px.png
    new file mode 100644
    index 0000000..be81c1d
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/blackandwhite/solaris_alt_72px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/AIX_48px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/AIX_48px.png
    new file mode 100644
    index 0000000..0db6538
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/AIX_48px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/AIX_72px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/AIX_72px.png
    new file mode 100644
    index 0000000..6a99988
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/AIX_72px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/Windows_72px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/Windows_72px.png
    new file mode 100644
    index 0000000..4265316
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/Windows_72px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/linux_48px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/linux_48px.png
    new file mode 100644
    index 0000000..ba56d8a
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/linux_48px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/linux_72px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/linux_72px.png
    new file mode 100644
    index 0000000..d5655d3
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/linux_72px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/linux_alt_128px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/linux_alt_128px.png
    new file mode 100644
    index 0000000..ea6a00e
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/linux_alt_128px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/solaris_128px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/solaris_128px.png
    new file mode 100644
    index 0000000..0a80240
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/solaris_128px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/solaris_48px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/solaris_48px.png
    new file mode 100644
    index 0000000..0f0a09e
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/solaris_48px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/solaris_72px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/solaris_72px.png
    new file mode 100644
    index 0000000..c817742
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/OS/colors/solaris_72px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/Others/RT_icon.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/Others/RT_icon.png
    new file mode 100644
    index 0000000..7a1d426
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/Others/RT_icon.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/Others/RT_icon.xcf b/deployment-apps/metricator-for-nmon/appserver/static/logos/Others/RT_icon.xcf
    new file mode 100644
    index 0000000..f3d6570
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/Others/RT_icon.xcf differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/appIconAlt_2x.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/appIconAlt_2x.png
    new file mode 100644
    index 0000000..82da975
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/appIconAlt_2x.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/logos/manufactors/IBM_logo_72px.png b/deployment-apps/metricator-for-nmon/appserver/static/logos/manufactors/IBM_logo_72px.png
    new file mode 100644
    index 0000000..29c609c
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/logos/manufactors/IBM_logo_72px.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_filesystem_table_bar.js b/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_filesystem_table_bar.js
    new file mode 100644
    index 0000000..613ec10
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_filesystem_table_bar.js
    @@ -0,0 +1,36 @@
    +require([
    +  "jquery",
    +  "underscore",
    +  "splunkjs/mvc",
    +  "views/shared/results_table/renderers/BaseCellRenderer",
    +  "splunkjs/mvc/simplexml/ready!",
    +], function ($, _, mvc, BaseCellRenderer) {
    +  var DataBarCellRenderer = BaseCellRenderer.extend({
    +    canRender: function (cell) {
    +      return cell.field === "current_used_percent";
    +    },
    +    render: function ($td, cell) {
    +      var pColor = "data-bar-under";
    +      if (cell.value > 15) {
    +        pColor = "data-bar-over";
    +      }
    +      $td.addClass("data-bar-cell").html(
    +        _.template(
    +          '<div class="data-bar-wrapper"><div class="data-bar <%- pColor %>" style="width:<%- percent %>%">&nbsp;<%- ppp %>%</div></div>',
    +          {
    +            percent: Math.min(Math.max(parseFloat(cell.value), 0), 100),
    +            ppp: parseFloat(cell.value).toFixed(2),
    +            pColor: pColor,
    +          }
    +        )
    +      );
    +    },
    +  });
    +
    +  mvc.Components.get("element_table_show_lookup_inventory").getVisualization(
    +    function (tableView) {
    +      tableView.table.addCellRenderer(new DataBarCellRenderer());
    +      tableView.table.render();
    +    }
    +  );
    +});
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_filesystem_v2.css b/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_filesystem_v2.css
    new file mode 100644
    index 0000000..79429ed
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_filesystem_v2.css
    @@ -0,0 +1,905 @@
    +/* Increase the default max-width for links */
    +.btn-pill {
    +  max-width: 600px !important;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-info h1 {
    +  color: #a7c7e7;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-success h1 {
    +  color: #77dd77;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-danger h1 {
    +  color: #ff6961;
    +}
    +
    +/* modal spl message */
    +.modal-spl-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/* modal success / info / error messages */
    +.modal-success-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-info-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-error-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: #ff6961;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/*** Buttons ***/
    +
    +.btn {
    +  background-color: black !important;
    +}
    +
    +.btn:hover {
    +  background-color: #31373e !important;
    +}
    +
    +/* fixes some UI issues in dark theme with bootstrap buttons */
    +button {
    +  background-color: transparent;
    +  border-width: inherit;
    +}
    +
    +/* Bootstrap btns */
    +
    +.btn-primary {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:hover {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +}
    +
    +.btn-primary:focus,
    +.btn-primary.focus {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-primary.disabled,
    +.btn-primary:disabled {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active,
    +.btn-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0062cc;
    +  border-color: #005cbf;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #117a8b;
    +  border-color: #10707f;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-success {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:hover {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +}
    +
    +.btn-success:focus,
    +.btn-success.focus {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-success.disabled,
    +.btn-success:disabled {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active,
    +.btn-success:not(:disabled):not(.disabled).active,
    +.show > .btn-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1e7e34;
    +  border-color: #1c7430;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active:focus,
    +.btn-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-light {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:hover {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +}
    +
    +.btn-light:focus,
    +.btn-light.focus {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-light.disabled,
    +.btn-light:disabled {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active,
    +.btn-light:not(:disabled):not(.disabled).active,
    +.show > .btn-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #dae0e5;
    +  border-color: #d3d9df;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active:focus,
    +.btn-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-dark {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:hover {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +}
    +
    +.btn-dark:focus,
    +.btn-dark.focus {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-dark.disabled,
    +.btn-dark:disabled {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active,
    +.btn-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1d2124;
    +  border-color: #171a1d;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-outline-primary {
    +  color: #fff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:hover {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:focus,
    +.btn-outline-primary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-primary.disabled,
    +.btn-outline-primary:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active,
    +.btn-outline-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-secondary {
    +  color: #fff;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:hover {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:focus,
    +.btn-outline-secondary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-secondary.disabled,
    +.btn-outline-secondary:disabled {
    +  color: #6c757d;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-secondary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-secondary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-success {
    +  color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:hover {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:focus,
    +.btn-outline-success.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-success.disabled,
    +.btn-outline-success:disabled {
    +  color: #28a745;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active,
    +.btn-outline-success:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-info {
    +  color: #fff;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:hover {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:focus,
    +.btn-outline-info.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-info.disabled,
    +.btn-outline-info:disabled {
    +  color: #17a2b8;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active,
    +.btn-outline-info:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-warning {
    +  color: #fff;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:hover {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:focus,
    +.btn-outline-warning.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-warning.disabled,
    +.btn-outline-warning:disabled {
    +  color: #ffc107;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active,
    +.btn-outline-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-danger {
    +  color: #fff;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:hover {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:focus,
    +.btn-outline-danger.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-danger.disabled,
    +.btn-outline-danger:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active,
    +.btn-outline-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-light {
    +  color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:hover {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:focus,
    +.btn-outline-light.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-light.disabled,
    +.btn-outline-light:disabled {
    +  color: #f8f9fa;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active,
    +.btn-outline-light:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-dark {
    +  color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:hover {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:focus,
    +.btn-outline-dark.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-outline-dark.disabled,
    +.btn-outline-dark:disabled {
    +  color: #343a40;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active,
    +.btn-outline-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-link {
    +  font-weight: 400;
    +  color: #007bff;
    +  text-decoration: none;
    +}
    +
    +.btn-link:hover {
    +  color: #0056b3;
    +  text-decoration: underline;
    +}
    +
    +.btn-link:focus,
    +.btn-link.focus {
    +  text-decoration: underline;
    +}
    +
    +.btn-link:disabled,
    +.btn-link.disabled {
    +  color: #6c757d;
    +  pointer-events: none;
    +}
    +
    +.btn-lg,
    +.btn-group-lg > .btn {
    +  padding: 0.5rem 1rem;
    +  font-size: 1.25rem;
    +  line-height: 1.5;
    +  border-radius: 0.3rem;
    +}
    +
    +.btn-sm,
    +.btn-group-sm > .btn {
    +  padding: 0.25rem 0.5rem;
    +  font-size: 0.875rem;
    +  line-height: 1.5;
    +  border-radius: 0.2rem;
    +}
    +
    +.btn-block {
    +  display: block;
    +  width: 100%;
    +}
    +
    +.btn-block + .btn-block {
    +  margin-top: 0.5rem;
    +}
    +
    +/* Prevents green disabled button */
    +
    +.btn-primary[disabled] {
    +  background-color: #007bff !important;
    +  opacity: 0.4;
    +}
    +
    +/* Manage disabled red */
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +/* some custom buttons design */
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +  box-shadow: inset 0 -1px 0 #ba202f;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +  box-shadow: inset 0 -1px 0 #e0a800;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +  box-shadow: inset 0 -1px 0 #138496;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  /*  background-color: #007bff;
    +        border-color: #007bff; */
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +/* Allow modals in simple xml dashboards */
    +.modal {
    +  display: none;
    +  margin-top: -1.5%;
    +}
    +
    +/* Some custom modal window sizes */
    +
    +.modal[class^="custom-modal"] {
    +  left: 50%;
    +  border: 1px solid green;
    +  margin-top: -1.5%;
    +}
    +
    +.custom-modal-30 {
    +  width: 30%;
    +  margin-left: -15%;
    +}
    +
    +.custom-modal-50 {
    +  width: 50%;
    +  margin-left: -25%;
    +}
    +
    +.custom-modal-60 {
    +  width: 60%;
    +  margin-left: -30%;
    +}
    +
    +.custom-modal-70 {
    +  width: 70%;
    +  margin-left: -35%;
    +}
    +
    +.custom-modal-80 {
    +  width: 80%;
    +  margin-left: -40%;
    +}
    +
    +.custom-modal-90 {
    +  width: 90%;
    +  margin-left: -45%;
    +}
    +
    +.custom-modal-96 {
    +  width: 96%;
    +  margin-left: -48%;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_filesystem_v2.js b/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_filesystem_v2.js
    new file mode 100644
    index 0000000..66939c8
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_filesystem_v2.js
    @@ -0,0 +1,818 @@
    +const { Callbacks, getJSON, get } = require("jquery");
    +
    +require([
    +  "jquery",
    +  "underscore",
    +  "splunkjs/mvc",
    +  "splunkjs/mvc/utils",
    +  "splunkjs/mvc/searchcontrolsview",
    +  "splunkjs/mvc/searchmanager",
    +  "splunkjs/mvc/postprocessmanager",
    +  "splunkjs/mvc/dropdownview",
    +  "splunkjs/mvc/multidropdownview",
    +  "splunkjs/mvc/tableview",
    +  "splunkjs/mvc/eventsviewerview",
    +  "splunkjs/mvc/textinputview",
    +  "splunkjs/mvc/singleview",
    +  "splunkjs/mvc/chartview",
    +  "splunkjs/mvc/resultslinkview",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/visualizationregistry",
    +  "splunkjs/mvc/simpleform/input/linklist",
    +  "splunkjs/mvc/simpleform/input/text",
    +  "splunkjs/mvc/simpleform/input/timerange",
    +  "splunkjs/mvc/simpleform/input/multiselect",
    +  "splunkjs/mvc/simpleform/input/dropdown",
    +  "splunkjs/mvc/simpleform/input/checkboxgroup",
    +  "splunkjs/mvc/simplexml/element/table",
    +  "splunkjs/mvc/simplexml/element/single",
    +  "splunkjs/mvc/simplexml/element/event",
    +  "splunkjs/mvc/simplexml/element/visualization",
    +  "splunkjs/mvc/simpleform/formutils",
    +  "splunkjs/mvc/simplexml/eventhandler",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/simplexml/ready!",
    +], function (
    +  $,
    +  _,
    +  mvc,
    +  utils,
    +  SearchControlsView,
    +  SearchManager,
    +  PostProcessManager,
    +  DropdownView,
    +  MultiDropdownView,
    +  TableView,
    +  EventsViewer,
    +  TextInputView,
    +  SingleView,
    +  ChartView,
    +  ResultsLinkView,
    +  SearchEventHandler,
    +  VisualizationRegistry,
    +  LinkListInput,
    +  TextInput,
    +  TimeRangeInput,
    +  MultiSelectInput,
    +  DropdownInput,
    +  CheckboxGroupInput,
    +  TableElement,
    +  VisualizationElement,
    +  SingleElement,
    +  EventElement,
    +  FormUtils,
    +  EventHandler,
    +  SearchEventHandler
    +) {
    +  //
    +  // START
    +  //
    +
    +  // tokens
    +
    +  var defaultTokenModel = mvc.Components.getInstance("default", {
    +    create: true,
    +  });
    +  var submittedTokenModel = mvc.Components.getInstance("submitted", {
    +    create: true,
    +  });
    +
    +  function setToken(name, value) {
    +    defaultTokenModel.set(name, value);
    +    submittedTokenModel.set(name, value);
    +  }
    +
    +  function getToken(name) {
    +    var ret = null;
    +    if (defaultTokenModel.get(name) != undefined) {
    +      ret = defaultTokenModel.get(name);
    +    } else if (submittedTokenModel.get(name) != undefined) {
    +      ret = submittedTokenModel.get(name);
    +    }
    +    return ret;
    +  }
    +
    +  function unsetToken(name) {
    +    defaultTokenModel.unset(name);
    +    submittedTokenModel.unset(name);
    +  }
    +
    +  // close all opened modals
    +  function closeModals() {
    +    $(".modal").modal("hide");
    +  }
    +
    +  // Returns true if numeric
    +  function isNumeric(n) {
    +    return !isNaN(parseFloat(n)) && isFinite(n) && n > 0;
    +  }
    +
    +  // searches
    +
    +  var search1 = new SearchManager(
    +    {
    +      id: "search1",
    +      earliest_time: "-24h",
    +      sample_ratio: 1,
    +      status_buckets: 0,
    +      cancelOnUnload: true,
    +      latest_time: "now",
    +      search: "| inputlookup nmon_alerting_threshold_filesystem | stats count",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search2 = new SearchManager(
    +    {
    +      id: "search2",
    +      earliest_time: "0",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_alerting_threshold_filesystem | eval KeyID=_key | search frameID=$input_inventory_search_frameid$ serialnum=$input_inventory_search_serialnum$ host=$input_inventory_search_host$ mount=$input_inventory_search_mount$",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search3 = new SearchManager(
    +    {
    +      id: "search3",
    +      earliest_time: "-7d",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_alerting_threshold_filesystem | stats dc(host) as dcount",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search4 = new SearchManager(
    +    {
    +      id: "search4",
    +      earliest_time: "-4h@m",
    +      latest_time: "now",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| `def_filesystem_inventory` | search frameID=$input_inventory_search_frameid$ serialnum=$input_inventory_search_serialnum$ host=$input_inventory_search_host$ mount=$input_inventory_search_mount$",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search5 = new SearchManager(
    +    {
    +      id: "search5",
    +      earliest_time: "-7d",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_alerting_threshold_filesystem | stats dc(mount) as dcount",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  function updateAllSearches() {
    +    search1.startSearch();
    +    search2.startSearch();
    +    search3.startSearch();
    +    search4.startSearch();
    +    search5.startSearch();
    +  }
    +
    +  // single views
    +
    +  var element_unset_exclusions = new SingleView(
    +    {
    +      id: "element_unset_exclusions",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of threshold configured",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search1",
    +      el: $("#element_unset_exclusions"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  var element_nb_hosts = new SingleView(
    +    {
    +      id: "element_nb_hosts",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of servers with threshold configured",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search3",
    +      el: $("#element_nb_hosts"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  var element_nb_mount = new SingleView(
    +    {
    +      id: "element_nb_mount",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of distinct mount points with threshold configured",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search5",
    +      el: $("#element_nb_mount"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  // link input
    +  var inputLink = new LinkListInput(
    +    {
    +      id: "inputLink",
    +      choices: [
    +        {
    +          value: "servers_inventory",
    +          label: "Servers inventory",
    +        },
    +        {
    +          value: "configured_thresholds",
    +          label: "Configured Thresholds",
    +        },
    +      ],
    +      default: "servers_inventory",
    +      searchWhenChanged: true,
    +      selectFirstChoice: false,
    +      initialValue: "servers_inventory",
    +      value: "$form.inputLink$",
    +      el: $("#inputLink"),
    +    },
    +    {
    +      tokens: true,
    +    }
    +  ).render();
    +
    +  inputLink.on("change", function (newValue) {
    +    setToken("inputLink", newValue);
    +  });
    +
    +  inputLink.on("valueChange", function (e) {
    +    if (e.value === "servers_inventory") {
    +      // show and hide elements
    +      $("#tableParent1").css("display", "inherit");
    +      $("#tableParent2").css("display", "none");
    +    } else if (e.value === "configured_thresholds") {
    +      // show and hide elements
    +      $("#tableParent1").css("display", "none");
    +      $("#tableParent2").css("display", "inherit");
    +    }
    +  });
    +
    +  // tables
    +
    +  var element_table_show_lookup_inventory = new TableElement(
    +    {
    +      id: "element_table_show_lookup_inventory",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "row",
    +      format: { "storage used (%)": [{ options: {}, type: "color" }] },
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search4",
    +      el: $("#element_table_show_lookup_inventory"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  element_table_show_lookup_inventory.on("click", function (e) {
    +    if (e.field !== undefined) {
    +      e.preventDefault();
    +      // Populate input form for addition
    +      setToken("tk_keyid", e.data["row.KeyID"]);
    +      setToken("form.input_add_frameid", e.data["row.frameID"]);
    +      setToken("form.input_add_serialnum", e.data["row.serialnum"]);
    +      setToken("form.input_add_host", e.data["row.host"]);
    +      setToken("form.input_add_mount", e.data["row.mount"]);
    +      $("#modal_add_entity").modal();
    +    }
    +  });
    +
    +  var element_table_show_lookup_content = new TableElement(
    +    {
    +      id: "element_table_show_lookup_content",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "row",
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search2",
    +      el: $("#element_table_show_lookup_content"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  element_table_show_lookup_content.on("click", function (e) {
    +    if (e.field !== undefined) {
    +      e.preventDefault();
    +      setToken("tk_keyid", e.data["row.KeyID"]);
    +      setToken("form.input_update_frameid", e.data["row.frameID"]);
    +      setToken("form.input_update_serialnum", e.data["row.serialnum"]);
    +      setToken("form.input_update_host", e.data["row.host"]);
    +      setToken("form.input_update_mount", e.data["row.mount"]);
    +      setToken(
    +        "form.input_update_alert_fs_max_percent",
    +        e.data["row.alert_fs_max_percent"]
    +      );
    +      setToken(
    +        "form.input_update_alert_fs_min_time_seconds",
    +        e.data["row.alert_fs_min_time_seconds"]
    +      );
    +      $("#modal_update_entity").modal();
    +    }
    +  });
    +
    +  // inventory searches
    +
    +  var input_inventory_search_frameid = new TextInput(
    +    {
    +      id: "input_inventory_search_frameid",
    +      value: "$form.input_inventory_search_frameid$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_inventory_search_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_inventory_search_frameid.on("change", function (newValue) {
    +    setToken("input_inventory_search_frameid", newValue);
    +  });
    +
    +  var input_inventory_search_serialnum = new TextInput(
    +    {
    +      id: "input_inventory_search_serialnum",
    +      value: "$form.input_inventory_search_serialnum$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_inventory_search_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_inventory_search_serialnum.on("change", function (newValue) {
    +    setToken("input_inventory_search_serialnum", newValue);
    +  });
    +
    +  var input_inventory_search_host = new TextInput(
    +    {
    +      id: "input_inventory_search_host",
    +      value: "$form.input_inventory_search_host$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_inventory_search_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_inventory_search_host.on("change", function (newValue) {
    +    setToken("input_inventory_search_host", newValue);
    +  });
    +
    +  var input_inventory_search_mount = new TextInput(
    +    {
    +      id: "input_inventory_search_mount",
    +      value: "$form.input_inventory_search_mount$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_inventory_search_mount"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_inventory_search_mount.on("change", function (newValue) {
    +    setToken("input_inventory_search_mount", newValue);
    +  });
    +
    +  // For additions
    +
    +  var input_add_frameid = new TextInput(
    +    {
    +      id: "input_add_frameid",
    +      value: "$form.input_add_frameid$",
    +      el: $("#input_add_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_frameid.on("change", function (newValue) {
    +    setToken("input_add_frameid", newValue);
    +  });
    +
    +  var input_add_serialnum = new TextInput(
    +    {
    +      id: "input_add_serialnum",
    +      value: "$form.input_add_serialnum$",
    +      el: $("#input_add_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_serialnum.on("change", function (newValue) {
    +    setToken("input_add_serialnum", newValue);
    +  });
    +
    +  var input_add_host = new TextInput(
    +    {
    +      id: "input_add_host",
    +      value: "$form.input_add_host$",
    +      el: $("#input_add_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_host.on("change", function (newValue) {
    +    setToken("input_add_host", newValue);
    +  });
    +
    +  var input_add_mount = new TextInput(
    +    {
    +      id: "input_add_mount",
    +      value: "$form.input_add_mount$",
    +      el: $("#input_add_mount"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_mount.on("change", function (newValue) {
    +    setToken("input_add_mount", newValue);
    +  });
    +
    +  var input_add_alert_fs_max_percent = new TextInput(
    +    {
    +      id: "input_add_alert_fs_max_percent",
    +      value: "$form.input_add_alert_fs_max_percent$",
    +      default: "90",
    +      el: $("#input_add_alert_fs_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_fs_max_percent.on("change", function (newValue) {
    +    setToken("input_add_alert_fs_max_percent", newValue);
    +  });
    +
    +  var input_add_alert_fs_min_time_seconds = new TextInput(
    +    {
    +      id: "input_add_alert_fs_min_time_seconds",
    +      value: "$form.input_add_alert_fs_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_add_alert_fs_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_fs_min_time_seconds.on("change", function (newValue) {
    +    setToken("input_add_alert_fs_min_time_seconds", newValue);
    +  });
    +
    +  // For update
    +
    +  var input_update_frameid = new TextInput(
    +    {
    +      id: "input_update_frameid",
    +      value: "$form.input_update_frameid$",
    +      el: $("#input_update_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_frameid.on("change", function (newValue) {
    +    setToken("input_update_frameid", newValue);
    +  });
    +
    +  var input_update_serialnum = new TextInput(
    +    {
    +      id: "input_update_serialnum",
    +      value: "$form.input_update_serialnum$",
    +      el: $("#input_update_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_serialnum.on("change", function (newValue) {
    +    setToken("input_update_serialnum", newValue);
    +  });
    +
    +  var input_update_host = new TextInput(
    +    {
    +      id: "input_update_host",
    +      value: "$form.input_update_host$",
    +      el: $("#input_update_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_host.on("change", function (newValue) {
    +    setToken("input_update_host", newValue);
    +  });
    +
    +  var input_update_mount = new TextInput(
    +    {
    +      id: "input_update_mount",
    +      value: "$form.input_update_mount$",
    +      el: $("#input_update_mount"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_mount.on("change", function (newValue) {
    +    setToken("input_update_mount", newValue);
    +  });
    +
    +  var input_update_alert_fs_max_percent = new TextInput(
    +    {
    +      id: "input_update_alert_fs_max_percent",
    +      value: "$form.input_update_alert_fs_max_percent$",
    +      default: "90",
    +      el: $("#input_update_alert_fs_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_fs_max_percent.on("change", function (newValue) {
    +    setToken("input_update_alert_fs_max_percent", newValue);
    +  });
    +
    +  var input_update_alert_fs_min_time_seconds = new TextInput(
    +    {
    +      id: "input_update_alert_fs_min_time_seconds",
    +      value: "$form.input_update_alert_fs_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_update_alert_fs_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_fs_min_time_seconds.on("change", function (newValue) {
    +    setToken("input_update_alert_fs_min_time_seconds", newValue);
    +  });
    +
    +  // interactions
    +
    +  // help
    +  $("#btn_help")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_help").modal();
    +    });
    +
    +  // add new entry
    +  $("#btn_add_new_template")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_add_entity").modal();
    +    });
    +
    +  // submit new entry
    +  $("#btn_submit_new_entity").click(function () {
    +    var frameID = getToken("input_add_frameid");
    +    var host = getToken("input_add_host");
    +    var serialnum = getToken("input_add_serialnum");
    +    var mount = getToken("input_add_mount");
    +    var alert_fs_max_percent = getToken("input_add_alert_fs_max_percent");
    +    var alert_fs_min_time_seconds = getToken(
    +      "input_add_alert_fs_min_time_seconds"
    +    );
    +
    +    // new record
    +    record = {
    +      frameID: frameID,
    +      host: host,
    +      serialnum: serialnum,
    +      mount: mount,
    +      alert_fs_max_percent: alert_fs_max_percent,
    +      alert_fs_min_time_seconds: alert_fs_min_time_seconds,
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_threshold_filesystem/";
    +
    +    if (
    +      frameID &&
    +      frameID.length &&
    +      host &&
    +      host.length &&
    +      serialnum &&
    +      serialnum.length &&
    +      mount &&
    +      mount.length &&
    +      alert_fs_max_percent &&
    +      alert_fs_max_percent.length &&
    +      isNumeric(alert_fs_max_percent) &&
    +      alert_fs_min_time_seconds &&
    +      alert_fs_min_time_seconds.length &&
    +      isNumeric(alert_fs_min_time_seconds)
    +    ) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  // delete entity
    +  $("#btn_submit_delete_entity").click(function () {
    +    var tk_keyid = getToken("tk_keyid");
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_threshold_filesystem/" +
    +      tk_keyid;
    +
    +    if (tk_keyid && tk_keyid.length) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "DELETE",
    +        async: true,
    +        contentType: "application/json",
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    }
    +  });
    +
    +  // update entry
    +  $("#btn_submit_update_entity").click(function () {
    +    var tk_keyid = getToken("tk_keyid");
    +    var frameID = getToken("input_update_frameid");
    +    var host = getToken("input_update_host");
    +    var serialnum = getToken("input_update_serialnum");
    +    var mount = getToken("input_update_mount");
    +    var alert_fs_max_percent = getToken("input_update_alert_fs_max_percent");
    +    var alert_fs_min_time_seconds = getToken(
    +      "input_update_alert_fs_min_time_seconds"
    +    );
    +
    +    // new record
    +    record = {
    +      frameID: frameID,
    +      host: host,
    +      serialnum: serialnum,
    +      mount: mount,
    +      alert_fs_max_percent: alert_fs_max_percent,
    +      alert_fs_min_time_seconds: alert_fs_min_time_seconds,
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_threshold_filesystem/" +
    +      tk_keyid;
    +
    +    if (
    +      frameID &&
    +      frameID.length &&
    +      host &&
    +      host.length &&
    +      serialnum &&
    +      serialnum.length &&
    +      mount &&
    +      mount.length &&
    +      alert_fs_max_percent &&
    +      alert_fs_max_percent.length &&
    +      isNumeric(alert_fs_max_percent) &&
    +      alert_fs_min_time_seconds &&
    +      alert_fs_min_time_seconds.length &&
    +      isNumeric(alert_fs_min_time_seconds)
    +    ) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  //
    +  // END
    +  //
    +});
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_table_bar.js b/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_table_bar.js
    new file mode 100644
    index 0000000..ff6ae4d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_table_bar.js
    @@ -0,0 +1,83 @@
    +require([
    +  "jquery",
    +  "underscore",
    +  "splunkjs/mvc",
    +  "views/shared/results_table/renderers/BaseCellRenderer",
    +  "splunkjs/mvc/simplexml/ready!",
    +], function ($, _, mvc, BaseCellRenderer) {
    +  // bar1
    +  var DataBarCellRenderer = BaseCellRenderer.extend({
    +    canRender: function (cell) {
    +      return cell.field === "max_cpu_percent";
    +    },
    +    render: function ($td, cell) {
    +      var pColor = "data-bar-under";
    +      if (cell.value > 15) {
    +        pColor = "data-bar-over";
    +      }
    +      $td.addClass("data-bar-cell").html(
    +        _.template(
    +          '<div class="data-bar-wrapper"><div class="data-bar <%- pColor %>" style="width:<%- percent %>%">&nbsp;<%- ppp %>%</div></div>',
    +          {
    +            percent: Math.min(Math.max(parseFloat(cell.value), 0), 100),
    +            ppp: parseFloat(cell.value).toFixed(2),
    +            pColor: pColor,
    +          }
    +        )
    +      );
    +    },
    +  });
    +  // bar2
    +  var DataBarCellRenderer2 = BaseCellRenderer.extend({
    +    canRender: function (cell) {
    +      return cell.field === "max_phy_percent";
    +    },
    +    render: function ($td, cell) {
    +      var pColor = "data-bar-under";
    +      if (cell.value > 15) {
    +        pColor = "data-bar-over";
    +      }
    +      $td.addClass("data-bar-cell").html(
    +        _.template(
    +          '<div class="data-bar-wrapper"><div class="data-bar <%- pColor %>" style="width:<%- percent %>%">&nbsp;<%- ppp %>%</div></div>',
    +          {
    +            percent: Math.min(Math.max(parseFloat(cell.value), 0), 100),
    +            ppp: parseFloat(cell.value).toFixed(2),
    +            pColor: pColor,
    +          }
    +        )
    +      );
    +    },
    +  });
    +  // bar3
    +  var DataBarCellRenderer3 = BaseCellRenderer.extend({
    +    canRender: function (cell) {
    +      return cell.field === "max_vir_percent";
    +    },
    +    render: function ($td, cell) {
    +      var pColor = "data-bar-under";
    +      if (cell.value > 15) {
    +        pColor = "data-bar-over";
    +      }
    +      $td.addClass("data-bar-cell").html(
    +        _.template(
    +          '<div class="data-bar-wrapper"><div class="data-bar <%- pColor %>" style="width:<%- percent %>%">&nbsp;<%- ppp %>%</div></div>',
    +          {
    +            percent: Math.min(Math.max(parseFloat(cell.value), 0), 100),
    +            ppp: parseFloat(cell.value).toFixed(2),
    +            pColor: pColor,
    +          }
    +        )
    +      );
    +    },
    +  });
    +
    +  mvc.Components.get("element_table_show_lookup_content").getVisualization(
    +    function (tableView) {
    +      tableView.table.addCellRenderer(new DataBarCellRenderer());
    +      tableView.table.addCellRenderer(new DataBarCellRenderer2());
    +      tableView.table.addCellRenderer(new DataBarCellRenderer3());
    +      tableView.table.render();
    +    }
    +  );
    +});
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_v2.css b/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_v2.css
    new file mode 100644
    index 0000000..2c67e0b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_v2.css
    @@ -0,0 +1,905 @@
    +/* Increase the default max-width for links */
    +.btn-pill {
    +  max-width: 600px !important;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-info h1 {
    +  color: #a7c7e7;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-success h1 {
    +  color: #77dd77;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-danger h1 {
    +  color: #ff6961;
    +}
    +
    +/* modal spl message */
    +.modal-spl-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/* modal success / info / error messages */
    +.modal-success-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-info-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-error-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: #ff6961;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/*** Buttons ***/
    +
    +.btn {
    +  background-color: black !important;
    +}
    +
    +.btn:hover {
    +  background-color: #31373e !important;
    +}
    +
    +/* fixes some UI issues in dark theme with bootstrap buttons */
    +button {
    +  background-color: transparent;
    +  border-width: inherit;
    +}
    +
    +/* Bootstrap btns */
    +
    +.btn-primary {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:hover {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +}
    +
    +.btn-primary:focus,
    +.btn-primary.focus {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-primary.disabled,
    +.btn-primary:disabled {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active,
    +.btn-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0062cc;
    +  border-color: #005cbf;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #117a8b;
    +  border-color: #10707f;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-success {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:hover {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +}
    +
    +.btn-success:focus,
    +.btn-success.focus {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-success.disabled,
    +.btn-success:disabled {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active,
    +.btn-success:not(:disabled):not(.disabled).active,
    +.show > .btn-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1e7e34;
    +  border-color: #1c7430;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active:focus,
    +.btn-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-light {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:hover {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +}
    +
    +.btn-light:focus,
    +.btn-light.focus {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-light.disabled,
    +.btn-light:disabled {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active,
    +.btn-light:not(:disabled):not(.disabled).active,
    +.show > .btn-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #dae0e5;
    +  border-color: #d3d9df;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active:focus,
    +.btn-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-dark {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:hover {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +}
    +
    +.btn-dark:focus,
    +.btn-dark.focus {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-dark.disabled,
    +.btn-dark:disabled {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active,
    +.btn-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1d2124;
    +  border-color: #171a1d;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-outline-primary {
    +  color: #fff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:hover {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:focus,
    +.btn-outline-primary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-primary.disabled,
    +.btn-outline-primary:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active,
    +.btn-outline-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-secondary {
    +  color: #fff;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:hover {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:focus,
    +.btn-outline-secondary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-secondary.disabled,
    +.btn-outline-secondary:disabled {
    +  color: #6c757d;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-secondary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-secondary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-success {
    +  color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:hover {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:focus,
    +.btn-outline-success.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-success.disabled,
    +.btn-outline-success:disabled {
    +  color: #28a745;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active,
    +.btn-outline-success:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-info {
    +  color: #fff;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:hover {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:focus,
    +.btn-outline-info.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-info.disabled,
    +.btn-outline-info:disabled {
    +  color: #17a2b8;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active,
    +.btn-outline-info:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-warning {
    +  color: #fff;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:hover {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:focus,
    +.btn-outline-warning.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-warning.disabled,
    +.btn-outline-warning:disabled {
    +  color: #ffc107;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active,
    +.btn-outline-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-danger {
    +  color: #fff;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:hover {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:focus,
    +.btn-outline-danger.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-danger.disabled,
    +.btn-outline-danger:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active,
    +.btn-outline-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-light {
    +  color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:hover {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:focus,
    +.btn-outline-light.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-light.disabled,
    +.btn-outline-light:disabled {
    +  color: #f8f9fa;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active,
    +.btn-outline-light:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-dark {
    +  color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:hover {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:focus,
    +.btn-outline-dark.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-outline-dark.disabled,
    +.btn-outline-dark:disabled {
    +  color: #343a40;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active,
    +.btn-outline-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-link {
    +  font-weight: 400;
    +  color: #007bff;
    +  text-decoration: none;
    +}
    +
    +.btn-link:hover {
    +  color: #0056b3;
    +  text-decoration: underline;
    +}
    +
    +.btn-link:focus,
    +.btn-link.focus {
    +  text-decoration: underline;
    +}
    +
    +.btn-link:disabled,
    +.btn-link.disabled {
    +  color: #6c757d;
    +  pointer-events: none;
    +}
    +
    +.btn-lg,
    +.btn-group-lg > .btn {
    +  padding: 0.5rem 1rem;
    +  font-size: 1.25rem;
    +  line-height: 1.5;
    +  border-radius: 0.3rem;
    +}
    +
    +.btn-sm,
    +.btn-group-sm > .btn {
    +  padding: 0.25rem 0.5rem;
    +  font-size: 0.875rem;
    +  line-height: 1.5;
    +  border-radius: 0.2rem;
    +}
    +
    +.btn-block {
    +  display: block;
    +  width: 100%;
    +}
    +
    +.btn-block + .btn-block {
    +  margin-top: 0.5rem;
    +}
    +
    +/* Prevents green disabled button */
    +
    +.btn-primary[disabled] {
    +  background-color: #007bff !important;
    +  opacity: 0.4;
    +}
    +
    +/* Manage disabled red */
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +/* some custom buttons design */
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +  box-shadow: inset 0 -1px 0 #ba202f;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +  box-shadow: inset 0 -1px 0 #e0a800;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +  box-shadow: inset 0 -1px 0 #138496;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  /*  background-color: #007bff;
    +          border-color: #007bff; */
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +/* Allow modals in simple xml dashboards */
    +.modal {
    +  display: none;
    +  margin-top: -1.5%;
    +}
    +
    +/* Some custom modal window sizes */
    +
    +.modal[class^="custom-modal"] {
    +  left: 50%;
    +  border: 1px solid green;
    +  margin-top: -1.5%;
    +}
    +
    +.custom-modal-30 {
    +  width: 30%;
    +  margin-left: -15%;
    +}
    +
    +.custom-modal-50 {
    +  width: 50%;
    +  margin-left: -25%;
    +}
    +
    +.custom-modal-60 {
    +  width: 60%;
    +  margin-left: -30%;
    +}
    +
    +.custom-modal-70 {
    +  width: 70%;
    +  margin-left: -35%;
    +}
    +
    +.custom-modal-80 {
    +  width: 80%;
    +  margin-left: -40%;
    +}
    +
    +.custom-modal-90 {
    +  width: 90%;
    +  margin-left: -45%;
    +}
    +
    +.custom-modal-96 {
    +  width: 96%;
    +  margin-left: -48%;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_v2.js b/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_v2.js
    new file mode 100644
    index 0000000..54070be
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_alerting_threshold_v2.js
    @@ -0,0 +1,969 @@
    +const { Callbacks, getJSON, get } = require("jquery");
    +
    +require([
    +  "jquery",
    +  "underscore",
    +  "splunkjs/mvc",
    +  "splunkjs/mvc/utils",
    +  "splunkjs/mvc/searchcontrolsview",
    +  "splunkjs/mvc/searchmanager",
    +  "splunkjs/mvc/postprocessmanager",
    +  "splunkjs/mvc/dropdownview",
    +  "splunkjs/mvc/multidropdownview",
    +  "splunkjs/mvc/tableview",
    +  "splunkjs/mvc/eventsviewerview",
    +  "splunkjs/mvc/textinputview",
    +  "splunkjs/mvc/singleview",
    +  "splunkjs/mvc/chartview",
    +  "splunkjs/mvc/resultslinkview",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/visualizationregistry",
    +  "splunkjs/mvc/simpleform/input/linklist",
    +  "splunkjs/mvc/simpleform/input/text",
    +  "splunkjs/mvc/simpleform/input/timerange",
    +  "splunkjs/mvc/simpleform/input/multiselect",
    +  "splunkjs/mvc/simpleform/input/dropdown",
    +  "splunkjs/mvc/simpleform/input/checkboxgroup",
    +  "splunkjs/mvc/simplexml/element/table",
    +  "splunkjs/mvc/simplexml/element/single",
    +  "splunkjs/mvc/simplexml/element/event",
    +  "splunkjs/mvc/simplexml/element/visualization",
    +  "splunkjs/mvc/simpleform/formutils",
    +  "splunkjs/mvc/simplexml/eventhandler",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/simplexml/ready!",
    +], function (
    +  $,
    +  _,
    +  mvc,
    +  utils,
    +  SearchControlsView,
    +  SearchManager,
    +  PostProcessManager,
    +  DropdownView,
    +  MultiDropdownView,
    +  TableView,
    +  EventsViewer,
    +  TextInputView,
    +  SingleView,
    +  ChartView,
    +  ResultsLinkView,
    +  SearchEventHandler,
    +  VisualizationRegistry,
    +  LinkListInput,
    +  TextInput,
    +  TimeRangeInput,
    +  MultiSelectInput,
    +  DropdownInput,
    +  CheckboxGroupInput,
    +  TableElement,
    +  VisualizationElement,
    +  SingleElement,
    +  EventElement,
    +  FormUtils,
    +  EventHandler,
    +  SearchEventHandler
    +) {
    +  //
    +  // START
    +  //
    +
    +  // tokens
    +
    +  var defaultTokenModel = mvc.Components.getInstance("default", {
    +    create: true,
    +  });
    +  var submittedTokenModel = mvc.Components.getInstance("submitted", {
    +    create: true,
    +  });
    +
    +  function setToken(name, value) {
    +    defaultTokenModel.set(name, value);
    +    submittedTokenModel.set(name, value);
    +  }
    +
    +  function getToken(name) {
    +    var ret = null;
    +    if (defaultTokenModel.get(name) != undefined) {
    +      ret = defaultTokenModel.get(name);
    +    } else if (submittedTokenModel.get(name) != undefined) {
    +      ret = submittedTokenModel.get(name);
    +    }
    +    return ret;
    +  }
    +
    +  function unsetToken(name) {
    +    defaultTokenModel.unset(name);
    +    submittedTokenModel.unset(name);
    +  }
    +
    +  // close all opened modals
    +  function closeModals() {
    +    $(".modal").modal("hide");
    +  }
    +
    +  // Returns true if numeric
    +  function isNumeric(n) {
    +    return !isNaN(parseFloat(n)) && isFinite(n) && n > 0;
    +  }
    +
    +  // searches
    +
    +  var search1 = new SearchManager(
    +    {
    +      id: "search1",
    +      earliest_time: "-5m",
    +      sample_ratio: 1,
    +      status_buckets: 0,
    +      cancelOnUnload: true,
    +      latest_time: "now",
    +      search: "| inputlookup nmon_alerting_threshold | stats count",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search2 = new SearchManager(
    +    {
    +      id: "search2",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_alerting_threshold | search frameID=$input_inventory_search_frameid$ serialnum=$input_inventory_search_serialnum$ host=$input_inventory_search_host$ | eval KeyID = _key | table KeyID,frameID,serialnum,host,* | eval max_cpu_percent=alert_cpu_max_percent, max_phy_percent=alert_physical_memory_max_percent, max_vir_percent=alert_virtual_memory_max_percent",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search3 = new SearchManager(
    +    {
    +      id: "search3",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_alerting_threshold | stats dc(host) as dcount",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search4 = new SearchManager(
    +    {
    +      id: "search4",
    +      earliest_time: "-24h",
    +      latest_time: "now",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| `def_mcatalog_mapped_nmon_inventory_with_main_kpis` | search frameID=$input_inventory_search_frameid$ serialnum=$input_inventory_search_serialnum$ host=$input_inventory_search_host$",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  function updateAllSearches() {
    +    search1.startSearch();
    +    search2.startSearch();
    +    search3.startSearch();
    +    search4.startSearch();
    +  }
    +
    +  // single views
    +
    +  var element_unset_exclusions = new SingleView(
    +    {
    +      id: "element_unset_exclusions",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of threshold configured",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search1",
    +      el: $("#element_unset_exclusions"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  var element_nb_hosts = new SingleView(
    +    {
    +      id: "element_nb_hosts",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of servers with threshold configured",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search3",
    +      el: $("#element_nb_hosts"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  // link input
    +  var inputLink = new LinkListInput(
    +    {
    +      id: "inputLink",
    +      choices: [
    +        {
    +          value: "servers_inventory",
    +          label: "Servers inventory",
    +        },
    +        {
    +          value: "configured_thresholds",
    +          label: "Configured Thresholds",
    +        },
    +      ],
    +      default: "servers_inventory",
    +      searchWhenChanged: true,
    +      selectFirstChoice: false,
    +      initialValue: "servers_inventory",
    +      value: "$form.inputLink$",
    +      el: $("#inputLink"),
    +    },
    +    {
    +      tokens: true,
    +    }
    +  ).render();
    +
    +  inputLink.on("change", function (newValue) {
    +    setToken("inputLink", newValue);
    +  });
    +
    +  inputLink.on("valueChange", function (e) {
    +    if (e.value === "servers_inventory") {
    +      // show and hide elements
    +      $("#tableParent1").css("display", "inherit");
    +      $("#tableParent2").css("display", "none");
    +    } else if (e.value === "configured_thresholds") {
    +      // show and hide elements
    +      $("#tableParent1").css("display", "none");
    +      $("#tableParent2").css("display", "inherit");
    +    }
    +  });
    +
    +  // tables
    +
    +  var element_table_show_lookup_inventory = new TableElement(
    +    {
    +      id: "element_table_show_lookup_inventory",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "row",
    +      format: {
    +        sparkline_physical_mem: [
    +          {
    +            options: {
    +              height: "25",
    +              lineWidth: "1",
    +              fillColor: "#CCDDFF",
    +              lineColor: "#5379af",
    +            },
    +            type: "sparkline",
    +          },
    +        ],
    +        sparkline_virtual_mem: [
    +          {
    +            options: {
    +              height: "25",
    +              lineWidth: "1",
    +              fillColor: "#CCDDFF",
    +              lineColor: "#5379af",
    +            },
    +            type: "sparkline",
    +          },
    +        ],
    +        cpu_sparkline: [
    +          {
    +            options: {
    +              height: "25",
    +              lineWidth: "1",
    +              fillColor: "#CCDDFF",
    +              lineColor: "#5379af",
    +            },
    +            type: "sparkline",
    +          },
    +        ],
    +      },
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search4",
    +      el: $("#element_table_show_lookup_inventory"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  element_table_show_lookup_inventory.on("click", function (e) {
    +    if (e.field !== undefined) {
    +      e.preventDefault();
    +      // Populate input form for addition
    +      setToken("tk_keyid", e.data["row.KeyID"]);
    +      setToken("form.input_add_frameid", e.data["row.frameID"]);
    +      setToken("form.input_add_serialnum", e.data["row.serialnum"]);
    +      setToken("form.input_add_host", e.data["row.host"]);
    +      setToken("form.input_add_mount", e.data["row.mount"]);
    +      $("#modal_add_entity").modal();
    +    }
    +  });
    +
    +  var element_table_show_lookup_content = new TableElement(
    +    {
    +      id: "element_table_show_lookup_content",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "row",
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search2",
    +      el: $("#element_table_show_lookup_content"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  element_table_show_lookup_content.on("click", function (e) {
    +    if (e.field !== undefined) {
    +      e.preventDefault();
    +      setToken("tk_keyid", e.data["row.KeyID"]);
    +      setToken("form.input_update_frameid", e.data["row.frameID"]);
    +      setToken("form.input_update_serialnum", e.data["row.serialnum"]);
    +      setToken("form.input_update_host", e.data["row.host"]);
    +      setToken(
    +        "form.input_update_alert_cpu_max_percent",
    +        e.data["row.alert_cpu_max_percent"]
    +      );
    +      setToken(
    +        "form.input_update_alert_cpu_min_time_seconds",
    +        e.data["row.alert_cpu_min_time_seconds"]
    +      );
    +      setToken(
    +        "form.input_update_alert_physical_memory_max_percent",
    +        e.data["row.alert_physical_memory_max_percent"]
    +      );
    +      setToken(
    +        "form.input_update_alert_physical_memory_min_time_seconds",
    +        e.data["row.alert_physical_memory_min_time_seconds"]
    +      );
    +      setToken(
    +        "form.input_update_alert_virtual_memory_max_percent",
    +        e.data["row.alert_virtual_memory_max_percent"]
    +      );
    +      setToken(
    +        "form.input_update_alert_virtual_memory_min_time_seconds",
    +        e.data["row.alert_virtual_memory_min_time_seconds"]
    +      );
    +      $("#modal_update_entity").modal();
    +    }
    +  });
    +
    +  // inventory searches
    +
    +  var input_inventory_search_frameid = new TextInput(
    +    {
    +      id: "input_inventory_search_frameid",
    +      value: "$form.input_inventory_search_frameid$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_inventory_search_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_inventory_search_frameid.on("change", function (newValue) {
    +    setToken("input_inventory_search_frameid", newValue);
    +  });
    +
    +  var input_inventory_search_serialnum = new TextInput(
    +    {
    +      id: "input_inventory_search_serialnum",
    +      value: "$form.input_inventory_search_serialnum$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_inventory_search_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_inventory_search_serialnum.on("change", function (newValue) {
    +    setToken("input_inventory_search_serialnum", newValue);
    +  });
    +
    +  var input_inventory_search_host = new TextInput(
    +    {
    +      id: "input_inventory_search_host",
    +      value: "$form.input_inventory_search_host$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_inventory_search_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_inventory_search_host.on("change", function (newValue) {
    +    setToken("input_inventory_search_host", newValue);
    +  });
    +
    +  // For additions
    +
    +  var input_add_frameid = new TextInput(
    +    {
    +      id: "input_add_frameid",
    +      value: "$form.input_add_frameid$",
    +      el: $("#input_add_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_frameid.on("change", function (newValue) {
    +    setToken("input_add_frameid", newValue);
    +  });
    +
    +  var input_add_serialnum = new TextInput(
    +    {
    +      id: "input_add_serialnum",
    +      value: "$form.input_add_serialnum$",
    +      el: $("#input_add_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_serialnum.on("change", function (newValue) {
    +    setToken("input_add_serialnum", newValue);
    +  });
    +
    +  var input_add_host = new TextInput(
    +    {
    +      id: "input_add_host",
    +      value: "$form.input_add_host$",
    +      el: $("#input_add_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_host.on("change", function (newValue) {
    +    setToken("input_add_host", newValue);
    +  });
    +
    +  var input_add_alert_cpu_max_percent = new TextInput(
    +    {
    +      id: "input_add_alert_cpu_max_percent",
    +      value: "$form.input_add_alert_cpu_max_percent$",
    +      default: "90",
    +      el: $("#input_add_alert_cpu_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_cpu_max_percent.on("change", function (newValue) {
    +    setToken("input_add_alert_cpu_max_percent", newValue);
    +  });
    +
    +  var input_add_alert_cpu_min_time_seconds = new TextInput(
    +    {
    +      id: "input_add_alert_cpu_min_time_seconds",
    +      value: "$form.input_add_alert_cpu_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_add_alert_cpu_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_cpu_min_time_seconds.on("change", function (newValue) {
    +    setToken("input_add_alert_cpu_min_time_seconds", newValue);
    +  });
    +
    +  var input_add_alert_physical_memory_max_percent = new TextInput(
    +    {
    +      id: "input_add_alert_physical_memory_max_percent",
    +      value: "$form.input_add_alert_physical_memory_max_percent$",
    +      default: "90",
    +      el: $("#input_add_alert_physical_memory_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_physical_memory_max_percent.on("change", function (newValue) {
    +    setToken("input_add_alert_physical_memory_max_percent", newValue);
    +  });
    +
    +  var input_add_alert_physical_memory_min_time_seconds = new TextInput(
    +    {
    +      id: "input_add_alert_physical_memory_min_time_seconds",
    +      value: "$form.input_add_alert_physical_memory_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_add_alert_physical_memory_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_physical_memory_min_time_seconds.on(
    +    "change",
    +    function (newValue) {
    +      setToken("input_add_alert_physical_memory_min_time_seconds", newValue);
    +    }
    +  );
    +
    +  var input_add_alert_virtual_memory_max_percent = new TextInput(
    +    {
    +      id: "input_add_alert_virtual_memory_max_percent",
    +      value: "$form.input_add_alert_virtual_memory_max_percent$",
    +      default: "40",
    +      el: $("#input_add_alert_virtual_memory_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_virtual_memory_max_percent.on("change", function (newValue) {
    +    setToken("input_add_alert_virtual_memory_max_percent", newValue);
    +  });
    +
    +  var input_add_alert_virtual_memory_min_time_seconds = new TextInput(
    +    {
    +      id: "input_add_alert_virtual_memory_min_time_seconds",
    +      value: "$form.input_add_alert_virtual_memory_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_add_alert_virtual_memory_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_virtual_memory_min_time_seconds.on(
    +    "change",
    +    function (newValue) {
    +      setToken("input_add_alert_virtual_memory_min_time_seconds", newValue);
    +    }
    +  );
    +
    +  // For update
    +
    +  var input_update_frameid = new TextInput(
    +    {
    +      id: "input_update_frameid",
    +      value: "$form.input_update_frameid$",
    +      el: $("#input_update_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_frameid.on("change", function (newValue) {
    +    setToken("input_update_frameid", newValue);
    +  });
    +
    +  var input_update_serialnum = new TextInput(
    +    {
    +      id: "input_update_serialnum",
    +      value: "$form.input_update_serialnum$",
    +      el: $("#input_update_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_serialnum.on("change", function (newValue) {
    +    setToken("input_update_serialnum", newValue);
    +  });
    +
    +  var input_update_host = new TextInput(
    +    {
    +      id: "input_update_host",
    +      value: "$form.input_update_host$",
    +      el: $("#input_update_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_host.on("change", function (newValue) {
    +    setToken("input_update_host", newValue);
    +  });
    +
    +  var input_update_alert_cpu_max_percent = new TextInput(
    +    {
    +      id: "input_update_alert_cpu_max_percent",
    +      value: "$form.input_update_alert_cpu_max_percent$",
    +      default: "90",
    +      el: $("#input_update_alert_cpu_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_cpu_max_percent.on("change", function (newValue) {
    +    setToken("input_update_alert_cpu_max_percent", newValue);
    +  });
    +
    +  var input_update_alert_cpu_min_time_seconds = new TextInput(
    +    {
    +      id: "input_update_alert_cpu_min_time_seconds",
    +      value: "$form.input_update_alert_cpu_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_update_alert_cpu_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_cpu_min_time_seconds.on("change", function (newValue) {
    +    setToken("input_update_alert_cpu_min_time_seconds", newValue);
    +  });
    +
    +  var input_update_alert_physical_memory_max_percent = new TextInput(
    +    {
    +      id: "input_update_alert_physical_memory_max_percent",
    +      value: "$form.input_update_alert_physical_memory_max_percent$",
    +      default: "90",
    +      el: $("#input_update_alert_physical_memory_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_physical_memory_max_percent.on(
    +    "change",
    +    function (newValue) {
    +      setToken("input_update_alert_physical_memory_max_percent", newValue);
    +    }
    +  );
    +
    +  var input_update_alert_physical_memory_min_time_seconds = new TextInput(
    +    {
    +      id: "input_update_alert_physical_memory_min_time_seconds",
    +      value: "$form.input_update_alert_physical_memory_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_update_alert_physical_memory_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_physical_memory_min_time_seconds.on(
    +    "change",
    +    function (newValue) {
    +      setToken("input_update_alert_physical_memory_min_time_seconds", newValue);
    +    }
    +  );
    +
    +  var input_update_alert_virtual_memory_max_percent = new TextInput(
    +    {
    +      id: "input_update_alert_virtual_memory_max_percent",
    +      value: "$form.input_update_alert_virtual_memory_max_percent$",
    +      default: "40",
    +      el: $("#input_update_alert_virtual_memory_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_virtual_memory_max_percent.on(
    +    "change",
    +    function (newValue) {
    +      setToken("input_update_alert_virtual_memory_max_percent", newValue);
    +    }
    +  );
    +
    +  var input_update_alert_virtual_memory_min_time_seconds = new TextInput(
    +    {
    +      id: "input_update_alert_virtual_memory_min_time_seconds",
    +      value: "$form.input_update_alert_virtual_memory_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_update_alert_virtual_memory_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_virtual_memory_min_time_seconds.on(
    +    "change",
    +    function (newValue) {
    +      setToken("input_update_alert_virtual_memory_min_time_seconds", newValue);
    +    }
    +  );
    +
    +  // interactions
    +
    +  // help
    +  $("#btn_help")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_help").modal();
    +    });
    +
    +  // add new entry
    +  $("#btn_add_new_template")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_add_entity").modal();
    +    });
    +
    +  // submit new entry
    +  $("#btn_submit_new_entity").click(function () {
    +    console.log("clicked");
    +    var frameID = getToken("input_add_frameid");
    +    var host = getToken("input_add_host");
    +    var serialnum = getToken("input_add_serialnum");
    +    var alert_cpu_max_percent = getToken("input_add_alert_cpu_max_percent");
    +    var alert_cpu_min_time_seconds = getToken(
    +      "input_add_alert_cpu_min_time_seconds"
    +    );
    +    var alert_physical_memory_max_percent = getToken(
    +      "input_add_alert_physical_memory_max_percent"
    +    );
    +    var alert_physical_memory_min_time_seconds = getToken(
    +      "input_add_alert_physical_memory_min_time_seconds"
    +    );
    +    var alert_virtual_memory_max_percent = getToken(
    +      "input_add_alert_virtual_memory_max_percent"
    +    );
    +    var alert_virtual_memory_min_time_seconds = getToken(
    +      "input_add_alert_virtual_memory_min_time_seconds"
    +    );
    +
    +    // new record
    +    record = {
    +      frameID: frameID,
    +      host: host,
    +      serialnum: serialnum,
    +      alert_cpu_max_percent: alert_cpu_max_percent,
    +      alert_cpu_min_time_seconds: alert_cpu_min_time_seconds,
    +      alert_physical_memory_max_percent: alert_physical_memory_max_percent,
    +      alert_physical_memory_min_time_seconds:
    +        alert_physical_memory_min_time_seconds,
    +      alert_virtual_memory_max_percent: alert_virtual_memory_max_percent,
    +      alert_virtual_memory_min_time_seconds:
    +        alert_virtual_memory_min_time_seconds,
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_threshold/";
    +
    +    if (
    +      frameID &&
    +      frameID.length &&
    +      host &&
    +      host.length &&
    +      serialnum &&
    +      serialnum.length &&
    +      alert_cpu_max_percent &&
    +      alert_cpu_max_percent.length &&
    +      isNumeric(alert_cpu_max_percent) &&
    +      alert_cpu_min_time_seconds &&
    +      alert_cpu_min_time_seconds.length &&
    +      isNumeric(alert_cpu_min_time_seconds) &&
    +      alert_physical_memory_max_percent &&
    +      alert_physical_memory_max_percent.length &&
    +      isNumeric(alert_physical_memory_max_percent) &&
    +      alert_physical_memory_min_time_seconds &&
    +      alert_physical_memory_min_time_seconds.length &&
    +      isNumeric(alert_physical_memory_min_time_seconds) &&
    +      alert_virtual_memory_max_percent &&
    +      alert_virtual_memory_max_percent.length &&
    +      isNumeric(alert_virtual_memory_max_percent) &&
    +      alert_virtual_memory_min_time_seconds &&
    +      alert_virtual_memory_min_time_seconds.length &&
    +      isNumeric(alert_virtual_memory_min_time_seconds)
    +    ) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  // delete entity
    +  $("#btn_submit_delete_entity").click(function () {
    +    console.log("clicked");
    +    var tk_keyid = getToken("tk_keyid");
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_threshold/" +
    +      tk_keyid;
    +
    +    if (tk_keyid && tk_keyid.length) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "DELETE",
    +        async: true,
    +        contentType: "application/json",
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    }
    +  });
    +
    +  // update entry
    +  $("#btn_submit_update_entity").click(function () {
    +    console.log("clicked");
    +    var tk_keyid = getToken("tk_keyid");
    +    var frameID = getToken("input_update_frameid");
    +    var host = getToken("input_update_host");
    +    var serialnum = getToken("input_update_serialnum");
    +    var alert_cpu_max_percent = getToken("input_update_alert_cpu_max_percent");
    +    var alert_cpu_min_time_seconds = getToken(
    +      "input_update_alert_cpu_min_time_seconds"
    +    );
    +    var alert_physical_memory_max_percent = getToken(
    +      "input_update_alert_physical_memory_max_percent"
    +    );
    +    var alert_physical_memory_min_time_seconds = getToken(
    +      "input_update_alert_physical_memory_min_time_seconds"
    +    );
    +    var alert_virtual_memory_max_percent = getToken(
    +      "input_update_alert_virtual_memory_max_percent"
    +    );
    +    var alert_virtual_memory_min_time_seconds = getToken(
    +      "input_update_alert_virtual_memory_min_time_seconds"
    +    );
    +
    +    // new record
    +    record = {
    +      frameID: frameID,
    +      host: host,
    +      serialnum: serialnum,
    +      alert_cpu_max_percent: alert_cpu_max_percent,
    +      alert_cpu_min_time_seconds: alert_cpu_min_time_seconds,
    +      alert_physical_memory_max_percent: alert_physical_memory_max_percent,
    +      alert_physical_memory_min_time_seconds:
    +        alert_physical_memory_min_time_seconds,
    +      alert_virtual_memory_max_percent: alert_virtual_memory_max_percent,
    +      alert_virtual_memory_min_time_seconds:
    +        alert_virtual_memory_min_time_seconds,
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_threshold/" +
    +      tk_keyid;
    +
    +    if (
    +      frameID &&
    +      frameID.length &&
    +      host &&
    +      host.length &&
    +      serialnum &&
    +      serialnum.length &&
    +      alert_cpu_max_percent &&
    +      alert_cpu_max_percent.length &&
    +      isNumeric(alert_cpu_max_percent) &&
    +      alert_cpu_min_time_seconds &&
    +      alert_cpu_min_time_seconds.length &&
    +      isNumeric(alert_cpu_min_time_seconds) &&
    +      alert_physical_memory_max_percent &&
    +      alert_physical_memory_max_percent.length &&
    +      isNumeric(alert_physical_memory_max_percent) &&
    +      alert_physical_memory_min_time_seconds &&
    +      alert_physical_memory_min_time_seconds.length &&
    +      isNumeric(alert_physical_memory_min_time_seconds) &&
    +      alert_virtual_memory_max_percent &&
    +      alert_virtual_memory_max_percent.length &&
    +      isNumeric(alert_virtual_memory_max_percent) &&
    +      alert_virtual_memory_min_time_seconds &&
    +      alert_virtual_memory_min_time_seconds.length &&
    +      isNumeric(alert_virtual_memory_min_time_seconds)
    +    ) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  //
    +  // END
    +  //
    +});
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_exclusion_v2.css b/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_exclusion_v2.css
    new file mode 100644
    index 0000000..79429ed
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_exclusion_v2.css
    @@ -0,0 +1,905 @@
    +/* Increase the default max-width for links */
    +.btn-pill {
    +  max-width: 600px !important;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-info h1 {
    +  color: #a7c7e7;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-success h1 {
    +  color: #77dd77;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-danger h1 {
    +  color: #ff6961;
    +}
    +
    +/* modal spl message */
    +.modal-spl-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/* modal success / info / error messages */
    +.modal-success-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-info-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-error-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: #ff6961;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/*** Buttons ***/
    +
    +.btn {
    +  background-color: black !important;
    +}
    +
    +.btn:hover {
    +  background-color: #31373e !important;
    +}
    +
    +/* fixes some UI issues in dark theme with bootstrap buttons */
    +button {
    +  background-color: transparent;
    +  border-width: inherit;
    +}
    +
    +/* Bootstrap btns */
    +
    +.btn-primary {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:hover {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +}
    +
    +.btn-primary:focus,
    +.btn-primary.focus {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-primary.disabled,
    +.btn-primary:disabled {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active,
    +.btn-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0062cc;
    +  border-color: #005cbf;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #117a8b;
    +  border-color: #10707f;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-success {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:hover {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +}
    +
    +.btn-success:focus,
    +.btn-success.focus {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-success.disabled,
    +.btn-success:disabled {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active,
    +.btn-success:not(:disabled):not(.disabled).active,
    +.show > .btn-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1e7e34;
    +  border-color: #1c7430;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active:focus,
    +.btn-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-light {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:hover {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +}
    +
    +.btn-light:focus,
    +.btn-light.focus {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-light.disabled,
    +.btn-light:disabled {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active,
    +.btn-light:not(:disabled):not(.disabled).active,
    +.show > .btn-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #dae0e5;
    +  border-color: #d3d9df;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active:focus,
    +.btn-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-dark {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:hover {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +}
    +
    +.btn-dark:focus,
    +.btn-dark.focus {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-dark.disabled,
    +.btn-dark:disabled {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active,
    +.btn-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1d2124;
    +  border-color: #171a1d;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-outline-primary {
    +  color: #fff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:hover {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:focus,
    +.btn-outline-primary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-primary.disabled,
    +.btn-outline-primary:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active,
    +.btn-outline-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-secondary {
    +  color: #fff;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:hover {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:focus,
    +.btn-outline-secondary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-secondary.disabled,
    +.btn-outline-secondary:disabled {
    +  color: #6c757d;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-secondary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-secondary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-success {
    +  color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:hover {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:focus,
    +.btn-outline-success.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-success.disabled,
    +.btn-outline-success:disabled {
    +  color: #28a745;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active,
    +.btn-outline-success:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-info {
    +  color: #fff;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:hover {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:focus,
    +.btn-outline-info.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-info.disabled,
    +.btn-outline-info:disabled {
    +  color: #17a2b8;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active,
    +.btn-outline-info:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-warning {
    +  color: #fff;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:hover {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:focus,
    +.btn-outline-warning.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-warning.disabled,
    +.btn-outline-warning:disabled {
    +  color: #ffc107;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active,
    +.btn-outline-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-danger {
    +  color: #fff;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:hover {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:focus,
    +.btn-outline-danger.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-danger.disabled,
    +.btn-outline-danger:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active,
    +.btn-outline-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-light {
    +  color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:hover {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:focus,
    +.btn-outline-light.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-light.disabled,
    +.btn-outline-light:disabled {
    +  color: #f8f9fa;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active,
    +.btn-outline-light:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-dark {
    +  color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:hover {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:focus,
    +.btn-outline-dark.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-outline-dark.disabled,
    +.btn-outline-dark:disabled {
    +  color: #343a40;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active,
    +.btn-outline-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-link {
    +  font-weight: 400;
    +  color: #007bff;
    +  text-decoration: none;
    +}
    +
    +.btn-link:hover {
    +  color: #0056b3;
    +  text-decoration: underline;
    +}
    +
    +.btn-link:focus,
    +.btn-link.focus {
    +  text-decoration: underline;
    +}
    +
    +.btn-link:disabled,
    +.btn-link.disabled {
    +  color: #6c757d;
    +  pointer-events: none;
    +}
    +
    +.btn-lg,
    +.btn-group-lg > .btn {
    +  padding: 0.5rem 1rem;
    +  font-size: 1.25rem;
    +  line-height: 1.5;
    +  border-radius: 0.3rem;
    +}
    +
    +.btn-sm,
    +.btn-group-sm > .btn {
    +  padding: 0.25rem 0.5rem;
    +  font-size: 0.875rem;
    +  line-height: 1.5;
    +  border-radius: 0.2rem;
    +}
    +
    +.btn-block {
    +  display: block;
    +  width: 100%;
    +}
    +
    +.btn-block + .btn-block {
    +  margin-top: 0.5rem;
    +}
    +
    +/* Prevents green disabled button */
    +
    +.btn-primary[disabled] {
    +  background-color: #007bff !important;
    +  opacity: 0.4;
    +}
    +
    +/* Manage disabled red */
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +/* some custom buttons design */
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +  box-shadow: inset 0 -1px 0 #ba202f;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +  box-shadow: inset 0 -1px 0 #e0a800;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +  box-shadow: inset 0 -1px 0 #138496;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  /*  background-color: #007bff;
    +        border-color: #007bff; */
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +/* Allow modals in simple xml dashboards */
    +.modal {
    +  display: none;
    +  margin-top: -1.5%;
    +}
    +
    +/* Some custom modal window sizes */
    +
    +.modal[class^="custom-modal"] {
    +  left: 50%;
    +  border: 1px solid green;
    +  margin-top: -1.5%;
    +}
    +
    +.custom-modal-30 {
    +  width: 30%;
    +  margin-left: -15%;
    +}
    +
    +.custom-modal-50 {
    +  width: 50%;
    +  margin-left: -25%;
    +}
    +
    +.custom-modal-60 {
    +  width: 60%;
    +  margin-left: -30%;
    +}
    +
    +.custom-modal-70 {
    +  width: 70%;
    +  margin-left: -35%;
    +}
    +
    +.custom-modal-80 {
    +  width: 80%;
    +  margin-left: -40%;
    +}
    +
    +.custom-modal-90 {
    +  width: 90%;
    +  margin-left: -45%;
    +}
    +
    +.custom-modal-96 {
    +  width: 96%;
    +  margin-left: -48%;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_exclusion_v2.js b/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_exclusion_v2.js
    new file mode 100644
    index 0000000..69777b5
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_exclusion_v2.js
    @@ -0,0 +1,737 @@
    +const { Callbacks, getJSON, get } = require("jquery");
    +
    +require([
    +  "jquery",
    +  "underscore",
    +  "splunkjs/mvc",
    +  "splunkjs/mvc/utils",
    +  "splunkjs/mvc/searchcontrolsview",
    +  "splunkjs/mvc/searchmanager",
    +  "splunkjs/mvc/postprocessmanager",
    +  "splunkjs/mvc/dropdownview",
    +  "splunkjs/mvc/multidropdownview",
    +  "splunkjs/mvc/tableview",
    +  "splunkjs/mvc/eventsviewerview",
    +  "splunkjs/mvc/textinputview",
    +  "splunkjs/mvc/singleview",
    +  "splunkjs/mvc/chartview",
    +  "splunkjs/mvc/resultslinkview",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/visualizationregistry",
    +  "splunkjs/mvc/simpleform/input/linklist",
    +  "splunkjs/mvc/simpleform/input/text",
    +  "splunkjs/mvc/simpleform/input/timerange",
    +  "splunkjs/mvc/simpleform/input/multiselect",
    +  "splunkjs/mvc/simpleform/input/dropdown",
    +  "splunkjs/mvc/simpleform/input/checkboxgroup",
    +  "splunkjs/mvc/simplexml/element/table",
    +  "splunkjs/mvc/simplexml/element/single",
    +  "splunkjs/mvc/simplexml/element/event",
    +  "splunkjs/mvc/simplexml/element/visualization",
    +  "splunkjs/mvc/simpleform/formutils",
    +  "splunkjs/mvc/simplexml/eventhandler",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/simplexml/ready!",
    +], function (
    +  $,
    +  _,
    +  mvc,
    +  utils,
    +  SearchControlsView,
    +  SearchManager,
    +  PostProcessManager,
    +  DropdownView,
    +  MultiDropdownView,
    +  TableView,
    +  EventsViewer,
    +  TextInputView,
    +  SingleView,
    +  ChartView,
    +  ResultsLinkView,
    +  SearchEventHandler,
    +  VisualizationRegistry,
    +  LinkListInput,
    +  TextInput,
    +  TimeRangeInput,
    +  MultiSelectInput,
    +  DropdownInput,
    +  CheckboxGroupInput,
    +  TableElement,
    +  VisualizationElement,
    +  SingleElement,
    +  EventElement,
    +  FormUtils,
    +  EventHandler,
    +  SearchEventHandler
    +) {
    +  //
    +  // START
    +  //
    +
    +  // tokens
    +
    +  var defaultTokenModel = mvc.Components.getInstance("default", {
    +    create: true,
    +  });
    +  var submittedTokenModel = mvc.Components.getInstance("submitted", {
    +    create: true,
    +  });
    +
    +  function setToken(name, value) {
    +    defaultTokenModel.set(name, value);
    +    submittedTokenModel.set(name, value);
    +  }
    +
    +  function getToken(name) {
    +    var ret = null;
    +    if (defaultTokenModel.get(name) != undefined) {
    +      ret = defaultTokenModel.get(name);
    +    } else if (submittedTokenModel.get(name) != undefined) {
    +      ret = submittedTokenModel.get(name);
    +    }
    +    return ret;
    +  }
    +
    +  function unsetToken(name) {
    +    defaultTokenModel.unset(name);
    +    submittedTokenModel.unset(name);
    +  }
    +
    +  // close all opened modals
    +  function closeModals() {
    +    $(".modal").modal("hide");
    +  }
    +
    +  // Returns true if numeric
    +  function isNumeric(n) {
    +    return !isNaN(parseFloat(n)) && isFinite(n) && n > 0;
    +  }
    +
    +  // searches
    +
    +  var search1 = new SearchManager(
    +    {
    +      id: "search1",
    +      earliest_time: "-5m",
    +      sample_ratio: 1,
    +      status_buckets: 0,
    +      cancelOnUnload: true,
    +      latest_time: "now",
    +      search:
    +        '| inputlookup nmon_alerting_filesystem_per_server_exclusion | where exclude="true" | stats count',
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search2 = new SearchManager(
    +    {
    +      id: "search2",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_alerting_filesystem_per_server_exclusion | search frameID=$input_inventory_search_frameid$ serialnum=$input_inventory_search_serialnum$ host=$input_inventory_search_host$ mount=$input_inventory_search_mount$ | eval KeyID = _key | table KeyID,frameID,serialnum,host,mount,exclude",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search3 = new SearchManager(
    +    {
    +      id: "search3",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        '| inputlookup nmon_alerting_filesystem_per_server_exclusion | where exclude="true" | stats dc(host) as dcount',
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search4 = new SearchManager(
    +    {
    +      id: "search4",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        '| inputlookup nmon_alerting_filesystem_per_server_exclusion | where exclude="true" | stats dc(mount) as dcount',
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search5 = new SearchManager(
    +    {
    +      id: "search5",
    +      earliest_time: "-7d",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| mcatalog values(dimension_mount) as mount values(dimension_filesystem) as filesystem where `nmon_metrics_index` metric_name=os.unix.nmon.storage.df_storage* host=* groupby host, serialnum, OStype | `mapping_frameID` | fields frameID, host, serialnum, OStype, mount, filesystem | search frameID=$input_inventory_search_frameid$ serialnum=$input_inventory_search_serialnum$ host=$input_inventory_search_host$ mount=$input_inventory_search_mount$",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  function updateAllSearches() {
    +    search1.startSearch();
    +    search2.startSearch();
    +    search3.startSearch();
    +    search4.startSearch();
    +    search5.startSearch();
    +  }
    +
    +  // single views
    +
    +  var element_unset_exclusions = new SingleView(
    +    {
    +      id: "element_unset_exclusions",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of file systems exclusion configured",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search1",
    +      el: $("#element_unset_exclusions"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  var element_nb_frameID = new SingleView(
    +    {
    +      id: "element_nb_frameID",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of distinct frameIDs excluded",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search4",
    +      el: $("#element_nb_frameID"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  var element_nb_mount = new SingleView(
    +    {
    +      id: "element_nb_mount",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of distinct mount points excluded",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search3",
    +      el: $("#element_nb_mount"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  // link input
    +  var inputLink = new LinkListInput(
    +    {
    +      id: "inputLink",
    +      choices: [
    +        {
    +          value: "servers_inventory",
    +          label: "Servers inventory",
    +        },
    +        {
    +          value: "configured_exclusions",
    +          label: "Configured Exclusions",
    +        },
    +      ],
    +      default: "servers_inventory",
    +      searchWhenChanged: true,
    +      selectFirstChoice: false,
    +      initialValue: "servers_inventory",
    +      value: "$form.inputLink$",
    +      el: $("#inputLink"),
    +    },
    +    {
    +      tokens: true,
    +    }
    +  ).render();
    +
    +  inputLink.on("change", function (newValue) {
    +    setToken("inputLink", newValue);
    +  });
    +
    +  inputLink.on("valueChange", function (e) {
    +    if (e.value === "servers_inventory") {
    +      // show and hide elements
    +      $("#tableParent1").css("display", "inherit");
    +      $("#tableParent2").css("display", "none");
    +    } else if (e.value === "configured_exclusions") {
    +      // show and hide elements
    +      $("#tableParent1").css("display", "none");
    +      $("#tableParent2").css("display", "inherit");
    +    }
    +  });
    +
    +  // tables
    +
    +  var element_table_show_lookup_inventory = new TableElement(
    +    {
    +      id: "element_table_show_lookup_inventory",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "row",
    +      format: { "storage used (%)": [{ options: {}, type: "color" }] },
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search5",
    +      el: $("#element_table_show_lookup_inventory"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  element_table_show_lookup_inventory.on("click", function (e) {
    +    if (e.field !== undefined) {
    +      e.preventDefault();
    +      // Populate input form for addition
    +      setToken("tk_keyid", e.data["row.KeyID"]);
    +      setToken("form.input_add_frameid", e.data["row.frameID"]);
    +      setToken("form.input_add_serialnum", e.data["row.serialnum"]);
    +      setToken("form.input_add_host", e.data["row.host"]);
    +      $("#modal_add_entity").modal();
    +    }
    +  });
    +
    +  var element_table_show_lookup_content = new TableElement(
    +    {
    +      id: "element_table_show_lookup_content",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "row",
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search2",
    +      el: $("#element_table_show_lookup_content"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  element_table_show_lookup_content.on("click", function (e) {
    +    if (e.field !== undefined) {
    +      e.preventDefault();
    +      // set tk_keyid
    +      setToken("tk_keyid", e.data["row.KeyID"]);
    +      // Populate input forms
    +      setToken("form.input_update_frameid", e.data["row.frameID"]);
    +      setToken("form.input_update_serialnum", e.data["row.serialnum"]);
    +      setToken("form.input_update_host", e.data["row.host"]);
    +      setToken("form.input_update_mount", e.data["row.mount"]);
    +      // open modal
    +      $("#modal_update_entity").modal();
    +    }
    +  });
    +
    +  // inventory searches
    +
    +  var input_inventory_search_frameid = new TextInput(
    +    {
    +      id: "input_inventory_search_frameid",
    +      value: "$form.input_inventory_search_frameid$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_inventory_search_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_inventory_search_frameid.on("change", function (newValue) {
    +    setToken("input_inventory_search_frameid", newValue);
    +  });
    +
    +  var input_inventory_search_serialnum = new TextInput(
    +    {
    +      id: "input_inventory_search_serialnum",
    +      value: "$form.input_inventory_search_serialnum$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_inventory_search_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_inventory_search_serialnum.on("change", function (newValue) {
    +    setToken("input_inventory_search_serialnum", newValue);
    +  });
    +
    +  var input_inventory_search_host = new TextInput(
    +    {
    +      id: "input_inventory_search_host",
    +      value: "$form.input_inventory_search_host$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_inventory_search_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_inventory_search_host.on("change", function (newValue) {
    +    setToken("input_inventory_search_host", newValue);
    +  });
    +
    +  var input_inventory_search_mount = new TextInput(
    +    {
    +      id: "input_inventory_search_mount",
    +      value: "$form.input_inventory_search_mount$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_inventory_search_mount"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_inventory_search_mount.on("change", function (newValue) {
    +    setToken("input_inventory_search_mount", newValue);
    +  });
    +
    +  // For additions
    +
    +  var input_add_frameid = new TextInput(
    +    {
    +      id: "input_add_frameid",
    +      value: "$form.input_add_frameid$",
    +      el: $("#input_add_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_frameid.on("change", function (newValue) {
    +    setToken("input_add_frameid", newValue);
    +  });
    +
    +  var input_add_serialnum = new TextInput(
    +    {
    +      id: "input_add_serialnum",
    +      value: "$form.input_add_serialnum$",
    +      el: $("#input_add_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_serialnum.on("change", function (newValue) {
    +    setToken("input_add_serialnum", newValue);
    +  });
    +
    +  var input_add_host = new TextInput(
    +    {
    +      id: "input_add_host",
    +      value: "$form.input_add_host$",
    +      el: $("#input_add_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_host.on("change", function (newValue) {
    +    setToken("input_add_host", newValue);
    +  });
    +
    +  var input_add_mount = new TextInput(
    +    {
    +      id: "input_add_mount",
    +      value: "$form.input_add_mount$",
    +      el: $("#input_add_mount"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_mount.on("change", function (newValue) {
    +    setToken("input_add_mount", newValue);
    +  });
    +
    +  // For update
    +
    +  var input_update_frameid = new TextInput(
    +    {
    +      id: "input_update_frameid",
    +      value: "$form.input_update_frameid$",
    +      el: $("#input_update_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_frameid.on("change", function (newValue) {
    +    setToken("input_update_frameid", newValue);
    +  });
    +
    +  var input_update_serialnum = new TextInput(
    +    {
    +      id: "input_update_serialnum",
    +      value: "$form.input_update_serialnum$",
    +      el: $("#input_update_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_serialnum.on("change", function (newValue) {
    +    setToken("input_update_serialnum", newValue);
    +  });
    +
    +  var input_update_host = new TextInput(
    +    {
    +      id: "input_update_host",
    +      value: "$form.input_update_host$",
    +      el: $("#input_update_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_host.on("change", function (newValue) {
    +    setToken("input_update_host", newValue);
    +  });
    +
    +  var input_update_mount = new TextInput(
    +    {
    +      id: "input_update_mount",
    +      value: "$form.input_update_mount$",
    +      el: $("#input_update_mount"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_mount.on("change", function (newValue) {
    +    setToken("input_update_mount", newValue);
    +  });
    +
    +  // interactions
    +
    +  // help
    +  $("#btn_help")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_help").modal();
    +    });
    +
    +  // add new entry
    +  $("#btn_add_new_template")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_add_entity").modal();
    +    });
    +
    +  // submit new entry
    +  $("#btn_submit_new_entity").click(function () {
    +    console.log("clicked");
    +    var frameID = getToken("input_add_frameid");
    +    var host = getToken("input_add_host");
    +    var serialnum = getToken("input_add_serialnum");
    +    var mount = getToken("input_add_mount");
    +
    +    // new record
    +    record = {
    +      frameID: frameID,
    +      host: host,
    +      serialnum: serialnum,
    +      mount: mount,
    +      exclude: "true",
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_filesystem_per_server_exclusion/";
    +
    +    if (
    +      frameID &&
    +      frameID.length &&
    +      host &&
    +      host.length &&
    +      serialnum &&
    +      serialnum.length &&
    +      mount &&
    +      mount.length
    +    ) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  // delete entity
    +  $("#btn_submit_delete_entity").click(function () {
    +    console.log("clicked");
    +    var tk_keyid = getToken("tk_keyid");
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_filesystem_per_server_exclusion/" +
    +      tk_keyid;
    +
    +    if (tk_keyid && tk_keyid.length) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "DELETE",
    +        async: true,
    +        contentType: "application/json",
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    }
    +  });
    +
    +  // update entry
    +  $("#btn_submit_update_entity").click(function () {
    +    console.log("clicked");
    +    var tk_keyid = getToken("tk_keyid");
    +    var frameID = getToken("input_update_frameid");
    +    var host = getToken("input_update_host");
    +    var serialnum = getToken("input_update_serialnum");
    +    var mount = getToken("input_update_mount");
    +
    +    // new record
    +    record = {
    +      frameID: frameID,
    +      host: host,
    +      serialnum: serialnum,
    +      mount: mount,
    +      exclude: "true",
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_filesystem_per_server_exclusion/" +
    +      tk_keyid;
    +
    +    if (
    +      frameID &&
    +      frameID.length &&
    +      host &&
    +      host.length &&
    +      serialnum &&
    +      serialnum.length &&
    +      mount &&
    +      mount.length
    +    ) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  //
    +  // END
    +  //
    +});
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_global_exclusion_v2.css b/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_global_exclusion_v2.css
    new file mode 100644
    index 0000000..79429ed
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_global_exclusion_v2.css
    @@ -0,0 +1,905 @@
    +/* Increase the default max-width for links */
    +.btn-pill {
    +  max-width: 600px !important;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-info h1 {
    +  color: #a7c7e7;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-success h1 {
    +  color: #77dd77;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-danger h1 {
    +  color: #ff6961;
    +}
    +
    +/* modal spl message */
    +.modal-spl-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/* modal success / info / error messages */
    +.modal-success-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-info-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-error-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: #ff6961;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/*** Buttons ***/
    +
    +.btn {
    +  background-color: black !important;
    +}
    +
    +.btn:hover {
    +  background-color: #31373e !important;
    +}
    +
    +/* fixes some UI issues in dark theme with bootstrap buttons */
    +button {
    +  background-color: transparent;
    +  border-width: inherit;
    +}
    +
    +/* Bootstrap btns */
    +
    +.btn-primary {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:hover {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +}
    +
    +.btn-primary:focus,
    +.btn-primary.focus {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-primary.disabled,
    +.btn-primary:disabled {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active,
    +.btn-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0062cc;
    +  border-color: #005cbf;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #117a8b;
    +  border-color: #10707f;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-success {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:hover {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +}
    +
    +.btn-success:focus,
    +.btn-success.focus {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-success.disabled,
    +.btn-success:disabled {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active,
    +.btn-success:not(:disabled):not(.disabled).active,
    +.show > .btn-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1e7e34;
    +  border-color: #1c7430;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active:focus,
    +.btn-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-light {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:hover {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +}
    +
    +.btn-light:focus,
    +.btn-light.focus {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-light.disabled,
    +.btn-light:disabled {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active,
    +.btn-light:not(:disabled):not(.disabled).active,
    +.show > .btn-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #dae0e5;
    +  border-color: #d3d9df;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active:focus,
    +.btn-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-dark {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:hover {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +}
    +
    +.btn-dark:focus,
    +.btn-dark.focus {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-dark.disabled,
    +.btn-dark:disabled {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active,
    +.btn-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1d2124;
    +  border-color: #171a1d;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-outline-primary {
    +  color: #fff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:hover {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:focus,
    +.btn-outline-primary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-primary.disabled,
    +.btn-outline-primary:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active,
    +.btn-outline-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-secondary {
    +  color: #fff;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:hover {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:focus,
    +.btn-outline-secondary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-secondary.disabled,
    +.btn-outline-secondary:disabled {
    +  color: #6c757d;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-secondary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-secondary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-success {
    +  color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:hover {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:focus,
    +.btn-outline-success.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-success.disabled,
    +.btn-outline-success:disabled {
    +  color: #28a745;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active,
    +.btn-outline-success:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-info {
    +  color: #fff;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:hover {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:focus,
    +.btn-outline-info.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-info.disabled,
    +.btn-outline-info:disabled {
    +  color: #17a2b8;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active,
    +.btn-outline-info:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-warning {
    +  color: #fff;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:hover {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:focus,
    +.btn-outline-warning.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-warning.disabled,
    +.btn-outline-warning:disabled {
    +  color: #ffc107;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active,
    +.btn-outline-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-danger {
    +  color: #fff;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:hover {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:focus,
    +.btn-outline-danger.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-danger.disabled,
    +.btn-outline-danger:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active,
    +.btn-outline-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-light {
    +  color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:hover {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:focus,
    +.btn-outline-light.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-light.disabled,
    +.btn-outline-light:disabled {
    +  color: #f8f9fa;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active,
    +.btn-outline-light:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-dark {
    +  color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:hover {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:focus,
    +.btn-outline-dark.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-outline-dark.disabled,
    +.btn-outline-dark:disabled {
    +  color: #343a40;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active,
    +.btn-outline-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-link {
    +  font-weight: 400;
    +  color: #007bff;
    +  text-decoration: none;
    +}
    +
    +.btn-link:hover {
    +  color: #0056b3;
    +  text-decoration: underline;
    +}
    +
    +.btn-link:focus,
    +.btn-link.focus {
    +  text-decoration: underline;
    +}
    +
    +.btn-link:disabled,
    +.btn-link.disabled {
    +  color: #6c757d;
    +  pointer-events: none;
    +}
    +
    +.btn-lg,
    +.btn-group-lg > .btn {
    +  padding: 0.5rem 1rem;
    +  font-size: 1.25rem;
    +  line-height: 1.5;
    +  border-radius: 0.3rem;
    +}
    +
    +.btn-sm,
    +.btn-group-sm > .btn {
    +  padding: 0.25rem 0.5rem;
    +  font-size: 0.875rem;
    +  line-height: 1.5;
    +  border-radius: 0.2rem;
    +}
    +
    +.btn-block {
    +  display: block;
    +  width: 100%;
    +}
    +
    +.btn-block + .btn-block {
    +  margin-top: 0.5rem;
    +}
    +
    +/* Prevents green disabled button */
    +
    +.btn-primary[disabled] {
    +  background-color: #007bff !important;
    +  opacity: 0.4;
    +}
    +
    +/* Manage disabled red */
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +/* some custom buttons design */
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +  box-shadow: inset 0 -1px 0 #ba202f;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +  box-shadow: inset 0 -1px 0 #e0a800;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +  box-shadow: inset 0 -1px 0 #138496;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  /*  background-color: #007bff;
    +        border-color: #007bff; */
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +/* Allow modals in simple xml dashboards */
    +.modal {
    +  display: none;
    +  margin-top: -1.5%;
    +}
    +
    +/* Some custom modal window sizes */
    +
    +.modal[class^="custom-modal"] {
    +  left: 50%;
    +  border: 1px solid green;
    +  margin-top: -1.5%;
    +}
    +
    +.custom-modal-30 {
    +  width: 30%;
    +  margin-left: -15%;
    +}
    +
    +.custom-modal-50 {
    +  width: 50%;
    +  margin-left: -25%;
    +}
    +
    +.custom-modal-60 {
    +  width: 60%;
    +  margin-left: -30%;
    +}
    +
    +.custom-modal-70 {
    +  width: 70%;
    +  margin-left: -35%;
    +}
    +
    +.custom-modal-80 {
    +  width: 80%;
    +  margin-left: -40%;
    +}
    +
    +.custom-modal-90 {
    +  width: 90%;
    +  margin-left: -45%;
    +}
    +
    +.custom-modal-96 {
    +  width: 96%;
    +  margin-left: -48%;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_global_exclusion_v2.js b/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_global_exclusion_v2.js
    new file mode 100644
    index 0000000..6f24a9e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_global_exclusion_v2.js
    @@ -0,0 +1,447 @@
    +const { Callbacks, getJSON, get } = require("jquery");
    +
    +require([
    +  "jquery",
    +  "underscore",
    +  "splunkjs/mvc",
    +  "splunkjs/mvc/utils",
    +  "splunkjs/mvc/searchcontrolsview",
    +  "splunkjs/mvc/searchmanager",
    +  "splunkjs/mvc/postprocessmanager",
    +  "splunkjs/mvc/dropdownview",
    +  "splunkjs/mvc/multidropdownview",
    +  "splunkjs/mvc/tableview",
    +  "splunkjs/mvc/eventsviewerview",
    +  "splunkjs/mvc/textinputview",
    +  "splunkjs/mvc/singleview",
    +  "splunkjs/mvc/chartview",
    +  "splunkjs/mvc/resultslinkview",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/visualizationregistry",
    +  "splunkjs/mvc/simpleform/input/linklist",
    +  "splunkjs/mvc/simpleform/input/text",
    +  "splunkjs/mvc/simpleform/input/timerange",
    +  "splunkjs/mvc/simpleform/input/multiselect",
    +  "splunkjs/mvc/simpleform/input/dropdown",
    +  "splunkjs/mvc/simpleform/input/checkboxgroup",
    +  "splunkjs/mvc/simplexml/element/table",
    +  "splunkjs/mvc/simplexml/element/single",
    +  "splunkjs/mvc/simplexml/element/event",
    +  "splunkjs/mvc/simplexml/element/visualization",
    +  "splunkjs/mvc/simpleform/formutils",
    +  "splunkjs/mvc/simplexml/eventhandler",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/simplexml/ready!",
    +], function (
    +  $,
    +  _,
    +  mvc,
    +  utils,
    +  SearchControlsView,
    +  SearchManager,
    +  PostProcessManager,
    +  DropdownView,
    +  MultiDropdownView,
    +  TableView,
    +  EventsViewer,
    +  TextInputView,
    +  SingleView,
    +  ChartView,
    +  ResultsLinkView,
    +  SearchEventHandler,
    +  VisualizationRegistry,
    +  LinkListInput,
    +  TextInput,
    +  TimeRangeInput,
    +  MultiSelectInput,
    +  DropdownInput,
    +  CheckboxGroupInput,
    +  TableElement,
    +  VisualizationElement,
    +  SingleElement,
    +  EventElement,
    +  FormUtils,
    +  EventHandler,
    +  SearchEventHandler
    +) {
    +  //
    +  // START
    +  //
    +
    +  // tokens
    +
    +  var defaultTokenModel = mvc.Components.getInstance("default", {
    +    create: true,
    +  });
    +  var submittedTokenModel = mvc.Components.getInstance("submitted", {
    +    create: true,
    +  });
    +
    +  function setToken(name, value) {
    +    defaultTokenModel.set(name, value);
    +    submittedTokenModel.set(name, value);
    +  }
    +
    +  function getToken(name) {
    +    var ret = null;
    +    if (defaultTokenModel.get(name) != undefined) {
    +      ret = defaultTokenModel.get(name);
    +    } else if (submittedTokenModel.get(name) != undefined) {
    +      ret = submittedTokenModel.get(name);
    +    }
    +    return ret;
    +  }
    +
    +  function unsetToken(name) {
    +    defaultTokenModel.unset(name);
    +    submittedTokenModel.unset(name);
    +  }
    +
    +  // close all opened modals
    +  function closeModals() {
    +    $(".modal").modal("hide");
    +  }
    +
    +  // Returns true if numeric
    +  function isNumeric(n) {
    +    return !isNaN(parseFloat(n)) && isFinite(n) && n > 0;
    +  }
    +
    +  // searches
    +
    +  var search1 = new SearchManager(
    +    {
    +      id: "search1",
    +      earliest_time: "-5m",
    +      sample_ratio: 1,
    +      status_buckets: 0,
    +      cancelOnUnload: true,
    +      latest_time: "now",
    +      search:
    +        '| inputlookup nmon_alerting_filesystem_global_exclusion | where exclude="true" | stats count',
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search2 = new SearchManager(
    +    {
    +      id: "search2",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_alerting_filesystem_global_exclusion | search mount=$search_mount$ | eval KeyID = _key | table KeyID,mount,exclude",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search3 = new SearchManager(
    +    {
    +      id: "search3",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        '| inputlookup nmon_alerting_filesystem_global_exclusion | where exclude="true" | stats dc(mount) as dcount',
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  function updateAllSearches() {
    +    search1.startSearch();
    +    search2.startSearch();
    +    search3.startSearch();
    +  }
    +
    +  // single views
    +
    +  var element_unset_exclusions = new SingleView(
    +    {
    +      id: "element_unset_exclusions",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of file systems exclusion configured",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search1",
    +      el: $("#element_unset_exclusions"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  var element_nb_mount = new SingleView(
    +    {
    +      id: "element_nb_mount",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of distinct mount points excluded",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search3",
    +      el: $("#element_nb_mount"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  // tables
    +
    +  var element_table_show_lookup_content = new TableElement(
    +    {
    +      id: "element_table_show_lookup_content",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "row",
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search2",
    +      el: $("#element_table_show_lookup_content"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  element_table_show_lookup_content.on("click", function (e) {
    +    if (e.field !== undefined) {
    +      e.preventDefault();
    +      // set tk_keyid
    +      setToken("tk_keyid", e.data["row.KeyID"]);
    +      // Populate input forms
    +      setToken("form.input_update_mount", e.data["row.mount"]);
    +      // open modal
    +      $("#modal_update_entity").modal();
    +    }
    +  });
    +
    +  // inputs for template search purposes
    +
    +  var input_search_mount = new TextInput(
    +    {
    +      id: "input_search_mount",
    +      value: "$form.search_mount$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_search_mount"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_search_mount.on("change", function (newValue) {
    +    setToken("search_mount", newValue);
    +  });
    +
    +  // add new entries
    +
    +  var input_add_mount = new TextInput(
    +    {
    +      id: "input_add_mount",
    +      value: "$form.input_add_mount$",
    +      el: $("#input_add_mount"),
    +      width: 300,
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_mount.on("change", function (newValue) {
    +    setToken("input_add_mount", newValue);
    +  });
    +
    +  // update entries
    +  var input_update_mount = new TextInput(
    +    {
    +      id: "input_update_mount",
    +      value: "$form.input_update_mount$",
    +      el: $("#input_update_mount"),
    +      width: 300,
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_mount.on("change", function (newValue) {
    +    setToken("input_update_mount", newValue);
    +  });
    +
    +  // interactions
    +
    +  // help
    +  $("#btn_help")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_help").modal();
    +    });
    +
    +  // add new entry
    +  $("#btn_add_new_template")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_add_entity").modal();
    +    });
    +
    +  // submit new entry
    +  $("#btn_submit_new_entity").click(function () {
    +    var mount = getToken("input_add_mount");
    +
    +    // new record
    +    record = {
    +      mount: mount,
    +      exclude: "true",
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_filesystem_global_exclusion/";
    +
    +    if (mount && mount.length) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  // delete entity
    +  $("#btn_submit_delete_entity").click(function () {
    +    var tk_keyid = getToken("tk_keyid");
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_filesystem_global_exclusion/" +
    +      tk_keyid;
    +
    +    if (tk_keyid && tk_keyid.length) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "DELETE",
    +        async: true,
    +        contentType: "application/json",
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    }
    +  });
    +
    +  // update entry
    +  $("#btn_submit_update_entity").click(function () {
    +    var tk_keyid = getToken("tk_keyid");
    +    var mount = getToken("input_update_mount");
    +
    +    // new record
    +    record = {
    +      mount: mount,
    +      exclude: "true",
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_filesystem_global_exclusion/" +
    +      tk_keyid;
    +
    +    if (mount && mount.length) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  //
    +  // END
    +  //
    +});
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_template_exclusion_v2.css b/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_template_exclusion_v2.css
    new file mode 100644
    index 0000000..79429ed
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_template_exclusion_v2.css
    @@ -0,0 +1,905 @@
    +/* Increase the default max-width for links */
    +.btn-pill {
    +  max-width: 600px !important;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-info h1 {
    +  color: #a7c7e7;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-success h1 {
    +  color: #77dd77;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-danger h1 {
    +  color: #ff6961;
    +}
    +
    +/* modal spl message */
    +.modal-spl-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/* modal success / info / error messages */
    +.modal-success-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-info-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-error-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: #ff6961;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/*** Buttons ***/
    +
    +.btn {
    +  background-color: black !important;
    +}
    +
    +.btn:hover {
    +  background-color: #31373e !important;
    +}
    +
    +/* fixes some UI issues in dark theme with bootstrap buttons */
    +button {
    +  background-color: transparent;
    +  border-width: inherit;
    +}
    +
    +/* Bootstrap btns */
    +
    +.btn-primary {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:hover {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +}
    +
    +.btn-primary:focus,
    +.btn-primary.focus {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-primary.disabled,
    +.btn-primary:disabled {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active,
    +.btn-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0062cc;
    +  border-color: #005cbf;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #117a8b;
    +  border-color: #10707f;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-success {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:hover {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +}
    +
    +.btn-success:focus,
    +.btn-success.focus {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-success.disabled,
    +.btn-success:disabled {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active,
    +.btn-success:not(:disabled):not(.disabled).active,
    +.show > .btn-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1e7e34;
    +  border-color: #1c7430;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active:focus,
    +.btn-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-light {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:hover {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +}
    +
    +.btn-light:focus,
    +.btn-light.focus {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-light.disabled,
    +.btn-light:disabled {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active,
    +.btn-light:not(:disabled):not(.disabled).active,
    +.show > .btn-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #dae0e5;
    +  border-color: #d3d9df;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active:focus,
    +.btn-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-dark {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:hover {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +}
    +
    +.btn-dark:focus,
    +.btn-dark.focus {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-dark.disabled,
    +.btn-dark:disabled {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active,
    +.btn-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1d2124;
    +  border-color: #171a1d;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-outline-primary {
    +  color: #fff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:hover {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:focus,
    +.btn-outline-primary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-primary.disabled,
    +.btn-outline-primary:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active,
    +.btn-outline-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-secondary {
    +  color: #fff;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:hover {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:focus,
    +.btn-outline-secondary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-secondary.disabled,
    +.btn-outline-secondary:disabled {
    +  color: #6c757d;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-secondary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-secondary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-success {
    +  color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:hover {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:focus,
    +.btn-outline-success.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-success.disabled,
    +.btn-outline-success:disabled {
    +  color: #28a745;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active,
    +.btn-outline-success:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-info {
    +  color: #fff;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:hover {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:focus,
    +.btn-outline-info.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-info.disabled,
    +.btn-outline-info:disabled {
    +  color: #17a2b8;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active,
    +.btn-outline-info:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-warning {
    +  color: #fff;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:hover {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:focus,
    +.btn-outline-warning.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-warning.disabled,
    +.btn-outline-warning:disabled {
    +  color: #ffc107;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active,
    +.btn-outline-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-danger {
    +  color: #fff;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:hover {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:focus,
    +.btn-outline-danger.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-danger.disabled,
    +.btn-outline-danger:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active,
    +.btn-outline-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-light {
    +  color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:hover {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:focus,
    +.btn-outline-light.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-light.disabled,
    +.btn-outline-light:disabled {
    +  color: #f8f9fa;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active,
    +.btn-outline-light:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-dark {
    +  color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:hover {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:focus,
    +.btn-outline-dark.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-outline-dark.disabled,
    +.btn-outline-dark:disabled {
    +  color: #343a40;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active,
    +.btn-outline-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-link {
    +  font-weight: 400;
    +  color: #007bff;
    +  text-decoration: none;
    +}
    +
    +.btn-link:hover {
    +  color: #0056b3;
    +  text-decoration: underline;
    +}
    +
    +.btn-link:focus,
    +.btn-link.focus {
    +  text-decoration: underline;
    +}
    +
    +.btn-link:disabled,
    +.btn-link.disabled {
    +  color: #6c757d;
    +  pointer-events: none;
    +}
    +
    +.btn-lg,
    +.btn-group-lg > .btn {
    +  padding: 0.5rem 1rem;
    +  font-size: 1.25rem;
    +  line-height: 1.5;
    +  border-radius: 0.3rem;
    +}
    +
    +.btn-sm,
    +.btn-group-sm > .btn {
    +  padding: 0.25rem 0.5rem;
    +  font-size: 0.875rem;
    +  line-height: 1.5;
    +  border-radius: 0.2rem;
    +}
    +
    +.btn-block {
    +  display: block;
    +  width: 100%;
    +}
    +
    +.btn-block + .btn-block {
    +  margin-top: 0.5rem;
    +}
    +
    +/* Prevents green disabled button */
    +
    +.btn-primary[disabled] {
    +  background-color: #007bff !important;
    +  opacity: 0.4;
    +}
    +
    +/* Manage disabled red */
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +/* some custom buttons design */
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +  box-shadow: inset 0 -1px 0 #ba202f;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +  box-shadow: inset 0 -1px 0 #e0a800;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +  box-shadow: inset 0 -1px 0 #138496;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  /*  background-color: #007bff;
    +        border-color: #007bff; */
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +/* Allow modals in simple xml dashboards */
    +.modal {
    +  display: none;
    +  margin-top: -1.5%;
    +}
    +
    +/* Some custom modal window sizes */
    +
    +.modal[class^="custom-modal"] {
    +  left: 50%;
    +  border: 1px solid green;
    +  margin-top: -1.5%;
    +}
    +
    +.custom-modal-30 {
    +  width: 30%;
    +  margin-left: -15%;
    +}
    +
    +.custom-modal-50 {
    +  width: 50%;
    +  margin-left: -25%;
    +}
    +
    +.custom-modal-60 {
    +  width: 60%;
    +  margin-left: -30%;
    +}
    +
    +.custom-modal-70 {
    +  width: 70%;
    +  margin-left: -35%;
    +}
    +
    +.custom-modal-80 {
    +  width: 80%;
    +  margin-left: -40%;
    +}
    +
    +.custom-modal-90 {
    +  width: 90%;
    +  margin-left: -45%;
    +}
    +
    +.custom-modal-96 {
    +  width: 96%;
    +  margin-left: -48%;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_template_exclusion_v2.js b/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_template_exclusion_v2.js
    new file mode 100644
    index 0000000..4b04c84
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_file_systems_template_exclusion_v2.js
    @@ -0,0 +1,538 @@
    +const { Callbacks, getJSON, get } = require("jquery");
    +
    +require([
    +  "jquery",
    +  "underscore",
    +  "splunkjs/mvc",
    +  "splunkjs/mvc/utils",
    +  "splunkjs/mvc/searchcontrolsview",
    +  "splunkjs/mvc/searchmanager",
    +  "splunkjs/mvc/postprocessmanager",
    +  "splunkjs/mvc/dropdownview",
    +  "splunkjs/mvc/multidropdownview",
    +  "splunkjs/mvc/tableview",
    +  "splunkjs/mvc/eventsviewerview",
    +  "splunkjs/mvc/textinputview",
    +  "splunkjs/mvc/singleview",
    +  "splunkjs/mvc/chartview",
    +  "splunkjs/mvc/resultslinkview",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/visualizationregistry",
    +  "splunkjs/mvc/simpleform/input/linklist",
    +  "splunkjs/mvc/simpleform/input/text",
    +  "splunkjs/mvc/simpleform/input/timerange",
    +  "splunkjs/mvc/simpleform/input/multiselect",
    +  "splunkjs/mvc/simpleform/input/dropdown",
    +  "splunkjs/mvc/simpleform/input/checkboxgroup",
    +  "splunkjs/mvc/simplexml/element/table",
    +  "splunkjs/mvc/simplexml/element/single",
    +  "splunkjs/mvc/simplexml/element/event",
    +  "splunkjs/mvc/simplexml/element/visualization",
    +  "splunkjs/mvc/simpleform/formutils",
    +  "splunkjs/mvc/simplexml/eventhandler",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/simplexml/ready!",
    +], function (
    +  $,
    +  _,
    +  mvc,
    +  utils,
    +  SearchControlsView,
    +  SearchManager,
    +  PostProcessManager,
    +  DropdownView,
    +  MultiDropdownView,
    +  TableView,
    +  EventsViewer,
    +  TextInputView,
    +  SingleView,
    +  ChartView,
    +  ResultsLinkView,
    +  SearchEventHandler,
    +  VisualizationRegistry,
    +  LinkListInput,
    +  TextInput,
    +  TimeRangeInput,
    +  MultiSelectInput,
    +  DropdownInput,
    +  CheckboxGroupInput,
    +  TableElement,
    +  VisualizationElement,
    +  SingleElement,
    +  EventElement,
    +  FormUtils,
    +  EventHandler,
    +  SearchEventHandler
    +) {
    +  //
    +  // START
    +  //
    +
    +  // tokens
    +
    +  var defaultTokenModel = mvc.Components.getInstance("default", {
    +    create: true,
    +  });
    +  var submittedTokenModel = mvc.Components.getInstance("submitted", {
    +    create: true,
    +  });
    +
    +  function setToken(name, value) {
    +    defaultTokenModel.set(name, value);
    +    submittedTokenModel.set(name, value);
    +  }
    +
    +  function getToken(name) {
    +    var ret = null;
    +    if (defaultTokenModel.get(name) != undefined) {
    +      ret = defaultTokenModel.get(name);
    +    } else if (submittedTokenModel.get(name) != undefined) {
    +      ret = submittedTokenModel.get(name);
    +    }
    +    return ret;
    +  }
    +
    +  function unsetToken(name) {
    +    defaultTokenModel.unset(name);
    +    submittedTokenModel.unset(name);
    +  }
    +
    +  // close all opened modals
    +  function closeModals() {
    +    $(".modal").modal("hide");
    +  }
    +
    +  // Returns true if numeric
    +  function isNumeric(n) {
    +    return !isNaN(parseFloat(n)) && isFinite(n) && n > 0;
    +  }
    +
    +  // searches
    +
    +  var search1 = new SearchManager(
    +    {
    +      id: "search1",
    +      earliest_time: "-24h",
    +      sample_ratio: 1,
    +      status_buckets: 0,
    +      cancelOnUnload: true,
    +      latest_time: "now",
    +      search:
    +        '| inputlookup nmon_alerting_filesystem_template_exclusion | where exclude="true" | stats count',
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search2 = new SearchManager(
    +    {
    +      id: "search2",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_alerting_filesystem_template_exclusion | search frameID=$search_frameid$ mount=$search_mount$ | eval KeyID = _key | table KeyID,frameID,mount,exclude",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search3 = new SearchManager(
    +    {
    +      id: "search3",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        '| inputlookup nmon_alerting_filesystem_template_exclusion | where exclude="true" | stats dc(mount) as dcount',
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search4 = new SearchManager(
    +    {
    +      id: "search4",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        '| inputlookup nmon_alerting_filesystem_template_exclusion | where exclude="true" | stats dc(frameID) as dcount',
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  function updateAllSearches() {
    +    search1.startSearch();
    +    search2.startSearch();
    +    search3.startSearch();
    +    search4.startSearch();
    +  }
    +
    +  // single views
    +
    +  var element_unset_exclusions = new SingleView(
    +    {
    +      id: "element_unset_exclusions",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of file systems exclusion configured",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search1",
    +      el: $("#element_unset_exclusions"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  var element_nb_frameID = new SingleView(
    +    {
    +      id: "element_nb_frameID",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of distinct frameIDs excluded",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search4",
    +      el: $("#element_nb_frameID"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  var element_nb_mount = new SingleView(
    +    {
    +      id: "element_nb_mount",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of distinct mount points excluded",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search3",
    +      el: $("#element_nb_mount"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  // tables
    +
    +  var element_table_show_lookup_content = new TableElement(
    +    {
    +      id: "element_table_show_lookup_content",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "row",
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search2",
    +      el: $("#element_table_show_lookup_content"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  element_table_show_lookup_content.on("click", function (e) {
    +    if (e.field !== undefined) {
    +      e.preventDefault();
    +      // set tk_keyid
    +      setToken("tk_keyid", e.data["row.KeyID"]);
    +      // Populate input forms
    +      setToken("form.input_update_frameid", e.data["row.frameID"]);
    +      setToken("form.input_update_mount", e.data["row.mount"]);
    +      // open modal
    +      $("#modal_update_entity").modal();
    +    }
    +  });
    +
    +  // inputs for template search purposes
    +
    +  var input_search_frameid = new TextInput(
    +    {
    +      id: "input_search_frameid",
    +      value: "$form.search_frameid$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_search_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_search_frameid.on("change", function (newValue) {
    +    setToken("search_frameid", newValue);
    +  });
    +
    +  var input_search_mount = new TextInput(
    +    {
    +      id: "input_search_mount",
    +      value: "$form.search_mount$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_search_mount"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_search_mount.on("change", function (newValue) {
    +    setToken("search_mount", newValue);
    +  });
    +
    +  // add new entries
    +
    +  var input_add_frameid = new TextInput(
    +    {
    +      id: "input_add_frameid",
    +      value: "$form.input_add_frameid$",
    +      el: $("#input_add_frameid"),
    +      width: 300,
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_frameid.on("change", function (newValue) {
    +    setToken("input_add_frameid", newValue);
    +  });
    +
    +  var input_add_mount = new TextInput(
    +    {
    +      id: "input_add_mount",
    +      value: "$form.input_add_mount$",
    +      el: $("#input_add_mount"),
    +      width: 300,
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_mount.on("change", function (newValue) {
    +    setToken("input_add_mount", newValue);
    +  });
    +
    +  // update entries
    +
    +  var input_update_frameid = new TextInput(
    +    {
    +      id: "input_update_frameid",
    +      value: "$form.input_update_frameid$",
    +      el: $("#input_update_frameid"),
    +      width: 300,
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_frameid.on("change", function (newValue) {
    +    setToken("input_update_frameid", newValue);
    +  });
    +
    +  var input_update_mount = new TextInput(
    +    {
    +      id: "input_update_mount",
    +      value: "$form.input_update_mount$",
    +      el: $("#input_update_mount"),
    +      width: 300,
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_mount.on("change", function (newValue) {
    +    setToken("input_update_mount", newValue);
    +  });
    +
    +  // interactions
    +
    +  // help
    +  $("#btn_help")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_help").modal();
    +    });
    +
    +  // add new entry
    +  $("#btn_add_new_template")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_add_entity").modal();
    +    });
    +
    +  // submit new entry
    +  $("#btn_submit_new_entity").click(function () {
    +    var frameid = getToken("input_add_frameid");
    +    var mount = getToken("input_add_mount");
    +
    +    // new record
    +    record = {
    +      frameID: frameid,
    +      mount: mount,
    +      exclude: "true",
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_filesystem_template_exclusion/";
    +
    +    if (frameid && frameid.length && mount && mount.length) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  // delete entity
    +  $("#btn_submit_delete_entity").click(function () {
    +    var tk_keyid = getToken("tk_keyid");
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_filesystem_template_exclusion/" +
    +      tk_keyid;
    +
    +    if (tk_keyid && tk_keyid.length) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "DELETE",
    +        async: true,
    +        contentType: "application/json",
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    }
    +  });
    +
    +  // update entry
    +  $("#btn_submit_update_entity").click(function () {
    +    var tk_keyid = getToken("tk_keyid");
    +    var frameid = getToken("input_update_frameid");
    +    var mount = getToken("input_update_mount");
    +
    +    // new record
    +    record = {
    +      frameID: frameid,
    +      mount: mount,
    +      exclude: "true",
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_filesystem_template_exclusion/" +
    +      tk_keyid;
    +
    +    if (frameid && frameid.length && mount && mount.length) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  //
    +  // END
    +  //
    +});
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_frameid_mapping_v2.css b/deployment-apps/metricator-for-nmon/appserver/static/manage_frameid_mapping_v2.css
    new file mode 100644
    index 0000000..8597751
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_frameid_mapping_v2.css
    @@ -0,0 +1,905 @@
    +/* Increase the default max-width for links */
    +.btn-pill {
    +  max-width: 600px !important;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-info h1 {
    +  color: #a7c7e7;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-success h1 {
    +  color: #77dd77;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-danger h1 {
    +  color: #ff6961;
    +}
    +
    +/* modal spl message */
    +.modal-spl-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/* modal success / info / error messages */
    +.modal-success-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-info-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-error-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: #ff6961;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/*** Buttons ***/
    +
    +.btn {
    +  background-color: black !important;
    +}
    +
    +.btn:hover {
    +  background-color: #31373e !important;
    +}
    +
    +/* fixes some UI issues in dark theme with bootstrap buttons */
    +button {
    +  background-color: transparent;
    +  border-width: inherit;
    +}
    +
    +/* Bootstrap btns */
    +
    +.btn-primary {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:hover {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +}
    +
    +.btn-primary:focus,
    +.btn-primary.focus {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-primary.disabled,
    +.btn-primary:disabled {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active,
    +.btn-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0062cc;
    +  border-color: #005cbf;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #117a8b;
    +  border-color: #10707f;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-success {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:hover {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +}
    +
    +.btn-success:focus,
    +.btn-success.focus {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-success.disabled,
    +.btn-success:disabled {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active,
    +.btn-success:not(:disabled):not(.disabled).active,
    +.show > .btn-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1e7e34;
    +  border-color: #1c7430;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active:focus,
    +.btn-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-light {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:hover {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +}
    +
    +.btn-light:focus,
    +.btn-light.focus {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-light.disabled,
    +.btn-light:disabled {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active,
    +.btn-light:not(:disabled):not(.disabled).active,
    +.show > .btn-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #dae0e5;
    +  border-color: #d3d9df;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active:focus,
    +.btn-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-dark {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:hover {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +}
    +
    +.btn-dark:focus,
    +.btn-dark.focus {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-dark.disabled,
    +.btn-dark:disabled {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active,
    +.btn-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1d2124;
    +  border-color: #171a1d;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-outline-primary {
    +  color: #fff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:hover {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:focus,
    +.btn-outline-primary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-primary.disabled,
    +.btn-outline-primary:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active,
    +.btn-outline-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-secondary {
    +  color: #fff;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:hover {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:focus,
    +.btn-outline-secondary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-secondary.disabled,
    +.btn-outline-secondary:disabled {
    +  color: #6c757d;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-secondary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-secondary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-success {
    +  color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:hover {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:focus,
    +.btn-outline-success.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-success.disabled,
    +.btn-outline-success:disabled {
    +  color: #28a745;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active,
    +.btn-outline-success:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-info {
    +  color: #fff;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:hover {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:focus,
    +.btn-outline-info.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-info.disabled,
    +.btn-outline-info:disabled {
    +  color: #17a2b8;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active,
    +.btn-outline-info:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-warning {
    +  color: #fff;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:hover {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:focus,
    +.btn-outline-warning.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-warning.disabled,
    +.btn-outline-warning:disabled {
    +  color: #ffc107;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active,
    +.btn-outline-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-danger {
    +  color: #fff;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:hover {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:focus,
    +.btn-outline-danger.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-danger.disabled,
    +.btn-outline-danger:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active,
    +.btn-outline-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-light {
    +  color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:hover {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:focus,
    +.btn-outline-light.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-light.disabled,
    +.btn-outline-light:disabled {
    +  color: #f8f9fa;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active,
    +.btn-outline-light:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-dark {
    +  color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:hover {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:focus,
    +.btn-outline-dark.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-outline-dark.disabled,
    +.btn-outline-dark:disabled {
    +  color: #343a40;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active,
    +.btn-outline-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-link {
    +  font-weight: 400;
    +  color: #007bff;
    +  text-decoration: none;
    +}
    +
    +.btn-link:hover {
    +  color: #0056b3;
    +  text-decoration: underline;
    +}
    +
    +.btn-link:focus,
    +.btn-link.focus {
    +  text-decoration: underline;
    +}
    +
    +.btn-link:disabled,
    +.btn-link.disabled {
    +  color: #6c757d;
    +  pointer-events: none;
    +}
    +
    +.btn-lg,
    +.btn-group-lg > .btn {
    +  padding: 0.5rem 1rem;
    +  font-size: 1.25rem;
    +  line-height: 1.5;
    +  border-radius: 0.3rem;
    +}
    +
    +.btn-sm,
    +.btn-group-sm > .btn {
    +  padding: 0.25rem 0.5rem;
    +  font-size: 0.875rem;
    +  line-height: 1.5;
    +  border-radius: 0.2rem;
    +}
    +
    +.btn-block {
    +  display: block;
    +  width: 100%;
    +}
    +
    +.btn-block + .btn-block {
    +  margin-top: 0.5rem;
    +}
    +
    +/* Prevents green disabled button */
    +
    +.btn-primary[disabled] {
    +  background-color: #007bff !important;
    +  opacity: 0.4;
    +}
    +
    +/* Manage disabled red */
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +/* some custom buttons design */
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +  box-shadow: inset 0 -1px 0 #ba202f;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +  box-shadow: inset 0 -1px 0 #e0a800;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +  box-shadow: inset 0 -1px 0 #138496;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  /*  background-color: #007bff;
    +    border-color: #007bff; */
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +/* Allow modals in simple xml dashboards */
    +.modal {
    +  display: none;
    +  margin-top: -1.5%;
    +}
    +
    +/* Some custom modal window sizes */
    +
    +.modal[class^="custom-modal"] {
    +  left: 50%;
    +  border: 1px solid green;
    +  margin-top: -1.5%;
    +}
    +
    +.custom-modal-30 {
    +  width: 30%;
    +  margin-left: -15%;
    +}
    +
    +.custom-modal-50 {
    +  width: 50%;
    +  margin-left: -25%;
    +}
    +
    +.custom-modal-60 {
    +  width: 60%;
    +  margin-left: -30%;
    +}
    +
    +.custom-modal-70 {
    +  width: 70%;
    +  margin-left: -35%;
    +}
    +
    +.custom-modal-80 {
    +  width: 80%;
    +  margin-left: -40%;
    +}
    +
    +.custom-modal-90 {
    +  width: 90%;
    +  margin-left: -45%;
    +}
    +
    +.custom-modal-96 {
    +  width: 96%;
    +  margin-left: -48%;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_frameid_mapping_v2.js b/deployment-apps/metricator-for-nmon/appserver/static/manage_frameid_mapping_v2.js
    new file mode 100644
    index 0000000..4b52778
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_frameid_mapping_v2.js
    @@ -0,0 +1,804 @@
    +const { Callbacks, getJSON, get } = require("jquery");
    +
    +require([
    +  "jquery",
    +  "underscore",
    +  "splunkjs/mvc",
    +  "splunkjs/mvc/utils",
    +  "splunkjs/mvc/searchcontrolsview",
    +  "splunkjs/mvc/searchmanager",
    +  "splunkjs/mvc/postprocessmanager",
    +  "splunkjs/mvc/dropdownview",
    +  "splunkjs/mvc/multidropdownview",
    +  "splunkjs/mvc/tableview",
    +  "splunkjs/mvc/eventsviewerview",
    +  "splunkjs/mvc/textinputview",
    +  "splunkjs/mvc/singleview",
    +  "splunkjs/mvc/chartview",
    +  "splunkjs/mvc/resultslinkview",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/visualizationregistry",
    +  "splunkjs/mvc/simpleform/input/linklist",
    +  "splunkjs/mvc/simpleform/input/text",
    +  "splunkjs/mvc/simpleform/input/timerange",
    +  "splunkjs/mvc/simpleform/input/multiselect",
    +  "splunkjs/mvc/simpleform/input/dropdown",
    +  "splunkjs/mvc/simpleform/input/checkboxgroup",
    +  "splunkjs/mvc/simplexml/element/table",
    +  "splunkjs/mvc/simplexml/element/single",
    +  "splunkjs/mvc/simplexml/element/event",
    +  "splunkjs/mvc/simplexml/element/visualization",
    +  "splunkjs/mvc/simpleform/formutils",
    +  "splunkjs/mvc/simplexml/eventhandler",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/simplexml/ready!",
    +], function (
    +  $,
    +  _,
    +  mvc,
    +  utils,
    +  SearchControlsView,
    +  SearchManager,
    +  PostProcessManager,
    +  DropdownView,
    +  MultiDropdownView,
    +  TableView,
    +  EventsViewer,
    +  TextInputView,
    +  SingleView,
    +  ChartView,
    +  ResultsLinkView,
    +  SearchEventHandler,
    +  VisualizationRegistry,
    +  LinkListInput,
    +  TextInput,
    +  TimeRangeInput,
    +  MultiSelectInput,
    +  DropdownInput,
    +  CheckboxGroupInput,
    +  TableElement,
    +  VisualizationElement,
    +  SingleElement,
    +  EventElement,
    +  FormUtils,
    +  EventHandler,
    +  SearchEventHandler
    +) {
    +  //
    +  // START
    +  //
    +
    +  // tokens
    +
    +  var defaultTokenModel = mvc.Components.getInstance("default", {
    +    create: true,
    +  });
    +  var submittedTokenModel = mvc.Components.getInstance("submitted", {
    +    create: true,
    +  });
    +
    +  function setToken(name, value) {
    +    defaultTokenModel.set(name, value);
    +    submittedTokenModel.set(name, value);
    +  }
    +
    +  function getToken(name) {
    +    var ret = null;
    +    if (defaultTokenModel.get(name) != undefined) {
    +      ret = defaultTokenModel.get(name);
    +    } else if (submittedTokenModel.get(name) != undefined) {
    +      ret = submittedTokenModel.get(name);
    +    }
    +    return ret;
    +  }
    +
    +  function unsetToken(name) {
    +    defaultTokenModel.unset(name);
    +    submittedTokenModel.unset(name);
    +  }
    +
    +  // close all opened modals
    +  function closeModals() {
    +    $(".modal").modal("hide");
    +  }
    +
    +  // ajax promise for API calls
    +  async function asyncAjax(ajaxurl, ajaxType, ajaxdata) {
    +    var resultCall;
    +    try {
    +      resultCall = await $.ajax({
    +        url: ajaxurl,
    +        type: ajaxType,
    +        data: JSON.stringify(ajaxdata),
    +      });
    +      // return resultUiPrefs
    +      $("#modal_generic_success").modal();
    +      // we do not want to catch the error
    +    } catch (error) {
    +      closeModals();
    +      $("#modal_generic_error")
    +        .find(".modal-error-message p")
    +        .text(JSON.stringify(error));
    +      $("#modal_generic_error").modal();
    +    }
    +  }
    +
    +  //
    +  // searches
    +  //
    +
    +  var search1 = new SearchManager(
    +    {
    +      id: "search1",
    +      earliest_time: "0",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_frameID_mapping | $user_selection$ | search frameID=* serialnum=* host=* host_description=* | eval  KeyID = _key | table KeyID,frameID,serialnum,host,host_description,*",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search2 = new SearchManager(
    +    {
    +      id: "search2",
    +      earliest_time: "-24h",
    +      sample_ratio: 1,
    +      status_buckets: 0,
    +      cancelOnUnload: true,
    +      latest_time: "now",
    +      search:
    +        "| inputlookup nmon_frameID_mapping | where frameID=host | stats dc(host) as count",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search3 = new SearchManager(
    +    {
    +      id: "search3",
    +      earliest_time: "0",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        '| inputlookup nmon_frameID_mapping | eval  KeyID = _key | table KeyID,frameID,serialnum,host,host_description,* | fillnull value="none" | search KeyID=$search_keyID$ frameID=$search_frameID$ serialnum=$search_serialnum$ host=$search_host$ host_description=$search_host_description$',
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search4 = new SearchManager(
    +    {
    +      id: "search4",
    +      earliest_time: "-7d",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_frameID_mapping | stats dc(host) as host_in_lookup | appendcols [ | tstats dc(host) as host_in_data WHERE `nmon_index` sourcetype=nmon_data ] | eval delta=if(host_in_lookup>host_in_data, host_in_lookup-host_in_data, host_in_data-host_in_lookup) | fields delta",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search5 = new SearchManager(
    +    {
    +      id: "search5",
    +      earliest_time: "-7d",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_frameID_mapping | stats count by host | where count>1 | stats dc(host) as count",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search6 = new SearchManager(
    +    {
    +      id: "search6",
    +      earliest_time: "-7d",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| mcatalog values(serialnum) as serials where `nmon_metrics_index` metric_name=os.unix.nmon.* by host | rename serials as serialnum | lookup nmon_frameID_mapping host as host OUTPUT frameID | where isnull(frameID)",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  new SearchEventHandler({
    +    managerid: "search6",
    +    event: "progress",
    +    conditions: [
    +      {
    +        attr: "match",
    +        value: "'job.resultCount' == 0",
    +        actions: [{ type: "unset", token: "show_null_missing_frameID" }],
    +      },
    +      {
    +        attr: "any",
    +        value: "*",
    +        actions: [
    +          { type: "set", token: "show_null_missing_frameID", value: "True" },
    +        ],
    +      },
    +    ],
    +  });
    +
    +  function updateAllSearches() {
    +    search1.startSearch();
    +    search2.startSearch();
    +    search3.startSearch();
    +    search4.startSearch();
    +    search5.startSearch();
    +    search6.startSearch();
    +  }
    +
    +  // singles
    +  var element_unset_frameID = new SingleView(
    +    {
    +      id: "element_unset_frameID",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of frameID undefined (frameID=hostname)",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search2",
    +      el: $("#element_unset_frameID"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  var element_delta_frameID = new SingleView(
    +    {
    +      id: "element_delta_frameID",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel:
    +        "Number of host(s) in delta (more hosts in data or more hosts in collection)",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search4",
    +      el: $("#element_delta_frameID"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  var element_duplicated_hosts = new SingleView(
    +    {
    +      id: "element_duplicated_hosts",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of host(s) with duplicated entries in the collection",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search5",
    +      el: $("#element_duplicated_hosts"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  // tables
    +
    +  var element_table_show_lookup_content = new TableView(
    +    {
    +      id: "element_table_show_lookup_content",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "row",
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search3",
    +      el: $("#element_table_show_lookup_content"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  element_table_show_lookup_content.on("click", function (e) {
    +    if (e.field !== undefined) {
    +      e.preventDefault();
    +      // Populate input form for deletion and addition
    +      setToken("tk_keyid", e.data["row.KeyID"]);
    +      setToken("form.modify_frameid", e.data["row.frameID"]);
    +      setToken("form.modify_serialnum", e.data["row.serialnum"]);
    +      setToken("form.modify_host", e.data["row.host"]);
    +      setToken("form.modify_host_description", e.data["row.host_description"]);
    +      $("#modal_update_entity").modal();
    +    }
    +  });
    +
    +  var element_table_missing_content = new TableView(
    +    {
    +      id: "element_table_missing_content",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "row",
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search6",
    +      el: $("#element_table_missing_content"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  element_table_missing_content.on("click", function (e) {
    +    if (e.field !== undefined) {
    +      e.preventDefault();
    +      // Populate input form for deletion and addition
    +      setToken("form.add_frameID", e.data["row.frameID"]);
    +      setToken("form.add_serialnum", e.data["row.serialnum"]);
    +      setToken("form.add_host", e.data["row.host"]);
    +      setToken("form.add_host_description", e.data["row.host_description"]);
    +      $("#modal_add_entity").modal();
    +    }
    +  });
    +
    +  // link input
    +  var inputLink = new LinkListInput(
    +    {
    +      id: "inputLink",
    +      choices: [
    +        {
    +          value: "frameid_collection",
    +          label: "FrameID current collection",
    +        },
    +        {
    +          value: "missing_hosts",
    +          label: "Hosts missing in the collection",
    +        },
    +      ],
    +      default: "frameid_collection",
    +      searchWhenChanged: true,
    +      selectFirstChoice: false,
    +      initialValue: "frameid_collection",
    +      value: "$form.inputLink$",
    +      el: $("#inputLink"),
    +    },
    +    {
    +      tokens: true,
    +    }
    +  ).render();
    +
    +  inputLink.on("change", function (newValue) {
    +    setToken("inputLink", newValue);
    +  });
    +
    +  inputLink.on("valueChange", function (e) {
    +    if (e.value === "frameid_collection") {
    +      // show and hide elements
    +      $("#tableParent1").css("display", "inherit");
    +      $("#tableParent2").css("display", "none");
    +    } else if (e.value === "missing_hosts") {
    +      // show and hide elements
    +      $("#tableParent1").css("display", "none");
    +      $("#tableParent2").css("display", "inherit");
    +    }
    +  });
    +
    +  // inputs
    +
    +  // inputs for searching purposes
    +
    +  var input_search_keyid = new TextInput(
    +    {
    +      id: "input_search_keyid",
    +      value: "$form.search_keyID$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_search_keyid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_search_keyid.on("change", function (newValue) {
    +    setToken("search_keyID", newValue);
    +  });
    +
    +  var input_search_frameid = new TextInput(
    +    {
    +      id: "input_search_frameid",
    +      value: "$form.search_frameID$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_search_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_search_frameid.on("change", function (newValue) {
    +    setToken("search_frameID", newValue);
    +  });
    +
    +  var input_search_serialnum = new TextInput(
    +    {
    +      id: "input_search_serialnum",
    +      value: "$form.search_serialnum$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_search_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_search_serialnum.on("change", function (newValue) {
    +    setToken("search_serialnum", newValue);
    +  });
    +
    +  var input_search_host = new TextInput(
    +    {
    +      id: "input_search_host",
    +      value: "$form.search_host$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_search_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_search_host.on("change", function (newValue) {
    +    setToken("search_host", newValue);
    +  });
    +
    +  var input_search_host_description = new TextInput(
    +    {
    +      id: "input_search_host_description",
    +      value: "$form.search_host_description$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_search_host_description"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_search_host_description.on("change", function (newValue) {
    +    setToken("search_host_description", newValue);
    +  });
    +
    +  // inputs for modification purposes
    +  var input_modify_frameid = new TextInput(
    +    {
    +      id: "input_modify_frameid",
    +      value: "$form.modify_frameid$",
    +      el: $("#input_modify_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_modify_frameid.on("change", function (newValue) {
    +    setToken("modify_frameid", newValue);
    +  });
    +
    +  var input_modify_serialnum = new TextInput(
    +    {
    +      id: "input_modify_serialnum",
    +      value: "$form.modify_serialnum$",
    +      el: $("#input_modify_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_modify_serialnum.on("change", function (newValue) {
    +    setToken("modify_serialnum", newValue);
    +  });
    +
    +  var input_modify_host = new TextInput(
    +    {
    +      id: "input_modify_host",
    +      value: "$form.modify_host$",
    +      el: $("#input_modify_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_modify_host.on("change", function (newValue) {
    +    setToken("modify_host", newValue);
    +  });
    +
    +  var input_modify_host_description = new TextInput(
    +    {
    +      id: "input_modify_host_description",
    +      value: "$form.modify_host_description$",
    +      el: $("#input_modify_host_description"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_modify_host_description.on("change", function (newValue) {
    +    setToken("modify_host_description", newValue);
    +  });
    +
    +  // inputs for addition purposes
    +  var input_add_frameid = new TextInput(
    +    {
    +      id: "input_add_frameid",
    +      value: "$form.add_frameID$",
    +      el: $("#input_add_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_frameid.on("change", function (newValue) {
    +    setToken("add_frameID", newValue);
    +  });
    +
    +  var input_add_serialnum = new TextInput(
    +    {
    +      id: "input_add_serialnum",
    +      value: "$form.add_serialnum$",
    +      el: $("#input_add_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_serialnum.on("change", function (newValue) {
    +    setToken("add_serialnum", newValue);
    +  });
    +
    +  var input_add_host = new TextInput(
    +    {
    +      id: "input_add_host",
    +      value: "$form.add_host$",
    +      el: $("#input_add_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_host.on("change", function (newValue) {
    +    setToken("add_host", newValue);
    +  });
    +
    +  var input_add_host_description = new TextInput(
    +    {
    +      id: "input_add_host_description",
    +      value: "$form.add_host_description$",
    +      el: $("#input_add_host_description"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_host_description.on("change", function (newValue) {
    +    setToken("add_host_description", newValue);
    +  });
    +
    +  // interactions
    +
    +  // help
    +  $("#btn_help")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_help").modal();
    +    });
    +
    +  // add new entry
    +  $("#btn_add_new_mapping")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_add_entity").modal();
    +    });
    +
    +  // submit new entry
    +  $("#btn_submit_new_entity").click(function () {
    +    var frameID = getToken("add_frameID");
    +    var serialnum = getToken("add_serialnum");
    +    var host = getToken("add_host");
    +    var host_description = getToken("add_host_description");
    +
    +    // new record
    +    record = {
    +      frameID: getToken("add_frameID"),
    +      serialnum: getToken("add_serialnum"),
    +      host: getToken("add_host"),
    +      host_description: getToken("add_host_description"),
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_frameID_mapping/";
    +
    +    // for sfatey check
    +    newHost = getToken("add_host");
    +
    +    if (
    +      frameID &&
    +      frameID.length &&
    +      serialnum &&
    +      serialnum.length &&
    +      host &&
    +      host.length &&
    +      host_description &&
    +      host_description.length
    +    ) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  // delete entity
    +  $("#btn_submit_delete_entity").click(function () {
    +    // set keyid
    +    var tk_keyid = getToken("tk_keyid");
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_frameID_mapping/" +
    +      tk_keyid;
    +    if (tk_keyid && tk_keyid.length) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "DELETE",
    +        async: true,
    +        contentType: "application/json",
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    }
    +  });
    +
    +  // update entity
    +  $("#btn_submit_update_entity").click(function () {
    +    // set vars
    +    var tk_keyid = getToken("tk_keyid");
    +    var frameID = getToken("modify_frameid");
    +    var serialnum = getToken("modify_serialnum");
    +    var host = getToken("modify_host");
    +    var host_description = getToken("modify_host_description");
    +
    +    // update record
    +    record = {
    +      frameID: frameID,
    +      serialnum: serialnum,
    +      host: host,
    +      host_description: host_description,
    +    };
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_frameID_mapping/" +
    +      tk_keyid;
    +
    +    if (
    +      tk_keyid &&
    +      tk_keyid.length &&
    +      frameID &&
    +      frameID.length &&
    +      serialnum &&
    +      serialnum.length &&
    +      host &&
    +      host.length &&
    +      host_description &&
    +      host_description.length
    +    ) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  //
    +  // END
    +  //
    +});
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_filesystem_v2.css b/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_filesystem_v2.css
    new file mode 100644
    index 0000000..db0bb60
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_filesystem_v2.css
    @@ -0,0 +1,905 @@
    +/* Increase the default max-width for links */
    +.btn-pill {
    +  max-width: 600px !important;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-info h1 {
    +  color: #a7c7e7;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-success h1 {
    +  color: #77dd77;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-danger h1 {
    +  color: #ff6961;
    +}
    +
    +/* modal spl message */
    +.modal-spl-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/* modal success / info / error messages */
    +.modal-success-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-info-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-error-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: #ff6961;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/*** Buttons ***/
    +
    +.btn {
    +  background-color: black !important;
    +}
    +
    +.btn:hover {
    +  background-color: #31373e !important;
    +}
    +
    +/* fixes some UI issues in dark theme with bootstrap buttons */
    +button {
    +  background-color: transparent;
    +  border-width: inherit;
    +}
    +
    +/* Bootstrap btns */
    +
    +.btn-primary {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:hover {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +}
    +
    +.btn-primary:focus,
    +.btn-primary.focus {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-primary.disabled,
    +.btn-primary:disabled {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active,
    +.btn-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0062cc;
    +  border-color: #005cbf;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #117a8b;
    +  border-color: #10707f;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-success {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:hover {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +}
    +
    +.btn-success:focus,
    +.btn-success.focus {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-success.disabled,
    +.btn-success:disabled {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active,
    +.btn-success:not(:disabled):not(.disabled).active,
    +.show > .btn-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1e7e34;
    +  border-color: #1c7430;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active:focus,
    +.btn-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-light {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:hover {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +}
    +
    +.btn-light:focus,
    +.btn-light.focus {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-light.disabled,
    +.btn-light:disabled {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active,
    +.btn-light:not(:disabled):not(.disabled).active,
    +.show > .btn-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #dae0e5;
    +  border-color: #d3d9df;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active:focus,
    +.btn-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-dark {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:hover {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +}
    +
    +.btn-dark:focus,
    +.btn-dark.focus {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-dark.disabled,
    +.btn-dark:disabled {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active,
    +.btn-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1d2124;
    +  border-color: #171a1d;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-outline-primary {
    +  color: #fff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:hover {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:focus,
    +.btn-outline-primary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-primary.disabled,
    +.btn-outline-primary:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active,
    +.btn-outline-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-secondary {
    +  color: #fff;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:hover {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:focus,
    +.btn-outline-secondary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-secondary.disabled,
    +.btn-outline-secondary:disabled {
    +  color: #6c757d;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-secondary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-secondary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-success {
    +  color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:hover {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:focus,
    +.btn-outline-success.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-success.disabled,
    +.btn-outline-success:disabled {
    +  color: #28a745;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active,
    +.btn-outline-success:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-info {
    +  color: #fff;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:hover {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:focus,
    +.btn-outline-info.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-info.disabled,
    +.btn-outline-info:disabled {
    +  color: #17a2b8;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active,
    +.btn-outline-info:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-warning {
    +  color: #fff;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:hover {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:focus,
    +.btn-outline-warning.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-warning.disabled,
    +.btn-outline-warning:disabled {
    +  color: #ffc107;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active,
    +.btn-outline-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-danger {
    +  color: #fff;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:hover {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:focus,
    +.btn-outline-danger.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-danger.disabled,
    +.btn-outline-danger:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active,
    +.btn-outline-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-light {
    +  color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:hover {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:focus,
    +.btn-outline-light.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-light.disabled,
    +.btn-outline-light:disabled {
    +  color: #f8f9fa;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active,
    +.btn-outline-light:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-dark {
    +  color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:hover {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:focus,
    +.btn-outline-dark.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-outline-dark.disabled,
    +.btn-outline-dark:disabled {
    +  color: #343a40;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active,
    +.btn-outline-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-link {
    +  font-weight: 400;
    +  color: #007bff;
    +  text-decoration: none;
    +}
    +
    +.btn-link:hover {
    +  color: #0056b3;
    +  text-decoration: underline;
    +}
    +
    +.btn-link:focus,
    +.btn-link.focus {
    +  text-decoration: underline;
    +}
    +
    +.btn-link:disabled,
    +.btn-link.disabled {
    +  color: #6c757d;
    +  pointer-events: none;
    +}
    +
    +.btn-lg,
    +.btn-group-lg > .btn {
    +  padding: 0.5rem 1rem;
    +  font-size: 1.25rem;
    +  line-height: 1.5;
    +  border-radius: 0.3rem;
    +}
    +
    +.btn-sm,
    +.btn-group-sm > .btn {
    +  padding: 0.25rem 0.5rem;
    +  font-size: 0.875rem;
    +  line-height: 1.5;
    +  border-radius: 0.2rem;
    +}
    +
    +.btn-block {
    +  display: block;
    +  width: 100%;
    +}
    +
    +.btn-block + .btn-block {
    +  margin-top: 0.5rem;
    +}
    +
    +/* Prevents green disabled button */
    +
    +.btn-primary[disabled] {
    +  background-color: #007bff !important;
    +  opacity: 0.4;
    +}
    +
    +/* Manage disabled red */
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +/* some custom buttons design */
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +  box-shadow: inset 0 -1px 0 #ba202f;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +  box-shadow: inset 0 -1px 0 #e0a800;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +  box-shadow: inset 0 -1px 0 #138496;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  /*  background-color: #007bff;
    +      border-color: #007bff; */
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +/* Allow modals in simple xml dashboards */
    +.modal {
    +  display: none;
    +  margin-top: -1.5%;
    +}
    +
    +/* Some custom modal window sizes */
    +
    +.modal[class^="custom-modal"] {
    +  left: 50%;
    +  border: 1px solid green;
    +  margin-top: -1.5%;
    +}
    +
    +.custom-modal-30 {
    +  width: 30%;
    +  margin-left: -15%;
    +}
    +
    +.custom-modal-50 {
    +  width: 50%;
    +  margin-left: -25%;
    +}
    +
    +.custom-modal-60 {
    +  width: 60%;
    +  margin-left: -30%;
    +}
    +
    +.custom-modal-70 {
    +  width: 70%;
    +  margin-left: -35%;
    +}
    +
    +.custom-modal-80 {
    +  width: 80%;
    +  margin-left: -40%;
    +}
    +
    +.custom-modal-90 {
    +  width: 90%;
    +  margin-left: -45%;
    +}
    +
    +.custom-modal-96 {
    +  width: 96%;
    +  margin-left: -48%;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_filesystem_v2.js b/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_filesystem_v2.js
    new file mode 100644
    index 0000000..0fb2251
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_filesystem_v2.js
    @@ -0,0 +1,794 @@
    +const { Callbacks, getJSON, get } = require("jquery");
    +
    +require([
    +  "jquery",
    +  "underscore",
    +  "splunkjs/mvc",
    +  "splunkjs/mvc/utils",
    +  "splunkjs/mvc/searchcontrolsview",
    +  "splunkjs/mvc/searchmanager",
    +  "splunkjs/mvc/postprocessmanager",
    +  "splunkjs/mvc/dropdownview",
    +  "splunkjs/mvc/multidropdownview",
    +  "splunkjs/mvc/tableview",
    +  "splunkjs/mvc/eventsviewerview",
    +  "splunkjs/mvc/textinputview",
    +  "splunkjs/mvc/singleview",
    +  "splunkjs/mvc/chartview",
    +  "splunkjs/mvc/resultslinkview",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/visualizationregistry",
    +  "splunkjs/mvc/simpleform/input/linklist",
    +  "splunkjs/mvc/simpleform/input/text",
    +  "splunkjs/mvc/simpleform/input/timerange",
    +  "splunkjs/mvc/simpleform/input/multiselect",
    +  "splunkjs/mvc/simpleform/input/dropdown",
    +  "splunkjs/mvc/simpleform/input/checkboxgroup",
    +  "splunkjs/mvc/simplexml/element/table",
    +  "splunkjs/mvc/simplexml/element/single",
    +  "splunkjs/mvc/simplexml/element/event",
    +  "splunkjs/mvc/simplexml/element/visualization",
    +  "splunkjs/mvc/simpleform/formutils",
    +  "splunkjs/mvc/simplexml/eventhandler",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/simplexml/ready!",
    +], function (
    +  $,
    +  _,
    +  mvc,
    +  utils,
    +  SearchControlsView,
    +  SearchManager,
    +  PostProcessManager,
    +  DropdownView,
    +  MultiDropdownView,
    +  TableView,
    +  EventsViewer,
    +  TextInputView,
    +  SingleView,
    +  ChartView,
    +  ResultsLinkView,
    +  SearchEventHandler,
    +  VisualizationRegistry,
    +  LinkListInput,
    +  TextInput,
    +  TimeRangeInput,
    +  MultiSelectInput,
    +  DropdownInput,
    +  CheckboxGroupInput,
    +  TableElement,
    +  VisualizationElement,
    +  SingleElement,
    +  EventElement,
    +  FormUtils,
    +  EventHandler,
    +  SearchEventHandler
    +) {
    +  //
    +  // START
    +  //
    +
    +  // tokens
    +
    +  var defaultTokenModel = mvc.Components.getInstance("default", {
    +    create: true,
    +  });
    +  var submittedTokenModel = mvc.Components.getInstance("submitted", {
    +    create: true,
    +  });
    +
    +  function setToken(name, value) {
    +    defaultTokenModel.set(name, value);
    +    submittedTokenModel.set(name, value);
    +  }
    +
    +  function getToken(name) {
    +    var ret = null;
    +    if (defaultTokenModel.get(name) != undefined) {
    +      ret = defaultTokenModel.get(name);
    +    } else if (submittedTokenModel.get(name) != undefined) {
    +      ret = submittedTokenModel.get(name);
    +    }
    +    return ret;
    +  }
    +
    +  function unsetToken(name) {
    +    defaultTokenModel.unset(name);
    +    submittedTokenModel.unset(name);
    +  }
    +
    +  // close all opened modals
    +  function closeModals() {
    +    $(".modal").modal("hide");
    +  }
    +
    +  // Returns true if numeric
    +  function isNumeric(n) {
    +    return !isNaN(parseFloat(n)) && isFinite(n) && n > 0;
    +  }
    +
    +  // searches
    +
    +  var search1 = new SearchManager(
    +    {
    +      id: "search1",
    +      earliest_time: "-5m",
    +      sample_ratio: 1,
    +      status_buckets: 0,
    +      cancelOnUnload: true,
    +      latest_time: "now",
    +      search:
    +        "| inputlookup nmon_alerting_threshold_template_filesystem | stats count",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search2 = new SearchManager(
    +    {
    +      id: "search2",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_alerting_threshold_template_filesystem | search frameID=$search_frameID$ mount=$search_mount$ | eval KeyID = _key | table KeyID,frameID,mount,*",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search3 = new SearchManager(
    +    {
    +      id: "search3",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_alerting_threshold_template_filesystem | stats dc(frameID) as frameID",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search4 = new SearchManager(
    +    {
    +      id: "search4",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_frameID_mapping | search frameID=$input_frameID_search_frameid$ serialnum=$input_frameID_search_serialnum$ host=$input_frameID_search_host$ host_description=$input_frameID_search_host_description$ | table frameID,serialnum,host,host_description,*",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  function updateAllSearches() {
    +    search1.startSearch();
    +    search2.startSearch();
    +    search3.startSearch();
    +    search4.startSearch();
    +  }
    +
    +  // single views
    +
    +  var element_unset_exclusions = new SingleView(
    +    {
    +      id: "element_unset_exclusions",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of threshold configured",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search1",
    +      el: $("#element_unset_exclusions"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  var element_nb_hosts = new SingleView(
    +    {
    +      id: "element_nb_hosts",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of frameID with threshold configured",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search3",
    +      el: $("#element_nb_hosts"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  // link input
    +  var inputLink = new LinkListInput(
    +    {
    +      id: "inputLink",
    +      choices: [
    +        {
    +          value: "template_thresholds",
    +          label: "Template thresholds collection",
    +        },
    +        {
    +          value: "frameid_collection",
    +          label: "FrameID current collection",
    +        },
    +      ],
    +      default: "template_thresholds",
    +      searchWhenChanged: true,
    +      selectFirstChoice: false,
    +      initialValue: "template_thresholds",
    +      value: "$form.inputLink$",
    +      el: $("#inputLink"),
    +    },
    +    {
    +      tokens: true,
    +    }
    +  ).render();
    +
    +  inputLink.on("change", function (newValue) {
    +    setToken("inputLink", newValue);
    +  });
    +
    +  inputLink.on("valueChange", function (e) {
    +    if (e.value === "template_thresholds") {
    +      // show and hide elements
    +      $("#tableParent1").css("display", "inherit");
    +      $("#tableParent2").css("display", "none");
    +    } else if (e.value === "frameid_collection") {
    +      // show and hide elements
    +      $("#tableParent1").css("display", "none");
    +      $("#tableParent2").css("display", "inherit");
    +    }
    +  });
    +
    +  // tables
    +
    +  var element_table_show_lookup_content = new TableElement(
    +    {
    +      id: "element_table_show_lookup_content",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "row",
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search2",
    +      el: $("#element_table_show_lookup_content"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  element_table_show_lookup_content.on("click", function (e) {
    +    if (e.field !== undefined) {
    +      e.preventDefault();
    +      // set tk_keyid
    +      setToken("tk_keyid", e.data["row.KeyID"]);
    +      // Populate input forms
    +      setToken("form.input_update_frameid", e.data["row.frameID"]);
    +      setToken("form.input_update_mount", e.data["row.mount"]);
    +      setToken(
    +        "form.input_update_alert_fs_max_percent",
    +        e.data["row.alert_fs_max_percent"]
    +      );
    +      setToken(
    +        "form.input_update_alert_fs_min_time_seconds",
    +        e.data["row.alert_fs_min_time_seconds"]
    +      );
    +      setToken("form.input_update_alert_fs_is_shared", e.data["row.is_shared"]);
    +      $("#modal_update_entity").modal();
    +    }
    +  });
    +
    +  var element_table_show_frameID_lookup_content = new TableElement(
    +    {
    +      id: "element_table_show_frameID_lookup_content",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "none",
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search4",
    +      el: $("#element_table_show_frameID_lookup_content"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  // inputs for template search purposes
    +
    +  var input_search_frameid = new TextInput(
    +    {
    +      id: "input_search_frameid",
    +      value: "$form.search_frameID$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_search_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_search_frameid.on("change", function (newValue) {
    +    setToken("search_frameID", newValue);
    +  });
    +
    +  var input_search_mount = new TextInput(
    +    {
    +      id: "input_search_mount",
    +      value: "$form.search_mount$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_search_mount"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_search_mount.on("change", function (newValue) {
    +    setToken("search_mount", newValue);
    +  });
    +
    +  // search frameID mapping
    +
    +  var input_frameID_search_frameid = new TextInput(
    +    {
    +      id: "input_frameID_search_frameid",
    +      value: "$form.input_frameID_search_frameid$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_frameID_search_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_frameID_search_frameid.on("change", function (newValue) {
    +    setToken("input_frameID_search_frameid", newValue);
    +  });
    +
    +  var input_frameID_search_serialnum = new TextInput(
    +    {
    +      id: "input_frameID_search_serialnum",
    +      value: "$form.input_frameID_search_serialnum$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_frameID_search_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_frameID_search_serialnum.on("change", function (newValue) {
    +    setToken("input_frameID_search_serialnum", newValue);
    +  });
    +
    +  var input_frameID_search_host = new TextInput(
    +    {
    +      id: "input_frameID_search_host",
    +      value: "$form.input_frameID_search_host$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_frameID_search_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_frameID_search_host.on("change", function (newValue) {
    +    setToken("input_frameID_search_host", newValue);
    +  });
    +
    +  var input_frameID_search_host_description = new TextInput(
    +    {
    +      id: "input_frameID_search_host_description",
    +      value: "$form.input_frameID_search_host_description$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_frameID_search_host_description"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_frameID_search_host_description.on("change", function (newValue) {
    +    setToken("input_frameID_search_host_description", newValue);
    +  });
    +
    +  // add new entries
    +
    +  var input_add_frameid = new TextInput(
    +    {
    +      id: "input_add_frameid",
    +      value: "$form.input_add_frameid$",
    +      el: $("#input_add_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_frameid.on("change", function (newValue) {
    +    setToken("input_add_frameid", newValue);
    +  });
    +
    +  var input_add_mount = new TextInput(
    +    {
    +      id: "input_add_mount",
    +      value: "$form.input_add_mount$",
    +      el: $("#input_add_mount"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_mount.on("change", function (newValue) {
    +    setToken("input_add_mount", newValue);
    +  });
    +
    +  var input_add_alert_fs_max_percent = new TextInput(
    +    {
    +      id: "input_add_alert_fs_max_percent",
    +      value: "$form.input_add_alert_fs_max_percent$",
    +      default: "90",
    +      el: $("#input_add_alert_fs_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_fs_max_percent.on("change", function (newValue) {
    +    setToken("input_add_alert_fs_max_percent", newValue);
    +  });
    +
    +  var input_add_alert_fs_min_time_seconds = new TextInput(
    +    {
    +      id: "input_add_alert_fs_min_time_seconds",
    +      value: "$form.input_add_alert_fs_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_add_alert_fs_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_fs_min_time_seconds.on("change", function (newValue) {
    +    setToken("input_add_alert_fs_min_time_seconds", newValue);
    +  });
    +
    +  var input_add_alert_fs_is_shared = new DropdownInput(
    +    {
    +      id: "input_add_alert_fs_is_shared",
    +      choices: [
    +        {
    +          label: "True",
    +          value: "True",
    +        },
    +        {
    +          label: "False",
    +          value: "False",
    +        },
    +      ],
    +      searchWhenChanged: true,
    +      default: "False",
    +      showClearButton: true,
    +      initialValue: "False",
    +      selectFirstChoice: false,
    +      value: "$form.input_add_alert_fs_is_shared$",
    +      el: $("#input_add_alert_fs_is_shared"),
    +    },
    +    {
    +      tokens: true,
    +    }
    +  ).render();
    +
    +  input_add_alert_fs_is_shared.on("change", function (newValue) {
    +    setToken("input_add_alert_fs_is_shared", newValue);
    +  });
    +
    +  // update entries
    +  var input_update_frameid = new TextInput(
    +    {
    +      id: "input_update_frameid",
    +      value: "$form.input_update_frameid$",
    +      el: $("#input_update_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_frameid.on("change", function (newValue) {
    +    setToken("input_update_frameid", newValue);
    +  });
    +
    +  var input_update_mount = new TextInput(
    +    {
    +      id: "input_update_mount",
    +      value: "$form.input_update_mount$",
    +      el: $("#input_update_mount"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_mount.on("change", function (newValue) {
    +    setToken("input_update_mount", newValue);
    +  });
    +
    +  var input_update_alert_fs_max_percent = new TextInput(
    +    {
    +      id: "input_update_alert_fs_max_percent",
    +      value: "$form.input_update_alert_fs_max_percent$",
    +      default: "90",
    +      el: $("#input_update_alert_fs_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_fs_max_percent.on("change", function (newValue) {
    +    setToken("input_update_alert_fs_max_percent", newValue);
    +  });
    +
    +  var input_update_alert_fs_min_time_seconds = new TextInput(
    +    {
    +      id: "input_update_alert_fs_min_time_seconds",
    +      value: "$form.input_update_alert_fs_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_update_alert_fs_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_fs_min_time_seconds.on("change", function (newValue) {
    +    setToken("input_update_alert_fs_min_time_seconds", newValue);
    +  });
    +
    +  var input_update_alert_fs_is_shared = new DropdownInput(
    +    {
    +      id: "input_update_alert_fs_is_shared",
    +      choices: [
    +        {
    +          label: "True",
    +          value: "True",
    +        },
    +        {
    +          label: "False",
    +          value: "False",
    +        },
    +      ],
    +      searchWhenChanged: true,
    +      default: "False",
    +      showClearButton: true,
    +      initialValue: "False",
    +      selectFirstChoice: false,
    +      value: "$form.input_update_alert_fs_is_shared$",
    +      el: $("#input_update_alert_fs_is_shared"),
    +    },
    +    {
    +      tokens: true,
    +    }
    +  ).render();
    +
    +  input_update_alert_fs_is_shared.on("change", function (newValue) {
    +    setToken("input_update_alert_fs_is_shared", newValue);
    +  });
    +
    +  // interactions
    +
    +  // help
    +  $("#btn_help")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_help").modal();
    +    });
    +
    +  // add new entry
    +  $("#btn_add_new_template")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_add_entity").modal();
    +    });
    +
    +  // submit new entry
    +  $("#btn_submit_new_entity").click(function () {
    +    var frameID = getToken("input_add_frameid");
    +    var mount = getToken("input_add_mount");
    +    var alert_fs_max_percent = getToken("input_add_alert_fs_max_percent");
    +    var alert_fs_min_time_seconds = getToken(
    +      "input_add_alert_fs_min_time_seconds"
    +    );
    +    var is_shared = getToken("input_add_alert_fs_is_shared");
    +
    +    // new record
    +    record = {
    +      frameID: frameID,
    +      mount: mount,
    +      alert_fs_max_percent: alert_fs_max_percent,
    +      alert_fs_min_time_seconds: alert_fs_min_time_seconds,
    +      is_shared: is_shared,
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_threshold_template_filesystem/";
    +
    +    if (
    +      frameID &&
    +      frameID.length &&
    +      mount &&
    +      mount.length &&
    +      alert_fs_max_percent &&
    +      alert_fs_max_percent.length &&
    +      isNumeric(alert_fs_max_percent) &&
    +      alert_fs_min_time_seconds &&
    +      alert_fs_min_time_seconds.length &&
    +      isNumeric(alert_fs_min_time_seconds) &&
    +      is_shared &&
    +      is_shared.length
    +    ) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  // delete entity
    +  $("#btn_submit_delete_entity").click(function () {
    +    var tk_keyid = getToken("tk_keyid");
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_threshold_template_filesystem/" +
    +      tk_keyid;
    +
    +    if (tk_keyid && tk_keyid.length) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "DELETE",
    +        async: true,
    +        contentType: "application/json",
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    }
    +  });
    +
    +  // update entry
    +  $("#btn_submit_update_entity").click(function () {
    +    var tk_keyid = getToken("tk_keyid");
    +    var frameID = getToken("input_update_frameid");
    +    var mount = getToken("input_update_mount");
    +    var alert_fs_max_percent = getToken("input_update_alert_fs_max_percent");
    +    var alert_fs_min_time_seconds = getToken(
    +      "input_update_alert_fs_min_time_seconds"
    +    );
    +    var is_shared = getToken("input_update_alert_fs_is_shared");
    +
    +    // new record
    +    record = {
    +      frameID: frameID,
    +      mount: mount,
    +      alert_fs_max_percent: alert_fs_max_percent,
    +      alert_fs_min_time_seconds: alert_fs_min_time_seconds,
    +      is_shared: is_shared,
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_threshold_template_filesystem/" +
    +      tk_keyid;
    +
    +    if (
    +      frameID &&
    +      frameID.length &&
    +      mount &&
    +      mount.length &&
    +      alert_fs_max_percent &&
    +      alert_fs_max_percent.length &&
    +      isNumeric(alert_fs_max_percent) &&
    +      alert_fs_min_time_seconds &&
    +      alert_fs_min_time_seconds.length &&
    +      isNumeric(alert_fs_min_time_seconds) &&
    +      is_shared &&
    +      is_shared.length
    +    ) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  //
    +  // END
    +  //
    +});
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_table_bar.js b/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_table_bar.js
    new file mode 100644
    index 0000000..ff6ae4d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_table_bar.js
    @@ -0,0 +1,83 @@
    +require([
    +  "jquery",
    +  "underscore",
    +  "splunkjs/mvc",
    +  "views/shared/results_table/renderers/BaseCellRenderer",
    +  "splunkjs/mvc/simplexml/ready!",
    +], function ($, _, mvc, BaseCellRenderer) {
    +  // bar1
    +  var DataBarCellRenderer = BaseCellRenderer.extend({
    +    canRender: function (cell) {
    +      return cell.field === "max_cpu_percent";
    +    },
    +    render: function ($td, cell) {
    +      var pColor = "data-bar-under";
    +      if (cell.value > 15) {
    +        pColor = "data-bar-over";
    +      }
    +      $td.addClass("data-bar-cell").html(
    +        _.template(
    +          '<div class="data-bar-wrapper"><div class="data-bar <%- pColor %>" style="width:<%- percent %>%">&nbsp;<%- ppp %>%</div></div>',
    +          {
    +            percent: Math.min(Math.max(parseFloat(cell.value), 0), 100),
    +            ppp: parseFloat(cell.value).toFixed(2),
    +            pColor: pColor,
    +          }
    +        )
    +      );
    +    },
    +  });
    +  // bar2
    +  var DataBarCellRenderer2 = BaseCellRenderer.extend({
    +    canRender: function (cell) {
    +      return cell.field === "max_phy_percent";
    +    },
    +    render: function ($td, cell) {
    +      var pColor = "data-bar-under";
    +      if (cell.value > 15) {
    +        pColor = "data-bar-over";
    +      }
    +      $td.addClass("data-bar-cell").html(
    +        _.template(
    +          '<div class="data-bar-wrapper"><div class="data-bar <%- pColor %>" style="width:<%- percent %>%">&nbsp;<%- ppp %>%</div></div>',
    +          {
    +            percent: Math.min(Math.max(parseFloat(cell.value), 0), 100),
    +            ppp: parseFloat(cell.value).toFixed(2),
    +            pColor: pColor,
    +          }
    +        )
    +      );
    +    },
    +  });
    +  // bar3
    +  var DataBarCellRenderer3 = BaseCellRenderer.extend({
    +    canRender: function (cell) {
    +      return cell.field === "max_vir_percent";
    +    },
    +    render: function ($td, cell) {
    +      var pColor = "data-bar-under";
    +      if (cell.value > 15) {
    +        pColor = "data-bar-over";
    +      }
    +      $td.addClass("data-bar-cell").html(
    +        _.template(
    +          '<div class="data-bar-wrapper"><div class="data-bar <%- pColor %>" style="width:<%- percent %>%">&nbsp;<%- ppp %>%</div></div>',
    +          {
    +            percent: Math.min(Math.max(parseFloat(cell.value), 0), 100),
    +            ppp: parseFloat(cell.value).toFixed(2),
    +            pColor: pColor,
    +          }
    +        )
    +      );
    +    },
    +  });
    +
    +  mvc.Components.get("element_table_show_lookup_content").getVisualization(
    +    function (tableView) {
    +      tableView.table.addCellRenderer(new DataBarCellRenderer());
    +      tableView.table.addCellRenderer(new DataBarCellRenderer2());
    +      tableView.table.addCellRenderer(new DataBarCellRenderer3());
    +      tableView.table.render();
    +    }
    +  );
    +});
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_v2.css b/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_v2.css
    new file mode 100644
    index 0000000..db0bb60
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_v2.css
    @@ -0,0 +1,905 @@
    +/* Increase the default max-width for links */
    +.btn-pill {
    +  max-width: 600px !important;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-info h1 {
    +  color: #a7c7e7;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-success h1 {
    +  color: #77dd77;
    +}
    +
    +/* modal header classes */
    +
    +.modal-header-danger h1 {
    +  color: #ff6961;
    +}
    +
    +/* modal spl message */
    +.modal-spl-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/* modal success / info / error messages */
    +.modal-success-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-info-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: dodgerblue;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +.modal-error-message {
    +  margin: 10px 0;
    +  padding: 10px;
    +  border-radius: 3px 3px 3px 3px;
    +  color: white;
    +  background-color: #ff6961;
    +  overflow-wrap: anywhere;
    +  overflow: auto;
    +  max-height: 600px;
    +}
    +
    +/*** Buttons ***/
    +
    +.btn {
    +  background-color: black !important;
    +}
    +
    +.btn:hover {
    +  background-color: #31373e !important;
    +}
    +
    +/* fixes some UI issues in dark theme with bootstrap buttons */
    +button {
    +  background-color: transparent;
    +  border-width: inherit;
    +}
    +
    +/* Bootstrap btns */
    +
    +.btn-primary {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:hover {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +}
    +
    +.btn-primary:focus,
    +.btn-primary.focus {
    +  color: #fff;
    +  background-color: #0069d9;
    +  border-color: #0062cc;
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-primary.disabled,
    +.btn-primary:disabled {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active,
    +.btn-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0062cc;
    +  border-color: #005cbf;
    +}
    +
    +.btn-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
    +}
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #138496;
    +  border-color: #117a8b;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #117a8b;
    +  border-color: #10707f;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-success {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:hover {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +}
    +
    +.btn-success:focus,
    +.btn-success.focus {
    +  color: #fff;
    +  background-color: #218838;
    +  border-color: #1e7e34;
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-success.disabled,
    +.btn-success:disabled {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active,
    +.btn-success:not(:disabled):not(.disabled).active,
    +.show > .btn-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1e7e34;
    +  border-color: #1c7430;
    +}
    +
    +.btn-success:not(:disabled):not(.disabled):active:focus,
    +.btn-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);
    +}
    +
    +.btn-light {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:hover {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +}
    +
    +.btn-light:focus,
    +.btn-light.focus {
    +  color: #212529;
    +  background-color: #e2e6ea;
    +  border-color: #dae0e5;
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-light.disabled,
    +.btn-light:disabled {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active,
    +.btn-light:not(:disabled):not(.disabled).active,
    +.show > .btn-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #dae0e5;
    +  border-color: #d3d9df;
    +}
    +
    +.btn-light:not(:disabled):not(.disabled):active:focus,
    +.btn-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
    +}
    +
    +.btn-dark {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:hover {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +}
    +
    +.btn-dark:focus,
    +.btn-dark.focus {
    +  color: #fff;
    +  background-color: #23272b;
    +  border-color: #1d2124;
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-dark.disabled,
    +.btn-dark:disabled {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active,
    +.btn-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #1d2124;
    +  border-color: #171a1d;
    +}
    +
    +.btn-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);
    +}
    +
    +.btn-outline-primary {
    +  color: #fff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:hover {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:focus,
    +.btn-outline-primary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-primary.disabled,
    +.btn-outline-primary:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active,
    +.btn-outline-primary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-primary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +}
    +
    +.btn-outline-primary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-primary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-primary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
    +}
    +
    +.btn-outline-secondary {
    +  color: #fff;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:hover {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:focus,
    +.btn-outline-secondary.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-secondary.disabled,
    +.btn-outline-secondary:disabled {
    +  color: #6c757d;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-secondary.dropdown-toggle {
    +  color: #fff;
    +  background-color: #6c757d;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-secondary.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
    +}
    +
    +.btn-outline-success {
    +  color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:hover {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:focus,
    +.btn-outline-success.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-success.disabled,
    +.btn-outline-success:disabled {
    +  color: #28a745;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active,
    +.btn-outline-success:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-success.dropdown-toggle {
    +  color: #fff;
    +  background-color: #28a745;
    +  border-color: #28a745;
    +}
    +
    +.btn-outline-success:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-success:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-success.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
    +}
    +
    +.btn-outline-info {
    +  color: #fff;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:hover {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:focus,
    +.btn-outline-info.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-info.disabled,
    +.btn-outline-info:disabled {
    +  color: #17a2b8;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active,
    +.btn-outline-info:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #17a2b8;
    +  border-color: #17a2b8;
    +}
    +
    +.btn-outline-info:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
    +}
    +
    +.btn-outline-warning {
    +  color: #fff;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:hover {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:focus,
    +.btn-outline-warning.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-warning.disabled,
    +.btn-outline-warning:disabled {
    +  color: #ffc107;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active,
    +.btn-outline-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-outline-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
    +}
    +
    +.btn-outline-danger {
    +  color: #fff;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:hover {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:focus,
    +.btn-outline-danger.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-danger.disabled,
    +.btn-outline-danger:disabled {
    +  color: #5c6773;
    +  background-color: transparent;
    +  border-color: #6c757d;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active,
    +.btn-outline-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-outline-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
    +}
    +
    +.btn-outline-light {
    +  color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:hover {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:focus,
    +.btn-outline-light.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-light.disabled,
    +.btn-outline-light:disabled {
    +  color: #f8f9fa;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active,
    +.btn-outline-light:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-light.dropdown-toggle {
    +  color: #212529;
    +  background-color: #f8f9fa;
    +  border-color: #f8f9fa;
    +}
    +
    +.btn-outline-light:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-light:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-light.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
    +}
    +
    +.btn-outline-dark {
    +  color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:hover {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:focus,
    +.btn-outline-dark.focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-outline-dark.disabled,
    +.btn-outline-dark:disabled {
    +  color: #343a40;
    +  background-color: transparent;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active,
    +.btn-outline-dark:not(:disabled):not(.disabled).active,
    +.show > .btn-outline-dark.dropdown-toggle {
    +  color: #fff;
    +  background-color: #343a40;
    +  border-color: #343a40;
    +}
    +
    +.btn-outline-dark:not(:disabled):not(.disabled):active:focus,
    +.btn-outline-dark:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-outline-dark.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
    +}
    +
    +.btn-link {
    +  font-weight: 400;
    +  color: #007bff;
    +  text-decoration: none;
    +}
    +
    +.btn-link:hover {
    +  color: #0056b3;
    +  text-decoration: underline;
    +}
    +
    +.btn-link:focus,
    +.btn-link.focus {
    +  text-decoration: underline;
    +}
    +
    +.btn-link:disabled,
    +.btn-link.disabled {
    +  color: #6c757d;
    +  pointer-events: none;
    +}
    +
    +.btn-lg,
    +.btn-group-lg > .btn {
    +  padding: 0.5rem 1rem;
    +  font-size: 1.25rem;
    +  line-height: 1.5;
    +  border-radius: 0.3rem;
    +}
    +
    +.btn-sm,
    +.btn-group-sm > .btn {
    +  padding: 0.25rem 0.5rem;
    +  font-size: 0.875rem;
    +  line-height: 1.5;
    +  border-radius: 0.2rem;
    +}
    +
    +.btn-block {
    +  display: block;
    +  width: 100%;
    +}
    +
    +.btn-block + .btn-block {
    +  margin-top: 0.5rem;
    +}
    +
    +/* Prevents green disabled button */
    +
    +.btn-primary[disabled] {
    +  background-color: #007bff !important;
    +  opacity: 0.4;
    +}
    +
    +/* Manage disabled red */
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +/* some custom buttons design */
    +
    +.btn-danger {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +  box-shadow: inset 0 -1px 0 #ba202f;
    +}
    +
    +.btn-danger:hover {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger:focus,
    +.btn-danger.focus {
    +  color: #fff;
    +  background-color: #c82333;
    +  border-color: #bd2130;
    +}
    +
    +.btn-danger.disabled,
    +.btn-danger:disabled {
    +  color: #fff;
    +  background-color: #dc3545;
    +  border-color: #dc3545;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active,
    +.btn-danger:not(:disabled):not(.disabled).active,
    +.show > .btn-danger.dropdown-toggle {
    +  color: #fff;
    +  background-color: #bd2130;
    +  border-color: #b21f2d;
    +}
    +
    +.btn-danger:not(:disabled):not(.disabled):active:focus,
    +.btn-danger:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-danger.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);
    +}
    +
    +.btn-danger[disabled] {
    +  background-color: #dc3545 !important;
    +  opacity: 0.4;
    +}
    +
    +.btn-warning {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +  box-shadow: inset 0 -1px 0 #e0a800;
    +}
    +
    +.btn-warning:hover {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +}
    +
    +.btn-warning:focus,
    +.btn-warning.focus {
    +  color: #212529;
    +  background-color: #e0a800;
    +  border-color: #d39e00;
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-warning.disabled,
    +.btn-warning:disabled {
    +  color: #212529;
    +  background-color: #ffc107;
    +  border-color: #ffc107;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active,
    +.btn-warning:not(:disabled):not(.disabled).active,
    +.show > .btn-warning.dropdown-toggle {
    +  color: #212529;
    +  background-color: #d39e00;
    +  border-color: #c69500;
    +}
    +
    +.btn-warning:not(:disabled):not(.disabled):active:focus,
    +.btn-warning:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-warning.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);
    +}
    +
    +.btn-info {
    +  color: #fff;
    +  background-color: #007bff;
    +  border-color: #007bff;
    +  box-shadow: inset 0 -1px 0 #138496;
    +}
    +
    +.btn-info:hover {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:focus,
    +.btn-info.focus {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +.btn-info.disabled,
    +.btn-info:disabled {
    +  color: #fff;
    +  /*  background-color: #007bff;
    +      border-color: #007bff; */
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active,
    +.btn-info:not(:disabled):not(.disabled).active,
    +.show > .btn-info.dropdown-toggle {
    +  color: #fff;
    +  background-color: #0066ff;
    +  border-color: #0066ff;
    +}
    +
    +.btn-info:not(:disabled):not(.disabled):active:focus,
    +.btn-info:not(:disabled):not(.disabled).active:focus,
    +.show > .btn-info.dropdown-toggle:focus {
    +  box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);
    +}
    +
    +/* Allow modals in simple xml dashboards */
    +.modal {
    +  display: none;
    +  margin-top: -1.5%;
    +}
    +
    +/* Some custom modal window sizes */
    +
    +.modal[class^="custom-modal"] {
    +  left: 50%;
    +  border: 1px solid green;
    +  margin-top: -1.5%;
    +}
    +
    +.custom-modal-30 {
    +  width: 30%;
    +  margin-left: -15%;
    +}
    +
    +.custom-modal-50 {
    +  width: 50%;
    +  margin-left: -25%;
    +}
    +
    +.custom-modal-60 {
    +  width: 60%;
    +  margin-left: -30%;
    +}
    +
    +.custom-modal-70 {
    +  width: 70%;
    +  margin-left: -35%;
    +}
    +
    +.custom-modal-80 {
    +  width: 80%;
    +  margin-left: -40%;
    +}
    +
    +.custom-modal-90 {
    +  width: 90%;
    +  margin-left: -45%;
    +}
    +
    +.custom-modal-96 {
    +  width: 96%;
    +  margin-left: -48%;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_v2.js b/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_v2.js
    new file mode 100644
    index 0000000..3ed8dfc
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/manage_template_alerting_threshold_v2.js
    @@ -0,0 +1,880 @@
    +const { Callbacks, getJSON, get } = require("jquery");
    +
    +require([
    +  "jquery",
    +  "underscore",
    +  "splunkjs/mvc",
    +  "splunkjs/mvc/utils",
    +  "splunkjs/mvc/searchcontrolsview",
    +  "splunkjs/mvc/searchmanager",
    +  "splunkjs/mvc/postprocessmanager",
    +  "splunkjs/mvc/dropdownview",
    +  "splunkjs/mvc/multidropdownview",
    +  "splunkjs/mvc/tableview",
    +  "splunkjs/mvc/eventsviewerview",
    +  "splunkjs/mvc/textinputview",
    +  "splunkjs/mvc/singleview",
    +  "splunkjs/mvc/chartview",
    +  "splunkjs/mvc/resultslinkview",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/visualizationregistry",
    +  "splunkjs/mvc/simpleform/input/linklist",
    +  "splunkjs/mvc/simpleform/input/text",
    +  "splunkjs/mvc/simpleform/input/timerange",
    +  "splunkjs/mvc/simpleform/input/multiselect",
    +  "splunkjs/mvc/simpleform/input/dropdown",
    +  "splunkjs/mvc/simpleform/input/checkboxgroup",
    +  "splunkjs/mvc/simplexml/element/table",
    +  "splunkjs/mvc/simplexml/element/single",
    +  "splunkjs/mvc/simplexml/element/event",
    +  "splunkjs/mvc/simplexml/element/visualization",
    +  "splunkjs/mvc/simpleform/formutils",
    +  "splunkjs/mvc/simplexml/eventhandler",
    +  "splunkjs/mvc/simplexml/searcheventhandler",
    +  "splunkjs/mvc/simplexml/ready!",
    +], function (
    +  $,
    +  _,
    +  mvc,
    +  utils,
    +  SearchControlsView,
    +  SearchManager,
    +  PostProcessManager,
    +  DropdownView,
    +  MultiDropdownView,
    +  TableView,
    +  EventsViewer,
    +  TextInputView,
    +  SingleView,
    +  ChartView,
    +  ResultsLinkView,
    +  SearchEventHandler,
    +  VisualizationRegistry,
    +  LinkListInput,
    +  TextInput,
    +  TimeRangeInput,
    +  MultiSelectInput,
    +  DropdownInput,
    +  CheckboxGroupInput,
    +  TableElement,
    +  VisualizationElement,
    +  SingleElement,
    +  EventElement,
    +  FormUtils,
    +  EventHandler,
    +  SearchEventHandler
    +) {
    +  //
    +  // START
    +  //
    +
    +  // tokens
    +
    +  var defaultTokenModel = mvc.Components.getInstance("default", {
    +    create: true,
    +  });
    +  var submittedTokenModel = mvc.Components.getInstance("submitted", {
    +    create: true,
    +  });
    +
    +  function setToken(name, value) {
    +    defaultTokenModel.set(name, value);
    +    submittedTokenModel.set(name, value);
    +  }
    +
    +  function getToken(name) {
    +    var ret = null;
    +    if (defaultTokenModel.get(name) != undefined) {
    +      ret = defaultTokenModel.get(name);
    +    } else if (submittedTokenModel.get(name) != undefined) {
    +      ret = submittedTokenModel.get(name);
    +    }
    +    return ret;
    +  }
    +
    +  function unsetToken(name) {
    +    defaultTokenModel.unset(name);
    +    submittedTokenModel.unset(name);
    +  }
    +
    +  // close all opened modals
    +  function closeModals() {
    +    $(".modal").modal("hide");
    +  }
    +
    +  // Returns true if numeric
    +  function isNumeric(n) {
    +    return !isNaN(parseFloat(n)) && isFinite(n) && n > 0;
    +  }
    +
    +  // searches
    +
    +  var search1 = new SearchManager(
    +    {
    +      id: "search1",
    +      earliest_time: "-5m",
    +      sample_ratio: 1,
    +      status_buckets: 0,
    +      cancelOnUnload: true,
    +      latest_time: "now",
    +      search: "| inputlookup nmon_alerting_threshold_template | stats count",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search2 = new SearchManager(
    +    {
    +      id: "search2",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_alerting_threshold_template | search frameID=$search_frameID$ | eval KeyID = _key | table KeyID,frameID,* | eval max_cpu_percent=alert_cpu_max_percent, max_phy_percent=alert_physical_memory_max_percent, max_vir_percent=alert_virtual_memory_max_percent",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search3 = new SearchManager(
    +    {
    +      id: "search3",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_alerting_threshold_template | stats dc(frameID) as frameID",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  var search4 = new SearchManager(
    +    {
    +      id: "search4",
    +      earliest_time: "-5m",
    +      status_buckets: 0,
    +      sample_ratio: 1,
    +      latest_time: "now",
    +      cancelOnUnload: true,
    +      search:
    +        "| inputlookup nmon_frameID_mapping | search frameID=$input_frameID_search_frameid$ serialnum=$input_frameID_search_serialnum$ host=$input_frameID_search_host$ host_description=$input_frameID_search_host_description$ | table frameID,serialnum,host,host_description,*",
    +      app: utils.getCurrentApp(),
    +      auto_cancel: 90,
    +      preview: true,
    +      runWhenTimeIsUndefined: false,
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  );
    +
    +  function updateAllSearches() {
    +    search1.startSearch();
    +    search2.startSearch();
    +    search3.startSearch();
    +    search4.startSearch();
    +  }
    +
    +  // single views
    +
    +  var element_unset_exclusions = new SingleView(
    +    {
    +      id: "element_unset_exclusions",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of threshold configured",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search1",
    +      el: $("#element_unset_exclusions"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  var element_nb_hosts = new SingleView(
    +    {
    +      id: "element_nb_hosts",
    +      unitPosition: "after",
    +      numberPrecision: "0",
    +      drilldown: "all",
    +      useColors: "1",
    +      trendDisplayMode: "absolute",
    +      rangeValues: "[0]",
    +      colorBy: "value",
    +      showTrendIndicator: "1",
    +      showSparkline: "1",
    +      colorMode: "none",
    +      trendColorInterpretation: "standard",
    +      underLabel: "Number of frameID with threshold configured",
    +      useThousandSeparators: "1",
    +      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
    +      managerid: "search3",
    +      el: $("#element_nb_hosts"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  // link input
    +  var inputLink = new LinkListInput(
    +    {
    +      id: "inputLink",
    +      choices: [
    +        {
    +          value: "template_thresholds",
    +          label: "Template thresholds collection",
    +        },
    +        {
    +          value: "frameid_collection",
    +          label: "FrameID current collection",
    +        },
    +      ],
    +      default: "template_thresholds",
    +      searchWhenChanged: true,
    +      selectFirstChoice: false,
    +      initialValue: "template_thresholds",
    +      value: "$form.inputLink$",
    +      el: $("#inputLink"),
    +    },
    +    {
    +      tokens: true,
    +    }
    +  ).render();
    +
    +  inputLink.on("change", function (newValue) {
    +    setToken("inputLink", newValue);
    +  });
    +
    +  inputLink.on("valueChange", function (e) {
    +    if (e.value === "template_thresholds") {
    +      // show and hide elements
    +      $("#tableParent1").css("display", "inherit");
    +      $("#tableParent2").css("display", "none");
    +    } else if (e.value === "frameid_collection") {
    +      // show and hide elements
    +      $("#tableParent1").css("display", "none");
    +      $("#tableParent2").css("display", "inherit");
    +    }
    +  });
    +
    +  // tables
    +
    +  var element_table_show_lookup_content = new TableElement(
    +    {
    +      id: "element_table_show_lookup_content",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "row",
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search2",
    +      el: $("#element_table_show_lookup_content"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  element_table_show_lookup_content.on("click", function (e) {
    +    if (e.field !== undefined) {
    +      e.preventDefault();
    +      // set tk_keyid
    +      setToken("tk_keyid", e.data["row.KeyID"]);
    +      // Populate input forms
    +      setToken("form.input_update_frameid", e.data["row.frameID"]);
    +      setToken(
    +        "form.input_update_alert_cpu_max_percent",
    +        e.data["row.alert_cpu_max_percent"]
    +      );
    +      setToken(
    +        "form.input_update_alert_cpu_min_time_seconds",
    +        e.data["row.alert_cpu_min_time_seconds"]
    +      );
    +      setToken(
    +        "form.input_update_alert_physical_memory_max_percent",
    +        e.data["row.alert_physical_memory_max_percent"]
    +      );
    +      setToken(
    +        "form.input_update_alert_physical_memory_min_time_seconds",
    +        e.data["row.alert_physical_memory_min_time_seconds"]
    +      );
    +      setToken(
    +        "form.input_update_alert_virtual_memory_max_percent",
    +        e.data["row.alert_virtual_memory_max_percent"]
    +      );
    +      setToken(
    +        "form.input_update_alert_virtual_memory_min_time_seconds",
    +        e.data["row.alert_virtual_memory_min_time_seconds"]
    +      );
    +      $("#modal_update_entity").modal();
    +    }
    +  });
    +
    +  var element_table_show_frameID_lookup_content = new TableElement(
    +    {
    +      id: "element_table_show_frameID_lookup_content",
    +      count: 10,
    +      dataOverlayMode: "none",
    +      drilldown: "none",
    +      percentagesRow: "false",
    +      rowNumbers: "false",
    +      totalsRow: "false",
    +      wrap: "true",
    +      managerid: "search4",
    +      el: $("#element_table_show_frameID_lookup_content"),
    +    },
    +    { tokens: true, tokenNamespace: "submitted" }
    +  ).render();
    +
    +  // inputs for template search purposes
    +
    +  var input_search_frameid = new TextInput(
    +    {
    +      id: "input_search_frameid",
    +      value: "$form.search_frameID$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_search_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_search_frameid.on("change", function (newValue) {
    +    setToken("search_frameID", newValue);
    +  });
    +
    +  // search frameID mapping
    +
    +  var input_frameID_search_frameid = new TextInput(
    +    {
    +      id: "input_frameID_search_frameid",
    +      value: "$form.input_frameID_search_frameid$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_frameID_search_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_frameID_search_frameid.on("change", function (newValue) {
    +    setToken("input_frameID_search_frameid", newValue);
    +  });
    +
    +  var input_frameID_search_serialnum = new TextInput(
    +    {
    +      id: "input_frameID_search_serialnum",
    +      value: "$form.input_frameID_search_serialnum$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_frameID_search_serialnum"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_frameID_search_serialnum.on("change", function (newValue) {
    +    setToken("input_frameID_search_serialnum", newValue);
    +  });
    +
    +  var input_frameID_search_host = new TextInput(
    +    {
    +      id: "input_frameID_search_host",
    +      value: "$form.input_frameID_search_host$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_frameID_search_host"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_frameID_search_host.on("change", function (newValue) {
    +    setToken("input_frameID_search_host", newValue);
    +  });
    +
    +  var input_frameID_search_host_description = new TextInput(
    +    {
    +      id: "input_frameID_search_host_description",
    +      value: "$form.input_frameID_search_host_description$",
    +      default: "*",
    +      searchWhenChanged: true,
    +      el: $("#input_frameID_search_host_description"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_frameID_search_host_description.on("change", function (newValue) {
    +    setToken("input_frameID_search_host_description", newValue);
    +  });
    +
    +  // add new entries
    +
    +  var input_add_frameid = new TextInput(
    +    {
    +      id: "input_add_frameid",
    +      value: "$form.input_add_frameid$",
    +      el: $("#input_add_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_frameid.on("change", function (newValue) {
    +    setToken("input_add_frameid", newValue);
    +  });
    +
    +  var input_add_alert_cpu_max_percent = new TextInput(
    +    {
    +      id: "input_add_alert_cpu_max_percent",
    +      value: "$form.input_add_alert_cpu_max_percent$",
    +      default: "90",
    +      el: $("#input_add_alert_cpu_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_cpu_max_percent.on("change", function (newValue) {
    +    setToken("input_add_alert_cpu_max_percent", newValue);
    +  });
    +
    +  var input_add_alert_cpu_min_time_seconds = new TextInput(
    +    {
    +      id: "input_add_alert_cpu_min_time_seconds",
    +      value: "$form.input_add_alert_cpu_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_add_alert_cpu_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_cpu_min_time_seconds.on("change", function (newValue) {
    +    setToken("input_add_alert_cpu_min_time_seconds", newValue);
    +  });
    +
    +  var input_add_alert_physical_memory_max_percent = new TextInput(
    +    {
    +      id: "input_add_alert_physical_memory_max_percent",
    +      value: "$form.input_add_alert_physical_memory_max_percent$",
    +      default: "90",
    +      el: $("#input_add_alert_physical_memory_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_physical_memory_max_percent.on("change", function (newValue) {
    +    setToken("input_add_alert_physical_memory_max_percent", newValue);
    +  });
    +
    +  var input_add_alert_physical_memory_min_time_seconds = new TextInput(
    +    {
    +      id: "input_add_alert_physical_memory_min_time_seconds",
    +      value: "$form.input_add_alert_physical_memory_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_add_alert_physical_memory_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_physical_memory_min_time_seconds.on(
    +    "change",
    +    function (newValue) {
    +      setToken("input_add_alert_physical_memory_min_time_seconds", newValue);
    +    }
    +  );
    +
    +  var input_add_alert_virtual_memory_max_percent = new TextInput(
    +    {
    +      id: "input_add_alert_virtual_memory_max_percent",
    +      value: "$form.input_add_alert_virtual_memory_max_percent$",
    +      default: "40",
    +      el: $("#input_add_alert_virtual_memory_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_virtual_memory_max_percent.on("change", function (newValue) {
    +    setToken("input_add_alert_virtual_memory_max_percent", newValue);
    +  });
    +
    +  var input_add_alert_virtual_memory_min_time_seconds = new TextInput(
    +    {
    +      id: "input_add_alert_virtual_memory_min_time_seconds",
    +      value: "$form.input_add_alert_virtual_memory_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_add_alert_virtual_memory_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_add_alert_virtual_memory_min_time_seconds.on(
    +    "change",
    +    function (newValue) {
    +      setToken("input_add_alert_virtual_memory_min_time_seconds", newValue);
    +    }
    +  );
    +
    +  // update entries
    +  var input_update_frameid = new TextInput(
    +    {
    +      id: "input_update_frameid",
    +      value: "$form.input_update_frameid$",
    +      el: $("#input_update_frameid"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_frameid.on("change", function (newValue) {
    +    setToken("input_update_frameid", newValue);
    +  });
    +
    +  var input_update_alert_cpu_max_percent = new TextInput(
    +    {
    +      id: "input_update_alert_cpu_max_percent",
    +      value: "$form.input_update_alert_cpu_max_percent$",
    +      default: "90",
    +      el: $("#input_update_alert_cpu_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_cpu_max_percent.on("change", function (newValue) {
    +    setToken("input_update_alert_cpu_max_percent", newValue);
    +  });
    +
    +  var input_update_alert_cpu_min_time_seconds = new TextInput(
    +    {
    +      id: "input_update_alert_cpu_min_time_seconds",
    +      value: "$form.input_update_alert_cpu_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_update_alert_cpu_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_cpu_min_time_seconds.on("change", function (newValue) {
    +    setToken("input_update_alert_cpu_min_time_seconds", newValue);
    +  });
    +
    +  var input_update_alert_physical_memory_max_percent = new TextInput(
    +    {
    +      id: "input_update_alert_physical_memory_max_percent",
    +      value: "$form.input_update_alert_physical_memory_max_percent$",
    +      default: "90",
    +      el: $("#input_update_alert_physical_memory_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_physical_memory_max_percent.on(
    +    "change",
    +    function (newValue) {
    +      setToken("input_update_alert_physical_memory_max_percent", newValue);
    +    }
    +  );
    +
    +  var input_update_alert_physical_memory_min_time_seconds = new TextInput(
    +    {
    +      id: "input_update_alert_physical_memory_min_time_seconds",
    +      value: "$form.input_update_alert_physical_memory_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_update_alert_physical_memory_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_physical_memory_min_time_seconds.on(
    +    "change",
    +    function (newValue) {
    +      setToken("input_update_alert_physical_memory_min_time_seconds", newValue);
    +    }
    +  );
    +
    +  var input_update_alert_virtual_memory_max_percent = new TextInput(
    +    {
    +      id: "input_update_alert_virtual_memory_max_percent",
    +      value: "$form.input_update_alert_virtual_memory_max_percent$",
    +      default: "40",
    +      el: $("#input_update_alert_virtual_memory_max_percent"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_virtual_memory_max_percent.on(
    +    "change",
    +    function (newValue) {
    +      setToken("input_update_alert_virtual_memory_max_percent", newValue);
    +    }
    +  );
    +
    +  var input_update_alert_virtual_memory_min_time_seconds = new TextInput(
    +    {
    +      id: "input_update_alert_virtual_memory_min_time_seconds",
    +      value: "$form.input_update_alert_virtual_memory_min_time_seconds$",
    +      default: "300",
    +      el: $("#input_update_alert_virtual_memory_min_time_seconds"),
    +    },
    +    { tokens: true }
    +  ).render();
    +
    +  input_update_alert_virtual_memory_min_time_seconds.on(
    +    "change",
    +    function (newValue) {
    +      setToken("input_update_alert_virtual_memory_min_time_seconds", newValue);
    +    }
    +  );
    +
    +  // interactions
    +
    +  // help
    +  $("#btn_help")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_help").modal();
    +    });
    +
    +  // add new entry
    +  $("#btn_add_new_template")
    +    .unbind()
    +    .click(function () {
    +      $("#modal_add_entity").modal();
    +    });
    +
    +  // submit new entry
    +  $("#btn_submit_new_entity").click(function () {
    +    var frameID = getToken("input_add_frameid");
    +    var alert_cpu_max_percent = getToken("input_add_alert_cpu_max_percent");
    +    var alert_cpu_min_time_seconds = getToken(
    +      "input_add_alert_cpu_min_time_seconds"
    +    );
    +    var alert_physical_memory_max_percent = getToken(
    +      "input_add_alert_physical_memory_max_percent"
    +    );
    +    var alert_physical_memory_min_time_seconds = getToken(
    +      "input_add_alert_physical_memory_min_time_seconds"
    +    );
    +    var alert_virtual_memory_max_percent = getToken(
    +      "input_add_alert_virtual_memory_max_percent"
    +    );
    +    var alert_virtual_memory_min_time_seconds = getToken(
    +      "input_add_alert_virtual_memory_min_time_seconds"
    +    );
    +
    +    // new record
    +    record = {
    +      frameID: frameID,
    +      alert_cpu_max_percent: alert_cpu_max_percent,
    +      alert_cpu_min_time_seconds: alert_cpu_min_time_seconds,
    +      alert_physical_memory_max_percent: alert_physical_memory_max_percent,
    +      alert_physical_memory_min_time_seconds:
    +        alert_physical_memory_min_time_seconds,
    +      alert_virtual_memory_max_percent: alert_virtual_memory_max_percent,
    +      alert_virtual_memory_min_time_seconds:
    +        alert_virtual_memory_min_time_seconds,
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_threshold_template/";
    +
    +    if (
    +      frameID &&
    +      frameID.length &&
    +      alert_cpu_max_percent &&
    +      alert_cpu_max_percent.length &&
    +      isNumeric(alert_cpu_max_percent) &&
    +      alert_cpu_min_time_seconds &&
    +      alert_cpu_min_time_seconds.length &&
    +      isNumeric(alert_cpu_min_time_seconds) &&
    +      alert_physical_memory_max_percent &&
    +      alert_physical_memory_max_percent.length &&
    +      isNumeric(alert_physical_memory_max_percent) &&
    +      alert_physical_memory_min_time_seconds &&
    +      alert_physical_memory_min_time_seconds.length &&
    +      isNumeric(alert_physical_memory_min_time_seconds) &&
    +      alert_virtual_memory_max_percent &&
    +      alert_virtual_memory_max_percent.length &&
    +      isNumeric(alert_virtual_memory_max_percent) &&
    +      alert_virtual_memory_min_time_seconds &&
    +      alert_virtual_memory_min_time_seconds.length &&
    +      isNumeric(alert_virtual_memory_min_time_seconds)
    +    ) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  // delete entity
    +  $("#btn_submit_delete_entity").click(function () {
    +    var tk_keyid = getToken("tk_keyid");
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_threshold_template/" +
    +      tk_keyid;
    +
    +    if (tk_keyid && tk_keyid.length) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "DELETE",
    +        async: true,
    +        contentType: "application/json",
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    }
    +  });
    +
    +  // update entry
    +  $("#btn_submit_update_entity").click(function () {
    +    var tk_keyid = getToken("tk_keyid");
    +    var frameID = getToken("input_update_frameid");
    +    var alert_cpu_max_percent = getToken("input_update_alert_cpu_max_percent");
    +    var alert_cpu_min_time_seconds = getToken(
    +      "input_update_alert_cpu_min_time_seconds"
    +    );
    +    var alert_physical_memory_max_percent = getToken(
    +      "input_update_alert_physical_memory_max_percent"
    +    );
    +    var alert_physical_memory_min_time_seconds = getToken(
    +      "input_update_alert_physical_memory_min_time_seconds"
    +    );
    +    var alert_virtual_memory_max_percent = getToken(
    +      "input_update_alert_virtual_memory_max_percent"
    +    );
    +    var alert_virtual_memory_min_time_seconds = getToken(
    +      "input_update_alert_virtual_memory_min_time_seconds"
    +    );
    +
    +    // new record
    +    record = {
    +      frameID: frameID,
    +      alert_cpu_max_percent: alert_cpu_max_percent,
    +      alert_cpu_min_time_seconds: alert_cpu_min_time_seconds,
    +      alert_physical_memory_max_percent: alert_physical_memory_max_percent,
    +      alert_physical_memory_min_time_seconds:
    +        alert_physical_memory_min_time_seconds,
    +      alert_virtual_memory_max_percent: alert_virtual_memory_max_percent,
    +      alert_virtual_memory_min_time_seconds:
    +        alert_virtual_memory_min_time_seconds,
    +    };
    +
    +    // Create the endpoint URL
    +    var myendpoint_URl =
    +      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_alerting_threshold_template/" +
    +      tk_keyid;
    +
    +    if (
    +      frameID &&
    +      frameID.length &&
    +      alert_cpu_max_percent &&
    +      alert_cpu_max_percent.length &&
    +      isNumeric(alert_cpu_max_percent) &&
    +      alert_cpu_min_time_seconds &&
    +      alert_cpu_min_time_seconds.length &&
    +      isNumeric(alert_cpu_min_time_seconds) &&
    +      alert_physical_memory_max_percent &&
    +      alert_physical_memory_max_percent.length &&
    +      isNumeric(alert_physical_memory_max_percent) &&
    +      alert_physical_memory_min_time_seconds &&
    +      alert_physical_memory_min_time_seconds.length &&
    +      isNumeric(alert_physical_memory_min_time_seconds) &&
    +      alert_virtual_memory_max_percent &&
    +      alert_virtual_memory_max_percent.length &&
    +      isNumeric(alert_virtual_memory_max_percent) &&
    +      alert_virtual_memory_min_time_seconds &&
    +      alert_virtual_memory_min_time_seconds.length &&
    +      isNumeric(alert_virtual_memory_min_time_seconds)
    +    ) {
    +      $.ajax({
    +        url: myendpoint_URl,
    +        type: "POST",
    +        async: true,
    +        contentType: "application/json",
    +        data: JSON.stringify(record),
    +        success: function (returneddata) {
    +          // Return to modal
    +          $("#modal_generic_success").modal();
    +          // update searches
    +          updateAllSearches();
    +        },
    +        error: function (xhr, textStatus, error) {
    +          message = "Error Updating!" + xhr + textStatus + error;
    +          // Hide main modal
    +          closeModals();
    +          $("#modal_generic_error")
    +            .find(".modal-error-message p")
    +            .text(message);
    +          $("#modal_generic_error").modal();
    +        },
    +      });
    +    } else {
    +      message =
    +        "Error Updating! Please check your inputs: " + JSON.stringify(record);
    +      // Hide main modal
    +      closeModals();
    +      $("#modal_generic_error").find(".modal-error-message p").text(message);
    +      $("#modal_generic_error").modal();
    +    }
    +  });
    +
    +  //
    +  // END
    +  //
    +});
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/metric_name.js b/deployment-apps/metricator-for-nmon/appserver/static/metric_name.js
    new file mode 100644
    index 0000000..c621442
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/metric_name.js
    @@ -0,0 +1,30 @@
    +(function() {
    +  require([
    +    "underscore",
    +    "jquery",
    +    "splunkjs/mvc",
    +    "appUtils",
    +    "splunkjs/ready!",
    +    "splunkjs/mvc/simplexml/ready!",
    +  ], function(_, $, mvc, appUtils) {
    +
    +    /////////////////////////////////////////
    +    ///  Start Main Code Here
    +    /////////////////////////////////////////
    +
    +    var ref = appUtils.getTokenModels();
    +    var defaultTokenModel = ref[0];
    +    var submittedTokenModel = ref[1];
    +
    +    appUtils.checkEmptyTokenFocus("metric_name", appUtils.getToken("metric_name"));
    +
    +    defaultTokenModel.on("change:metric_name", function(model, value, options) {
    +      appUtils.checkEmptyTokenFocus("metric_name", value);
    +      if (typeof value !== 'undefined' && value.toString().trim() === "") {
    +        appUtils.setToken("form.metric_name", undefined, true);
    +      }
    +    });
    +
    +    appUtils.submitTokens();
    +  });
    +}).call(this);
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/modal.js b/deployment-apps/metricator-for-nmon/appserver/static/modal.js
    new file mode 100644
    index 0000000..31c1719
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/modal.js
    @@ -0,0 +1,61 @@
    +require(['splunkjs/mvc/simplexml/ready!'], function() {
    +    require(['splunkjs/ready!', 'splunkjs/mvc'], function(mvc) {
    +
    +        // For each button with the class "custom-sub-nav"
    +        $('.custom-modal').each(function() {
    +            var $btn_group = $(this);
    +
    +            /* for each button in this nav with the class "modal":
    +                    - retrieve the modal window ID from data-modal-name attr of the button
    +                    - open the modal
    +               This trick is required since Splunk 8.0.0 which stripes out the native data-togle
    +
    +	       Example:
    +
    +	       <!-- Button trigger modal -->
    +               <div class="custom-modal">
    +                 <button type="button" class="btn btn-primary" data-modal-name="exampleModal">
    +                  Launch demo modal
    +                 </button>
    +               </div>
    +
    +               <!-- Modal -->
    +               <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    +                 <div class="modal-dialog" role="document">
    +                  <div class="modal-content">
    +                    <div class="modal-header">
    +                      <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
    +                      <button type="button" class="close" data-dismiss="modal" aria-label="Close">
    +                        <span aria-hidden="true">&amp;times;</span>
    +                      </button>
    +                    </div>
    +                    <div class="modal-body">
    +                      This is a modal window test!
    +                    </div>
    +                    <div class="modal-footer">
    +                      <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
    +                      <button type="button" class="btn btn-primary">Save changes</button>
    +                    </div>
    +                  </div>
    +                </div>
    +              </div>
    +
    +            */
    +
    +            $btn_group.find('button').on('click', function() {
    +                var $btn = $(this);
    +                var modal_name = $btn.attr('data-modal-name');
    +                var modal_id = "#" + modal_name
    +                $(modal_id).modal();
    +            });
    +
    +            $btn_group.find('a').on('click', function() {
    +                var $btn = $(this);
    +                var modal_name = $btn.attr('data-modal-name');
    +                var modal_id = "#" + modal_name
    +                $(modal_id).modal();
    +            });
    +
    +        });
    +    });
    +});
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/modal_msg.js b/deployment-apps/metricator-for-nmon/appserver/static/modal_msg.js
    new file mode 100644
    index 0000000..d50e13b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/modal_msg.js
    @@ -0,0 +1,30 @@
    +/**
    + * @fileoverview Setup the paths and load the Modal Text Message feature properly load components
    + * @author Ryan Thibodeaux
    + * @version 1.0.1
    + */
    +
    +/* 
    + * Copyright (c) 2017, Ryan Thibodeaux. All Rights Reserved
    + * see included LICENSE file (BSD 3-clause) in the app's root directory
    + */
    +
    +(function() {
    +  "use strict";
    +
    +  // configure the RequrieJS paths
    +  require.config({
    +    paths: {
    +      "ModalTextMsg" : "../app/metricator-for-nmon/components/modaltextmsg/modaltextmsg"
    +    }
    +  });
    +
    +  require([
    +    "/static/app/metricator-for-nmon/components/modaltextmsg/wrapper.js"
    +  ], function() { /* do nothing */ }, function(err) {
    +    // error callback
    +    // the error has a list of modules that failed
    +    var failedId = err.requireModules && err.requireModules[0];
    +    console.error("Error when loading Modal Text Message dependencies: ", err);
    +  });
    +}).call(this);
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/octamis_website.css b/deployment-apps/metricator-for-nmon/appserver/static/octamis_website.css
    new file mode 100644
    index 0000000..51db641
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/octamis_website.css
    @@ -0,0 +1,19702 @@
    +/* cyrillic-ext */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 300;
    +  src: local('Ubuntu Light'), local('Ubuntu-Light'), url(https://fonts.gstatic.com/s/ubuntu/v9/X_EdMnknKUltk57alVVbVxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
    +}
    +/* cyrillic */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 300;
    +  src: local('Ubuntu Light'), local('Ubuntu-Light'), url(https://fonts.gstatic.com/s/ubuntu/v9/nBF2d6Y3AbOwfkBM-9HcWBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
    +}
    +/* greek-ext */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 300;
    +  src: local('Ubuntu Light'), local('Ubuntu-Light'), url(https://fonts.gstatic.com/s/ubuntu/v9/CdlIlwqST01WNAKqZbtZkhJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+1F00-1FFF;
    +}
    +/* greek */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 300;
    +  src: local('Ubuntu Light'), local('Ubuntu-Light'), url(https://fonts.gstatic.com/s/ubuntu/v9/7k0RmqCN8EFxqS6sChuRzRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+0370-03FF;
    +}
    +/* latin-ext */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 300;
    +  src: local('Ubuntu Light'), local('Ubuntu-Light'), url(https://fonts.gstatic.com/s/ubuntu/v9/WtcvfJHWXKxx4x0kuS1koRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
    +}
    +/* latin */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 300;
    +  src: local('Ubuntu Light'), local('Ubuntu-Light'), url(https://fonts.gstatic.com/s/ubuntu/v9/_aijTyevf54tkVDLy-dlnFtXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
    +  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
    +}
    +/* cyrillic-ext */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 400;
    +  src: local('Ubuntu'), url(https://fonts.gstatic.com/s/ubuntu/v9/ODszJI8YqNw8V2xPulzjO_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
    +  unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
    +}
    +/* cyrillic */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 400;
    +  src: local('Ubuntu'), url(https://fonts.gstatic.com/s/ubuntu/v9/iQ9VJx1UMASKNiGywyyCXvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
    +  unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
    +}
    +/* greek-ext */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 400;
    +  src: local('Ubuntu'), url(https://fonts.gstatic.com/s/ubuntu/v9/WkvQmvwsfw_KKeau9SlQ2_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
    +  unicode-range: U+1F00-1FFF;
    +}
    +/* greek */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 400;
    +  src: local('Ubuntu'), url(https://fonts.gstatic.com/s/ubuntu/v9/gYAtqXUikkQjyJA1SnpDLvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
    +  unicode-range: U+0370-03FF;
    +}
    +/* latin-ext */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 400;
    +  src: local('Ubuntu'), url(https://fonts.gstatic.com/s/ubuntu/v9/Wu5Iuha-XnKDBvqRwQzAG_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
    +  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
    +}
    +/* latin */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 400;
    +  src: local('Ubuntu'), url(https://fonts.gstatic.com/s/ubuntu/v9/sDGTilo5QRsfWu6Yc11AXg.woff2) format('woff2');
    +  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
    +}
    +/* cyrillic-ext */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 500;
    +  src: local('Ubuntu Medium'), local('Ubuntu-Medium'), url(https://fonts.gstatic.com/s/ubuntu/v9/MLKvhAbswThSVACnSTWCpxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
    +}
    +/* cyrillic */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 500;
    +  src: local('Ubuntu Medium'), local('Ubuntu-Medium'), url(https://fonts.gstatic.com/s/ubuntu/v9/IiMFELcoPB-OzGzq14k4ehJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
    +}
    +/* greek-ext */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 500;
    +  src: local('Ubuntu Medium'), local('Ubuntu-Medium'), url(https://fonts.gstatic.com/s/ubuntu/v9/H2j4_4xA-HIuoc_A3BIwVBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+1F00-1FFF;
    +}
    +/* greek */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 500;
    +  src: local('Ubuntu Medium'), local('Ubuntu-Medium'), url(https://fonts.gstatic.com/s/ubuntu/v9/EtSRPnpS3nIR-zKYiR-sDBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+0370-03FF;
    +}
    +/* latin-ext */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 500;
    +  src: local('Ubuntu Medium'), local('Ubuntu-Medium'), url(https://fonts.gstatic.com/s/ubuntu/v9/gMhvhm-nVj1086DvGgmzBxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
    +}
    +/* latin */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 500;
    +  src: local('Ubuntu Medium'), local('Ubuntu-Medium'), url(https://fonts.gstatic.com/s/ubuntu/v9/OsJ2DjdpjqFRVUSto6IffFtXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
    +  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
    +}
    +/* cyrillic-ext */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 700;
    +  src: local('Ubuntu Bold'), local('Ubuntu-Bold'), url(https://fonts.gstatic.com/s/ubuntu/v9/oxrPYIm05JrY_0rFIEQ_oRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
    +}
    +/* cyrillic */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 700;
    +  src: local('Ubuntu Bold'), local('Ubuntu-Bold'), url(https://fonts.gstatic.com/s/ubuntu/v9/4z2U46_RRLOfkoHsWJG3vxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
    +}
    +/* greek-ext */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 700;
    +  src: local('Ubuntu Bold'), local('Ubuntu-Bold'), url(https://fonts.gstatic.com/s/ubuntu/v9/2vaWVxeAxHVkFcnCBCQCyRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+1F00-1FFF;
    +}
    +/* greek */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 700;
    +  src: local('Ubuntu Bold'), local('Ubuntu-Bold'), url(https://fonts.gstatic.com/s/ubuntu/v9/M-Ii49WH_TYYnOjQyLgTMBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+0370-03FF;
    +}
    +/* latin-ext */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 700;
    +  src: local('Ubuntu Bold'), local('Ubuntu-Bold'), url(https://fonts.gstatic.com/s/ubuntu/v9/nsLtvfQoT-rVwGTHHnkeJhJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
    +  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
    +}
    +/* latin */
    +@font-face {
    +  font-family: 'Ubuntu';
    +  font-style: normal;
    +  font-weight: 700;
    +  src: local('Ubuntu Bold'), local('Ubuntu-Bold'), url(https://fonts.gstatic.com/s/ubuntu/v9/0ihfXUL2emPh0ROJezvraFtXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
    +  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
    +}
    +
    +@charset "UTF-8";
    +
    +/* Bootstrap v3.3.5 */
    +html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
    +
    +/* Font Awesome 4.4.0 */
    +@font-face{font-family:'FontAwesome';src:url('fonts/fontawesome-webfont.eot?v=4.4.0');src:url('fonts/fontawesome-webfont.eot?#iefix&v=4.4.0') format('embedded-opentype'),url('fonts/fontawesome-webfont.woff2?v=4.4.0') format('woff2'),url('fonts/fontawesome-webfont.woff?v=4.4.0') format('woff'),url('fonts/fontawesome-webfont.ttf?v=4.4.0') format('truetype'),url('fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}
    +
    +/* Linea Icons */
    +@font-face {font-family:linea;src:url(fonts/linea.eot);src:url(fonts/linea.eot?#iefix) format("embedded-opentype"),url(fonts/linea.woff) format("woff"),url(fonts/linea.ttf) format("truetype"),url(fonts/linea.svg#linea) format("svg");font-weight:400;font-style:normal}[class*=" icons-"]:before,[class^=icons-]:before,[data-icons]:before{font-family:linea!important;font-style:normal!important;font-weight:400!important;font-variant:normal!important;text-transform:none!important;speak:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}[data-icons]:before{content:attr(data-icons)}.icons-basic-accelerator:before{content:"a"}.icons-basic-alarm:before{content:"b"}.icons-basic-anchor:before{content:"c"}.icons-basic-anticlockwise:before{content:"d"}.icons-basic-archive:before{content:"e"}.icons-basic-archive-full:before{content:"f"}.icons-basic-ban:before{content:"g"}.icons-basic-battery-charge:before{content:"h"}.icons-basic-battery-empty:before{content:"i"}.icons-basic-battery-full:before{content:"j"}.icons-basic-battery-half:before{content:"k"}.icons-basic-bolt:before{content:"l"}.icons-basic-book:before{content:"m"}.icons-basic-book-pen:before{content:"n"}.icons-basic-book-pencil:before{content:"o"}.icons-basic-bookmark:before{content:"p"}.icons-basic-calculator:before{content:"q"}.icons-basic-calendar:before{content:"r"}.icons-basic-cards-diamonds:before{content:"s"}.icons-basic-cards-hearts:before{content:"t"}.icons-basic-case:before{content:"u"}.icons-basic-chronometer:before{content:"v"}.icons-basic-clessidre:before{content:"w"}.icons-basic-clock:before{content:"x"}.icons-basic-clockwise:before{content:"y"}.icons-basic-cloud:before{content:"z"}.icons-basic-clubs:before{content:"A"}.icons-basic-compass:before{content:"B"}.icons-basic-cup:before{content:"C"}.icons-basic-diamonds:before{content:"D"}.icons-basic-display:before{content:"E"}.icons-basic-download:before{content:"F"}.icons-basic-exclamation:before{content:"G"}.icons-basic-eye:before{content:"H"}.icons-basic-eye-closed:before{content:"I"}.icons-basic-female:before{content:"J"}.icons-basic-flag1:before{content:"K"}.icons-basic-flag2:before{content:"L"}.icons-basic-floppydisk:before{content:"M"}.icons-basic-folder:before{content:"N"}.icons-basic-folder-multiple:before{content:"O"}.icons-basic-gear:before{content:"P"}.icons-basic-geolocalize-01:before{content:"Q"}.icons-basic-geolocalize-05:before{content:"R"}.icons-basic-globe:before{content:"S"}.icons-basic-gunsight:before{content:"T"}.icons-basic-hammer:before{content:"U"}.icons-basic-headset:before{content:"V"}.icons-basic-heart:before{content:"W"}.icons-basic-heart-broken:before{content:"X"}.icons-basic-helm:before{content:"Y"}.icons-basic-home:before{content:"Z"}.icons-basic-info:before{content:"0"}.icons-basic-ipod:before{content:"1"}.icons-basic-joypad:before{content:"2"}.icons-basic-key:before{content:"3"}.icons-basic-keyboard:before{content:"4"}.icons-basic-laptop:before{content:"5"}.icons-basic-life-buoy:before{content:"6"}.icons-basic-lightbulb:before{content:"7"}.icons-basic-link:before{content:"8"}.icons-basic-lock:before{content:"9"}.icons-basic-lock-open:before{content:"!"}.icons-basic-magic-mouse:before{content:"\""}.icons-basic-magnifier:before{content:"#"}.icons-basic-magnifier-minus:before{content:"$"}.icons-basic-magnifier-plus:before{content:"%"}.icons-basic-mail:before{content:"&"}.icons-basic-mail-multiple:before{content:"'"}.icons-basic-mail-open:before{content:"("}.icons-basic-mail-open-text:before{content:")"}.icons-basic-male:before{content:"*"}.icons-basic-map:before{content:"+"}.icons-basic-message:before{content:","}.icons-basic-message-multiple:before{content:"-"}.icons-basic-message-txt:before{content:"."}.icons-basic-mixer2:before{content:"/"}.icons-basic-mouse:before{content:":"}.icons-basic-notebook:before{content:";"}.icons-basic-notebook-pen:before{content:"<"}.icons-basic-notebook-pencil:before{content:"="}.icons-basic-paperplane:before{content:">"}.icons-basic-pencil-ruler:before{content:"?"}.icons-basic-pencil-ruler-pen:before{content:"@"}.icons-basic-photo:before{content:"["}.icons-basic-picture:before{content:"]"}.icons-basic-picture-multiple:before{content:"^"}.icons-basic-pin1:before{content:"_"}.icons-basic-pin2:before{content:"`"}.icons-basic-postcard:before{content:"{"}.icons-basic-postcard-multiple:before{content:"|"}.icons-basic-printer:before{content:"}"}.icons-basic-question:before{content:"~"}.icons-basic-rss:before{content:"\rss"}.icons-basic-server:before{content:"\e000"}.icons-basic-server2:before{content:"\e001"}.icons-basic-server-cloud:before{content:"\e002"}.icons-basic-server-download:before{content:"\e003"}.icons-basic-server-upload:before{content:"\e004"}.icons-basic-settings:before{content:"\e005"}.icons-basic-share:before{content:"\e006"}.icons-basic-sheet:before{content:"\e007"}.icons-basic-sheet-multiple:before{content:"\e008"}.icons-basic-sheet-pen:before{content:"\e009"}.icons-basic-sheet-pencil:before{content:"\e00a"}.icons-basic-sheet-txt:before{content:"\e00b"}.icons-basic-signs:before{content:"\e00c"}.icons-basic-smartphone:before{content:"\e00d"}.icons-basic-spades:before{content:"\e00e"}.icons-basic-spread:before{content:"\e00f"}.icons-basic-spread-bookmark:before{content:"\e010"}.icons-basic-spread-text:before{content:"\e011"}.icons-basic-spread-text-bookmark:before{content:"\e012"}.icons-basic-star:before{content:"\e013"}.icons-basic-tablet:before{content:"\e014"}.icons-basic-target:before{content:"\e015"}.icons-basic-todo:before{content:"\e016"}.icons-basic-todo-pen:before{content:"\e017"}.icons-basic-todo-pencil:before{content:"\e018"}.icons-basic-todo-txt:before{content:"\e019"}.icons-basic-todolist-pen:before{content:"\e01a"}.icons-basic-todolist-pencil:before{content:"\e01b"}.icons-basic-trashcan:before{content:"\e01c"}.icons-basic-trashcan-full:before{content:"\e01d"}.icons-basic-trashcan-refresh:before{content:"\e01e"}.icons-basic-trashcan-remove:before{content:"\e01f"}.icons-basic-upload:before{content:"\e020"}.icons-basic-usb:before{content:"\e021"}.icons-basic-video:before{content:"\e022"}.icons-basic-watch:before{content:"\e023"}.icons-basic-webpage:before{content:"\e024"}.icons-basic-webpage-img-txt:before{content:"\e025"}.icons-basic-webpage-multiple:before{content:"\e026"}.icons-basic-webpage-txt:before{content:"\e027"}.icons-basic-world:before{content:"\e028"}.icons-music-beginning-button:before{content:"\e029"}.icons-music-bell:before{content:"\e02a"}.icons-music-cd:before{content:"\e02b"}.icons-music-diapason:before{content:"\e02c"}.icons-music-eject-button:before{content:"\e02d"}.icons-music-end-button:before{content:"\e02e"}.icons-music-fastforward-button:before{content:"\e02f"}.icons-music-headphones:before{content:"\e030"}.icons-music-ipod:before{content:"\e031"}.icons-music-loudspeaker:before{content:"\e032"}.icons-music-microphone:before{content:"\e033"}.icons-music-microphone-old:before{content:"\e034"}.icons-music-mixer:before{content:"\e035"}.icons-music-mute:before{content:"\e036"}.icons-music-note-multiple:before{content:"\e037"}.icons-music-note-single:before{content:"\e038"}.icons-music-pause-button:before{content:"\e039"}.icons-music-play-button:before{content:"\e03a"}.icons-music-playlist:before{content:"\e03b"}.icons-music-radio-ghettoblaster:before{content:"\e03c"}.icons-music-radio-portable:before{content:"\e03d"}.icons-music-record:before{content:"\e03e"}.icons-music-recordplayer:before{content:"\e03f"}.icons-music-repeat-button:before{content:"\e040"}.icons-music-rewind-button:before{content:"\e041"}.icons-music-shuffle-button:before{content:"\e042"}.icons-music-stop-button:before{content:"\e043"}.icons-music-tape:before{content:"\e044"}.icons-music-volume-down:before{content:"\e045"}.icons-music-volume-up:before{content:"\e046"}.icons-ecommerce-bag:before{content:"\e047"}.icons-ecommerce-bag-check:before{content:"\e048"}.icons-ecommerce-bag-cloud:before{content:"\e049"}.icons-ecommerce-bag-download:before{content:"\e04a"}.icons-ecommerce-bag-minus:before{content:"\e04b"}.icons-ecommerce-bag-plus:before{content:"\e04c"}.icons-ecommerce-bag-refresh:before{content:"\e04d"}.icons-ecommerce-bag-remove:before{content:"\e04e"}.icons-ecommerce-bag-search:before{content:"\e04f"}.icons-ecommerce-bag-upload:before{content:"\e050"}.icons-ecommerce-banknote:before{content:"\e051"}.icons-ecommerce-banknotes:before{content:"\e052"}.icons-ecommerce-basket:before{content:"\e053"}.icons-ecommerce-basket-check:before{content:"\e054"}.icons-ecommerce-basket-cloud:before{content:"\e055"}.icons-ecommerce-basket-download:before{content:"\e056"}.icons-ecommerce-basket-minus:before{content:"\e057"}.icons-ecommerce-basket-plus:before{content:"\e058"}.icons-ecommerce-basket-refresh:before{content:"\e059"}.icons-ecommerce-basket-remove:before{content:"\e05a"}.icons-ecommerce-basket-search:before{content:"\e05b"}.icons-ecommerce-basket-upload:before{content:"\e05c"}.icons-ecommerce-bath:before{content:"\e05d"}.icons-ecommerce-cart:before{content:"\e05e"}.icons-ecommerce-cart-check:before{content:"\e05f"}.icons-ecommerce-cart-cloud:before{content:"\e060"}.icons-ecommerce-cart-content:before{content:"\e061"}.icons-ecommerce-cart-download:before{content:"\e062"}.icons-ecommerce-cart-minus:before{content:"\e063"}.icons-ecommerce-cart-plus:before{content:"\e064"}.icons-ecommerce-cart-refresh:before{content:"\e065"}.icons-ecommerce-cart-remove:before{content:"\e066"}.icons-ecommerce-cart-search:before{content:"\e067"}.icons-ecommerce-cart-upload:before{content:"\e068"}.icons-ecommerce-cent:before{content:"\e069"}.icons-ecommerce-colon:before{content:"\e06a"}.icons-ecommerce-creditcard:before{content:"\e06b"}.icons-ecommerce-diamond:before{content:"\e06c"}.icons-ecommerce-dollar:before{content:"\e06d"}.icons-ecommerce-euro:before{content:"\e06e"}.icons-ecommerce-franc:before{content:"\e06f"}.icons-ecommerce-gift:before{content:"\e070"}.icons-ecommerce-graph1:before{content:"\e071"}.icons-ecommerce-graph2:before{content:"\e072"}.icons-ecommerce-graph3:before{content:"\e073"}.icons-ecommerce-graph-decrease:before{content:"\e074"}.icons-ecommerce-graph-increase:before{content:"\e075"}.icons-ecommerce-guarani:before{content:"\e076"}.icons-ecommerce-kips:before{content:"\e077"}.icons-ecommerce-lira:before{content:"\e078"}.icons-ecommerce-megaphone:before{content:"\e079"}.icons-ecommerce-money:before{content:"\e07a"}.icons-ecommerce-naira:before{content:"\e07b"}.icons-ecommerce-pesos:before{content:"\e07c"}.icons-ecommerce-pound:before{content:"\e07d"}.icons-ecommerce-receipt:before{content:"\e07e"}.icons-ecommerce-receipt-bath:before{content:"\e07f"}.icons-ecommerce-receipt-cent:before{content:"\e080"}.icons-ecommerce-receipt-dollar:before{content:"\e081"}.icons-ecommerce-receipt-euro:before{content:"\e082"}.icons-ecommerce-receipt-franc:before{content:"\e083"}.icons-ecommerce-receipt-guarani:before{content:"\e084"}.icons-ecommerce-receipt-kips:before{content:"\e085"}.icons-ecommerce-receipt-lira:before{content:"\e086"}.icons-ecommerce-receipt-naira:before{content:"\e087"}.icons-ecommerce-receipt-pesos:before{content:"\e088"}.icons-ecommerce-receipt-pound:before{content:"\e089"}.icons-ecommerce-receipt-rublo:before{content:"\e08a"}.icons-ecommerce-receipt-rupee:before{content:"\e08b"}.icons-ecommerce-receipt-tugrik:before{content:"\e08c"}.icons-ecommerce-receipt-won:before{content:"\e08d"}.icons-ecommerce-receipt-yen:before{content:"\e08e"}.icons-ecommerce-receipt-yen2:before{content:"\e08f"}.icons-ecommerce-recept-colon:before{content:"\e090"}.icons-ecommerce-rublo:before{content:"\e091"}.icons-ecommerce-rupee:before{content:"\e092"}.icons-ecommerce-safe:before{content:"\e093"}.icons-ecommerce-sale:before{content:"\e094"}.icons-ecommerce-sales:before{content:"\e095"}.icons-ecommerce-ticket:before{content:"\e096"}.icons-ecommerce-tugriks:before{content:"\e097"}.icons-ecommerce-wallet:before{content:"\e098"}.icons-ecommerce-won:before{content:"\e099"}.icons-ecommerce-yen:before{content:"\e09a"}.icons-ecommerce-yen2:before{content:"\e09b"}
    +
    +/* animate.css */
    +.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}.animated.bounceIn,.animated.bounceOut,.animated.flipOutX,.animated.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounce{20%,53%,80%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{20%,53%,80%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{50%,from,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{50%,from,to{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes pulse{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes rubberBand{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{from,to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{from,to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}to{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}to{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{from{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}to{-webkit-transform:none;transform:none}}@keyframes wobble{from{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}to{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{11.1%,from,to{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{11.1%,from,to{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes bounceIn{20%,40%,60%,80%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes bounceIn{20%,40%,60%,80%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:none;transform:none}}@keyframes bounceInDown{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:none;transform:none}}@keyframes bounceInRight{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes bounceInUp{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{from{opacity:0}to{opacity:1}}@keyframes fadeIn{from{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{from{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{from{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{from{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{from{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{from{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{from{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{from{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{from{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{from{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{from{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{from{opacity:1}to{opacity:0}}@keyframes fadeOut{from{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}to{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}to{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{from{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{from{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}@keyframes flipOutY{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{from{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}to{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{from{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}to{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{from{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{from{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{from{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{from{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{from{-webkit-transform-origin:center;transform-origin:center;opacity:1}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}@keyframes rotateOut{from{-webkit-transform-origin:center;transform-origin:center;opacity:1}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}@keyframes rotateOutDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}@keyframes rotateOutUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{from{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{from{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}to{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}@keyframes rollOut{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInDown{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInLeft{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInRight{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInUp{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@keyframes zoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{from{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInLeft{from{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{from{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInRight{from{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}
    +
    +/* Slick Slider */
    +.slick-slider{position:relative;overflow:hidden;display:block;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none;-khtml-user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:transparent}.slick-list{position:relative;display:block;overflow:hidden;margin:0;padding:0}.slick-list:focus{outline:0}.slick-list.dragging{cursor:pointer;cursor:hand}.slick-slider .slick-list,.slick-slider .slick-track{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.slick-track{position:relative;top:0;left:0;display:block}.slick-track:after,.slick-track:before{display:table;content:''}.slick-track:after{clear:both}.slick-loading .slick-track{visibility:hidden}.slick-slide{display:none;float:left;height:100%;min-height:1px}[dir=rtl] .slick-slide{float:right}.slick-slide img{display:block}.slick-slide.slick-loading img{display:none}.slick-slide.dragging img{pointer-events:none}.slick-initialized .slick-slide{display:block}.slick-loading .slick-slide{visibility:hidden}.slick-vertical .slick-slide{display:block;height:auto;border:1px solid transparent}.slick-dots,.slider_controls{display:table;margin:15px auto 0}.slider_controls .slick-dots{margin:0}.slick-dots li{position:relative;display:inline-block;padding:0;margin:0 3px}.slick-dots li button{height:12px;width:12px;outline:0;line-height:10px;font:0/0 a;border-radius:50%;cursor:pointer;background:0 0;display:block;padding:0}.slick-dots li button:focus{outline:0}.slick-next,.slick-prev{line-height:0;font-size:0;cursor:pointer;padding:0;border:none;outline:0;text-align:center;width:28px;height:28px;color:#777;background:0 0}.slick-next:before,.slick-prev:before{font-family:FontAwesome;font-size:18px;line-height:28px;display:inline-block;margin:auto}.slick-prev:before{content:"\f104"}.slick-next:before{content:"\f105"}.slider_controls .slick-dots,.slider_controls .slick-prev{float:left}.slider_controls .slick-next{float:right}
    +
    +/* counter */
    +.odometer.odometer-auto-theme,.odometer.odometer-theme-car{vertical-align:middle;position:relative}.odometer.odometer-auto-theme .odometer-digit,.odometer.odometer-theme-car .odometer-digit{display:inline-block;position:relative}.odometer.odometer-auto-theme .odometer-digit .odometer-digit-spacer,.odometer.odometer-theme-car .odometer-digit .odometer-digit-spacer{display:inline-block;visibility:hidden}.odometer.odometer-auto-theme .odometer-digit .odometer-digit-inner,.odometer.odometer-theme-car .odometer-digit .odometer-digit-inner{text-align:left;display:block;position:absolute;top:0;left:0;right:0;bottom:0;overflow:hidden}.odometer.odometer-auto-theme .odometer-digit .odometer-ribbon,.odometer.odometer-theme-car .odometer-digit .odometer-ribbon{display:block}.odometer.odometer-auto-theme .odometer-digit .odometer-ribbon-inner,.odometer.odometer-theme-car .odometer-digit .odometer-ribbon-inner{display:block;-webkit-backface-visibility:hidden}.odometer.odometer-auto-theme .odometer-digit .odometer-value,.odometer.odometer-theme-car .odometer-digit .odometer-value{display:block;-webkit-transform:translateZ(0)}.odometer.odometer-auto-theme .odometer-digit .odometer-value.odometer-last-value,.odometer.odometer-theme-car .odometer-digit .odometer-value.odometer-last-value{position:absolute}.odometer.odometer-auto-theme.odometer-animating-up .odometer-ribbon-inner,.odometer.odometer-theme-car.odometer-animating-up .odometer-ribbon-inner{-webkit-transition:-webkit-transform 2s;-moz-transition:-moz-transform 2s;-ms-transition:-ms-transform 2s;-o-transition:-o-transform 2s;transition:transform 2s}.odometer.odometer-auto-theme.odometer-animating-down .odometer-ribbon-inner,.odometer.odometer-auto-theme.odometer-animating-up.odometer-animating .odometer-ribbon-inner,.odometer.odometer-theme-car.odometer-animating-down .odometer-ribbon-inner,.odometer.odometer-theme-car.odometer-animating-up.odometer-animating .odometer-ribbon-inner{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%)}.odometer.odometer-auto-theme.odometer-animating-down.odometer-animating .odometer-ribbon-inner,.odometer.odometer-theme-car.odometer-animating-down.odometer-animating .odometer-ribbon-inner{-webkit-transition:-webkit-transform 2s;-moz-transition:-moz-transform 2s;-ms-transition:-ms-transform 2s;-o-transition:-o-transform 2s;transition:transform 2s;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}.odometer.odometer-auto-theme .odometer-digit:first-child,.odometer.odometer-theme-car .odometer-digit:first-child{-moz-border-radius:.2em 0 0 .2em;-webkit-border-radius:.2em;border-radius:.2em 0 0 .2em}.odometer.odometer-auto-theme .odometer-digit:last-child,.odometer.odometer-theme-car .odometer-digit:last-child{-moz-border-radius:0 .2em .2em 0}.odometer.odometer-auto-theme.odometer-animating-down.odometer-animating .odometer-ribbon-inner,.odometer.odometer-auto-theme.odometer-animating-up .odometer-ribbon-inner,.odometer.odometer-theme-car.odometer-animating-down.odometer-animating .odometer-ribbon-inner,.odometer.odometer-theme-car.odometer-animating-up .odometer-ribbon-inner{-webkit-transition-timing-function:linear;-moz-transition-timing-function:linear;-ms-transition-timing-function:linear;-o-transition-timing-function:linear;transition-timing-function:linear}
    +
    +/* Magnific Popup CSS */
    +.mfp-bg{top:0;left:0;width:100%;height:100%;z-index:1042;overflow:hidden;position:fixed;background:#0b0b0b;opacity:.8;filter:alpha(opacity=80)}.mfp-wrap{top:0;left:0;width:100%;height:100%;z-index:1043;position:fixed;outline:0!important;-webkit-backface-visibility:hidden}.mfp-container{text-align:center;position:absolute;width:100%;height:100%;left:0;top:0;padding:0 8px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.mfp-container:before{content:'';display:inline-block;height:100%;vertical-align:middle}.mfp-align-top .mfp-container:before{display:none}.mfp-content{position:relative;display:inline-block;vertical-align:middle;margin:0 auto;text-align:left;z-index:1045}.mfp-ajax-holder .mfp-content,.mfp-inline-holder .mfp-content{width:100%;cursor:auto}.mfp-ajax-cur{cursor:progress}.mfp-zoom-out-cur,.mfp-zoom-out-cur .mfp-image-holder .mfp-close{cursor:-moz-zoom-out;cursor:-webkit-zoom-out;cursor:zoom-out}.mfp-zoom{cursor:pointer;cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.mfp-auto-cursor .mfp-content{cursor:auto}.mfp-arrow,.mfp-close,.mfp-counter,.mfp-preloader{-webkit-user-select:none;-moz-user-select:none;user-select:none}.mfp-loading.mfp-figure{display:none}.mfp-hide{display:none!important}.mfp-preloader{color:#CCC;position:absolute;top:50%;width:auto;text-align:center;margin-top:-.8em;z-index:1044}.mfp-preloader a{color:#CCC}.mfp-preloader a:hover{color:#FFF}.mfp-s-error .mfp-content,.mfp-s-ready .mfp-preloader{display:none}button.mfp-arrow,button.mfp-close{overflow:visible;cursor:pointer;background:0 0;border:0;-webkit-appearance:none;display:block;outline:0;padding:0;z-index:1046;-webkit-box-shadow:none;box-shadow:none}button::-moz-focus-inner{padding:0;border:0}.mfp-close{width:44px;height:44px;line-height:44px;position:absolute;right:0;top:0;text-decoration:none;text-align:center;opacity:.65;filter:alpha(opacity=65);padding:0 0 18px 10px;color:#FFF;font-style:normal;font-size:28px;font-family:Arial,Baskerville,monospace}.mfp-close:focus,.mfp-close:hover{opacity:1;filter:alpha(opacity=100)}.mfp-close:active{top:1px}.mfp-close-btn-in .mfp-close{color:#333}.mfp-iframe-holder .mfp-close,.mfp-image-holder .mfp-close{color:#FFF;right:-6px;text-align:right;padding-right:6px;width:100%}.mfp-counter{position:absolute;top:0;right:0;color:#CCC;font-size:12px;line-height:18px;white-space:nowrap}.mfp-arrow{position:absolute;opacity:.65;filter:alpha(opacity=65);margin:-55px 0 0;top:50%;padding:0;width:90px;height:110px;-webkit-tap-highlight-color:transparent}.mfp-arrow:active{margin-top:-54px}.mfp-arrow:focus,.mfp-arrow:hover{opacity:1;filter:alpha(opacity=100)}.mfp-arrow .mfp-a,.mfp-arrow .mfp-b,.mfp-arrow:after,.mfp-arrow:before{content:'';display:block;width:0;height:0;position:absolute;left:0;top:0;margin-top:35px;margin-left:35px;border:inset transparent}.mfp-arrow .mfp-a,.mfp-arrow:after{border-top-width:13px;border-bottom-width:13px;top:8px}.mfp-arrow .mfp-b,.mfp-arrow:before{border-top-width:21px;border-bottom-width:21px;opacity:.7}.mfp-arrow-left{left:0}.mfp-arrow-left .mfp-a,.mfp-arrow-left:after{border-right:17px solid #FFF;margin-left:31px}.mfp-arrow-left .mfp-b,.mfp-arrow-left:before{margin-left:25px;border-right:27px solid #3F3F3F}.mfp-arrow-right{right:0}.mfp-arrow-right .mfp-a,.mfp-arrow-right:after{border-left:17px solid #FFF;margin-left:39px}.mfp-arrow-right .mfp-b,.mfp-arrow-right:before{border-left:27px solid #3F3F3F}.mfp-iframe-holder{padding-top:40px;padding-bottom:40px}.mfp-iframe-holder .mfp-content{line-height:0;width:100%;max-width:900px}.mfp-iframe-holder .mfp-close{top:-40px}.mfp-iframe-scaler{width:100%;height:0;overflow:hidden;padding-top:56.25%}.mfp-iframe-scaler iframe{position:absolute;display:block;top:0;left:0;width:100%;height:100%;box-shadow:0 0 8px rgba(0,0,0,.6);background:#000}img.mfp-img{width:auto;max-width:100%;height:auto;display:block;line-height:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:40px 0;margin:0 auto}.mfp-figure{line-height:0}.mfp-figure:after{content:'';position:absolute;left:0;top:40px;bottom:40px;display:block;right:0;width:auto;height:auto;z-index:-1;box-shadow:0 0 8px rgba(0,0,0,.6);background:#444}.mfp-figure small{color:#BDBDBD;display:block;font-size:12px;line-height:14px}.mfp-figure figure{margin:0}.mfp-bottom-bar{margin-top:-36px;position:absolute;top:100%;left:0;width:100%;cursor:auto}.mfp-title{text-align:left;line-height:18px;color:#F3F3F3;word-wrap:break-word;padding-right:36px}.mfp-image-holder .mfp-content{max-width:100%}.mfp-gallery .mfp-image-holder .mfp-figure{cursor:pointer}@media screen and (max-width:800px) and (orientation:landscape),screen and (max-height:300px){.mfp-img-mobile .mfp-image-holder{padding-left:0;padding-right:0}.mfp-img-mobile img.mfp-img{padding:0}.mfp-img-mobile .mfp-figure:after{top:0;bottom:0}.mfp-img-mobile .mfp-figure small{display:inline;margin-left:5px}.mfp-img-mobile .mfp-bottom-bar{background:rgba(0,0,0,.6);bottom:0;margin:0;top:auto;padding:3px 5px;position:fixed;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.mfp-img-mobile .mfp-bottom-bar:empty{padding:0}.mfp-img-mobile .mfp-counter{right:5px;top:3px}.mfp-img-mobile .mfp-close{top:0;right:0;width:35px;height:35px;line-height:35px;background:rgba(0,0,0,.6);position:fixed;text-align:center;padding:0}}@media all and (max-width:900px){.mfp-arrow{-webkit-transform:scale(.75);transform:scale(.75)}.mfp-arrow-left{-webkit-transform-origin:0;transform-origin:0}.mfp-arrow-right{-webkit-transform-origin:100%;transform-origin:100%}.mfp-container{padding-left:6px;padding-right:6px}}.mfp-ie7 .mfp-img{padding:0}.mfp-ie7 .mfp-bottom-bar{width:600px;left:50%;margin-left:-300px;margin-top:5px;padding-bottom:5px}.mfp-ie7 .mfp-container{padding:0}.mfp-ie7 .mfp-content{padding-top:44px}.mfp-ie7 .mfp-close{top:0;right:0;padding-top:0}
    +
    +/* Camera SlideShow */
    +.camera_thumbs_wrap img,.camera_thumbs_wrap li,.camera_thumbs_wrap ol,.camera_thumbs_wrap table,.camera_thumbs_wrap tbody,.camera_thumbs_wrap td,.camera_thumbs_wrap tfoot,.camera_thumbs_wrap th,.camera_thumbs_wrap thead,.camera_thumbs_wrap tr,.camera_thumbs_wrap ul,.camera_wrap a,.camera_wrap img,.camera_wrap li,.camera_wrap ol,.camera_wrap table,.camera_wrap tbody,.camera_wrap td .camera_thumbs_wrap a,.camera_wrap tfoot,.camera_wrap th,.camera_wrap thead,.camera_wrap tr,.camera_wrap ul{background:0 0;border:0;font:inherit;font-size:100%;margin:0;padding:0;vertical-align:baseline;list-style:none}.camera_wrap{direction:ltr;display:none;float:left;position:relative;z-index:0}.camera_wrap img{max-width:none!important}.camera_fakehover{height:100%;min-height:60px;position:relative;width:100%;z-index:1}.camera_wrap{width:100%}.camera_src{display:none}.cameraCont,.cameraContents{height:100%;position:relative;width:100%;z-index:1}.cameraSlide{bottom:0;left:0;position:absolute;right:0;top:0;width:100%}.cameraContent{bottom:0;display:none;left:0;position:absolute;right:0;top:0;width:100%}.camera_target{bottom:0;height:100%;left:0;overflow:hidden;position:absolute;right:0;text-align:left;top:0;width:100%;z-index:0}.camera_overlayer{bottom:0;height:100%;left:0;overflow:hidden;position:absolute;right:0;top:0;width:100%;z-index:0}.camera_target_content{bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0;z-index:2}.camera_target_content .camera_link{background:url(../images/blank.gif);display:block;height:100%;text-decoration:none}.camera_loader{background:url(../images/ajax-loader.gif) center no-repeat #fff;background:url(../images/ajax-loader.gif) center no-repeat rgba(255,255,255,.9);border:1px solid #fff;-webkit-border-radius:18px;-moz-border-radius:18px;border-radius:18px;height:36px;left:50%;overflow:hidden;position:absolute;margin:-18px 0 0 -18px;top:50%;width:36px;z-index:3}.camera_bar{bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0;z-index:3}.camera_thumbs_wrap.camera_left .camera_bar,.camera_thumbs_wrap.camera_right .camera_bar{height:100%;position:absolute;width:auto}.camera_thumbs_wrap.camera_bottom .camera_bar,.camera_thumbs_wrap.camera_top .camera_bar{height:auto;position:absolute;width:100%}.camera_nav_cont{height:65px;overflow:hidden;position:absolute;right:9px;top:15px;width:120px;z-index:4}.camera_caption{bottom:0;display:block;position:absolute;width:100%}.camera_caption>div{padding: 20px 10%;font-size: 16px;}.camerarelative{overflow:hidden;position:relative}.imgFake{cursor:pointer}.camera_prevThumbs{bottom:4px;cursor:pointer;left:0;position:absolute;top:4px;visibility:hidden;width:30px;z-index:10}.camera_prevThumbs div{display:block;height:40px;margin-top:-20px;position:absolute;top:50%;width:30px}.camera_nextThumbs{bottom:4px;cursor:pointer;position:absolute;right:0;top:4px;visibility:hidden;width:30px;z-index:10}.camera_nextThumbs div{display:block;height:40px;margin-top:-20px;position:absolute;top:50%;width:30px}.camera_command_wrap .hideNav{display:none}.camera_command_wrap{left:0;position:relative;right:0;z-index:4}.camera_pag{position: absolute;text-align:center;width:100%;bottom: 0px;right: 2%;}.camera_wrap .camera_pag .camera_pag_ul{list-style:none;margin:0;padding:0;text-align:right}.camera_wrap .camera_pag .camera_pag_ul li{text-align:left}.camera_commands_emboss .camera_pag .camera_pag_ul li{-moz-box-shadow:0 1px 0 rgba(255,255,255,1),inset 0 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:0 1px 0 rgba(255,255,255,1),inset 0 1px 1px rgba(0,0,0,.2);box-shadow:0 1px 0 rgba(255,255,255,1),inset 0 1px 1px rgba(0,0,0,.2)}.camera_wrap .camera_pag .camera_pag_ul li>span{-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;height: 6px;left: 3px;overflow:hidden;position:absolute;top: 3px;width: 6px;}.camera_commands_emboss .camera_pag .camera_pag_ul li:hover>span{-moz-box-shadow:0 1px 0 rgba(255,255,255,1),inset 0 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:0 1px 0 rgba(255,255,255,1),inset 0 1px 1px rgba(0,0,0,.2);box-shadow:0 1px 0 rgba(255,255,255,1),inset 0 1px 1px rgba(0,0,0,.2)}.camera_wrap .camera_pag .camera_pag_ul li.cameracurrent>span{-moz-box-shadow:0;-webkit-box-shadow:0;box-shadow:0}.camera_pag_ul li img{display:none;position:absolute}.camera_pag_ul .thumb_arrow{border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid;top:0;left:50%;margin-left:-4px;position:absolute}.camera_commands,.camera_next,.camera_prev{cursor:pointer;height:40px;margin-top:-25px;position:absolute;top:50%;width:40px;z-index:2}.camera_prev{left:0}.camera_prev>span{background:rgba(0,0,0,.5);display:block;height:50px;width:40px;text-align:center;line-height:40px}.camera_next>span:before,.camera_prev>span:before{font-family:FontAwesome;font-size:22px;line-height:50px;display:inline-block;margin:auto;color:#fff}.camera_next{right:0}.camera_next>span{background:rgba(0,0,0,.5);display:block;height:50px;width:40px;text-align:center;line-height:40px}.camera_next>span:before{content:"\f105"}.camera_prev>span:before{content:"\f104"}.camera_commands{right:41px}.camera_wrap .camera_pag .camera_pag_ul li{-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;cursor:pointer;display:inline-block;height: 12px;margin: 20px 3px;position:relative;text-indent:9999px;width: 12px;}.camera_thumbs_cont{-webkit-border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;overflow:hidden;position:relative;width:100%}.camera_commands_emboss .camera_thumbs_cont{-moz-box-shadow:0 1px 0 rgba(255,255,255,1),inset 0 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:0 1px 0 rgba(255,255,255,1),inset 0 1px 1px rgba(0,0,0,.2);box-shadow:0 1px 0 rgba(255,255,255,1),inset 0 1px 1px rgba(0,0,0,.2)}.camera_thumbs_cont>div{float:left;width:100%}.camera_thumbs_cont ul{overflow:hidden;padding:3px 4px 8px;position:relative;text-align:center}.camera_thumbs_cont ul li{display:inline;padding:0 4px}.camera_thumbs_cont ul li>img{cursor:pointer;margin-top:5px;vertical-align:bottom}.showIt{display:none}.camera_clear{clear:both;display:block;height:1px;margin:-1px 0 25px;position:relative}.pattern_1 .camera_overlayer{background:url(../images/patterns/overlay1.png)}.pattern_2 .camera_overlayer{background:url(../images/patterns/overlay2.png)}.pattern_3 .camera_overlayer{background:url(../images/patterns/overlay3.png)}.pattern_4 .camera_overlayer{background:url(../images/patterns/overlay4.png)}.pattern_5 .camera_overlayer{background:url(../images/patterns/overlay5.png)}.pattern_6 .camera_overlayer{background:url(../images/patterns/overlay6.png)}.pattern_7 .camera_overlayer{background:url(../images/patterns/overlay7.png)}.pattern_8 .camera_overlayer{background:url(../images/patterns/overlay8.png)}.pattern_9 .camera_overlayer{background:url(../images/patterns/overlay9.png)}.pattern_10 .camera_overlayer{background:url(../images/patterns/overlay10.png)}.camera_caption{color:#fff}.camera_caption>div{background:#000;background:rgba(0,0,0,.8)}.camera_wrap .camera_pag .camera_pag_ul li:hover>span{background:#b7b7b7}.camera_wrap .camera_pag .camera_pag_ul li.cameracurrent>span{background:#434648}.camera_pag_ul li img{border:4px solid #e6e6e6;-moz-box-shadow:0 3px 6px rgba(0,0,0,.5);-webkit-box-shadow:0 3px 6px rgba(0,0,0,.5);box-shadow:0 3px 6px rgba(0,0,0,.5)}.camera_pag_ul .thumb_arrow{border-top-color:#e6e6e6}.camera_wrap .camera_pag .camera_pag_ul li{background:#b7b7b7}.camera_thumbs_cont ul li>img{border-color:1px solid #000}.camera_amber_skin .camera_prevThumbs div{background-position:-160px -160px}.camera_amber_skin .camera_nextThumbs div{background-position:-190px -160px}.camera_amber_skin .camera_prev>span{background-position:0 -160px}.camera_amber_skin .camera_next>span{background-position:-40px -160px}.camera_play:after,.camera_stop:after,.camera_prevThumbs div:after,.camera_nextThumbs div:after{font-family: FontAwesome;font-size: 13px;display: inline-block;margin: auto;color: #fff;background: rgba(0,0,0,.5);display: block;height: 50px;width: 40px;text-align: center;line-height: 50px;}.camera_prevThumbs div:after{content:"\f104"}.camera_nextThumbs div:after{content:"\f105";font-size:20px;width:auto}.camera_play:after{content:"\f04b";font-size:20px;width:auto}.camera_stop:after{content:"\f04c"}.camera_amber_skin .camera_commands>.camera_play{background-position:-80px -160px}.camera_amber_skin .camera_commands>.camera_stop{background-position:-120px -160px}.camera_ash_skin .camera_prevThumbs div{background-position:-160px -200px}.camera_ash_skin .camera_nextThumbs div{background-position:-190px -200px}.camera_ash_skin .camera_prev>span{background-position:0 -200px}.camera_ash_skin .camera_next>span{background-position:-40px -200px}.camera_ash_skin .camera_commands>.camera_play{background-position:-80px -200px}.camera_ash_skin .camera_commands>.camera_stop{background-position:-120px -200px}.camera_azure_skin .camera_prevThumbs div{background-position:-160px -240px}.camera_azure_skin .camera_nextThumbs div{background-position:-190px -240px}.camera_azure_skin .camera_prev>span{background-position:0 -240px}.camera_azure_skin .camera_next>span{background-position:-40px -240px}.camera_azure_skin .camera_commands>.camera_play{background-position:-80px -240px}.camera_azure_skin .camera_commands>.camera_stop{background-position:-120px -240px}.camera_beige_skin .camera_prevThumbs div{background-position:-160px -120px}.camera_beige_skin .camera_nextThumbs div{background-position:-190px -120px}.camera_beige_skin .camera_prev>span{background-position:0 -120px}.camera_beige_skin .camera_next>span{background-position:-40px -120px}.camera_beige_skin .camera_commands>.camera_play{background-position:-80px -120px}.camera_beige_skin .camera_commands>.camera_stop{background-position:-120px -120px}.camera_black_skin .camera_prevThumbs div{background-position:-160px -40px}.camera_black_skin .camera_nextThumbs div{background-position:-190px -40px}.camera_black_skin .camera_prev>span{background-position:0 -40px}.camera_black_skin .camera_next>span{background-position:-40px -40px}.camera_black_skin .camera_commands>.camera_play{background-position:-80px -40px}.camera_black_skin .camera_commands>.camera_stop{background-position:-120px -40px}.camera_blue_skin .camera_prevThumbs div{background-position:-160px -280px}.camera_blue_skin .camera_nextThumbs div{background-position:-190px -280px}.camera_blue_skin .camera_prev>span{background-position:0 -280px}.camera_blue_skin .camera_next>span{background-position:-40px -280px}.camera_blue_skin .camera_commands>.camera_play{background-position:-80px -280px}.camera_blue_skin .camera_commands>.camera_stop{background-position:-120px -280px}.camera_brown_skin .camera_prevThumbs div{background-position:-160px -320px}.camera_brown_skin .camera_nextThumbs div{background-position:-190px -320px}.camera_brown_skin .camera_prev>span{background-position:0 -320px}.camera_brown_skin .camera_next>span{background-position:-40px -320px}.camera_brown_skin .camera_commands>.camera_play{background-position:-80px -320px}.camera_brown_skin .camera_commands>.camera_stop{background-position:-120px -320px}.camera_burgundy_skin .camera_prevThumbs div{background-position:-160px -360px}.camera_burgundy_skin .camera_nextThumbs div{background-position:-190px -360px}.camera_burgundy_skin .camera_prev>span{background-position:0 -360px}.camera_burgundy_skin .camera_next>span{background-position:-40px -360px}.camera_burgundy_skin .camera_commands>.camera_play{background-position:-80px -360px}.camera_burgundy_skin .camera_commands>.camera_stop{background-position:-120px -360px}.camera_charcoal_skin .camera_prevThumbs div{background-position:-160px -400px}.camera_charcoal_skin .camera_nextThumbs div{background-position:-190px -400px}.camera_charcoal_skin .camera_prev>span{background-position:0 -400px}.camera_charcoal_skin .camera_next>span{background-position:-40px -400px}.camera_charcoal_skin .camera_commands>.camera_play{background-position:-80px -400px}.camera_charcoal_skin .camera_commands>.camera_stop{background-position:-120px -400px}.camera_chocolate_skin .camera_prevThumbs div{background-position:-160px -440px}.camera_chocolate_skin .camera_nextThumbs div{background-position:-190px -440px}.camera_chocolate_skin .camera_prev>span{background-position:0 -440px}.camera_chocolate_skin .camera_next>span{background-position:-40px -440px}.camera_chocolate_skin .camera_commands>.camera_play{background-position:-80px -440px}.camera_chocolate_skin .camera_commands>.camera_stop{background-position:-120px -440px}.camera_coffee_skin .camera_prevThumbs div{background-position:-160px -480px}.camera_coffee_skin .camera_nextThumbs div{background-position:-190px -480px}.camera_coffee_skin .camera_prev>span{background-position:0 -480px}.camera_coffee_skin .camera_next>span{background-position:-40px -480px}.camera_coffee_skin .camera_commands>.camera_play{background-position:-80px -480px}.camera_coffee_skin .camera_commands>.camera_stop{background-position:-120px -480px}.camera_cyan_skin .camera_prevThumbs div{background-position:-160px -520px}.camera_cyan_skin .camera_nextThumbs div{background-position:-190px -520px}.camera_cyan_skin .camera_prev>span{background-position:0 -520px}.camera_cyan_skin .camera_next>span{background-position:-40px -520px}.camera_cyan_skin .camera_commands>.camera_play{background-position:-80px -520px}.camera_cyan_skin .camera_commands>.camera_stop{background-position:-120px -520px}.camera_fuchsia_skin .camera_prevThumbs div{background-position:-160px -560px}.camera_fuchsia_skin .camera_nextThumbs div{background-position:-190px -560px}.camera_fuchsia_skin .camera_prev>span{background-position:0 -560px}.camera_fuchsia_skin .camera_next>span{background-position:-40px -560px}.camera_fuchsia_skin .camera_commands>.camera_play{background-position:-80px -560px}.camera_fuchsia_skin .camera_commands>.camera_stop{background-position:-120px -560px}.camera_gold_skin .camera_prevThumbs div{background-position:-160px -600px}.camera_gold_skin .camera_nextThumbs div{background-position:-190px -600px}.camera_gold_skin .camera_prev>span{background-position:0 -600px}.camera_gold_skin .camera_next>span{background-position:-40px -600px}.camera_gold_skin .camera_commands>.camera_play{background-position:-80px -600px}.camera_gold_skin .camera_commands>.camera_stop{background-position:-120px -600px}.camera_green_skin .camera_prevThumbs div{background-position:-160px -640px}.camera_green_skin .camera_nextThumbs div{background-position:-190px -640px}.camera_green_skin .camera_prev>span{background-position:0 -640px}.camera_green_skin .camera_next>span{background-position:-40px -640px}.camera_green_skin .camera_commands>.camera_play{background-position:-80px -640px}.camera_green_skin .camera_commands>.camera_stop{background-position:-120px -640px}.camera_grey_skin .camera_prevThumbs div{background-position:-160px -680px}.camera_grey_skin .camera_nextThumbs div{background-position:-190px -680px}.camera_grey_skin .camera_prev>span{background-position:0 -680px}.camera_grey_skin .camera_next>span{background-position:-40px -680px}.camera_grey_skin .camera_commands>.camera_play{background-position:-80px -680px}.camera_grey_skin .camera_commands>.camera_stop{background-position:-120px -680px}.camera_indigo_skin .camera_prevThumbs div{background-position:-160px -720px}.camera_indigo_skin .camera_nextThumbs div{background-position:-190px -720px}.camera_indigo_skin .camera_prev>span{background-position:0 -720px}.camera_indigo_skin .camera_next>span{background-position:-40px -720px}.camera_indigo_skin .camera_commands>.camera_play{background-position:-80px -720px}.camera_indigo_skin .camera_commands>.camera_stop{background-position:-120px -720px}.camera_khaki_skin .camera_prevThumbs div{background-position:-160px -760px}.camera_khaki_skin .camera_nextThumbs div{background-position:-190px -760px}.camera_khaki_skin .camera_prev>span{background-position:0 -760px}.camera_khaki_skin .camera_next>span{background-position:-40px -760px}.camera_khaki_skin .camera_commands>.camera_play{background-position:-80px -760px}.camera_khaki_skin .camera_commands>.camera_stop{background-position:-120px -760px}.camera_lime_skin .camera_prevThumbs div{background-position:-160px -800px}.camera_lime_skin .camera_nextThumbs div{background-position:-190px -800px}.camera_lime_skin .camera_prev>span{background-position:0 -800px}.camera_lime_skin .camera_next>span{background-position:-40px -800px}.camera_lime_skin .camera_commands>.camera_play{background-position:-80px -800px}.camera_lime_skin .camera_commands>.camera_stop{background-position:-120px -800px}.camera_magenta_skin .camera_prevThumbs div{background-position:-160px -840px}.camera_magenta_skin .camera_nextThumbs div{background-position:-190px -840px}.camera_magenta_skin .camera_prev>span{background-position:0 -840px}.camera_magenta_skin .camera_next>span{background-position:-40px -840px}.camera_magenta_skin .camera_commands>.camera_play{background-position:-80px -840px}.camera_magenta_skin .camera_commands>.camera_stop{background-position:-120px -840px}.camera_maroon_skin .camera_prevThumbs div{background-position:-160px -880px}.camera_maroon_skin .camera_nextThumbs div{background-position:-190px -880px}.camera_maroon_skin .camera_prev>span{background-position:0 -880px}.camera_maroon_skin .camera_next>span{background-position:-40px -880px}.camera_maroon_skin .camera_commands>.camera_play{background-position:-80px -880px}.camera_maroon_skin .camera_commands>.camera_stop{background-position:-120px -880px}.camera_orange_skin .camera_prevThumbs div{background-position:-160px -920px}.camera_orange_skin .camera_nextThumbs div{background-position:-190px -920px}.camera_orange_skin .camera_prev>span{background-position:0 -920px}.camera_orange_skin .camera_next>span{background-position:-40px -920px}.camera_orange_skin .camera_commands>.camera_play{background-position:-80px -920px}.camera_orange_skin .camera_commands>.camera_stop{background-position:-120px -920px}.camera_olive_skin .camera_prevThumbs div{background-position:-160px -1080px}.camera_olive_skin .camera_nextThumbs div{background-position:-190px -1080px}.camera_olive_skin .camera_prev>span{background-position:0 -1080px}.camera_olive_skin .camera_next>span{background-position:-40px -1080px}.camera_olive_skin .camera_commands>.camera_play{background-position:-80px -1080px}.camera_olive_skin .camera_commands>.camera_stop{background-position:-120px -1080px}.camera_pistachio_skin .camera_prevThumbs div{background-position:-160px -1040px}.camera_pistachio_skin .camera_nextThumbs div{background-position:-190px -1040px}.camera_pistachio_skin .camera_prev>span{background-position:0 -1040px}.camera_pistachio_skin .camera_next>span{background-position:-40px -1040px}.camera_pistachio_skin .camera_commands>.camera_play{background-position:-80px -1040px}.camera_pistachio_skin .camera_commands>.camera_stop{background-position:-120px -1040px}.camera_pink_skin .camera_prevThumbs div{background-position:-160px -80px}.camera_pink_skin .camera_nextThumbs div{background-position:-190px -80px}.camera_pink_skin .camera_prev>span{background-position:0 -80px}.camera_pink_skin .camera_next>span{background-position:-40px -80px}.camera_pink_skin .camera_commands>.camera_play{background-position:-80px -80px}.camera_pink_skin .camera_commands>.camera_stop{background-position:-120px -80px}.camera_red_skin .camera_prevThumbs div{background-position:-160px -1000px}.camera_red_skin .camera_nextThumbs div{background-position:-190px -1000px}.camera_red_skin .camera_prev>span{background-position:0 -1000px}.camera_red_skin .camera_next>span{background-position:-40px -1000px}.camera_red_skin .camera_commands>.camera_play{background-position:-80px -1000px}.camera_red_skin .camera_commands>.camera_stop{background-position:-120px -1000px}.camera_tangerine_skin .camera_prevThumbs div{background-position:-160px -1120px}.camera_tangerine_skin .camera_nextThumbs div{background-position:-190px -1120px}.camera_tangerine_skin .camera_prev>span{background-position:0 -1120px}.camera_tangerine_skin .camera_next>span{background-position:-40px -1120px}.camera_tangerine_skin .camera_commands>.camera_play{background-position:-80px -1120px}.camera_tangerine_skin .camera_commands>.camera_stop{background-position:-120px -1120px}.camera_turquoise_skin .camera_prevThumbs div{background-position:-160px -1160px}.camera_turquoise_skin .camera_nextThumbs div{background-position:-190px -1160px}.camera_turquoise_skin .camera_prev>span{background-position:0 -1160px}.camera_turquoise_skin .camera_next>span{background-position:-40px -1160px}.camera_turquoise_skin .camera_commands>.camera_play{background-position:-80px -1160px}.camera_turquoise_skin .camera_commands>.camera_stop{background-position:-120px -1160px}.camera_violet_skin .camera_prevThumbs div{background-position:-160px -1200px}.camera_violet_skin .camera_nextThumbs div{background-position:-190px -1200px}.camera_violet_skin .camera_prev>span{background-position:0 -1200px}.camera_violet_skin .camera_next>span{background-position:-40px -1200px}.camera_violet_skin .camera_commands>.camera_play{background-position:-80px -1200px}.camera_violet_skin .camera_commands>.camera_stop{background-position:-120px -1200px}.camera_white_skin .camera_prevThumbs div{background-position:-160px -80px}.camera_white_skin .camera_nextThumbs div{background-position:-190px -80px}.camera_white_skin .camera_prev>span{background-position:0 -80px}.camera_white_skin .camera_next>span{background-position:-40px -80px}.camera_white_skin .camera_commands>.camera_play{background-position:-80px -80px}.camera_white_skin .camera_commands>.camera_stop{background-position:-120px -80px}.camera_yellow_skin .camera_prevThumbs div{background-position:-160px -1240px}.camera_yellow_skin .camera_nextThumbs div{background-position:-190px -1240px}.camera_yellow_skin .camera_prev>span{background-position:0 -1240px}.camera_yellow_skin .camera_next>span{background-position:-40px -1240px}.camera_yellow_skin .camera_commands>.camera_play{background-position:-80px -1240px}.camera_yellow_skin .camera_commands>.camera_stop{background-position:-120px -1240px}
    +
    +/* animsition v4.0.0 */
    +.animsition,.animsition-overlay{position:relative;opacity:0;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animsition-overlay-slide{position:fixed;z-index:1;width:100%;height:100%;background-color:#ddd}.animsition-loading,.animsition-loading:after{width:2pc;height:2pc;position:fixed;top:50%;left:50%;margin-top:-1pc;margin-left:-1pc;border-radius:50%;z-index:2}.animsition-loading{background-color:transparent;border-top:5px solid rgba(0,0,0,.2);border-right:5px solid rgba(0,0,0,.2);border-bottom:5px solid rgba(0,0,0,.2);border-left:5px solid #eee;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-duration:.8s;animation-duration:.8s;-webkit-animation-name:animsition-loading;animation-name:animsition-loading}@-webkit-keyframes animsition-loading{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes animsition-loading{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@-webkit-keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.fade-in{-webkit-animation-name:fade-in;animation-name:fade-in}@-webkit-keyframes fade-out{0%{opacity:1}to{opacity:0}}@keyframes fade-out{0%{opacity:1}to{opacity:0}}.fade-out{-webkit-animation-name:fade-out;animation-name:fade-out}@-webkit-keyframes fade-in-up{0%{-webkit-transform:translateY(500px);transform:translateY(500px);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}@keyframes fade-in-up{0%{-webkit-transform:translateY(500px);transform:translateY(500px);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}.fade-in-up{-webkit-animation-name:fade-in-up;animation-name:fade-in-up}@-webkit-keyframes fade-out-up{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}to{-webkit-transform:translateY(-500px);transform:translateY(-500px);opacity:0}}@keyframes fade-out-up{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}to{-webkit-transform:translateY(-500px);transform:translateY(-500px);opacity:0}}.fade-out-up{-webkit-animation-name:fade-out-up;animation-name:fade-out-up}@-webkit-keyframes fade-in-up-sm{0%{-webkit-transform:translateY(75pt);transform:translateY(75pt);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}@keyframes fade-in-up-sm{0%{-webkit-transform:translateY(75pt);transform:translateY(75pt);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}.fade-in-up-sm{-webkit-animation-name:fade-in-up-sm;animation-name:fade-in-up-sm}@-webkit-keyframes fade-out-up-sm{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}to{-webkit-transform:translateY(-75pt);transform:translateY(-75pt);opacity:0}}@keyframes fade-out-up-sm{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}to{-webkit-transform:translateY(-75pt);transform:translateY(-75pt);opacity:0}}.fade-out-up-sm{-webkit-animation-name:fade-out-up-sm;animation-name:fade-out-up-sm}@-webkit-keyframes fade-in-up-lg{0%{-webkit-transform:translateY(750pt);transform:translateY(750pt);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}@keyframes fade-in-up-lg{0%{-webkit-transform:translateY(750pt);transform:translateY(750pt);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}.fade-in-up-lg{-webkit-animation-name:fade-in-up-lg;animation-name:fade-in-up-lg}@-webkit-keyframes fade-out-up-lg{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}to{-webkit-transform:translateY(-750pt);transform:translateY(-750pt);opacity:0}}@keyframes fade-out-up-lg{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}to{-webkit-transform:translateY(-750pt);transform:translateY(-750pt);opacity:0}}.fade-out-up-lg{-webkit-animation-name:fade-out-up-lg;animation-name:fade-out-up-lg}@-webkit-keyframes fade-in-down{0%{-webkit-transform:translateY(-500px);transform:translateY(-500px);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}@keyframes fade-in-down{0%{-webkit-transform:translateY(-500px);transform:translateY(-500px);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}.fade-in-down{-webkit-animation-name:fade-in-down;animation-name:fade-in-down}@-webkit-keyframes fade-out-down{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}to{-webkit-transform:translateY(500px);transform:translateY(500px);opacity:0}}@keyframes fade-out-down{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}to{-webkit-transform:translateY(500px);transform:translateY(500px);opacity:0}}.fade-out-down{-webkit-animation-name:fade-out-down;animation-name:fade-out-down}@-webkit-keyframes fade-in-down-sm{0%{-webkit-transform:translateY(-75pt);transform:translateY(-75pt);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}@keyframes fade-in-down-sm{0%{-webkit-transform:translateY(-75pt);transform:translateY(-75pt);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}.fade-in-down-sm{-webkit-animation-name:fade-in-down-sm;animation-name:fade-in-down-sm}@-webkit-keyframes fade-out-down-sm{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}to{-webkit-transform:translateY(75pt);transform:translateY(75pt);opacity:0}}@keyframes fade-out-down-sm{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}to{-webkit-transform:translateY(75pt);transform:translateY(75pt);opacity:0}}.fade-out-down-sm{-webkit-animation-name:fade-out-down-sm;animation-name:fade-out-down-sm}.fade-in-down-lg{-webkit-animation-name:fade-in-down;animation-name:fade-in-down}@-webkit-keyframes fade-out-down-lg{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}to{-webkit-transform:translateY(750pt);transform:translateY(750pt);opacity:0}}@keyframes fade-out-down-lg{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}to{-webkit-transform:translateY(750pt);transform:translateY(750pt);opacity:0}}.fade-out-down-lg{-webkit-animation-name:fade-out-down-lg;animation-name:fade-out-down-lg}@-webkit-keyframes fade-in-left{0%{-webkit-transform:translateX(-500px);transform:translateX(-500px);opacity:0}to{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}@keyframes fade-in-left{0%{-webkit-transform:translateX(-500px);transform:translateX(-500px);opacity:0}to{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}.fade-in-left{-webkit-animation-name:fade-in-left;animation-name:fade-in-left}@-webkit-keyframes fade-out-left{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform:translateX(-500px);transform:translateX(-500px);opacity:0}}@keyframes fade-out-left{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform:translateX(-500px);transform:translateX(-500px);opacity:0}}.fade-out-left{-webkit-animation-name:fade-out-left;animation-name:fade-out-left}@-webkit-keyframes fade-in-left-sm{0%{-webkit-transform:translateX(-75pt);transform:translateX(-75pt);opacity:0}to{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}@keyframes fade-in-left-sm{0%{-webkit-transform:translateX(-75pt);transform:translateX(-75pt);opacity:0}to{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}.fade-in-left-sm{-webkit-animation-name:fade-in-left-sm;animation-name:fade-in-left-sm}@-webkit-keyframes fade-out-left-sm{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform:translateX(-75pt);transform:translateX(-75pt);opacity:0}}@keyframes fade-out-left-sm{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform:translateX(-75pt);transform:translateX(-75pt);opacity:0}}.fade-out-left-sm{-webkit-animation-name:fade-out-left-sm;animation-name:fade-out-left-sm}@-webkit-keyframes fade-in-left-lg{0%{-webkit-transform:translateX(-1500px);transform:translateX(-1500px);opacity:0}to{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}@keyframes fade-in-left-lg{0%{-webkit-transform:translateX(-1500px);transform:translateX(-1500px);opacity:0}to{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}.fade-in-left-lg{-webkit-animation-name:fade-in-left-lg;animation-name:fade-in-left-lg}@-webkit-keyframes fade-out-left-lg{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform:translateX(-1500px);transform:translateX(-1500px);opacity:0}}@keyframes fade-out-left-lg{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform:translateX(-1500px);transform:translateX(-1500px);opacity:0}}.fade-out-left-lg{-webkit-animation-name:fade-out-left-lg;animation-name:fade-out-left-lg}@-webkit-keyframes fade-in-right{0%{-webkit-transform:translateX(500px);transform:translateX(500px);opacity:0}to{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}@keyframes fade-in-right{0%{-webkit-transform:translateX(500px);transform:translateX(500px);opacity:0}to{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}.fade-in-right{-webkit-animation-name:fade-in-right;animation-name:fade-in-right}@-webkit-keyframes fade-out-right{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform:translateX(500px);transform:translateX(500px);opacity:0}}@keyframes fade-out-right{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform:translateX(500px);transform:translateX(500px);opacity:0}}.fade-out-right{-webkit-animation-name:fade-out-right;animation-name:fade-out-right}@-webkit-keyframes fade-in-right-sm{0%{-webkit-transform:translateX(75pt);transform:translateX(75pt);opacity:0}to{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}@keyframes fade-in-right-sm{0%{-webkit-transform:translateX(75pt);transform:translateX(75pt);opacity:0}to{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}.fade-in-right-sm{-webkit-animation-name:fade-in-right-sm;animation-name:fade-in-right-sm}@-webkit-keyframes fade-out-right-sm{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform:translateX(75pt);transform:translateX(75pt);opacity:0}}@keyframes fade-out-right-sm{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform:translateX(75pt);transform:translateX(75pt);opacity:0}}.fade-out-right-sm{-webkit-animation-name:fade-out-right-sm;animation-name:fade-out-right-sm}@-webkit-keyframes fade-in-right-lg{0%{-webkit-transform:translateX(1500px);transform:translateX(1500px);opacity:0}to{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}@keyframes fade-in-right-lg{0%{-webkit-transform:translateX(1500px);transform:translateX(1500px);opacity:0}to{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}.fade-in-right-lg{-webkit-animation-name:fade-in-right-lg;animation-name:fade-in-right-lg}@-webkit-keyframes fade-out-right-lg{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform:translateX(1500px);transform:translateX(1500px);opacity:0}}@keyframes fade-out-right-lg{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform:translateX(1500px);transform:translateX(1500px);opacity:0}}.fade-out-right-lg{-webkit-animation-name:fade-out-right-lg;animation-name:fade-out-right-lg}@-webkit-keyframes rotate-in{0%{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);transform-origin:center center;opacity:0}0%,to{-webkit-transform-origin:center center}to{-webkit-transform:rotate(0);transform:rotate(0);transform-origin:center center;opacity:1}}@keyframes rotate-in{0%{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);transform-origin:center center;opacity:0}0%,to{-webkit-transform-origin:center center}to{-webkit-transform:rotate(0);transform:rotate(0);transform-origin:center center;opacity:1}}.rotate-in{-webkit-animation-name:rotate-in;animation-name:rotate-in}@-webkit-keyframes rotate-out{0%{-webkit-transform:rotate(0);transform:rotate(0);transform-origin:center center;opacity:1}0%,to{-webkit-transform-origin:center center}to{-webkit-transform:rotate(90deg);transform:rotate(90deg);transform-origin:center center;opacity:0}}@keyframes rotate-out{0%{-webkit-transform:rotate(0);transform:rotate(0);transform-origin:center center;opacity:1}0%,to{-webkit-transform-origin:center center}to{-webkit-transform:rotate(90deg);transform:rotate(90deg);transform-origin:center center;opacity:0}}.rotate-out{-webkit-animation-name:rotate-out;animation-name:rotate-out}@-webkit-keyframes rotate-in-sm{0%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);transform-origin:center center;opacity:0}0%,to{-webkit-transform-origin:center center}to{-webkit-transform:rotate(0);transform:rotate(0);transform-origin:center center;opacity:1}}@keyframes rotate-in-sm{0%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);transform-origin:center center;opacity:0}0%,to{-webkit-transform-origin:center center}to{-webkit-transform:rotate(0);transform:rotate(0);transform-origin:center center;opacity:1}}.rotate-in-sm{-webkit-animation-name:rotate-in-sm;animation-name:rotate-in-sm}@-webkit-keyframes rotate-out-sm{0%{-webkit-transform:rotate(0);transform:rotate(0);transform-origin:center center;opacity:1}0%,to{-webkit-transform-origin:center center}to{-webkit-transform:rotate(45deg);transform:rotate(45deg);transform-origin:center center;opacity:0}}@keyframes rotate-out-sm{0%{-webkit-transform:rotate(0);transform:rotate(0);transform-origin:center center;opacity:1}0%,to{-webkit-transform-origin:center center}to{-webkit-transform:rotate(45deg);transform:rotate(45deg);transform-origin:center center;opacity:0}}.rotate-out-sm{-webkit-animation-name:rotate-out-sm;animation-name:rotate-out-sm}@-webkit-keyframes rotate-in-lg{0%{-webkit-transform:rotate(-180deg);transform:rotate(-180deg);transform-origin:center center;opacity:0}0%,to{-webkit-transform-origin:center center}to{-webkit-transform:rotate(0);transform:rotate(0);transform-origin:center center;opacity:1}}@keyframes rotate-in-lg{0%{-webkit-transform:rotate(-180deg);transform:rotate(-180deg);transform-origin:center center;opacity:0}0%,to{-webkit-transform-origin:center center}to{-webkit-transform:rotate(0);transform:rotate(0);transform-origin:center center;opacity:1}}.rotate-in-lg{-webkit-animation-name:rotate-in-lg;animation-name:rotate-in-lg}@-webkit-keyframes rotate-out-lg{0%{-webkit-transform:rotate(0);transform:rotate(0);transform-origin:center center;opacity:1}0%,to{-webkit-transform-origin:center center}to{-webkit-transform:rotate(180deg);transform:rotate(180deg);transform-origin:center center;opacity:0}}@keyframes rotate-out-lg{0%{-webkit-transform:rotate(0);transform:rotate(0);transform-origin:center center;opacity:1}0%,to{-webkit-transform-origin:center center}to{-webkit-transform:rotate(180deg);transform:rotate(180deg);transform-origin:center center;opacity:0}}.rotate-out-lg{-webkit-animation-name:rotate-out-lg;animation-name:rotate-out-lg}@-webkit-keyframes flip-in-x{0%{-webkit-transform:perspective(550px) rotateX(90deg);transform:perspective(550px) rotateX(90deg);opacity:0}to{-webkit-transform:perspective(550px) rotateX(0deg);transform:perspective(550px) rotateX(0deg);opacity:1}}@keyframes flip-in-x{0%{-webkit-transform:perspective(550px) rotateX(90deg);transform:perspective(550px) rotateX(90deg);opacity:0}to{-webkit-transform:perspective(550px) rotateX(0deg);transform:perspective(550px) rotateX(0deg);opacity:1}}.flip-in-x{-webkit-animation-name:flip-in-x;animation-name:flip-in-x;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flip-out-x{0%{-webkit-transform:perspective(550px) rotateX(0deg);transform:perspective(550px) rotateX(0deg);opacity:1}to{-webkit-transform:perspective(550px) rotateX(90deg);transform:perspective(550px) rotateX(90deg);opacity:0}}@keyframes flip-out-x{0%{-webkit-transform:perspective(550px) rotateX(0deg);transform:perspective(550px) rotateX(0deg);opacity:1}to{-webkit-transform:perspective(550px) rotateX(90deg);transform:perspective(550px) rotateX(90deg);opacity:0}}.flip-out-x{-webkit-animation-name:flip-out-x;animation-name:flip-out-x;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flip-in-x-nr{0%{-webkit-transform:perspective(75pt) rotateX(90deg);transform:perspective(75pt) rotateX(90deg);opacity:0}to{-webkit-transform:perspective(75pt) rotateX(0deg);transform:perspective(75pt) rotateX(0deg);opacity:1}}@keyframes flip-in-x-nr{0%{-webkit-transform:perspective(75pt) rotateX(90deg);transform:perspective(75pt) rotateX(90deg);opacity:0}to{-webkit-transform:perspective(75pt) rotateX(0deg);transform:perspective(75pt) rotateX(0deg);opacity:1}}.flip-in-x-nr{-webkit-animation-name:flip-in-x-nr;animation-name:flip-in-x-nr;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flip-out-x-nr{0%{-webkit-transform:perspective(75pt) rotateX(0deg);transform:perspective(75pt) rotateX(0deg);opacity:1}to{-webkit-transform:perspective(75pt) rotateX(90deg);transform:perspective(75pt) rotateX(90deg);opacity:0}}@keyframes flip-out-x-nr{0%{-webkit-transform:perspective(75pt) rotateX(0deg);transform:perspective(75pt) rotateX(0deg);opacity:1}to{-webkit-transform:perspective(75pt) rotateX(90deg);transform:perspective(75pt) rotateX(90deg);opacity:0}}.flip-out-x-nr{-webkit-animation-name:flip-out-x-nr;animation-name:flip-out-x-nr;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flip-in-x-fr{0%{-webkit-transform:perspective(750pt) rotateX(90deg);transform:perspective(750pt) rotateX(90deg);opacity:0}to{-webkit-transform:perspective(750pt) rotateX(0deg);transform:perspective(750pt) rotateX(0deg);opacity:1}}@keyframes flip-in-x-fr{0%{-webkit-transform:perspective(750pt) rotateX(90deg);transform:perspective(750pt) rotateX(90deg);opacity:0}to{-webkit-transform:perspective(750pt) rotateX(0deg);transform:perspective(750pt) rotateX(0deg);opacity:1}}.flip-in-x-fr{-webkit-animation-name:flip-in-x-fr;animation-name:flip-in-x-fr;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flip-out-x-fr{0%{-webkit-transform:perspective(750pt) rotateX(0deg);transform:perspective(750pt) rotateX(0deg);opacity:1}to{-webkit-transform:perspective(750pt) rotateX(90deg);transform:perspective(750pt) rotateX(90deg);opacity:0}}@keyframes flip-out-x-fr{0%{-webkit-transform:perspective(750pt) rotateX(0deg);transform:perspective(750pt) rotateX(0deg);opacity:1}to{-webkit-transform:perspective(750pt) rotateX(90deg);transform:perspective(750pt) rotateX(90deg);opacity:0}}.flip-out-x-fr{-webkit-animation-name:flip-out-x-fr;animation-name:flip-out-x-fr;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flip-in-y{0%{-webkit-transform:perspective(550px) rotateY(90deg);transform:perspective(550px) rotateY(90deg);opacity:0}to{-webkit-transform:perspective(550px) rotateY(0deg);transform:perspective(550px) rotateY(0deg);opacity:1}}@keyframes flip-in-y{0%{-webkit-transform:perspective(550px) rotateY(90deg);transform:perspective(550px) rotateY(90deg);opacity:0}to{-webkit-transform:perspective(550px) rotateY(0deg);transform:perspective(550px) rotateY(0deg);opacity:1}}.flip-in-y{-webkit-animation-name:flip-in-y;animation-name:flip-in-y;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flip-out-y{0%{-webkit-transform:perspective(550px) rotateY(0deg);transform:perspective(550px) rotateY(0deg);opacity:1}to{-webkit-transform:perspective(550px) rotateY(90deg);transform:perspective(550px) rotateY(90deg);opacity:0}}@keyframes flip-out-y{0%{-webkit-transform:perspective(550px) rotateY(0deg);transform:perspective(550px) rotateY(0deg);opacity:1}to{-webkit-transform:perspective(550px) rotateY(90deg);transform:perspective(550px) rotateY(90deg);opacity:0}}.flip-out-y{-webkit-animation-name:flip-out-y;animation-name:flip-out-y;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flip-in-y-nr{0%{-webkit-transform:perspective(75pt) rotateY(90deg);transform:perspective(75pt) rotateY(90deg);opacity:0}to{-webkit-transform:perspective(75pt) rotateY(0deg);transform:perspective(75pt) rotateY(0deg);opacity:1}}@keyframes flip-in-y-nr{0%{-webkit-transform:perspective(75pt) rotateY(90deg);transform:perspective(75pt) rotateY(90deg);opacity:0}to{-webkit-transform:perspective(75pt) rotateY(0deg);transform:perspective(75pt) rotateY(0deg);opacity:1}}.flip-in-y-nr{-webkit-animation-name:flip-in-y-nr;animation-name:flip-in-y-nr;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flip-out-y-nr{0%{-webkit-transform:perspective(75pt) rotateY(0deg);transform:perspective(75pt) rotateY(0deg);opacity:1}to{-webkit-transform:perspective(75pt) rotateY(90deg);transform:perspective(75pt) rotateY(90deg);opacity:0}}@keyframes flip-out-y-nr{0%{-webkit-transform:perspective(75pt) rotateY(0deg);transform:perspective(75pt) rotateY(0deg);opacity:1}to{-webkit-transform:perspective(75pt) rotateY(90deg);transform:perspective(75pt) rotateY(90deg);opacity:0}}.flip-out-y-nr{-webkit-animation-name:flip-out-y-nr;animation-name:flip-out-y-nr;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flip-in-y-fr{0%{-webkit-transform:perspective(750pt) rotateY(90deg);transform:perspective(750pt) rotateY(90deg);opacity:0}to{-webkit-transform:perspective(750pt) rotateY(0deg);transform:perspective(750pt) rotateY(0deg);opacity:1}}@keyframes flip-in-y-fr{0%{-webkit-transform:perspective(750pt) rotateY(90deg);transform:perspective(750pt) rotateY(90deg);opacity:0}to{-webkit-transform:perspective(750pt) rotateY(0deg);transform:perspective(750pt) rotateY(0deg);opacity:1}}.flip-in-y-fr{-webkit-animation-name:flip-in-y-fr;animation-name:flip-in-y-fr;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flip-out-y-fr{0%{-webkit-transform:perspective(750pt) rotateY(0deg);transform:perspective(750pt) rotateY(0deg);opacity:1}to{-webkit-transform:perspective(750pt) rotateY(90deg);transform:perspective(750pt) rotateY(90deg);opacity:0}}@keyframes flip-out-y-fr{0%{-webkit-transform:perspective(750pt) rotateY(0deg);transform:perspective(750pt) rotateY(0deg);opacity:1}to{-webkit-transform:perspective(750pt) rotateY(90deg);transform:perspective(750pt) rotateY(90deg);opacity:0}}.flip-out-y-fr{-webkit-animation-name:flip-out-y-fr;animation-name:flip-out-y-fr;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes zoom-in{0%{-webkit-transform:scale(.7);transform:scale(.7);opacity:0}to{opacity:1}}@keyframes zoom-in{0%{-webkit-transform:scale(.7);transform:scale(.7);opacity:0}to{opacity:1}}.zoom-in{-webkit-animation-name:zoom-in;animation-name:zoom-in}@-webkit-keyframes zoom-out{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}50%{-webkit-transform:scale(.7);transform:scale(.7)}50%,to{opacity:0}}@keyframes zoom-out{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}50%{-webkit-transform:scale(.7);transform:scale(.7)}50%,to{opacity:0}}.zoom-out{-webkit-animation-name:zoom-out;animation-name:zoom-out}@-webkit-keyframes zoom-in-sm{0%{-webkit-transform:scale(.95);transform:scale(.95);opacity:0}to{opacity:1}}@keyframes zoom-in-sm{0%{-webkit-transform:scale(.95);transform:scale(.95);opacity:0}to{opacity:1}}.zoom-in-sm{-webkit-animation-name:zoom-in-sm;animation-name:zoom-in-sm}@-webkit-keyframes zoom-out-sm{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}50%{-webkit-transform:scale(.95);transform:scale(.95)}50%,to{opacity:0}}@keyframes zoom-out-sm{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}50%{-webkit-transform:scale(.95);transform:scale(.95)}50%,to{opacity:0}}.zoom-out-sm{-webkit-animation-name:zoom-out-sm;animation-name:zoom-out-sm}@-webkit-keyframes zoom-in-lg{0%{-webkit-transform:scale(.4);transform:scale(.4);opacity:0}to{opacity:1}}@keyframes zoom-in-lg{0%{-webkit-transform:scale(.4);transform:scale(.4);opacity:0}to{opacity:1}}.zoom-in-lg{-webkit-animation-name:zoom-in-lg;animation-name:zoom-in-lg}@-webkit-keyframes zoom-out-lg{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}50%{-webkit-transform:scale(.4);transform:scale(.4)}50%,to{opacity:0}}@keyframes zoom-out-lg{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}50%{-webkit-transform:scale(.4);transform:scale(.4)}50%,to{opacity:0}}.zoom-out-lg{-webkit-animation-name:zoom-out-lg;animation-name:zoom-out-lg}@-webkit-keyframes overlay-slide-in-top{0%{height:100%}to{height:0}}@keyframes overlay-slide-in-top{0%{height:100%}to{height:0}}.overlay-slide-in-top{top:0;height:0;-webkit-animation-name:overlay-slide-in-top;animation-name:overlay-slide-in-top}@-webkit-keyframes overlay-slide-out-top{0%{height:0}to{height:100%}}@keyframes overlay-slide-out-top{0%{height:0}to{height:100%}}.overlay-slide-out-top{top:0;height:100%;-webkit-animation-name:overlay-slide-out-top;animation-name:overlay-slide-out-top}@-webkit-keyframes overlay-slide-in-bottom{0%{height:100%}to{height:0}}@keyframes overlay-slide-in-bottom{0%{height:100%}to{height:0}}.overlay-slide-in-bottom{bottom:0;height:0;-webkit-animation-name:overlay-slide-in-bottom;animation-name:overlay-slide-in-bottom}@-webkit-keyframes overlay-slide-out-bottom{0%{height:0}to{height:100%}}@keyframes overlay-slide-out-bottom{0%{height:0}to{height:100%}}.overlay-slide-out-bottom{bottom:0;height:100%;-webkit-animation-name:overlay-slide-out-bottom;animation-name:overlay-slide-out-bottom}@-webkit-keyframes overlay-slide-in-left{0%{width:100%}to{width:0}}@keyframes overlay-slide-in-left{0%{width:100%}to{width:0}}.overlay-slide-in-left{width:0;-webkit-animation-name:overlay-slide-in-left;animation-name:overlay-slide-in-left}@-webkit-keyframes overlay-slide-out-left{0%{width:0}to{width:100%}}@keyframes overlay-slide-out-left{0%{width:0}to{width:100%}}.overlay-slide-out-left{left:0;width:100%;-webkit-animation-name:overlay-slide-out-left;animation-name:overlay-slide-out-left}@-webkit-keyframes overlay-slide-in-right{0%{width:100%}to{width:0}}@keyframes overlay-slide-in-right{0%{width:100%}to{width:0}}.overlay-slide-in-right{right:0;width:0;-webkit-animation-name:overlay-slide-in-right;animation-name:overlay-slide-in-right}@-webkit-keyframes overlay-slide-out-right{0%{width:0}to{width:100%}}@keyframes overlay-slide-out-right{0%{width:0}to{width:100%}}.overlay-slide-out-right{right:0;width:100%;-webkit-animation-name:overlay-slide-out-right;animation-name:overlay-slide-out-right}
    +
    +/* spectrum */
    +.sp-container{position:absolute;top:0;left:0;display:inline-block;z-index:9999994;overflow:hidden}.sp-container.sp-flat{position:relative}.sp-container,.sp-container *{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.sp-top{position:relative;width:100%;display:inline-block}.sp-top-inner{position:absolute;top:0;left:0;bottom:0;right:0}.sp-color{position:absolute;top:0;left:0;bottom:0;right:20%}.sp-hue{position:absolute;top:0;right:0;bottom:0;left:84%;height:100%}.sp-clear-enabled .sp-hue{top:33px;height:77.5%}.sp-fill{padding-top:80%}.sp-sat,.sp-val{position:absolute;top:0;left:0;right:0;bottom:0}.sp-alpha-enabled .sp-top{margin-bottom:18px}.sp-alpha-enabled .sp-alpha{display:block}.sp-alpha-handle{position:absolute;top:-4px;bottom:-4px;width:6px;left:50%;cursor:pointer;border:1px solid #000;background:#fff;opacity:.8}.sp-alpha{display:none;bottom:-14px;right:0;left:0;height:8px}.sp-alpha-inner{border:1px solid #333}.sp-clear{display:none}.sp-clear.sp-clear-display{background-position:center}.sp-clear-enabled .sp-clear{display:block;position:absolute;top:0;right:0;bottom:0;left:84%;height:28px}.sp-alpha,.sp-alpha-handle,.sp-clear,.sp-container,.sp-container button,.sp-container.sp-dragging .sp-input,.sp-dragger,.sp-preview,.sp-replacer,.sp-slider{-webkit-user-select:none;-moz-user-select:-moz-none;-o-user-select:none;user-select:none}.sp-container.sp-buttons-disabled .sp-button-container,.sp-container.sp-input-disabled .sp-input-container,.sp-container.sp-palette-buttons-disabled .sp-palette-button-container,.sp-initial-disabled .sp-initial,.sp-palette-disabled .sp-palette-container,.sp-palette-only .sp-picker-container{display:none}.sp-sat{-ms-filter:"progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)";background-image:linear-gradient(to right,#fff,rgba(204,154,129,0))}.sp-val{-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)";background-image:linear-gradient(to top,#000,rgba(204,154,129,0))}.sp-hue{background:-moz-linear-gradient(top,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);background:-ms-linear-gradient(top,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);background:-o-linear-gradient(top,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);background:-webkit-gradient(linear,left top,left bottom,from(red),color-stop(.17,#ff0),color-stop(.33,#0f0),color-stop(.5,#0ff),color-stop(.67,#00f),color-stop(.83,#f0f),to(red));background:-webkit-linear-gradient(top,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);background:linear-gradient(to bottom,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%)}.sp-1{height:17%;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00')}.sp-2{height:16%;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00')}.sp-3{height:17%;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff')}.sp-4{height:17%;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff')}.sp-5{height:16%;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff')}.sp-6{height:17%;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000')}.sp-hidden{display:none!important}.sp-cf:after,.sp-cf:before{content:"";display:table}.sp-cf:after{clear:both}@media (max-device-width:480px){.sp-color{right:40%}.sp-hue{left:63%}.sp-fill{padding-top:60%}}.sp-dragger{border-radius:5px;height:5px;width:5px;border:1px solid #fff;background:#000;cursor:pointer;position:absolute;top:0;left:0}.sp-slider{position:absolute;top:0;cursor:pointer;height:3px;left:-1px;right:-1px;border:1px solid #000;background:#fff;opacity:.8}.sp-container{padding:0}.sp-clear,.sp-color,.sp-container,.sp-container button,.sp-container input,.sp-hue{font:400 12px "Lucida Grande","Lucida Sans Unicode","Lucida Sans",Geneva,Verdana,sans-serif;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.sp-top{margin-bottom: 0px;}.sp-clear,.sp-color,.sp-hue{border:1px solid #666}.sp-input-container{float:right;width:100px;margin-bottom:4px}.sp-initial-disabled .sp-input-container{width:100%}.sp-input{font-size:12px!important;border:1px inset;padding:4px 5px;margin:0;width:100%;background:0 0;border-radius:3px;color:#222}.sp-input:focus{border:1px solid orange}.sp-input.sp-validation-error{border:1px solid red;background:#fdd}.sp-palette-container,.sp-picker-container{position:relative;padding: 0 0 10px 0;}.sp-picker-container{width: 225px;padding: 0;}.sp-palette-only .sp-palette-container{border:0}.sp-palette .sp-thumb-el{display:block;position:relative;float:left;cursor:pointer}.sp-palette .sp-thumb-el.sp-thumb-active,.sp-palette .sp-thumb-el:hover{border-color:orange}.sp-initial{float:left;border:1px solid #333}.sp-initial span{width:30px;height:25px;border:none;display:block;float:left;margin:0}.sp-initial .sp-clear-display{background-position:center}.sp-button-container,.sp-palette-button-container{float:right}.sp-replacer{margin:0;overflow:hidden;cursor:pointer;padding:4px;display:inline-block;border:1px solid #91765d;background:#eee;color:#333;vertical-align:middle}.sp-replacer.sp-active,.sp-replacer:hover{border-color:#F0C49B;color:#111}.sp-replacer.sp-disabled{cursor:default;border-color:silver;color:silver}.sp-dd{padding:2px 0;height:16px;line-height:16px;float:left;font-size:10px}.sp-preview{width:25px;height:20px;border:1px solid #222;margin-right:5px;float:left;z-index:0}.sp-palette{max-width:220px}.sp-palette .sp-thumb-el{width: 20px;height: 20px;margin: 1px;border: 1px solid #EFEFEF;}.sp-container{padding-bottom:0}.sp-container button{background-color:#eee;background-image:-webkit-linear-gradient(top,#eee,#ccc);background-image:-moz-linear-gradient(top,#eee,#ccc);background-image:-ms-linear-gradient(top,#eee,#ccc);background-image:-o-linear-gradient(top,#eee,#ccc);background-image:linear-gradient(to bottom,#eee,#ccc);border:1px solid #ccc;border-bottom:1px solid #bbb;border-radius:3px;color:#333;font-size:14px;line-height:1;padding:5px 4px;text-align:center;text-shadow:0 1px 0 #eee;vertical-align:middle}.sp-container button:hover{background-color:#ddd;background-image:-webkit-linear-gradient(top,#ddd,#bbb);background-image:-moz-linear-gradient(top,#ddd,#bbb);background-image:-ms-linear-gradient(top,#ddd,#bbb);background-image:-o-linear-gradient(top,#ddd,#bbb);background-image:linear-gradient(to bottom,#ddd,#bbb);border:1px solid #bbb;border-bottom:1px solid #999;cursor:pointer;text-shadow:0 1px 0 #ddd}.sp-container button:active{border:1px solid #aaa;border-bottom:1px solid #888;-webkit-box-shadow:inset 0 0 5px 2px #aaa,0 1px 0 0 #eee;-moz-box-shadow:inset 0 0 5px 2px #aaa,0 1px 0 0 #eee;-ms-box-shadow:inset 0 0 5px 2px #aaa,0 1px 0 0 #eee;-o-box-shadow:inset 0 0 5px 2px #aaa,0 1px 0 0 #eee;box-shadow:inset 0 0 5px 2px #aaa,0 1px 0 0 #eee}.sp-cancel{font-size:11px;color:#d93f3f!important;margin:0 5px 0 0;padding:2px;vertical-align:middle;text-decoration:none}.sp-cancel:hover{color:#d93f3f!important;text-decoration:underline}.sp-palette span.sp-thumb-active,.sp-palette span:hover{border-color:#000}.sp-alpha,.sp-preview,.sp-thumb-el{position:relative;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.sp-alpha-inner,.sp-preview-inner,.sp-thumb-inner{display:block;position:absolute;top:0;left:0;bottom:0;right:0}.sp-palette .sp-thumb-inner{background-position:50% 50%;background-repeat:no-repeat}.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=)}.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=)}.sp-clear-display{background-repeat:no-repeat;background-position:center;background-image:url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==)}
    +@keyframes spin {from {transform: rotate(0deg);}to {transform: rotate(360deg);}}.show-tools:before{animation-name: spin;animation-iteration-count: infinite;animation-timing-function: linear;animation-duration: 3s;}
    +@-webkit-keyframes spin {from {-webkit-transform: rotate(0deg);}to {-webkit-transform: rotate(360deg);}}.show-tools:before{-webkit-animation-name: spin;-webkit-animation-iteration-count: infinite;-webkit-animation-timing-function: linear;-webkit-animation-duration: 3s;}
    +
    +/* animations */
    +@keyframes move {0% {transform: scale(0);}100% {transform: scale(1);}}
    +@-webkit-keyframes move {0% {-webkit-transform: scale(0);}100% {-webkit-transform: scale(1);}}
    +@keyframes radar {0% {transform: scale(0); opacity: 0;}25% {transform: scale(0); opacity: 0.5;}50% {transform: scale(1); opacity: 1;}75% {transform: scale(1.5); opacity: 0.5;}100% {transform: scale(2); opacity: 0;}}
    +@-webkit-keyframes radar {0% {-webkit-transform: scale(0); opacity: 0;}25% {-webkit-transform: scale(0); opacity: 0.5;}50% {-webkit-transform: scale(1); opacity: 1;}75% {webkit-transform: scale(1.5); opacity: 0.5;}100% {-webkit-transform: scale(2); opacity: 0;}}
    +.social-list li a:after,.tags.hover-effect li a:after,.nav-animate > ul > li > a span:after, .nav-animate > ul > li > span > a span:after{content:attr(data-hover);}
    +
    +/* Row with equal height columns */
    +.row-eq-height,.testimonials-5 > .row {display: -webkit-box;display: -webkit-flex;display: -ms-flexbox;display:flex;}
    +.row .row {margin-top: 10px;margin-bottom: 0;}
    +
    +.share-post, .comment-list li.new-angle, footer .tags li, .team-box, .gallery_thumbs a, .feature-img figure, .feature-img2 figure, .horizontal-slider.round, .item-box.round, .vis-search,.filter-by ul li.border5px{
    +	-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
    +}
    +
    +/* ============================================================================
    +	- CSS Document
    +	- Theme Name: SuperFine | MultiPurpose HTML5 Template.
    +	- Theme URI: http://html.it-rays.net/superfine/
    +	- Author: IT-RAYS
    +	- Version: 1.0
    +============================================================================= */
    +/*==============================================================================
    +    CONTENTS:
    +
    +    1. CSS RESET.
    +    2. SITE PRELOADER.
    +    3. HEADER STYLE:
    +        3.1. Top bar.
    +        3.2. Main menu.
    +        3.3. Top Search.
    +        3.4. Top Cart.
    +        3.5. Header Styles.
    +    4. PAGE TITLES.
    +    5. FORM CONRTOLS.
    +    6. SHORTCODES.
    +    	6.1. Headings
    +    	6.2. Dividers
    +    	6.3. Icon Boxes
    +    	6.4. Tabs
    +    	6.5. Accordions
    +    	6.6. Progress Bars
    +    	6.7. Circliful Charts
    +    	6.8. CTA
    +    	6.9. Team Boxes
    +    	6.10. Pricing Tables
    +    	6.11. Testimonials
    +    	6.12. Pagination
    +    	6.13. Message Boxes
    +    7. PAGE SPECIFIC STYLES:
    +        widgets.
    +		login.
    +		coming soon.
    +		404 not found.
    +		portfolio.
    +		About.
    +		Site Map.
    +		Blog.
    +		Shop.
    +    8. FOOTER.
    +    	8.1. Footer 1.
    +    	8.2. Footer 2.
    +    	8.3. Footer 3.
    +    	8.4. Footer 4.
    +    	8.5. Footer Light.
    +    	8.6. Footer Minimal.
    +    	8.7. Fixed Footer.
    +    9. HOME ELEMENTS.
    +    10. TYPOGRAPHY.
    +    11. IMPORTANT CLASSES.
    +    12. SHAPES.
    +    13. BOXED MODE.
    +    14. RESPONSIVE DESIGN.
    +
    +/* ==========================================================================
    +  1. CSS RESET
    +============================================================================= */
    +html{
    +	-webkit-font-smoothing: antialiased;
    +	-webkit-tap-highlight-color: transparent;
    +}
    +body {
    +	font-family:"Raleway",sans-serif;
    +	line-height:1.5;
    +	-webkit-font-smoothing: antialiased;
    +	font-size:13px
    +}
    +p {
    +	margin: 0 0 20px 0;
    +	line-height: 24px;
    +}
    +dd, dt, dl, ol, ul, li {
    +	margin:0;
    +	padding:0;
    +	list-style:none;
    +}
    +a {
    +	text-decoration:none;
    +}
    +.main-bg a,.main-bg a:hover,.btn.main-bg:focus{
    +	color:#fff
    +}
    +a:focus, a:hover {
    +	text-decoration:none;
    +}
    +a:focus{
    +	outline:none;
    +}
    +h1, h2, h3, h4, h5, h6 {
    +	font-weight:600;
    +	line-height:1.5;
    +	margin:0 0 30px;
    +}
    +h5, h6 {margin-bottom:20px;font-weight:700}
    +
    +:active,:focus {
    +	outline:0 !important;
    +}
    +.hidden,.nl-note{
    +	display:none
    +}
    +table {
    +	width: 100%;
    +	border-spacing: 0;
    +	border-collapse: collapse;
    +	margin-bottom:15px
    +}
    +th, td, caption {padding: 10px;}
    +img {
    +	max-width:100%;
    +	vertical-align:middle;
    +	border:0;
    +}
    +iframe {
    +	border:none !important;
    +}
    +.relative, .tp-banner-container {
    +	position:relative;
    +	z-index:1
    +}
    +.fx{
    +	opacity:0
    +}
    +.animated{
    +	opacity:1;
    +}
    +.pos-static{
    +	position:static !important
    +}
    +.tp-caption.Newspaper-Title, .Newspaper-Title,.tp-caption.Newspaper-Subtitle, .Newspaper-Subtitle,.erinyen .tp-tab-desc,.tp-caption.Newspaper-Button, .Newspaper-Button,.tp-caption.Newspaper-Title-Centered, .Newspaper-Title-Centered{
    +	font-family:inherit !important
    +}
    +.section {
    +	padding: 100px 0;
    +	position:relative;
    +	overflow:hidden;
    +	clear:both
    +}
    +.section:after{
    +	display:table;
    +	content:"";
    +	clear:both;
    +}
    +.lg-banner{
    +	position:relative
    +}
    +.lg-banner > .container{
    +	display:table
    +}
    +.banner-content{
    +	position:relative;
    +	z-index:9;
    +	display:table-cell;
    +	vertical-align:middle
    +}
    +.banner-slick h1{
    +	margin-bottom:20px
    +}
    +.banner-content hr.custom-hr{
    +	border-top:1px solid rgba(255,255,255,.3);
    +}
    +.pageWrapper {
    +	position:relative;
    +	z-index:1;
    +}
    +.login-page .pageWrapper, .login-page #contentWrapper,.soon-page .pageWrapper, .soon-page #contentWrapper{
    +	background:transparent
    +}
    +#contentWrapper,.fullscreen-container,.modal-content{
    +	overflow:hidden
    +}
    +.modal-header {
    +	padding: 10px 15px;
    +}
    +.modal-header h4{
    +	color:#fff
    +}
    +.modal-content {
    +	border: 7px solid rgba(255, 255, 255, 0.4);
    +	-webkit-box-shadow: none;
    +	box-shadow: none;
    +}
    +.modal-header .close {
    +	font-size: 32px;
    +	line-height: 23px;
    +}
    +.login-popup{
    +	width:300px;
    +	border-radius:0px;
    +	padding:20px !important;
    +	margin:0;
    +	border:0
    +}
    +.dropdown.open .login-popup{
    +	margin-top:10px !important
    +}
    +.login-popup.black-bg:after{
    +	position:absolute;
    +	left:30px;
    +	top:-6px;
    +	content:"";
    +	display:inline-block;
    +	width: 0;
    +	height: 0;
    +	border-style: solid;
    +	border-width: 0 6px 6px 6px;
    +	border-color: transparent transparent #333 transparent;
    +}
    +
    +/* =========================================================================
    +	2.SITE PRELOADER.
    +============================================================================ */
    +.page-loader {
    +	position: fixed;
    +	z-index: 999999;
    +	width: 100%;
    +	height: 100%;
    +	background: #fff;
    +	top:0;
    +	left:0
    +}
    +.page-loader .inner-l {
    +	position: absolute;
    +	top: 50%;
    +	left: 50%;
    +	margin-top:-30px;
    +	margin-left:-30px;
    +	width: 60px;
    +	height: 60px;
    +}
    +.page-loader span {
    +	position:absolute;
    +	width:50px;
    +	height:50px;
    +	border: 5px solid #ddd;
    +	border-radius:999px;
    +	animation: radar 2s infinite linear;
    +	opacity: 0;
    +}
    +
    +.page-loader span:nth-child(1) {
    +	animation-delay: 0s;
    +}
    +.page-loader span:nth-child(2) {
    +	animation-delay: 0.66s;
    +}
    +.page-loader span:nth-child(3) {
    +	animation-delay: 1.33s;
    +}
    +
    +/* =========================================================================
    +	3.HEADER STYLE.
    +============================================================================ */
    +/*
    +-------------- 3.1. Top bar. ------------- */
    +.top-bar {
    +	min-height: 35px;
    +	padding:10px 0
    +}
    +.top-bar ul li {
    +	float: left;
    +	line-height: 30px;
    +	position:relative;
    +	padding: 0 15px;
    +	font-size:11px
    +}
    +.top-bar ul ul li{
    +	float:none;
    +	line-height:normal;
    +}
    +.dropdown-menu {
    +	min-width: 160px;
    +	padding: 0;
    +	margin: 0;
    +	border: 1px solid rgba(0,0,0,.09) !important;
    +	border-radius: 0px;
    +}
    +.top-bar ul ul li:first-child a{
    +	border-top:0
    +}
    +.top-bar ul li i {
    +	margin-right: 5px;
    +}
    +.top-bar ul > li > a {
    +	text-transform: uppercase;
    +	display:block;
    +	margin: 0 -15px;
    +	padding: 0 15px;
    +}
    +.top-bar ul:not(.social-list) > li li a{
    +	border-radius:0
    +}
    +
    +.top-bar ul.social-list li:first-child a,.top-bar ul.social-list li:last-child a{
    +	width:35px
    +}
    +.bar-menu li a {
    +	font-size: 11px;
    +	text-transform: uppercase;
    +}
    +.top-bar .alter-bg.social-list li a:hover{
    +	background:rgba(0,0,0,.2) !important
    +}
    +.top-bar .alter-bg.social-list li a:after{
    +	color:#eee !important;
    +}
    +.middle-ul{
    +	margin:0 10px;
    +	overflow:hidden
    +}
    +.top-bar .center-tbl ul{
    +	float:left
    +}
    +.top-bar .social-list{
    +	overflow:hidden
    +}
    +.top-bar .social-list li{
    +	margin:0;
    +	padding:0
    +}
    +.top-bar .social-list li a{
    +	height:30px;
    +	width:30px;
    +	line-height:30px
    +}
    +.top-bar.main-bg li.dropdown ul li a{
    +	border-top-color :rgba(255,255,255,.3)
    +}
    +.top-bar .social-list li a{
    +	border-radius:0px;
    +	margin:0;
    +	padding:0
    +}
    +.top-bar ul ul li{
    +	line-height:normal;
    +}
    +.top-bar ul ul li a{
    +	line-height:normal;
    +	padding:10px 15px
    +}
    +.top-bar ul li a b{
    +	font-weight:normal;
    +	font-size: 10px;
    +	margin: 10px 0 0 5px;
    +}
    +.currency ul,.language ul{
    +	min-width:80px !important
    +}
    +.login-ul input[type=text], .login-ul input[type=email], .login-ul input[type=password], .login-ul select, .login-ul input[type=file]{
    +	height:40px
    +}
    +
    +.top-border {
    +	height:3px;
    +}
    +.top-head:after{
    +	clear:both;
    +	display:table;
    +	content:" ";
    +}
    +.top-head .container {
    +	position:relative;
    +	display:table;
    +	height:100%;
    +}
    +.tbl-row{
    +	display:table-row;
    +	height:100%
    +}
    +.responsive-nav{
    +	display:table-cell;
    +	vertical-align:middle;
    +	height:100%
    +}
    +.full.responsive-nav{
    +	display:block
    +}
    +.no-lines:before,.no-lines:after{
    +	display:none !important
    +}
    +.top-head .logo {
    +	position:relative;
    +	display:table-cell;
    +	vertical-align:middle;
    +}
    +.top-head.boxed-transparent .logo {
    +	height:100%
    +}
    +.top-head.boxed-transparent .logo:before {
    +	position:absolute;
    +	right:0;
    +	bottom:-1px;
    +	display:inline-block;
    +	content:"";
    +	height:1px;
    +	width:100%;
    +	animation:move .5s normal forwards ease-in-out;
    +	animation-delay:1s;
    +	-webkit-animation-delay:1s;
    +	transform-origin:right top;
    +	transform:scale(0);
    +	-webkit-transform:scale(0);
    +	-moz-transform:scale(0);
    +	-ms-transform:scale(0);
    +}
    +.top-head .logo a {
    +	display:table-cell;
    +	vertical-align:middle
    +}
    +.top-head.transparent {
    +	position: fixed;
    +	top: 0;
    +	left: 0;
    +	width: 100%;
    +	border-bottom: 1px rgba(255,255,255,.2) solid;
    +	z-index: 99;
    +	background: transparent;
    +}
    +.top-head.fixed-head {
    +	position:fixed;
    +	top:0;
    +	left:0;
    +	width:100%;
    +	z-index:99;
    +	border-bottom:0 ;
    +}
    +.top-head.fluid.transparent {
    +	position:fixed;
    +	top:0;
    +	left:0;
    +	width:100%;
    +	height:auto;
    +	z-index:99;
    +	border-bottom:1px rgba(0,0,0, 0.2) solid;
    +}
    +.top-head.fluid.transparent .logo {
    +	border-right:1px rgba(0,0,0 ,0.2) solid;
    +}
    +.top-head.fluid .transparent.dark .logo {
    +	border-right:1px rgba(255,255,255,0.2 ) solid;
    +	padding-right:20px;
    +}
    +.top-head.fluid.transparent.dark {
    +	border-bottom:1px rgba(255 ,255,255,0.2) solid;
    +}
    +.top-head.boxed-transparent {
    +	position:fixed;
    +	top:20px;
    +	left:0;
    +	width:100%;
    +	height:auto;
    +	z-index:99;
    +	background-color:transparent;
    +	border-bottom:0;
    +}
    +.top-head.boxed-transparent > .container {
    +	border:1px rgba(0,0,0,0.2) solid;
    +	padding: 0 30px 0 0;
    +	border-bottom-right-radius: 7em;
    +	border-top-right-radius: 7em;
    +}
    +.top-head.boxed-transparent.dark > .container {
    +	border: 1px rgba(255,255,255,0.4) solid;
    +}
    +.top-head.boxed-transparent .logo {
    +	padding-left: 30px;
    +}
    +.top-head.boxed-transparent > .container .head-srch-cart{
    +	margin-right:-30px
    +}
    +.top-head.boxed-transparent .lft-line {
    +	position:absolute;
    +	left:0px;
    +	bottom:0;
    +	display:inline-block;
    +	content:"";
    +	height:100%;
    +	width:1px;
    +	animation:move 0.4s normal forwards ease-in-out;
    +	animation-delay:1.4s;
    +	transform-origin:bottom left;
    +	transform:scale(0);
    +	-webkit-transform:scale(0);
    +	-moz-transform:scale(0);
    +	-ms-transform:scale(0);
    +}
    +.top-head.boxed-transparent .bot-line {
    +	position:absolute;
    +	left:0;
    +	top:-1px;
    +	display:inline-block;
    +	content:"";
    +	height:1px;
    +	animation:move .7s normal forwards ease-in-out;
    +	animation-delay:1.7s;
    +	transform-origin:left bottom;
    +	transform:scale(0);
    +	-webkit-transform:scale(0);
    +	-moz-transform:scale(0);
    +	-ms-transform:scale(0);
    +}
    +.top-head.transparent .top-nav > ul > li{
    +	padding-left:0;
    +	padding-right:0;
    +	margin:0 15px
    +}
    +.top-head.transparent .top-nav > ul > li:hover{
    +	background:transparent
    +}
    +.top-head.boxed-transparent .top-nav > ul > li:hover{
    +	background:transparent
    +}
    +.top-head.semi-light{
    +	background-color:rgba(255,255,255,.3);
    +}
    +.top-head .container.semi-light{
    +	background-color:rgba(255,255,255,.3);
    +}
    +.top-head.semi-dark{
    +	background-color:rgba(0,0,0,.3);
    +}
    +.top-head .container.semi-dark{
    +	background-color:rgba(0,0,0,.3);
    +}
    +
    +/*
    +------------- 2. header 2 -------------- */
    +.top-head.header-2 .top-nav > ul > li > a,.top-head.header-2 .top-nav > ul > li > span > a {
    +	font-size:12px
    +}
    +.top-head.transparent.header-2 .top-nav > ul > li, .top-head.transparent.header-2 .top-search, .top-head.transparent.header-2 .top-cart {
    +	border-left-color: rgba(255,255,255,.2);
    +}
    +.top-head.transparent.header-2 .top-cart {
    +	border-right-color: rgba(255,255,255,.2);
    +}
    +.top-head.header-2 .top-nav > ul > li{
    +	padding: 20px 10px 20px 0;
    +}
    +.top-head.header-2 .top-nav > ul > li > a,.top-head.header-2 .top-nav > ul > li > span > a{
    +	padding: 0 13px;
    +	line-height: 35px;
    +}
    +.top-head.header-2 .top-search,.top-head.header-2 .top-cart {
    +	padding: 0;
    +	margin: 20px 0 0 10px;
    +	position:relative;
    +}
    +.top-head.header-2 .top-search > a,.top-head.header-2 .top-cart > a{
    +	padding: 0 15px;
    +	display:block;
    +	position:relative;
    +	line-height: 35px;
    +}
    +.top-head.header-2 .top-search > a:before,.top-head.header-2 .top-cart > a:before{
    +	position:absolute;
    +	width:90%;
    +	height:90%;
    +	left:5%;
    +	top:5%;
    +	content:"";
    +	display:inline-block;
    +	-moz-transform: scale(1.8);
    +	-ms-transform: scale(0);
    +	-o-transform: scale(0);
    +	-webkit-transform: scale(1.8);
    +	transform: scale(0);
    +	opacity:0;
    +	-moz-transition:all 0.3s ease 0s;
    +	-ms-transition:all 0.3s ease 0s;
    +	-o-transition:all 0.3s ease 0s;
    +	-webkit-transition:all 0.3s ease 0s ;
    +	transition:all 0.3s ease 0s ;
    +	z-index:1;
    +}
    +.top-head.header-2 .top-search > a:hover:before,.top-head.header-2 .top-cart > a:hover:before{
    +	-moz-transform: scale(1);
    +	-ms-transform: scale(1);
    +	-o-transform: scale(1);
    +	-webkit-transform: scale(1);
    +	transform: scale(1);
    +	opacity:1
    +}
    +.top-head.header-2 .top-search > a > span,.top-head.header-2 .top-cart > a > span{
    +	position:relative;
    +	z-index:2
    +}
    +.top-head.header-2 .top-cart > a > i{
    +	z-index:2
    +}
    +.top-head.header-2 .top-search > a:hover span,.top-head.header-2 .top-cart > a:hover span{
    +	color:#fff;
    +}
    +.top-head.header-2 .top-cart .cart-box{
    +	margin-top:20px
    +}
    +.top-head.header-2 .top-cart .cart-num{
    +	top: 3px;
    +	right:6px
    +}
    +.top-head.header-2 .top-cart > a,.top-head.header-2 .top-search > a {
    +	margin: 0;
    +}
    +.top-head.header-2 .top-nav > ul > li:hover{
    +	background:transparent
    +}
    +.top-head.header-2 .top-nav > ul > li:hover > a > span:after,.top-head.header-2 .top-nav > ul > li:hover > a:after,.top-head.header-2 .top-nav > ul > li:hover > span > a > span:after,.top-head.header-2 .top-nav > ul > li:hover > span > a:after{
    +	color:#fff
    +}
    +
    +/*
    +------------- 3. header 3 -------------- */
    +.top-head.header-3, .top-head.header-4 {
    +	padding: 15px 0 0;
    +}
    +.top-head.header-3 .logo {
    +	display: table;
    +	margin: 0 auto;
    +	float: none;
    +	border: 0;
    +	padding:15px 0
    +}
    +.top-head.header-3 .logo:before, .top-head.header-4 .logo:before {
    +	display: none;
    +}
    +.top-head.header-3 .container {
    +	height: auto;
    +}
    +.top-head.header-3 .full, .top-head.header-4 .full {
    +	display: table;
    +	margin: 15px auto 0;
    +	clear: both;
    +}
    +.top-head.header-3 .container, .top-head.header-3 .top-search, .top-head.header-4 .container, .top-head.header-4 .top-search {
    +	height: auto;
    +}
    +.top-head.header-3 .top-search, .top-head.header-4 .top-search {
    +	border-left: 0;
    +}
    +.top-head.header-3 .top-nav > ul > li,.top-head.header-3 .top-search,.top-head.header-4 .top-nav > ul > li{
    +	padding:10px 15px 20px
    +}
    +.top-head.header-3 .top-cart{
    +	padding:10px 0 20px
    +}
    +.top-head.header-3 .top-nav > ul > li:hover,.top-head.header-4 .top-nav > ul > li:hover,.top-head.header-5 .top-nav > ul > li:hover,.top-head.header-6 .top-nav > ul > li:hover{
    +	background:transparent
    +}
    +
    +/*
    +------------- 4. header 4 -------------- */
    +.top-head.header-4 .top-search {
    +	float: right;
    +	padding: 7px 7px 7px 12px;
    +	margin: 8px 0 0;
    +}
    +.top-head.header-4 .top-cart {
    +	padding:20px 0 0 10px
    +}
    +.top-head.header-4 .top-cart .cart-box{
    +	margin-top: 25px;
    +}
    +.top-head.header-4 .top-search button {
    +	margin:-7px -7px -7px 0;
    +	padding: 7px 15px;
    +}
    +.top-head.header-4 .top-search input[type=text] {
    +	border: 0;
    +	font-size: 11px;
    +	width: 400px;
    +	height:auto;
    +	padding:0
    +}
    +.top-head.header-4.shop-head{
    +	padding-top:0
    +}
    +.top-shop-links{
    +	font-size:11px;
    +	margin-top:9px;
    +	margin-right:25px
    +}
    +.top-shop-links a{
    +	display:inline-block;
    +	padding:10px;
    +}
    +.top-shop-links a i{
    +	margin-right:7px
    +}
    +.top-shop-section .container{
    +	padding-right:25px;
    +	padding-left:25px
    +}
    +.top-shop-section [class*="col-md-"]{
    +	padding-left:5px;
    +	padding-right:5px
    +}
    +.top-head.header-3.sticky-nav .full, .top-head.header-4.sticky-nav .full{
    +	margin:0 auto
    +}
    +/*
    +------------- 5. header 5 -------------- */
    +.top-head.header-5 .top-search, .top-head.header-6 .top-search {
    +	border-left: 0px;
    +	position: relative;
    +}
    +.top-head.header-5 .top-search > a, .top-head.header-5 .top-cart > a {
    +	line-height: 33px;
    +	width: 33px;
    +	height: 33px;
    +	text-align: center;
    +	display: block;
    +	position: relative;
    +}
    +.top-head.header-5 .top-cart .cart-num {
    +	position: absolute;
    +	top: -3px;
    +	right: 0;
    +	left: auto;
    +}
    +.top-head.header-5 .bx-search .search-box button {
    +	background-color: transparent;
    +}
    +.top-head.header-5 .top-nav > ul > li > a {
    +	position: relative;
    +}
    +.top-head.header-5 .top-nav > ul > li:before,.top-head.header-5 .top-nav > ul > li .inner-mega:before {
    +	width: 0;
    +	position: absolute;
    +	bottom: 1px;
    +	left: 50%;
    +	height: 1px;
    +	content: "";
    +	display: inline-block;
    +}
    +.top-head.header-5 .top-nav > ul > li:hover:before,.top-head.header-5 .top-nav > ul > li:hover .inner-mega:before,.top-head.header-5 .top-nav > ul > li.selected .inner-mega:before,.top-head.header-5 .top-nav > ul > li.selected:before {
    +	width: 100%;
    +	left: 0;
    +}
    +.top-head.header-5 .top-nav > ul > li.mega-menu:before{
    +	display:none
    +}
    +.top-head.header-5 .top-search{
    +	padding: 23px 0;
    +}
    +.top-head.header-5 .top-cart{
    +	padding: 23px 0 23px  10px;
    +}
    +
    +/*
    +------------- 6. header 6 -------------- */
    +.top-head.header-6 .top-nav > ul > li > a,.top-head.header-6 .top-nav > ul > li > span > a {
    +	line-height: 1;
    +	position: relative;
    +	display: block;
    +	margin: -30px -15px;
    +	padding: 30px 15px;
    +}
    +.top-head.header-6 .top-nav > ul > li > a > i,.top-head.header-6 .top-nav > ul > li > span > a > i {
    +	display: block;
    +	text-align: center;
    +	padding: 0 0 10px;
    +	font-size: 14px;
    +}
    +.top-head.header-6 .top-nav > ul > li:hover > a,.top-head.header-6 .top-nav > ul > li:hover > span > a {
    +	text-shadow: 1px 1px 1px rgba(0,0,0,.2);
    +}
    +.top-head.header-6 .top-nav > ul > li:before,.top-head.header-6 .top-nav > ul > li .inner-mega:before {
    +	position: absolute;
    +	bottom: 0;
    +	left: 0;
    +	height: 0;
    +	content: "";
    +	display: inline-block;
    +	width: 100%;
    +	background-color: transparent;
    +	z-index: 0;
    +}
    +.top-head.header-6 .top-nav > ul > li:hover:before,.top-head.header-6 .top-nav > ul > li:hover .inner-mega:before {
    +	height: 95%;
    +}
    +.top-head.header-6 .top-nav > ul > li .inner-mega{
    +	margin-left:-15px;
    +	margin-right:-15px;
    +	padding-left:15px;
    +	padding-right:15px
    +}
    +.top-head.header-6 .top-nav > ul > li > a:before,.top-head.header-6 .top-nav > ul > li > span > a:before {
    +	position: absolute;
    +	top: -10px;
    +	left: 0;
    +	height: 2px;
    +	content: "";
    +	display: inline-block;
    +	width: 100%;
    +	background-color: transparent;
    +	opacity:0
    +}
    +.top-head.header-6 .top-nav > ul > li:hover > a:before,.top-head.header-6 .top-nav > ul > li:hover > span > a:before {
    +	top: 1px;
    +	opacity:1
    +}
    +.top-head.header-6 .top-nav > ul > li.mega-menu:before {
    +	display: none;
    +}
    +.top-head.header-6 .top-nav > ul > li.hasChildren:hover > a:after,.top-head.header-6 .top-nav > ul > li:hover .inner-mega a,.top-head.header-6 .top-nav > ul > li:hover .inner-mega a:after{
    +	color:#fff
    +}
    +.top-head.header-6 .top-search {
    +	padding: 32px 0 26px 15px;
    +}
    +.top-head.header-6 .top-search > a{
    +	padding: 12px;
    +}
    +.top-head.header-6 .top-cart {
    +	padding: 32px 0 26px 10px;
    +}
    +.top-head.header-6 .top-cart > a {
    +	padding: 12px;
    +	display: block;
    +	line-height: 1;
    +}
    +.top-head.header-6 .top-cart > a .cart-num{
    +	top: -4px;
    +	right: -4px;
    +}
    +/*
    +------------- 7. header 7 -------------- */
    +.up-head{
    +	padding: 20px 0;
    +	position:relative;
    +	display: table;
    +	width: 100%;
    +}
    +.up-head:after{
    +	display:table;
    +	clear:both;
    +	content:""
    +}
    +.top-head.header-7 .logo:before {
    +	display: none;
    +}
    +.top-head.header-7 .up-head {
    +	padding: 20px 0;
    +}
    +.top-head .full.main-bg {
    +	display: block;
    +}
    +.top-head .full.main-bg .top-nav {
    +	display: table;
    +	float: none;
    +	margin: auto;
    +}
    +.top-head .full.main-bg .top-nav > ul > li {
    +	padding:15px 18px
    +}
    +.top-head .full.main-bg .top-nav > ul > li > a,.top-head .full.main-bg .top-nav > ul > li > span > a{
    +	font-weight:normal
    +}
    +.top-head .full.main-bg .top-nav > ul > li:hover > a span:after,.top-head .full.main-bg .top-nav > ul > li:hover > span > a span:after{
    +	color:#fff
    +}
    +.top-head.header-7 .top-search {
    +	float: right;
    +	border-radius: 3px;
    +	padding: 7px 7px 7px 12px;
    +	margin: 0;
    +	height: auto;
    +}
    +.top-head.header-7 .top-search button {
    +	border: 0;
    +	background: transparent;
    +}
    +.top-head.header-7 .top-search input[type=text] {
    +	border: 0;
    +	font-size: 11px;
    +	width: 200px;
    +	height:auto;
    +	padding:0
    +}
    +.top-head.header-7 .top-cart{
    +	padding: 11px 0 0 10px;
    +}
    +.top-head.header-7 .top-cart .cart-box{
    +	margin-top: 25px;
    +}
    +.top-head .full.main-bg .top-nav > ul > li {
    +	border-left: 1px rgba(255,255,255,.3) solid;
    +}
    +.top-head .full.main-bg .top-nav ul ul li {
    +	text-shadow: none;
    +}
    +
    +/*
    +------------- 8. header 8 -------------- */
    +.top-head.header-8{
    +	border-bottom:0
    +}
    +.top-head.header-8 .top-nav > ul > li > a,.top-head.header-8 .top-nav > ul > li .inner-mega > a {
    +	line-height: 1;
    +	margin: -30px -15px;
    +	display:block;
    +	padding: 30px 15px 22px 15px;
    +}
    +.top-head.header-8 .top-nav > ul > li > a span,.top-head.header-8 .top-nav > ul > li > span > a span {
    +	display: block;
    +	margin-top: 7px;
    +	line-height: 12px;
    +	font-size: 11px;
    +	font-weight: 400;
    +	text-transform: capitalize;
    +}
    +.top-head.header-8 .top-nav > ul > li.hasChildren > a:after,.top-head.header-8 .top-nav > ul > li.hasChildren > span > a:after {
    +	display: none;
    +}
    +.top-head.header-8 .top-nav > ul > li:hover > a,.top-head.header-8 .top-nav > ul > li.selected > a,.top-head.header-8 .top-nav > ul > li:hover > span > a,.top-head.header-8 .top-nav > ul > li.selected > span > a  {
    +	border-bottom-width: 4px;
    +	border-bottom-style: solid;
    +}
    +.top-head.header-8 .top-search {
    +	border-left: 0px;
    +	position: relative;
    +	margin-left:10px
    +}
    +.top-head.header-8 .top-search > a, .top-head.header-8 .top-cart > a {
    +	line-height: 33px;
    +	width: 33px;
    +	height: 33px;
    +	margin-top: 30px;
    +	text-align: center;
    +	display: block;
    +	position: relative;
    +}
    +.top-head.header-8 .top-cart{
    +	margin-left:10px;
    +	padding-bottom: 25px !important;
    +}
    +.top-head.header-8 .top-cart .cart-num {
    +	position: absolute;
    +	top: -7px;
    +	right: -5px;
    +	left: auto;
    +}
    +.top-head.header-8 .top-nav ul ul{
    +	border-top:0
    +}
    +.top-head.header-8 .top-nav > ul > li > a,.top-head.header-8 .top-nav > ul > li.inner-mega {
    +	position: relative;
    +	font-weight: bold;
    +}
    +.top-head.header-8 .top-nav > ul > li > a:before,.top-head.header-8 .top-nav > ul > li > span > a:before {
    +	width: 0;
    +	position: absolute;
    +	bottom: -1px;
    +	left: 50%;
    +	height: 1px;
    +	content: "";
    +	display: inline-block;
    +}
    +.top-head.header-8 .top-nav > ul > li:hover > a:before,.top-head.header-8 .top-nav > ul > li.selected > a:before,.top-head.header-8 .top-nav > ul > li.inner-mega:hover:before {
    +	width: 100%;
    +	left: 0;
    +}
    +.top-head.header-8 .top-cart,.top-head.header-8 .top-search{
    +	padding: 0;
    +}
    +
    +/*
    +--------------------- header left -------------------- */
    +.left-side-wrap{
    +	margin:0 !important;
    +	margin-left: 280px !important;
    +	width:auto !important;
    +	position:relative
    +}
    +.right-side-wrap{
    +	margin:0 !important;
    +	margin-right: 280px !important;
    +	width:auto !important;
    +	position:relative
    +}
    +.header-left,.header-right{
    +	position:fixed;
    +	left:0;
    +	top:0 !important;
    +	width:280px;
    +	height:100%;
    +	-webkit-box-shadow: 3px 0px 5px 0px rgba(0, 0, 0, 0.4);
    +	-moz-box-shadow: 3px 0px 5px 0px rgba(0, 0, 0, 0.4);
    +	box-shadow: 3px 0px 5px 0px rgba(0, 0, 0, 0.4);
    +	z-index:999;
    +	border-bottom:0;
    +	padding:70px 0;
    +}
    +.header-left .responsive-nav,.header-right .responsive-nav{
    +	display:block
    +}
    +.header-right{
    +	left:auto;
    +	right:0;
    +	-webkit-box-shadow: -3px 0px 5px 0px rgba(0, 0, 0, 0.4);
    +	-moz-box-shadow: -3px 0px 5px 0px rgba(0, 0, 0, 0.4);
    +	box-shadow: -3px 0px 5px 0px rgba(0, 0, 0, 0.4);
    +}
    +.header-left .logo,.header-right .logo{
    +	display:table;
    +	margin:auto;
    +	float:none;
    +	padding:10px 20px
    +}
    +.side-nav{
    +	padding:40px 0;
    +}
    +.side-nav > ul > li {
    +	position: relative;
    +	margin: 0;
    +	padding:0 30px
    +}
    +.side-nav > ul > li > a:hover i, .side-nav > ul > li.selected > a i {
    +	margin-top: 5px;
    +}
    +.side-nav > ul > li > a {
    +	display: block;
    +	text-transform: uppercase;
    +	overflow: hidden;
    +	font-weight: bold;
    +	padding:15px 0;
    +	border-bottom:1px rgba(0,0,0,.1) solid
    +}
    +.black-bg .side-nav > ul > li > a {
    +	border-bottom:1px rgba(255,255,255,.1) solid
    +}
    +.header-left .top-search,.header-right .top-search {
    +  border: 1px rgba(0, 0, 0, 0.1) solid ;
    +}
    +.black-bg.header-left .top-search,.black-bg.header-right .top-search,.dark-bg.header-left .top-search,.dark-bg.header-right .top-search {
    +  border: 1px rgba(255, 255, 255, 0.1) solid;
    +}
    +.side-nav > ul > li.current > a{
    +	font-weight:bold
    +}
    +.side-nav > ul li a i{
    +	font-size:16px;
    +	margin-right:10px
    +}
    +.side-nav > ul ul {
    +	position: absolute;
    +	min-width: 220px;
    +	top:0;
    +	left:100%;
    +	z-index:99;
    +	-webkit-transform: translate3d(0,30px,0);
    +	transform: translate3d(0,30px,0);
    +	opacity: 0;
    +	visibility: hidden;
    +	-webkit-transition: all .4s ease-out;
    +	-moz-transition: all .4s ease-out;
    +	-ms-transition: all .4s ease-out;
    +	-o-transition: all .4s ease-out;
    +	transition: all .4s ease-out;
    +}
    +.side-nav ul ul li {
    +	position: relative;
    +	float: none;
    +	margin: 0;
    +	padding: 0;
    +	line-height: 35px;
    +}
    +.side-nav ul ul li a{
    +	padding-left:20px !important
    +}
    +.side-nav ul ul li i{
    +	font-size:12px
    +}
    +.side-nav li li a {
    +	display: block;
    +	overflow: hidden;
    +	padding: 0 25px !important;
    +	-ms-text-overflow: ellipsis;
    +	-o-text-overflow: ellipsis;
    +	text-overflow: ellipsis;
    +	white-space: nowrap;
    +	font-size: 13px;
    +	line-height: 40px !important;
    +}
    +.side-nav li.hasChildren:after {
    +	position: absolute;
    +	top: 15px;
    +	right: 30px;
    +	display: inline-block;
    +	content: "\f105";
    +	font-family: FontAwesome;
    +	-moz-transition: transform 0.3s linear;
    +	-o-transition: transform 0.3s linear;
    +	-webkit-transition: transform 0.3s linear;
    +	transition: transform 0.3s linear;
    +}
    +.side-nav li.hasChildren:hover:after {
    +	-webkit-transform: rotate(-180deg);
    +	-moz-transform: rotate(-180deg);
    +	-ms-transform: rotate(-180deg);
    +	-o-transform: rotate(-180deg);
    +	transform: rotate(-180deg);
    +}
    +.side-nav li li.hasChildren:after {
    +	top: 2px;
    +	right: 10px;
    +}
    +.header-left .top-search,.header-right .top-search{
    +	display:table;
    +	width: 76%;
    +	margin: 0 12% 30px !important;
    +	padding:0 0 0 10px !important
    +}
    +.header-left .top-search a,.header-right .top-search a{
    +	line-height:1
    +}
    +.header-left .search-box,.header-right .search-box{
    +	position:static
    +}
    +.header-left .top-search input[type=text], .header-right .top-search input[type=text]{
    +	border:0;
    +	height:39px;
    +	background:transparent;
    +	width:85%;
    +	padding:0
    +}
    +.side-nav li.mega-menu > ul > li{
    +	width:100%;
    +}
    +.side-nav li.mega-menu > ul > li h4{
    +	font-size:13px;
    +	line-height: 40px;
    +	margin: 0;
    +	padding-left: 15px;
    +	cursor:pointer;
    +	color:#fff;
    +	font-weight:normal
    +}
    +.header-right li.mega-menu > ul > li h4{
    +	padding-left: 30px;
    +}
    +.header-right .side-nav ul li a{
    +	text-align:right
    +}
    +.header-right .side-nav > ul ul {
    +	right:100%;
    +	left:auto
    +}
    +.header-right .side-nav li.hasChildren:after {
    +	left: 30px;
    +	content: "\f104";
    +	right:auto
    +}
    +.header-right .side-nav li li.hasChildren:after {
    +	left: 15px;
    +}
    +.header-right .side-nav li li i{
    +	float: right;
    +	margin:15px 0 0 10px
    +}
    +.side-header-bottom{
    +	text-align:center;
    +	font-size:12px;
    +	padding:30px
    +}
    +.side-header-bottom .social-list{
    +	display:table;
    +	margin:15px auto 5px
    +}
    +.top-head.transparent-3 {
    +	border-bottom: 1px rgba(255,255,255,.3) solid;
    +}
    +.top-head.transparent-3 .top-cart > a{
    +	margin-left: 5px
    +}
    +.top-head.transparent-3 .fluid-header{
    +	padding-right:30px
    +}
    +.top-head.dark .top-nav > ul > li > a, .top-head.dark .top-nav > ul > li > span > a {
    +	color:#fff;
    +}
    +.top-head.not-dark .top-nav > ul > li:not(.selected) > a,.top-head.not-dark .top-nav > ul > li:not(.selected) > span > a ,.top-head.not-dark .top-nav > ul > li:not(.selected) > a:after, .top-head.not-dark .top-cart > a {color:#444 !important;}
    +.top-head.not-dark .top-nav > ul > li > a, .top-head.not-dark .top-nav > ul > li > a:after {
    +	text-shadow:none !important;
    +}
    +.top-head.not-dark.transparent, .top-head.transparent.not-dark .logo, .top-head.transparent.not-dark .top-search {
    +	border-color:rgba(0,0,0,.2);
    +}
    +.top-head .full.main-bg .top-nav > ul > li > a,.top-head .full.main-bg .top-nav > ul > li > span > a, .top-head .full .main-bg .top-nav > ul > li > a:after {
    +	color:#fff !important;
    +}
    +.top-head.transparent.sticky-nav, .top-head.transparent.sticky-nav .logo, .top-head.transparent.sticky-nav .top-search {
    +	border:0px !important;
    +}
    +.top-head{
    +	transition: top 700ms ease;
    +	-webkit-transition: top 700ms ease;
    +	top:-100px
    +}
    +.top-head.sticky-nav {
    +	-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.1);
    +	box-shadow:0 1px 4px rgba(0, 0, 0, 0.1);
    +	position:fixed;
    +	z-index:999;
    +	width:100%;
    +	top:0;
    +	left:0;
    +}
    +/* fluid headers */
    +.top-head .fluid-header{
    +	width:100% !important
    +}
    +.top-head .fluid-header .top-nav .mega-menu > ul{
    +	width:98.5% !important
    +}
    +.top-head .fluid-header .logo {
    +	float: left;
    +	padding: 25px 20px 15px 0px;
    +}
    +.top-head.sticky-nav .bot-line, .top-head.sticky-nav .lft-line,.top-head.sticky-nav.header-3 .logo,.top-head.sticky-nav .up-head,.top-head.sticky-nav.boxed-transparent .logo:before{
    +	display:none
    +}
    +.top-head.sticky-nav.boxed-transparent > .container{
    +	border:0
    +}
    +.navbtn {
    +	display:none;
    +	position:fixed;
    +	right: 0;
    +	top: 0;
    +	width: 58px;
    +	height: 58px;
    +	line-height: 58px;
    +	text-align:center;
    +	z-index:9999;
    +	font-size:22px;
    +	color:#fff;
    +}
    +.navbtn.active {
    +	right:40%;
    +}
    +.navbtn:focus{
    +	color:#fff
    +}
    +.new-nav {
    +	position:fixed;
    +	right:-40%;
    +	top:0;
    +	z-index:9999;
    +	width:40%;
    +	height:100%;
    +	overflow:scroll;
    +	display:none
    +}
    +.new-nav.active {
    +	right:0;
    +}
    +.new-nav ul ul {
    +	display:none;
    +	background:#111;
    +}
    +.new-nav li {
    +	position:relative;
    +}
    +.new-nav li:after{
    +	display:none
    +}
    +.new-nav > ul > li a, .new-nav > ul > li.mega-menu h4 {
    +	display:block;
    +	padding:12px 20px;
    +	color:#ccc;
    +	font-size:13px;
    +	border-bottom:1px #353535 solid;
    +	margin:0;
    +	cursor:pointer
    +}
    +.new-nav > ul > li i {
    +	margin-right:10px;
    +}
    +.new-nav > ul > li.mega-menu [class*="col-md-"] {
    +	padding:0 ;
    +}
    +.new-nav li.hasChildren:after,.new-nav > ul > li.mega-menu h4:after {
    +	position:absolute;
    +	top:15px;
    +	right:15px;
    +	display:inline-block;
    +	content:"\f107";
    +	font-family:FontAwesome;
    +	font-size:15px;
    +	-moz-transition:transform 0.3s linear;
    +	-o-transition:transform 0.3s linear;
    +	-webkit-transition:transform 0.3s linear;
    +	transition:transform 0.3s linear;
    +	color:#ddd;
    +}
    +.new-nav li.hasChildren.active:after {
    +	-webkit-transform:rotate(-180deg);
    +	-moz-transform:rotate(-180deg);
    +	-ms-transform:rotate(-180deg);
    +	-o-transform:rotate(-180deg);
    +	transform:rotate(-180deg);
    +}
    +.new-nav ul ul li a, .new-nav > ul > li.mega-menu h4 {
    +	border-bottom:1px #1F1F1F solid;
    +	color:#868686;
    +}
    +.new-nav ul ul li.selected > a {
    +	background-color:#000;
    +}
    +.new-nav li li.selected > a {
    +	background-color:#0A0A0A;
    +}
    +.new-nav li.hasChildren.active > a, .new-nav li.hasChildren.active > h4 {
    +	background:#0B0B0B;
    +}
    +.top-nav {
    +	float:left;
    +	min-height:1px
    +}
    +.top-nav > ul > li {
    +	float:left;
    +	position:relative;
    +	padding: 30px 15px;
    +	cursor:pointer;
    +}
    +.top-nav > ul > li a{
    +	z-index:4 !important;
    +	font-size:14px
    +}
    +.header-9 .top-nav > ul > li.mega-menu > span{
    +	margin-left:-15px;
    +	margin-right:-15px;
    +	padding-right:15px;
    +	padding-left:15px
    +}
    +.header-9 .top-nav > ul > li:hover{
    +	background:transparent
    +}
    +.header-9 .top-nav > ul > li:not(.mega-menu):after,.header-9 .top-nav > ul > li.mega-menu > span:after{
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	right:0;
    +	top:0;
    +	content:"";
    +	display:inline-block;
    +	border-right-width:1px;
    +	border-right-style:solid;
    +	border-top-right-radius:10em;
    +	border-bottom-right-radius:10em;
    +	z-index:2;
    +}
    +.header-9 .top-nav > ul > li:not(.mega-menu):before,.header-9 .top-nav > ul > li.mega-menu > span:before{
    +	position:absolute;
    +	width: 35px;
    +	height:100%;
    +	left: -35px;
    +	top:0;
    +	content:"";
    +	display:inline-block;
    +	z-index:1
    +}
    +.header-9 .top-nav > ul > li:not(.mega-menu):first-child:before{
    +	border-top-right-radius:10em;
    +	border-bottom-right-radius:10em;
    +	z-index:3 !important;
    +	left: -15px !important;
    +	width: 55px;
    +}
    +.header-9 .top-nav > ul > li.mega-menu:first-child > span:before{
    +	border-top-right-radius:10em;
    +	border-bottom-right-radius:10em;
    +	z-index:3 !important;
    +	left: -15px !important;
    +	width: 55px;
    +	background:#fff !important;
    +}
    +
    +.header-9 .top-nav > ul > li:not(.mega-menu):first-child,.header-9 .top-nav > ul > li.mega-menu:first-child > span{
    +	padding-left: 45px;
    +}
    +.header-9 .top-nav > ul > li:not(.mega-menu):first-child > ul{
    +	left:0
    +}
    +.top-head.header-9 .top-search{
    +	margin-left:10px
    +}
    +/*.top-head.sticky-nav.header-9 .top-nav > ul > li:first-child{
    +	padding-left:15px
    +}*/
    +.top-nav > ul > li > a, .top-nav > ul > li > span > a {
    +	font-weight:700;
    +	text-transform:uppercase;
    +	z-index:2;
    +	font-size:13px;
    +	letter-spacing:0.5px;
    +	position: relative;
    +}
    +li.mega-menu .inner-mega {
    +	position:relative;
    +	display:block;
    +	margin: -30px 0;
    +	padding: 30px 0;
    +}
    +.top-nav > ul > li ul, .top-head .top-cart .cart-box, .bx-search .search-box, .top-search .search-box {
    +	-webkit-box-shadow:0px 2px 2px 0px rgba(0,0, 0,0.3);
    +	-moz-box-shadow:0px 2px 2px 0px rgba( 0,0,0,0.3);
    +	box-shadow:0px 2px 2px 0px rgba(0,0,0,0.3);
    +}
    +.top-nav ul li ul {
    +	position:absolute;
    +	top:100%;
    +	left:0;
    +	min-width:200px;
    +	border-top-style:solid;
    +	border-top-width:3px;
    +	z-index:999;
    +	-webkit-transform: translate3d(0,30px,0);
    +	transform: translate3d(0,30px,0);
    +	opacity: 0;
    +	visibility: hidden;
    +	-webkit-transition: all .4s ease-out;
    +	-moz-transition: all .4s ease-out;
    +	-ms-transition: all .4s ease-out;
    +	-o-transition: all .4s ease-out;
    +	transition: all .4s ease-out;
    +}
    +.top-nav ul li:hover > ul {
    +	opacity: 1;
    +	visibility: visible;
    +	-webkit-transform: translate3d(0,0,0);
    +	transform: translate3d(0,0,0);
    +}
    +.top-nav ul li:hover > ul,.side-nav ul li:hover > ul {
    +	opacity: 1;
    +	visibility: visible;
    +}
    +.header-9 .top-nav > ul > li:not(.mega-menu) > ul {
    +	left: -35px;
    +}
    +.top-nav.colored-submenu ul li ul {
    +	border-top:0 !important;
    +}
    +.top-nav ul li ul ul,.side-nav ul li > ul {
    +	top:0;
    +	left:100%;
    +	border-top-width:0;
    +	border-left-style:solid;
    +	border-left-width:3px;
    +	-webkit-transform: translate3d(30px,0,0);
    +	transform: translate3d(30px,0,0);
    +}
    +.top-nav ul li ul li:hover > ul,.side-nav ul li:hover > ul {
    +	top:0;
    +	-webkit-transform: translate3d(0,0,0);
    +	transform: translate3d(0,0,0);
    +}
    +.top-nav ul li ul li > ul.rit-menu {
    +	top:0;
    +	right:100%;
    +	left:auto;
    +	-webkit-transform: translate3d(-30px,0,0);
    +	transform: translate3d(-30px,0,0);
    +	border-right-width:3px;
    +	border-right-style:solid;
    +	border-left:0
    +}
    +.top-nav ul li ul li:hover > ul.rit-menu {
    +	-webkit-transform: translate3d(0,0,0);
    +	transform: translate3d(0,0,0);
    +}
    +
    +.top-nav ul ul li {
    +	line-height:normal;
    +	float:none;
    +	position:relative;
    +	display:block;
    +}
    +.top-nav > ul > li.hasChildren > a:after, .top-nav > ul > li.hasChildren > span > a:after {
    +	display:inline-block;
    +	font:normal normal normal 8px/1 FontAwesome;
    +	content:"\f078";
    +	margin-left:5px;
    +	top:-1px;
    +	position:relative;
    +	-moz-transition-delay:0.3s !important;
    +	-ms-transition-delay:0.3s !important;
    +	-o-transition-delay:0.3s !important;
    +	-webkit-transition-delay:0.3s !important;
    +	transition-delay:0.3s !important;
    +}
    +.top-nav > ul > li.hasChildren:hover > a:after, .top-nav > ul > li.hasChildren:hover > span > a:after {
    +	-webkit-transform:rotate(-180deg);
    +	-moz-transform:rotate(-180deg);
    +	-o-transform:rotate(-180deg);
    +	-ms-transform:rotate(-180deg);
    +	transform:rotate(-180deg);
    +}
    +.top-nav ul li li.hasChildren > a:after, .top-nav ul li li.hasChildren > span > a:after {
    +	content:"\f105";
    +	float:right;
    +	display:inline-block;
    +	font:normal normal normal 12px/1 FontAwesome;
    +}
    +.top-nav .mega-menu > ul > li > a:after, .top-nav .mega-menu ul li:first-child:hover:before, .top-nav .mega-menu ul:before {
    +	display:none;
    +}
    +.top-nav li li a {
    +	display:block;
    +	padding:13px 15px;
    +	-moz-transition:all 0.2s ease 0s;
    +	-ms-transition:all 0.2s ease 0s;
    +	-o-transition:all 0.2s ease 0s;
    +	-webkit-transition:all 0.2s ease 0s;
    +	transition:all 0.2s ease 0s;
    +	font-size:13px;
    +	line-height:1.5
    +}
    +.top-nav li.mega-menu li a{
    +	padding: 15px 10px;
    +}
    +.top-nav li li a:hover {
    +	/*padding-left:20px;*/
    +}
    +.top-nav li li:first-child > a {
    +	border-top:0;
    +}
    +.top-nav li li i {
    +	margin-right:8px;
    +}
    +.top-nav > ul > .mega-menu {
    +	position:static;
    +}
    +.top-nav .mega-menu > ul {
    +	left:15px;
    +	/*top:100%;*/
    +	display:table;
    +}
    +.top-nav .mega-menu ul ul {
    +	border-left-width:0;
    +	border-top-width:0;
    +	position:static;
    +	margin:0 10px;
    +	display:block !important;
    +	opacity:1 !important;
    +	-webkit-box-shadow:0 0 0 0 rgba(0,0,0,0);
    +	-moz-box-shadow:0 0 0 0 rgba(0,0,0,0);
    +	box-shadow:0 0 0 0 rgba(0,0,0,0);
    +	-webkit-transform: translate3d(0,0,0);
    +	transform: translate3d(0,0,0);
    +}
    +.top-nav .mega-menu:hover ul li ul{
    +	visibility:visible
    +}
    +.top-nav .mega-menu > ul > li {
    +	padding-bottom:15px;
    +	display:table-cell;
    +}
    +.top-nav .mega-menu > ul > li h4 {
    +	font-weight:900;
    +	text-transform:uppercase;
    +	font-size:13px;
    +	margin:20px 10px 15px;
    +}
    +.nav-border-bottom > ul > li:before, .nav-border-bottom li.mega-menu .inner-mega:before {
    +	position:absolute;
    +	bottom:2px;
    +	height:2px;
    +	left:0;
    +	width:100%;
    +	content:"";
    +	display:inline-block;
    +	z-index:1;
    +}
    +.nav-border-bottom > ul > li:after, .nav-border-bottom li.mega-menu .inner-mega:after {
    +	position:absolute;
    +	bottom:2px;
    +	height:2px;
    +	left:0;
    +	width:5px;
    +	content:"";
    +	display:inline-block;
    +	z-index:2;
    +}
    +.sticky-nav .nav-border-bottom > ul > li:after, .sticky-nav .nav-border-bottom li.mega-menu .inner-mega:after,.sticky-nav .nav-border-bottom > ul > li:before, .sticky-nav .nav-border-bottom li.mega-menu .inner-mega:before{
    +	display:none
    +}
    +.nav-border-bottom > ul > li:hover:after, .nav-border-bottom > ul > li.mega-menu:hover span:after,.nav-border-bottom > ul > li.selected:after, .nav-border-bottom > ul > li.mega-menu.selected span:after {
    +	width:100%;
    +}
    +.nav-border-bottom > ul > li.mega-menu:before, .nav-border-bottom > ul > li.mega-menu:after, .nav-border-left > ul > li.mega-menu:before, .nav-border-left > ul > li.mega-menu:after, .nav-border-top > ul > li.mega-menu:before, .nav-border-top > ul > li.mega-menu:after, .nav-border-right > ul > li .mega-menu:before, .nav-border-right > ul > li.mega-menu:after {
    +	display:none;
    +}
    +.nav-border-top > ul > li:before, .nav-border-top li.mega-menu .inner-mega:before {
    +	position:absolute;
    +	top:2px;
    +	height:2px;
    +	left:0;
    +	width:100%;
    +	content:"";
    +	display:inline-block;
    +	z-index:1;
    +}
    +.nav-border-top > ul > li:after, .nav-border-top li.mega-menu .inner-mega:after {
    +	position:absolute;
    +	top:2px;
    +	height:2px;
    +	left:0;
    +	width:5px;
    +	content:"";
    +	display:inline-block;
    +	z-index:2;
    +}
    +.nav-border-top > ul > li:hover:after, .nav-border-top > ul > li.mega-menu:hover span:after {
    +	width:100%;
    +}
    +.nav-border-left > ul > li:before, .nav-border-left li.mega-menu .inner-mega:before {
    +	position:absolute;
    +	top:20%;
    +	height:60%;
    +	left:-15px;
    +	width:2px;
    +	content:"";
    +	display:inline-block;
    +	z-index:1;
    +}
    +.nav-border-left > ul > li:after, .nav-border-left li.mega-menu .inner-mega:after {
    +	position:absolute;
    +	bottom:20%;
    +	height:5px;
    +	left:-15px;
    +	width:2px;
    +	content:"";
    +	display:inline-block;
    +	z-index:2;
    +}
    +.nav-border-left > ul > li:hover:after, .nav-border-left > ul > li.mega-menu:hover span:after {
    +	height:60% ;
    +}
    +.nav-border-right > ul > li:before, .nav-border-right li.mega-menu .inner-mega:before {
    +	position:absolute;
    +	top:20%;
    +	height:60%;
    +	right:-15px;
    +	width:2px;
    +	content:"";
    +	display:inline-block;
    +	z-index:1;
    +}
    +.nav-border-right > ul > li:after, .nav-border-right li.mega-menu .inner-mega:after {
    +	position:absolute;
    +	bottom:20%;
    +	height:5px;
    +	right:-15px;
    +	width:2px;
    +	content:"";
    +	display:inline-block;
    +	z-index:2;
    +}
    +.nav-border-right > ul > li:hover:after, .nav-border-right > ul > li.mega-menu:hover span:after {
    +	height:60%;
    +}
    +.nav-animate > ul > li > a span, .nav-animate > ul > li > span > a span {
    +	position:relative;
    +	display:inline-block;
    +	-webkit-transition:-webkit-transform 0.4s;
    +	-moz-transition:-moz-transform 0.4s;
    +	transition:transform 0.4s;
    +}
    +.nav-animate > ul > li > a span:after, .nav-animate > ul > li > span > a span:after {
    +	display:inline-block;
    +	position:absolute;
    +	-webkit-transform:translate3d(0,0,0);
    +	-moz-transform:translate3d(0,0,0);
    +	transform:translate3d(0,0,0);
    +	width:100%
    +}
    +.nav-animate > ul > li > a, .nav-animate > ul > li > span > a {
    +	position:relative;
    +	overflow:hidden;
    +	display:block;
    +}
    +.nav-animate.to-right > ul > li > a span:after, .nav-animate.to-right > ul > li > span > a span:after {
    +	right:150%;
    +}
    +.nav-animate.to-right > ul > li:hover > a > span, .nav-animate.to-right > ul > li:hover > span > a > span {
    +	-webkit-transform:translateX(150%);
    +	-moz-transform:translateX(150%);
    +	transform:translateX(150% );
    +}
    +.nav-animate.to-left > ul > li > a span:after, .nav-animate.to-left > ul > li > span > a span:after {
    +	left:150%;
    +}
    +.nav-animate.to-left > ul > li:hover > a > span, .nav-animate.to-left > ul > li:hover > span > a > span {
    +	-webkit-transform:translateX(-150%);
    +	-moz-transform:translateX(-150%);
    +	transform:translateX(-150%);
    +}
    +.nav-border-bottom.to-left > ul > li:after, .nav-border-bottom.to-left li.mega-menu .i nner-mega:after,.nav-border-top.to-left > ul > li:after, .nav-border-top.to-left li.mega-menu .i nner-mega:after {
    +	left:auto;
    +	right:0;
    +}
    +
    +.nav-border-left.to-bottom > ul > li:after, .nav-border-left.to-bottom li.mega-menu .inner-mega:after {
    +	bottom:auto;
    +	top:20%;
    +}
    +.nav-animate.to-bottom > ul > li > a span:after, .nav-animate.to-bottom > ul > li > span > a span:after {
    +	left:0;
    +	top:-100%;
    +}
    +.nav-animate.to-bottom ul > li:hover > a > span, .nav-animate.to-bottom > ul > li:hover > span > a > span {
    +	-webkit-transform:translateY(100%);
    +	-moz-transform:translate Y(100%);
    +	transform:translateY(100%);
    +}
    +.nav-animate.to-top > ul > li > a span:after, .nav-animate.to-top > ul > li > span > a span:after {
    +	left:0;
    +	top:100%;
    +}
    +.nav-animate.to-top ul > li:hover > a > span, .nav-animate.to-top > ul > li:hover > span > a > span {
    +	-webkit-transform:translateY(-100%);
    +	-moz-transform:translateY(-100%);
    +	transform:translateY(-100%);
    +}
    +
    +.top-nav[class*="nav-border-"] > ul > li{
    +	padding-left:0;
    +	padding-right:0;
    +	margin-right:15px;
    +	margin-left:15px
    +}
    +.top-nav[class*="nav-border-"] > ul > li:hover{
    +	background:transparent
    +}
    +.top-head .top-search {
    +	padding: 32px 10px;
    +}
    +.top-nav.scale > ul > li > a {
    +	overflow:visible
    +}
    +.top-nav.scale > ul > li > a span:after{
    +	opacity:0;
    +	transform:scaleY(5);
    +	left:0;
    +	-moz-transition: all 0.4s ease 0s;
    +	-ms-transition: all 0.4s ease 0s;
    +	-o-transition: all 0.4s ease 0s;
    +	-webkit-transition: all 0.4s ease 0s;
    +	transition: all 0.4s ease 0s;
    +}
    +.top-nav.scale > ul > li:hover > a span:after{
    +	opacity:1;
    +	transform:scaleY(1);
    +}
    +.top-head .top-search > a {
    +	font-weight:bold;
    +	display:block;
    +	line-height:1;
    +}
    +.top-search {
    +	float:left;
    +	position:relative;
    +}
    +.head-srch-cart-fluid .top-search {
    +	border-left:1px rgba(255,255,255,.2) solid;
    +}
    +.head-srch-cart .top-search > a, .head-srch-cart .top-cart > a {
    +	float:none;
    +	display:block;
    +	text-align:center;
    +	margin:15px 0;
    +	border-radius:2em;
    +	height: 49px;
    +	line-height: 49px;
    +	width:30px;
    +	text-align:center
    +}
    +.top-search .search-box {
    +	position:fixed;
    +	top:50%;
    +	width:50%;
    +	left:50%;
    +	border-bottom-style:solid;
    +	border-bottom-width:4px;
    +	padding:20px 0;
    +	line-height:1;
    +	z-index:999;
    +	margin-left:-25%;
    +	margin-top:-40px;
    +	display:none;
    +}
    +.top-search .search-box input[type=text] {
    +	width:95%;
    +	border:0;
    +	font-size:35px;
    +	text-transform:none;
    +	background:transparent;
    +	text-transform:uppercase;
    +	letter-spacing:1px;
    +	font-weight:200;
    +}
    +.top-search .search-box button {
    +	border:0;
    +	width:30px;
    +	height:30px;
    +	line-height:28px;
    +	text-align:center;
    +}
    +.srch-overlay {
    +	background:rgba(0, 0,0,0.9);
    +	position:fixed;
    +	width:100%;
    +	height:100%;
    +	z-index:99;
    +	left:0;
    +	top:0;
    +}
    +.close-srch {
    +	position:absolute;
    +	right:0;
    +	top:20px;
    +	display:block;
    +	font-size:0px;
    +}
    +.close-srch:before {
    +	font-size:25px;
    +}
    +.top-head .top-cart {
    +	float:right;
    +	padding: 29px 5px;
    +}
    +.top-head .top-cart > a {
    +	font-weight:bold;
    +	position:relative;
    +}
    +.top-cart .cart-num {
    +	display:inline-block;
    +	font-style:normal;
    +	line-height: 13px;
    +	position:absolute;
    +	border-radius:50%;
    +	top: -10px;
    +	right: -10px;
    +	font-size: 9px;
    +	font-weight:normal;
    +	width: 15px;
    +	text-align: center;
    +	height: 15px;
    +}
    +.top-cart {
    +	position:relative;
    +}
    +.top-cart .cart-box {
    +	position:absolute;
    +	top:100%;
    +	right:0;
    +	min-width:275px;
    +	padding:20px;
    +	min-height:200px;
    +	border-top-style:solid;
    +	border-top-width:3px;
    +	z-index:99;
    +	display:none
    +}
    +.head-srch-cart .top-cart .main-bg {
    +	color:#fff
    +}
    +.cart-box .empty {
    +	line-height:160px;
    +	text-align:center;
    +	color:#f00;
    +}
    +.mini-cart-list li {
    +	position:relative;
    +	overflow:hidden;
    +	padding-bottom:15px;
    +	margin-bottom:15px;
    +	font-size:11px;
    +}
    +.mini-cart .cart-body {
    +	padding-right:10px;
    +	line-height:1.7;
    +}
    +.cart-mini-lft {
    +	float:left;
    +	margin-right:8px;
    +}
    +.cart-mini-lft img {
    +	width:40px;
    +	padding:1px;
    +}
    +.mini-cart-list a.remove {
    +	position:absolute;
    +	right:0;
    +	top:0;
    +}
    +.mini-cart-total {
    +	padding:0 0 10px;
    +	font-weight:400;
    +	overflow:hidden;
    +	font-size:11px;
    +}
    +.mini-cart-total .clearfix {
    +	padding:5px 0;
    +	overflow:hidden;
    +}
    +.mini-cart-total .total {
    +	margin-top:10px;
    +	padding-top:15px;
    +}
    +.mini-cart .checkout {
    +	text-align:center;
    +	padding-top:15px;
    +}
    +.mini-cart .checkout a {
    +	margin:0 5px;
    +	height:35px;
    +	display:inline-block;
    +	line-height:33px;
    +	padding:0 20px;
    +	text-transform:none;
    +}
    +.head-srch-cart .top-search, .head-srch-cart .top-cart {
    +	margin:0 0 0 5px !important;
    +	padding:0 !important;
    +}
    +.head-srch-cart .top-cart .cart-num {
    +	top: 4px;
    +	right: 4px;
    +}
    +
    +/*
    +----------- inner-menu -------------- */
    +.inner-menu{
    +	height:40px
    +}
    +.inner-menu ul > li {
    +	border-left: 1px rgba(255,255,255,.3) solid;
    +	float:left;
    +	position:relative
    +}
    +.inner-menu ul > li > a{
    +	height: 40px;
    +	line-height: 40px;
    +	padding:0 18px;
    +	display:block;
    +}
    +.inner-menu ul ul,.top-bar li ul{
    +	position:absolute;
    +	left:0;
    +	top:100%;
    +	min-width: 200px;
    +	border-bottom-style: solid;
    +	border-bottom-width: 3px;
    +	z-index: 999;
    +	-webkit-box-shadow: 0px 2px 2px 0px rgba(0,0,0,0.3);
    +	-moz-box-shadow: 0px 2px 2px 0px rgba(0,0,0,0.3);
    +	box-shadow: 0px 2px 2px 0px rgba(0,0,0,0.3);
    +	overflow:hidden;
    +	z-index:-1;
    +	opacity:0
    +}
    +.top-bar li ul{
    +	margin-top:10px
    +}
    +.inner-menu ul li:hover > ul,.top-bar ul li:hover > ul{
    +	z-index:2;
    +	opacity:1
    +}
    +.top-bar ul li:hover > ul{
    +	z-index:999
    +}
    +.inner-menu ul ul li,.top-bar ul ul li{
    +	float:none
    +}
    +.inner-menu ul ul li a,.top-bar ul ul li a{
    +	display:block;
    +	text-shadow: none;
    +}
    +.inner-menu ul ul li:hover > a,.inner-menu ul ul li.selected > a,.top-bar ul ul li:hover > a{
    +	background: rgba(0,0,0,.05);
    +	color:#333
    +}
    +
    +/* ==========================================================================
    +  4. PAGE TITLES.
    +============================================================================= */
    +.page-title.title-1,.page-title.title-2,.page-title.title-3,.page-title.title-5 {
    +	background: url('../images/page-titles/title-light.jpg') no-repeat 50% 0;
    +}
    +.page-title > .container{
    +	position:relative;
    +	display:table
    +}
    +.page-title > .container > .row{
    +	height: 220px;
    +	padding-bottom: 30px;
    +	display:table-cell;
    +	vertical-align:middle;
    +  	width: 100%;
    +}
    +.page-title h1 {
    +	margin: 50px 0 5px;
    +	font-size: 40px;
    +	line-height: 1;
    +}
    +.page-title h3 {
    +	font-size: 20px;
    +	font-weight: 400;
    +}
    +.breadcrumbs {
    +	position: absolute;
    +	right: 15px;
    +	bottom: 10px;
    +	font-size: 12px;
    +}
    +.breadcrumbs.white-bg{
    +	bottom:0;
    +	padding: 10px;
    +}
    +.breadcrumbs i {
    +	display: inline-block;
    +	margin: 0 10px;
    +}
    +.page-title .title-icon{
    +	margin: 54px 15px 0 0;
    +	width:58px;
    +	height:58px;
    +	line-height:58px;
    +	text-align:center;
    +	font-size:30px;
    +	-webkit-text-shadow: none;
    +	-moz-text-shadow:none;
    +	text-shadow: none;
    +}
    +/*
    +------------ title minimal ------------ */
    +.page-title.title-minimal > .container {
    +	min-height: 130px;
    +}
    +.page-title.title-minimal > .container > .row{
    +	height: 150px;
    +}
    +.page-title.title-minimal h1{
    +	margin-top:30px;	text-transform: uppercase;
    +}
    +
    +/*
    +------------ title 2 ------------ */
    +.page-title.title-2 {
    +	text-align:center
    +}
    +.page-title.title-2 .breadcrumbs{
    +	position:static;
    +	display:table;
    +	margin:35px auto -16px
    +}
    +
    +/*
    +------------ title 4 ------------ */
    +.page-title.title-4 {
    +	text-align:center;
    +	background:#2d5d7d url('../images/page-titles/bg-parallax.jpg') no-repeat 0 0;
    +}
    +.page-title.title-4 .row{
    +	height:250px
    +}
    +.page-title.title-4 .breadcrumbs{
    +	position:static;
    +	display:table;
    +	margin:35px auto 0;
    +	padding: 10px 20px;
    +}
    +
    +/*
    +------------ title 5 ------------ */
    +.page-title.title-5 {
    +	text-align:center
    +}
    +.page-title.title-5 h1{
    +	display:table;
    +	padding: 15px 35px;
    +	margin-bottom:15px;
    +	margin-left:auto;
    +	margin-right:auto;
    +	font-size: 36px;
    +	text-transform: uppercase;
    +	line-height: 1;
    +}
    +.page-title.title-5 h3{
    +	display:inline-block;
    +	border-bottom-style:solid;
    +	border-bottom-width:3px;
    +	clear:both;
    +	font-size:25px;
    +	border-radius: 2em;
    +	padding: 10px 25px;
    +}
    +.page-title.title-5 .breadcrumbs{
    +	border-top-left-radius: 2em;
    +	border-top-right-radius: 2em;
    +	padding: 10px 20px 0px;
    +}
    +.transparent-title > .container{
    +	height:400px
    +}
    +/*
    +------------------ title video ----------- */
    +.page-title-video,.section-video {
    +	background: none;
    +	position: relative;
    +	overflow: hidden;
    +	clear:both
    +}
    +.page-title-video .container,.section-video .container {
    +	z-index: 3;
    +}
    +.page-title-video > .container > .row{
    +	height:400px
    +}
    +.page-title-video .video-wrap,.section-video .video-wrap {
    +	position: absolute;
    +	width: 100%;
    +	height:100%;
    +	top: 0;
    +	left: 0;
    +	z-index:0
    +}
    +.page-title-video .video-wrap video,.section-video .video-wrap video {
    +	width: 100%;
    +	margin-top:-200px;
    +	display:block;
    +	height:auto
    +}
    +.video-overlay {
    +	position: absolute;
    +	width: 100%;
    +	height: 100%;
    +	top: 0;
    +	left: 0;
    +	z-index: 5;
    +	background: rgba(0,0,0,.6);
    +	-webkit-backface-visibility: hidden;
    +}
    +/* =========================================================================
    +	5.FORM CONTROLS.
    +============================================================================ */
    +
    +.btn {
    +	text-shadow:1px 1px 1px rgba(0,0,0,.5);
    +	text-transform:uppercase;
    +	letter-spacing:1px;
    +	border-radius:0px;
    +	font-size:12px;
    +	white-space:normal
    +}
    +.btn span{
    +	line-height:1;
    +}
    +.btn-xs {
    +	padding:2px 5px;
    +	font-size:10px;
    +	line-height:1.5;
    +}
    +.btn-sm {
    +	line-height:1.5;
    +	font-size:11px;
    +	padding:6px 8px;
    +}
    +.btn-md {
    +	line-height:37px;
    +	font-size:12px;
    +	padding:0 12px;
    +}
    +.btn-lg {
    +	line-height:55px;
    +	font-size:14px;
    +	padding:0 17px;
    +}
    +.btn-xl {
    +	line-height:1;
    +	font-size:18px;
    +	padding:20px;
    +}
    +.btn-xxl {
    +	line-height:1;
    +	font-size:30px;
    +	padding:25px 30px;
    +	letter-spacing:0.5px;
    +	text-transform:none
    +}
    +.btn-xxl span.sub {
    +	display:block;
    +	font-size:11px;
    +	line-height:1;
    +	font-weight:400;
    +	letter-spacing:normal
    +}
    +.button-group .btn {
    +	margin:10px 5px;
    +}
    +.btn-block {
    +	display:table;
    +	width:50%;
    +	margin:auto !important;
    +}
    +.btn-block-full {
    +	display:block;
    +	width:100%;
    +}
    +.btn i {
    +	margin-right:8px;
    +}
    +.btn i.block {
    +	margin-bottom:15px;
    +}
    +[class*="btn-icon-"] {
    +	overflow:hidden;
    +	position:relative;
    +	padding-right:40px;
    +	padding-left:40px;
    +}
    +[class*="btn-icon-"] i {
    +	position:absolute;
    +	top:0;
    +	height:100%;
    +	background:rgba(0,0,0,.2);
    +	line-height:40px;
    +	width:40px;
    +	text-align:center;
    +}
    +.left-icon {
    +	overflow:hidden;
    +	padding:0 20px 0 0;
    +}
    +.right-icon {
    +	overflow:hidden;
    +	padding:0 0 0 20px;
    +}
    +.right-icon i, .left-icon i {
    +	background:rgba(0,0,0 ,.2);
    +	line-height:55px;
    +	text-align:center;
    +	padding:0 10px;
    +	margin-right:15px;
    +}
    +.right-icon i {
    +	margin-left:15px;
    +	margin-right:0;
    +}
    +.btn-xl.right-icon i, .btn-xl.left-icon i {
    +	line-height:68px;
    +}
    +.btn-md.right-icon i, .btn-md.left-icon i {
    +	line-height:40px;
    +}
    +.btn-sm.right-icon i, .btn-sm.left-icon i {
    +	line-height:16px;
    +}
    +[class*="btn-icon-"] span {
    +	display:inline-block;
    +	position:relative;
    +	left:0;
    +}
    +.btn-xs[class*="btn-icon-" ] i {
    +	padding:2px 5px;
    +	font-size:10px;
    +	line-height:1.2;
    +}
    +.btn-sm[class*="btn-icon-"] i {
    +	line-height:27px;
    +}
    +.btn-md[class*="btn-icon-"] i {
    +	line-height:40px;
    +}
    +.btn-lg[class*="btn-icon-"] i {
    +	line-height:55px;
    +}
    +.btn-xl [class*="btn-icon-"] i {
    +	line-height:70px;
    +}
    +.btn-xxl[class*= "btn-icon-"] i {
    +	line-height:1.5;
    +}
    +[class*="btn-icon-"].no-bg i {
    +	background:transparent;
    +}
    +.btn-icon-left i {
    +	left:-40px;
    +}
    +.btn-icon-left:hover i {
    +	left:0;
    +}
    +.btn-icon-left:hover span {
    +	left:15px;
    +}
    +.btn-icon-right i {
    +	right:-48px;
    +}
    +.btn-icon-right:hover i {
    +	right:-8px;
    +}
    +.btn-icon-right:hover span {
    +	left:-15px;
    +}
    +.btn.white {
    +	color:#fff !important;
    +}
    +.btn-blue {
    +	background-color:#5472d2;
    +	color:#fff;
    +}
    +.btn-blue:hover {
    +	background-color:#3c5ecc;
    +	color:#f7f7f7;
    +}
    +.btn-blue.btn-outlined, .btn-blue.btn-square_outlined {
    +	color:#5472d2;
    +	border-color:#5472d2;
    +}
    +.btn-blue.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #3253bc;
    +	box-shadow:0 4px 0 #3253bc;
    +	margin-bottom:5px;
    +}
    +.btn-turquoise {
    +	background-color:#00c1cf;
    +	color:#fff;
    +}
    +.btn-turquoise:hover {
    +	background-color:#00a4b0;
    +	color:#f7f7f7;
    +}
    +.btn-turquoise.btn-outlined, .btn-turquoise.btn-square_outlined {
    +	color:#00c1cf;
    +	border-color:#00c1cf;
    +}
    +.btn-turquoise.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #008d97;
    +	box-shadow:0 4px 0 #008d97;
    +	margin-bottom:5px;
    +}
    +.btn-pink {
    +	background-color:#fe6c61;
    +	color:#fff;
    +}
    +.btn-pink:hover {
    +	background-color:#fe5043;
    +	color:#f7f7f7;
    +}
    +.btn-pink.btn-outlined, .btn-pink.btn-square_outlined {
    +	color:#fe6c61 !important;
    +	border-color:#fe6c61;
    +}
    +.btn-pink.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #fe3829;
    +	box-shadow:0 4px 0 #fe3829;
    +	margin-bottom:5px;
    +}
    +.btn-default.btn-3d {
    +	margin-bottom:5px;
    +}
    +.btn-default.btn-3d:hover {
    +	-webkit-box-shadow:0 4px 0 #2A2A2A;
    +	box-shadow:0 4px 0 #2A2A2A;
    +	color:#fff;
    +}
    +.btn-default.btn-outlined {
    +	background-color:transparent;
    +}
    +.btn-violet {
    +	background-color:#8d6dc4;
    +	color:#fff;
    +}
    +.btn-violet:hover {
    +	background-color:#7c57bb;
    +	color:#f7f7f7;
    +}
    +.btn-violet.btn-outlined, .btn-violet.btn-square_outlined {
    +	color:#8d6dc4;
    +	border-color:#8d6dc4;
    +}
    +.btn-violet.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #6e48b1;
    +	box-shadow:0 4px 0 #6e48b1;
    +	margin-bottom:5px;
    +}
    +.btn-peacoc {
    +	background-color:#4cadc9;
    +	color:#fff;
    +}
    +.btn-peacoc:hover {
    +	background-color:#39a0bd;
    +	color:#f7f7f7;
    +}
    +.btn-peacoc.btn-outlined, .btn-peacoc.btn-square_outlined {
    +	color:#4cadc9;
    +	border-color:#1cadc9;
    +}
    +.btn-peacoc.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #338faa;
    +	box-shadow:0 4px 0 #338faa;
    +	margin-bottom:5px;
    +}
    +.btn-chino {
    +	background-color:#cec2ab;
    +	color:#fff;
    +}
    +.btn-chino:hover {
    +	background-color:#c3b498;
    +	color:#f7f7f7;
    +}
    +.btn-chino.btn-outlined, .btn-chino.btn-square_outlined {
    +	color:#cec2ab;
    +	border-color:#cec2ab;
    +}
    +.btn-chino.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #b9a888;
    +	box-shadow:0 4px 0 #b9a888;
    +	margin-bottom:5px;
    +}
    +.btn-mulled_wine {
    +	background-color:#50485b;
    +	color:#fff;
    +}
    +.btn-mulled_wine:hover {
    +	background-color:#413a4a;
    +	color:#f7f7f7;
    +}
    +.btn-mulled_wine.btn-outlined, .btn-mulled_wine.btn-square_outlined {
    +	color:#50485b;
    +	border-color:#50485b;
    +}
    +.btn-mulled_wine.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #342f3c;
    +	box-shadow:0 4px 0 #342f3c;
    +	margin-bottom:5px;
    +}
    +.btn-vista_blue {
    +	background-color:#75d69c;
    +	color:#fff;
    +}
    +.btn-vista_blue:hover {
    +	background-color:#5dcf8b;
    +	color:#f7f7f7;
    +}
    +.btn-vista_blue.btn-outlined, .btn-vista_blue.btn-square_outlined {
    +	color:#75d69c !important;
    +	border-color:#75d69c;
    +}
    +.btn-vista_blue.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #4ac97d;
    +	box-shadow:0 4px 0 #4ac97d;
    +	margin-bottom:5px;
    +}
    +.btn-black {
    +	background-color:#2a2a2a;
    +	color:#fff;
    +}
    +.btn-black:hover {
    +	background-color:#383838;
    +	color:#f7f7f7;
    +}
    +.btn-black.btn-outlined, .btn-black.btn-square_outlined {
    +	color:#2a2a2a;
    +	border-color:#2a2a2a;
    +}
    +.btn-black.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #595959;
    +	box-shadow:0 4px 0 #151515;
    +	margin-bottom:5px;
    +}
    +.btn-grey {
    +	background-color:#ebebeb;
    +	text-shadow:none;
    +}
    +.btn-grey:hover {
    +	background-color:#dcdcdc;
    +	color:#5e5e5e;
    +}
    +.btn-grey.btn-outlined, .btn-grey.btn-square_outlined {
    +	color:#ebebeb;
    +	border-color:#ebebeb;
    +}
    +.btn-grey.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #cfcfcf;
    +	box-shadow:0 4px 0 #cfcfcf;
    +	margin-bottom:5px;
    +}
    +.btn-orange {
    +	background-color:#f7be68;
    +	color:#fff;
    +}
    +.btn-orange:hover {
    +	background-color:#f5b14b;
    +	color:#f7f7f7;
    +}
    +.btn-orange.btn-outlined, .btn-orange.btn-square_outlined {
    +	color:#f7be68;
    +	border-color:#f7be68;
    +}
    +.btn-orange.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #f4a733;
    +	box-shadow:0 4px 0 #f4a733;
    +	margin-bottom:5px;
    +}
    +.btn-sky {
    +	background-color:#5aa1e3;
    +	color:#fff;
    +}
    +.btn-sky:hover {
    +	background-color:#4092df;
    +	color:#f7f7f7;
    +}
    +.btn-sky.btn-outlined, .btn-sky.btn-square_outlined {
    +	color:#5aa1e3;
    +	border-color:#5aa1e3;
    +}
    +.btn-sky.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #2a86db;
    +	box-shadow:0 4px 0 #2a86db;
    +	margin-bottom:5px;
    +}
    +.btn-green {
    +	background-color:#6dab3c;
    +	color:#fff;
    +}
    +.btn-green:hover {
    +	background-color:#5f9434;
    +	color:#f7f7f7;
    +}
    +.btn-green.btn-outlined, .btn-green.btn-square_outlined {
    +	color:#6dab3c;
    +	border-color:#6dab3c;
    +}
    +.btn-green.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #53812d;
    +	box-shadow:0 4px 0 #53812d;
    +	margin-bottom:5px;
    +}
    +.btn-juicy_pink {
    +	background-color:#f4524d;
    +	color:#fff;
    +}
    +.btn-juicy_pink:hover {
    +	background-color:#f23630;
    +	color:#f7f7f7;
    +}
    +.btn-juicy_pink.btn-outlined, .btn-juicy_pink.btn-square_outlined {
    +	color:#f4524d;
    +	border-color:#f4524d;
    +}
    +.btn-juicy_pink.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #f11f18;
    +	box-shadow:0 4px 0 #f11f18;
    +	margin-bottom:5px;
    +}
    +.btn-sandy_brown {
    +	background-color:#f79468;
    +	color:#fff;
    +}
    +.btn-sandy_brown:hover {
    +	background-color:#f57f4b;
    +	color:#f7f7f7;
    +}
    +.btn-sandy_brown.btn-outlined, .btn-sandy_brown.btn-square_outlined {
    +	color:#f79468;
    +	border-color:#f79468;
    +}
    +.btn-sandy_brown.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #f46e33;
    +	box-shadow:0 4px 0 #f46e33;
    +	margin-bottom:5px;
    +}
    +.btn-purple {
    +	background-color:#b97ebb;
    +	color:#fff;
    +}
    +.btn-purple:hover {
    +	background-color:#ae6ab0;
    +	color:#f7f7f7;
    +}
    +.btn-purple.btn-outlined, .btn-purple.btn-square_outlined {
    +	color:#b97ebb;
    +	border-color:#b97ebb;
    +}
    +.btn-purple.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #a559a8;
    +	box-shadow:0 4px 0 #a559a8;
    +	margin-bottom:5px;
    +}
    +.btn-white {
    +	background-color:#fff;
    +	text-shadow:none;
    +}
    +.btn-white:hover {
    +	background-color:#f0f0f0;
    +	color:#5e5e5e;
    +}
    +.btn-white.btn-outlined, .btn-white.btn-square_outlined {
    +	color:#fff;
    +	border-color:#fff;
    +}
    +.btn-white.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #e3e3e3;
    +	box-shadow:0 4px 0 #e3e3e3;
    +	margin-bottom:5px;
    +}
    +.btn-grace {
    +	background-color:#aed13b;
    +	color:#fff;
    +}
    +.btn-grace:hover {
    +	background-color:#9ec02d;
    +	color:#f7f7f7;
    +}
    +.btn-grace.btn-outlined, .btn-grace.btn-square_outlined {
    +	color:#aed13b;
    +	border-color:#aed13b;
    +}
    +.btn-grace.btn-3d {
    +	-webkit-box-shadow:0 4px 0 #8dac28;
    +	box-shadow:0 4px 0 #8dac28;
    +	margin-bottom:5px;
    +}
    +.btn-square,.modal-content {
    +	border-radius:0px;
    +}
    +.btn-shadow {
    +	border-radius:0px;
    +}
    +.btn-round {
    +	border-radius:25px;
    +}
    +.btn-outlined {
    +	background-color:transparent;
    +	border:1px solid;
    +	text-shadow:none !important;
    +}
    +label{
    +	font-weight:bold;
    +	margin-bottom:5px;
    +	display:block
    +}
    +label.checkbox-lbl,.radio-lbl{
    +	font-weight:normal;
    +	overflow:hidden;
    +	line-height:25px
    +}
    +label.radio-lbl{
    +	font-weight:normal;
    +	overflow:hidden;
    +	line-height:20px
    +}
    +label.radio-lbl .radio{
    +	margin:5px 5px 0 0
    +}
    +.floated-radios {
    +	overflow:hidden
    +}
    +.floated-item{
    +	float:left;
    +	margin: 0 20px 10px 0;
    +	line-height:26px
    +}
    +.checkbox-table{
    +	display:table;
    +	width:100%;
    +	border-collapse:collapse
    +}
    +.checkbox-table .clearfix{
    +	display:table-row
    +}
    +.checkbox-table .floated-item{
    +	float:none;
    +	display:table-cell;
    +	padding: 10px;
    +	font-size: 12px;
    +}
    +.checkbox-block{
    +	line-height:27px
    +}
    +.radio {
    +	width : 20px;
    +	margin : 0;
    +	padding : 0;
    +	font-size : 1em;
    +	opacity : 0;
    +	height: 20px;
    +	float:left
    +}
    +.radio + label {
    +	display : inline-block;
    +	margin-left: -20px;
    +	line-height : 1.5em;
    +	font-weight:normal
    +}
    +.radio + label > span {
    +	display : inline-block;
    +	width: 15px;
    +	height: 15px;
    +	margin : 0 10px 0 0;
    +	background: #ECECEC;
    +	-webkit-box-shadow: inset 0px 0px 5px 0px rgba(0,0,0,0.2);
    +	-moz-box-shadow: inset 0px 0px 5px 0px rgba(0,0,0,0.2);
    +	box-shadow: inset 0px 0px 5px 0px rgba(0,0,0,0.2);
    +	vertical-align : middle;
    +	cursor:pointer
    +}
    +.radio:checked + label > span {
    +	background: #555;
    +	cursor:pointer
    +}
    +.radio:checked + label > span > span {
    +	display : block;
    +	width: 100%;
    +	height: 100%;
    +	cursor:pointer;
    +	margin: 3px;
    +}
    +.form-input{
    +	padding:8px 0
    +}
    +select{
    +	width:100%;
    +	padding:8px 0 8px 10px
    +}
    +.form-control {
    +	height: auto;
    +	padding: 10px 15px;
    +	font-size: 13px;
    +	border-radius: 0;
    +}
    +.small-select{
    +	width:32%;
    +	margin:0 5px 0 0
    +}
    +input.small-txt{
    +	width:auto;
    +	margin-right:3px;
    +	display:inline-block
    +}
    +input[type=file]{
    +	height:auto;
    +	padding:12px 15px
    +}
    +.captcha-div .sm-txtbox{
    +	width: 56% !important;
    +	height: 76px !important;
    +	font-size: 20px;
    +	font-weight: 200;
    +	padding: 0 15px;
    +	vertical-align: middle;
    +}
    +.captcha-div-lft .sm-txtbox{
    +	width:50%;
    +	height: 75px !important;
    +	font-size:20px;
    +	font-weight:200;
    +	padding:0 15px;
    +	vertical-align:middle
    +}
    +textarea{
    +	width:100%;
    +	height:220px;
    +	padding:15px
    +}
    +.center_contact{
    +	width:70%;
    +	margin:auto
    +}
    +.center_contact .button-group{
    +	text-align:center
    +}
    +.left-lbl{
    +	display:inline-block
    +}
    +#message{
    +	display:none
    +}
    +#captchaimg{
    +	margin-right:5px
    +}
    +.sub-heading.block{
    +	width:100% !important
    +}
    +.captcha-div{
    +	display:table;
    +	margin:10px auto;
    +	width:50%;
    +	text-align:center
    +}
    +.errCap{
    +	font-weight:normal;
    +	color:#f00;
    +	margin:25px 0 0;
    +	display:block
    +}
    +.cont-success{
    +	padding: 50px;
    +}
    +.cont-success i.success-icon{
    +	font-size:45px;
    +	margin-bottom:20px;
    +}
    +.cont-success p.congrats{
    +	font-size:30px;
    +	text-transform:uppercase;
    +	font-weight:900
    +}
    +.cont-success p.congratsTxt{
    +	font-size:15px
    +}
    +.map-overlay{
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	z-index:0;
    +	top:0;
    +	overflow:hidden
    +}
    +.conact_center_form{
    +	position:relative;
    +	z-index:2;
    +	max-width:800px;
    +	margin:auto;
    +	box-shadow: 0 1px 10px rgba(0,0,0,.15);
    +	padding:40px 0
    +}
    +.conact_center_form .captcha-div{
    +	width:75%;
    +}
    +.side-socials{
    +	display:table;
    +	margin:auto
    +}
    +.custom-checkbox{
    +	position: relative;
    +	display: block;
    +	height: inherit;
    +	font-size: 9px;
    +	text-transform: uppercase;
    +	-webkit-transition: 0.15s ease-out;
    +	-moz-transition: 0.15s ease-out;
    +	-o-transition: 0.15s ease-out;
    +	transition: 0.15s ease-out;
    +	width: 50px;
    +	height: 26px;
    +	float:left;
    +	background-color: #ECECEC;
    +	border-radius: 0px;
    +	cursor: pointer;
    +	-webkit-box-shadow: inset 0px 0px 5px 0px rgba(0,0,0,0.2);
    +	-moz-box-shadow: inset 0px 0px 5px 0px rgba(0,0,0,0.2);
    +	box-shadow: inset 0px 0px 5px 0px rgba(0,0,0,0.2);
    +	margin:0 8px 0 0
    +}
    +.custom-checkbox:before, .custom-checkbox:after {
    +	position: absolute;
    +	top: 50%;
    +	margin-top: -.5em;
    +	line-height: 1;
    +	-webkit-transition: inherit;
    +	-moz-transition: inherit;
    +	-o-transition: inherit;
    +	transition: inherit;
    +}
    +.custom-checkbox.selected:after {
    +	content: "on";
    +	left: 7px;
    +	color: white;
    +	text-shadow: 0 1px rgba(0, 0, 0, 0.2);
    +}
    +.custom-checkbox.selected:before {
    +	display:none
    +}
    +.custom-checkbox .switcher{
    +	position: absolute;
    +	top: 6px;
    +	left: 5px;
    +	width: 14px;
    +	height: 14px;
    +	background: white;
    +	border-radius: 0px;
    +	box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.2);
    +	background-image: -webkit-linear-gradient(top, white 40%, #f0f0f0);
    +	background-image: -moz-linear-gradient(top, white 40%, #f0f0f0);
    +	background-image: -o-linear-gradient(top, white 40%, #f0f0f0);
    +	background-image: linear-gradient(to bottom, #ffffff 40%, #f0f0f0);
    +	-webkit-transition: left 0.15s ease-out;
    +	-moz-transition: left 0.15s ease-out;
    +	-o-transition: left 0.15s ease-out;
    +	transition: left 0.15s ease-out;
    +}
    +.custom-checkbox.selected .switcher{
    +	left: 30px;
    +	box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.2);
    +}
    +.custom-checkbox:before {
    +	content: "off";
    +	right: 7px;
    +	color: #aaa;
    +	text-shadow: 0 1px rgba(255, 255, 255, 0.5);
    +}
    +.custom-checkbox .on,.custom-checkbox .off{
    +	margin: 0 !important;
    +	position: absolute;
    +	z-index: 2;
    +	cursor: pointer;
    +	outline: none;
    +	opacity: 0;
    +	-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
    +	width: 32px !important;
    +	height: 31px !important;
    +	background-color:transparent !important
    +}
    +.custom-checkbox .on{
    +	right:0
    +}
    +.custom-checkbox .checkbox{
    +	margin: 0 !important;
    +	position: absolute;
    +	z-index: 2;
    +	cursor: pointer;
    +	outline: none;
    +	opacity: 0;
    +	-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
    +	width: 50px !important;
    +	height: 30px !important;
    +	background-color:transparent !important
    +}
    +.error{
    +	border:1px #FFC5C5 solid !important
    +}
    +
    +/* =========================================================================
    +	6.SHORTCODES.
    +============================================================================ */
    +/*
    +------------ Headings ---------- */
    +.head-icon{
    +	margin-right:15px
    +}
    +.label-icon{
    +	margin-right:8px
    +}
    +.section .full-heading{
    +	margin-top: -100px;
    +	margin-bottom: 75px;
    +}
    +.full-heading{
    +	padding:30px 0;
    +	text-align:center;
    +	margin-bottom:50px;
    +	position:relative;
    +}
    +.full-heading:before {
    +	position: absolute;
    +	bottom: -30px;
    +	left: 50%;
    +	margin-left: -22px;
    +	width: 40px;
    +	height: 30px;
    +	display: inline-block;
    +	border-bottom-left-radius: 2em;
    +	border-bottom-right-radius: 2em;
    +	background-color: #EAEAEA;
    +	content: "\f078";
    +	font: normal normal normal 14px/24px FontAwesome;
    +	color:#999
    +}
    +.inner-head{
    +	margin:0;
    +	padding:0;
    +	font-size:35px;
    +	font-weight:700;
    +	text-transform:uppercase;
    +}
    +.small-heading{
    +	font-size:13px;
    +	text-transform:uppercase;
    +	letter-spacing:8px;
    +	margin:0;
    +	padding:0;
    +}
    +
    +.main-heading.centered {
    +	text-align:center;
    +	display:table;
    +	margin:auto;
    +}
    +.main-heading h3 {
    +	font-size: 30px;
    +	font-weight:300;
    +	margin:0 0 5px;
    +	padding:0;
    +	line-height:1;
    +	letter-spacing: -1px;
    +}
    +.main-heading .sub-title {
    +	font-size:35px;
    +	font-weight:800;
    +	margin:0 0 5px;
    +	padding:0;
    +	line-height:1;
    +	letter-spacing: -1px;
    +}
    +.heading-desc,.sub-heading {
    +	font-size:15px;
    +	line-height: 26px;
    +}
    +.heading-desc.centered {
    +	display:table;
    +	margin: 0 auto 50px;
    +	width: 90%;
    +	text-align:center;
    +}
    +.heading-desc:after {
    +	display:table;
    +	content:" ";
    +	clear:both;
    +}
    +.main-heading .heading-separator {
    +	margin: 15px 0 30px;
    +	position:relative;
    +	height:10px;
    +}
    +.main-heading .heading-separator .main-bg {
    +	position:absolute;
    +	left:50%;
    +	width:14px;
    +	height:5px;
    +	top:5px;
    +	margin-left: -13px;
    +}
    +.main-heading .heading-separator .dark-bg {
    +	position:absolute;
    +	right:50%;
    +	width:14px;
    +	height:5px;
    +	bottom:5px;
    +	margin-right: -13px;
    +}
    +.main-heading .heading-separator:before, .main-heading .heading-separator:after {
    +	content:"";
    +	display:inline-block;
    +	position:absolute;
    +	right:0;
    +	width:50%;
    +	height:1px;
    +	bottom:2px;
    +	margin-right: -2px;
    +}
    +.main-heading .heading-separator:before {
    +	right:auto;
    +	left:0;
    +	top:auto;
    +	top:2px;
    +	background:#777;
    +	width:50%;
    +	margin-left: -2px;
    +}
    +.main-heading.no-desc {
    +	margin-bottom:30px !important;
    +}
    +.heading, .heading [class*="head-"] {
    +	position:relative;
    +	line-height:1
    +}
    +.head-angle{
    +	display:table;
    +	position:relative;
    +	height:60px;
    +	line-height:60px !important;
    +	padding: 0 20px;
    +	white-space:nowrap;
    +}
    +.heading i.tbl {
    +	display:table;
    +	margin:0 auto 10px;
    +	font-size:16px;
    +	float:none
    +}
    +.heading i {
    +	margin:-3px 15px 0 0;
    +	vertical-align:middle;
    +	font-size:70%
    +}
    +.heading .top-bord {
    +	position:relative;
    +	top:-5px;
    +	height:3px;
    +	width:40px;
    +}
    +.heading.centered {
    +	display:table;
    +	margin:auto;
    +	text-align:center;
    +}
    +.heading.centered [class*="head-"] {
    +	display:table;
    +	margin:auto;
    +	position:relative;
    +	margin-bottom:30px;
    +	padding-bottom:20px
    +
    +}
    +.heading [class*= "head-"] h3 {
    +	font-size: 35px;
    +	font-weight: 300;
    +	padding: 0;
    +	line-height: 1;
    +	letter-spacing: -1.5px;
    +	margin:0
    +}
    +.heading [class*= "head-"] h4 {
    +	font-size:35px;
    +	font-weight:800;
    +	letter-spacing:-1px;
    +	line-height:1;
    +	margin:0
    +}
    +.side-head [class*="head-"] h3,.side-head [class*="head-"] h4{
    +	font-size:30px
    +}
    +.heading-full {
    +	text-align:center;
    +}
    +.heading-full:before {
    +	position:absolute;
    +	height:30px;
    +	background:#f5f5f5;
    +	display:inline-block;
    +	content:"";
    +	width:100%;
    +	left:0;
    +	top:5px;
    +	z-index:5;
    +}
    +.heading-full [class*="head-"] {
    +	padding:0 50px;
    +	background:#fff;
    +	z-index:6;
    +	display:table;
    +	margin:auto;
    +}
    +.heading-full [class*= "head-"]:before, .heading-full [class*="head-"]:after {
    +	position:absolute;
    +	top:5px;
    +	height:30px;
    +	width:10px;
    +	display:inline-block;
    +	content:"";
    +	left:0;
    +}
    +.heading-full [class*="head-"]:after {
    +	left:auto;
    +	right:0;
    +}
    +.sub-heading-auto {
    +	width:70%;
    +	display:table;
    +	margin:0 auto 30px;
    +	font-size:16px;
    +}
    +.heading.centered p.sub-heading {
    +	display:table;
    +	margin-right:auto;
    +	margin-left:auto;
    +	width:60%;
    +	font-size:16px;
    +	line-height:23px;
    +}
    +.heading-full-color {
    +	text-align:center;
    +	margin:0;
    +	padding:30px 0;
    +	position:relative;
    +}
    +.heading-full-color p.sub-heading {
    +	display:table;
    +	margin-top:20px;
    +	margin-right:auto;
    +	margin-left:auto;
    +	width:45%;
    +	font-size:15px;
    +	line-height:23px;
    +}
    +.heading-full-color [class*="head-"] {
    +	margin-bottom:0;
    +	padding-bottom:0;
    +}
    +.heading-full-color .tri-angle-down {
    +	position:absolute;
    +	left:50%;
    +	margin-left:-20px;
    +	bottom:-20px;
    +	width:0;
    +	height:0;
    +	border-style:solid;
    +	border-width:20px 20px 0 20px;
    +	z-index:9;
    +}
    +.head-1:after, .head-1:before {
    +	position:absolute;
    +	bottom:7px;
    +	left:0;
    +	width:42%;
    +	height:1px;
    +	content:"";
    +}
    +.head-1:before {
    +	right:0;
    +	left:auto;
    +}
    +.head-1 b {
    +	position:absolute;
    +	bottom:-10px;
    +	left:50%;
    +	width:25px;
    +	height:25px;
    +	margin-left:-12.5px;
    +	font-size:14px;
    +}
    +.head-2:after, .head-2:before {
    +	position:absolute;
    +	bottom:0;
    +	left:-15px;
    +	width:52%;
    +	height:1px;
    +	content:"";
    +}
    +.head-2:before {
    +	right:-15px;
    +	left:auto;
    +}
    +.head-2 b {
    +	position:absolute;
    +	bottom:-15px;
    +	left:50%;
    +	width:25px;
    +	height:25px;
    +	margin-left:-7px;
    +	font-size:11px;
    +}
    +.head-2 b.rit {
    +	position:absolute;
    +	bottom:-24px;
    +	right:50%;
    +	left:auto;
    +	width:25px;
    +	height:25px;
    +	margin-right:-5px;
    +	margin-left:0;
    +	font-size:11px;
    +}
    +.head-3:after, .head-3:before {
    +	position:absolute;
    +	bottom:0;
    +	left:0;
    +	width:48%;
    +	height:3px;
    +	content:"";
    +	margin-left:-15px;
    +}
    +.head-3:before {
    +	right:0;
    +	left:auto;
    +	margin-right:-15px;
    +	margin-left:0;
    +}
    +.head-3 b {
    +	position:absolute;
    +	bottom:-2px;
    +	left:50%;
    +	width:16px;
    +	height:8px;
    +	margin-left:-8px;
    +}
    +.head-3 b:before {
    +	content:"";
    +	position:absolute;
    +	top:-4px;
    +	left:0;
    +	width:0;
    +	height:0;
    +	border-left:8px solid transparent;
    +	border-right:8px solid transparent;
    +	border-bottom-width:4px;
    +	border-bottom-style:solid;
    +}
    +.head-3 b:after {
    +	content:"";
    +	position:absolute;
    +	bottom:-4px;
    +	left:0;
    +	width:0;
    +	height:0;
    +	border-left:8px solid transparent;
    +	border-right:8px solid transparent;
    +	border-top-width:4px;
    +	border-top-style:solid;
    +}
    +.head-4:after {
    +	position:absolute;
    +	bottom: 0;
    +	left:0;
    +	width:30px;
    +	height:3px;
    +	content:"";
    +}
    +.heading.centered .head-4:after {
    +	left:50%;
    +	margin-left:-15px;
    +}
    +.head-5{
    +	margin-bottom:30px
    +}
    +.head-5 p.sub-heading, .head-6 p.sub-heading, .head-7 p.sub-heading, .head-8 p.sub-heading {
    +	margin:15px 0 0;
    +	width:85%;
    +	font-size:15px;
    +	line-height:23px;
    +}
    +.heading.lf-heading p.sub-heading {
    +	margin:15px 0 0;
    +	width:auto;
    +	font-size:15px;
    +	line-height:23px;
    +	text-align:left;
    +}
    +.heading.lf-heading [class*="head-"] {
    +	line-height:1.2;
    +	margin:0 0 30px;
    +	position:relative;
    +}
    +.heading.lf-heading [class*="head-"]:after {
    +	left:0;
    +	bottom:0;
    +}
    +.head-5 p.sub-heading {
    +	margin:15px 40px 0;
    +}
    +.head-5:after,.head-5:before {
    +	position:absolute;
    +	bottom:0;
    +	left: 0;
    +	width: 16.3%;
    +	height:1px;
    +	content:"";
    +	bottom:-10px;
    +}
    +.head-5:before{
    +	left: 16.5%;
    +	width: 83.5%;
    +}
    +.head-6 {
    +	padding-bottom:20px;
    +	margin-bottom:30px
    +}
    +.head-6 *,.head-7 *{
    +	margin-bottom:0
    +}
    +.head-6:after {
    +	position:absolute;
    +	bottom:0;
    +	left:0;
    +	width:60px;
    +	height:1px;
    +	content:"";
    +	bottom:-1px;
    +}
    +.head-7 {
    +	border-width:0 !important;
    +	border-bottom-width:1px !important;
    +	margin-bottom:30px
    +}
    +.head-7 span {
    +	padding:7px 15px;
    +	display: inline-block;
    +	margin-bottom: 1px;
    +}
    +.head-7 span i{
    +	float:none
    +}
    +.head-8 {
    +	padding-left:20px;
    +	margin-bottom:30px;
    +}
    +.head-8:before {
    +	width:8px;
    +	height:80%;
    +	left:0;
    +	top:10%;
    +	content:"";
    +	display:inline-block;
    +	position:absolute;
    +}
    +
    +.sub-head [class*="head-"]{
    +	padding-bottom: 20px;
    +	margin-bottom: 40px;
    +}
    +
    +/*
    +---------- 6.2. Dividers --------------- */
    +.divider {
    +	position:relative;
    +	width:100%;
    +}
    +.divider i {
    +	font-size:15px;
    +}
    +.divider.centered {
    +	text-align:center;
    +}
    +.divider.centered.short {
    +	display:table;
    +	width:50%;
    +}
    +.divider.centered:before, .divider.centered:after {
    +	position:absolute;
    +	top:50%;
    +	left:0;
    +	width:48%;
    +	height:1px;
    +	margin-top:-0.5px;
    +	content:"";
    +}
    +.divider.centered.short:before, .divider.centered.short:after {
    +	width:45%;
    +}
    +.divider.centered:after {
    +	left:auto;
    +	right:0;
    +}
    +.divider.bg i {
    +	border-radius:50%;
    +	width:45px;
    +	height:45px;
    +	line-height:45px;
    +	text-align:center;
    +}
    +.divider.bordered i {
    +	border-radius:50%;
    +	width:45px;
    +	height:45px;
    +	line-height:45px;
    +	text-align:center ;
    +}
    +.divider.lft:before {
    +	position:absolute;
    +	top:50%;
    +	left:0;
    +	width:96%;
    +	height:1px;
    +	margin-top:-0.5px;
    +	content:"";
    +	margin-left:20px;
    +}
    +.divider.lft.short:before {
    +	width:45%;
    +}
    +.divider.lft.bg:before, .divider.lft.bordered:before {
    +	margin-left:45px;
    +}
    +.divider.rit {
    +	text-align:right;
    +}
    +.divider.rit:before {
    +	position:absolute;
    +	top:50%;
    +	right:0;
    +	width:96%;
    +	height:1px;
    +	margin-top:-0.5px;
    +	content:"";
    +	margin-right:20px;
    +}
    +.divider.lft.short:before {
    +	width:45%;
    +}
    +.divider.rit.bg:before, .divider.rit.bordered:before {
    +	margin-right:45px;
    +}
    +.divider .two i {
    +	position:relative;
    +	left:13px;
    +}
    +.divider i.flipped {
    +	transform:rotate(180deg);
    +	position:relative;
    +	top:1px;
    +	left:-5px !important;
    +}
    +.divider i.to-top {
    +	font-size:18px;
    +	cursor:pointer;
    +}
    +
    +/*
    +---------- 6.3. Icon Boxes ------------ */
    +/* icons style 1 */
    +.icons-style-1 i{
    +	position: absolute;
    +	right: 0;
    +	bottom: 0;
    +	font-size: 84px;
    +	line-height: .7;
    +	opacity: .08;
    +	-webkit-transform: rotate(45deg);
    +	transform: rotate(45deg);
    +}
    +.icons-style-1 .heading{
    +	font-size:17px;
    +	margin:0 0 20px;
    +	padding:0
    +}
    +.icons-style-1:hover i.animat-icon{
    +	right: 15px;
    +	font-size: 60px;
    +	line-height: 1;
    +	opacity: .3;
    +	-webkit-transform: rotate(0deg);
    +	transform: rotate(0deg);
    +}
    +.icons-style-1,.icons-style-2 {
    +	margin-bottom:20px;
    +	position:relative;
    +	z-index:99999
    +}
    +.icons-style-2 i {
    +	font-size:35px;
    +	margin-bottom:10px;
    +	border-bottom-style:solid;
    +	border-bottom-width:3px;
    +	padding-bottom:10px;
    +	display:inline-block;
    +}
    +.icons-style-2 .heading {
    +	padding-bottom:10px;
    +	margin-bottom:10px;
    +}
    +.tri-line{
    +	position: absolute;
    +	width:50px;
    +	height:30px;
    +	border-width:1px 1px 0 0;
    +	border-style:solid solid none none;
    +	display:block;
    +	top: 63px;
    +	right: -52px;
    +}
    +.tri-line:before{
    +	position: absolute;
    +	width:70px;
    +	height:1px;
    +	display:inline-block;
    +	bottom: 0;
    +	right: -70px;
    +	content:"";
    +	z-index:9999
    +}
    +.tri-line.left{
    +	border-width:1px 0 0 1px;
    +	border-style:solid none none solid;
    +	left: -53px;
    +	right:auto
    +}
    +.tri-line.left:before{
    +	left: -70px;
    +	right:auto
    +}
    +.tri-line.bottom-tri{
    +	-moz-transform: scaleY(-1);
    +	-o-transform: scaleY(-1);
    +	-webkit-transform: scaleY(-1);
    +	transform: scaleY(-1);
    +	top:34px
    +}
    +
    +.block-icon {
    +	display:table;
    +	margin:0 auto 40px ;
    +}
    +.icon-box i, .icon-box h3 {
    +	position:relative;
    +	z-index:1;
    +}
    +.lg-icon i {
    +	width:90px;
    +	height: 90px;
    +	text-align:center;
    +	line-height: 90px;
    +	font-size:23px;
    +}
    +a.sm-icon{
    +	width: 25px !important;
    +	height: 25px !important;
    +	line-height: 25px !important;
    +}
    +a.sm-icon:before,a.sm-icon:after{
    +	font-size:12px !important;
    +}
    +a.lg-icon{
    +	width: 60px !important;
    +	height: 60px !important;
    +	line-height: 60px !important;
    +}
    +a.xl-icon{
    +	width: 80px !important;
    +	height: 80px !important;
    +	line-height: 80px !important;
    +}
    +a.lg-icon:before,a.lg-icon:after{
    +	font-size:23px !important;
    +}
    +a.xl-icon:before,a.xl-icon:after{
    +	font-size:33px !important;
    +}
    +
    +.img-icon {
    +	margin:0 auto 20px;
    +	border-radius:50%;
    +	width:170px;
    +	height:170px;
    +	border-style:solid;
    +	border-width:3px;
    +	overflow:hidden;
    +	-webkit-transform:translateZ(0);
    +	-webkit-mask-image:-webkit-radial-gradient(circle, white 100% , black 100%);
    +}
    +.img-icon img {
    +	transform:scale(1);
    +	-webkit-transform:scale(1);
    +	-moz-transform:scale(1);
    +	-ms-transform:scale(1);
    +	border-radius:50%;
    +}
    +.icon-box:hover .img-icon img {
    +	transform:scale( 1.5);
    +	-webkit-transform:scale( 1.5);
    +	-moz-transform:scale(1.5);
    +	-ms-transform:scale(1.5);
    +}
    +.md-icon i {
    +	width: 60px;
    +	height: 60px;
    +	text-align:center;
    +	line-height: 60px;
    +	font-size: 20px;
    +}
    +.lg-icon.re ct-shadow i {
    +	-webkit-transition:box-shadow 0.3s ease-in-out 0s;
    +	-moz-transition:box-shadow 0.3s ease-in-out 0s;
    +	-o-transition:box-shadow 0.3s ease-in-out 0s;
    +	-ms-transition:box-shadow 0.3s ease-in-out 0s;
    +	transition:box-shadow 0.3s ease-in-out 0s;
    +}
    +.icon-box h3 {
    +	font-size:16px;
    +	line-height: 1;
    +	margin-bottom: 20px;
    +}
    +.lg-icon.diamon d i {
    +	width:80px;
    +	height:80px;
    +	line-height:80px;
    +}
    +.outlined.circle i, .filled.circle i {
    +	border-radius:50%;
    +}
    +.box-1 .outlined i {
    +	background:transparent;
    +	position:relative
    +}
    +.box-1 .outlined i:after {
    +	content:"";
    +	width:96%;
    +	height:96%;
    +	display:inline-block;
    +	position:absolute;
    +	top:2%;
    +	left:2%;
    +	z-index:-1;
    +	-webkit-transform:scale(1.6);
    +	-moz-transform:scale(1.6);
    +	-ms-transform:scale(1.6);
    +	transform:scale(1.6);
    +	opacity:0;
    +	-webkit-transition:all 0.4s, opacity 0.7s;
    +	-moz-transition:transform 0.4s, opacity 0.7s;
    +	transition:transform 0.4s, opacity 0.7s;
    +}
    +.box-1 .filled i:after {
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	content:'';
    +	-webkit-box-sizing:content-box;
    +	-moz-box-sizing:content-box;
    +	box-sizing:content-box;
    +}
    +.box-1 .filled.circle i:after, .box-1 .outlined.circle i:after {
    +	border-radius:50%;
    +}
    +.box-1 .filled i:after {
    +	top:-2px;
    +	left:-2px;
    +	padding:2px;
    +	opacity:0;
    +	-webkit-transition:-webkit-transform 0.4s, opacity 0.5s;
    +	-moz-transition:-moz-transform 0.4s, opacity 0.5s;
    +	transition:transform 0.4s, opacity 0.5s;
    +	-webkit-transform:scale(.8);
    +	-moz-transform:scale(.8);
    +	-ms-transform:scale(.8);
    +	transform:scale(.8);
    +}
    +.box-1:hover .filled i:after {
    +	-webkit-transform:scale(1);
    +	-moz-transform:scale(1);
    +	-ms-transform:scale(1);
    +	transform:scale(1);
    +	opacity:1;
    +}
    +.box-1 .filled.eff-2 i:after {
    +	-webkit-transform:scale(1.8);
    +	-moz-transform:scale(1.8);
    +	-ms-transform:scale(1.8);
    +	transform:scale(1.8);
    +}
    +.box-1:hover .filled.eff-2 i:after {
    +	-webkit-transform:scale(1);
    +	-moz-transform:scale(1);
    +	-ms-transform:scale(1);
    +	transform:scale(1);
    +	opacity:1;
    +}
    +.box-1:hover .outlined i:after {
    +	-webkit-transform:scale(1);
    +	-moz-transform:scale(1);
    +	-ms-transform:scale(1);
    +	transform:scale( 1);
    +	opacity:1;
    +}
    +.box-1 .transparent i {
    +	background:transparent;
    +	font-size:60px;
    +	height:60px;
    +	line-height:60px;
    +	margin-top: 40px;
    +}
    +.box-1.bordered {
    +	border:1px transparent solid;
    +	display:table;
    +	overflow:hidden;
    +	position:relative;
    +	padding:0 15px;
    +	width:100%
    +}
    +.box-1.bordered:before, .box-1.bordered:after {
    +	right:0;
    +	bottom:0;
    +	content:"";
    +	position:absolute;
    +	display:inline-block;
    +}
    +.box-1.bordered:before {
    +	width:100%;
    +	height:1px;
    +	left:1px;
    +	transform:translateX(-100%);
    +	-webkit-transform:translateX(-100%);
    +}
    +.box-1.bordered:after {
    +	width:1px;
    +	height:100%;
    +	transform:translateY(100%);
    +	-webkit-transform:translateY(100%);
    +}
    +.box-1 .bordered .inner {
    +	display:block;
    +	padding:20px;
    +	position:relative;
    +}
    +.box-1.bordered .i nner p {
    +	margin-bottom:0;
    +}
    +.box-1.bordered .inner:before, .box-1.bordered .inner:after {
    +	left:0;
    +	top:0;
    +	content:"";
    +	display:inline-block;
    +	position:absolute;
    +}
    +.box-1.bordered .inner:before {
    +	width:100%;
    +	height:1px;
    +	transform:translateX(100%);
    +	-webkit-transform:translateX(100%);
    +	left:1px
    +}
    +.box-1.bordered .inner:after {
    +	width:1px;
    +	height:100%;
    +	left:1px;
    +	transform:translateY(-100%);
    +	-webkit-transform:translateY(-100%);
    +}
    +.box-1.bordered:hover:before, .box-1.bordered:hover:after, .box-1.bordered:hover .inner:before, .box-1.bordered:hover .inner:after {
    +	transform:translate(0 , 0);
    +	-webkit-transform:translate(0 , 0);
    +}
    +.icon-box.gry-border-1 {
    +	padding:15px 10px;
    +}
    +.icon-box.gry-border-1 .block-icon {
    +	margin: 30px auto 40px;
    +}
    +.icon-box h3.bottom_half_border {
    +	position:relative;
    +	padding-bottom:20px;
    +}
    +.icon-box h3.bottom_half_border:after {
    +	position:absolute;
    +	display:inline-block;
    +	content:"";
    +	height:1px;
    +	width:25%;
    +	margin-left:-12%;
    +	bottom:0px;
    +	left:50%;
    +	text-decoration:none;
    +}
    +.icon-box.gry-border-1:hover i {
    +	text-shadow:none;
    +}
    +.icon-box:hover h3.bottom_half_border:after {
    +	width:80%;
    +	margin-left:-40%;
    +	left:50%;
    +}
    +.icon-box.gry-border-2 {
    +	padding:1px;
    +}
    +.icon-box.gry-border-2 .head-bg {
    +	padding:25px 0;
    +}
    +.icon-box.gry-border-2 .block-icon {
    +	font-size:35px;
    +	margin:30px auto;
    +}
    +.icon-box.gry-border-2 .icon-desc {
    +	padding:0 20px;
    +}
    +.icons-style-2 i {
    +	font-size:35px;
    +	margin-bottom:10px;
    +	border-bottom-style:solid;
    +	border-bottom-width:3px;
    +	padding-bottom:10px;
    +	display:inline-block;
    +}
    +.icons-style-2 .heading {
    +	font-size:17px;
    +	font-weight:bold;
    +	text-transform:uppercase;
    +	margin-bottom:10px;
    +	padding-bottom:10px;
    +}
    +.icon-box-small i {
    +	float:left;
    +	margin-right:18px;
    +	font-size:16px;
    +	line-height:1.6;
    +	font-style:normal;
    +}
    +.icon-box-small i.md-icon {
    +	width: 40px;
    +	height: 40px;
    +	line-height: 40px !important;
    +	margin-right:0;
    +	font-size:12px;
    +}
    +.left-icons .icon-box-small i {
    +	float:right;
    +	margin-right:0;
    +	margin-left:18px;
    +}
    +.left-icons .icon-box-small .icon-sm-desc {
    +	margin-left:0;
    +	margin-right:70px;
    +	text-align:right;
    +}
    +.icon-box-small h3,.icon-box-small h4 {
    +	font-size: 16px;
    +	margin-bottom:15px;
    +	line-height:1.6;
    +}
    +.icon-box-small .icon-sm-desc.md-desc {
    +	margin-left: 55px;
    +	margin-bottom: 50px;
    +}
    +.icon-box-small:last-child .icon-sm-desc.md-desc{
    +	margin-bottom:0
    +}
    +.icon-box-small .icon-sm-desc.md-desc h3,.icon-box-small .icon-sm-desc.md-desc h4{
    +	margin-bottom: 10px;
    +	line-height:1
    +}
    +.icon-box-small i{
    +	position:relative;
    +	text-align:center;
    +}
    +.icon-box-small:hover i.filled:before{
    +	color:#fff
    +}
    +.icon-box-small i:before,.icon-box-small i span{
    +	z-index:1;
    +	position:relative
    +}
    +.icon-box-small i:after{
    +	background:#222;
    +	position:absolute;
    +	left:0;
    +	top:0;
    +	width:100%;
    +	height:100%;
    +	content:"";
    +	display:inline-block;
    +	-webkit-transform: scale(1.7);
    +	-moz-transform: scale(1.7);
    +	-ms-transform: scale(1.7);
    +	transform: scale(1.7);
    +	opacity: 0;
    +	z-index:0;
    +}
    +.no-after:after{
    +	display:none !important
    +}
    +.icon-box-small i.circle:after{
    +	border-radius:50%
    +}
    +.icon-box-small i.border3px:after{
    +	border-radius:3px;
    +}
    +.icon-box-small:hover i:after{
    +	-webkit-transform: scale(1);
    +	-moz-transform: scale(1);
    +	-ms-transform: scale(1);
    +	transform: scale(1);
    +	opacity: 1;
    +}
    +.icon-box-small .icon-sm-desc h3 {
    +	margin-bottom:5px;
    +}
    +.icon-box-small p {
    +	margin-bottom:0;
    +}
    +.icon-box-small .filled, .icon-box-small .outlined {
    +	width:50px;
    +	height:50px;
    +	line-height: 50px;
    +	text-align:center;
    +}
    +.lg-box {
    +	padding:40px;
    +	text-align:center;
    +	border:1px transparent solid;
    +}
    +.lg-box i {
    +	font-size:25px;
    +	margin-bottom:30px;
    +}
    +.lg-box h4 {
    +	font-size:17px;
    +	margin-bottom:15px;
    +	font-weight:bold;
    +}
    +
    +/*
    +------------ 6.4. Tabs ------------ */
    +.tab-content .tab-pane{
    +	padding:20px 0;
    +	overflow:hidden;
    +}
    +.tabs-style-default .tab-content .tab-pane{
    +	padding:20px;
    +	background:#fff
    +}
    +.tab-content.main-bg .tab-pane{
    +	padding:20px;
    +}
    +.nav-tabs>li>a i{
    +	margin-right:10px
    +}
    +.nav-tabs>li>a i.tab-icon{
    +	display:table;
    +	margin:0 auto 5px;
    +	font-size:15px
    +}
    +.nav-tabs>li>a {
    +	transition: background-color 0.2s, color 0.2s;
    +	font-weight:600;
    +	border-radius:0
    +}
    +.nav-tabs>li>a:hover{
    +	background:transparent;
    +	border-color:transparent;
    +}
    +.nav-tabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover,.nav-tabs {
    +	border: 0;
    +}
    +.nav-tabs>li>a span {
    +	vertical-align: middle;
    +	position:relative;
    +	z-index:1
    +}
    +.tabs nav li.active a {
    +	padding:15px 20px 14px;
    +}
    +.tabs-style-default .nav-tabs>li.active>a,.tabs-style-default .nav-tabs>li.active>a:focus,.tabs-style-default .nav-tabs>li.active>a:hover{
    +	border-top-width:3px !important
    +}
    +.tabs nav li.active a:before{
    +	height:1px;
    +	position:absolute;
    +	bottom:-1px;
    +	width:100%;
    +	display:inline-block;
    +	content:"";
    +	left:0
    +}
    +.tabs-style-ballon .nav-tabs>li.active>a:after,.filter-by.style-2 ul li.active:after,.filter-by.style-3 ul li.active:after{
    +	content: "";
    +	position: absolute;
    +	top: 0;
    +	left: 50%;
    +	display: block;
    +	margin-left: -6px;
    +	width: 0;
    +	height: 0;
    +	border-style: solid;
    +	border-width: 5px 5px 0 5px
    +}
    +.nav-tabs>li>a:focus {
    +	outline: none;
    +}
    +.tabs nav li a i{
    +	margin-right:10px
    +}
    +.tabs nav li a i.block-icon{
    +	margin:0 auto 10px;
    +	display:table;
    +	font-size:15px
    +}
    +
    +/* bottom line */
    +.tabs-style-bottomline .nav-tabs>li {
    +	margin-bottom: 1px;
    +}
    +.tabs-style-bottomline .nav-tabs li a,.tabs-style-bottomline .nav-tabs li.active a{
    +	background:transparent !important
    +}
    +.tabs-style-bottomline .nav-tabs li:after{
    +	display:inline-block;
    +	position:absolute;
    +	bottom:-5px;
    +	left:50%;
    +	width:0;
    +	content:"";
    +	height:3px;
    +}
    +.tabs-style-bottomline .nav-tabs li.active:before{
    +	display:inline-block;
    +	position:absolute;
    +	bottom:-2px;
    +	left:50%;
    +	width:0;
    +	content:"";
    +	height:0;
    +	border-style: solid;
    +	border-width: 0 4px 4px 4px;
    +	margin-left:-4px
    +}
    +.tabs-style-bottomline .nav-tabs li.active:after{
    +	left:0;
    +	width:100%;
    +}
    +.tabs-style-bottomline .content-wrap section{
    +	padding:30px 0
    +}
    +.tabs-style-bottomline .tab-icon{
    +	margin-top:-15px
    +}
    +
    +/* bg */
    +.tabs-style-bg .nav-tabs{
    +	border-bottom:0
    +}
    +.tabs-style-bg .nav-tabs>li{
    +	margin-bottom:0;
    +}
    +.tabs-style-bg .nav-tabs>li a{
    +	border:0;
    +	position:relative;
    +	overflow:hidden
    +}
    +.tabs-style-bg .nav-tabs>li a:after {
    +	position: absolute;
    +	top: 0;
    +	left: 0;
    +	z-index: 0;
    +	width: 100%;
    +	height: 100%;
    +	background-color: #f0f0f0;
    +	content: '';
    +	-webkit-transition: -webkit-transform 0.3s, background-color 0.3s;
    +	transition: transform 0.3s, background-color 0.3s;
    +	-webkit-transform: perspective(900px) rotate3d(1,0,0,90deg);
    +	transform: perspective(900px) rotate3d(1,0,0,90deg);
    +	-webkit-transform-origin: 50% 100%;
    +	transform-origin: 50% 100%;
    +	-webkit-perspective-origin: 50% 100%;
    +	perspective-origin: 50% 100%;
    +}
    +.tabs-style-bg .nav-tabs>li.active a:after{
    +	-webkit-transform: perspective(900px) rotate3d(1,0,0,0deg);
    +	transform: perspective(900px) rotate3d(1,0,0,0deg);
    +}
    +.tabs-style-bg .nav-tabs>li.active a i,.tabs-style-bg .nav-tabs>li.active a{
    +	color:#fff
    +}
    +.tabs-style-bg .tab-content .tab-pane{
    +	padding:20px
    +}
    +
    +/* ballon */
    +.tabs-style-ballon .nav-tabs>li>a{
    +	padding: 12px 20px;
    +}
    +.tabs-style-ballon nav li.active a{
    +	padding:12px 20px
    +}
    +.tabs-style-ballon .nav-tabs>li.active>a:after{
    +	top:auto;
    +	bottom:-4px
    +}
    +.tabs-style-ballon .tab-content .tab-pane{
    +	padding:20px;
    +	border-bottom:3px #ddd solid
    +}
    +
    +/* tabs-style-lg 1 */
    +.tabs-style-lg .nav-tabs{
    +	margin:auto;
    +	display:table;
    +	width:auto;
    +	position:relative;
    +	z-index:9;
    +	margin-bottom:0
    +}
    +.tabs-style-lg.style-1 .nav-tabs>li{
    +	margin:0
    +}
    +.tabs-style-lg .nav-tabs>li>a{
    +	font-size:15px;
    +	padding: 25px 30px;
    +	border:0;
    +	margin:0
    +}
    +.tabs-style-lg .nav-tabs>li>a .tab-icon{
    +	font-size:20px;
    +	text-align:center;
    +	background:rgba(0,0,0,0.03);
    +	padding: 15px 35px;
    +	margin:0 auto 15px;
    +	border-radius: 2em;
    +}
    +.tabs-style-lg.style-1 .nav-tabs>li.active>a i{
    +	color:#fff
    +}
    +.tabs-style-lg.style-1 .nav-tabs>li.active>a:before {
    +	content: "";
    +	position: absolute;
    +	bottom: -10px;
    +	left: 50%;
    +	display: block;
    +	margin-left: -10px;
    +	width: 0;
    +	height: 0;
    +	border-style: solid;
    +	border-width: 10px 10px 0 10px;
    +}
    +.lg-tab-txt{
    +	font-size:16px
    +}
    +.tabs-style-lg.gry-bg .nav-tabs>li{
    +	border-top:0
    +}
    +/* verticals */
    +[class*="tabs-style-"].vertical .nav-tabs {
    +	float:left;
    +	width:30%;
    +	border-bottom:0
    +}
    +[class*="tabs-style-"].vertical .nav-tabs>li{
    +	float:none;
    +	display:block;
    +	text-align:left;
    +	margin-bottom: 0;
    +	margin-right: -1px;
    +}
    +[class*="tabs-style-"].vertical >.nav-tabs>li>a{
    +	margin:0 1px 1px 0;
    +	border:0 !important
    +}
    +.tabs-style-default.vertical >.nav-tabs>li>a{
    +	margin:0 0 1px -1px;
    +}
    +.tabs-style-bottomline .nav-tabs li.active a:before,.tabs.vertical nav li.active a:before{
    +	display:none
    +}
    +[class*="tabs-style-"].vertical .tab-content{
    +	margin-left:30%;
    +	clear:none;
    +}
    +.tabs-style-ballon.vertical .nav-tabs>li.active> a:after{
    +	transform:rotate(-90deg);
    +	right:-7px;
    +	top:50%;
    +	margin-top:-3px;
    +	left:auto
    +}
    +.tabs-style-bottomline.vertical .nav-tabs {
    +	border-bottom:0
    +}
    +.tabs.vertical nav li:last-child.active a {
    +	border-right:0
    +}
    +.tabs-style-bottomline.vertical .nav-tabs>li:after{
    +	width:2px;
    +	height:100%;
    +	left:auto;
    +	top:0;
    +	right:-1px
    +}
    +.tabs-style-bottomline.vertical .nav-tabs>li:before{
    +	transform:rotate(-90deg);
    +	right:-1px;
    +	top:50%;
    +	margin-top:-3px;
    +	left:auto
    +}
    +.tabs-style-bottomline.vertical .nav-tabs>li>a{
    +	border-top:0 !important;
    +	border-left:0 !important;
    +	border-bottom:0 !important;
    +}
    +.tabs-style-bottomline.vertical .tab-content .tab-pane,.tabs-style-ballon.vertical .tab-content .tab-pane{
    +	padding:10px 30px
    +}
    +.tabs-style-bg.vertical .nav-tabs>li.active a:after {
    +	-webkit-transform: perspective(900px) rotate3d(0,1,0,0deg);
    +	transform: perspective(900px) rotate3d(0,1,0,0deg);
    +}
    +.tabs-style-bg.vertical .nav-tabs>li a:after {
    +	-webkit-transition: -webkit-transform 0.3s, background-color 0.3s;
    +	transition: transform 0.3s, background-color 0.3s;
    +	-webkit-transform: perspective(900px) rotate3d(0,1,0,-90deg);
    +	transform: perspective(900px) rotate3d(0,1,0,-90deg);
    +	-webkit-transform-origin: 100% 50%;
    +	transform-origin: 100% 50%;
    +	-webkit-perspective-origin: 100% 50%;
    +	perspective-origin: 100% 50%;
    +	right:0 !important;
    +	left:auto !important
    +}
    +.tabs-style-ballon.vertical .nav-tabs>li{
    +	border-bottom:1px transparent solid
    +}
    +.tabs-style-ballon.vertical .tab-content .tab-pane{
    +	border-bottom:0;
    +	border-right:3px transparent solid
    +}
    +/*
    +------------- 6.5. Accordions ------------ */
    +.accordion .panel:not(.main-bg){
    +	background:transparent;
    +}
    +.accordion .panel{
    +	-webkit-box-shadow: none;
    +	box-shadow: none;
    +	border:0px transparent none;
    +}
    +.panel-body p{
    +	margin:0
    +}
    +.accordion .panel-default,.panel-group .panel-heading+.panel-collapse>.list-group, .panel-group .panel-heading+.panel-collapse>.panel-body {
    +	border:0px transparent none;
    +}
    +.accordion .panel>.panel-heading{
    +	cursor:pointer;
    +	border:0;
    +	padding:0;
    +	margin:0;
    +	font-weight:600;
    +	background-color:transparent;
    +}
    +.accordion .panel >.panel-heading h4{
    +	font-size:14px;
    +}
    +.accordion .panel >.panel-heading h4 a{
    +	display:block;
    +	padding:12px 18px;
    +	position:relative;
    +}
    +.accordion.style-5 .panel >.panel-heading h4 a{
    +	overflow:hidden
    +}
    +.accordion .panel.main-bg >.panel-heading h4 a,.accordion .panel.main-bg >.panel-heading h4 a i,.accordion .panel >.panel-heading h4 a.main-bg,.accordion .panel >.panel-heading h4 a.main-bg i{
    +	color:#fff
    +}
    +.accordion .panel>.panel-heading h4 a:after {
    +	position:absolute;
    +	top:50%;
    +	right:15px;
    +	display:inline-block;
    +	font:normal normal normal 14px/1 FontAwesome;
    +	content:"\f106";
    +	margin-top:-8px
    +}
    +.accordion .panel>.panel-heading h4 a.collapsed:after {
    +	content:"\f107";
    +}
    +.panel-title i {
    +	margin-right:15px;
    +}
    +.accordion.style-3 .panel-title a:not(.collapsed) i{
    +	color:#fff
    +}
    +/* style 1 */
    +.accordion.style-1 .panel >.panel-heading h4 a{
    +	border:1px transparent solid
    +}
    +.accordion.style-1 .panel >.panel-heading h4 a:not(.collapsed):before{
    +	position:absolute;
    +	height:1px;
    +	width:99%;
    +	left:0.5%;
    +	bottom:-3px;
    +	content:"";
    +	display:inline-block
    +}
    +
    +/* style 3 */
    +.accordion.style-3{
    +	-webkit-box-shadow: 0 0px 4px rgba(0,0,0,.3);
    +	box-shadow: 0 0px 4px rgba(0,0,0,.3);
    +}
    +.accordion.style-3 .panel:first-child >.panel-heading h4 a{
    +	border-top:0px;
    +}
    +.accordion.style-3.border5px .panel:first-child >.panel-heading h4 a{
    +	border-top-left-radius: 5px;
    +	border-top-right-radius: 5px;
    +}
    +
    +/* style 4 */
    +.accordion.style-4 .panel>.panel-heading h4 a:after {
    +	content:"\f068";
    +	font-size:12px
    +}
    +.accordion.style-4 .panel>.panel-heading h4 a.collapsed:after {
    +	content:" \f067";
    +}
    +.accordion.style-4 .panel>.panel-heading h4 a:not(.collapsed):before{
    +	display: inline-block;
    +	position: absolute;
    +	bottom: -6px;
    +	left: 5%;
    +	width: 0;
    +	content: "";
    +	height: 0;
    +	border-style: solid;
    +	border-width: 6px 6px 0 6px;
    +}
    +
    +/* style 5 */
    +.accordion.style-5 .panel>.panel-heading h4 a:after{
    +	background-color:rgba(255,255,255,.15);
    +	top:0;
    +	right:0;
    +	padding:15px 17px 16px;
    +	margin:0
    +}
    +.accordion.style-5 .panel>.panel-heading h4 a i{
    +	background-color:rgba(255,255,255,.15);
    +	padding:15px 12px 16px;
    +	margin:-12px 12px -12px -18px
    +}
    +.accordion.style-5 .panel-collapse{
    +	margin-left:39px;
    +	margin-right: 42px;
    +}
    +/*
    +---------------- 6.6. Progress bars --------------- */
    +.progress-bars .progress{
    +	position:relative;
    +	overflow:visible;
    +}
    +.progress-bars .bar {
    +	position:relative
    +}
    +.progress-bars.tiny-line .progress{
    +	height:2px;
    +}
    +.progress-bars.small-line .progress{
    +	height:10px;
    +}
    +.progress-bars.lg-line .progress{
    +	height: 25px;
    +}
    +.progress-bars.xl-line .progress{
    +	height: 35px;
    +}
    +.progress-bars .progress-bar,.progress-bars .progress{
    +	-webkit-transition: width 1s ease-in-out;
    +	-moz-transition: width 1s ease-in-out;
    +	-o-transition: width 1s ease-in-out;
    +	transition: width 1s ease-in-out;
    +}
    +.progress-bars .bar-title{
    +	display:inline-block;
    +	margin-bottom:5px;
    +}
    +.progress-bars .progress-bar{
    +	position:relative;
    +	opacity:0
    +}
    +/* small lines */
    +.progress-bars.tool-tip .progress-bar span{
    +	position:absolute;
    +	right:0;
    +	top: -25px !important;
    +}
    +.progress-bars.tiny-line .progress{
    +	margin-bottom:30px
    +}
    +/* style 2 */
    +.progress-bars.style-2 .bar{
    +	margin-right:0
    +}
    +.progress-bars.tool-tip .progress-bar span{
    +	padding:1px 4px;
    +	width:auto;
    +	display:block;
    +	font-size:11px;
    +	color: #fff !important;
    +	top: -25px;
    +	border-radius: 0 !important;
    +}
    +.progress-bars.tool-tip .progress-bar span:after{
    +	width: 0;
    +	height: 0;
    +	border-style: solid;
    +	border-width: 4px 4px 0 4px;
    +	position:absolute;
    +	left:50%;
    +	margin-left:-4px;
    +	bottom:-3px;
    +	content:"";
    +	display:inline-block
    +}
    +
    +/* lg line */
    +.progress-bars.lg-line:not(.tool-tip) .progress-bar span{
    +	top: 1px;
    +	right: 1px;
    +	height: 23px;
    +	line-height: 23px;
    +	width: 23px;
    +	background:rgba(255,255,255,.7);
    +	color:#333;
    +	font-weight:600;
    +	font-size: 8px;
    +	position: absolute;
    +}
    +.progress-bars:not(.tool-tip) .progress-bar{
    +	overflow:hidden
    +}
    +/* xl line */
    +.progress-bars.xl-line:not(.tool-tip) .progress-bar span{
    +	top: 1px;
    +	right: 1px;
    +	height: 33px;
    +	line-height: 33px;
    +	width: 33px;
    +	background:rgba(255,255,255,.7);
    +	color:#333;
    +	position: absolute;
    +	font-weight:600
    +
    +}
    +.progress-bars.xl-line:not(.tool-tip) .progress-bar span:after,.progress-bars.lg-line:not(.tool-tip) .progress-bar span:after{
    +	display:none
    +}
    +.progress-bars.xl-line:not(.tool-tip) .progress-bar span,.progress-bars.lg-line:not(.tool-tip) .progress-bar span{
    +	border-radius:50%
    +}
    +.progress-bars.xl-line .bar span.bar-title.in-bar{
    +	position:absolute;
    +	left:10px;
    +	top:11px;
    +	z-index:6;
    +	color:#fff;
    +	text-shadow: 1px 1px 1px rgba(0,0,0,.5);
    +}
    +.progress-bars.lg-line .bar span.bar-title.in-bar{
    +	position:absolute;
    +	left:10px;
    +	top:5px;
    +	z-index:6;
    +	color:#fff;
    +	font-size:12px;
    +	text-shadow: 1px 1px 1px rgba(0,0,0,.5);
    +}
    +
    +.sm-progress{
    +	text-shadow: none !important;
    +	margin-left:10px
    +}
    +
    +/* style 5 */
    +.progress-bars.style-5,.progress-bars.style-6{
    +	overflow:hidden;
    +	-webkit-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.2);
    +	-moz-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.2);
    +	box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.2);
    +	border-style:solid;
    +	border-width:1px
    +}
    +.progress-bars.style-5 .progress,.progress-bars.style-6 .progress{
    +	background:transparent;
    +	-webkit-box-shadow: none;
    +	box-shadow: none;
    +	padding: 2px 65px 25px 20px;
    +	margin-bottom: 0;
    +	border-radius:0
    +}
    +
    +.progress-bars.style-5 .progress .progress-bar,.progress-bars.style-6 .progress .progress-bar{
    +	position:static;
    +	height:10px;
    +	float:none
    +}
    +.progress-bars.style-5 .progress-bar span,.progress-bars.style-6 .progress-bar span{
    +	position: absolute;
    +	right: 0;
    +	height: 61px;
    +	line-height: 61px;
    +	width: 60px !important;
    +	top: -34px !important;
    +	text-align: center;
    +	font-weight: bold;
    +	border-radius:0 !important
    +}
    +.progress-bars.style-5 span.bar-title,.progress-bars.style-6 span.bar-title{
    +	margin-left:20px;
    +	margin-top: 10px;
    +}
    +
    +/*
    +-------------------- 6.7. Circliful charts ----------------- */
    +.circliful {
    +	position: relative;
    +	font-weight:900;
    +}
    +.circle-text, .circle-info, .circle-text-half, .circle-info-half {
    +	width: 100%;
    +	position: absolute;
    +	text-align: center;
    +	display: inline-block;
    +}
    +.circle-info, .circle-info-half {
    +	font-size:14px;
    +	font-weight:normal;
    +	margin-top:10px
    +}
    +.c-chart[data-type=half] .circle-info-half {
    +	margin-top:7px
    +}
    +.circliful .fa {
    +	position: absolute;
    +	top: 25%;
    +	left:50%;
    +}
    +.circliful .fa:before{
    +	position:relative;
    +	left:-50%;
    +}
    +.c-chart.bottom-txt{
    +	display:table;
    +	margin:auto
    +}
    +.c-chart.bottom-txt .fa{
    +	top:50%;
    +}
    +
    +/*
    +------------- 6.8. CTA ---------------- */
    +.cta_btn{
    +
    +}
    +.cta-left{
    +	width:70%;
    +	line-height: 1;
    +}
    +.cta-icon{
    +	margin: 0 25px 0 0;
    +}
    +h2.cta_heading{
    +	font-size:27px;
    +	margin-bottom: 0;
    +	line-height: 1;
    +}
    +h4.cta_heading{
    +	font-size:15px;
    +	margin-top: 8px;
    +	font-weight:normal;
    +	margin-bottom: 0;
    +}
    +.cta_btn p{
    +	margin: 10px 0 0;
    +	width:90%;
    +	line-height: 1.7;
    +}
    +.cta_btn .btn{
    +	margin:0
    +}
    +/*
    +------------- 6.9. Team Boxes ---------------- */
    +.team-box{
    +	overflow:hidden;
    +	position:relative;
    +}
    +.team-box .team-img,.team-box .team-details{
    +	text-align:center;
    +}
    +.team-box .team-details .team-name{
    +	padding:20px 0 5px;
    +	font-size:16px;
    +	font-weight:bold;
    +	margin:0
    +}
    +.team-box .team-details .team-pos{
    +	padding:8px 0 20px;
    +	font-size:11px;
    +	font-weight:bold;
    +	text-transform:uppercase;
    +	margin:0
    +}
    +.team-box .social-list{
    +	display:table;
    +	margin:auto
    +}
    +.team-box.box-2 .social-list li a{
    +	border:1px #919191 solid;
    +}
    +.team-box.box-1 .team-details{
    +	padding-bottom:30px
    +}
    +.team-box.box-1 .team-img{
    +	background:#2c333b
    +}
    +.team-box.box-1:hover .team-details .team-name,.box-1:hover .team-details .team-pos,.box-3:hover .team-name,.team-box.box-2:hover .social-list li a{
    +	color:#fff
    +}
    +
    +/* box 2 */
    +.team-box.box-2 .team-img{
    +	position:relative;
    +	overflow:hidden
    +}
    +
    +.team-box.box-2 .team-name{
    +	padding: 15px 0;
    +}
    +.team-box.box-2 .team-details .team-pos{
    +	padding:12px 0;
    +}
    +.team-box.box-2 .social-list li{
    +	transform:scale(0);
    +	-webkit-transform: scale(0);
    +}
    +.team-box.box-2 .social-list li:nth-child(2) {
    +  -webkit-transition-delay: 0.1s;
    +  transition-delay: 0.1s;
    +}
    +.team-box.box-2 .social-list li:nth-child(3) {
    +  -webkit-transition-delay: 0.15s;
    +  transition-delay: 0.15s;
    +}
    +.team-box.box-2 .social-list li:nth-child(4) {
    +  -webkit-transition-delay: 0.2s;
    +  transition-delay: 0.2s;
    +}
    +.team-box.box-2 .social-list li:nth-child(5) {
    +  -webkit-transition-delay: 0.25s;
    +  transition-delay: 0.25s;
    +}
    +.team-box.box-2 .social-list li:nth-child(6) {
    +  -webkit-transition-delay: 0.3s;
    +  transition-delay: 0.3s;
    +}
    +.team-box.box-2 .social-list li:nth-child(7) {
    +  -webkit-transition-delay: 0.35s;
    +  transition-delay: 0.35s;
    +}
    +
    +.team-box.box-2 .box-socials{
    +	position:absolute;
    +	top: 80%;
    +	z-index:5;
    +	width: 100%;
    +}
    +.team-box.box-2:hover .social-list li{
    +	transform:scale(1);
    +	-webkit-transform: scale(1);
    +}
    +.team-box.box-2 .team-img span,.team-box.box-3 .team-img span{
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	background:rgba(0,0,0,.7);
    +	z-index:3;
    +	opacity:0;
    +	left:0
    +}
    +.team-box.box-2:hover .team-img span,.team-box.box-3:hover .team-img span{
    +	opacity:1
    +}
    +
    +/* box 3 */
    +.team-box.box-3,.team-box.box-4{
    +	position:relative;
    +}
    +.team-box.box-3 .team-details,.team-box.box-4 .team-details{
    +	position:absolute;
    +	bottom:-100%;
    +	width:100%;
    +	padding-bottom:20px;
    +	z-index:5
    +}
    +.team-box.box-3:hover .team-details{
    +	bottom:0
    +}
    +
    +/* box 4 */
    +.team-box.box-4 .team-img{
    +	position:relative
    +}
    +.team-box.box-4 .team-details .team-name{
    +	background:rgba(0,0,0,.07);
    +	color:#fff;
    +	padding:10px 0 8px;
    +	line-height:1.5;
    +	font-size:15px
    +}
    +.team-box.box-4 .team-details .team-pos{
    +	color:#444 !important;
    +	padding:8px 0 10px;
    +	position:relative;
    +	margin:5px 0 15px
    +}
    +.team-box.box-4 .team-details .team-pos:after{
    +	position:absolute;
    +	background:#fff;
    +	height:3px;
    +	width:20px;
    +	left:50%;
    +	margin-left:-10px;
    +	bottom:0;
    +	content:"";
    +	display:inline-block
    +}
    +.team-box.box-4 .team-details p{
    +	padding:5px 25px
    +}
    +.team-box.box-4 .team-details{
    +	-webkit-transform: translateX(-100%);
    +	-moz-transform: translateX(-100%);
    +	-o-transform: translateX(-100%);
    +	-ms-transform: translateX(-100%);
    +	transform: translateX(-100%);
    +	-ms-filter: "progid: DXImageTransform.Microsoft.Alpha(Opacity=100)";
    +	opacity: 1;
    +	height:100%;
    +	padding:20px 0;
    +	top:0;
    +}
    +.team-box.box-4:hover .team-details {
    +	-webkit-transform: translateX(0px);
    +	-moz-transform: translateX(0px);
    +	-o-transform: translateX(0px);
    +	-ms-transform: translateX(0px);
    +	transform: translateX(0px);
    +}
    +.team-box.box-4:hover .team-img {
    +	-webkit-transform: translateX(100%);
    +	-moz-transform: translateX(100%);
    +	-o-transform: translateX(100%);
    +	-ms-transform: translateX(100%);
    +	transform: translateX(100%);
    +}
    +/* box 5 */
    +.box-5{
    +	padding-bottom:20px
    +}
    +.rounded-img{
    +	border-radius:50%;
    +	overflow:hidden;
    +	max-height:275px
    +}
    +.box-5:hover .team-pos,.box-5:hover .team-name{
    +	color:#fff
    +}
    +
    +/*
    +----------------- 6.10. Pricing Tables --------------- */
    +.pricing-tbl{
    +	text-align:center;
    +}
    +.pricing-tbl ul{
    +	margin:auto;
    +	width:85%
    +}
    +.pricing-tbl ul li{
    +	padding:12px 0;
    +}
    +.pricing-tbl ul li:first-child{
    +	border-top-width:0
    +}
    +.pricing-tbl.style-1 ul li:first-child{
    +	border-top-width:1px
    +}
    +.pricing-tbl h3{
    +	padding:30px 0;
    +	font-size:17px;
    +	font-weight:bold;
    +	margin:0
    +}
    +.pricing-tbl .pricing-footer{
    +	padding:25px 0
    +}
    +.pricing-tbl .price-lg{
    +	font-size:28px;
    +}
    +.pricing-tbl .price_txt{
    +	padding:5px 0
    +}
    +.pricing-tbl .pricing-footer .btn{
    +	padding-right:30px;
    +	padding-left:30px;
    +	text-transform:none
    +}
    +
    +/* style 2 */
    +.pricing-tbl.style-2 ul,.pricing-tbl.style-4 ul{
    +	margin-top:10px
    +}
    +.pricing-tbl.style-2 h3{
    +	position:relative;
    +	text-transform:uppercase
    +}
    +.pricing-tbl.style-2 h3:before, .pricing-tbl.style-2 h3:after {
    +	content: "";
    +	position: absolute;
    +	width: 0;
    +	height: 0;
    +	border-style: solid;
    +	border-color: transparent;
    +	border-bottom: 0;
    +}
    +.pricing-tbl.style-2 h3:before {
    +	bottom: -7px;
    +	left: 50%;
    +	border-width: 6px;
    +	margin-left:-6px
    +}
    +.pricing-tbl.style-2 h3:after {
    +	bottom: -6px;
    +	left: 50%;
    +	border-width: 6px;
    +	margin-left:-6px
    +}
    +
    +/* style 3 */
    +.pricing-tbl.style-3 .price_txt{
    +	display:table;
    +	width:140px;
    +	height:140px;
    +	border-radius:50%;
    +	padding-top: 40px;
    +	margin:auto;
    +	text-align:center
    +}
    +.pricing-tbl.style-3 .price_txt span{
    +	display:block
    +}
    +.pricing-tbl.style-3 ul li:nth-child(2){
    +	border-top:0
    +}
    +.pricing-tbl.style-3:hover ul li,.pricing-tbl.style-3.selected ul li{
    +	color:#fff;
    +	border-color:rgba(255,255,255,0.2)
    +}
    +.pricing-tbl.style-3:hover h3,.pricing-tbl.style-3.selected h3{
    +	color:#fff
    +}
    +
    +/* style 4 */
    +.pricing-tbl.style-4.no-margin{
    +	margin: 0 -16px;
    +	position:relative;
    +	padding:0;
    +	z-index:1
    +}
    +.pricing-tbl.style-4 .plan-head{
    +	position:relative;
    +	text-transform:uppercase;
    +	padding-bottom: 30px;
    +	margin-bottom: 57px;
    +}
    +.pricing-tbl.style-4 .plan-head h3{
    +	position:relative;
    +	z-index:5
    +}
    +.pricing-tbl.style-4 .plan-head:before{
    +	width: 104px;
    +	height: 104px;
    +	text-align: center;
    +	position: absolute;
    +	left: 50%;
    +	margin-left: -52px;
    +	bottom: -52px;
    +	border-radius: 50%;
    +	z-index: 0;
    +	content: "";
    +	display: inline-block;
    +}
    +.pricing-tbl.style-4 .plan-head:after{
    +	width: 104px;
    +	height: 52px;
    +	text-align: center;
    +	position: absolute;
    +	left: 50%;
    +	margin-left: -52px;
    +	bottom: 0;
    +	z-index: 1;
    +	content: "";
    +	display: inline-block;
    +}
    +.pricing-tbl.style-4 .plan-head i{
    +	width:94px;
    +	height:94px;
    +	text-align:center;
    +	line-height:94px;
    +	position:absolute;
    +	left:50%;
    +	margin-left:-47px;
    +	bottom:-47px;
    +	border-radius:50%;
    +	font-size:25px;
    +	z-index:5
    +}
    +.pricing-tbl.style-4 ul{
    +	width:100%;
    +}
    +.pricing-tbl.style-4 ul li{
    +	border:0
    +}
    +.pricing-tbl.style-4.no-margin:hover{
    +	margin-top: -20px;
    +	z-index:3;
    +	padding:0 0 40px !important;
    +	-webkit-box-shadow: 0 0 20px -2px rgba(0,0,0,.25);
    +	box-shadow: 0 0 20px -2px rgba(0,0,0,.25);
    +}
    +.pricing-tbl.style-4.no-margin.selected{
    +	margin-top: -20px;
    +  	z-index:2;
    +	padding:0 0 40px !important;
    +	-webkit-box-shadow: 0 0 20px -2px rgba(0,0,0,.25);
    +	box-shadow: 0 0 20px -2px rgba(0,0,0,.25);
    +}
    +.pricing-tbl.style-4.selected .plan-head h3{
    +	color:#fff
    +}
    +
    +/*
    +------------- 6.11. Testimonials -------------- */
    +.testimonials-1 .testimonials-bg {
    +	position:relative;
    +	z-index:4;
    +	margin:10px 15px 5px 20px;
    +	padding:20px;
    +	border-radius: 15px;
    +	border-bottom-right-radius: 0;
    +}
    +.testimonials-1 .testimonials-bg:before,.testimonials-1 .testimonials-bg:after{
    +	position:absolute;
    +	content:"";
    +	display:inline-block;
    +	bottom:-3px;
    +	right:-3px;
    +	width:3px;
    +	height:50px;
    +}
    +.testimonials-1 .testimonials-bg:after{
    +	width:50px;
    +	height:3px
    +}
    +.testimonials-1 .testimonials-img {
    +	position:relative;
    +	z-index:2;
    +	left:-30px;
    +	top:-30px;
    +	width:70px;
    +	float:left
    +}
    +.testimonials-1 .testimonials-img img{
    +	max-width:70px
    +}
    +.testimonials-1 .testimonials-img:before,.testimonials-1 .testimonials-img:after{
    +	display:inline-block;
    +	content:"";
    +	position:absolute;
    +	top:0;
    +	right:-10px;
    +	width: 0;
    +	height: 0;
    +	border-style: solid;
    +	border-width: 10px 0 0 10px;
    +	border-color: transparent transparent transparent #007bff;
    +}
    +.testimonials-1 .testimonials-img:after{
    +	bottom:-10px;
    +	left:0;
    +	right:auto;
    +	top:auto;
    +	border-width: 0 10px 10px 0;
    +	border-color: transparent #007bff transparent transparent;
    +}
    +
    +.testo-pos{
    +	display:inline-block;
    +	padding:3px 5px;
    +	font-size:12px;
    +	clear:both;
    +	line-height:1
    +}
    +.testimonials-1 .testimonials-name {
    +	position: relative;
    +	left: -10px;
    +	top:-8px;
    +	line-height:1.8
    +}
    +.testimonials-1 p{
    +	margin:0 0 -10px;
    +	clear:both;
    +	position:relative;
    +	top:-10px
    +}
    +.testimonials-2 .testimonials-img {
    +	position:relative;
    +	z-index:2;
    +	margin:0 auto 20px;
    +	width:100px;
    +	overflow:hidden;
    +	padding:0;
    +}
    +.testimonials-2 .testimonials-img img{
    +	border-radius:50%;
    +	width:100px;
    +}
    +.testimonials-2 .testimonials-name {
    +	display:table;
    +	margin:20px auto 0;
    +	padding:7px;
    +	font-size:12px;
    +	line-height:1;
    +}
    +.testimonials-2 p {
    +	font-size:15px;
    +	width:65%;
    +	display:table;
    +	margin:15px auto 10px;
    +	text-align:center;
    +	position:relative;
    +}
    +.testimonials-2 p:before {
    +	position:absolute;
    +	content:"\f10d";
    +	font:normal normal normal 16px/1 fontAwesome;
    +	top:-7px;
    +	left:-14px;
    +}
    +.testimonials-2 p:after {
    +	position:absolute;
    +	content:"\f10e";
    +	font:normal normal normal 16px/1 fontAwesome;
    +	bottom:-7px;
    +	right:-14px;
    +}
    +.testimonials-3 {
    +	position:relative;
    +}
    +.testimonials-3 .testimonials-bg{
    +	padding:15px 20px;
    +	margin:0 15px 15px;
    +	border-bottom:3px #ddd solid;
    +	position:relative;
    +	overflow: hidden;
    +}
    +.testimonials-3 .testimonials-bg:after,.testimonials-3 .testimonials-bg:before,.testimonials-4 .testimonials-bg:before{
    +	display:inline-block;
    +	content:"";
    +	position:absolute;
    +	bottom: -15px;
    +	left:100px;
    +	width: 10px;
    +	height: 10px;
    +}
    +.testimonials-3 .testimonials-bg:before,.testimonials-4 .testimonials-bg:before{
    +	width: 0;
    +	height: 5px;
    +	bottom: -5px;
    +	left: 0;
    +	border-bottom-left-radius: 10px;
    +	border-bottom-right-radius: 10px;
    +}
    +.testimonials-3 .testimonials-name{
    +	padding:15px;
    +	margin:0 -20px -15px;
    +}
    +.testimonials-3 .testimonials-name{
    +	padding:15px;
    +	margin:0 -20px -15px;
    +}
    +.testimonials-3 .testimonials-name span.block{
    +	margin-bottom:-5px;
    +	font-size:12px
    +}
    +.testimonials-3 .testimonials-img{
    +	display:table;
    +	margin:auto !important;
    +	float:none !important
    +}
    +.testimonials-3 .tbl-cell {
    +	display:table-cell;
    +}
    +.testo-cell {
    +	display:table-cell;
    +}
    +.testimonials-bg p{
    +	margin-bottom:0
    +}
    +.testimonials-4 .testimonials-bg {
    +	position:relative;
    +	padding: 20px 20px 30px;
    +	margin: 0 15px 10px;
    +}
    +.testimonials-4 .testimonials-img, .testimonials-3 .testimonials-img {
    +	width:70px;
    +	float:left;
    +	margin:0 15px 0 0;
    +}
    +.testimonials-4 .testimonials-img{
    +	margin-left: 30px;
    +	margin-top: -30px;
    +	position:relative
    +}
    +.testimonials-4 .testimonials-img, .testimonials-3 .testimonials-img{
    +	border-width:0;
    +	border-bottom-width:3px;
    +	padding-bottom:4px;
    +	border-radius:50%
    +}
    +.testimonials-4 .testimonials-img img, .testimonials-3 .testimonials-img img{
    +	border-radius:50%
    +}
    +
    +.testimonials-4 .testimonials-name {
    +	padding:10px;
    +	float:left;
    +	margin-top: -5px;
    +}
    +.testimonials-4 .testimonials-bg:after{
    +	left: 76px;
    +}
    +/* Style 5 */
    +.testimonials-5{position:relative;}
    +.testimonials-5 [class*="col-md-"], .clients-grid1 [class*="col-md-"], .clients-grid2 [class*="col-md-"], .clients-grid3 [class*="col-md-"] {
    +	padding-top:25px;
    +	padding-bottom:10px;
    +	border-style:dashed;
    +	border-width:0;
    +	border-bottom-width:1px;
    +	border-right-width:1px;
    +}
    +.testimonials-5 [class*="col-md-"]:first-child, .clients-grid1 [class*="col-md-"]:first-child, .clients-grid2 [class*="col-md-"]:first-child, .clients-grid3 [class*="col-md-"]:first-child {
    +	border-left-width:1px;
    +}
    +.testimonials-5 .row:first-child [class*="col-md-"], .clients-grid1 .row:first-child [class*="col-md-"], .clients-grid2 .row:first-child [class*="col-md-"], .clients-grid3 .row:first-child [class*="col-md-"]{
    +	border-top-width:1px;
    +}
    +.normal-testimonials .testimonials-img img{
    +	width:70px;
    +	float:left;
    +	border-radius:50%
    +}
    +.normal-testimonials .testimonials-name,.normal-testimonials p{
    +	margin-left:85px;
    +}
    +
    +.testimonials-5 .testimonials-name {
    +	margin:0;
    +	text-align:center;
    +	padding:15px 0 ;
    +}
    +.testimonials-5 .testimonials-name:before {
    +	display:none;
    +}
    +.testimonials-5 .testimonials-img {
    +	margin-right:20px;
    +	margin-bottom:0;
    +	width:70px;
    +	float:left;
    +}
    +.testimonials-5 .testimonials-img img {
    +	overflow:hidden;
    +	padding:2px;
    +	border-width:1px;
    +	border-style:solid;
    +	width:70px;
    +}
    +.testimonials-5 .testimonials-name:after {
    +	display:none;
    +}
    +.testimonials-5 .testo-name {
    +	padding:8px 0 0;
    +	text-transform:uppercase;
    +	letter-spacing:1px;
    +}
    +.testimonials blockquote p{
    +	font-size: 13px;
    +	line-height: 1.7;
    +	padding-top:15px
    +}
    +.testimonials blockquote span{
    +	font-size: 13px;
    +	padding:20px 0 0
    +}
    +.testimonials blockquote .testimonials-img{
    +	display:table;
    +	margin:15px auto 0;
    +}
    +.testimonials blockquote .testimonials-img img{
    +	width:70px;
    +	border-radius:50%
    +}
    +
    +/*
    +----------- Fun Staff ----------- */
    +.fun{
    +	padding:20px
    +}
    +.fun-number{
    +	margin:5px 0;
    +	font-size:35px;
    +	white-space: nowrap;
    +}
    +.fun-info{
    +	font-size:17px;
    +	white-space: nowrap;
    +}
    +.fun-icon{
    +	display:table;
    +	margin: 0 auto 20px;
    +	position:relative;
    +	font-size:35px;
    +	text-align:center;
    +}
    +.fun-icon.round{
    +	border-radius: 2em;
    +}
    +.fun-icon.lg-icon i:before{
    +	top: -2px;
    +	position:relative
    +}
    +.fun-icon.lg-icon i{
    +	font-size:35px;
    +}
    +.c-chart[data-type=half] .circle-text-half{
    +	margin-top:-10px
    +}
    +.c-chart[data-type=half] .circle-info-half{
    +	margin-top:2px
    +}
    +
    +/*
    +---------- features ------------- */
    +.feature-img{
    +	overflow:hidden
    +}
    +.feature-img figure {
    +	position:relative;
    +	overflow:hidden;
    +	text-align:center;
    +}
    +.feature-img figure a {
    +	font-weight:700;
    +	font-size: 35px;
    +	text-align:center;
    +	line-height: 43px;
    +	z-index:5;
    +	background:#fff;
    +	position:absolute;
    +	content:"";
    +	display:inline-block;
    +	right: 10px;
    +	bottom:0;
    +	width: 35px;
    +	height: 35px;
    +}
    +.feature-img figure a span {
    +	position:relative;
    +	z-index:3;
    +}
    +.feature-details-hidden{
    +	position:absolute;
    +	bottom:0;
    +	width:80%;
    +	left:10%;
    +	z-index:999;
    +	color:#fff;
    +	opacity:0
    +}
    +.feature-details2 h4{
    +	margin-bottom:15px
    +}
    +.feature-img:hover .feature-details-hidden{
    +	bottom:50px;
    +	opacity:1
    +}
    +.feature-img .feature-details-hidden .feature-head{
    +	padding-bottom:0;
    +	margin-bottom:10px
    +}
    +.feature-img figure:before {
    +	width:100%;
    +	height:100%;
    +	position:absolute;
    +	left:0;
    +	top:0;
    +	content:"";
    +	display:inline-block;
    +}
    +.feature-img figure img{
    +	-moz-transition: all 0.9s ease;
    +	-ms-transition: all 0.9s ease;
    +	-o-transition: all 0.9s ease;
    +	-webkit-transition: all 0.9s ease;
    +	transition: all 2s ease;
    +}
    +.feature-img:hover figure img{
    +	transform:scale(1.5);
    +	-webkit-transform:scale(2);
    +}
    +.feature-img:hover figure:before {
    +	border-style:solid;
    +	border-width:5px;
    +	background:rgba(0,0,0,.5);
    +	z-index:3;
    +}
    +.feature-details {
    +	padding:20px 0 15px;
    +}
    +.feature-details .feature-head {
    +	margin-bottom:10px;
    +	text-transform:uppercase
    +}
    +.feature-img:hover .feature-details {
    +	background:#444;
    +	color:#fff;
    +	padding:20px 15px 15px;
    +}
    +.feature-img .no-hover{
    +	background:transparent !important;
    +	color:inherit !important;
    +	padding:20px 0 15px !important
    +}
    +.feature-img:hover .no-hover h5{
    +	color:inherit !important;
    +}
    +.feature-img .feature-details p{
    +	margin-bottom:0
    +}
    +.feature-img:hover .feature-head, .feature-img:hover figure a {
    +	color:#fff;
    +}
    +.feature-img:hover figure a{
    +	height:50px;
    +	line-height:52px
    +}
    +/* feature 2 */
    +.feature-img2 figure{
    +	position:relative;
    +	margin-bottom:20px;
    +	overflow:hidden
    +}
    +.feature-img2 figure:after{
    +	position:absolute;
    +	left:0;
    +	top:0;
    +	width:100%;
    +	height:100%;
    +	background:rgba(0,0,0,.5);
    +	content:"";
    +	display:inline-block;
    +	z-index:1;
    +	opacity:0
    +}
    +.feature-img2:hover figure:after{
    +	opacity:1
    +}
    +.feature-img2 figure a{
    +	position:absolute;
    +	right:50%;
    +	bottom:50%;
    +	margin-right: -25px;
    +	margin-bottom: -25px;
    +	width: 50px;
    +	height: 50px;
    +	text-align:center;
    +	line-height: 50px;
    +	z-index:2;
    +	-webkit-transform:scale(7);
    +	transform:scale(7);
    +	opacity:0
    +}
    +.feature-img2 figure a span{
    +	font-size:35px
    +}
    +.feature-img2:hover figure a{
    +	-webkit-transform:scale(1);
    +	transform:scale(1);
    +	opacity:1;
    +}
    +/*
    +------------- 6.12. Pagination ---------------- */
    +.pagination{
    +	clear:both;
    +	padding-top:20px;
    +	display:table;
    +	margin:auto;
    +	position:relative
    +}
    +.pagination ul li{
    +	float:left;
    +	margin:0 0 0 3px;
    +}
    +.pagination ul li:first-child{
    +	margin-left: 2px
    +}
    +.pagination ul li a{
    +	display:block;
    +	width:40px;
    +	text-align:center;
    +	height:40px;
    +	line-height:40px
    +}
    +
    +/* diamond */
    +.pagination.diamond-pager li{
    +	transform:rotate(-45deg);
    +	margin: 0 8px
    +}
    +.pagination.diamond-pager li a{
    +	transform:rotate(45deg);
    +	width:35px;
    +	height:35px;
    +	line-height:35px
    +}
    +
    +/* circle */
    +.pagination.circle-pager ul li{
    +	border-radius:50%
    +}
    +
    +/* bottom border */
    +.pagination.bottom-border ul li{
    +	margin:0 0 0 1px;
    +	border-radius:0px;
    +	border:0;
    +}
    +.pagination.bottom-border ul li a{
    +	width:50px;
    +	height:50px;
    +	line-height:50px
    +}
    +.pagination.bottom-border ul li:hover a{
    +	color:#fff
    +}
    +
    +/* bar-1 */
    +.pagination.bar-1 ul,.pagination.bar-2 ul{
    +	border-radius:20em;
    +	overflow:hidden;
    +}
    +.pagination.bar-1 ul li{
    +	border-radius:0px;
    +	border:0;
    +	background:transparent;
    +	margin:0
    +}
    +.pagination.bar-1 ul li:first-child{
    +	border:0
    +}
    +.pagination.bar-1 ul li a{
    +	font-size:15px;
    +	font-weight:bold;
    +	width:50px;
    +	height:50px;
    +	line-height:50px;
    +}
    +.pagination.bar-2 ul{
    +	-webkit-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.1);
    +	-moz-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.1);
    +	box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.1);
    +}
    +.pagination.bar-2 ul li{
    +	border:0;
    +	background:transparent;
    +}
    +.pagination.bar-2 ul li a{
    +	font-size:15px;
    +	font-weight:bold;
    +	width:auto;
    +	height:40px;
    +	line-height:40px;
    +	min-width:40px
    +}
    +.pagination.bar-2 ul li a.main-bg {
    +	color:#fff;
    +	font-size:12px;
    +	padding-left:10px;
    +	padding-right:10px;
    +	font-weight:normal
    +}
    +.pagination.bar-2 ul li a.main-bg i.fa-chevron-left{
    +	margin:0 5px 0 0
    +}
    +.pagination.bar-2 ul li a.main-bg i.fa-chevron-right{
    +	margin:0 0 0 5px
    +}
    +.pagination.bar-2 ul li:hover a,.pagination.bar-2 ul li.selected a{
    +	color:#fff
    +}
    +
    +/* bar 3 */
    +.pagination.bar-3 ul li:not(.next_page):not(.prev_page):not(.selected) {
    +	background:transparent;
    +	border:0;
    +	position:relative;
    +	margin:0
    +}
    +.pagination.bar-3 ul li a{
    +	font-size:15px;
    +	font-weight:bold;
    +	line-height:35px
    +}
    +.pagination.bar-3 ul li.selected a{
    +	color:#fff;
    +}
    +.pagination.bar-3 ul li.next_page a,.pagination.bar-3 ul li.prev_page a{
    +	height: 33px;
    +	line-height: 37px;
    +}
    +.pagination.bar-3 ul{
    +	overflow:hidden
    +}
    +.pagination.bar-3 ul:after{
    +	position: absolute;
    +	left: 0;
    +	bottom: -8px;
    +	width: 130%;
    +	height: 11px;
    +	border-radius: 20em;
    +	content: "";
    +	display: inline-block;
    +	margin-left: -55px;
    +	z-index:1
    +}
    +.pager-slider{
    +	position: absolute;
    +	left: 0;
    +	bottom: -5px;
    +	height: 5px;
    +	border-radius: 20em;
    +	content: "";
    +	display: inline-block;
    +	margin-left: -50px;
    +	z-index: 2;
    +	width:0
    +}
    +
    +
    +/* ---- 6.13. Message boxes -------------- */
    +.msg-box {
    +	position: relative;
    +	margin: 0 auto 15px;
    +	padding: 15px;
    +	border-width: 1px;
    +	border-style: solid;
    +}
    +.msg-box i,.msg-box .ico {
    +	color: #111;
    +	position:absolute;
    +	left:25px;
    +	top:50%;
    +	margin-top:-10px;
    +	font-size:16px
    +}
    +.msg-box h4 {
    +	margin-bottom: 0px;
    +	font-weight: bold;
    +	font-size: 15px;
    +}
    +.msg-box p {
    +	margin: 5px 0 0;
    +	padding-bottom: 0;
    +}
    +.warning-box {
    +	border-color: #e0d594;
    +	background: #fff6bf;
    +}
    +.info-box {
    +	border-color: #9fc6d7;
    +	background: #c2e1ee;
    +}
    +.success-box {
    +	border-color: #a0c272;
    +	background: #bbdd8c;
    +}
    +.error-box {
    +	border-color: #f2b1b4;
    +	background: #f1d5d6;
    +}
    +.rounded{
    +	border-radius:5px
    +}
    +.round{
    + border-radius:50em
    +
    +}
    +.msg-box.round{
    +	padding:20px 40px
    +}
    +.msg-box.outlined{
    +	background-color:transparent;
    +	border-width:2px
    +}
    +.msg-box.with-icon{
    +	padding-left:60px
    +}
    +
    +/* ==========================================================================
    +  7. PAGE SPECIFIC STYLES.
    +============================================================================= */
    +/*
    +---------------- Widgets -------------------- */
    +.sidebar_widgets .widget-head{
    +	font-size: 14px;
    +	margin-bottom: 15px;
    +	padding-bottom: 10px;
    +	text-transform:uppercase;
    +	position:relative
    +}
    +.sidebar_widgets .widget-content{
    +	overflow:hidden;
    +}
    +.sidebar_widgets li.widget{
    +	margin-bottom: 40px;
    +	border-bottom: 1px #ddd solid;
    +	padding: 15px;
    +	-webkit-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.2);
    +	-moz-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.2);
    +	box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.2);
    +	position:relative;
    +}
    +.sidebar_widgets li.widget:before,.sidebar_widgets li.widget:after,.sidebar_widgets .widget-head:after{
    +	position:absolute;
    +	bottom:-3px;
    +	left: 5%;
    +	width: 90%;
    +	height:1px;
    +	content:"";
    +	display:inline-block;
    +}
    +.sidebar_widgets li.widget:after{
    +	bottom:-5px;
    +	left: 10%;
    +	width: 80%;
    +}
    +.sidebar_widgets .widget-head:after{
    +	bottom:-1px;
    +	left:0;
    +	width:20%;
    +}
    +.sidebar_widgets h5{
    +	font-size:13px;
    +	margin-bottom:10px;
    +	font-weight:normal
    +}
    +.sidebar_widgets .meta{
    +	font-size:11px;
    +	margin-bottom: 5px;
    +}
    +.sidebar_widgets .tab-content .tab-pane{
    +	padding:15px
    +}
    +/* search */
    +.search-widget .txt-box{
    +	height:40px;
    +	padding:0 35px 0 10px;
    +	width:100%;
    +	border:0;
    +	background:transparent
    +}
    +.search-widget .widget-content{
    +	position:relative;
    +}
    +.search-widget button{
    +	background:transparent;
    +	border:0;
    +	position:absolute;
    +	right:5px;
    +	top:10px
    +}
    +
    +.sidebar_widgets ul.flickr-widget li img, .sidebar_widgets ul.flickr-widget .img-overlay {
    +	width: 56px;
    +	height: 56px;
    +}
    +.sidebar_widgets ul.flickr-widget .img-overlay:before {
    +	line-height: 56px;
    +	height: 56px
    +}
    +.sidebar_widgets ul.flickr-widget .flickr{
    +	height:56px;
    +}
    +
    +/* recent posts */
    +.w-recent-posts > ul > li, .w-recent-comments ul li {
    +	padding: 8px 0;
    +}
    +.widget-categories ul li {
    +	padding: 10px 0;
    +}
    +.w-recent-posts > ul > li:first-child, .widget-categories ul li:first-child, .w-recent-comments ul li:first-child {
    +	border-top: 0px;
    +}
    +.w-recent-posts .post-img {
    +	float: left;
    +	margin-right: 10px;
    +	max-height: 55px;
    +	overflow:hidden
    +}
    +.w-recent-posts .post-img img {
    +	padding: 1px;
    +	width: 55px;
    +}
    +.w-recent-posts .meta span {
    +	display: inline-block;
    +	margin-right: 10px;
    +}
    +.w-recent-posts .meta i {
    +	margin: 0 5px 0 0;
    +}
    +.w-recent-posts li{
    +	padding:10px 0
    +}
    +.w-recent-posts li:first-child{
    +	border-top:0px
    +}
    +.sale-widget .meta span{
    +	margin-right:2px !important
    +}
    +.widget-content .accordion{
    +	margin:10px auto
    +}
    +.widget-categories li span{
    +	float:right
    +}
    +/* recent comments widget */
    +.w-recent-comments i {
    +	margin-right: 10px;
    +	font-size: 40px;
    +}
    +.w-recent-comments i.fa.fa-clock-o {
    +	font-size: 16px;
    +	vertical-align:middle
    +}
    +.w-recent-comments h5 {
    +	margin: 10px 0 5px;
    +	font-size:12px;
    +	width:70%;
    +	overflow:hidden;
    +	white-space:nowrap;
    +	text-overflow: ellipsis;
    +}
    +
    +/* Tag cloud */
    +.tags-widget {
    +	overflow: hidden;
    +}
    +.tags-widget .tags a {
    +	display: block;
    +	float: left;
    +	margin: 0 2px 4px;
    +	padding: 0 10px;
    +	font-size: 12px;
    +	line-height:30px;
    +	text-transform:uppercase
    +
    +}
    +.main-bg .tags-widget .tags a {
    +	background-color:rgba(0,0,0,.1);
    +	color:#fff
    +}
    +.widget-content .tags {
    +	overflow: hidden;
    +}
    +
    +/* tabs widget */
    +.sidebar_widgets .nav-tabs>li>a{
    +	padding:12px 15px;
    +}
    +.sidebar_widgets .tabs nav li.active a:before {
    +	bottom: -2px;
    +}
    +.sidebar_widgets .tab-content{
    +	margin-bottom:50px;
    +	border-bottom-left-radius: 1em;
    +	border-bottom-right-radius: 1em;
    +	border-top-right-radius: 1em;
    +}
    +.tab-content.main-bg h5,.tab-content.main-bg .w-recent-comments i,.tab-content.main-bg a:hover{
    +	color:#fff
    +}
    +.tab-content.main-bg .w-recent-posts > ul > li, .tab-content.main-bg .w-recent-comments ul li{
    +	border-color:rgba(0,0,0,.1)
    +}
    +/* custom menu */
    +.widget.custom-menu-widget ul li{
    +	padding: 10px 10px 10px 30px;
    +	position: relative;
    +}
    +.widget.custom-menu-widget ul li:first-child{
    +	border-top:0px
    +}
    +.widget.custom-menu-widget ul li:before{
    +	position:absolute;
    +	content: "\f192";
    +	display: inline-block;
    +	font: normal normal normal 11px/1 FontAwesome;
    +	position: absolute;
    +	left: 7px;
    +	top: 15px;
    +}
    +.widget.custom-menu-widget ul li.selected{
    +	font-weight:bold
    +}
    +.widget.custom-menu-widget ul li.selected:before{
    +	content:"\f061"
    +}
    +
    +/*
    +------------- login-1 ---------------- */
    +.login-1{
    +	background:#14191e url('../images/login-bg.jpg') no-repeat 0 0;
    +	background-size:cover;
    +}
    +.login-box-lg{
    +	max-width:500px;
    +	margin:auto;
    +}
    +.logo.light a{
    +	color:#fff
    +}
    +.login-head{
    +	color:#fff;
    +	font-size:25px;
    +	font-weight:bold;
    +	text-transform:uppercase;
    +}
    +.login-box-lg .login-inner{
    +	margin-top:5px;
    +	padding:40px 50px;
    +	text-align:center;
    +	position:relative
    +}
    +.login-box-lg .login-inner:after{
    +	position:absolute;
    +	right: 0;
    +	bottom:-5px;
    +	width: 98%;
    +	height:3px;
    +	content:"";
    +	display:inline-block;
    +}
    +.login-2 .login-box-lg .login-inner:after{
    +	display:none
    +}
    +.login-2 .login-box-lg .login-inner{/* border-radius:5px
    + */
    +}
    +.login-inner h4.intro{
    +	margin-bottom:20px;
    +	font-size:17px
    +}
    +.login-inner .form-input{
    +	padding: 10px 0;
    +	position:relative
    +}
    +.login-inner label{
    +	display:block;
    +	float:left;
    +	font-weight:bold;
    +	text-transform:uppercase;
    +	letter-spacing:1px;
    +	padding-bottom:3px
    +}
    +.login-inner .button-group{
    +	padding-top:0;
    +	float:left
    +}
    +.login-inner .form-input span{
    +	position:absolute;
    +	left:15px;
    +	top: 56px;
    +}
    +.login-inner .form-input .form-control{
    +	padding: 15px 15px 15px 35px;
    +}
    +.login-inner .login-links{
    +	line-height:1.8;
    +	padding-top: 17px;
    +}
    +.login-form{
    +	overflow:hidden;
    +}
    +.social-login .btn{
    +	font-size:13px;
    +	padding:0 30px;
    +	margin:0 6px
    +}
    +.login-box-lg .copyrights{
    +	text-align:center;
    +	padding-top:15px;
    +	font-size:14px
    +}
    +
    +/*
    +-------------- coming soon --------------- */
    +.soon-page{
    +	background:#14191e url('../images/soon-bg.jpg') no-repeat 0 0;
    +	background-size:cover;
    +}
    +.soon-page .pageWrapper {
    +	padding-top:80px
    +}
    +.soon-logo{
    +	display:table;
    +	padding:15px 30px;
    +	border:2px #fff solid;
    +	margin:auto;
    +}
    +.soon-logo a{
    +	color:#fff
    +}
    +.soon-lg-head{
    +	font-size:65px;
    +	padding:0;
    +	padding-top:40px;
    +	margin:0
    +}
    +.soon-heading h2{
    +	font-size:29px;
    +	margin:0;
    +	padding:0;
    +	letter-spacing:1px
    +}
    +.soon-heading h3{
    +	font-size:24px;
    +	font-weight:300;
    +	margin:0;
    +	padding:0;
    +	letter-spacing:1px
    +}
    +.soon-form{
    +	width:60%;
    +	margin:50px auto 25px;
    +	position:relative
    +}
    +.soon-form:before{
    +	position: absolute;
    +	content: "\f0e0";
    +	display: inline-block;
    +	font: normal normal normal 19px/1 FontAwesome;
    +	position: absolute;
    +	left: 8.4%;
    +	top: 20px;
    +}
    +.soon-form input[type=text]{
    +	width: 70%;
    +	height: 60px;
    +	margin: 0px -7px 0 0;
    +	padding-left:50px;
    +	font-size: 17px;
    +	padding-right: 26px;
    +	vertical-align: middle;
    +}
    +.btn-soon{
    +	margin-left: -20px;
    +}
    +#holder {
    +	margin: auto;
    +	display:table
    +}
    +.digits {
    +	margin:60px auto 0;
    +	display:table
    +}
    +.digits span{
    +	display: block;
    +	text-align: center;
    +	position: relative;
    +	height: 130px;
    +	width:130px;
    +	line-height:120px;
    +	border: 1px #fff solid;
    +	border-bottom:0;
    +	font-size:55px;
    +	font-weight:800;
    +	color:#fff;
    +}
    +.digits li{
    +	float:left;
    +	margin:0 15px;
    +	text-align:center;
    +	position:relative
    +}
    +.digits li:before,.digits li:after{
    +	content: "";
    +	position: absolute;
    +	top: 130px;
    +	left: 0px;
    +	display: block;
    +	width: 57px;
    +	background: #fff;
    +	height:1px
    +}
    +.digits li:after{
    +	right: 0;
    +	left:auto
    +}
    +.digits span:after {
    +	content: "";
    +	position: absolute;
    +	bottom: -5px;
    +	left: 50%;
    +	margin-left:-10px;
    +	display: block;
    +	background: #fff;
    +	height:1px;
    +	width:12px;
    +	-webkit-transform: rotate(45deg);
    +	-moz-transform: rotate(45deg);
    +	-o-transform: rotate(45deg);
    +	-ms-transform: rotate(45deg);
    +	transform: rotate(45deg);
    +}
    +.digits span:before {
    +	content: "";
    +	position: absolute;
    +	bottom: -5px;
    +	right: 50%;
    +	margin-right:-10px;
    +	display: block;
    +	background: #fff;
    +	height:1px;
    +	width:12px;
    +	-webkit-transform: rotate(-45deg);
    +	-moz-transform: rotate(-45deg);
    +	-o-transform: rotate(-45deg);
    +	-ms-transform: rotate(-45deg);
    +	transform: rotate(-45deg);
    +}
    +
    +.digits li p{
    +	color:#fff;
    +	font-size:20px;
    +	padding-top:30px
    +}
    +
    +/*
    +-------------- 404 not found -------------- */
    +.not-found{
    +	max-width:730px;
    +	margin:auto
    +}
    +.lg-not-found{
    +	font-size:190px;
    +	font-weight:bold;
    +	line-height: 110px;
    +	margin-right:20px;
    +	position:relative
    +}
    +.lg-not-found i{
    +	position: absolute;
    +	width: 93px;
    +	height: 11px;
    +	overflow: hidden;
    +	bottom: -35px;
    +	left: 50%;
    +	margin-left: -47px;
    +}
    +.lg-not-found i:after{
    +	position: absolute;
    +	width: 93px;
    +	height: 93px;
    +	border-radius: 50%;
    +	content: "";
    +	display: inline-block;
    +}
    +.pg-nt-fnd{
    +	font-size:26px;
    +	line-height:32px;
    +}
    +.ops{
    +	padding-bottom:90px
    +}
    +.not-found-form{
    +	width: 80%;
    +	margin:20px auto 60px;
    +	position:relative;
    +}
    +.not-found-form:before{
    +	position: absolute;
    +	content: "\f002";
    +	display: inline-block;
    +	font: normal normal normal 20px/1 FontAwesome;
    +	position: absolute;
    +	left: 15px;
    +	top: 19px;
    +}
    +.not-found-form input[type=text]{
    +	width: 80%;
    +	height: 60px;
    +	margin: 0px -7px 0 0;
    +	padding-left: 50px;
    +	font-size: 17px;
    +	padding-right: 26px;
    +	vertical-align: middle;
    +}
    +.not-found p{
    +	font-size:17px
    +}
    +
    +/*
    +--------------- portfolio -------------- */
    +.filter-by{
    +	margin: 0 5px 50px;
    +	clear:both;
    +	position:relative
    +}
    +.portfolio-filter-bg{
    +	margin-bottom: 0;
    +}
    +.portfolio-filter-bg .filter-by{
    +	margin:0;
    +	border-bottom:0
    +}
    +.portfolio-filter-bg .filter-by ul li{
    +	margin:0;
    +	border-bottom:0
    +}
    +.portfolio-filter-bg .filter-by ul li:before{
    +	display:none
    +}
    +.portfolio-filter-bg .filter-by ul li a{
    +	padding:30px;
    +	border-radius: 0;
    +	border:0
    +}
    +.portfolio-filter-bg .filter-by ul li:after {
    +	border-radius: 0;
    +}
    +.filter-by:after{
    +	clear:both;
    +	display:table;
    +	content:"";
    +}
    +.filter-by > span{
    +	padding: 10px 20px;
    +	font-weight:bold;
    +	margin-right:20px;
    +	text-transform:uppercase;
    +	display:table;
    +	position:relative;
    +}
    +.filter-by ul{
    +	display:table;
    +	margin:auto;
    +}
    +.filter-by.style-2 ul,.filter-by.style-3 ul{
    +	margin:0 15px;
    +	float: left
    +}
    +.filter-by ul li{
    +	float: left;
    +	position:relative;
    +	margin: 0 10px;
    +	border-bottom: 2px #e6e6e6 solid;
    +}
    +.filter-by ul li a{
    +	display:block;
    +	padding: 7px 20px;
    +	position:relative;
    +	font-weight:bold;
    +	text-transform:uppercase;
    +	z-index:3;
    +}
    +.filter-by ul li:before{
    +	position:absolute;
    +	width: 20px;
    +	height: 1px;
    +	content:"";
    +	left: -20px;
    +	top: 20px;
    +	display:inline-block;
    +	z-index:0;
    +	background-color: #E0E0E0;
    +	border-radius: 50%;
    +}
    +.filter-by ul li:after{
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	content:"";
    +	left:0;
    +	bottom:0;
    +	display:inline-block;
    +	opacity:0;
    +	-webkit-transition: transform 0.3s, background-color 0.3s, opacity  0.3s;
    +	transition: transform 0.3s, background-color 0.3s, opacity  0.3s;
    +	-webkit-transform: perspective(900px) rotate3d(1,0,0,90deg);
    +	transform: perspective(900px) rotate3d(1,0,0,90deg);
    +	-webkit-transform-origin: 50% 100%;
    +	transform-origin: 50% 100%;
    +	-webkit-perspective-origin: 50% 100%;
    +	perspective-origin: 50% 100%;
    +	z-index:1;
    +}
    +.filter-by ul li:first-child:before{
    +	display:none
    +}
    +.filter-by ul li.active:after{
    +	display:none
    +}
    +.filter-by ul li:hover:after,.filter-by ul li.active:after{
    +	-webkit-transform: perspective(900px) rotate3d(1,0,0,0deg);
    +	transform: perspective(900px) rotate3d(1,0,0,0deg);
    +	opacity:1;
    +}
    +.filter-by ul li a:hover,.filter-by:not(.style-2):not(.style-3) ul li.active a{
    +	color:#fff
    +}
    +.filter-by.style-2 ul li.active:after,.filter-by.style-3 ul li.active:after{
    +	top:auto;
    +	bottom:-4px
    +}
    +.filter-by ul li.active a:after{
    +	display: inline-block;
    +	position: absolute;
    +	bottom: -6px;
    +	left: 50%;
    +	width: 0;
    +	height: 0;
    +	/* content: ""; */
    +	border-style: solid;
    +	border-width: 6px 6px 0 6px;
    +	border-color: #ddd transparent transparent transparent;
    +	margin-left:-6px
    +}
    +
    +/* style 3 */
    +.filter-by.style-3{
    +	display:table;
    +	margin:0 auto 30px;
    +	padding:0;
    +	overflow:visible;
    +	-webkit-box-shadow: 0px 0px 14px rgba(0, 0, 0, 0.1);
    +	box-shadow: 0px 0px 14px rgba(0, 0, 0, 0.1);
    +	border-bottom:0
    +}
    +.filter-by.style-3 > span{
    +	padding:12px 15px;
    +	font-weight:bold;
    +	text-transform:uppercase;
    +	margin:0
    +}
    +.filter-by.style-3 ul{
    +	margin:0
    +}
    +.filter-by.style-3 ul li{
    +	margin:0;
    +	padding:0
    +}
    +.filter-by.style-3 ul li a{
    +	padding:12px 20px;
    +	border-bottom:0 !important;
    +	border-top:0 !important;
    +	border-right:0 !important;
    +}
    +.filter-by.style-2 ul li a:after,.filter-by.style-3 ul li a:before,.filter-by.style-2 ul li a:before,.filter-by.style-3 ul li a:after{
    +	display:none
    +}
    +.img-holder {
    +	position: relative;
    +	overflow: hidden;
    +	margin: 0;
    +	cursor: pointer;
    +}
    +.img-holder:hover img {
    +	-moz-transform: scale(1.3);
    +	-ms-transform: scale(1.3);
    +	-o-transform: scale(1.3);
    +	-webkit-transform: scale(1.3);
    +	transform: scale(1.3);
    +}
    +.img-over {
    +	position: absolute;
    +	left: 0;
    +	top:0;
    +	z-index: 9;
    +	opacity:0;
    +	overflow: hidden;
    +	width: 100%;
    +	height: 100%;
    +	background:rgba(0,0,0,.75);
    +}
    +.img-holder:hover .img-over{
    +	opacity:1;
    +}
    +.img-over .link,.img-over .zoom{
    +	position:absolute;
    +	bottom:40%;
    +	opacity:0;
    +	font-size:13px;
    +	color:#fff;
    +	display:block;
    +	width:35px;
    +	height:35px;
    +	line-height:35px;
    +	text-align:center;
    +	margin-bottom:-20px
    +}
    +.img-over .link i,.img-over .zoom i{
    +	display:block;
    +	width:35px;
    +	height:35px;
    +	line-height:35px;
    +	text-align:center
    +}
    +
    +.img-holder:hover .link,.img-holder:hover .zoom{
    +	opacity:1;
    +	bottom:50%
    +}
    +.name-holder {
    +	padding:15px 10px
    +}
    +.name-holder h4 {
    +	font-size:15px;
    +	font-weight:bold;
    +	margin:0;
    +	padding:0
    +}
    +
    +.name-holder h5{
    +	margin:0;
    +	padding:0;
    +}
    +.name-holder h5 a{
    +	font-size:13px;
    +}
    +.img-over .link{
    +	left:50%;
    +	margin-left:-45px;
    +	transition-delay: .2s;
    +}
    +.img-over .zoom{
    +	right:50%;
    +	margin-right:-45px;
    +	transition-delay: .3s;
    +}
    +
    +/* columns */
    +.p-1-col .portfolio-item{
    +	width:100%;
    +	margin:0 0 25px 0;
    +	padding-bottom:25px;
    +}
    +.p-1-col .img-holder{
    +	float:left;
    +	margin-right:20px;
    +}
    +.p-1-col .name-holder{
    +	padding:0
    +}
    +.p-1-col .name-holder h4{
    +	font-size:18px;
    +	margin-bottom:10px
    +}
    +.p-1-col .name-holder .list li{
    +	line-height:30px
    +}
    +
    +.p-2-cols .portfolio-item{
    +	width:49%;
    +	margin:0 0.5% 1%;
    +}
    +.p-2-cols .img-holder img{
    +	width:100%;
    +}
    +.masonry.p-2-cols .img-holder img{
    +	height:auto;
    +	max-width: none;
    +}
    +.p-2-cols.no-margin .portfolio-item{
    +	width:50%;
    +	margin-right:0
    +}
    +.p-3-cols .portfolio-item{
    +	width:32.33333333%;
    +	margin: 0 0.5% 1%;
    +}
    +.p-3-cols .img-holder{
    +	width: 100%;
    +}
    +.p-3-cols .img-holder img{
    +	width:100%;
    +}
    +.p-3-cols.no-margin .portfolio-item{
    +	width:33.33333333%;
    +	margin:0 !important
    +}
    +.p-3-cols.no-margin .img-holder{
    +	width: 100%;
    +}
    +.p-3-cols.no-margin .img-holder img{
    +	width:100%;
    +}
    +.p-3-cols.full.no-margin .portfolio-item{
    +	width:33.333333%;
    +	margin:0 0 15px;
    +}
    +
    +.p-4-cols .portfolio-item{
    +	width:24%;
    +	margin:0 0.5% 30px;
    +}
    +.p-4-cols.no-margin .portfolio-item{
    +	width:25%;
    +	margin:0 !important
    +}
    +.p-4-cols .img-holder img{
    +	width:100%;
    +}
    +.portfolio.no-margin .img-holder{
    +	width: 100%;
    +}
    +.portfolio.no-margin .img-holder img{
    +	width:100%;
    +	height:auto
    +}
    +
    +/* simple */
    +.simple .img-over .link, .simple .img-over .zoom{
    +	width: 50px;
    +	height: 50px;
    +	margin-left:-55px;
    +	border:1px #999 solid;
    +}
    +.simple .img-over .zoom{
    +	margin-right:-55px;
    +	margin-left:0
    +}
    +.simple .img-over .link i,.simple .img-over .zoom i{
    +
    +	width: 50px;
    +	height: 50px;
    +	line-height: 50px;
    +}
    +
    +
    +/* style 2 */
    +.p-style2 figure{
    +	width:100%;
    +	position:relative;
    +	overflow:hidden;
    +}
    +.no-margin.portfolio .portfolio-item{
    +	margin:0
    +}
    +.p-style2 figure img{
    +	position: relative;
    +	width:100%;
    +	z-index:1;
    +	-moz-transition: all 0.4s ease 0s;
    +	-ms-transition: all 0.4s ease 0s;
    +	-o-transition: all 0.4s ease 0s;
    +	-webkit-transition: all 0.4s ease 0s;
    +	transition: all 0.4s ease 0s;
    +	top:0
    +}
    +.p-style2 figure:hover img{
    +	top:-50px
    +}
    +.p-style2 figure figcaption {
    +	position:absolute;
    +	bottom: -40%;
    +	width:100%;
    +	padding: 10px;
    +	z-index:5;
    +	opacity:0
    +}
    +.p-style2 figure h4 {
    +	margin:0 0 5px;
    +	font-size: 14px;
    +	font-weight:normal;
    +	color:#fff;
    +	padding:0;
    +	text-align:center
    +}
    +.p-style2 figure h4 a{
    +	color:#fff
    +}
    +.p-style2 figure:after,.p-style3 figure:after{
    +	background:rgba(0,0,0,.75);
    +	position:absolute;
    +	left:0;
    +	top:0;
    +	width:100%;
    +	height:100%;
    +	opacity:0;
    +	z-index:2;
    +	display:inline-block;
    +	content:"";
    +	-webkit-transition: opacity 0.35s;
    +	transition: opacity 0.35s;
    +	-webkit-backface-visibility: hidden;
    +}
    +.p-style2 figure .icon-links {
    +	margin:0;
    +	position: absolute;
    +	top: -60px;
    +	left:0;
    +	width:100%;
    +	text-align:center
    +}
    +.p-style2 figure .icon-links p{
    +	display:table;
    +	margin:auto
    +}
    +.p-style2 figure .icon-links a {
    +	color:#fff;
    +	float:left;
    +	margin:0 3px;
    +	border:1px #999 solid;
    +	padding:10px 15px;
    +	-webkit-transition: -webkit-transform 0.45s;
    +	transition: transform 0.45s;
    +	-webkit-transform: scale(0);
    +	transform: scale(0);
    +	opacity:0
    +}
    +.p-style2 figure .description {
    +	text-transform: none;
    +	font-size: 90%;
    +	margin:0;
    +	text-align:center;
    +	text-shadow:none;
    +	display:block
    +}
    +.p-style2 figure .description a{
    +	text-shadow:none
    +}
    +.p-style2 figure:hover:after,.p-style3 figure:hover:after{
    +	opacity: 1;
    +}
    +.p-style2 figure:hover h4,.p-style2 figure .description {
    +	-webkit-transform: translate3d(0,0,0);
    +	transform: translate3d(0,0,0);
    +	opacity:1
    +}
    +.p-style2 figure:hover .icon-links a{
    +	-webkit-transform: scale(1);
    +	transform: scale(1);
    +	opacity:1
    +}
    +.p-style2 figure:hover figcaption{
    +	opacity:1;
    +	bottom:0;
    +}
    +.p-style2 figure .icon-links a:nth-child(3) {
    +	-webkit-transition-delay: 0.2s;
    +	transition-delay: 0.2s;
    +}
    +.p-style2 figure .icon-links a:nth-child(2) {
    +	-webkit-transition-delay: 0.15s;
    +	transition-delay: 0.15s;
    +}
    +.p-style2 figure .icon-links a:first-child {
    +	-webkit-transition-delay: 0.1s;
    +	transition-delay: 0.1s;
    +}
    +
    +/* style 3 */
    +.p-style3 figure figcaption, .p-style3 figure figcaption > a {
    +	position: absolute;
    +	top: 0;
    +	left: 0;
    +	width: 100%;
    +	height: 100%;
    +}
    +.p-style3 figure{
    +	overflow:hidden;
    +	position:relative
    +}
    +.p-style3 img {
    +	-webkit-transition: opacity 0.45s;
    +	transition: opacity 0.45s;
    +	-webkit-backface-visibility: hidden;
    +	backface-visibility: hidden;
    +	z-index:1;
    +	width:100%
    +}
    +.p-style3 figcaption::before {
    +	position: absolute;
    +	bottom: -20%;
    +	left: 0;
    +	width: 100%;
    +	height: 44px;
    +	background: rgba(255,255,255,.7);
    +	content: '';
    +	z-index:3;
    +	opacity:0
    +}
    +.p-style3 h4,.p-style3 .description{
    +	position:relative;
    +	z-index:3;
    +	opacity:0;
    +	margin:8px 0 0;
    +	left:-100%;
    +	clear:both;
    +	float: left;
    +	border-top-right-radius: 2em;
    +	border-bottom-right-radius: 2em;
    +}
    +.p-style3 h4 {
    +	font-size:14px;
    +	font-weight:bold;
    +	padding: 8px 15px;
    +	color: #000;
    +	background:rgba(255,255,255,.7);
    +	display:inline-block;
    +	-webkit-transition-delay: 0.1s !important;
    +	transition-delay: 0.1s !important;
    +}
    +.p-style3 .description {
    +	font-size:12px;
    +	padding: 5px 15px;
    +	color: #000;
    +	background:rgba(255,255,255,.5);
    +	display:table;
    +	-webkit-transition-delay: 0.2s !important;
    +	transition-delay: 0.2s !important;
    +}
    +.p-style3 .description a,.p-style3 h4 a{
    +	font-size:12px;
    +	color: #000;
    +}
    +.p-style3 .icon-links {
    +	position: absolute;
    +	right: 0;
    +	bottom: 0;
    +	z-index: 3;
    +}
    +.p-style3 .icon-links a{
    +	font-size: 15px;
    +	color:#333;
    +	display:inline-block;
    +	margin: 0;
    +	padding: 10px 15px;
    +}
    +.p-style3 .icon-links a:hover{
    +	background:#222;
    +	color:#fff
    +}
    +.p-style3 .icon-links p{
    +	margin:0
    +}
    +.p-style3 .icon-links a i {
    +	opacity: 0;
    +	-webkit-transition: opacity 0.35s, -webkit-transform 0.35s;
    +	transition: opacity 0.35s, transform 0.35s;
    +	-webkit-transform: translate3d(0,50px,0);
    +	transform: translate3d(0,50px,0);
    +}
    +.p-style3 figure:hover h4,.p-style3 figure:hover .description {
    +	-webkit-transform: translate3d(0,0,0);
    +	transform: translate3d(0,0,0);
    +	opacity:1;
    +	left:0
    +}
    +.p-style3 figure:hover figcaption::before {
    +	opacity: 1;
    +	bottom:0
    +}
    +.p-style3 figure:hover .icon-links i {
    +	opacity: 1;
    +	-webkit-transform: translate3d(0,0,0);
    +	transform: translate3d(0,0,0);
    +}
    +.p-style3 figure:hover .icon-links a:nth-child(3) i {
    +	-webkit-transition-delay: 0.05s;
    +	transition-delay: 0.05s;
    +}
    +.p-style3 figure:hover .icon-links a:nth-child(2) i {
    +	-webkit-transition-delay: 0.1s;
    +	transition-delay: 0.1s;
    +}
    +.p-style3 figure:hover .icon-links a:first-child i {
    +	-webkit-transition-delay: 0.15s;
    +	transition-delay: 0.15s;
    +}
    +
    +/* style 4 */
    +.p-style4 .name-holder{
    +	padding:15px;
    +	border-bottom-width:3px;
    +	border-bottom-style:solid
    +}
    +.p-style4 .img-over .zoom{
    +	bottom:-100%;
    +	right:0;
    +	margin:0;
    +	width:60px;
    +	height:60px;
    +}
    +.p-style4 .img-over .link{
    +	top:-100%;
    +	left:0;
    +	margin:0;
    +	width:60px;
    +	height:60px;
    +}
    +.p-style4 .img-over .zoom i,.p-style4 .img-over .link i{
    +	width:60px;
    +	height:60px;
    +	line-height:60px;
    +	font-size:17px
    +}
    +.p-style4 .img-over:hover .zoom{
    +	bottom:0;
    +}
    +.p-style4 .img-over:hover .link{
    +	top:0;
    +}
    +
    +/* style 5 */
    +.p-style5 figure{
    +	position:relative;
    +	overflow:hidden;
    +}
    +.p-style5 figure:before{
    +	background:rgba(0,0,0,.5);
    +	position:absolute;
    +	left:0;
    +	top:0;
    +	width:100%;
    +	height:100%;
    +	opacity:0;
    +	z-index:0;
    +	display:inline-block;
    +	content:"";
    +	-webkit-transition: opacity 0.35s;
    +	transition: opacity 0.35s;
    +	-webkit-backface-visibility: hidden;
    +	z-index: 2;
    +}
    +.p-style5 figure img{
    +	width:100%;
    +	-webkit-transform: scale(1);
    +	transform: scale(1);
    +	position: relative;
    +	z-index: 1;
    +}
    +.p-style5 figcaption {
    +	padding: 10px 30px;
    +	z-index:2
    +}
    +.p-style5 figure figcaption, .p-style5 figure figcaption > a {
    +	position: absolute;
    +	top: 0;
    +	left: 0;
    +	width: 100%;
    +	height: 100%;
    +}
    +.p-style5 figcaption::before,.p-style5 figcaption::after {
    +	position: absolute;
    +	content: '';
    +	opacity: 0;
    +}
    +.p-style5 figcaption::before {
    +	top: 10px;
    +	right: 10px;
    +	bottom: 10px;
    +	left: 10px;
    +	border-top: 1px solid rgba(255,255,255,.5);
    +	border-bottom: 1px solid rgba(255,255,255,.5);
    +	-webkit-transform: scale(0,1);
    +	transform: scale(0,1);
    +	-webkit-transform-origin: 0 0;
    +	transform-origin: 0 0;
    +}
    +.p-style5 figcaption::after {
    +	top: 10px;
    +	right: 10px;
    +	bottom: 10px;
    +	left: 10px;
    +	border-right: 1px solid rgba(255,255,255,.5);
    +	border-left: 1px solid rgba(255,255,255,.5);
    +	-webkit-transform: scale(1,0);
    +	transform: scale(1,0);
    +	-webkit-transform-origin: 100% 0;
    +	transform-origin: 100% 0;
    +}
    +.p-style5 h4 {
    +	padding-top: 4%;
    +	-webkit-transition: -webkit-transform 0.5s;
    +	transition: transform 0.5s;
    +	font-size: 14px;
    +	color:#fff;
    +	text-align: center;
    +	opacity: 0;
    +	margin-bottom: 10px;
    +	position: relative;
    +	z-index: 3;
    +}
    +.p-style5 h4 a{
    +	color:#fff;
    +	text-transform: uppercase;
    +}
    +.p-style5 .icon-links {
    +	padding: 0.5em 2em;
    +	text-transform: none;
    +	opacity: 0;
    +	-webkit-transform: translate3d(0,30px,0);
    +	transform: translate3d(0,30px,0);
    +	position:relative;
    +	z-index:999
    +}
    +.p-style5 h4,.p-style5 figure .description {
    +	-webkit-transform: translate3d(0,-50px,0);
    +	transform: translate3d(0,-50px,0);
    +}
    +.p-style5 figure .icon-links {
    +	margin:0;
    +	position: absolute;
    +	width:100%;
    +	text-align:center;
    +	z-index:5;
    +	bottom: 20px;
    +	left:0
    +}
    +.p-style5.p-3-cols figure .icon-links{
    +	bottom: 15px;
    +}
    +.p-style5 figure .icon-links p{
    +	display:table;
    +	margin:auto;
    +}
    +.p-style5 figure .icon-links a {
    +	float: left;
    +	color:#fff;
    +	margin:0 5px;
    +	border: 1px #999 solid;
    +	width: 40px;
    +	height: 40px;
    +	line-height: 40px;
    +	text-align:center;
    +	position:relative;
    +}
    +.p-style5 figure .description {
    +	text-transform: none;
    +	font-size: 12px;
    +	margin:0;
    +	text-align:center;
    +	color: #fff;
    +	text-shadow:none;
    +	padding: 10px;
    +	display:table;
    +	margin:auto;
    +	opacity:0;
    +	line-height: 1;
    +	position: relative;
    +	z-index: 3;
    +}
    +.p-style5 figure .description a{
    +	color: #FFF;
    +	text-shadow:none
    +}
    +.p-style5 figcaption::before,.p-style5 figcaption::after,.p-style5 .icon-links,.p-style5 figure .description,.p-style5 figure img {
    +	-webkit-transition: opacity 0.7s,-webkit-transform 0.7s;
    +	transition: opacity 0.7s, transform 0.7s;
    +}
    +.p-style5 figure:hover figcaption::before,.p-style5 figure:hover figcaption::after {
    +	opacity: 1;
    +	-webkit-transform: scale(1);
    +	transform: scale(1);
    +}
    +.p-style5 figure:hover img {
    +	opacity: 1;
    +	-webkit-transform: scale(1.5);
    +	transform: scale(1.5);
    +	-moz-transform:scale(1.5);
    +	-ms-transform:scale(1.5);
    +}
    +.p-style5 figure:hover:before{
    +	opacity: 1;
    +}
    +.p-style5 figure:hover h4,.p-style5 figure:hover .icon-links,.p-style5 figure:hover .description {
    +	opacity: 1;
    +	-webkit-transform: translate3d(0,0,0);
    +	transform: translate3d(0,0,0);
    +}
    +.p-style5 figure:hover figcaption::after, .p-style5 figure:hover .icon-links,.p-style5 figure:hover .description {
    +	-webkit-transition-delay: 0.15s;
    +	transition-delay: 0.15s;
    +}
    +.p-style3 figure img{
    +	width:100%;
    +	transform:scale(1);
    +	-webkit-transform:scale(1);
    +	-moz-transform:scale(1);
    +	-ms-transform:scale(1);
    +	display:block
    +}
    +.p-style3 figure:hover img{
    +	transform:scale(1.5);
    +	-webkit-transform:scale(1.5);
    +	-moz-transform:scale(1.5);
    +	-ms-transform:scale(1.5);
    +}
    +.p-4-cols.p-style3 .icon-links p{
    +	margin: 0;
    +}
    +.p-4-cols.p-style5 h4{
    +	font-size:13px;
    +	display: table;
    +	margin: 2px auto;
    +	line-height: 1;
    +	padding: 10px;
    +	text-transform: uppercase;
    +}
    +
    +/* masonry */
    +.masonry .img-holder img{
    +	width:100%;
    +	height:auto
    +}
    +.masonry.p-style5.p-4-cols figcaption::before{
    +	top: 15px;
    +	right: 10px;
    +	bottom: 15px;
    +	left: 10px;
    +}
    +.masonry.p-style5.p-4-cols figcaption::after{
    +	top: 10px;
    +	right: 15px;
    +	bottom: 10px;
    +	left: 15px;
    +}
    +.masonry.p-style5.p-4-cols figure .icon-links{
    +	bottom:20px
    +}
    +
    +/*
    +------------- Parallax --------------- */
    +.parallax{
    +	position:relative;
    +	background-attachment: fixed;
    +	background-position: 0 0;
    +	background-repeat: no-repeat;
    +	overflow: hidden;
    +	background-size:cover;
    +	transform: translate(0,0);
    +}
    +.parallax-overlay{
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	top:0;
    +	left:0;
    +	z-index:1
    +}
    +.fixed-bg{
    +	background-attachment: fixed !important;
    +	background-size: cover;
    +}
    +.parallax > .container,.fixed-bg > .container,.section > .container{
    +	z-index:2;
    +	position:relative
    +}
    +.portfolio.parallax p{
    +	width:70%;
    +	margin:20px auto;
    +	display:table;
    +}
    +
    +/* single */
    +.single-pro-img{
    +	height:500px
    +}
    +.pro-info-cell > div{
    +	padding:15px
    +}
    +.pro-gallery {
    +	margin-bottom:-50px;
    +	padding-bottom:15px;
    +	-webkit-box-shadow: 0px 25px 20px -8px rgba(0,0,0,0.35);
    +	-moz-box-shadow: 0px 25px 20px -8px rgba(0,0,0,0.35);
    +	box-shadow: 0px 25px 20px -8px rgba(0,0,0,0.35);
    +}
    +.pro-info-cell label{
    +	display:inline-block
    +}
    +
    +/*
    +------------ About ---------------- */
    +.about-title > .container{
    +	height:500px
    +}
    +.about-me-title > .container{
    +	height:600px
    +}
    +.my-info{
    +	position: absolute;
    +	right: 15px;
    +	top: 30%;
    +	padding: 20px;
    +	background-color: rgba(255,255,255,.2);
    +}
    +.my-info li{
    +	color:#bbb;
    +	font-size:14px;
    +	border-top: 1px rgba(255, 255, 255, 0.18) solid;
    +	padding:5px
    +}
    +.my-info li a{
    +	color:#bbb
    +}
    +.my-info li:first-child{
    +	border-top:0
    +}
    +.my-exp h5{
    +	font-size:13px;
    +	margin-bottom:5px
    +}
    +.my-exp h5 i{
    +	margin-right:10px
    +}
    +.my-exp p{
    +	margin:0 0 15px 25px
    +}
    +
    +/*
    +----------- sitemap ---------------- */
    +.sitemap > ul > li > a{
    +	padding:15px 25px;
    +	text-transform:uppercase;
    +	display:block;
    +	clear:both;
    +	overflow:hidden;
    +	font-weight:bold
    +}
    +.sitemap > ul > li > a i{
    +	margin-right:10px
    +}
    +.sitemap > ul > li > ul{
    +	padding:10px 20px 20px;
    +	overflow:hidden
    +}
    +.sitemap > ul > li > ul > li{
    +	float:left;
    +	margin:20px 16px 0 0;
    +	width:23%
    +}
    +.sitemap > ul > li > ul > li:nth-child(4n+1){
    +	clear:left
    +}
    +.sitemap > ul > li > ul > li > a,.sitemap > ul > li > ul > li > h4{
    +	font-weight:bold;
    +	text-transform:uppercase;
    +	margin-bottom:8px;
    +	display:block;
    +	font-size:13px
    +}
    +.sitemap > ul > li > ul > li li{
    +	padding:5px 10px 5px 17px;
    +	position:relative
    +}
    +.sitemap > ul > li > ul > li li:before{
    +	position:absolute;
    +	left:0;
    +	top:10px;
    +	font: normal normal normal 9px/1 FontAwesome;
    +	content:"\f068";
    +	display:inline-block;
    +}
    +
    +/*
    +-------------- blog --------------- */
    +.post-item{
    +	margin-bottom:40px;
    +}
    +.horizontal-slider .post-item,.posts-mini .post-item{
    +	margin-bottom:0
    +}
    +.post-item .post-image,.post-item .slick-slide{
    +	overflow:hidden
    +}
    +.post-item .post-image{
    +	position:relative;
    +}
    +.posts-mini .post-item .post-content{
    +	background:transparent;
    +}
    +.posts-mini .post-item .post-info-container{
    +	padding-right:0;
    +	padding-left:0
    +}
    +.posts-mini .post-item .post-content p{
    +	padding:20px 0 0;
    +	margin:0
    +}
    +.post-item img{
    +	transform:scale(1);
    +	-webkit-transform:scale(1);
    +	-moz-transform:scale(1);
    +	-ms-transform:scale(1);
    +}
    +.post-item:hover .post-image img,.post-img:hover img{
    +	transform:scale(1.3);
    +	-webkit-transform:scale(1.3);
    +	-moz-transform:scale(1.3);
    +	-ms-transform:scale(1.3);
    +}
    +.post-item .post-content{
    +	text-align:left;
    +	border-bottom-left-radius: 1em;
    +	border-bottom-right-radius: 1em;
    +	border-width:0;
    +	border-top-width:4px
    +}
    +.post-item .post-content p{
    +	padding:20px;
    +	margin-bottom:0
    +}
    +.blog-posts .post-item:hover .post-content .post-info-container a,.blog-posts .post-item:hover .post-meta li{
    +	color:#fff
    +}
    +.blog-posts .post-item:hover .post-content.main-border{
    +	border-top-color:#fff !important
    +}
    +.blog-posts .post-item:hover .post-content .post-icon,.blog-posts .post-item:hover .post-image .post-icon {
    +	background-color:#fff;
    +	color:#777 !important
    +}
    +.blog-posts .post-item:hover .post-image .post-icon{
    +	color:#fff
    +}
    +.post-info-container{
    +	margin-bottom:20px;
    +}
    +.post-item .post-info-container{
    +	padding:20px 20px 0;
    +	margin:0;
    +	overflow:hidden
    +}
    +.post-item .post-info h2{
    +	font-size:18px;
    +	margin-bottom:5px;
    +}
    +.post-meta{
    +	overflow:hidden
    +}
    +.post-item .post-meta li{
    +	float:left;
    +	font-size:11px;
    +	padding-right:15px;
    +}
    +.post-item .post-meta li i{
    +	margin-right:8px;
    +}
    +.post-icon{
    +	float: left;
    +	margin-right: 20px;
    +	width: 50px;
    +	height: 80px;
    +	font-size: 22px;
    +	line-height: 100px;
    +	text-align: center;
    +	border-bottom-left-radius: 2em;
    +	border-bottom-right-radius: 2em;
    +	margin-top: -20px;
    +}
    +.post-image .post-icon{
    +	position:absolute;
    +	left: 15px;
    +	bottom:0;
    +	z-index:99;
    +	border-bottom-left-radius: 0;
    +	border-bottom-right-radius: 0;
    +	border-top-left-radius: 2em;
    +	border-top-right-radius: 2em;
    +	height: 55px;
    +	line-height: 62px;
    +}
    +.bottom_tools{
    +	padding:15px;
    +	overflow:hidden;
    +	border-bottom-left-radius: 1em;
    +	border-bottom-right-radius: 1em;
    +}
    +.bottom_tools a{
    +	padding:7px 12px;
    +	margin:0 7px 0 0;
    +	font-size:11px;
    +	text-transform:uppercase;
    +}
    +.bottom_tools .f-right{
    +	margin-right:0
    +}
    +.bottom_tools a i{
    +	margin-right:5px;
    +}
    +.post-item:hover .bottom_tools a i{
    +	color:#fff
    +}
    +.post-image video,.post-image audio{
    +	width:100%;
    +}
    +.post-gallery{
    +	display:table;
    +	margin:auto;
    +	overflow:hidden;
    +}
    +.gallery-columns-5 .gallery-item {
    +	width: 19.855%;
    +}
    +.gallery-item {
    +	float: left;
    +	margin: 0 1px 1px 0;
    +	position: relative;
    +	overflow:hidden
    +}
    +.gallery-caption {
    +	background-color: rgba(0,0,0,.7);
    +	-webkit-box-sizing: border-box;
    +	-moz-box-sizing: border-box;
    +	box-sizing: border-box;
    +	color: #fff;
    +	font-size: 12px;
    +	line-height: 1.5;
    +	margin: 0;
    +	max-height: 50%;
    +	opacity: 0;
    +	padding: 6px 8px;
    +	position: absolute;
    +	bottom: 0;
    +	left: 0;
    +	text-align: left;
    +	width: 100%;
    +}
    +.gallery-item:hover .gallery-caption{
    +	opacity:1
    +}
    +
    +/* small-image */
    +.blog-posts.small-image .post-image,.blog-posts.small-image .post-gallery{
    +	float:left;
    +	width:260px;
    +	height:245px
    +}
    +.col-md-8 .blog-posts.small-image .post-image,.col-md-8 .blog-posts.small-image .post-gallery{
    +	float:left;
    +	width: 190px;
    +	max-width:190px;
    +	height:185px;
    +	display:block
    +}
    +.col-md-8 .blog-posts.small-image .post-image video{
    +	float:left;
    +	width:193px;
    +	height:185px
    +}
    +.col-md-8 .blog-posts.small-image .gallery-columns-5 .gallery-item {
    +	width: 32.8%;
    +}
    +.blog-posts.small-image .post-content{
    +	margin-left:30%
    +}
    +.col-md-8.inner-magazine .recent-posts .post-content{
    +	margin-left: 25% !important;
    +	padding-top: 10px;
    +}
    +.col-md-8.inner-magazine .recent-posts .post-content p{
    +	padding: 21px 29px !important;
    +}
    +.inner-magazine .blog-posts .post-item:hover .post-content a{
    +	color:#fff
    +}
    +.col-md-4 .sidebar_widgets ul.flickr-widget li img, .col-md-4 .sidebar_widgets ul.flickr-widget .img-overlay {
    +	width: 54px;
    +	height: 54px;
    +}
    +.col-md-8.inner-magazine .recent-posts .post-info-container{
    +	padding-left:20px
    +}
    +.col-md-8.inner-magazine .recent-posts .post-item {
    +	overflow:hidden;
    +	margin-bottom:20px
    +}
    +.blog-posts.small-image  .post-item .post-content p{
    +	padding:17px 25px
    +}
    +.blog-posts.small-image .post-image video,.blog-posts.small-image .post-image iframe,.blog-posts.small-image .post-image img{
    +	width:260px;
    +	background:#000
    +}
    +.blog-posts.small-image .post-image iframe,.blog-posts.small-image .post-image img{
    +	background:#000
    +}
    +.blog-posts.small-image .gallery-columns-5 .gallery-item {
    +	width: 32.855%;
    +}
    +.blog-posts.small-image.full .post-content{
    +	margin-left: 22.8%;
    +}
    +.blog-posts.small-image.full .post-content p{
    +	padding:28px 35px
    +}
    +.blog-posts.small-image .gallery-caption {
    +	max-height:none;
    +	font-size:10px
    +}
    +
    +/* timeline */
    +.timeline{
    +	position:relative
    +}
    +.timeline:before{
    +	position:absolute;
    +	width:1px;
    +	height:100%;
    +	content:"";
    +	display:inline-block;
    +	margin-top:2px
    +}
    +.lft-tl:before{
    +	left:35px;
    +}
    +.rit-tl:before{
    +	right:35px;
    +}
    +.timeline .post-item{
    +	position:relative;
    +}
    +.timeline .post-item iframe{
    +	position:relative;
    +	overflow:hidden
    +}
    +.lft-tl .post-item{
    +	margin-left:80px;
    +}
    +.rit-tl .post-item{
    +	margin-right:80px;
    +}
    +.timeline .post-item .timeline_date{
    +	position:absolute;
    +	top:0;
    +	width:80px
    +}
    +.lft-tl .post-item .timeline_date{
    +	left:-80px;
    +}
    +.rit-tl .post-item .timeline_date{
    +	right:-80px;
    +}
    +.timeline .post-item .timeline_date span{
    +	display:block;
    +	text-align:center
    +}
    +.timeline .post-item .timeline_date:before{
    +	position:absolute;
    +	height:1px;
    +	width:20px;
    +	content:"";
    +	display:inline-block;
    +	top:35px
    +}
    +.lft-tl .post-item .timeline_date:before{
    +	right:0;
    +}
    +.rit-tl .post-item .timeline_date:before{
    +	left:0;
    +}
    +.timeline .post-item .timeline_date .inner_date{
    +	height: 70px;
    +	text-align: center;
    +}
    +.timeline .post-item .timeline_date .inner_date:before{
    +	-moz-transform: rotate(-45deg);
    +	-ms-transform: rotate(-45deg);
    +	-o-transform: rotate(-45deg);
    +	transform: rotate(-45deg);
    +	-webkit-transform: rotate(-45deg);
    +	position: absolute;
    +	z-index: 0;
    +	content: "";
    +	display: inline-block;
    +	width: 50px;
    +	height: 50px;
    +	top: 10px;
    +}
    +.lft-tl .post-item .timeline_date .inner_date:before{
    +	right: 20px;
    +}
    +.rit-tl .post-item .timeline_date .inner_date:before{
    +	left: 20px;
    +}
    +.timeline .post-item .timeline_date .inner_date span{
    +	position:relative;
    +	z-index:1;
    +}
    +.lft-tl .post-item .timeline_date .inner_date span{
    +	padding-right:10px
    +}
    +.rit-tl .post-item .timeline_date .inner_date span{
    +	padding-left:10px
    +}
    +.lft-tl .post-item .timeline_date .year{
    +	padding-right:10px;
    +}
    +.rit-tl .post-item .timeline_date .year{
    +	padding-left:10px;
    +}
    +
    +.timeline .post-item .timeline_date .day{
    +	color:#fff;
    +	font-size:24px;
    +	font-weight:900;
    +	margin-top:5px
    +}
    +.timeline .post-item .timeline_date .month{
    +	margin-top:-5px;
    +	color:#fff;
    +}
    +.timeline.full{
    +	overflow:hidden;
    +	height:100%
    +}
    +.timeline.full .post-item{
    +	width:46%;
    +	float:left;
    +}
    +.timeline.full .post-item:nth-child(even){
    +	float:right
    +}
    +.timeline.full .post-item .gallery-columns-5 .gallery-item {
    +	width: 19.8%;
    +}
    +.timeline.full:before{
    +	left:50%;
    +	margin-left:-0.5px
    +}
    +.timeline.full .post-item .timeline_date{
    +	right:-80px;
    +	width:60px
    +}
    +.timeline.full .post-item .timeline_date:before{
    +	left:-20px
    +}
    +.timeline.full .post-item:nth-child(even) .timeline_date:before{
    +	right:-20px;
    +	left:auto
    +}
    +.timeline.full .post-item .timeline_date span{
    +	text-align:inherit
    +}
    +.timeline.full .post-item .timeline_date .inner_date span{
    +	text-align:center;
    +	padding-right:10px
    +}
    +.timeline.full .post-item .timeline_date .year{
    +	text-align:center;
    +	padding-right:10px
    +}
    +.timeline.full .post-item:nth-child(even) .timeline_date{
    +	left:-71px;
    +	top:120px
    +}
    +
    +/* masonry */
    +.masonry .post-item{
    +	width:48%;
    +	margin:0 15px 15px 0;
    +}
    +.right-cell .masonry .post-item{
    +	margin:0 0 15px 15px;
    +}
    +.masonry .post-item .gallery-columns-5 .gallery-item {
    +	width: 19.744444%;
    +}
    +.masonry.full .post-item{
    +	width:32%;
    +}
    +.masonry.full .post-item .gallery-columns-5 .gallery-item {
    +	width: 24.6777%;
    +}
    +
    +/* grid */
    +.grid .post-item{
    +	width:48%;
    +	margin:0 15px 15px 0;
    +}
    +.right-cell .grid .post-item{
    +	margin:0 0 15px 15px;
    +}
    +.grid .post-item iframe,.grid .post-item video{
    +	width:100%;
    +	height:210px;
    +	background:#000
    +}
    +.grid .post-item .post-gallery{
    +	height:210px;
    +}
    +.grid .post-item .gallery-columns-5 .gallery-item {
    +	width: 19.744444%;
    +}
    +.grid.full .post-item{
    +	width:32%;
    +}
    +.grid.full .post-item .gallery-columns-5 .gallery-item {
    +	width: 24.6777%;
    +}
    +.grid .post-item .post-info h2{
    +	height:25px;
    +	overflow:hidden;
    +	white-space:nowrap;
    +	text-overflow: ellipsis;
    +}
    +.grid.full .post-item iframe,.grid.full .post-item video{
    +	height:182px;
    +}
    +.grid.full .post-item .post-gallery{
    +	height:187px;
    +}
    +
    +/* single */
    +.blog-single .post-item,.blog-single .post-item .post-content{
    +	background:transparent;
    +}
    +.details-img{
    +	margin-bottom:20px
    +}
    +.blog-single .post-item .post-info-container, .blog-single .post-item .post-content p{
    +	padding:0
    +}
    +.blog-single .post-item .post-info-container{
    +	margin-bottom:20px;
    +	overflow:hidden
    +}
    +.post-tags .tags{
    +	margin-top:10px
    +}
    +.post-tags{
    +	margin-top:30px;
    +	overflow:hidden
    +}
    +.post-tags i{
    +	margin-right:8px
    +}
    +.post-tags > span{
    +	display:inline-block;
    +	margin-right:15px;
    +}
    +.share-post{
    +	overflow:hidden;
    +	margin-top:10px
    +}
    +.share-post #shareme{
    +	float:left;
    +	height:38px
    +}
    +.share-post li{
    +	margin:0
    +}
    +.social-list li.no-icon a{
    +	font-size:16px
    +}
    +
    +.share-post .facebook{
    +	background:#1b57a1;
    +	color:#fff
    +}
    +.share-post .twitter{
    +	background:#0cbce2;
    +	color:#fff
    +}
    +.share-post .googleplus{
    +	background:#dd4b39;
    +	color:#fff
    +}
    +.share-post .linkedin{
    +	background:#1583ba;
    +	color:#fff
    +}
    +.comments{
    +	padding-top:30px
    +}
    +.comment-list li{
    +	position:relative
    +}
    +.comment-list > li{
    +	overflow:hidden;
    +	margin-bottom:15px;
    +}
    +.comment-list .comment-avatar{
    +	position:absolute;
    +	left:0;
    +	height:100%;
    +	width:80px;
    +	padding:30px 10px
    +}
    +.comment-list > li .comment-content{
    +	padding:20px;
    +	margin-left:80px
    +}
    +.comment-list .comment-content h6{
    +	font-weight:bold;
    +	margin-bottom:5px;
    +	display:inline-block;
    +	padding:5px 10px
    +}
    +.comment-list .comment-content h6 a{
    +	color:#fff
    +}
    +.comment-list .comment-content .meta{
    +	font-size:10px;
    +	margin-bottom:15px
    +}
    +.comment-list .comment-content .meta span{
    +	display:inline-block;
    +	margin-right:10px
    +}
    +ul.child-comment{
    +	margin-left:100px;
    +	position:relative;
    +}
    +ul.child-comment:before{
    +	content:"";
    +	height:1px;
    +	width:95%;
    +	left:0;
    +	display:inline-block
    +}
    +ul.child-comment li{
    +	border:0;
    +	margin-bottom:0
    +}
    +.comment-list ul.child-comment .comment-avatar{
    +	background:transparent
    +}
    +
    +
    +/* ---- Shop -------------- */
    +.grid-list{
    +	margin:0 -15px
    +}
    +.shop-item{
    +	margin-bottom:40px;
    +}
    +.item-box {
    +	cursor: pointer;
    +	overflow:hidden;
    +}
    +.item-img {
    +	position:relative;
    +	overflow:hidden;
    +	width:100%;
    +	text-align:center
    +}
    +.item-img img{
    +	position:relative;
    +	z-index:1;
    +}
    +.item-img .hidden-img{
    +	position:absolute;
    +	top:0;
    +	left:0;
    +	z-index:2;
    +	opacity:0;
    +	width:100%
    +}
    +.item-img .hidden-img img{
    +	display:table;
    +	margin:auto;
    +	width:auto
    +}
    +.item-img .product-buttons{
    +	position:absolute;
    +	width:156px;
    +	bottom:45%;
    +	z-index:3;
    +	left:50%;
    +	margin-left:-78px
    +}
    +.item-img .product-buttons a{
    +	display:inline-block;
    +	color:#fff;
    +	font-size:15px;
    +	background:rgba(0,0,0,.9);
    +	width:50px;
    +	height:50px;
    +	line-height:50px;
    +	text-align:center;
    +	-webkit-transition: opacity 0.35s, -webkit-transform 0.35s;
    +	transition: opacity 0.35s, transform 0.35s;
    +	-webkit-transform: translate3d(0,-50px,0);
    +	transform: translate3d(0,-50px,0);
    +	opacity:0;
    +	margin:0 -1px
    +}
    +.item-box:hover .item-img img {
    +	opacity: 0.8;
    +}
    +.item-box:hover .product-buttons a{
    +	opacity:1;
    +	-webkit-transform: translate3d(0,0,0);
    +	transform: translate3d(0,0,0);
    +}
    +.item-img .product-buttons a:nth-child(3) {
    +	-webkit-transition-delay: 0.15s;
    +	transition-delay: 0.15s;
    +}
    +.item-img .product-buttons a:nth-child(2) {
    +	-webkit-transition-delay: 0.25s;
    +	transition-delay: 0.25s;
    +}
    +.item-img .product-buttons a:first-child {
    +	-webkit-transition-delay: 0.35s;
    +	transition-delay: 0.35s;
    +}
    +.item-box:hover .item-img .hidden-img{
    +	opacity:0;
    +}
    +.item-box:hover .item-img .hidden-img,.item-box:hover .item-img .hidden-img img {
    +	opacity:1;
    +}
    +.item-title {
    +	margin: 0;
    +	padding: 10px 0 0;
    +	text-align: center;
    +	font-size: 15px;
    +	font-weight:bold;
    +	position:relative;
    +	width: 98%;
    +	text-overflow: ellipsis;
    +	overflow: hidden;
    +	white-space:nowrap
    +}
    +.item-details {
    +	overflow: hidden;
    +	padding: 10px 0;
    +	position:relative;
    +}
    +.item-details p{
    +	display:none
    +}
    +.grid-list.list p{
    +	display:block
    +}
    +.grid-list.list .item-img .product-buttons{
    +	width:94px;
    +	margin-left:-47px
    +}
    +.item-price {
    +	font-size: 20px;
    +	text-align:center;
    +	font-weight:bold;
    +	padding:5px 0
    +}
    +.item-price ins{
    +	font-size:14px;
    +	text-decoration:line-through;
    +	display:inline-block;
    +	margin-right:10px;
    +	font-weight:normal
    +}
    +.item-rating {
    +	padding-bottom: 3px;
    +}
    +.item-details .item-rating {
    +	text-align: center;
    +}
    +.item-rating .fa {
    +	margin-right: 4px;
    +	color: #ffc000;
    +	font-size: 15px;
    +}
    +.item-rating .fa-star-o {
    +	color: #c0c0c0;
    +}
    +.right-rating {
    +	float: right;
    +	clear: both;
    +	font-size: 14px;
    +	font-weight: bold;
    +}
    +.right-rating .item-rating {
    +	float: right;
    +}
    +.item-details .left {
    +	padding-left: 10px;
    +}
    +.item-cart {
    +	padding: 0 0 6px 0;
    +}
    +.item-cart a {
    +	text-transform: uppercase;
    +	font-size: 11px;
    +}
    +.remove-item i {
    +	font-size: 23px;
    +}
    +.item-details .left i{
    +	margin-right: 8px;
    +}
    +.item-tools {
    +	padding-top: 8px;
    +}
    +.cart_totals{
    +	margin-top:20px
    +}
    +.on-sale{
    +	position: absolute;
    +	left: -40px;
    +	top: -40px;
    +	font-size: 11px;
    +	z-index: 9;
    +	width: 80px;
    +	height: 80px;
    +	-moz-transform: rotate(-45deg);
    +	-ms-transform: rotate(-45deg);
    +	-o-transform: rotate(-45deg);
    +	transform: rotate(-45deg);
    +	-webkit-transform: rotate(-45deg);
    +	line-height: 132px;
    +	text-align:center
    +}
    +.toolsBar {
    +	display: table;
    +	margin: 0 0 30px 0;
    +	padding: 0 0 15px;
    +	width: 100%;
    +	border-bottom-style:solid;
    +	border-bottom-width:1px
    +}
    +.toolsBar span {
    +	display: inline-block;
    +	margin: 0 5px 0 0;
    +}
    +.toolsBar select {
    +	margin-right: 10px;
    +	display: inline-block;
    +	width: inherit;
    +}
    +.order-asc i{
    +	margin-top: 7px;
    +	font-size: 20px;
    +}
    +.products-filter-top {
    +	float: left !important;
    +	clear: none !important;
    +	width: auto !important;
    +	padding-left: 0;
    +}
    +.list-grid {
    +	float: right !important;
    +	clear: none !important;
    +	width: auto !important;
    +	padding-right: 0;
    +}
    +.list-grid a {
    +	position: relative;
    +	float: right;
    +	margin: 0 0 0 4px;
    +	font-size: 15px;
    +	width:40px;
    +	height:40px;
    +	line-height:40px;
    +	text-align:center
    +}
    +.shop-item p {
    +	overflow: hidden;
    +	padding: 5px 10px;
    +	max-height: 50px;
    +}
    +.grid-list.list .shop-item {
    +	float: none;
    +	clear: both;
    +	width: 100%;
    +	margin-bottom:20px
    +}
    +.grid-list.list .item-box {
    +	overflow: hidden;
    +	background: transparent;
    +}
    +.grid-list.list .item-details{
    +	padding:5px 0
    +}
    +.grid-list.list .item-details p,.grid-list.list .item-details .item-rating,.grid-list.list .item-details .item-price {
    +	text-align:left;
    +	padding-left:10px
    +}
    +.grid-list.list .item-img {
    +	float: left;
    +	margin-right: 20px;
    +	max-height: 200px;
    +	width:auto
    +}
    +.grid-list.list .item-img .product-buttons a{
    +	width:30px;
    +	height:30px;
    +	line-height:30px;
    +	font-size:14px
    +}
    +.grid-list.list .item-img img {
    +	max-height: 200px;
    +}
    +.control-group .box i {
    +	margin-right: 7px;
    +}
    +.similar-products .item-img img {
    +	max-height: 200px;
    +}
    +.grid-list.list .item-title {
    +	padding:20px 0 0 10px;
    +	border: 0;
    +	text-align: left;
    +	width:auto;
    +	margin:0
    +}
    +.widget-content .control-group select {
    +	width: 100%;
    +}
    +.widget-content .control-group{
    +	overflow:hidden;
    +	padding:0 0 10px
    +}
    +.widget-content .control-group .col-md-6{
    +	padding:0
    +}
    +.widget-content .control-group label.checkbox{
    +	font-weight:normal
    +}
    +.widget-content .control-group .col-md-6:first-child{
    +	padding-right:10px
    +}
    +.widget-content .control-group label.checkbox input[type=checkbox], .widget-content .control-group label.checkbox input[type=radio] {
    +	display: inline;
    +	margin-right: 8px;
    +	margin-left:5px;
    +	vertical-align: middle;
    +}
    +.search-filter .accordion-content{
    +	padding-right:0;
    +	padding-left:0
    +}
    +.control-label{
    +	padding-bottom:5px
    +}
    +.control-labeli{
    +	margin-right:10px
    +}
    +.product-img {
    +	position: relative;
    +	text-align: center;
    +	padding:5px
    +}
    +.product-specs a.btn, .item-avl > div {
    +	margin-right: 6px;
    +	margin-bottom: 0;
    +}
    +.product-specs a.btn {
    +	padding-right: 20px;
    +	padding-left: 20px;
    +}
    +.product-price {
    +	font-size: 29px;
    +	font-weight:bold;
    +	line-height: 1;
    +}
    +.old-price{
    +	text-decoration:line-through;
    +	font-size: 20px;
    +	margin: 0 0 0 10px;
    +}
    +.price-block {
    +	display: table;
    +	clear: both;
    +	margin: 0;
    +	padding: 0 0 20px;
    +	width: 100%;
    +}
    +.price-box{
    +	padding-bottom: 10px;
    +}
    +.pro-btns{
    +	margin: 5px 0 0 15px;
    +	line-height: 1.9;
    +}
    +.item-avl > div {
    +	padding: 10px;
    +	font-weight: bold;
    +}
    +.item-avl .success-box,.item-avl .warning-box,.item-avl .error-box{
    +	border-radius: 50%;
    +	padding: 0;
    +	width: 25px;
    +	height: 25px;
    +	text-align: center;
    +	line-height: 25px;
    +}
    +.item-avl span{
    +	line-height:25px
    +}
    +.item-avl i{
    +	color:#fff !important;
    +	margin:0 !important
    +}
    +.product-block{
    +	padding: 15px 0;
    +}
    +.last-list{
    +	padding-top: 15px !important
    +}
    +.last-list p{
    +	margin-bottom:0px
    +}
    +.reviews .comments {
    +	padding: 30px 0;
    +}
    +.item-add {
    +	clear: both;
    +	overflow: hidden;
    +}
    +#items-num {
    +	width: 55px;
    +	text-align: center;
    +	line-height: 57px;
    +	height: 57px;
    +	font-size:17px;
    +	background-color: transparent;
    +}
    +.add-items{
    +	margin:0 3px;
    +	line-height:55px;
    +	height:55px
    +}
    +.add-items i {
    +	padding: 0 8px;
    +	height: 57px;
    +	border: 1px transparent solid;
    +	font-size: 10px;
    +	line-height: 57px;
    +}
    +.qty-txt-box {
    +	width: 70px;
    +	text-align: center;
    +}
    +.qty-txt-box i {
    +	font-size: 14px;
    +	margin-left: 5px;
    +	cursor: pointer;
    +}
    +.qty-txt-box input[type=text] {
    +	width: 30px;
    +	text-align: center;
    +	padding: 5px 10px;
    +	height:auto
    +}
    +.shop-bottom-btns{
    +	overflow:hidden
    +}
    +tr.shipping{
    +	background:transparent !important
    +}
    +.list-item{
    +	padding:10px 0
    +}
    +.mfp-preloader {
    +	color: #ccc;
    +	position: absolute;
    +	top: 50%;
    +	left: 50%;
    +	width: 24px;
    +	height: 24px;
    +	background: url(../images/ajax-loader-dark.gif) center center no-repeat;
    +	text-align: center;
    +	margin-top: -12px;
    +	margin-left: -12px;
    +	z-index: 1044;
    +	text-indent: -9999px;
    +}
    +.shop-ajax {
    +	position: relative;
    +	width: 800px;
    +	margin: 0 auto;
    +	overflow:hidden;
    +	padding:20px;
    +	-webkit-transition: opacity 0.35s, -webkit-transform 0.35s;
    +	transition: opacity 0.35s, transform 0.35s;
    +	-webkit-transform: translate3d(0,50px,0);
    +	transform: translate3d(0,50px,0);
    +}
    +.newEff{
    +	-webkit-transform: translate3d(0,0,0);
    +	transform: translate3d(0,0,0);
    +}
    +.shop-ajax h1{
    +	font-size:23px;
    +	font-weight:bold;
    +	margin:0;
    +	padding:15px 0 0
    +}
    +.shop-ajax .list li{
    +	line-height:23px
    +}
    +.sidebar_widgets li.widget.widget-ads {
    +	-webkit-box-shadow: none;
    +	-moz-box-shadow: none;
    +	box-shadow: none;
    +	padding:0;
    +	border:0;
    +	text-align:center;
    +	background:transparent
    +}
    +.sidebar_widgets li.widget.widget-ads:after,.sidebar_widgets li.widget.widget-ads:before{
    +	display:none
    +}
    +/*
    +------------------ shop-main-menu ------------ */
    +.shop-main-menu {
    +	-webkit-box-shadow: 0px 0 2px 0px rgba(0,0,0,0.3);
    +	-moz-box-shadow: 0px 0 2px 0px rgba(0,0,0,0.3);
    +	box-shadow: 0px 0 2px 0px rgba(0,0,0,0.3);
    +}
    +.shop-main-menu > ul > li{
    +	padding:0 15px;
    +	position:relative
    +}
    +.shop-main-menu > ul > li a{
    +	line-height:46px;
    +	display:block
    +}
    +.shop-main-menu ul li i{
    +	position:absolute;
    +	right:15px;
    +	top:15px;
    +	font-size: 10px;
    +	color: #ccc;
    +}
    +.shop-ads-top{
    +	padding:3px;
    +}
    +.shop-main-menu > ul > li > ul{
    +	display:none;
    +	position:absolute;
    +	left:100%;
    +	top:-1px;
    +	width:250px;
    +	z-index:99;
    +	-webkit-box-shadow: 0px 0 2px 0px rgba(0,0,0,0.3);
    +	-moz-box-shadow: 0px 0 2px 0px rgba(0,0,0,0.3);
    +	box-shadow: 0px 0 2px 0px rgba(0,0,0,0.3);
    +}
    +.shop-main-menu > ul > li:hover > ul{
    +	display:block;
    +}
    +.shop-main-menu li li a{
    +	line-height:40px;
    +	padding:0 15px
    +}
    +.shop-main-menu li h4{
    +	padding:0 0 5px;
    +	margin:0;
    +	font-size:15px;
    +	font-weight:bold
    +}
    +.shop-main-menu > ul > li > ul.mega{
    +	width:200%;
    +	padding:20px
    +}
    +.shop-main-menu > ul > li > ul.mega li a{
    +	line-height:35px;
    +	border-bottom:0;
    +	padding:0
    +}
    +.shop-main-menu .brands li{
    +	float:left;
    +	margin:5px
    +}
    +
    +/* clients */
    +.clients img{
    +	opacity:0.4
    +}
    +.clients img:hover{
    +	opacity:1
    +}
    +
    +/* ==========================================================================
    +  8. FOOTER.
    +============================================================================= */
    +/*
    +------------- 8.1. Footer 1 -------------- */
    +.footer-top {
    +	overflow: hidden;
    +	padding: 10px 0;
    +}
    +.footer-top p {
    +	margin: 0;
    +	padding: 0;
    +	font-size: 14px;
    +}
    +.footer-top .block-link{
    +	display:inline-block;
    +	margin:-10px 0;
    +	padding:13px;
    +	font-size:16px;
    +	padding-right:30px;
    +	padding-left:30px
    +}
    +.footer-top .twitter-text p{
    +	margin: 0;
    +	padding: 0;
    +	font-size: 14px;
    +	line-height:30px !important
    +}
    +.footer-top .twitter-text p{
    +	margin: 0;
    +	padding: 0;
    +	font-size: 14px;
    +	line-height:30px !important
    +}
    +.footer-top .social-list li a{
    +	border:0px !important
    +}
    +.footer-top .twitter-pic{
    +	display:none
    +}
    +.twitter-pic{
    +	text-align:center;
    +	margin:0 0 15px
    +}
    +.twitter-pic img{
    +	border-radius:50%;
    +	display:table;
    +	margin:auto
    +}
    +.footer-middle .twitter-pic img{
    +	border-radius:0px;
    +}
    +.twitter-text p{
    +	margin-bottom:0
    +}
    +#loading-container{
    +	display:table;
    +	margin:auto
    +}
    +.footer-middle {
    +	padding: 100px 0;
    +	height: 100%;
    +	position: relative;
    +	overflow: hidden;
    +	color: #aaa;
    +	background:#222
    +}
    +.foot-text-widget p {
    +	margin-bottom: 0;
    +}
    +.footer-middle .container {
    +	position: relative;
    +	z-index: 1;
    +}
    +.bottom-md-footer{
    +	background: #161616;
    +	padding:20px 5px;
    +	overflow:hidden
    +}
    +.bottom-md-footer .form-control{
    +	display:inline-block;
    +	float:left;
    +	width:75%;
    +	background:#000;
    +	border-color:#333;
    +}
    +.bottom-md-footer .btn{
    +	padding:10px 12px;
    +}
    +.bottom-md-footer label{
    +	margin-bottom:10px
    +}
    +.footer-middle a {
    +	color: #bbb;
    +}
    +.nl{
    +	position:relative;
    +}
    +.nl .btn{
    +	margin-left:-30px
    +}
    +.nl-note{
    +	position:absolute;
    +	left:0;
    +	bottom:-15px;
    +	z-index:9;
    +	padding:8px 15px;
    +	color:#333;
    +	width:75%;
    +}
    +.revtp-form .nl-note{
    +	bottom:auto;
    +	top:-125%;
    +	padding:20px
    +}
    +.footer-middle h3 {
    +	font-size: 16px;
    +	position:relative;
    +	text-transform: uppercase;
    +	letter-spacing: 0.5px;
    +	color: #ccc;
    +	font-weight: 700;
    +	margin-bottom: 40px;
    +}
    +.footer-middle h3:after {
    +	content: "";
    +	width: 9%;
    +	height: 2px;
    +	display: block;
    +	margin: 15px 0;
    +}
    +.footer-middle h3:after {
    +	content: "";
    +	width: 9%;
    +	height: 2px;
    +	display: block;
    +	margin: 15px 0;
    +}
    +.footer-middle h3:before {
    +	content: "";
    +	width: 25%;
    +	height: 2px;
    +	display: block;
    +	position: absolute;
    +	left: 10%;
    +	bottom: 0px;
    +	background: #404040;
    +}
    +.footer-middle .menu-widget li {
    +	padding: 12px 0;
    +	border-top: 1px #2f2f2f solid;
    +	margin-right: 10px;
    +}
    +.footer-middle .menu-widget li:first-child {
    +	border-top: 0;
    +	padding-top:0
    +}
    +.footer-middle .menu-widget li a {
    +	position: relative;
    +}
    +.footer-middle .menu-widget li a:before {
    +	content: "\f105";
    +	display: inline-block;
    +	margin-right: 8px;
    +	font: normal normal normal 12px/1 FontAwesome;
    +}
    +.contact-widget {
    +	background: transparent url('../images/world.png') no-repeat 50% 50%;
    +}
    +.contact-widget p {
    +	margin-bottom: 10px;
    +}
    +.contact-widget .details li {
    +	margin: 13px 0;
    +	line-height: 1.5;
    +	letter-spacing: 0.6px;
    +}
    +.contact-widget .details li i{
    +	display:table-cell;
    +	position: relative;
    +	vertical-align: middle;
    +}
    +.contact-widget .details li i:before {
    +	margin-right: 15px;
    +	color: #949494;
    +	width: 30px;
    +	height:30px;
    +	line-height:30px;
    +	background: #333;
    +	font-size:12px;
    +	display:block;
    +	text-align:center;
    +}
    +.contact-widget .details li span{
    +	display:table-cell;
    +	vertical-align:middle
    +}
    +.footer-bottom {
    +	padding: 25px 0;
    +	overflow: hidden;
    +	font-size: 13px;
    +	color: #6b6b6b;
    +	background-color: #111;
    +}
    +.footer-bottom .footer-menu li {
    +	float: left;
    +	padding: 0 0 0 15px;
    +}
    +.footer-bottom .footer-menu li:first-child{
    +	padding:0
    +}
    +.footer-bottom .footer-menu li a {
    +	color: #969595;
    +	text-transform: uppercase;
    +}
    +.footer-bottom .social-list li{
    +	margin-bottom:0
    +}
    +.footer-bottom .social-list li a{
    +	border:0 !important;
    +	border-radius:0px;
    +	height:45px;
    +	width:45px;
    +	line-height:45px
    +}
    +#footWrapper .social-list li a {
    +	border: 1px #515151 solid;
    +	color: #bbb;
    +}
    +
    +/*
    +----------- 8.2. Footer 2 --------------- */
    +.footer-2 .footer-middle {
    +	background-image: url('../images/footer-bg.jpg');
    +	background-position: 0 0;
    +	background-repeat: no-repeat;
    +	background-size: 100% 100%;
    +}
    +.footer-2 .footer-middle:after {
    +	display: none;
    +}
    +.footer-2 .footer-bottom {
    +	padding: 0;
    +}
    +.footer-2 .footer-bottom .copyrights {
    +	padding: 15px 0 13px;
    +}
    +
    +/*
    +----------- 8.3. Footer 3 --------------- */
    +.footer-3 .footer-top {
    +	background-color: #282828;
    +}
    +.footer-3 .footer-top p {
    +	color: #959595;
    +	height:30px;
    +	line-height:30px
    +}
    +.footer-3 .footer-top .social-list {
    +	margin: -5px 0;
    +}
    +.footer-3 .footer-top .social-list li {
    +	margin: 0 1px;
    +}
    +.footer-3 .footer-middle{
    +	background-color:#111
    +}
    +.footer-3 .footer-middle:after {
    +	display: none;
    +}
    +.footer-3 .footer-bottom {
    +	background-color: #282828;
    +}
    +
    +/*
    +----------- 8.4. Footer 4 --------------- */
    +.footer-4 .footer-middle:after{
    +	display:none
    +}
    +.footer-4 .footer-middle {
    +	padding:0
    +}
    +.footer-4 .footer-middle .container{
    +	position:relative;
    +	padding-top:50px;
    +	padding-bottom:50px;
    +	overflow:hidden
    +}
    +.footer-4 .footer-middle .container:before{
    +	position: absolute;
    +	height: 100%;
    +	width: 50%;
    +	left: 25%;
    +	content: "";
    +	display: inline-block;
    +	top: 0;
    +	z-index: -1;
    +	margin-left: -15px;
    +}
    +.footer-4 .footer-bottom{
    +	padding:30px 0;
    +	text-align:center
    +}
    +.footer-4 .footer-menu-center{
    +	display:table;
    +	margin:10px auto 0
    +}
    +
    +/*
    +----------- 8.5. Footer light --------------- */
    +.footer-light .footer-middle:after{
    +	display:none
    +}
    +.footer-light .footer-middle {
    +	padding:0;
    +}
    +.footer-light .footer-middle .container{
    +	position:relative;
    +	padding-top:50px;
    +	padding-bottom:50px;
    +	overflow:hidden
    +}
    +.footer-light .footer-middle .container:before{
    +	position: absolute;
    +	height: 100%;
    +	width: 50%;
    +	left: 25%;
    +	background: #e2e2e2;
    +	content: "";
    +	display: inline-block;
    +	top: 0;
    +	z-index: -1;
    +	margin-left: -15px;
    +}
    +.footer-light .footer-bottom{
    +	padding:30px 0;
    +	text-align:center
    +}
    +.footer-light .footer-menu-center{
    +	display:table;
    +	margin:10px auto 0
    +}
    +.footer-light .social-list li a{
    +	border:1px #ccc solid !important
    +}
    +.footer-light .contact-widget .details li i:before{
    +	background:#E0E0E0
    +}
    +
    +/*
    +----------- 8.6. Footer Minimal --------------- */
    +.footer-minimal .footer-middle:after {
    +	display: none;
    +}
    +.footer-minimal .footer-bottom {
    +	padding: 0;
    +}
    +.footer-minimal .footer-bottom .copyrights {
    +	padding: 15px 0 13px;
    +}
    +.footer-logo-txt{
    +	margin: 0 20px;
    +	width: 40%;
    +	line-height: 1.7;
    +}
    +.minimal-info{
    +	line-height:25px;
    +}
    +.minimal-info i{
    +	margin-right:10px
    +}
    +.centered{
    +	display:table;
    +	margin:auto
    +}
    +.minimal-socials li{
    +	margin:0 4px;
    +}
    +.footer-menu li{
    +	float:left;
    +	padding:0 0 0 15px;
    +	text-transform:uppercase;
    +	font-size: 12px;
    +}
    +.footer-menu li:first-child{
    +	padding:0 0 0 0
    +}
    +
    +/*
    +------------------- 8.7. Fixed Footer -------------- */
    +.fixed-footer{
    +	position:fixed;
    +	bottom:0;
    +	z-index:99;
    +	width:100%;
    +	left:0
    +}
    +.fixed-foot{
    +	position:fixed;
    +	z-index:999;
    +	bottom:20px;
    +	left:20px;
    +	padding:10px 15px;
    +	background-color: rgba(0, 0, 0, 0.52);
    +	color:#fff;
    +	font-size:13px;
    +	letter-spacing:0.6px
    +}
    +.fixed-footer .footer-bottom{
    +	background-color: rgba(0, 0, 0, 0.52);
    +}
    +.fixed-footer.no-bg .footer-bottom{
    +	background-color:transparent
    +}
    +.fixed-footer.no-bg .container{
    +	background-color: rgba(0, 0, 0, 0.52);
    +	padding:5px 0 5px 15px;
    +	margin-bottom:20px
    +}
    +.fixed-footer .social-list li {
    +	margin-bottom:0 !important
    +}
    +.fixed-footer .social-list li a{
    +	border:0 !important;
    +	width:45px;
    +	height:45px;
    +	line-height:45px;
    +	border-radius:0
    +}
    +.copy2{
    +	line-height:45px
    +}
    +.fullscreen{
    +	overflow:hidden;
    +	position:relative;
    +	height:100%
    +}
    +.fullscreen video{
    +	z-index:1;
    +	position:absolute;
    +	left:-10%;
    +	top:-10%;
    +	width:130%;
    +	height:130%;
    +}
    +.fullscreen .video-overlay{
    +	z-index:2
    +}
    +.fullscreen .main-txt{
    +	position:absolute;
    +	z-index:3;
    +	left:0;
    +	width:100%
    +}
    +.fixed-lft-foot{
    +	position:fixed;
    +	left:0;
    +	bottom:0;
    +	width: 280px;
    +}
    +.fixed-lft-foot .copyrights{
    +	line-height:normal;
    +	margin-bottom:10px
    +}
    +.foot-lft-socials ul{
    +	display:table;
    +	margin:auto
    +}
    +
    +/* footer contact widget */
    +.contact-widget .social-list {
    +	margin: 20px 0 0;
    +}
    +
    +/* footer tags widget */
    +.tags li {
    +	float: left;
    +	margin: 0 2px 7px;
    +	height: 30px;
    +	overflow: hidden;
    +	line-height: 30px;
    +	border: 1px #4c4c4c solid;
    +	display: inline-block;
    +}
    +.tags li a {
    +	display: table;
    +	width: 100%;
    +	height: 200%;
    +	position: relative;
    +	top: 0;
    +	text-align: center;
    +	font-size: 11px;
    +	text-transform: uppercase;
    +	padding: 0 10px;
    +	z-index:1;
    +}
    +.tags.hover-effect li:hover{
    +	border-color:#4c4c4c
    +}
    +.tags.hover-effect li:hover{
    +	border-color:#4c4c4c
    +}
    +.tags.hover-effect li:hover a {
    +	top: 28px;
    +	right: 0;
    +}
    +.tags.hover-effect li a:after {
    +	text-align: center;
    +	position: absolute;
    +	width: inherit;
    +	height: 50%;
    +	left: 0;
    +	top: -28px;
    +	line-height: 30px;
    +	z-index: 0;
    +	display:block
    +}
    +footer .tags li {
    +	border: 1px #4c4c4c solid;
    +	color: #6b6b6b;
    +}
    +footer .tags li a {
    +	color: #bbb;
    +}
    +
    +/* footer recent posts widget */
    +.recent-posts-footer li {
    +	margin-bottom: 10px;
    +	padding: 10px 0 0;
    +	border-top: 1px rgba(255,255,255,0.05) solid;
    +	overflow: hidden;
    +}
    +.recent-posts-footer li:first-child{
    +	border-top:0
    +}
    +.recent-posts-footer li:first-child{
    +	border-top:0
    +}
    +.recent-posts-footer li .post-img {
    +	float: left;
    +	margin-right: 10px;
    +	max-height: 40px;
    +	overflow: hidden;
    +}
    +.recent-posts-footer li .post-img  img {
    +	padding: 1px;
    +	width: 40px;
    +	border:1px #2d2d2d solid
    +}
    +.recent-posts-footer li h4 {
    +	overflow: hidden;
    +	margin-bottom: 3px;
    +	height: 18px;
    +	-ms-text-overflow: ellipsis;
    +	-o-text-overflow: ellipsis;
    +	text-overflow: ellipsis;
    +	white-space: nowrap;
    +	font-size: 12px;
    +	font-weight:normal
    +}
    +.recent-posts-footer li .meta {
    +	display: inline-block;
    +	margin-right: 10px;
    +	font-size:11px;
    +	color:#999
    +}
    +.recent-posts-footer li .meta i{
    +	margin: 0 5px 0 0;
    +}
    +
    +/***** tweets widget *****/
    +.tweets-widget .tweet_avatar{
    +	float:left;
    +	width:50px;
    +	height:50px
    +}
    +.tweets-widget .tweets_txt{
    +	margin-left:65px
    +}
    +.tweets-widget .tweets_txt span,.tweets-widget .tweets_txt a{
    +	display:block;
    +}
    +.tweets-widget .widget-content,.tweets-widget .slick-slider{
    +	overflow:visible
    +}
    +.footer-top p,.footer-top .tweets_txt {
    +	margin: 0;
    +	padding: 0;
    +	font-size: 14px;
    +}
    +.footer-top div.tweets > div{
    +	padding:0 66px 0 30px;
    +	line-height:30px
    +}
    +.footer-top div.tweets > div:before{
    +	font: normal normal normal 19px/1 FontAwesome;
    +	position: absolute;
    +	left: 0;
    +	top: 6px;
    +	content: "\f099";
    +	display: inline-block;
    +}
    +.footer-top div.tweets > div a{
    +	text-decoration:underline
    +}
    +.footer-top div.tweets .slick-prev,.footer-top div.tweets .slick-next{
    +	border:0;
    +	background:rgba(0,0,0,.11);
    +	position:absolute;
    +	right:0px;
    +	font-size:0px;
    +	top:-2px;
    +	width:30px;
    +	height:30px;
    +}
    +.footer-top div.tweets .slick-prev:before,.footer-top div.tweets .slick-next:before{
    +	font: normal normal normal 15px/0.8 FontAwesome;
    +	content: "\f106";
    +	display: inline-block;
    +	line-height:31px
    +}
    +.footer-top div.tweets .slick-prev{
    +	right:33px;
    +	background:rgba(0,0,0,.22);
    +}
    +.footer-top div.tweets .slick-prev:before{
    +	content: "\f107";
    +}
    +.footer-top div.tweets .slick-dots{
    +	display:none !important
    +}
    +/******* Footer Flickr **********/
    +ul.flickr-widget li{
    +	float:left;
    +	margin:0 1px 1px 0;
    +	position:relative;
    +	overflow:hidden
    +}
    +ul.flickr-widget li img, ul.flickr-widget .img-overlay {
    +	width: 64px;
    +	height: 64px;
    +}
    +ul.flickr-widget .img-overlay:before {
    +	font-size: 22px;
    +	line-height: 59px;
    +	height: 59px;
    +	font-weight: 100;
    +}
    +ul.flickr-widget .flickr{
    +	height:59px;
    +	display:block;
    +	overflow:hidden
    +}
    +ul.flickr-widget .img-overlay,.zoom .img-overlay {
    +	position: absolute;
    +	top: 0;
    +	width: 100%;
    +	height: 100%;
    +	opacity: 0;
    +	background:rgba(0,0,0,.8);
    +	left:0;
    +	transform:scale(2);
    +	-webkit-transform:scale(2);
    +	-moz-transform:scale(2);
    +	-ms-transform:scale(2);
    +}
    +ul.flickr-widget .img-overlay:before,.zoom .img-overlay:before {
    +	display: block;
    +	content: "\f00e";
    +	text-align: center;
    +	font-size: 15px;
    +	font-family: FontAwesome;
    +	line-height: 60px;
    +}
    +ul.flickr-widget li:hover .img-overlay,.zoom:hover .img-overlay {
    +	opacity: 1;
    +	transform:scale(1);
    +	-webkit-transform:scale(1);
    +	-moz-transform:scale(1);
    +	-ms-transform:scale(1);
    +}
    +.zoom{
    +	position:relative;
    +	display:inline-block;
    +}
    +#footWrapper .footer-middle .tweets-widget .twitter-pic{
    +	float:left
    +}
    +#footWrapper .footer-middle .tweets-widget{
    +	position:relative;
    +	overflow:visible
    +}
    +#footWrapper .footer-middle .tweets-widget .twitter-text{
    +	margin:-5px 0 0 57px
    +}
    +
    +/* ==========================================================================
    +  9. HOME ELEMENTS
    +============================================================================= */
    +.sm-mob{
    +	position:absolute;
    +	right: 73px;
    +	bottom: 20px;
    +}
    +.vertical-icons .icon-box-small{
    +	border-top:1px rgba(255,255,255,0.2) solid
    +}
    +.vertical-icons .icon-box-small:first-child{
    +	border-top:0
    +}
    +.vertical-icons .icon-box-small .icon-sm-desc{
    +	margin-left:90px
    +}
    +.icon-sm-desc{
    +	margin-left:70px
    +}
    +.portfolio-slider.no-margin .portfolio-item{
    +	margin:0 1px !important;
    +}
    +.three-imgs{
    +	text-align:center;
    +	position:relative;
    +	clear:both
    +}
    +.three-imgs .img-2{
    +	position:absolute;
    +	left:10%;
    +	bottom:-20px
    +}
    +.three-imgs .img-3{
    +	position:absolute;
    +	right:10%;
    +	bottom:-20px
    +}
    +.gallery_thumbs li{
    +	float:left;
    +	width:120px;
    +	height:80px;
    +	margin:0 1px 1px 0;
    +	overflow:hidden
    +}
    +.gallery_thumbs a{
    +	display:block;
    +	overflow:hidden
    +}
    +.gallery_thumbs li .img-overlay:before{
    +	line-height:80px
    +}
    +.gallery_thumbs li .img-overlay:before{
    +	line-height:80px
    +}
    +.chef_rit{
    +	background:transparent url('../images/demos/restaurant/chef.jpg') no-repeat;
    +	min-height:430px !important
    +}
    +.left-video-box{
    +	padding:50px 80px !important
    +}
    +.small-video{
    +	width:400px;
    +	margin-right:20px;
    +	overflow:hidden
    +}
    +.portfolio-bg{
    +	background:#000
    +}
    +.entry-image{
    +	margin:0 0 15px
    +}
    +.entry-content h5{
    +	margin-bottom:8px;
    +}
    +.entry-content .post-meta{
    +	margin-bottom:10px;
    +	overflow:hidden
    +}
    +.break-news{
    +	padding:0 30px 0 0;
    +	margin:15px 0;
    +	position:relative;
    +	padding-left:160px;
    +	overflow:hidden;
    +	height:50px;
    +	line-height:50px
    +}
    +span.lbl{
    +	position:absolute;
    +	left:0;
    +	top:0;
    +	padding:0 15px;
    +	font-size:12px;
    +	font-weight:bold;
    +	height:50px;
    +	line-height:50px;
    +	text-transform:uppercase
    +}
    +.break-news-slider{
    +	overflow:visible
    +}
    +.lft-pad-cell{
    +	padding-right:30px !important
    +}
    +.inner-magazine .post-content{
    +	background:transparent !important;
    +	margin-left:0 !important
    +}
    +.inner-magazine .post-item{
    +	margin-bottom:0
    +}
    +.p-1-col .portfolio-item, .lg-item{
    +	border-bottom-style:dashed !important
    +}
    +.inner-magazine .post-content .post-info-container{
    +	padding:0
    +}
    +.inner-magazine .post-item .post-content p{
    +	padding:5px 0 !important
    +}
    +.small_items{
    +	padding: 20px 0 0;
    +}
    +.small_items .post-item{
    +	margin-bottom:0
    +}
    +.small_items .entry-image{
    +	width:50px;
    +	height:50px;
    +	float:left;
    +	margin:0 15px 0 0;
    +}
    +.small_items .entry-content{
    +	position:relative;
    +	overflow:hidden;
    +}
    +.small_items .entry-content h5{
    +	margin-bottom:7px;
    +	font-size:14px;
    +}
    +.lg-item{
    +	padding-bottom: 20px;
    +	margin-bottom: 0;
    +}
    +.lg-item{
    +	padding-bottom: 20px;
    +	margin-bottom: 0;
    +}
    +.inner-magazine .heading{
    +	padding-bottom: 1px !important;
    +}
    +.inner-magazine .gallery_thumbs li{
    +	float:left;
    +	width:100px;
    +	height:80px;
    +	margin:0 1px 1px 0;
    +	overflow:hidden
    +}
    +.inner-magazine.col-md-8 .gallery_thumbs li,.inner-magazine.col-md-8 .gallery_thumbs li img{
    +	width: 103px;
    +	height:82px;
    +}
    +.inner-magazine .gallery_thumbs li img{
    +	width:100px;
    +	height:80px;
    +}
    +.gallery_thumbs li .img-overlay:before{
    +	line-height:80px
    +}
    +.widget-tweets{
    +	padding: 15px 0 10px;
    +}
    +.socials-widget .social-list span,.socials-widget .social-list a{
    +	float:left;
    +	overflow:hidden
    +}
    +.socials-widget.style-2 .widget-content{
    +	margin:-15px
    +}
    +.socials-widget.style-2 .social-list span,.socials-widget.style-2 .social-list a{
    +	float:none;
    +	display:block;
    +	text-align:center
    +}
    +.socials-widget .social-list li{
    +	margin:0 0 12px 0;
    +	width:47%
    +}
    +.socials-widget.style-2 .social-list{
    +	margin-right:-15px;
    +	overflow:hidden
    +}
    +.socials-widget.style-2 .social-list li{
    +	width:24%;
    +	padding:15px 3px;
    +	margin:0;
    +}
    +.socials-widget.style-2 .widget-content{
    +	border-left:0
    +}
    +.socials-widget .social-list a{
    +	margin:0 8px 0 0
    +}
    +.socials-widget.style-2 .social-list a{
    +	margin: 0 auto 10px;
    +}
    +.socials-widget .social-list span{
    +	font-size:70%;
    +}
    +.socials-widget .social-list span strong{
    +	font-size:140% !important
    +}
    +.abs-logo{
    +	position:absolute;
    +	left:50%;
    +	top:100px;
    +	z-index:222;
    +	margin-left:-100px;
    +}
    +.diamond-grid {
    +	width: 700px;
    +	margin: 0 auto;
    +	padding-right: 10px;
    +	position: absolute;
    +	left:50%;
    +	margin-left:-350px;
    +	top:270px;
    +	z-index:333;
    +	height:900px
    +}
    +.diamonds {
    +	background: transparent;
    +	color: #fff;
    +	position: relative;
    +	-webkit-transform: rotate(45deg);
    +	-moz-transform: rotate(45deg);
    +	-ms-transform: rotate(45deg);
    +	-o-transform: rotate(45deg);
    +	transform: rotate(45deg);
    +	width: 23.3333333333333%;
    +	padding-bottom: 23.3333333333333%;
    +	display:block;
    +	margin: 5%;
    +	margin-top: -10%;
    +	float:left;
    +	border:1px #fff solid;
    +	background: rgba(255,255,255,.15);
    +}
    +.diamonds a{
    +	display:block;
    +	color:#fff;
    +	font-weight:bold
    +}
    +.diamonds:hover a{
    +	color:#fff !important
    +}
    +.diamonds i{
    +	display:block;
    +	font-size:30px;
    +	margin-bottom:5px;
    +	position:absolute;
    +	left:30%;
    +	top:30%;
    +	-webkit-transform: rotate(-45deg);
    +	-moz-transform: rotate(-45deg);
    +	-ms-transform: rotate(-45deg);
    +	-o-transform: rotate(-45deg);
    +	transform: rotate(-45deg);
    +}
    +.diamond-grid li.diamonds span {
    +	text-transform: uppercase;
    +	-webkit-transform: rotate(-45deg);
    +	-moz-transform: rotate(-45deg);
    +	-ms-transform: rotate(-45deg);
    +	-o-transform: rotate(-45deg);
    +	transform: rotate(-45deg);
    +	text-align: center;
    +	box-sizing: border-box;
    +	position: absolute;
    +	top:0;
    +	left: 0;
    +	width: 100%;
    +	height: 100%;
    +	text-align: center;
    +	padding-top: 50%;
    +	font-size: 19px;
    +}
    +.diamond-grid > li.diamonds:nth-child(1),.diamond-grid > li.diamonds:nth-child(2),.diamond-grid > li.diamonds:nth-child(3) {
    +	margin-top: 5%;
    +}
    +.diamond-grid > li.diamonds:nth-child(5n+4) {
    +	margin-left: 21.555555555%;
    +}
    +.diamond-grid > li.diamonds:nth-child(5n+6) {
    +	clear:left;
    +}
    +.diamond-grid > li.diamonds:nth-child(5n+6):last-of-type {
    +	margin-left: 38%;
    +}
    +.logo.xxlarge-text a{
    +	font-size:60px
    +}
    +.logo.xxlarge-text a span{
    +	line-height:48px
    +}
    +.side-one{
    +	position:fixed;
    +	left:0;
    +	top:200px;
    +	z-index: 99;
    +}
    +.side-one li{
    +	position:relative;
    +	height:50px;
    +	margin-bottom:2px;
    +	left:-85px
    +}
    +.side-one li a{
    +	display:block;
    +	line-height:50px;
    +	height:50px;
    +	padding-left:15px;
    +}
    +.side-one li a i{
    +	font-size:17px;
    +	position:static;
    +	float:right;
    +	width:50px;
    +	height:50px;
    +	line-height:50px;
    +	text-align:center;
    +}
    +.side-one li a span{
    +	position:relative;
    +	float:left
    +}
    +.side-one li:hover{
    +	left:0
    +}
    +
    +.odometer-value{
    +	background:transparent !important
    +}
    +
    +/* social icons */
    +.social-list li {
    +	float: left;
    +	-webkit-transition-duration: 0.4s;
    +	-moz-transition-duration: 0.4s;
    +	-o-transition-duration: 0.4s;
    +	transition-duration: 0.4s;
    +	margin: 0 5px 5px 0;
    +}
    +.sharrre .social-list li{
    +	margin:0
    +}
    +.social-list li a {
    +	position: relative;
    +	display:block;
    +	overflow: hidden;
    +	position:relative;
    +	text-align: center;
    +	width: 35px;
    +	height: 35px;
    +	line-height: 35px;
    +}
    +.social-list li a:before,.social-list li a:after{
    +	font-size: 16px;
    +	text-align: center;
    +	display:block
    +}
    +.social-list li a:before,.social-list li a:after {
    +	-webkit-transition: -webkit-top 0.4s;
    +	-moz-transition: top 0.4s;
    +	-o-transition: top 0.4s;
    +	transition: top 0.4s;
    +}
    +.social-list li a:hover:before {
    +	top: -100%;
    +}
    +.social-list li a:hover:after {
    +	top: 0;
    +}
    +.social-list li a:before{
    +	position:relative;
    +	top:0;
    +	left: 0;
    +}
    +.social-list li.sm-icon a{
    +	width:30px;
    +	height:30px;
    +	line-height:30px
    +}
    +.social-list li.sm-icon a:before,.social-list li.sm-icon a:after{
    +	font-size:13px
    +}
    +.social-list li.sm-icon a:hover:before {
    +	top: -30px;
    +}
    +.social-list li.sm-icon a:hover:after {
    +	top: -2px;
    +}
    +.social-list li.md-icon a{
    +	width:38px;
    +	height:38px;
    +	line-height:38px
    +}
    +.social-list li.lg-icon a{
    +	width:60px;
    +	height:60px;
    +	line-height:60px;
    +}
    +.social-list li.lg-icon a:before,.social-list li.lg-icon a:after{
    +	font-size:20px !important
    +}
    +.social-list li.xl-icon a{
    +	width:80px;
    +	height:80px;
    +	line-height:80px;
    +	font-size:30px !important
    +}
    +.social-list li.xl-icon a:before,.social-list li.xl-icon a:after{
    +	font-size:30px !important
    +}
    +.social-list li a:after {
    +	position: absolute;
    +	width: 100%;
    +	height: 100%;
    +	left: 0;
    +	text-shadow: 1px 1px 1px rgba(0,0,0,.5);
    +	z-index: 9999;
    +	top: 100%;
    +	display: block;
    +}
    +
    +/* ==========================================================================
    +  10. TYPOGRAPHY.
    +============================================================================= */
    +
    +/* css transitions */
    +a,.btn,.btn i,.social-list li a, .top-head .logo, .top-nav > ul > li.hasChildren > a:after, .top-nav > ul > li.hasChildren > span > a:after,.top-head.header-5 .top-nav > ul > li:before,.top-head.header-6 .top-nav > ul > li > a:before,.top-head.header-8 .top-nav > ul > li > a:before,
    +.clients img,.tags.hover-effect li,.tags.hover-effect li a,ul.flickr-widget .img-overlay,[class*= "btn-icon-"] span,[class*="btn-icon-"] i,.icon-box i,.icon-box h3,.box-1 .outlined i,.box-1.bordered:before, .box-1.bordered:after,.top-nav > ul > li,.icon-box-small i b:before,
    +.box-1.bordered .inner:before, .box-1.bordered .inner:after,.icon-box h3.bottom_half_border:after,.tabs-style-bottomline .nav-tabs>li:after,.slick-prev,.slick-next,.team-details,.team-box .box-2 .box-socials,.icons-style-1 i,.icons-style-1 .heading,
    +.team-box.box-2 .team-img span,.team-box.box-3 .team-img span,.team-box.box-2:hover .team-pos,.team-box.box-2:hover .team-name,.box-5,.box-5 .rounded-img, .pricing-tbl,.pagination ul li,.lg-box,.pricing-tbl.style-2 h3,.new-nav,.fun-separator,.msg-box,
    +.pricing-tbl.style-2 h3:before,.pricing-tbl.style-2 h3:after,.icon-box.gry-border-1,.item-img img ,.item-img .hidden-img,.gallery-caption,.team-box.box-4 .team-img,.team-box.box-4 .team-details, .inner-menu ul ul,.img-over,.diamond:before,.icon-box-small i:after,
    +.img-over .link,.img-over .zoom,.img-holder img,.shop-item,.p-style2 figure figcaption,.p-style3 figcaption::before,.p-style3 h4,.p-style3 .description,.zoom .img-overlay,.img-icon img,.top-bar li ul,.side-one li,.feature-details-hidden,.item-box,.side-nav ul li,
    +.diamonds,.post-image img,.post-img img,input,.pageWrapper:not(.left-side-wrap):not(.right-side-wrap) ,textarea,select ,.top-head.dark-transparent .top-nav > ul > li,.p-style3 figure img,.top-head.boxed-transparent .bot-line,.post-item .post-content,
    +.bottom_tools,.top-nav > ul > li:after,li.mega-menu .inner-mega:after,.feature-details,.feature-img figure a,.feature-img figure:before,.head-srch-cart,.icons-style-2 i,.icons-style-2 .heading,.top-head.header-5 .top-nav > ul > li .inner-mega:before,
    +.top-head.header-6 .top-nav > ul > li:before,.top-head.header-6 .top-nav > ul > li .inner-mega:before,.top-head.header-6 .top-nav > ul > li > span > a:before,.feature-img2 figure:after,.top-nav > ul > li:not(.mega-menu):before,.top-nav > ul > li.mega-menu > span:before,
    +.p-style5 figure .icon-links a:before{
    +	-moz-transition:all 0.4s ease;
    +	-ms-transition:all 0.4s ease;
    +	-o-transition:all 0.4s ease;
    +	-webkit-transition:all 0.4s ease;
    +	transition:all 0.4s ease;
    +}
    +.border10px{border-radius:10px}
    +.border3px{border-radius:3px}
    +.circle{border-radius:50%}
    +.main-border {border-style:solid;border-width:1px;}
    +.block {display:block;}
    +.over-hidden {overflow:hidden;}
    +.t-right {text-align:right;}
    +.t-left {text-align:left;}
    +.t-center {text-align:center;}
    +.f-right {float:right;}
    +.f-left {float:left;}
    +.f-none {float:none;}
    +.zindx-0{z-index:0}
    +.zindx-1{z-index:1}
    +.zindx-9{z-index:9}
    +.lg-font {font-size:50px;}
    +.xl-font {font-size:80px;}
    +.light-font {font-weight:300 !important;}
    +.heavy-font {font-weight:900 !important;}
    +.slider-txt {font-size:21px;}
    +.uppercase {text-transform:uppercase;}
    +.bold{font-weight:bold !important}
    +.bolder{font-weight:bolder !important}
    +.lft-img{
    +	margin-right:15px;
    +	float:left
    +}
    +.rit-img{
    +	margin-left:15px;
    +	float:right
    +}
    +.ollist,.ullist{
    +	margin-left:25px
    +}
    +.ollist li{
    +	list-style-type:decimal
    +}
    +.ullist li{
    +	list-style-type:disc
    +}
    +.bordered-img{
    +	padding:2px;
    +	border:1px #ddd solid
    +}
    +#to-top {
    +	position:fixed;
    +	right: 0px;
    +	bottom: 0;
    +	z-index:99;
    +	cursor:pointer;
    +}
    +#to-top span {
    +	width: 40px;
    +	height: 40px;
    +	text-align:center;
    +	line-height: 40px;
    +	display:block;
    +}
    +
    +/* slider styles */
    +.lft-tp-caption{
    +	left:0 !important
    +}
    +.slider-square-txt {
    +	padding:5px;
    +	text-transform:uppercase;
    +	font-size:80px;
    +	font-weight:800;
    +	line-height:1;
    +	border-width:2px;
    +	letter-spacing:-2px
    +}
    +.md-slide-head{
    +	font-size:28px;
    +}
    +.slider-md-txt{
    +	font-size:19px
    +}
    +.slider-lg-txt{
    +	font-size:23px;
    +	line-height:1.3
    +}
    +.lg-slide-head{
    +	font-size:53px;
    +	font-weight:900
    +}
    +.lg-slide-head2{
    +	font-size:40px;
    +	font-weight:900;
    +	border-bottom:1px #dedede solid;
    +	padding-bottom:10px;
    +	line-height:1
    +}
    +.banner_separator {
    +	height: 1px;
    +	background: rgba(0,0,0,0.2);
    +	width: 40%;
    +}
    +.banner_separator_wit {
    +	height: 1px;
    +	background: rgba(255,255,255,0.2);
    +	width: 40%;
    +}
    +.light-lg-txt{
    +	font-weight:200;
    +	font-size:28px;
    +	text-transform:uppercase
    +}
    +.bolder-lg-txt{
    +	font-weight:900;
    +	font-size:85px;
    +	text-transform:uppercase
    +}
    +.lg-list-item{
    +	font-weight:200;
    +	font-size:30px;
    +	text-transform:capitalize
    +}
    +.md-list-item{
    +	font-weight:700;
    +	font-size:18px;
    +	text-transform:uppercase
    +}
    +.md-list-item i{
    +	padding:10px 20px 10px 15px;
    +	border-right:1px #ccc solid;
    +	margin-right:20px;
    +	font-size:20px
    +}
    +.gry-sep{
    +	height:1px;
    +	background:#4c4c4c;
    +	width:460px
    +}
    +.light-gry-sep{
    +	height:1px;
    +	background:#ccc;
    +	width:350px
    +}
    +.lg-list-item i{
    +	padding:10px 20px 10px 15px;
    +	border-right:1px #4c4c4c solid;
    +	margin-right:20px;
    +	font-size:25px
    +}
    +.tp-caption a.btn.main-bg{
    +	color:#fff
    +}
    +.btn.main-bg.btn-3d{
    +	margin-bottom:4px
    +}
    +.pink-bg{
    +	background-color:#f358db;
    +	color:#fff
    +}
    +.pink-bg{
    +	background-color:#f358db;
    +	color:#fff
    +}
    +.light-pink-bg{
    +	background-color:#f888e7;
    +}
    +.dark-pink-bg{
    +	background-color:#C52B70;
    +}
    +.pink-bg.hexagon:before{
    +	border-right: 25px solid #f358db;
    +}
    +.pink-bg.hexagon:after{
    +	border-left: 25px solid #f358db;
    +}
    +.green-bg{
    +	background-color:#47d103;
    +	color:#fff
    +}
    +.light-green-bg{
    +	background-color:#7ceb45;
    +}
    +.green-bg.hexagon:before{
    +	border-right: 25px solid #47d103;
    +}
    +.green-bg.hexagon:after{
    +	border-left: 25px solid #47d103;
    +}
    +.blue-bg{
    +	background-color:#0090ff;
    +	color:#fff
    +}
    +.light-blue-bg{
    +	background-color:#5db2f3;
    +}
    +.blue-bg.hexagon:before{
    +	border-right: 25px solid #0090ff;
    +}
    +.blue-bg.hexagon:after{
    +	border-left: 25px solid #0090ff;
    +}
    +.orange-bg{
    +	background-color:#ec8a32;
    +	color:#fff
    +}
    +.light-orange-bg{
    +	background-color:#f2aa6a;
    +}
    +.orange-bg.hexagon:before{
    +	border-right: 25px solid #ec8a32;
    +}
    +.orange-bg.hexagon:after{
    +	border-left: 25px solid #ec8a32;
    +}
    +.fb-bg{
    +	background-color:#3b5998;
    +	color:#fff
    +}
    +.tw-bg{
    +	background-color:#00acee;
    +	color:#fff
    +}
    +.ln-bg{
    +	background:#0177b5;
    +	color:#fff
    +}
    +.rss-bg{
    +	background:#EE802F;
    +	color:#fff
    +}
    +.gplus-bg{
    +	background:#dd4b39;
    +	color:#fff
    +}
    +.yt-bg{
    +	background:#de2c28;
    +	color:#fff
    +}
    +.dr-bg{
    +	background:#c32361;
    +	color:#fff
    +}
    +.sound-bg{
    +	background:#ff4900;
    +	color:#fff
    +}
    +
    +.bg-full-rit,.bg-full-lft{
    +	position:absolute;
    +	width:500%;
    +	height:100%;
    +	z-index:-1
    +}
    +.bg-full-lft{
    +	left:-100%
    +}
    +.white-border{
    +	border:1px #fff solid;
    +}
    +.fa-hover > span {
    +	display: block;
    +	line-height: 40px;
    +	height: 40px;
    +	padding-left: 35px;
    +	-moz-transition: all 0.2s ease-in-out;
    +	-o-transition: all 0.2s ease-in-out;
    +	-webkit-transition: all 0.2s ease-in-out;
    +	transition: all 0.2s ease-in-out;
    +	cursor: pointer;
    +	position:relative
    +}
    +.fa-hover:hover > span{
    +	padding-left:45px
    +}
    +.fa-hover > span i{
    +	margin-right:9px;
    +	-moz-transition: all 0.3s ease-in-out;
    +	-o-transition: all 0.3s ease-in-out;
    +	-webkit-transition: all 0.3s ease-in-out;
    +	transition: all 0.1s ease-in-out;
    +	position:absolute;
    +	left:12px;
    +	top:13px
    +}
    +.fa-hover:hover > span i{
    +	font-size: 28px;
    +	top:5px;
    +	left:8px;
    +	transform:scale(1.1);
    +	-webkit-transform:scale(1.1);
    +	-moz-transform:scale(1.1);
    +	-ms-transform:scale(1.1);
    +}
    +.no-border{
    +	border:0 !important
    +}
    +.saf-tags.hover-effect li:hover a:after{
    +	background:transparent !important
    +}
    +
    +/*
    +--------- highlight, Dropcaps & Blockquote --------- */
    +.highlight-1 {
    +	background: #fcff00;
    +}
    +.dropcap {
    +	display: block;
    +	float: left;
    +	margin: 2px 8px 0 0;
    +	font-weight: bold;
    +	font-size: 36px;
    +	line-height: 36px;
    +}
    +.dropcap.main-color{
    +	font-weight:normal
    +}
    +.dropcap.main-bg{
    +	display:inline-block;
    +	padding:0 4px
    +}
    +blockquote {
    +	margin: 0;
    +	position:relative
    +}
    +blockquote:before,blockquote:after{
    +	content: "\f10d";
    +	display: inline-block;
    +	font: normal normal normal 25px/1 FontAwesome;
    +	position:absolute;
    +	left:18px;
    +	top:18px;
    +}
    +blockquote:after{
    +	content: "\f10e";
    +	right:18px;
    +	bottom:18px;
    +	left:auto;
    +	top:auto
    +}
    +blockquote p {
    +	margin: 0;
    +	margin-bottom: 0;
    +	font-size: 15px;
    +	line-height:27px;
    +	padding: 30px 20px 0 20px;
    +}
    +blockquote span {
    +	font-weight: bold;
    +	font-size: 16px;
    +	display:block;
    +	padding: 30px 40px 30px 60px;
    +}
    +.bquote-2{
    +	border:0
    +}
    +.bquote-2 p{
    +	color:#fff
    +}
    +.bquote-2:before,.bquote-2:after{
    +	color:rgba(0,0,0,.15)
    +}
    +.bquote-3{
    +	border-bottom-width:4px !important;
    +	border-bottom-style:solid;
    +	padding-bottom:0
    +}
    +.bquote-3 .bottom{
    +	padding-bottom:25px;
    +	position:relative
    +}
    +.bquote-3 .bottom:after{
    +	position:absolute;
    +	width: 0;
    +	height: 0;
    +	border-style: solid;
    +	border-width: 0 8px 8px 8px;
    +	content: "";
    +	left: 50%;
    +	bottom: -2px;
    +}
    +.bquotes_slider .bquote-3,.bquotes_slider .bquote-4 {
    +	margin-right:10px
    +}
    +.bquote-4 span.main-bg{
    +	padding: 15px !important;
    +	margin: 25px -20px -10px;
    +	position:relative
    +}
    +.bquote-4 span.main-bg:after{
    +	position:absolute;
    +	width: 0;
    +	height: 0;
    +	border-style: solid;
    +	border-width: 0 8px 8px 8px;
    +	content: "";
    +	left: 50%;
    +	top: -8px;
    +}
    +.bquote-4 span.main-bg:after{
    +	position:absolute;
    +	width: 0;
    +	height: 0;
    +	border-style: solid;
    +	border-width: 0 8px 8px 8px;
    +	content: "";
    +	left: 50%;
    +	top: -8px;
    +}
    +.bquote-4:after{
    +	bottom:70px
    +}
    +
    +/*
    +------------ list styles -------------- */
    +.list li{
    +	line-height:30px;
    +	overflow: hidden;
    +}
    +.list li i{
    +	font-size:11px;
    +	margin-right:8px;
    +	width:25px;
    +	height:25px;
    +	text-align:center;
    +	line-height:25px;
    +}
    +.list li.list-bg{
    +	margin-bottom:2px
    +}
    +.list li.list-bg i{
    +	width:35px;
    +	height:35px;
    +	line-height: 35px;
    +	font-size:15px;
    +	float:left
    +}
    +.date-time-list li{
    +	line-height:25px;
    +	padding:8px 0;
    +	overflow:hidden
    +}
    +.date-time-list i{
    +	float:left;
    +}
    +.lg-list li{
    +	line-height:40px
    +}
    +
    +/* sections bg */
    +.diamonds-pattern{
    +	background-image:url('../images/patterns/diamonds.png');
    +}
    +.diamonds-pattern-2{
    +	background-image:url('../images/patterns/diamonds-2.png');
    +}
    +.pattern-bg-1{
    +	background-image:url('../images/patterns/pattern-1.png');
    +}
    +video{
    +	width:100%;
    +	height:100%
    +}
    +.video-overlay {
    +	position: absolute;
    +	width: 100%;
    +	height: 100%;
    +	top: 0;
    +	left: 0;
    +	z-index: 5;
    +	background: rgba(0,0,0,.6);
    +	-webkit-backface-visibility: hidden;
    +}
    +
    +/* ==========================================================================
    +  11. IMPORTANT CLASSES
    +============================================================================= */
    +.txt-shadow{text-shadow: 1px 1px 1px rgba(0,0,0,.2);}
    +.font-10{font-size:10px !important}
    +.font-15{font-size:15px !important}
    +.font-20{font-size:20px !important}
    +.font-30{font-size:30px !important}
    +.font-40{font-size:40px !important;letter-spacing: 1px;}
    +.font-50{font-size:50px !important;letter-spacing: 1px;}
    +.font-60{font-size:60px !important;letter-spacing: 1px;}
    +.font-70{font-size:70px !important;letter-spacing: 1px;}
    +.font-80{font-size:80px !important;letter-spacing: 1px;}
    +.font-90{font-size:90px !important;letter-spacing: 1px;}
    +.font-100{font-size:100px !important;letter-spacing: 1px;}
    +.padding-horizontal-0 {padding-left: 0;padding-right: 0;}
    +.padding-horizontal-5 {padding-left: 5px;padding-right: 5px;}
    +.padding-horizontal-10 {padding-left: 10px;padding-right: 10px;}
    +.padding-horizontal-15 {padding-left: 15px;padding-right: 15px;}
    +.padding-horizontal-20 {padding-left: 20px;padding-right: 20px;}
    +.padding-horizontal-25 {padding-left: 25px;padding-right: 25px;}
    +.padding-horizontal-30 {padding-left: 30px;padding-right: 30px;}
    +.padding-horizontal-35 {padding-left: 35px;padding-right: 35px;}
    +.padding-horizontal-40 {padding-left: 40px;padding-right: 40px;}
    +.padding-horizontal-45 {padding-left: 45px;padding-right: 45px;}
    +.padding-horizontal-50 {padding-left: 50px;padding-right: 50px;}
    +.padding-horizontal-60 {padding-left: 60px;padding-right: 60px;}
    +.padding-horizontal-70 {padding-left: 70px;padding-right: 70px;}
    +.padding-horizontal-80 {padding-left: 80px;padding-right: 80px;}
    +.padding-horizontal-90 {padding-left: 90px;padding-right: 90px;}
    +.padding-horizontal-100 {padding-left: 100px;padding-right: 100px;}
    +.padding-vertical-0 {padding-top: 0;padding-bottom: 0;}
    +.padding-vertical-5 {padding-top: 5px;padding-bottom: 5px;}
    +.padding-vertical-10 {padding-top: 10px;padding-bottom: 10px;}
    +.padding-vertical-15 {padding-top: 15px;padding-bottom: 15px;}
    +.padding-vertical-20 {padding-top: 20px;padding-bottom: 20px;}
    +.padding-vertical-25 {padding-top: 25px;padding-bottom: 25px;}
    +.padding-vertical-30 {padding-top: 30px;padding-bottom: 30px;}
    +.padding-vertical-35 {padding-top: 35px;padding-bottom: 35px;}
    +.padding-vertical-40 {padding-top: 40px;padding-bottom: 40px;}
    +.padding-vertical-45 {padding-top: 45px;padding-bottom: 45px;}
    +.padding-vertical-50 {padding-top: 50px;padding-bottom: 50px;}
    +.padding-vertical-60 {padding-top: 60px;padding-bottom: 60px;}
    +.padding-vertical-70 {padding-top: 70px;padding-bottom: 70px;}
    +.padding-vertical-80 {padding-top: 80px;padding-bottom: 80px;}
    +.padding-vertical-90 {padding-top: 90px;padding-bottom: 90px;}
    +.padding-vertical-100 {padding-top: 100px;padding-bottom: 100px;}
    +.lg-padding{padding:120px 0}
    +.padding-bottom-0{padding-bottom:0}
    +.padding-top-0{padding-top:0}
    +.margin-0{margin:0}
    +.margin-vertical-0 {margin-top: 0;margin-bottom: 0;}
    +.margin-vertical-5 {margin-top: 5px;margin-bottom: 5px;}
    +.margin-vertical-10 {margin-top: 10px;margin-bottom: 10px;}
    +.margin-vertical-15 {margin-top: 15px;margin-bottom: 15px;}
    +.margin-vertical-20 {margin-top: 20px;margin-bottom: 20px;}
    +.margin-vertical-25 {margin-top: 25px;margin-bottom: 25px;}
    +.margin-vertical-30 {margin-top: 30px;margin-bottom: 30px;}
    +.margin-vertical-35 {margin-top: 35px;margin-bottom: 35px;}
    +.margin-vertical-40 {margin-top: 40px;margin-bottom: 40px;}
    +.margin-vertical-45 {margin-top: 45px;margin-bottom: 45px;}
    +.margin-vertical-50 {margin-top: 50px;margin-bottom: 50px;}
    +.margin-vertical-60 {margin-top: 60px;margin-bottom: 60px;}
    +.margin-vertical-70 {margin-top: 70px;margin-bottom: 70px;}
    +.margin-vertical-80 {margin-top: 80px;margin-bottom: 80px;}
    +.margin-vertical-90 {margin-top: 90px;margin-bottom: 90px;}
    +.margin-vertical-100 {margin-top: 100px;margin-bottom: 100px;}
    +.margin-top-0 {margin-top: 0;}
    +.margin-top-5 {margin-top: 5px;}
    +.margin-top-10 {margin-top: 10px;}
    +.margin-top-15 {margin-top: 15px;}
    +.margin-top-20 {margin-top: 20px;}
    +.margin-top-25 {margin-top: 25px;}
    +.margin-top-30 {margin-top: 30px;}
    +.margin-top-35 {margin-top: 35px;}
    +.margin-top-40 {margin-top: 40px;}
    +.margin-top-45 {margin-top: 45px;}
    +.margin-top-50 {margin-top: 50px;}
    +.margin-top-60 {margin-top: 60px;}
    +.margin-top-70 {margin-top: 70px;}
    +.margin-top-80 {margin-top: 80px;}
    +.margin-top-90 {margin-top: 90px;}
    +.margin-top-100 {margin-top: 100px;}
    +.margin-bottom-0 {margin-bottom: 0 !important;}
    +.margin-bottom-5 {margin-bottom: 5px;}
    +.margin-bottom-10 {margin-bottom: 10px;}
    +.margin-bottom-15 {margin-bottom: 15px;}
    +.margin-bottom-20 {margin-bottom: 20px;}
    +.margin-bottom-25 {margin-bottom: 25px;}
    +.margin-bottom-30 {margin-bottom: 30px;}
    +.margin-bottom-35 {margin-bottom: 35px;}
    +.margin-bottom-40 {margin-bottom: 40px;}
    +.margin-bottom-45 {margin-bottom: 45px;}
    +.margin-bottom-50 {margin-bottom: 50px;}
    +.margin-bottom-60 {margin-bottom: 60px;}
    +.margin-bottom-70 {margin-bottom: 70px;}
    +.margin-bottom-80 {margin-bottom: 80px;}
    +.margin-bottom-90 {margin-bottom: 90px;}
    +.margin-bottom-100 {margin-bottom: 100px;}
    +.margin-left-100{margin-left:100px}
    +.margin-auto{margin:auto;}
    +.width-10{width:10px}
    +.width-20{width:20px}
    +.width-30{width:30px}
    +.width-40{width:40px}
    +.width-50{width:50px}
    +.width-60{width:60px}
    +.width-70{width:70px}
    +.width-80{width:80px}
    +.width-90{width:90px}
    +.width-100{width:100px}
    +.width-percent-10{width:10%}
    +.width-percent-20{width:20%}
    +.width-percent-30{width:30%}
    +.width-percent-40{width:40%}
    +.width-percent-50{width:50%}
    +.width-percent-60{width:60%}
    +.width-percent-70{width:70%}
    +.width-percent-80{width:80%}
    +.width-percent-90{width:90%}
    +
    +.no-bg-btn{background:transparent none;border:0}
    +.right-cell {float: right !important;}
    +.left-text{text-align:left}
    +.center-tbl{
    +	display:table;
    +	margin:auto;
    +	float:none
    +}
    +.ads-box{
    +	padding:50px;
    +}
    +.ads-box p{
    +	line-height:1.4;
    +	margin:0;
    +	text-shadow:none;
    +	font-size:19px;
    +}
    +.section-full-bg{
    +	position:absolute;
    +	top: 0;
    +	width:300%;
    +	height: 100%;
    +	display:inline-block;
    +	z-index:0;
    +}
    +.section-full-bg.left.circle{
    +	border-radius:50em;
    +	border-top-left-radius:0;
    +	border-bottom-left-radius:0
    +}
    +.section-full-bg.right.circle{
    +	border-radius:50em;
    +	border-top-right-radius:0;
    +	border-bottom-right-radius:0
    +}
    +
    +.bg-block{
    +	position:relative;
    +	z-index:9;
    +	padding:50px 30px;
    +	border-width:5px;
    +	border-left-width:0;
    +	-webkit-box-shadow:-25px 0px 15px -15px rgba(50, 50, 50, 0.45);
    +	-moz-box-shadow:-25px 0px 15px -15px rgba(50, 50, 50, 0.45);
    +	box-shadow:-25px 0px 15px -15px rgba(50, 50, 50, 0.45);
    +}
    +.bg-block p{
    +	margin-bottom:0
    +}
    +.sec-bg.left.circle{
    +	border-radius:50em;
    +	border-top-left-radius:0;
    +	border-bottom-left-radius:0
    +}
    +.sec-bg.right.circle{
    +	border-radius:50em;
    +	border-top-right-radius:0;
    +	border-bottom-right-radius:0
    +}
    +.section-side{
    +	padding:0 40px
    +}
    +.section-full-bg.left{
    +	right: 0;
    +}
    +.section-full-bg.right{
    +	left:0;
    +}
    +.section-full-bg.left.circle{
    +	right: -25px;
    +}
    +.section-full-bg.right.circle{
    +	left:-25px;
    +}
    +.section-full-bg.left.rect{
    +	right: 30%;
    +}
    +.section-full-bg.right.rect{
    +	left:30%;
    +}
    +/* slick slider */
    +.testimonials-3 .slick-dots li button:before {
    +	font-size:30px !important;
    +	width:10px !important;
    +	height:10px !important ;
    +}
    +.testimonials-3 .slick-dots li button, .testimonials-3 .slick-dots li {
    +	width:12px !important;
    +	height:12px !important;
    +}
    +.testimonials-2 .slick-next, .testimonials-2 .slick-prev {
    +	position:absolute;
    +	left:0;
    +	top:50%;
    +	margin-top:-20px;
    +	width:40px;
    +	height:40px;
    +	line-height:40px;
    +	text-align:center;
    +	border:1px rgba(156, 156, 156 , 0.68) solid;
    +}
    +.testimonials-2 .slick-next:before, .testimonials-2 .slick-prev:before {
    +	font-size:20px;
    +	line-height:38px;
    +}
    +.testimonials-2 .slick-next {
    +	right:0;
    +	left:auto;
    +}
    +.img-holder .slick-dots{
    +	position:absolute;
    +	bottom:8px;
    +	right:10px
    +}
    +.pro-gallery .slick-dots{
    +	margin-top:-35px
    +}
    +.posts-gal .slick-dots{
    +	position:absolute;
    +	bottom:15px;
    +	right:15px
    +}
    +.shop-horizontal-slick .shop-item{
    +	margin-bottom:1px;
    +}
    +.product-img .slick-dots {
    +	display: table;
    +	margin: 5px auto 0;
    +	width:100%
    +}
    +.product-img .slick-dots li {
    +	display: table-cell;
    +	padding: 0 2px 0 0;
    +}
    +.product-img .slick-dots li img {
    +	width: 75px;
    +	cursor:pointer;
    +	opacity:0.6
    +}
    +.product-img .slick-dots li img:hover , .product-img .slick-dots li.slick-active img{
    +	opacity:1;
    +}
    +.shop-ajax .slick-prev, .shop-ajax .slick-next{
    +	position:absolute;
    +	top:50%;
    +	left:0;
    +	background:rgba(0,0,0,.5);
    +	color:#fff;
    +	width:40px;
    +	height:40px;
    +	line-height:40px;
    +	text-align:center;
    +	margin-top:-15px;
    +	display:inline-block
    +}
    +.shop-ajax .slick-prev:before, .shop-ajax .slick-next:before{
    +	line-height:40px;
    +	display:inline-block;
    +	width:40px;
    +	text-align:center
    +}
    +.shop-ajax .slick-next{
    +	left:auto;
    +	right:0
    +}
    +.shop-ads-top .slick-slide img{
    +	width:100%
    +}
    +.shop-ads-top .slick-dots{
    +	margin-top:-35px;
    +	margin-bottom:15px
    +}
    +.footer-top div.slick-s{
    +	height: 35px !important;
    +	overflow:hidden;
    +}
    +.footer-top div.slick-s .slick-slide{
    +	padding:0 66px 0 30px;
    +	line-height:60px;
    +	position:relative;
    +	overflow:hidden;
    +	height: 30px !important;
    +}
    +.footer-top div.slick-s .slick-slide:before{
    +	font: normal normal normal 19px/1 FontAwesome;
    +	position: absolute;
    +	left: 0;
    +	top: 6px;
    +	content: "\f099";
    +	display: inline-block;
    +}
    +.footer-top div.slick-s a{
    +	color:#fff
    +}
    +.footer-top div.slick-s .slick-prev,.footer-top div.slick-s .slick-next{
    +	border:0;
    +	background:rgba(0,0,0,.11);
    +	position:absolute;
    +	right:0px;
    +	font-size:0px;
    +	top: 0px;
    +	width: 35px;
    +	height: 30px;
    +	color:#fff;
    +}
    +.footer-top div.slick-s .slick-prev:before,.footer-top div.slick-s .slick-next:before{
    +	font: normal normal normal 15px/0.8 FontAwesome;
    +	content: "\f106";
    +	display: inline-block;
    +	margin-right: 3px;
    +}
    +.footer-top div.slick-s .slick-prev{
    +	right:33px;
    +	background:rgba(0,0,0,.22);
    +}
    +.footer-top div.slick-s .slick-prev{
    +	right: 35px;
    +	background:rgba(0,0,0,.22);
    +}
    +.footer-top div.slick-s .slick-prev:before{
    +	content: "\f107";
    +	margin-left: 3px;
    +	margin-right: 0;
    +}
    +.footer-top div.slick-s .slick-dots{
    +	display:none !important
    +}
    +.widget-tweets .slick-dots, .widget-tweets .slider_controls {
    +	margin: 10px auto;
    +}
    +.footer-light .footer-top div.slick-s a{
    +	color:#666;
    +	font-weight:normal !important
    +}
    +#footWrapper .footer-middle .tweets-widget .slick-prev,#footWrapper .footer-middle .tweets-widget .slick-next{
    +	display:block !important;
    +	position:absolute;
    +	right:0;
    +	top: -72px;
    +}
    +#footWrapper .footer-middle .tweets-widget .slick-prev{
    +	right:20px
    +}
    +#footWrapper .footer-middle .tweets-widget .slick-next:before {
    +	content: "\f106";
    +}
    +#footWrapper .footer-middle .tweets-widget .slick-prev:before {
    +	content: "\f107";
    +}
    +.break-news-slider .slick-prev,.break-news-slider .slick-next{
    +	position:absolute;
    +	top:10px;
    +	right:-25px
    +}
    +.break-news-slider .slick-prev{
    +	right:-5px
    +}
    +.tweets-widget .slick-prev,.tweets-widget .slick-next{
    +	position:absolute;
    +	top:-50px;
    +	right:-10px
    +}
    +.tweets-widget .slick-prev{
    +	right:10px
    +}
    +.horizontal-slider .slick-prev,.horizontal-slider .slick-next{
    +	position:absolute;
    +	left: 1px;
    +	background: #555;
    +	color: #FFF;
    +	width: 40px;
    +	height:40px;
    +	text-align:center;
    +	top:50%;
    +	margin-top:-20px;
    +	-webkit-transition: transform 0.45s;
    +	transition: transform 0.45s;
    +	-webkit-transform: translate3d(-60px,0,0);
    +	transform: translate3d(-60px,0,0);
    +	opacity:0;
    +	z-index:99;
    +	border-top-right-radius: 30px;
    +	border-bottom-right-radius: 30px;
    +}
    +.horizontal-slider .slick-prev:before,.horizontal-slider .slick-next:before{
    +	font-size:20px;
    +	display:inline-block;
    +	line-height:40px;
    +	position:relative
    +}
    +.horizontal-slider .slick-prev:before{
    +	left:auto;
    +}
    +.horizontal-slider .slick-next{
    +	left:auto;
    +	right: 1px;
    +	-webkit-transform: translate3d(60px,0,0);
    +	transform: translate3d(60px,0,0);
    +	border-top-right-radius: 0;
    +	border-bottom-right-radius: 0;
    +	border-top-left-radius: 30px;
    +	border-bottom-left-radius: 30px;
    +}
    +.horizontal-slider.slick-slider:hover .slick-prev,.horizontal-slider.slick-slider:hover .slick-next{
    +	-webkit-transform: translate3d(0,0,0);
    +	transform: translate3d(0,0,0);
    +	opacity:1
    +}
    +.horizontal-slider.slick-slider:hover .slick-prev,.horizontal-slider.slick-slider:hover .slick-next{
    +	-webkit-transform: translate3d(0,0,0);
    +	transform: translate3d(0,0,0);
    +	opacity:1
    +}
    +.show-arrows{
    +	overflow:visible
    +}
    +.show-arrows .slick-prev,.show-arrows .slick-next{
    +	opacity:1;
    +	top: -63px;
    +	right: 15px;
    +	left:auto;
    +	transform: translate3d(0,0,0);
    +	-webkit-transform: translate3d(0,0,0);
    +	width: 30px;
    +	height: 30px;
    +	border-top-right-radius: 30px;
    +	border-bottom-right-radius: 30px;
    +	border-top-left-radius: 0;
    +	border-bottom-left-radius: 0;
    +}
    +.show-arrows .slick-prev:before, .show-arrows .slick-next:before {
    +	font-size: 13px;
    +	line-height: 30px;
    +}
    +.show-arrows .slick-prev{
    +	right: 46px;
    +	border-top-right-radius: 0 !important;
    +	border-bottom-right-radius: 0 !important;
    +	border-top-left-radius: 30px;
    +	border-bottom-left-radius: 30px;
    +}
    +
    +/* ==========================================================================
    +  12. SHAPES
    +============================================================================= */
    +.new-angle,.panel.new-angle,.contact-widget .details li i.new-angle:before,.filter-by ul li.new-angle:after,.filter-by ul li.new-angle.active a,.top-head.header-2 .top-search.new-angle > a:before, .top-head.header-2 .top-cart.new-angle > a:before{
    +	border-top-right-radius: 1.2em;
    +	border-bottom-left-radius: 1.2em;
    +}
    +.new-angle.lg,.contact-widget .details li i.new-angle.lg:before{
    +	border-top-right-radius: 3em;
    +	border-bottom-left-radius: 3em;
    +}
    +.new-angle.sm,.contact-widget .details li i.new-angle.sm:before,.icon-box-small i.new-angle.sm:after{
    +	border-top-right-radius: 10px;
    +	border-bottom-left-radius: 10px;
    +}
    +.top-bar ul.new-angle{
    +	border-top-right-radius: 15px;
    +	border-bottom-left-radius: 15px;
    +}
    +.accordion.style-1 .panel >.panel-heading h4 a.new-angle:not(.collapsed):before{
    +	width: 97.7%;
    +	left: 2.5%;
    +}
    +.accordion.style-1 .panel >.panel-heading h4 a.round:not(.collapsed):before{
    +	width: 92%;
    +	left: 4%;
    +}
    +.accordion.style-3.new-angle .panel:first-child>.panel-heading h4 a:not(.collapsed){
    +	border-top-right-radius:1.2em
    +}
    +.nav-tabs.new-angle li:first-child a{
    +	border-bottom-left-radius:1.2em
    +}
    +.box-5.new-angle:hover .rounded-img{
    +	border-top-left-radius: 0;
    +	border-top-right-radius:2em;
    +	border-bottom-left-radius:0;
    +	border-bottom-right-radius:0
    +}
    +.box-5.new-angle:hover{
    +	border-top-right-radius: 2em;
    +	border-bottom-left-radius: 2em;
    +}
    +.new-angle.lg .slick-slide img{
    +	border-top-right-radius: 3em;
    +}
    +.feature-img .new-angle:before{
    +	border-top-right-radius: 1.2em;
    +	border-bottom-left-radius: 1.2em;
    +}
    +.feature-img .new-angle.lg:before{
    +	border-top-right-radius: 3em;
    +	border-bottom-left-radius: 3em;
    +}
    +.new-angle .slick-dots li:first-child img{
    +	border-bottom-left-radius: 1.2em;
    +}
    +.new-angle.icon-box.gry-border-2 .head-bg{
    +	border-top-right-radius: 0.9em;
    +}
    +.icon-box-small i.new-angle:after{
    +	border-top-right-radius: 1.2em;
    +	border-bottom-left-radius: 1.2em;
    +}
    +.progress-bar.new-angle span{
    +	border-radius:0 !important;
    +	top:0;
    +	right:0;
    +	border-top-right-radius: 1.5em !important;
    +	width: 30px !important;
    +	text-align: center;
    +}
    +.progress-bars.new-angle.xl-line.tool-tip .progress-bar span{
    +	height:35px;
    +	line-height:35px;
    +	top:0;
    +	right:0
    +}
    +.progress-bar.new-angle.lg span{
    +	border-radius:0 !important;
    +	top: 1px;
    +	right: 1px;
    +	border-top-right-radius: 3em !important;
    +	width: 40px !important;
    +	text-align: center;
    +}
    +.pricing-tbl.style-2.new-angle h3{
    +	border-top-right-radius: 0.8em;
    +}
    +.pricing-tbl.style-4.new-angle .plan-head{
    +	border-top-right-radius: 1em;
    +}
    +.new-angle.bquote-4 span.main-bg{
    +	border-bottom-left-radius: 1.6em;
    +}
    +.portfolio.horizontal-slider.new-angle .slick-list{
    +	border-top-right-radius: 8em;
    +	border-bottom-left-radius: 8em;
    +}
    +.footer-top div.slick-s.new-angle .slick-prev{
    +	border-top-left-radius: 20px;
    +	border-bottom-left-radius: 20px;
    +}
    +.footer-top div.slick-s.new-angle .slick-next{
    +	border-top-right-radius: 20px;
    +	border-bottom-right-radius: 20px;
    +}
    +.comment-list li.new-angle,.feature-img .new-angle{
    +	position:relative;
    +	overflow:hidden
    +}
    +
    +/*
    +---------------- round ---------------------- */
    +.shape.round,.feature-img:hover figure.round:before,.filter-by ul li.round:after,.filter-by ul li.round.active a,.top-head.header-2 .top-search.round > a:before, .top-head.header-2 .top-cart.round > a:before,.icon-box-small i.round:after,.feature-img figure.round:before{
    +	border-radius:20em
    +}
    +.panel.round,.testimonials-4 .testimonials-bg.round,.contact-widget .details li i.round:before,.team-box.round,[class*="tabs-style-"] .tab-content .tab-pane.round,.ads-box.round,.horizontal-slider.round,.accordion.style-3.round,.pricing-tbl.round,
    +[class*="bquote-"].round,.msg-box.round,.progress-bars.round,.sm-round.round,.post-item img.round,.my-info.round,.comment-list li.round,.icon-box.round,.testimonials-bg.round,.modal-content.round{
    +	border-radius:2.2em
    +}
    +.lg-slider.round{
    +	border-radius:20em
    +}
    +.lg-slider.round{
    +	border-radius:20em
    +}
    +.widget.round,textarea.round,.product-img.round{
    +	border-radius:1em
    +}
    +.pricing-tbl.round{
    +	overflow:hidden
    +}
    +.accordion.style-3.round .panel:first-child>.panel-heading h4 a:not(.collapsed){
    +	border-top-left-radius:2.2em;
    +	border-top-right-radius:2.2em
    +}
    +.icon-box.gry-border-2.round .head-bg{
    +	border-top-left-radius:1.7em;
    +	border-top-right-radius:1.7em
    +}
    +.nav-tabs.round li:first-child a{
    +	border-top-left-radius:10em;
    +	border-bottom-left-radius:10em
    +}
    +[class*="tabs-style-"] .tab-content .tab-pane:first-child.active.round{
    +	border-top-left-radius:0
    +}
    +.tabs-style-bg .tab-content .tab-pane.round{
    +	border-top-left-radius:0
    +}
    +
    +#footWrapper .social-list li a.round,.progress-bars.xl-line.tool-tip .progress-bar.round span{
    +	border-radius:50%
    +}
    +.round.bquote-4 span.main-bg {
    +    border-bottom-left-radius: 1.2em;
    +    border-bottom-right-radius: 1.2em;
    +}
    +.round.sm{
    +	border-radius:40px
    +}
    +.footer-top div.slick-s.round .slick-prev,.footer-top div.slick-s.round .slick-next{
    +	border-radius: 50%;
    +	width:30px
    +}
    +.footer-top div.slick-s.round .slick-prev:before, .footer-top div.slick-s.round .slick-next:before{
    +	margin:0
    +}
    +.feature-img figure.round a{
    +	right:50%;
    +	margin-right:-17.5px
    +}
    +.item-box.round .on-sale{
    +	left: 7%;
    +	top: 7%;
    +	width: 50px;
    +	height: 50px;
    +	line-height: 66px;
    +	border-radius: 50%;
    +}
    +
    +/*
    +---------------- square ---------------------- */
    +.shape.square{
    +	border-radius:0
    +}
    +html.square .pageWrapper *,html.square .circle:after,html.square .circle:before,html.square .full-heading:before,.box-5:hover .team-img{
    +	border-radius:0 !important
    +}
    +
    +/*
    +---------------- border5px ------------------- */
    +.border5px{border-radius:5px}
    +.accordion.style-3.border5px .panel:first-child >.panel-heading h4 a{
    +	border-top-left-radius: 3px;
    +	border-top-right-radius: 3px;
    +}
    +.icon-box-small i.border5px:after{
    +	border-radius: 5px;
    +}
    +html.border5px .bottom_tools,html.border5px .post-icon,html.border5px .post-item .post-content{
    +	border-bottom-left-radius: 5px;
    +	border-bottom-right-radius: 5px;
    +}
    +html.border5px .post-image .post-icon{
    +	border-bottom-left-radius: 0;
    +	border-bottom-right-radius: 0;
    +	border-top-left-radius: 5px;
    +	border-top-right-radius: 5px;
    +}
    +html.border5px .footer-top div.slick-s .slick-prev,html.border5px .footer-top div.slick-s .slick-next{
    +	border-radius:5px;
    +	width:30px;
    +}
    +html.border5px .footer-top div.slick-s .slick-prev:before,html.border5px .footer-top div.slick-s .slick-next:before{
    +	margin:0
    +}
    +html.border5px .top-head.boxed-transparent > .container,html.border5px .sidebar_widgets .tab-content{
    +	border-bottom-right-radius: 5px;
    +    border-top-right-radius: 5px;
    +}
    +html.border5px .full-heading:before,html.border5px .sidebar_widgets .tab-content{
    +	border-bottom-left-radius: 5px;
    +    border-bottom-right-radius: 5px;
    +}
    +html.border5px .top-head.boxed-transparent > .container{
    +	border-bottom-right-radius: 5px;
    +    border-top-right-radius: 5px;
    +}
    +html.border5px .full-heading:before{
    +	border-bottom-left-radius: 5px;
    +    border-bottom-right-radius: 5px;
    +}
    +.border5px.icon-box.gry-border-2 .head-bg{
    +	border-top-right-radius:5px;
    +	border-top-left-radius:5px
    +}
    +
    +/*
    +---------------- right-angle ------------------- */
    +.right-angle,.icon-box-small i.right-angle:after,.feature-img figure.right-angle:before,.filter-by ul li.right-angle.active a,.filter-by ul li.right-angle:after{
    +	border-top-right-radius: 30em;
    +	border-bottom-right-radius: 30em;
    +}
    +.widget.right-angle,textarea.right-angle,.product-img.right-angle,.modal-content.right-angle{
    +	border-top-right-radius:1em;
    +	border-bottom-right-radius:1em
    +}
    +.panel.right-angle,.testimonials-4 .testimonials-bg.right-angle,.contact-widget .details li i.right-angle:before,.team-box.right-angle,[class*="tabs-style-"] .tab-content .tab-pane.right-angle,.ads-box.right-angle,.horizontal-slider.right-angle,.accordion.style-3.right-angle,.pricing-tbl.right-angle,
    +[class*="bquote-"].right-angle,.msg-box.right-angle,.progress-bars.right-angle,.post-item img.right-angle,.my-info.right-angle,.comment-list li.right-angle,.icon-box.right-angle,.testimonials-bg.right-angle,.right-angle.bg-block{
    +	border-top-right-radius:2.2em;
    +	border-bottom-right-radius:2.2em
    +}
    +.right-angle.icon-box.gry-border-2 .head-bg,.right-angle.accordion.style-3 .panel:first-child >.panel-heading h4 a, .pricing-tbl.right-angle.style-4 .plan-head, .pricing-tbl.right-angle.style-2 h3{
    +	border-top-right-radius:1.7em
    +}
    +/*
    +---------------- left-angle ------------------- */
    +.left-angle,.icon-box-small i.left-angle:after,.feature-img figure.left-angle:before,.filter-by ul li.left-angle.active a,.filter-by ul li.left-angle:after{
    +	border-top-left-radius: 30em;
    +	border-bottom-left-radius: 30em;
    +}
    +.widget.left-angle,textarea.left-angle,.product-img.left-angle,.modal-content.left-angle{
    +	border-top-left-radius:1em;
    +	border-bottom-left-radius:1em
    +}
    +.panel.left-angle,.testimonials-4 .testimonials-bg.left-angle,.contact-widget .details li i.left-angle:before,.team-box.left-angle,[class*="tabs-style-"] .tab-content .tab-pane.left-angle,.ads-box.left-angle,.horizontal-slider.left-angle,.accordion.style-3.left-angle,.pricing-tbl.left-angle,
    +[class*="bquote-"].left-angle,.msg-box.left-angle,.progress-bars.left-angle,.post-item img.left-angle,.my-info.left-angle,.comment-list li.left-angle,.icon-box.left-angle,.testimonials-bg.left-angle,.left-angle.bg-block{
    +	border-top-left-radius:2.2em;
    +	border-bottom-left-radius:2.2em
    +}
    +.left-angle.icon-box.gry-border-2 .head-bg,.left-angle.accordion.style-3 .panel:first-child >.panel-heading h4 a, .pricing-tbl.left-angle.style-4 .plan-head, .pricing-tbl.left-angle.style-2 h3{
    +	border-top-left-radius:1.7em
    +}
    +.tabs-style-default .tab-content .tab-pane.active.left-angle{
    +	border-top-left-radius:0
    +}
    +/*
    +---------------- top-angle ------------------- */
    +.top-angle,.icon-box-small i.top-angle:after{
    +	border-top-right-radius: 30em;
    +	border-top-left-radius: 30em;
    +}
    +.top-angle.btn,.accordion .top-angle,.top-head.header-4 .top-search.top-angle{
    +	border-top-right-radius: 1.5em;
    +	border-top-left-radius: 1.5em;
    +}
    +.widget.top-angle,textarea.top-angle,.product-img.top-angle,.tags .top-angle{
    +	border-top-right-radius:1em;
    +	border-top-left-radius:1em
    +}
    +.panel.top-angle,.testimonials-4 .testimonials-bg.top-angle,.contact-widget .details li i.top-angle:before,.team-box.top-angle,[class*="tabs-style-"] .tab-content .tab-pane.top-angle,.ads-box.top-angle,.horizontal-slider.top-angle,.accordion.style-3.top-angle,.pricing-tbl.top-angle,
    +[class*="bquote-"].top-angle,.msg-box.top-angle,.progress-bars.top-angle,.post-item img.top-angle,.my-info.top-angle,.comment-list li.top-angle,.icon-box.top-angle,.testimonials-bg.top-angle,.feature-img figure.top-angle:before,.feature-img figure.top-angle,.modal-content.top-angle,
    +.break-news.top-angle, .pricing-tbl.top-angle.style-4 .plan-head,.not-found-form input[type=text].top-angle{
    +	border-top-left-radius:2.2em;
    +	border-top-right-radius:2.2em
    +}
    +.top-angle.icon-box.gry-border-2 .head-bg,.top-angle.accordion.style-3 .panel:first-child >.panel-heading h4 a,.p-style5 figure .description.top-angle,.item-box.top-angle,.pricing-tbl.top-angle.style-2 h3,.top-angle.form-control{
    +	border-top-right-radius:1.7em;
    +	border-top-left-radius:1.7em
    +}
    +
    +/*
    +---------------- bottom-angle ------------------- */
    +.bottom-angle,.icon-box-small i.bottom-angle:after,.filter-by ul li.bottom-angle.active a,.filter-by ul li.bottom-angle:after{
    +	border-bottom-right-radius: 30em;
    +	border-bottom-left-radius: 30em;
    +}
    +.bottom-angle.btn,.accordion .bottom-angle,.p-style5 figure .description.bottom-angle,.top-head.header-4 .top-search.bottom-angle{
    +	border-bottom-right-radius: 1.5em;
    +	border-bottom-left-radius: 1.5em;
    +}
    +.widget.bottom-angle,textarea.bottom-angle,.product-img.bottom-angle,.tags .bottom-angle{
    +	border-bottom-right-radius:1em;
    +	border-bottom-left-radius:1em
    +}
    +.panel.bottom-angle,.testimonials-4 .testimonials-bg.bottom-angle,.contact-widget .details li i.bottom-angle:before,.team-box.bottom-angle,[class*="tabs-style-"] .tab-content .tab-pane.bottom-angle,.ads-box.bottom-angle,.horizontal-slider.bottom-angle,.accordion.style-3.bottom-angle,.pricing-tbl.bottom-angle,
    +[class*="bquote-"].bottom-angle,.msg-box.bottom-angle,.progress-bars.bottom-angle,.post-item img.bottom-angle,.my-info.bottom-angle,.comment-list li.bottom-angle,.icon-box.bottom-angle,.testimonials-bg.bottom-angle,.feature-img figure.bottom-angle,.feature-img figure.bottom-angle:before,.modal-content.bottom-angle,
    +.break-news.bottom-angle,.item-box.bottom-angle, .pricing-tbl.bottom-angle.style-4 .plan-head{
    +	border-bottom-left-radius:2.2em;
    +	border-bottom-right-radius:2.2em
    +}
    +.pricing-tbl.bottom-angle.style-2 h3,.bottom-angle.form-control,.not-found-form input[type=text].bottom-angle{
    +	border-bottom-right-radius: 1.7em;
    +	border-bottom-left-radius: 1.7em;
    +}
    +
    +/* ==========================================================================
    +  13. BOXED MODE
    +============================================================================= */
    +
    +.pageWrapper.boxed{
    +	margin: 0 auto;
    +}
    +.pageWrapper.boxed .full-cell{
    +	width:100%
    +}
    +.pageWrapper.boxed .fullwidthbanner-container,.pageWrapper.boxed .forcefullwidth_wrapper_tp_banner{
    +	width:100% !important;
    +	left:0 !important
    +}
    +.pageWrapper.boxed .top-head.transparent,.pageWrapper.boxed .top-head.sticky-nav{
    +	width:auto;
    +	left:auto;
    +	top:30px
    +}
    +.pageWrapper.boxed .fixed-footer{
    +	width:auto;
    +	left:auto;
    +}
    +.full-2-foot{
    +	margin-left:-15px
    +}
    +.fullscreen-body .pageWrapper.boxed{
    +	margin:0 auto
    +}
    +.fullscreen-body .pageWrapper.boxed .top-head.transparent, .fullscreen-body .pageWrapper.boxed .top-head.sticky-nav{
    +	top:0
    +}
    +.fullscreen-body video {
    +	z-index: 1;
    +	position: absolute;
    +	left: -30%;
    +	top: -35%;
    +	width: 160%;
    +	height: 170%;
    +}
    +.pageWrapper.boxed .top-head .logo:before,.pageWrapper.boxed .top-head .logo:after,.pageWrapper.boxed .top-head .bot-line,.pageWrapper.boxed .top-head .lft-line{
    +	display:none
    +}
    +.pageWrapper.boxed .top-head.boxed-transparent > .container{
    +	border-radius:0
    +}
    +.pageWrapper.boxed .top-head.boxed-transparent{
    +	top: 0;
    +}
    +.pageWrapper.boxed .fixed-footer .footer-bottom{
    +	padding-left:0;
    +	padding-right:0
    +}
    +.pageWrapper.boxed .sticky-nav.transparent,.pageWrapper.boxed .sticky-nav.sticky-nav{
    +	top:0
    +}
    +.pageWrapper.boxed .footer-bottom ul.right{
    +	margin-right:15px
    +}
    +.bg1{
    +	background-image:url('../images/patterns/bg1.jpg')
    +}
    +.bg2{
    +	background-image:url('../images/patterns/bg2.jpg')
    +}
    +.bg3{
    +	background-image:url('../images/patterns/bg3.jpg')
    +}
    +.bg4{
    +	background-image:url('../images/patterns/bg4.jpg')
    +}
    +.bg5{
    +	background-image:url('../images/patterns/bg5.jpg')
    +}
    +.bg6{
    +	background-image:url('../images/patterns/bg6.jpg')
    +}
    +.bg7{
    +	background-image:url('../images/patterns/bg7.jpg')
    +}
    +.bg8{
    +	background-image:url('../images/patterns/bg8.jpg')
    +}
    +.bg9{
    +	background-image:url('../images/patterns/bg9.jpg')
    +}
    +.bg10{
    +	background-image:url('../images/patterns/bg10.jpg')
    +}
    +.bg11{
    +	background-image:url('../images/patterns/bg11.jpg');
    +	background-repeat:no-repeat;
    +	background-size:cover;
    +	background-attachment:fixed
    +}
    +.bg12{
    +	background-image:url('../images/patterns/bg12.jpg');
    +	background-repeat:no-repeat;
    +	background-size:cover;
    +	background-attachment:fixed
    +}
    +.bg13{
    +	background-image:url('../images/patterns/bg13.jpg');
    +	background-repeat:no-repeat;
    +	background-size:cover;
    +	background-attachment:fixed
    +}
    +
    +/* ==========================================================================
    +  14. RESPONSIVE DESIGN.
    +============================================================================= */
    +@media (min-width: 768px){
    +	.top-nav .mega-menu > ul {
    +		width: 720px;
    +	}
    +}
    +@media (min-width: 992px){
    +	.top-nav .mega-menu > ul {
    +		width: 940px;
    +	}
    +}
    +@media (min-width: 1200px){
    +	.top-nav .mega-menu > ul {
    +		width: 1140px;
    +	}
    +	.pageWrapper.boxed {
    +		width: 1170px;
    +	}
    +	.pageWrapper.boxed .top-head.transparent, .pageWrapper.boxed .top-head.sticky-nav{
    +		width:1170px
    +	}
    +}
    +@media (max-width: 1200px) {
    +	.pageWrapper.boxed {
    +		width: auto;
    +		margin:auto
    +	}
    +	.pageWrapper.boxed .top-head.transparent,.pageWrapper.boxed .top-head.sticky-nav,.pageWrapper.boxed .fixed-footer{
    +		width:100%;
    +		left:0
    +	}
    +	.pageWrapper.boxed .top-head.transparent, .pageWrapper.boxed .top-head.sticky-nav{
    +		top:0
    +	}
    +	.bottom-md-footer .form-control{
    +		width:70%;
    +	}
    +}
    +
    +@media (max-width: 1024px){
    +	.top-head.transparent.full{
    +		padding:0 10px;
    +	}
    +	.header-left, .header-right{
    +		width:250px
    +	}
    +	.left-side-wrap{
    +		margin-left: 250px;
    +	}
    +	.right-side-wrap{
    +		margin-right: 250px;
    +	}
    +	.header-left .top-search input[type=text], .header-right .top-search input[type=text] {
    +		width: 79%;
    +	}
    +	.p-4-cols .portfolio-item{
    +		width:33.33333% !important;
    +		margin:0 !important
    +	}
    +}
    +
    +@media (max-width: 992px) {
    +	.new-nav{
    +		display:block
    +	}
    +	.tri-line,.half-section:before,.footer-middle:after{
    +		display:none
    +	}
    +	.top-bar .center-tbl ul,.top-ad{
    +		display: table;
    +		margin: 0 auto 5px;
    +		float: none !important;
    +		clear: both;
    +	}
    +	.circliful{
    +		margin:auto
    +	}
    +	.top-head.header-4 .top-search input[type=text] {
    +		width: 140px;
    +	}
    +	.top-bar ul{
    +		float:none;
    +		clear:both;
    +		margin:5px auto;
    +		display:table
    +	}
    +	.p-1-col .name-holder .meta{
    +		clear:both
    +	}
    +	.fullscreen video {
    +		width: 260%;
    +	}
    +	.fixed-footer .footer-bottom{
    +		padding:0
    +	}
    +	.masonry .post-item,.grid .post-item{
    +		width:47.5% !important;
    +		margin:0 12px 15px 0 !important
    +	}
    +	[class*="col-md-"]:after{
    +		clear:both;
    +		display:table;
    +		content:" ";
    +		height:15px
    +	}
    +	.left-white-border{
    +		border-left-width:0 !important
    +	}
    +	.cta_btn .f-left{
    +		width: 100%;
    +		float:none;
    +		clear:both;
    +		display:block !important;
    +		padding:15px 29px;
    +	}
    +	[class*="col-md-"]:not(.slick-slide){
    +		width: 100%;
    +		float:none;
    +		clear:both;
    +		display:block;
    +		padding:15px 29px;
    +	}
    +	.slider-txt{
    +		font-size:15px !important
    +	}
    +	.section{
    +		padding:40px 0
    +	}
    +	.section .full-heading {
    +	    margin-top: -40px;
    +	}
    +	.sec-bg.left.circle,.sec-bg.right.circle{
    +		border-radius:0
    +	}
    +	.responsive-nav,.footer-middle:after,.responsive-nav .top-search, .responsive-nav .top-cart,.footer-4 .footer-middle .container:before,.footer-light .footer-middle .container:before,.bg-full-rit, .bg-full-lft,.top-head.boxed-transparent .bot-line,
    +	.top-head.boxed-transparent .logo:before,.top-head.boxed-transparent .logo:after,.header-left, .header-right{
    +		display:none
    +	}
    +	.pageWrapper{
    +		margin:0 !important
    +	}
    +	.responsive-nav{
    +		position:fixed;
    +		right:-100%;
    +		top:0;
    +		width:40%;
    +	}
    +	.responsive-nav li{
    +		display:block;
    +		float:none !important
    +	}
    +	.slick-slide img{
    +		display:inline-block
    +	}
    +	.cta_btn .btn{
    +		margin:15px auto 0;
    +		display:table;
    +		float:none
    +	}
    +	.cta-icon,.cta_btn .left,.slick-slide img,.footer-bottom{
    +		text-align:center
    +	}
    +	.navbtn{
    +		display:block;
    +	}
    +	.footer-bottom ul{
    +		float:none;
    +		display:table;
    +		margin:auto !important
    +	}
    +	.footer-bottom [class*="col-md-"]{
    +		padding:5px 0;
    +	}
    +	.footer-bottom .footer-menu li{
    +		padding-left:12px
    +	}
    +	.filter-by{
    +		padding-left:20px;
    +		padding-right:20px;
    +		overflow:hidden
    +	}
    +	.captcha-div *{
    +		float:none;
    +		margin:0 0 10px
    +	}
    +	.pricing-tbl.style-4.no-margin.selected{
    +		margin-top:0
    +	}
    +	.digits span{
    +		height: 120px;
    +		width:120px;
    +		line-height:120px;
    +		font-size:50px;
    +	}
    +	.digits li:before,.digits li:after{
    +		top: 120px;
    +		width: 50px;
    +	}
    +	.soon-form input[type=text] {
    +		width: 68%;
    +	}
    +	.shop-main-menu > ul > li > ul.mega,.shop-main-menu > ul > li > ul{
    +		position:static;
    +		width: auto;
    +		z-index: 99;
    +		-webkit-box-shadow: none;
    +		-moz-box-shadow: none;
    +		box-shadow: none;
    +		border:0 !important;
    +		padding:0
    +	}
    +	.shop-main-menu > ul > li > ul a{
    +		border:0 !important;
    +	}
    +	.shop-main-menu > ul > li{
    +		overflow:hidden
    +	}
    +	.blog-posts.small-image .post-image, .blog-posts.small-image .post-gallery {
    +		width: 30%;
    +		height: auto;
    +	}
    +	.post-item{
    +		margin-bottom:20px
    +	}
    +	.blog-posts.small-image .post-image video,.blog-posts.small-image .post-image iframe {
    +		width: 100% !important;
    +		height: 100% !important;
    +	}
    +	.blog-posts.small-image .post-item .post-content p{
    +		padding:8px
    +	}
    +	.blog-posts.small-image .post-info{
    +		overflow:hidden
    +	}
    +	.blog-posts.small-image .post-meta{
    +		display:none
    +	}
    +	.masonry .post-item,.grid .post-item{
    +		width:47.5% !important;
    +		margin:0 12px 15px 0 !important
    +	}
    +	.heading.centered *{
    +		text-align:center
    +	}
    +	.left-side-wrap,.right-side-wrap{
    +		margin:0
    +	}
    +	.top-head .logo{
    +		display:table;
    +		margin:auto;
    +		float:none !important;
    +		border:0 !important;
    +		padding:10px 0
    +	}
    +	.parallax{
    +		background-position:0 0 !important;
    +		background-attachment:scroll !important
    +	}
    +	.feature-img figure img{
    +		width:100%
    +	}
    +	.NL,.slick-slide{
    +		text-align:center
    +	}
    +	.bottom-md-footer .NL .form-control{
    +		float:none;
    +		margin-bottom:5px
    +	}
    +	.footer-middle .flickr-widget{
    +		display:table;
    +		margin:auto
    +	}
    +	.captcha-div{
    +		width:100%
    +	}
    +	.top-head.boxed-transparent > .container{
    +		border:0 !important
    +	}
    +	.row-eq-height{
    +		display:block
    +	}
    +	li.mega-menu .inner-mega{
    +		margin:0;
    +		padding:0
    +	}
    +	.testimonials-5 .row:first-child [class*="col-md-"], .clients-grid1 .row:first-child [class*="col-md-"], .clients-grid2 .row:first-child [class*="col-md-"], .clients-grid3 .row:first-child [class*="col-md-"]{
    +		border-width:1px !important
    +	}
    +	.team-box .rounded-img{
    +		border-radius:0;
    +		max-height:none
    +	}
    +	.page-title-video .video-wrap video,.section-video .video-wrap video {
    +		margin-top:0;
    +	}
    +}
    +@media (max-width: 768px) {
    +	.navbtn{
    +		width: 45px;
    +		height: 45px;
    +		line-height: 45px;
    +		text-align: center;
    +		z-index: 9999;
    +		font-size: 18px;
    +	}
    +	.timeline_date,.timeline:before{
    +		display:none
    +	}
    +	.post-item{
    +		margin:0 0 20px !important;
    +		overflow: hidden;
    +	}
    +	#container,#masonry {
    +		max-width: 800px;
    +	}
    +	.p-4-cols .portfolio-item,.p-3-cols .portfolio-item{
    +		width:48.33333% !important
    +	}
    +	.p-4-cols .portfolio-item,.p-3-cols .portfolio-item{
    +		width:50% !important;
    +		margin:0
    +	}
    +	.page-title-video > .container > .row{
    +		height:300px
    +	}
    +}
    +@media (max-width: 480px) {
    +	.new-nav > ul > li a, .new-nav > ul > li.mega-menu h4{
    +		font-size:13px;
    +		padding:10px 15px
    +	}
    +	.new-nav{
    +		width:60%;
    +		right:-60%
    +	}
    +	.navbtn.active{
    +		right:60%
    +	}
    +	.responsive-body{
    +		margin:0
    +	}
    +	.three-imgs img{
    +		position:static !important;
    +	}
    +	.filter-by ul{
    +		margin:0
    +	}
    +	.filter-by ul li{
    +		margin: 0 2px 10px;
    +	}
    +	.filter-by ul li:before{
    +		display:none
    +	}
    +	.filter-by ul li a{
    +		padding: 7px 10px;
    +	}
    +	.conact_center_form{
    +		margin:0 15px
    +	}
    +	.portfolio-slider.p-4-cols.no-margin .portfolio-item {
    +		width: 318px !important;
    +	}
    +	.tp-caption[class*="font-"]{
    +		font-size:inherit !important;
    +		line-height:normal !important
    +	}
    +	.blog-posts .post-image, .blog-posts .post-gallery{
    +		float:none !important;
    +		width:100% !important;
    +		clear:both;
    +		margin-bottom:10px;
    +		text-align:center
    +	}
    +	.blog-posts .post-content{
    +		margin:0 !important;
    +	}
    +	.inner-menu ul > li > a {
    +		padding: 0 9px;
    +	}
    +	.gry-sep{
    +		width:45%
    +	}
    +	.p-4-cols .portfolio-item,.p-3-cols .portfolio-item,.p-2-cols .portfolio-item{
    +		width:100% !important;
    +		margin:0 !important;
    +	}
    +	.main-heading h3,.main-heading .sub-title{
    +		font-size:25px;
    +		letter-spacing:0.5px;
    +	}
    +	.heading-desc,.post-item .post-info h2{
    +		font-size:14px
    +	}
    +	.heading-desc.centered{
    +		width:100%
    +	}
    +	.nav-tabs>li>a{
    +		padding:5px
    +	}
    +	.rit-img,.lft-img{
    +		float:none;
    +		clear:both;
    +		margin:0 auto 15px;
    +		display:table;
    +	}
    +	.testimonials-2 p{
    +		font-size:13px
    +	}
    +	.page-title-video > .container > .row{
    +		height:180px
    +	}
    +	.page-title h1{
    +		font-size:20px !important;
    +		margin-top:20px
    +	}
    +	.page-title h3{
    +		font-size:15px !important
    +	}
    +	.page-title > .container > .row{
    +		padding-bottom:0
    +	}
    +}
    +
    +.comment-list ul.child-comment .comment-content h6 a,.team-box .team-details .social-list li a{
    +	color:#666
    +}
    +.top-head.sticky-nav .top-nav > ul > li > a,.top-head.sticky-nav .top-nav > ul > li > span > a,.top-head.transparent.sticky-nav .top-nav > ul > li > span > a{
    +	color:#777
    +}
    +body,.top-head.sticky-nav .top-nav > ul > li.hasChildren > a:after, .top-head.sticky-nav .top-nav > ul > li.hasChildren > span > a:after{
    +	color: #666 !important;
    +}
    +.top-head .main-bg .top-nav > ul > li.hasChildren > a:after, .top-head .main-bg .top-nav > ul > li.hasChildren > span > a:after,.header-9 .top-nav > ul > li.hasChildren:hover > a:after,.header-9 .top-nav > ul > li.hasChildren:hover > span > a:after,
    +.header-9 .top-nav > ul > li.hasChildren:hover > a span:after,.header-9 .top-nav > ul > li.hasChildren:hover > span > a span:after{
    +	color:#fff !important
    +}
    +
    +.nav-border-bottom > ul > li:before,.nav-border-bottom li.mega-menu .inner-mega:before,.nav-border-left > ul > li:before,.nav-border-left li.mega-menu .inner-mega:before,.nav-border-top > ul > li:before,.nav-border-top li.mega-menu .inner-mega:before,
    +.nav-border-right > ul > li:before,.nav-border-right li.mega-menu .inner-mega:before,.feature-img figure{
    +	background-color:#ddd;
    +}
    +.dark .nav-border-bottom > ul > li:before,.dark .nav-border-bottom li.mega-menu .inner-mega:before,.dark .nav-border-left > ul > li:before,.dark .nav-border-left li.mega-menu .inner-mega:before,.dark .nav-border-top > ul > li:before,.dark .nav-border-top li.mega-menu .inner-mega:before,
    +.dark .nav-border-right > ul > li:before,.dark .nav-border-right li.mega-menu .inner-mega:before{
    +	background-color:#696969;
    +}
    +
    +/* #999 */
    +.top-bar ul.top-info li,.top-bar ul.top-info li a,.bar-menu li a,.top-bar ul.top-info li,.top-search .search-box input[type=text],.top-head.header-6 .top-nav > ul > li > a > i,.post-item .post-meta li,
    +.top-head.header-8 .top-nav > ul > li > a span,.top-nav.dark-submenu li li a,.top-nav.dark-submenu .mega-menu > ul > li h4,.pricing-tbl.style-4 .plan-head i,select,input[type=file],.post-item .post-meta li a,.comment-list .comment-content .meta{
    +	color: #999
    +}
    +.fa-hover:hover > span{
    +	background:#999
    +}
    +.slick-dots li button{
    +	border:1px #999 solid;
    +}
    +
    +
    +/* #fff */
    +.social-list li a:after,.top-bar.main-bg ul li, .top-bar.main-bg ul li a,.top-bar.main-bg ul li i, .top-bar.main-bg ul.social-list li a,.top-head.transparent.dark .top-nav > ul > li.hasChildren > a:after,.top-head.transparent .logo a,.top-head.transparent .top-cart > a,
    +.top-head.transparent .top-nav > ul > li > a,.top-head.header-5 .top-cart > a,.top-head.header-6 .top-nav > ul > li:hover > a i,.top-head.header-6 .top-nav > ul > li:hover > a,.top-head .full.main-bg .top-nav > ul > li > a,.top-head.transparent .top-nav > ul > li > span > a,
    +.top-head.header-8 .top-nav > ul > li:hover > a span,.top-head.header-8 .top-cart > a,.top-head.header-5.sticky-nav .top-cart > a, .top-head.sticky-nav.header-8 .top-cart > a,.page-title.title-5 h1,.footer-top div.tweets > div a,.footer-top div.tweets .slick-prev,
    +.footer-top div.tweets .slick-next,.block-link,.dark-bg,.black-bg,.contact-widget .social-list li a:after,.tags.hover-effect li a:after,ul.flickr-widget .img-overlay:before,.box-1:hover .outlined i,.icon-box.gry-border-1:hover h3,.darker-bg,.black-bg
    +.top-nav.colored-submenu ul li ul a,.tags-widget .tags a:hover,.pricing-tbl.style-4:hover .plan-head h3,.top-head.header-8 .top-nav > ul > li.selected > a span,.darker-bg a,
    +.black-bg a,.dark-bg a,.btn-default,mark,.zoom .img-overlay:before,a.main-bg:hover,.btn.main-border.btn-outlined:hover,.fa-hover:hover > span{
    +	color:#fff
    +}
    +.top-head.transparent .top-nav > ul > li > a{
    +	text-shadow: 0 1px 0px rgba(0,0,0,.2);
    +}
    +.top-head.transparent.sticky-nav .top-nav > ul > li > a{
    +	text-shadow: none;
    +}
    +
    +.white,.tabs-style-ballon li.active a,.one-page .diamonds.current a:hover,.pagination ul li.selected a{
    +	color: #fff !important;
    +}
    +.icon-box.gry-border-1:hover i,.white-bg,.team-box .team-img,.header-9 .top-nav > ul > li:not(.mega-menu):first-child:before {
    +	background-color:#fff !important;
    +}
    +body,.footer-top div.tweets .slick-prev:hover,.footer-top div.tweets .slick-next:hover,.top-head,.top-nav ul li ul,.cart-box,.top-head.sticky-nav,.page-title.title-4 .breadcrumbs,.icon-box:hover h3.bottom_half_border:after,.add-items i:hover,
    +.tabs li.active a,.tabs li.active a:before,.tabs nav li:first-child.active a,.content-wrap section,.pagination ul li:hover,.pricing-tbl.style-4,.pricing-tbl.style-4 .plan-head i,.toolsBar select,.white-bg,
    +.pagination.bar-1 ul,.pagination.bar-2 ul,.pager-slider,.header-left,.header-right,.conact_center_form,.bottom_tools a,.timeline .post-item:nth-child(even) .timeline_date .inner_date:before,.inner-menu ul ul,.top-bar li ul,.bordered-ul > li:hover,
    +.shop-main-menu > ul > li > ul,.pricing-tbl,.pageWrapper.boxed,.top-nav ul li ul,.top-cart .cart-box,.top-head.sticky-nav,#contentWrapper,.pageWrapper,.header-9 .top-nav > ul > li:not(.mega-menu):after,.header-9 .top-nav > ul > li.mega-menu > span:after{
    +	background-color:#fff;
    +}
    +.tabs-style-ballon.vertical .nav-tabs>li {
    +	border-color: #fff transparent;
    +}
    +.team-box.box-2:hover .social-list li,.progress-bars.style-5, .progress-bars.style-6{
    +	border-color: #fff !important;
    +}
    +input:-webkit-autofill {
    +    -webkit-box-shadow:0 0 0 50px #fff inset;
    +    -webkit-text-fill-color: #333;
    +}
    +
    +/* #111 */
    +.tabs nav a:focus,.mini-cart-list a.remove:hover i,.black-color{
    +	color: #111;
    +}
    +/* #222 */
    +.top-bar.main-bg .social-list li a:after,.cont-success,.p-style2 figure .description,.p-style2 figure .description a,.cart-body a {
    +	color: #222;
    +}
    +.footer-3 .footer-top .social-list li,footer .divider.centered:before,footer .divider.centered:after,.btn-outlined:hover,.top-nav.dark-submenu ul li ul,.black-bg,.progress-bars.tool-tip .progress-bar span,.navbtn,.new-nav,.social-list li.main-bg:hover,
    +.section-full-bg.black-bg:before,.section-full-bg.black-bg:after {
    +	background-color: #222;
    +}
    +.btn-outlined:hover,.icon-box-small i.filled:after{
    +	border-color:#222;
    +}
    +.progress-bars.tool-tip .progress-bar span:after{
    +	border-color: #222 transparent transparent transparent;
    +}
    +.icon-box-small:hover i.right-angle b:before{
    +	border-color: transparent transparent transparent #222 !important;
    +}
    +.icon-box-small:hover i.left-angle b:before{
    +	border-color: transparent #222 transparent transparent !important;
    +}
    +
    +/* #333 */
    +h1, h2, h3, h4, h5, h6,.dark-color,.team-box .team-details .team-name,.timeline .post-item .timeline_date .year,.item-cart a,.control-group .box i,span.lbl {
    +	color:#666
    +}
    +.page-title.title-5 h1,.footer-4 .footer-middle .container:before,.btn-default.btn-3d:hover,.pagination.bar-2 ul li:hover,.one-page.side-one .current a{
    +	background:#333;
    +}
    +.btn-default.btn-3d {
    +	-webkit-box-shadow: 0 4px 0 #333;
    +	box-shadow: 0 4px 0 #333;
    +}
    +.btn-default.btn-3d:hover {
    +	-webkit-box-shadow: 0 4px 0 #2A2A2A;
    +	box-shadow: 0 4px 0 #2A2A2A;
    +	border-color: #333;
    +	color: #fff;
    +}
    +.top-nav.dark-submenu li li a{
    +	border-top-color:#333
    +}
    +.top-nav.dark-submenu .mega-menu > ul > li{
    +	border-left-color:#333 !important
    +}
    +.section-full-bg.black-bg .tri{
    +	border-color: transparent transparent transparent #222;
    +}
    +
    +
    +/* #444 */
    +a,.top-nav li li a,.top-nav .mega-menu > ul > li h4,.mini-cart-total,.page-title h1,.page-title h3,.breadcrumbs a,.footer-top div.tweets .slick-prev:hover,.footer-top div.tweets .slick-next:hover,.icon-box h3,.panel-title,.pricing-tbl.style-3.selected .price_txt,
    +.footer-light .footer-middle h3,footer .divider i,.icon-box.gry-border-2:hover .block-icon i,.dark-text,.btn-grey,.btn-white,.pricing-tbl .price-lg,.fa-hover,.inner-menu ul ul li a,.top-bar ul ul li a,.icons-style-2 .heading,
    +.filter-by.style-2 ul li a:hover,.filter-by.style-3 ul li a:hover,.main-bg .btn-white:not(.btn-outlined),.main-bg .btn-white:not(.btn-outlined):hover {
    +	color:#444;
    +}
    +.darker-bg,.btn-default{
    +	background-color:#444
    +}
    +.btn-default{
    +	border-color: #444;
    +}
    +.pagination.bottom-border ul li:hover,.icons-style-2:hover i{
    +	border-bottom-color:#444 !important
    +}
    +.btn-shadow{
    +	-webkit-box-shadow: 3px 3px 0px 0px #444;
    +	-moz-box-shadow: 3px 3px 0px 0px #444;
    +	box-shadow: 3px 3px 0px 0px #444;
    +}
    +.section-full-bg.dark-bg .tri{
    +	border-color: transparent transparent transparent #444;
    +}
    +
    +/* #666 */
    +.item-title{
    +	color:#666
    +}
    +
    +/* #777 */
    +.top-bar ul.social-list li a,.top-head .logo a,.top-head .top-nav > ul > li > a, .top-head .top-nav > ul > li > span > a,.top-head .top-cart > a,.top-nav > ul > li li.hasChildren > a:after,.cart-body .price,.top-head.sticky-nav .logo a,.footer-middle .logo,.footer-light .footer-middle,.bar-wrap b,
    +.top-head.sticky-nav .top-nav > ul > li.hasChildren > a:after, .top-head.sticky-nav .top-cart > a,.footer-light .contact-widget .details li,.footer-light .footer-middle a,.list li.list-bg i,.filled.lg-icon i,
    +.btn-default.btn-outlined, .btn-default.btn-square_outlined,.head-1 p.sub-heading,.head-2 p.sub-heading,.head-3 p.sub-heading,.head-4 p.sub-heading,.head-5 p.sub-heading,.head-6 p.sub-heading,.head-7 p.sub-heading,.head-8 p.sub-heading,.tabs nav a,.circliful,
    +.circle-info, .circle-info-half,.fun-info,.cta_btn p,.pricing-tbl h3,.pricing-tbl.style-3:hover .price_txt,.pagination.bar-1 ul li a,.pagination.bar-2 ul li a,.pagination.bar-3 ul li a,.progress-bars.style-6 span.bar-title,.item-price ins
    +.tags-widget .tags a,.cont-success i.success-icon,.login-2 .login-head,.name-holder h5 a,.cart-body .price{
    +	color: #777;
    +}
    +.top-head.sticky-nav .top-nav > ul > li > a{
    +	color:#777
    +}
    +.dark-bg,.icon-box h3.bottom_half_border:after,.head-6:after,.tags-widget .tags a:hover{
    +	background-color:#777
    +}
    +.dark-border{
    +	border:1px #777 solid
    +}
    +.top-head.sticky-nav a.white{
    +	color:#777 !important
    +}
    +.top-head.sticky-nav a.dark-bg.white{
    +	color:#fff !important
    +}
    +
    +.btn-default.btn-outlined, .btn-default.btn-square_outlined {
    +	border-color: #c2c2c2;
    +}
    +
    +/* #888 */
    +.icons-style-1 i{
    +	color:#000
    +}
    +/* #f1f1f1 */
    +pre,.filter-by.style-2 ul li a:hover,.filter-by.style-3 ul li a:hover,span.lbl,.testimonials-3 .testimonials-bg {
    +	background:#f1f1f1;
    +}
    +.content-wrap section,.filter-by.style-2 ul li a,.filter-by.style-3 ul li a,.item-box,.break-news,.shop-main-menu > ul > li > ul,.shop-main-menu {
    +	border:1px #e8e8e8 solid
    +}
    +.tabs li.active a,.tabs.vertical li:first-child.active a {
    +	border-top:1px #f1f1f1 solid;
    +}
    +.tabs nav li:first-child.active a,.tabs.vertical li.active a,.socials-widget.style-2 .social-list li {
    +	border-left:1px #e9e9e9 solid;
    +}
    +.tabs nav li:last-child.active a {
    +	border-right:1px #f1f1f1 solid;
    +}
    +.tabs.vertical li:last-child.active a,.p-1-col .portfolio-item,.lg-item,.socials-widget.style-2 .social-list li,.shop-main-menu > ul > li,.shop-main-menu li li a{
    +	border-bottom:1px #e9e9e9 solid;
    +}
    +.tabs-style-bottomline.vertical .nav-tabs {
    +	border-right: 2px #ddd solid;
    +}
    +
    +/* #eee */
    +.filled.lg-icon i,.team-box .team-details .social-list li a,.pagination.bar-3 ul li:hover,.progress-bars.style-6,.tags-widget .tags a{
    +	background:#eee;
    +}
    +.filter-by.style-3{
    +	border: 1px #eee solid;
    +}
    +blockquote{
    +	border-color: #eee;
    +}
    +
    +.top-nav li li a,.w-recent-posts li,.inner-menu ul ul li a,.top-bar ul ul li a {
    +	border-top: 1px #eee solid;
    +}
    +.icons-style-2 .heading {
    +	border-bottom: 1px #eee solid;
    +}
    +
    +.cart-mini-lft img {
    +  border: 1px rgba(255, 255, 255, 0.26) solid !important;
    +}
    +.bordered-ul > li{
    +	border-left:1px rgba(0,0,0,.07) solid
    +}
    +.lg-not-found{
    +	color:#e0e0e0;
    +}
    +.lg-not-found i:after{
    +	border: 5px #e0e0e0 solid;
    +}
    +.tabs-style-default .tab-content .tab-pane.active{
    +	border:1px solid #ddd;/* border-top:0
    + */
    +}
    +
    +/* #f2f2f2 */
    +.tabs nav a,.pagination ul li,.cont-success,.login-box-lg .login-inner,.grid .post-item .post-gallery,.share-post,.accordion .panel-default >.panel-heading h4 a,.accordion.style-1 .panel >.panel-heading h4 a.collapsed,.icon-box.gry-border-2 .head-bg,
    +.item-box:hover,.product-img,.alter-gry,.team-box.box-2 .team-details .team-pos {
    +	background-color: #e8e8e8;
    +}
    +
    +/* #f4f4f4 */
    +.bar-menu li {
    +	border-left: 1px #f4f4f4 solid;
    +}
    +.page-title,.p-style4 .name-holder{
    +	background-color: #eaeaea;
    +}
    +
    +/* #f5f5f5 */
    +.pricing-tbl.style-3 .price_txt,.pricing-tbl.style-4 .plan-head,.pricing-tbl.style-4 .plan-head:before,.pricing-tbl.style-4 .plan-head:after,.pricing-tbl.style-2 h3,th,.testimonials-3 .testimonials-name{
    +	background-color:#EFEFEF;
    +}
    +.pricing-tbl.style-2 h3:after {
    +	border-top-color: #EFEFEF;
    +}
    +.sidebar_widgets li.widget{
    +	background:#f5f5f5
    +}
    +/* #fafafa */
    +.post-item .post-content{
    +	background:#f5f5f5
    +}
    +
    +/* #e4e4e4 */
    +.pricing-tbl{
    +	border:1px #e4e4e4 solid
    +}
    +.tabs-style-ballon .nav-tabs{
    +	background:#EAEAEA
    +}
    +
    +.top-head{
    +	border-bottom: 1px #f7f7f7 solid;
    +}
    +
    +/* #e6e6e6 */
    +.btn-default.btn-outlined:hover, .btn-default.btn-square_outlined:hover,.divider.centered:before,.divider.centered:after,.divider.lft:before,.divider.rit:before {
    +	background-color: #e6e6e6;
    +}
    +.divider.bordered i{
    +	border:1px #e6e6e6 solid;
    +}
    +blockquote:before,blockquote:after,.top-nav.colored-submenu ul li ul a:hover{
    +	color:#e6e6e6
    +}
    +
    +/* #f9f9f9 */
    +.bquote-1,.bquote-3,.bquote-4,.team-box.box-1 .team-details,.pricing-tbl.style-4 ul li:nth-child(even),tr.even td{
    +	background-color:#f2f2f2
    +}
    +.gry-bg, .tabs-style-bg .nav-tabs>li a{
    +	background-color:#f1f1f1
    +}
    +/* #f0f0f0 */
    +.list li.list-bg,.bottom_tools{
    +	background:#f0f0f0;
    +}
    +.widget-categories ul li,.w-recent-posts > ul > li, .w-recent-comments ul li {
    +	border-top: 1px #E4E4E4 solid;
    +}
    +
    +/* #e1e1e1 */
    +.team-box.box-2,.pagination.bar-1 ul,.pagination.bar-2 ul,.mini-cart .checkout a,.pagination ul li,.accordion.style-1 .panel >.panel-heading h4 a:not(.collapsed),.accordion.style-2 .panel {
    +	border:1px #e1e1e1 solid
    +}
    +.pagination.bar-1 ul li{
    +	border-left:1px #e1e1e1 solid;
    +}
    +.accordion.style-3 .panel >.panel-heading h4 a{
    +	border-top:1px #e1e1e1 solid;
    +}
    +.accordion.style-4 .panel>.panel-heading h4 a{
    +	border-bottom:1px #e1e1e1 solid;
    +}
    +
    +/* #e7e7e7 */
    +.footer-light .footer-middle {
    +	background:#e7e7e7;
    +}
    +.mini-cart-list li,.mini-cart-total {
    +	border-bottom: 1px solid #e7e7e7;
    +}
    +.mini-cart-total .total {
    +	border-top: 1px solid #e7e7e7;
    +}
    +.left-gry-border{
    +	border-left: 1px solid #e7e7e7;
    +}
    +.left-white-border{
    +	border-left: 1px solid #fff;
    +}
    +
    +
    +/* e8e8e8 */
    +.list li.list-bg i,.comment-list .child-comment .comment-content h6{
    +	background:#e8e8e8;
    +}
    +.bquote-3,.bquote-4,input[type=text], input[type=email],input[type=password],.login-2 .login-box-lg .login-inner,select,input[type=file],.post-tags .tags li{
    +	border:1px #e8e8e8 solid
    +}
    +.widget.custom-menu-widget ul li{
    +	border-top: 1px #e8e8e8 solid;
    +}
    +.sidebar_widgets .widget-head{
    +	border-bottom: 1px #e8e8e8 solid;
    +}
    +textarea{
    +	border: 1px solid #e8e8e8;
    +	border-radius: 0;
    +	-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
    +	box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
    +	-webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;
    +	-o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
    +	transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
    +	resize:none
    +}
    +
    +/* #e9e9e9 */
    +.timeline:before,.timeline .post-item:nth-child(even) .timeline_date:before,tfoot{
    +	background:#e9e9e9
    +}
    +.top-head.header-4 .top-search,.top-head.header-7 .top-search,.timeline .post-item:nth-child(even) .timeline_date .inner_date:before,.top-head.header-2 .top-nav > ul > li > a,.top-head.header-2 .top-nav > ul > li > span > a,.top-head.header-2 .top-cart,.top-head.header-2 .top-search {
    +	border: 1px #e9e9e9 solid;
    +}
    +/*.top-head,*/.list li.bottom-border,.price-block,.product-block,.top-bar:not(.main-bg) {
    +	border-bottom: 1px #e9e9e9 solid;
    +}
    +.top-head.header-2 .top-cart {
    +	border-right: 1px #e9e9e9 solid;
    +}
    +.top-nav .mega-menu > ul > li {
    +	border-left: 1px #e9e9e9 solid;
    +}
    +.tabs-style-lg .nav-tabs>li {
    +	border-right: 1px #e9e9e9 solid;
    +	border-top: 1px #e9e9e9 solid;
    +}
    +.tabs-style-lg .nav-tabs>li:first-child {
    +	border-left: 1px #e9e9e9 solid;
    +}
    +
    +/* efefef */
    +.team-box.box-2 .team-name{
    +	background:#efefef;
    +}
    +.testimonials-5 [class*="col-md-"],.clients-grid1 [class*="col-md-"],.clients-grid2 [class*="col-md-"],.clients-grid3 [class*="col-md-"]{
    +	border-color:#ddd;
    +}
    +
    +
    +/* #dcdcdc */
    +.head-2 b{
    +	color: #DCDCDC;
    +}
    +.head-1:after,.head-1:before,.head-2:after,.head-2:before{
    +	background-color:#dcdcdc
    +}
    +.head-3:after,.head-3:before{
    +	border-top:1px #dcdcdc solid;
    +	border-bottom:1px #dcdcdc solid;
    +}
    +
    +/* #ddd */
    +.widget.custom-menu-widget ul li:before,.w-recent-comments i,.soon-form:before,.not-found-form:before,.top-shop-links a i{
    +	color:#ddd
    +}
    +.footer-light .footer-top,.footer-light .footer-bottom,ul.child-comment:before,.add-items i,.head-5:before{
    +	background:#ddd
    +}
    +.box-1 .outlined i,.icon-box-small .outlined,pre,.social-list .outlined,.pro-info-cell > div,.add-items i:hover,.qty-txt-box input[type=text],.shop-ads-top,.tabs-style-default.vertical .tab-content .tab-pane.active,.checkbox-table .floated-item{
    +	border:1px #ddd solid;
    +}
    +.footer-light .contact-widget .social-list li.diamond.outlined:after,.default-border,.testimonials-4 .testimonials-img img,.testimonials-3 .testimonials-img img,.testimonials-5 .testimonials-img img,
    +.header-9 .top-nav > ul > li:not(.mega-menu):after,.header-9 .top-nav > ul > li.mega-menu > span:after{
    +	border-color:#ddd
    +}
    +.tabs-style-default.vertical .nav-tabs>li.active>a{
    +	border:1px #ddd solid !important;
    +	border-right:0px !important
    +}
    +
    +.top-head.header-4 .top-cart .cart-box {
    +	border-top: 3px #ddd solid;
    +}
    +.head-6,.icons-style-2 .heading,.tabs-style-bottomline .nav-tabs{
    +	border-bottom:1px #ddd solid;
    +}
    +.pagination.bottom-border ul li{
    +	border-bottom:3px #ddd solid
    +}
    +.tabs-style-default .nav-tabs>li.active>a, .tabs-style-default .nav-tabs>li.active>a:focus, .tabs-style-default .nav-tabs>li.active>a:hover {
    +    border: 1px solid #ddd;
    +    border-bottom-color: transparent;
    +}
    +/* #d0d0d0 */
    +.contact-widget .details li {
    +	color: #d0d0d0;
    +}
    +.footer-light .menu-widget li{
    +	border-top-color:#d0d0d0
    +}
    +
    +/* #ccc */
    +.sitemap > ul > li > ul > li li:before,.icons-style-2 i{
    +	color:#ccc
    +}
    +.head-8:before{
    +	background:#ccc;
    +}
    +.footer-light .tags li,.footer-light .social-list li.outlined{
    +	border-color:#ccc
    +}
    +
    +.mini-cart-list a.remove i {
    +	color: #bababa;
    +}
    +.footer-light .recent-posts-footer li .post-img img{
    +	border-color:#cdcdcd
    +}
    +.divider i{
    +	color:#d5d5d5;
    +}
    +
    +.icon-box.gry-border-1,.icon-box.gry-border-2{
    +	border:1px #ebebeb solid;
    +}
    +li.outlined.circle,li.outlined.rectangle,.minimal-socials .outlined{
    +	border:1px #4a4a4a solid
    +}
    +blockquote p {
    +	color: #afafaf;
    +}
    +blockquote span {
    +	color: #a3a3a3;
    +}
    +.top-nav.colored-submenu ul li ul ul {
    +	border-left-color: #fff !important;
    +}
    +.top-nav.colored-submenu ul li ul li a{
    +	border-color:rgba(0,0,0,.12)
    +}
    +.top-nav.colored-submenu .mega-menu > ul > li{
    +	border-left-color:rgba(0,0,0,.12) !important
    +}
    +.top-nav.colored-submenu ul ul ul:before{
    +	border-color: transparent #fff transparent transparent !important;
    +}
    +.testimonials-4 .testimonials-bg:after{
    +	border-color: rgba(255,255,255,.5) transparent transparent transparent;
    +}
    +.testimonials-4 .testimonials-bg{
    +	border:1px rgba(255,255,255,.5) solid;
    +	border-bottom-width: 4px;
    +}
    +.testimonials-3 .testimonials-bg:after,.testimonials-4 .testimonials-bg:after,.testimonials-3 .testimonials-bg:before,.testimonials-4 .testimonials-bg:before{
    +	background-color:rgba(255,255,255,.5)
    +}
    +.testimonials-3.dark .testimonials-bg:after,.testimonials-4.dark .testimonials-bg:after,.testimonials-3.dark .testimonials-bg:before,.testimonials-4.dark .testimonials-bg:before{
    +	background-color:rgba(0,0,0,.7)
    +}
    +.testimonials-4.dark .testimonials-bg{
    +	background:rgba(0,0,0,.7);
    +	color:#fff
    +}
    +
    +.top-nav.colored-submenu li li a:hover{
    +	background-color:rgba(0,0,0,.12);
    +}
    +.top-nav.colored-submenu .mega-menu li a:hover{
    +	background-color:transparent;
    +}
    +.top-nav.colored-submenu > ul > li > ul{
    +	border-bottom:0 !important;
    +	border-top:3px #fff solid
    +}
    +.pricing-tbl ul li{
    +	border-top:1px #ebebeb solid;
    +	color:#bbb
    +}
    +.pricing-tbl.style-2 h3,.pricing-tbl.style-4 .plan-head{
    +	border-bottom:1px #ebebeb solid;
    +}
    +.pricing-tbl.style-2 h3:before {
    +	border-top-color: #ebebeb;
    +}
    +.list-grid a{
    +	background:#ebebeb
    +}
    +.pricing-tbl.style-4 .plan-head:before,.pricing-tbl.style-4 .plan-head i{
    +	border: 1px #e9e9e9 solid;
    +}
    +.progress-bars.style-5{
    +	background:#2a2a2a;
    +}
    +.progress-bars.style-5 .progress{
    +	border-bottom:1px #343434 solid;
    +}
    +.progress-bars.style-5 span.bar-title{
    +	color:#b8b8b8;
    +}
    +.progress-bars.style-6 span.bar-title{
    +	color:#777
    +}
    +.progress-bars.style-5 .progress-bar span{
    +	background:rgba(0,0,0,.2)
    +}
    +.progress-bars.style-6 .progress-bar span{
    +	background:#e6e6e6;
    +	color:#777
    +}
    +.progress-bars.style-6 .progress{
    +	border-bottom:1px #ddd solid;
    +}
    +.progress-bars.style-6 .progress:last-child{
    +	border-bottom:0
    +}
    +
    +.pagination.bar-1 ul,.pagination.bar-2 ul{
    +	background: -moz-linear-gradient(top,  #ffffff 0%, #f3f3f3 100%);
    +	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#f3f3f3));
    +	background: -webkit-linear-gradient(top,  #ffffff 0%,#f3f3f3 100%);
    +	background: -o-linear-gradient(top,  #ffffff 0%,#f3f3f3 100%);
    +	background: -ms-linear-gradient(top,  #ffffff 0%,#f3f3f3 100%);
    +	background: linear-gradient(to bottom,  #ffffff 0%,#f3f3f3 100%);
    +}
    +
    +.top-nav li li:hover > a,.top-nav li li.selected > a{
    +	background:rgba(0,0,0,.02);
    +}
    +.top-nav.colored-submenu li li > a{
    +	color:#fff !important
    +}
    +.top-nav.colored-submenu li li.selected > a{
    +	background:rgba(0,0,0,.12) !important;
    +	color:#fff !important
    +}
    +
    +.top-bar{
    +	background:#f1f1f1
    +}
    +.side-nav > ul > li > ul li {
    +	border-bottom:1px rgba(0,0,0,.08) solid
    +}
    +
    +table {
    +	border: 1px solid #e2e2e2;
    +}
    +tr:nth-child(even) {
    +    background: #f3f3f3;
    +}
    +th {
    +    border-right: 1px solid #e2e2e2;
    +
    +	border-bottom: 2px #777 solid;
    +}
    +td, caption {
    +	border-right: 1px solid #e2e2e2;
    +	border-bottom: 1px solid #e2e2e2;
    +}
    +.bottom_tools a i{
    +	color:#dadada
    +}
    +.comment-list > li{
    +	border:1px #ececec solid;
    +}
    +.divider.bg i,.sitemap > ul > li > a,.comment-list .comment-avatar,.accordion.style-5 .panel-collapse{
    +	background:#ececec
    +}
    +.item-cart {
    +	border-bottom: 1px #dfdfdf solid;
    +}
    +#items-num {
    +	border: 1px #dfdfdf solid;
    +
    +}
    +.old-price{
    +	color:#c4c3c3;
    +}
    +.shop-ajax {
    +	background-color: #fff;
    +}
    +.diamond.colored{
    +	color:#fff;
    +	text-shadow: 1px 1px 1px rgba(0,0,0,.5);
    +}
    +.pageWrapper.boxed{
    +	box-shadow: 0 10px 10px #666;
    +}
    +.full-heading.dark-bg:before{
    +	border-color:#777 transparent transparent transparent
    +}
    +.full-heading.black-bg:before{
    +	border-color:#222 transparent transparent transparent
    +}
    +.full-heading.gry-bg:before{
    +	border-color:#f1f1f1 transparent transparent transparent
    +}
    +.full-heading.alter-gry:before{
    +	border-color:#e8e8e8 transparent transparent transparent
    +}
    +
    +@font-face {
    +	font-family: 'Pe-icon-7-stroke';
    +	src:url('../fonts/Pe-icon-7-stroke.eot?d7yf1v');
    +	src:url('../fonts/Pe-icon-7-stroke.eot?#iefixd7yf1v') format('embedded-opentype'),
    +		url('../fonts/Pe-icon-7-stroke.woff?d7yf1v') format('woff'),
    +		url('../fonts/Pe-icon-7-stroke.ttf?d7yf1v') format('truetype'),
    +		url('../fonts/Pe-icon-7-stroke.svg?d7yf1v#Pe-icon-7-stroke') format('svg');
    +	font-weight: normal;
    +	font-style: normal;
    +}
    +
    +[class^="pe-7s-"], [class*=" pe-7s-"] {
    +	display: inline-block;
    +	font-family: 'Pe-icon-7-stroke';
    +	speak: none;
    +	font-style: normal;
    +	font-weight: normal;
    +	font-variant: normal;
    +	text-transform: none;
    +	line-height: 1;
    +
    +	/* Better Font Rendering =========== */
    +	-webkit-font-smoothing: antialiased;
    +	-moz-osx-font-smoothing: grayscale;
    +}
    +
    +.pe-7s-album:before {
    +	content: "\e6aa";
    +}
    +.pe-7s-arc:before {
    +	content: "\e6ab";
    +}
    +.pe-7s-back-2:before {
    +	content: "\e6ac";
    +}
    +.pe-7s-bandaid:before {
    +	content: "\e6ad";
    +}
    +.pe-7s-car:before {
    +	content: "\e6ae";
    +}
    +.pe-7s-diamond:before {
    +	content: "\e6af";
    +}
    +.pe-7s-door-lock:before {
    +	content: "\e6b0";
    +}
    +.pe-7s-eyedropper:before {
    +	content: "\e6b1";
    +}
    +.pe-7s-female:before {
    +	content: "\e6b2";
    +}
    +.pe-7s-gym:before {
    +	content: "\e6b3";
    +}
    +.pe-7s-hammer:before {
    +	content: "\e6b4";
    +}
    +.pe-7s-headphones:before {
    +	content: "\e6b5";
    +}
    +.pe-7s-helm:before {
    +	content: "\e6b6";
    +}
    +.pe-7s-hourglass:before {
    +	content: "\e6b7";
    +}
    +.pe-7s-leaf:before {
    +	content: "\e6b8";
    +}
    +.pe-7s-magic-wand:before {
    +	content: "\e6b9";
    +}
    +.pe-7s-male:before {
    +	content: "\e6ba";
    +}
    +.pe-7s-map-2:before {
    +	content: "\e6bb";
    +}
    +.pe-7s-next-2:before {
    +	content: "\e6bc";
    +}
    +.pe-7s-paint-bucket:before {
    +	content: "\e6bd";
    +}
    +.pe-7s-pendrive:before {
    +	content: "\e6be";
    +}
    +.pe-7s-photo:before {
    +	content: "\e6bf";
    +}
    +.pe-7s-piggy:before {
    +	content: "\e6c0";
    +}
    +.pe-7s-plugin:before {
    +	content: "\e6c1";
    +}
    +.pe-7s-refresh-2:before {
    +	content: "\e6c2";
    +}
    +.pe-7s-rocket:before {
    +	content: "\e6c3";
    +}
    +.pe-7s-settings:before {
    +	content: "\e6c4";
    +}
    +.pe-7s-shield:before {
    +	content: "\e6c5";
    +}
    +.pe-7s-smile:before {
    +	content: "\e6c6";
    +}
    +.pe-7s-usb:before {
    +	content: "\e6c7";
    +}
    +.pe-7s-vector:before {
    +	content: "\e6c8";
    +}
    +.pe-7s-wine:before {
    +	content: "\e6c9";
    +}
    +.pe-7s-cloud-upload:before {
    +	content: "\e68a";
    +}
    +.pe-7s-cash:before {
    +	content: "\e68c";
    +}
    +.pe-7s-close:before {
    +	content: "\e680";
    +}
    +.pe-7s-bluetooth:before {
    +	content: "\e68d";
    +}
    +.pe-7s-cloud-download:before {
    +	content: "\e68b";
    +}
    +.pe-7s-way:before {
    +	content: "\e68e";
    +}
    +.pe-7s-close-circle:before {
    +	content: "\e681";
    +}
    +.pe-7s-id:before {
    +	content: "\e68f";
    +}
    +.pe-7s-angle-up:before {
    +	content: "\e682";
    +}
    +.pe-7s-wristwatch:before {
    +	content: "\e690";
    +}
    +.pe-7s-angle-up-circle:before {
    +	content: "\e683";
    +}
    +.pe-7s-world:before {
    +	content: "\e691";
    +}
    +.pe-7s-angle-right:before {
    +	content: "\e684";
    +}
    +.pe-7s-volume:before {
    +	content: "\e692";
    +}
    +.pe-7s-angle-right-circle:before {
    +	content: "\e685";
    +}
    +.pe-7s-users:before {
    +	content: "\e693";
    +}
    +.pe-7s-angle-left:before {
    +	content: "\e686";
    +}
    +.pe-7s-user-female:before {
    +	content: "\e694";
    +}
    +.pe-7s-angle-left-circle:before {
    +	content: "\e687";
    +}
    +.pe-7s-up-arrow:before {
    +	content: "\e695";
    +}
    +.pe-7s-angle-down:before {
    +	content: "\e688";
    +}
    +.pe-7s-switch:before {
    +	content: "\e696";
    +}
    +.pe-7s-angle-down-circle:before {
    +	content: "\e689";
    +}
    +.pe-7s-scissors:before {
    +	content: "\e697";
    +}
    +.pe-7s-wallet:before {
    +	content: "\e600";
    +}
    +.pe-7s-safe:before {
    +	content: "\e698";
    +}
    +.pe-7s-volume2:before {
    +	content: "\e601";
    +}
    +.pe-7s-volume1:before {
    +	content: "\e602";
    +}
    +.pe-7s-voicemail:before {
    +	content: "\e603";
    +}
    +.pe-7s-video:before {
    +	content: "\e604";
    +}
    +.pe-7s-user:before {
    +	content: "\e605";
    +}
    +.pe-7s-upload:before {
    +	content: "\e606";
    +}
    +.pe-7s-unlock:before {
    +	content: "\e607";
    +}
    +.pe-7s-umbrella:before {
    +	content: "\e608";
    +}
    +.pe-7s-trash:before {
    +	content: "\e609";
    +}
    +.pe-7s-tools:before {
    +	content: "\e60a";
    +}
    +.pe-7s-timer:before {
    +	content: "\e60b";
    +}
    +.pe-7s-ticket:before {
    +	content: "\e60c";
    +}
    +.pe-7s-target:before {
    +	content: "\e60d";
    +}
    +.pe-7s-sun:before {
    +	content: "\e60e";
    +}
    +.pe-7s-study:before {
    +	content: "\e60f";
    +}
    +.pe-7s-stopwatch:before {
    +	content: "\e610";
    +}
    +.pe-7s-star:before {
    +	content: "\e611";
    +}
    +.pe-7s-speaker:before {
    +	content: "\e612";
    +}
    +.pe-7s-signal:before {
    +	content: "\e613";
    +}
    +.pe-7s-shuffle:before {
    +	content: "\e614";
    +}
    +.pe-7s-shopbag:before {
    +	content: "\e615";
    +}
    +.pe-7s-share:before {
    +	content: "\e616";
    +}
    +.pe-7s-server:before {
    +	content: "\e617";
    +}
    +.pe-7s-search:before {
    +	content: "\e618";
    +}
    +.pe-7s-film:before {
    +	content: "\e6a5";
    +}
    +.pe-7s-science:before {
    +	content: "\e619";
    +}
    +.pe-7s-disk:before {
    +	content: "\e6a6";
    +}
    +.pe-7s-ribbon:before {
    +	content: "\e61a";
    +}
    +.pe-7s-repeat:before {
    +	content: "\e61b";
    +}
    +.pe-7s-refresh:before {
    +	content: "\e61c";
    +}
    +.pe-7s-add-user:before {
    +	content: "\e6a9";
    +}
    +.pe-7s-refresh-cloud:before {
    +	content: "\e61d";
    +}
    +.pe-7s-paperclip:before {
    +	content: "\e69c";
    +}
    +.pe-7s-radio:before {
    +	content: "\e61e";
    +}
    +.pe-7s-note2:before {
    +	content: "\e69d";
    +}
    +.pe-7s-print:before {
    +	content: "\e61f";
    +}
    +.pe-7s-network:before {
    +	content: "\e69e";
    +}
    +.pe-7s-prev:before {
    +	content: "\e620";
    +}
    +.pe-7s-mute:before {
    +	content: "\e69f";
    +}
    +.pe-7s-power:before {
    +	content: "\e621";
    +}
    +.pe-7s-medal:before {
    +	content: "\e6a0";
    +}
    +.pe-7s-portfolio:before {
    +	content: "\e622";
    +}
    +.pe-7s-like2:before {
    +	content: "\e6a1";
    +}
    +.pe-7s-plus:before {
    +	content: "\e623";
    +}
    +.pe-7s-left-arrow:before {
    +	content: "\e6a2";
    +}
    +.pe-7s-play:before {
    +	content: "\e624";
    +}
    +.pe-7s-key:before {
    +	content: "\e6a3";
    +}
    +.pe-7s-plane:before {
    +	content: "\e625";
    +}
    +.pe-7s-joy:before {
    +	content: "\e6a4";
    +}
    +.pe-7s-photo-gallery:before {
    +	content: "\e626";
    +}
    +.pe-7s-pin:before {
    +	content: "\e69b";
    +}
    +.pe-7s-phone:before {
    +	content: "\e627";
    +}
    +.pe-7s-plug:before {
    +	content: "\e69a";
    +}
    +.pe-7s-pen:before {
    +	content: "\e628";
    +}
    +.pe-7s-right-arrow:before {
    +	content: "\e699";
    +}
    +.pe-7s-paper-plane:before {
    +	content: "\e629";
    +}
    +.pe-7s-delete-user:before {
    +	content: "\e6a7";
    +}
    +.pe-7s-paint:before {
    +	content: "\e62a";
    +}
    +.pe-7s-bottom-arrow:before {
    +	content: "\e6a8";
    +}
    +.pe-7s-notebook:before {
    +	content: "\e62b";
    +}
    +.pe-7s-note:before {
    +	content: "\e62c";
    +}
    +.pe-7s-next:before {
    +	content: "\e62d";
    +}
    +.pe-7s-news-paper:before {
    +	content: "\e62e";
    +}
    +.pe-7s-musiclist:before {
    +	content: "\e62f";
    +}
    +.pe-7s-music:before {
    +	content: "\e630";
    +}
    +.pe-7s-mouse:before {
    +	content: "\e631";
    +}
    +.pe-7s-more:before {
    +	content: "\e632";
    +}
    +.pe-7s-moon:before {
    +	content: "\e633";
    +}
    +.pe-7s-monitor:before {
    +	content: "\e634";
    +}
    +.pe-7s-micro:before {
    +	content: "\e635";
    +}
    +.pe-7s-menu:before {
    +	content: "\e636";
    +}
    +.pe-7s-map:before {
    +	content: "\e637";
    +}
    +.pe-7s-map-marker:before {
    +	content: "\e638";
    +}
    +.pe-7s-mail:before {
    +	content: "\e639";
    +}
    +.pe-7s-mail-open:before {
    +	content: "\e63a";
    +}
    +.pe-7s-mail-open-file:before {
    +	content: "\e63b";
    +}
    +.pe-7s-magnet:before {
    +	content: "\e63c";
    +}
    +.pe-7s-loop:before {
    +	content: "\e63d";
    +}
    +.pe-7s-look:before {
    +	content: "\e63e";
    +}
    +.pe-7s-lock:before {
    +	content: "\e63f";
    +}
    +.pe-7s-lintern:before {
    +	content: "\e640";
    +}
    +.pe-7s-link:before {
    +	content: "\e641";
    +}
    +.pe-7s-like:before {
    +	content: "\e642";
    +}
    +.pe-7s-light:before {
    +	content: "\e643";
    +}
    +.pe-7s-less:before {
    +	content: "\e644";
    +}
    +.pe-7s-keypad:before {
    +	content: "\e645";
    +}
    +.pe-7s-junk:before {
    +	content: "\e646";
    +}
    +.pe-7s-info:before {
    +	content: "\e647";
    +}
    +.pe-7s-home:before {
    +	content: "\e648";
    +}
    +.pe-7s-help2:before {
    +	content: "\e649";
    +}
    +.pe-7s-help1:before {
    +	content: "\e64a";
    +}
    +.pe-7s-graph3:before {
    +	content: "\e64b";
    +}
    +.pe-7s-graph2:before {
    +	content: "\e64c";
    +}
    +.pe-7s-graph1:before {
    +	content: "\e64d";
    +}
    +.pe-7s-graph:before {
    +	content: "\e64e";
    +}
    +.pe-7s-global:before {
    +	content: "\e64f";
    +}
    +.pe-7s-gleam:before {
    +	content: "\e650";
    +}
    +.pe-7s-glasses:before {
    +	content: "\e651";
    +}
    +.pe-7s-gift:before {
    +	content: "\e652";
    +}
    +.pe-7s-folder:before {
    +	content: "\e653";
    +}
    +.pe-7s-flag:before {
    +	content: "\e654";
    +}
    +.pe-7s-filter:before {
    +	content: "\e655";
    +}
    +.pe-7s-file:before {
    +	content: "\e656";
    +}
    +.pe-7s-expand1:before {
    +	content: "\e657";
    +}
    +.pe-7s-exapnd2:before {
    +	content: "\e658";
    +}
    +.pe-7s-edit:before {
    +	content: "\e659";
    +}
    +.pe-7s-drop:before {
    +	content: "\e65a";
    +}
    +.pe-7s-drawer:before {
    +	content: "\e65b";
    +}
    +.pe-7s-download:before {
    +	content: "\e65c";
    +}
    +.pe-7s-display2:before {
    +	content: "\e65d";
    +}
    +.pe-7s-display1:before {
    +	content: "\e65e";
    +}
    +.pe-7s-diskette:before {
    +	content: "\e65f";
    +}
    +.pe-7s-date:before {
    +	content: "\e660";
    +}
    +.pe-7s-cup:before {
    +	content: "\e661";
    +}
    +.pe-7s-culture:before {
    +	content: "\e662";
    +}
    +.pe-7s-crop:before {
    +	content: "\e663";
    +}
    +.pe-7s-credit:before {
    +	content: "\e664";
    +}
    +.pe-7s-copy-file:before {
    +	content: "\e665";
    +}
    +.pe-7s-config:before {
    +	content: "\e666";
    +}
    +.pe-7s-compass:before {
    +	content: "\e667";
    +}
    +.pe-7s-comment:before {
    +	content: "\e668";
    +}
    +.pe-7s-coffee:before {
    +	content: "\e669";
    +}
    +.pe-7s-cloud:before {
    +	content: "\e66a";
    +}
    +.pe-7s-clock:before {
    +	content: "\e66b";
    +}
    +.pe-7s-check:before {
    +	content: "\e66c";
    +}
    +.pe-7s-chat:before {
    +	content: "\e66d";
    +}
    +.pe-7s-cart:before {
    +	content: "\e66e";
    +}
    +.pe-7s-camera:before {
    +	content: "\e66f";
    +}
    +.pe-7s-call:before {
    +	content: "\e670";
    +}
    +.pe-7s-calculator:before {
    +	content: "\e671";
    +}
    +.pe-7s-browser:before {
    +	content: "\e672";
    +}
    +.pe-7s-box2:before {
    +	content: "\e673";
    +}
    +.pe-7s-box1:before {
    +	content: "\e674";
    +}
    +.pe-7s-bookmarks:before {
    +	content: "\e675";
    +}
    +.pe-7s-bicycle:before {
    +	content: "\e676";
    +}
    +.pe-7s-bell:before {
    +	content: "\e677";
    +}
    +.pe-7s-battery:before {
    +	content: "\e678";
    +}
    +.pe-7s-ball:before {
    +	content: "\e679";
    +}
    +.pe-7s-back:before {
    +	content: "\e67a";
    +}
    +.pe-7s-attention:before {
    +	content: "\e67b";
    +}
    +.pe-7s-anchor:before {
    +	content: "\e67c";
    +}
    +.pe-7s-albums:before {
    +	content: "\e67d";
    +}
    +.pe-7s-alarm:before {
    +	content: "\e67e";
    +}
    +.pe-7s-airplay:before {
    +	content: "\e67f";
    +}
    +/*-----------------------------------------------------------------------------
    +
    +-	Revolution Slider 5.0 Default Style Settings -
    +
    +Screen Stylesheet
    +
    +version:   	5.0.0
    +date:      	18/03/15
    +author:		themepunch
    +email:     	info@themepunch.com
    +website:   	http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +
    +
    +@font-face {
    +  font-family: 'revicons';
    +  src: url('../fonts/revicons/revicons.eot?5510888');
    +  src: url('../fonts/revicons/revicons.eot?5510888#iefix') format('embedded-opentype'),
    +       url('../fonts/revicons/revicons.woff?5510888') format('woff'),
    +       url('../fonts/revicons/revicons.ttf?5510888') format('truetype'),
    +       url('../fonts/revicons/revicons.svg?5510888#revicons') format('svg');
    +  font-weight: normal;
    +  font-style: normal;
    +}
    +
    + [class^="revicon-"]:before, [class*=" revicon-"]:before {
    +  font-family: "revicons";
    +  font-style: normal;
    +  font-weight: normal;
    +  speak: none;
    +  display: inline-block;
    +  text-decoration: inherit;
    +  width: 1em;
    +  margin-right: .2em;
    +  text-align: center;
    +
    +  /* For safety - reset parent styles, that can break glyph codes*/
    +  font-variant: normal;
    +  text-transform: none;
    +
    +  /* fix buttons height, for twitter bootstrap */
    +  line-height: 1em;
    +
    +  /* Animation center compensation - margins should be symmetric */
    +  /* remove if not needed */
    +  margin-left: .2em;
    +
    +  /* you can be more comfortable with increased icons size */
    +  /* font-size: 120%; */
    +
    +  /* Uncomment for 3D effect */
    +  /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
    +}
    +
    +.revicon-search-1:before { content: '\e802'; } /* 'î ‚' */
    +.revicon-pencil-1:before { content: '\e831'; } /* 'î ±' */
    +.revicon-picture-1:before { content: '\e803'; } /* 'î ƒ' */
    +.revicon-cancel:before { content: '\e80a'; } /* 'î Š' */
    +.revicon-info-circled:before { content: '\e80f'; } /* 'î ' */
    +.revicon-trash:before { content: '\e801'; } /* 'î ' */
    +.revicon-left-dir:before { content: '\e817'; } /* 'î —' */
    +.revicon-right-dir:before { content: '\e818'; } /* 'î ˜' */
    +.revicon-down-open:before { content: '\e83b'; } /* 'î »' */
    +.revicon-left-open:before { content: '\e819'; } /* 'î ™' */
    +.revicon-right-open:before { content: '\e81a'; } /* 'î š' */
    +.revicon-angle-left:before { content: '\e820'; } /* 'î  ' */
    +.revicon-angle-right:before { content: '\e81d'; } /* 'î ' */
    +.revicon-left-big:before { content: '\e81f'; } /* 'î Ÿ' */
    +.revicon-right-big:before { content: '\e81e'; } /* 'î ž' */
    +.revicon-magic:before { content: '\e807'; } /* 'î ‡' */
    +.revicon-picture:before { content: '\e800'; } /* 'î €' */
    +.revicon-export:before { content: '\e80b'; } /* 'î ‹' */
    +.revicon-cog:before { content: '\e832'; } /* 'î ²' */
    +.revicon-login:before { content: '\e833'; } /* 'î ³' */
    +.revicon-logout:before { content: '\e834'; } /* 'î ´' */
    +.revicon-video:before { content: '\e805'; } /* 'î …' */
    +.revicon-arrow-combo:before { content: '\e827'; } /* 'î §' */
    +.revicon-left-open-1:before { content: '\e82a'; } /* 'î ª' */
    +.revicon-right-open-1:before { content: '\e82b'; } /* 'î «' */
    +.revicon-left-open-mini:before { content: '\e822'; } /* 'î ¢' */
    +.revicon-right-open-mini:before { content: '\e823'; } /* 'î £' */
    +.revicon-left-open-big:before { content: '\e824'; } /* 'î ¤' */
    +.revicon-right-open-big:before { content: '\e825'; } /* 'î ¥' */
    +.revicon-left:before { content: '\e836'; } /* 'î ¶' */
    +.revicon-right:before { content: '\e826'; } /* 'î ¦' */
    +.revicon-ccw:before { content: '\e808'; } /* 'î ˆ' */
    +.revicon-arrows-ccw:before { content: '\e806'; } /* 'î †' */
    +.revicon-palette:before { content: '\e829'; } /* 'î ©' */
    +.revicon-list-add:before { content: '\e80c'; } /* 'î Œ' */
    +.revicon-doc:before { content: '\e809'; } /* 'î ‰' */
    +.revicon-left-open-outline:before { content: '\e82e'; } /* 'î ®' */
    +.revicon-left-open-2:before { content: '\e82c'; } /* 'î ¬' */
    +.revicon-right-open-outline:before { content: '\e82f'; } /* 'î ¯' */
    +.revicon-right-open-2:before { content: '\e82d'; } /* 'î ­' */
    +.revicon-equalizer:before { content: '\e83a'; } /* 'î º' */
    +.revicon-layers-alt:before { content: '\e804'; } /* 'î „' */
    +.revicon-popup:before { content: '\e828'; } /* 'î ¨' */
    +
    +
    +
    +/******************************
    +	-	BASIC STYLES		-
    +******************************/
    +
    +.rev_slider_wrapper{
    +	position:relative;
    +	z-index: 0;
    +}
    +
    +
    +.rev_slider{
    +	position:relative;
    +	overflow:visible;
    +}
    +
    +.tp-overflow-hidden { overflow:hidden;}
    +
    +.tp-simpleresponsive img,
    +.rev_slider img{
    +	max-width:none !important;
    +	-moz-transition: none 0;
    +	-webkit-transition: none 0;
    +	-o-transition: none 0;
    +	transition: none 0;
    +	margin:0px;
    +	padding:0px;
    +	border-width:0px;
    +	border:none;
    +}
    +
    +.rev_slider .no-slides-text{
    +	font-weight:bold;
    +	text-align:center;
    +	padding-top:80px;
    +}
    +
    +.rev_slider >ul,
    +.rev_slider_wrapper >ul,
    +.tp-revslider-mainul >li,
    +.rev_slider >ul >li,
    +.rev_slider >ul >li:before,
    +.tp-revslider-mainul >li:before,
    +.tp-simpleresponsive >ul,
    +.tp-simpleresponsive >ul >li,
    +.tp-simpleresponsive >ul >li:before,
    +.tp-revslider-mainul >li,
    +.tp-simpleresponsive >ul >li{
    +	list-style:none !important;
    +	position:absolute;
    +	margin:0px !important;
    +	padding:0px !important;
    +	overflow-x: visible;
    +	overflow-y: visible;
    +	list-style-type: none !important;
    +	background-image:none;
    +	background-position:0px 0px;
    +	text-indent: 0em;
    +	top:0px;left:0px;
    +}
    +
    +
    +.tp-revslider-mainul >li,
    +.rev_slider >ul >li,
    +.rev_slider >ul >li:before,
    +.tp-revslider-mainul >li:before,
    +.tp-simpleresponsive >ul >li,
    +.tp-simpleresponsive >ul >li:before,
    +.tp-revslider-mainul >li,
    +.tp-simpleresponsive >ul >li {
    +	visibility:hidden;
    +}
    +
    +.tp-revslider-slidesli,
    +.tp-revslider-mainul	{
    +	padding:0 !important;
    +	margin:0 !important;
    +	list-style:none !important;
    +}
    +
    +.rev_slider .tp-caption,
    +.rev_slider .caption 	{
    +	position:relative;
    +	visibility:hidden;
    +	white-space: nowrap;
    +	display: block;
    +}
    +
    +
    +/* CAROUSEL FUNCTIONS */
    +.tp-carousel-wrapper {
    +	cursor:url(openhand.cur), move;
    +}
    +.tp-carousel-wrapper.dragged {
    +	cursor:url(closedhand.cur), move;
    +}
    +
    +/* ADDED FOR SLIDELINK MANAGEMENT */
    +.tp-caption {
    +	z-index:1
    +}
    +
    +.tp_inner_padding {
    +	box-sizing:border-box;
    +	-webkit-box-sizing:border-box;
    +	-moz-box-sizing:border-box;
    +	max-height:none !important;
    +}
    +
    +
    +.tp-caption {
    +	-moz-user-select: none;
    +	-khtml-user-select: none;
    +	-webkit-user-select: none;
    +	-o-user-select: none;
    +	position:absolute;
    +	-webkit-font-smoothing: antialiased !important;
    +}
    +
    +
    +
    +.tp-forcenotvisible,
    +.tp-hide-revslider,
    +.tp-caption.tp-hidden-caption {
    +	visibility:hidden !important;
    +	display:none !important
    +}
    +
    +.rev_slider embed,
    +.rev_slider iframe,
    +.rev_slider object,
    +.rev_slider video {
    +	max-width: none !important
    +}
    +
    +
    +
    +/**********************************************
    +	-	FULLSCREEN AND FULLWIDHT CONTAINERS	-
    +**********************************************/
    +.rev_slider_wrapper	{	width:100%;}
    +
    +.fullscreen-container {
    +	position:relative;
    +	padding:0;
    +}
    +
    +
    +.fullwidthbanner-container{
    +	position:relative;
    +	padding:0;
    +	overflow:hidden;
    +}
    +
    +.fullwidthbanner-container .fullwidthabanner{
    +	width:100%;
    +	position:relative;
    +}
    +
    +
    +
    +/*********************************
    +	-	SPECIAL TP CAPTIONS -
    +**********************************/
    +
    +.tp-static-layers				{
    +	position:absolute; z-index:505; top:0px;left:0px}
    +
    +
    +.tp-caption .frontcorner		{
    +	width: 0;
    +	height: 0;
    +	border-left: 40px solid transparent;
    +	border-right: 0px solid transparent;
    +	border-top: 40px solid #00A8FF;
    +	position: absolute;left:-40px;top:0px;
    +}
    +
    +.tp-caption .backcorner		{
    +	width: 0;
    +	height: 0;
    +	border-left: 0px solid transparent;
    +	border-right: 40px solid transparent;
    +	border-bottom: 40px solid #00A8FF;
    +	position: absolute;right:0px;top:0px;
    +}
    +
    +.tp-caption .frontcornertop		{
    +	width: 0;
    +	height: 0;
    +	border-left: 40px solid transparent;
    +	border-right: 0px solid transparent;
    +	border-bottom: 40px solid #00A8FF;
    +	position: absolute;left:-40px;top:0px;
    +}
    +
    +.tp-caption .backcornertop		{
    +	width: 0;
    +	height: 0;
    +	border-left: 0px solid transparent;
    +	border-right: 40px solid transparent;
    +	border-top: 40px solid #00A8FF;
    +	position: absolute;right:0px;top:0px;
    +}
    +
    +.tp-layer-inner-rotation {
    +	position: relative !important;
    +}
    +
    +
    +/***********************************************
    +	-	SPECIAL ALTERNATIVE IMAGE SETTINGS	-
    +***********************************************/
    +
    +img.tp-slider-alternative-image	{
    +	width:100%; height:auto;
    +}
    +
    +
    +/******************************
    +	-	IE8 HACKS	-
    +*******************************/
    +.noFilterClass {
    +	filter:none !important;
    +}
    +
    +
    +/********************************
    +	-	FULLSCREEN VIDEO	-
    +*********************************/
    +
    +.rs-background-video-layer 		{	position: absolute;top:0px;left:0px; width:100%;height:100%;visibility: hidden;z-index: 0;}
    +
    +.tp-caption.coverscreenvideo	{	width:100%;height:100%;top:0px;left:0px;position:absolute;}
    +.caption.fullscreenvideo,
    +.tp-caption.fullscreenvideo		{	left:0px; top:0px; position:absolute;width:100%;height:100%}
    +
    +.caption.fullscreenvideo iframe,
    +.caption.fullscreenvideo video,
    +.tp-caption.fullscreenvideo iframe,
    +.tp-caption.fullscreenvideo iframe video	{ width:100% !important; height:100% !important; display: none}
    +
    +.fullcoveredvideo video,
    +.fullscreenvideo video				{	background: #000}
    +
    +.fullcoveredvideo .tp-poster		{	background-position: center center;background-size: cover;width:100%;height:100%;top:0px;left:0px}
    +
    +
    +.videoisplaying .html5vid .tp-poster	{	display: none}
    +
    +.tp-video-play-button					{
    +	background:#000;
    +	background:rgba(0,0,0,0.3);
    +	border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;
    +	position: absolute;
    +	top: 50%;
    +	left: 50%;
    +	color: #FFF;
    +	z-index: 3;
    +	margin-top: -25px;
    +	margin-left: -25px;
    +	line-height: 50px !important;
    +	text-align: center;
    +	cursor: pointer;
    +	width: 50px;
    +	height:50px;
    +	box-sizing: border-box;
    +	-moz-box-sizing: border-box;
    +	display: inline-block;
    +	vertical-align: top;
    +	z-index: 4;
    +	opacity: 0;
    +	-webkit-transition:opacity 300ms ease-out !important;
    +	-moz-transition:opacity 300ms ease-out !important;
    +	-o-transition:opacity 300ms ease-out !important;
    +	transition:opacity 300ms ease-out !important;
    +}
    +.tp-caption .html5vid					{	width:100% !important; height:100% !important;}
    +.tp-video-play-button i 				{	width:50px;height:50px; display:inline-block; text-align: center; vertical-align: top; line-height: 50px !important; font-size: 40px !important;}
    +.tp-caption:hover .tp-video-play-button	{	opacity: 1;}
    +.tp-caption .tp-revstop					{	display:none; border-left:5px solid #fff !important; border-right:5px solid #fff !important;margin-top:15px !important;line-height: 20px !important;vertical-align: top; font-size:25px !important;}
    +.videoisplaying .revicon-right-dir		{	display:none}
    +.videoisplaying .tp-revstop				{	display:inline-block}
    +
    +.videoisplaying  .tp-video-play-button			{	display:none}
    +.tp-caption:hover .tp-video-play-button 		{ 	display:block}
    +
    +.fullcoveredvideo .tp-video-play-button			{	display:none !important}
    +
    +
    +.fullscreenvideo .fullscreenvideo video 		{	object-fit:contain !important;}
    +
    +.fullscreenvideo .fullcoveredvideo video 		{	object-fit:cover !important;}
    +
    +.tp-video-controls {
    +	position: absolute;
    +	bottom: 0;
    +	left: 0;
    +	right: 0;
    +	padding: 5px;
    +	opacity: 0;
    +	-webkit-transition: opacity .3s;
    +	-moz-transition: opacity .3s;
    +	-o-transition: opacity .3s;
    +	-ms-transition: opacity .3s;
    +	transition: opacity .3s;
    +	background-image: linear-gradient(bottom, rgb(0,0,0) 13%, rgb(50,50,50) 100%);
    +	background-image: -o-linear-gradient(bottom, rgb(0,0,0) 13%, rgb(50,50,50) 100%);
    +	background-image: -moz-linear-gradient(bottom, rgb(0,0,0) 13%, rgb(50,50,50) 100%);
    +	background-image: -webkit-linear-gradient(bottom, rgb(0,0,0) 13%, rgb(50,50,50) 100%);
    +	background-image: -ms-linear-gradient(bottom, rgb(0,0,0) 13%, rgb(50,50,50) 100%);
    +	background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0.13, rgb(0,0,0)),color-stop(1, rgb(50,50,50)));
    +	display:table;max-width:100%; overflow:hidden;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;
    +}
    +
    +.tp-caption:hover .tp-video-controls {	opacity: .9;}
    +
    +.tp-video-button {
    +	background: rgba(0,0,0,.5);
    +	border: 0;
    +	color: #EEE;
    +	-webkit-border-radius: 3px;
    +	-moz-border-radius: 3px;
    +	-o-border-radius: 3px;
    +	border-radius: 3px;
    +	cursor:pointer;
    +	line-height:12px;
    +	font-size:12px;
    +	color:#fff;
    +	padding:0px;
    +	margin:0px;
    +	outline: none;
    +	}
    +.tp-video-button:hover 				{	cursor: pointer;}
    +
    +
    +.tp-video-button-wrap,
    +.tp-video-seek-bar-wrap,
    +.tp-video-vol-bar-wrap 				{ 	padding:0px 5px;display:table-cell; }
    +
    +.tp-video-seek-bar-wrap				{	width:80%}
    +.tp-video-vol-bar-wrap				{	width:20%}
    +
    +.tp-volume-bar,
    +.tp-seek-bar						{	width:100%; cursor: pointer;  outline:none; line-height:12px;margin:0; padding:0;}
    +
    +
    +.rs-fullvideo-cover					{	width:100%;height:100%;top:0px;left:0px;position: absolute; background:transparent;z-index:5;}
    +
    +
    +
    +
    +/********************************
    +	-	DOTTED OVERLAYS	-
    +*********************************/
    +.tp-dottedoverlay						{	background-repeat:repeat;width:100%;height:100%;position:absolute;top:0px;left:0px;z-index:3}
    +.tp-dottedoverlay.twoxtwo				{	background:url(../assets/gridtile.png)}
    +.tp-dottedoverlay.twoxtwowhite			{	background:url(../assets/gridtile_white.png)}
    +.tp-dottedoverlay.threexthree			{	background:url(../assets/gridtile_3x3.png)}
    +.tp-dottedoverlay.threexthreewhite		{	background:url(../assets/gridtile_3x3_white.png)}
    +
    +
    +/******************************
    +	-	SHADOWS		-
    +******************************/
    +
    +.tp-shadowcover	{	width:100%;height:100%;top:0px;left:0px;background: #fff;position: absolute; z-index: -1;}
    +.tp-shadow1 {
    +	-webkit-box-shadow: 0 10px 6px -6px rgba(0,0,0,0.8);
    +	   -moz-box-shadow: 0 10px 6px -6px rgba(0,0,0,0.8);
    +	        box-shadow: 0 10px 6px -6px rgba(0,0,0,0.8);
    +}
    +
    +.tp-shadow2:before, .tp-shadow2:after,
    +.tp-shadow3:before, .tp-shadow4:after
    +{
    +  z-index: -2;
    +  position: absolute;
    +  content: "";
    +  bottom: 10px;
    +  left: 10px;
    +  width: 50%;
    +  top: 85%;
    +  max-width:300px;
    +  background: transparent;
    +  -webkit-box-shadow: 0 15px 10px rgba(0,0,0,0.8);
    +  -moz-box-shadow: 0 15px 10px rgba(0,0,0,0.8);
    +  box-shadow: 0 15px 10px rgba(0,0,0,0.8);
    +  -webkit-transform: rotate(-3deg);
    +  -moz-transform: rotate(-3deg);
    +  -o-transform: rotate(-3deg);
    +  -ms-transform: rotate(-3deg);
    +  transform: rotate(-3deg);
    +}
    +
    +.tp-shadow2:after,
    +.tp-shadow4:after
    +{
    +  -webkit-transform: rotate(3deg);
    +  -moz-transform: rotate(3deg);
    +  -o-transform: rotate(3deg);
    +  -ms-transform: rotate(3deg);
    +  transform: rotate(3deg);
    +  right: 10px;
    +  left: auto;
    +}
    +
    +.tp-shadow5
    +{
    +  	position:relative;
    +    -webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
    +       -moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
    +            box-shadow:0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
    +}
    +.tp-shadow5:before, .tp-shadow5:after
    +{
    +	content:"";
    +    position:absolute;
    +    z-index:-2;
    +    -webkit-box-shadow:0 0 25px 0px rgba(0,0,0,0.6);
    +    -moz-box-shadow:0 0 25px 0px  rgba(0,0,0,0.6);
    +    box-shadow:0 0 25px 0px  rgba(0,0,0,0.6);
    +    top:30%;
    +    bottom:0;
    +    left:20px;
    +    right:20px;
    +    -moz-border-radius:100px / 20px;
    +    border-radius:100px / 20px;
    +}
    +
    +/******************************
    +	-	BUTTONS	-
    +*******************************/
    +
    +.tp-button{
    +	padding:6px 13px 5px;
    +	border-radius: 3px;
    +	-moz-border-radius: 3px;
    +	-webkit-border-radius: 3px;
    +	height:30px;
    +	cursor:pointer;
    +	color:#fff !important; text-shadow:0px 1px 1px rgba(0, 0, 0, 0.6) !important; font-size:15px; line-height:45px !important;
    +	background:url(../images/gradient/g30.png) repeat-x top; font-family: arial, sans-serif; font-weight: bold; letter-spacing: -1px;
    +	text-decoration:none;
    +}
    +
    +.tp-button.big	{	color:#fff; text-shadow:0px 1px 1px rgba(0, 0, 0, 0.6); font-weight:bold; padding:9px 20px; font-size:19px;  line-height:57px !important; background:url(../images/gradient/g40.png) repeat-x top}
    +
    +
    +.purchase:hover,
    +.tp-button:hover,
    +.tp-button.big:hover {	background-position:bottom, 15px 11px}
    +
    +
    +/*	BUTTON COLORS	*/
    +
    +.tp-button.green, .tp-button:hover.green,
    +.purchase.green, .purchase:hover.green			{ background-color:#21a117; -webkit-box-shadow:  0px 3px 0px 0px #104d0b;        -moz-box-shadow:   0px 3px 0px 0px #104d0b;        box-shadow:   0px 3px 0px 0px #104d0b;  }
    +
    +.tp-button.blue, .tp-button:hover.blue,
    +.purchase.blue, .purchase:hover.blue			{ background-color:#1d78cb; -webkit-box-shadow:  0px 3px 0px 0px #0f3e68;        -moz-box-shadow:   0px 3px 0px 0px #0f3e68;        box-shadow:   0px 3px 0px 0px #0f3e68}
    +
    +.tp-button.red, .tp-button:hover.red,
    +.purchase.red, .purchase:hover.red				{ background-color:#cb1d1d; -webkit-box-shadow:  0px 3px 0px 0px #7c1212;        -moz-box-shadow:   0px 3px 0px 0px #7c1212;        box-shadow:   0px 3px 0px 0px #7c1212}
    +
    +.tp-button.orange, .tp-button:hover.orange,
    +.purchase.orange, .purchase:hover.orange		{ background-color:#ff7700; -webkit-box-shadow:  0px 3px 0px 0px #a34c00;        -moz-box-shadow:   0px 3px 0px 0px #a34c00;        box-shadow:   0px 3px 0px 0px #a34c00}
    +
    +.tp-button.darkgrey,.tp-button.grey,
    +.tp-button:hover.darkgrey,.tp-button:hover.grey,
    +.purchase.darkgrey, .purchase:hover.darkgrey	{ background-color:#555; -webkit-box-shadow:  0px 3px 0px 0px #222;        -moz-box-shadow:   0px 3px 0px 0px #222;        box-shadow:   0px 3px 0px 0px #222}
    +
    +.tp-button.lightgrey, .tp-button:hover.lightgrey,
    +.purchase.lightgrey, .purchase:hover.lightgrey	{ background-color:#888; -webkit-box-shadow:  0px 3px 0px 0px #555;        -moz-box-shadow:   0px 3px 0px 0px #555;        box-shadow:   0px 3px 0px 0px #555}
    +
    +
    +
    +/* TP BUTTONS DESKTOP SIZE */
    +
    +.rev-btn,
    +.rev-btn:visited						{ 	outline:none !important; box-shadow:none !important; text-decoration: none !important; line-height: 44px; font-size: 17px; font-weight: 500; padding: 12px 35px; box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;  font-family: "Roboto", sans-serif;  cursor: pointer;}
    +
    +.rev-btn.rev-uppercase,
    +.rev-btn.rev-uppercase:visited			{ 	text-transform: uppercase; letter-spacing: 1px; font-size: 15px; font-weight: 900; }
    +
    +.rev-btn.rev-withicon i					{ 	font-size: 15px; font-weight: normal; position: relative; top: 0px; -webkit-transition: all 0.2s ease-out !important; -moz-transition: all 0.2s ease-out !important; -o-transition: all 0.2s ease-out !important; -ms-transition: all 0.2s ease-out !important; margin-left:10px !importan;}
    +
    +.rev-btn.rev-hiddenicon i				{ 	font-size: 15px; font-weight: normal; position: relative; top: 0px; -webkit-transition: all 0.2s ease-out !important; -moz-transition: all 0.2s ease-out !important; -o-transition: all 0.2s ease-out !important; -ms-transition: all 0.2s ease-out !important; opacity: 0; margin-left:0px !important; width:0px !important;  }
    +.rev-btn.rev-hiddenicon:hover i			{   opacity: 1 !important; margin-left:10px !important; width:auto !important;}
    +
    +/* REV BUTTONS MEDIUM */
    +.rev-btn.rev-medium,
    +.rev-btn.rev-medium:visited				{	 line-height: 36px; font-size: 14px; padding: 10px 30px; }
    +
    +.rev-btn.rev-medium.rev-withicon i		{ 	font-size: 14px; top: 0px; }
    +
    +.rev-btn.rev-medium.rev-hiddenicon i	{ 	font-size: 14px; top: 0px; }
    +
    +
    +/* REV BUTTONS SMALL */
    +.rev-btn.rev-small,
    +.rev-btn.rev-small:visited				{	line-height: 28px; font-size: 12px; padding: 7px 20px; }
    +
    +.rev-btn.rev-small.rev-withicon i		{	font-size: 12px; top: 0px; }
    +
    +.rev-btn.rev-small.rev-hiddenicon i		{ 	font-size: 12px; top: 0px; }
    +
    +
    +/* ROUNDING OPTIONS */
    +.rev-maxround 							{ 	-webkit-border-radius: 30px; -moz-border-radius: 30px; border-radius: 30px; }
    +.rev-minround 							{ 	-webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; }
    +
    +
    +/* BURGER BUTTON */
    +.rev-burger {
    +  position: relative;
    +  width: 60px;
    +  height: 60px;
    +  box-sizing: border-box;
    +  padding: 22px 0 0 14px;
    +  border-radius: 50%;
    +  border: 1px solid rgba(51,51,51,0.25);
    +  tap-highlight-color: transparent;
    +  cursor: pointer;
    +}
    +.rev-burger span {
    +  display: block;
    +  width: 30px;
    +  height: 3px;
    +  background: #333;
    +  transition: .7s;
    +  pointer-events: none;
    +  transform-style: flat !important;
    +}
    +.rev-burger span:nth-child(2) {
    +  margin: 3px 0;
    +}
    +
    +#dialog_addbutton .rev-burger:hover :first-child,
    +.open .rev-burger :first-child,
    +.open.rev-burger :first-child {
    +  transform: translateY(6px) rotate(-45deg);
    +  -webkit-transform: translateY(6px) rotate(-45deg);
    +}
    +#dialog_addbutton .rev-burger:hover :nth-child(2),
    +.open .rev-burger :nth-child(2),
    +.open.rev-burger :nth-child(2) {
    +  transform: rotate(-45deg);
    +  -webkit-transform: rotate(-45deg);
    +  opacity: 0;
    +}
    +#dialog_addbutton .rev-burger:hover :last-child,
    +.open .rev-burger :last-child,
    +.open.rev-burger :last-child {
    +  transform: translateY(-6px) rotate(-135deg);
    +  -webkit-transform: translateY(-6px) rotate(-135deg);
    +}
    +
    +.rev-burger.revb-white {
    +  border: 2px solid rgba(255,255,255,0.2);
    +}
    +.rev-burger.revb-white span {
    +  background: #fff;
    +}
    +.rev-burger.revb-whitenoborder {
    +  border: 0;
    +}
    +.rev-burger.revb-whitenoborder span {
    +  background: #fff;
    +}
    +.rev-burger.revb-darknoborder {
    +  border: 0;
    +}
    +.rev-burger.revb-darknoborder span {
    +  background: #333;
    +}
    +
    +.rev-burger.revb-whitefull {
    +  background: #fff;
    +  border:none;
    +}
    +
    +.rev-burger.revb-whitefull span {
    +	background:#333;
    +}
    +
    +.rev-burger.revb-darkfull {
    +  background: #333;
    +  border:none;
    +}
    +
    +.rev-burger.revb-darkfull span {
    +	background:#fff;
    +}
    +
    +
    +/* SCROLL DOWN BUTTON */
    +@-webkit-keyframes rev-ani-mouse {
    +	0% { opacity: 1;top: 29%;}
    +	15% {opacity: 1;top: 50%;}
    +	50% { opacity: 0;top: 50%;}
    +	100% { opacity: 0;top: 29%;}
    +}
    +@-moz-keyframes rev-ani-mouse {
    +	0% {opacity: 1;top: 29%;}
    +	15% {opacity: 1;top: 50%;}
    +	50% {opacity: 0;top: 50%;}
    +	100% {opacity: 0;top: 29%;}
    +}
    +@keyframes rev-ani-mouse {
    +	0% {opacity: 1;top: 29%;}
    +	15% {opacity: 1;top: 50%;}
    +	50% {opacity: 0;top: 50%;}
    +	100% {opacity: 0;top: 29%;}
    +}
    +.rev-scroll-btn {
    +	display: inline-block;
    +	position: relative;
    +	left: 0;
    +	right: 0;
    +	text-align: center;
    +	cursor: pointer;
    +	width:35px;
    +	height:55px;
    +	-webkit-box-sizing: border-box;
    +	-moz-box-sizing: border-box;
    +	box-sizing: border-box;
    +	border: 3px solid white;
    +	border-radius: 23px;
    +}
    +.rev-scroll-btn > * {
    +	display: inline-block;
    +	line-height: 18px;
    +	font-size: 13px;
    +	font-weight: normal;
    +	color: #7f8c8d;
    +	color: #ffffff;
    +	font-family: "proxima-nova", "Helvetica Neue", Helvetica, Arial, sans-serif;
    +	letter-spacing: 2px;
    +}
    +.rev-scroll-btn > *:hover,
    +.rev-scroll-btn > *:focus,
    +.rev-scroll-btn > *.active {
    +	color: #ffffff;
    +}
    +.rev-scroll-btn > *:hover,
    +.rev-scroll-btn > *:focus,
    +.rev-scroll-btn > *:active,
    +.rev-scroll-btn > *.active {
    +	opacity: 0.8;
    +	filter: alpha(opacity=80);
    +}
    +
    +.rev-scroll-btn.revs-fullwhite  {
    +	background:#fff;
    +}
    +
    +.rev-scroll-btn.revs-fullwhite span {
    +	background: #333;
    +}
    +
    +.rev-scroll-btn.revs-fulldark  {
    +	background:#333;
    +	border:none;
    +}
    +
    +.rev-scroll-btn.revs-fulldark  span {
    +	background: #fff;
    +}
    +
    +.rev-scroll-btn span {
    +	position: absolute;
    +	display: block;
    +	top: 29%;
    +	left: 50%;
    +	width: 8px;
    +	height: 8px;
    +	margin: -4px 0 0 -4px;
    +	background: white;
    +	border-radius: 50%;
    +	-webkit-animation: rev-ani-mouse 2.5s linear infinite;
    +	-moz-animation: rev-ani-mouse 2.5s linear infinite;
    +	animation: rev-ani-mouse 2.5s linear infinite;
    +}
    +
    +.rev-scroll-btn.revs-dark {
    +	border-color:#333;
    +}
    +.rev-scroll-btn.revs-dark span {
    +	background: #333;
    +}
    +
    +.rev-control-btn {
    +	position: relative;
    +	display: inline-block;
    +	z-index: 5;
    +	color: #FFF;
    +	font-size: 20px;
    +	line-height: 60px;
    +	font-weight: 400;
    +	font-style: normal;
    +	font-family: Raleway;
    +	text-decoration: none;
    +	text-align: center;
    +	background-color: #000;
    +	border-radius: 50px;
    +	text-shadow: none;
    +	background-color: rgba(0, 0, 0, 0.50);
    +	width:60px;
    +	height:60px;
    +	box-sizing: border-box;
    +	cursor: pointer;
    +}
    +
    +.rev-cbutton-dark-sr	{
    +	border-radius: 3px;
    +}
    +
    +.rev-cbutton-light	{
    +	color: #333;
    +	background-color: rgba(255,255,255, 0.75);
    +}
    +
    +.rev-cbutton-light-sr	{
    +	color: #333;
    +	border-radius: 3;
    +	background-color: rgba(255,255,255, 0.75);
    +}
    +
    +
    +.rev-sbutton {
    +	line-height: 37px;
    +	width:37px;
    +	height:37px;
    +}
    +
    +.rev-sbutton-blue	{
    +	background-color: #3B5998
    +}
    +.rev-sbutton-lightblue	{
    +	background-color: #00A0D1;
    +}
    +.rev-sbutton-red	{
    +	background-color: #DD4B39;
    +}
    +
    +
    +
    +
    +/************************************
    +-	TP BANNER TIMER		-
    +*************************************/
    +.tp-bannertimer								{	visibility: hidden; width:100%; height:5px; /*background:url(../assets/timer.png);*/ background: #fff; background: rgba(0,0,0,0.15); position:absolute; z-index:200; top:0px}
    +.tp-bannertimer.tp-bottom					{	top:auto; bottom:0px !important;height:5px}
    +
    +
    +/*********************************************
    +-	BASIC SETTINGS FOR THE BANNER	-
    +***********************************************/
    +
    + .tp-simpleresponsive img {
    +	-moz-user-select: none;
    +    -khtml-user-select: none;
    +    -webkit-user-select: none;
    +    -o-user-select: none;
    +}
    +
    +.tp-caption img {
    +	background: transparent;
    +	-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)";
    +	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF);
    +	zoom: 1;
    +}
    +
    +
    +
    +/*  CAPTION SLIDELINK   **/
    +.caption.slidelink a div,
    +.tp-caption.slidelink a div {	width:3000px; height:1500px;  background:url(../assets/coloredbg.png) repeat}
    +.tp-caption.slidelink a span{	background:url(../assets/coloredbg.png) repeat}
    +.tp-shape {	width:100%;height:100%;}
    +
    +
    +
    +
    +/******************************
    +	-	LOADER FORMS	-
    +********************************/
    +
    +.tp-loader 	{
    +	top:50%; left:50%;
    +	z-index:10000;
    +	position:absolute;
    +}
    +
    +.tp-loader.spinner0 {
    +	width: 40px;
    +	height: 40px;
    +	background-color: #fff;
    +	background:url(../assets/loader.gif) no-repeat center center;
    +	box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.15);
    +	-webkit-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.15);
    +	margin-top:-20px;
    +	margin-left:-20px;
    +	-webkit-animation: tp-rotateplane 1.2s infinite ease-in-out;
    +	animation: tp-rotateplane 1.2s infinite ease-in-out;
    +	border-radius: 3px;
    +	-moz-border-radius: 3px;
    +	-webkit-border-radius: 3px;
    +}
    +
    +
    +.tp-loader.spinner1 {
    +	width: 40px;
    +	height: 40px;
    +	background-color: #fff;
    +	box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.15);
    +	-webkit-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.15);
    +	margin-top:-20px;
    +	margin-left:-20px;
    +	-webkit-animation: tp-rotateplane 1.2s infinite ease-in-out;
    +	animation: tp-rotateplane 1.2s infinite ease-in-out;
    +	border-radius: 3px;
    +	-moz-border-radius: 3px;
    +	-webkit-border-radius: 3px;
    +}
    +
    +
    +
    +.tp-loader.spinner5 	{
    +	background:url(../assets/loader.gif) no-repeat 10px 10px;
    +	background-color:#fff;
    +	margin:-22px -22px;
    +	width:44px;height:44px;
    +	border-radius: 3px;
    +	-moz-border-radius: 3px;
    +	-webkit-border-radius: 3px;
    +}
    +
    +
    +@-webkit-keyframes tp-rotateplane {
    +  0% { -webkit-transform: perspective(120px) }
    +  50% { -webkit-transform: perspective(120px) rotateY(180deg) }
    +  100% { -webkit-transform: perspective(120px) rotateY(180deg)  rotateX(180deg) }
    +}
    +
    +@keyframes tp-rotateplane {
    +  0% { transform: perspective(120px) rotateX(0deg) rotateY(0deg);}
    +  50% { transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);}
    +  100% { transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);}
    +}
    +
    +
    +.tp-loader.spinner2 {
    +	width: 40px;
    +	height: 40px;
    +	margin-top:-20px;margin-left:-20px;
    +	background-color: #ff0000;
    +	box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.15);
    +	-webkit-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.15);
    +	border-radius: 100%;
    +	-webkit-animation: tp-scaleout 1.0s infinite ease-in-out;
    +	animation: tp-scaleout 1.0s infinite ease-in-out;
    +}
    +
    +@-webkit-keyframes tp-scaleout {
    +  0% { -webkit-transform: scale(0.0) }
    +  100% {-webkit-transform: scale(1.0); opacity: 0;}
    +}
    +
    +@keyframes tp-scaleout {
    +  0% {transform: scale(0.0);-webkit-transform: scale(0.0);}
    +  100% {transform: scale(1.0);-webkit-transform: scale(1.0);opacity: 0;}
    +}
    +
    +
    +.tp-loader.spinner3 {
    +  margin: -9px 0px 0px -35px;
    +  width: 70px;
    +  text-align: center;
    +}
    +
    +.tp-loader.spinner3 .bounce1,
    +.tp-loader.spinner3 .bounce2,
    +.tp-loader.spinner3 .bounce3 {
    +  width: 18px;
    +  height: 18px;
    +  background-color: #fff;
    +  box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.15);
    +  -webkit-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.15);
    +  border-radius: 100%;
    +  display: inline-block;
    +  -webkit-animation: tp-bouncedelay 1.4s infinite ease-in-out;
    +  animation: tp-bouncedelay 1.4s infinite ease-in-out;
    +  /* Prevent first frame from flickering when animation starts */
    +  -webkit-animation-fill-mode: both;
    +  animation-fill-mode: both;
    +}
    +
    +.tp-loader.spinner3 .bounce1 {
    +  -webkit-animation-delay: -0.32s;
    +  animation-delay: -0.32s;
    +}
    +
    +.tp-loader.spinner3 .bounce2 {
    +  -webkit-animation-delay: -0.16s;
    +  animation-delay: -0.16s;
    +}
    +
    +@-webkit-keyframes tp-bouncedelay {
    +  0%, 80%, 100% { -webkit-transform: scale(0.0) }
    +  40% { -webkit-transform: scale(1.0) }
    +}
    +
    +@keyframes tp-bouncedelay {
    +  0%, 80%, 100% {transform: scale(0.0);}
    +  40% {transform: scale(1.0);}
    +}
    +
    +
    +
    +
    +.tp-loader.spinner4 {
    +  margin: -20px 0px 0px -20px;
    +  width: 40px;
    +  height: 40px;
    +  text-align: center;
    +  -webkit-animation: tp-rotate 2.0s infinite linear;
    +  animation: tp-rotate 2.0s infinite linear;
    +}
    +
    +.tp-loader.spinner4 .dot1,
    +.tp-loader.spinner4 .dot2 {
    +  width: 60%;
    +  height: 60%;
    +  display: inline-block;
    +  position: absolute;
    +  top: 0;
    +  background-color: #fff;
    +  border-radius: 100%;
    +  -webkit-animation: tp-bounce 2.0s infinite ease-in-out;
    +  animation: tp-bounce 2.0s infinite ease-in-out;
    +  box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.15);
    +  -webkit-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.15);
    +}
    +
    +.tp-loader.spinner4 .dot2 {
    +  top: auto;
    +  bottom: 0px;
    +  -webkit-animation-delay: -1.0s;
    +  animation-delay: -1.0s;
    +}
    +
    +@-webkit-keyframes tp-rotate { 100% { -webkit-transform: rotate(360deg) }}
    +@keyframes tp-rotate { 100% { transform: rotate(360deg); -webkit-transform: rotate(360deg) }}
    +
    +@-webkit-keyframes tp-bounce {
    +  0%, 100% { -webkit-transform: scale(0.0) }
    +  50% { -webkit-transform: scale(1.0) }
    +}
    +
    +@keyframes tp-bounce {
    +  0%, 100% {transform: scale(0.0);}
    +  50% { transform: scale(1.0);}
    +}
    +
    +
    +
    +/***********************************************
    +	-  STANDARD NAVIGATION SETTINGS
    +***********************************************/
    +
    +
    +.tp-thumbs.navbar,
    +.tp-bullets.navbar,
    +.tp-tabs.navbar					{	border:none; min-height: 0; margin:0; border-radius: 0; -moz-border-radius:0; -webkit-border-radius:0;}
    +
    +.tp-tabs,
    +.tp-thumbs,
    +.tp-bullets						{	position:absolute; display:block; z-index:1000; top:0px; left:0px;}
    +
    +.tp-tab,
    +.tp-thumb 						{	cursor: pointer; position:absolute;opacity:0.5;  box-sizing: border-box;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;}
    +
    +.tp-videoposter,
    +.tp-thumb-image,
    +.tp-tab-image					{	background-position: center center; background-size:cover;width:100%;height:100%; display:block; position:absolute;top:0px;left:0px;}
    +
    +.tp-tab:hover,
    +.tp-tab.selected,
    +.tp-thumb:hover,
    +.tp-thumb.selected				{	opacity:1;}
    +
    +.tp-tab-mask,
    +.tp-thumb-mask 					{	box-sizing:border-box !important; -webkit-box-sizing:border-box !important; -moz-box-sizing:border-box !important}
    +
    +.tp-tabs,
    +.tp-thumbs						{	box-sizing:content-box !important; -webkit-box-sizing:content-box !important; -moz-box-sizing: content-box !important}
    +
    +.tp-bullet 						{	width:15px;height:15px; position:absolute; background:#fff; background:rgba(255,255,255,0.3); cursor: pointer;}
    +.tp-bullet.selected,
    +.tp-bullet:hover				{	background:#fff;}
    +
    +.tp-bannertimer					{	background:#000; background:rgba(0,0,0,0.15); height:5px;}
    +
    +
    +.tparrows						{	cursor:pointer; background:#000; background:rgba(0,0,0,0.5); width:40px;height:40px;position:absolute; display:block; z-index:100; }
    +.tparrows:hover 				{	background:#000;}
    +.tparrows:before				{	font-family: "revicons"; font-size:15px; color:#fff; display:block; line-height: 40px; text-align: center;}
    +.tparrows.tp-leftarrow:before	{	content: '\e824'; }
    +.tparrows.tp-rightarrow:before	{	content: '\e825'; }
    +
    +
    +
    +/*******************
    +	- DEBUG MODE -
    +*******************/
    +
    +.hglayerinfo				   {	  position: fixed;
    +  bottom: 0px;
    +  left: 0px;
    +  color: #FFF;
    +  font-size: 12px;
    +  line-height: 20px;
    +  font-weight: 600;
    +  background: rgba(0, 0, 0, 0.75);
    +  padding: 5px 10px;
    +  z-index: 2000;
    +  white-space: normal;}
    +.hginfo 					   { 	position:absolute;top:-2px;left:-2px;color:#e74c3c;font-size:12px;font-weight:600; background:#000;padding:2px 5px;}
    +.indebugmode .tp-caption:hover { 	border:1px dashed #c0392b !important;}
    +.helpgrid 					   { 	border:2px dashed #c0392b;position:absolute;top:0px;peft:0px;z-index:0 }
    +
    +
    +/*-----------------------------------------------------------------------------
    +
    +-	Revolution Slider 5.0 Layer Style Settings -
    +
    +Screen Stylesheet
    +
    +version:   	5.0.0
    +date:      	18/03/15
    +author:		themepunch
    +email:     	info@themepunch.com
    +website:   	http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +
    +.tp-caption.Twitter-Content a,.tp-caption.Twitter-Content a:visited
    +{
    +	color:#0084B4!important;
    +}
    +
    +.tp-caption.Twitter-Content a:hover
    +{
    +	color:#0084B4!important;
    +	text-decoration:underline!important;
    +}
    +
    +.tp-caption.medium_grey,.medium_grey
    +{
    +	background-color:#888;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:Arial;
    +	font-size:20px;
    +	font-weight:700;
    +	line-height:20px;
    +	margin:0;
    +	padding:2px 4px;
    +	position:absolute;
    +	text-shadow:0 2px 5px rgba(0,0,0,0.5);
    +	white-space:nowrap;
    +}
    +
    +.tp-caption.small_text,.small_text
    +{
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:Arial;
    +	font-size:14px;
    +	font-weight:700;
    +	line-height:20px;
    +	margin:0;
    +	position:absolute;
    +	text-shadow:0 2px 5px rgba(0,0,0,0.5);
    +	white-space:nowrap;
    +}
    +
    +.tp-caption.medium_text,.medium_text
    +{
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:Arial;
    +	font-size:20px;
    +	font-weight:700;
    +	line-height:20px;
    +	margin:0;
    +	position:absolute;
    +	text-shadow:0 2px 5px rgba(0,0,0,0.5);
    +	white-space:nowrap;
    +}
    +
    +.tp-caption.large_text,.large_text
    +{
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:Arial;
    +	font-size:40px;
    +	font-weight:700;
    +	line-height:40px;
    +	margin:0;
    +	position:absolute;
    +	text-shadow:0 2px 5px rgba(0,0,0,0.5);
    +	white-space:nowrap;
    +}
    +
    +.tp-caption.very_large_text,.very_large_text
    +{
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:Arial;
    +	font-size:60px;
    +	font-weight:700;
    +	letter-spacing:-2px;
    +	line-height:60px;
    +	margin:0;
    +	position:absolute;
    +	text-shadow:0 2px 5px rgba(0,0,0,0.5);
    +	white-space:nowrap;
    +}
    +
    +.tp-caption.very_big_white,.very_big_white
    +{
    +	background-color:#000;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:Arial;
    +	font-size:60px;
    +	font-weight:800;
    +	line-height:60px;
    +	margin:0;
    +	padding:1px 4px 0;
    +	position:absolute;
    +	text-shadow:none;
    +	white-space:nowrap;
    +}
    +
    +.tp-caption.very_big_black,.very_big_black
    +{
    +	background-color:#fff;
    +	border-style:none;
    +	border-width:0;
    +	color:#000;
    +	font-family:Arial;
    +	font-size:60px;
    +	font-weight:700;
    +	line-height:60px;
    +	margin:0;
    +	padding:1px 4px 0;
    +	position:absolute;
    +	text-shadow:none;
    +	white-space:nowrap;
    +}
    +
    +.tp-caption.modern_medium_fat,.modern_medium_fat
    +{
    +	border-style:none;
    +	border-width:0;
    +	color:#000;
    +	font-family:"Open Sans", sans-serif;
    +	font-size:24px;
    +	font-weight:800;
    +	line-height:20px;
    +	margin:0;
    +	position:absolute;
    +	text-shadow:none;
    +	white-space:nowrap;
    +}
    +
    +.tp-caption.modern_medium_fat_white,.modern_medium_fat_white
    +{
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans", sans-serif;
    +	font-size:24px;
    +	font-weight:800;
    +	line-height:20px;
    +	margin:0;
    +	position:absolute;
    +	text-shadow:none;
    +	white-space:nowrap;
    +}
    +
    +.tp-caption.modern_medium_light,.modern_medium_light
    +{
    +	border-style:none;
    +	border-width:0;
    +	color:#000;
    +	font-family:"Open Sans", sans-serif;
    +	font-size:24px;
    +	font-weight:300;
    +	line-height:20px;
    +	margin:0;
    +	position:absolute;
    +	text-shadow:none;
    +	white-space:nowrap;
    +}
    +
    +.tp-caption.modern_big_bluebg,.modern_big_bluebg
    +{
    +	background-color:#4e5b6c;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans", sans-serif;
    +	font-size:30px;
    +	font-weight:800;
    +	letter-spacing:0;
    +	line-height:36px;
    +	margin:0;
    +	padding:3px 10px;
    +	position:absolute;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.modern_big_redbg,.modern_big_redbg
    +{
    +	background-color:#de543e;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans", sans-serif;
    +	font-size:30px;
    +	font-weight:300;
    +	letter-spacing:0;
    +	line-height:36px;
    +	margin:0;
    +	padding:1px 10px 3px;
    +	position:absolute;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.modern_small_text_dark,.modern_small_text_dark
    +{
    +	border-style:none;
    +	border-width:0;
    +	color:#555;
    +	font-family:Arial;
    +	font-size:14px;
    +	line-height:22px;
    +	margin:0;
    +	position:absolute;
    +	text-shadow:none;
    +	white-space:nowrap;
    +}
    +
    +.tp-caption.boxshadow,.boxshadow
    +{
    +	-moz-box-shadow:0 0 20px rgba(0,0,0,0.5);
    +	-webkit-box-shadow:0 0 20px rgba(0,0,0,0.5);
    +	box-shadow:0 0 20px rgba(0,0,0,0.5);
    +}
    +
    +.tp-caption.black,.black
    +{
    +	color:#000;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.noshadow,.noshadow
    +{
    +	text-shadow:none;
    +}
    +
    +.tp-caption.thinheadline_dark,.thinheadline_dark
    +{
    +	background-color:transparent;
    +	color:rgba(0,0,0,0.85);
    +	font-family:"Open Sans";
    +	font-size:30px;
    +	font-weight:300;
    +	line-height:30px;
    +	position:absolute;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.thintext_dark,.thintext_dark
    +{
    +	background-color:transparent;
    +	color:rgba(0,0,0,0.85);
    +	font-family:"Open Sans";
    +	font-size:16px;
    +	font-weight:300;
    +	line-height:26px;
    +	position:absolute;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.largeblackbg,.largeblackbg
    +{
    +	-moz-border-radius:0;
    +	-webkit-border-radius:0;
    +	background-color:#000;
    +	border-radius:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:50px;
    +	font-weight:300;
    +	line-height:70px;
    +	padding:0 20px;
    +	position:absolute;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.largepinkbg,.largepinkbg
    +{
    +	-moz-border-radius:0;
    +	-webkit-border-radius:0;
    +	background-color:#db4360;
    +	border-radius:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:50px;
    +	font-weight:300;
    +	line-height:70px;
    +	padding:0 20px;
    +	position:absolute;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.largewhitebg,.largewhitebg
    +{
    +	-moz-border-radius:0;
    +	-webkit-border-radius:0;
    +	background-color:#fff;
    +	border-radius:0;
    +	color:#000;
    +	font-family:"Open Sans";
    +	font-size:50px;
    +	font-weight:300;
    +	line-height:70px;
    +	padding:0 20px;
    +	position:absolute;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.largegreenbg,.largegreenbg
    +{
    +	-moz-border-radius:0;
    +	-webkit-border-radius:0;
    +	background-color:#67ae73;
    +	border-radius:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:50px;
    +	font-weight:300;
    +	line-height:70px;
    +	padding:0 20px;
    +	position:absolute;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.excerpt,.excerpt
    +{
    +	background-color:rgba(0,0,0,1);
    +	border-color:#fff;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:Arial;
    +	font-size:36px;
    +	font-weight:700;
    +	height:auto;
    +	letter-spacing:-1.5px;
    +	line-height:36px;
    +	margin:0;
    +	padding:1px 4px 0;
    +	text-decoration:none;
    +	text-shadow:none;
    +	white-space:normal!important;
    +	width:150px;
    +}
    +
    +.tp-caption.large_bold_grey,.large_bold_grey
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#666;
    +	font-family:"Open Sans";
    +	font-size:60px;
    +	font-weight:800;
    +	line-height:60px;
    +	margin:0;
    +	padding:1px 4px 0;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.medium_thin_grey,.medium_thin_grey
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#666;
    +	font-family:"Open Sans";
    +	font-size:34px;
    +	font-weight:300;
    +	line-height:30px;
    +	margin:0;
    +	padding:1px 4px 0;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.small_thin_grey,.small_thin_grey
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#757575;
    +	font-family:"Open Sans";
    +	font-size:18px;
    +	font-weight:300;
    +	line-height:26px;
    +	margin:0;
    +	padding:1px 4px 0;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.lightgrey_divider,.lightgrey_divider
    +{
    +	background-color:rgba(235,235,235,1);
    +	background-position:initial initial;
    +	background-repeat:initial initial;
    +	border-color:#222;
    +	border-style:none;
    +	border-width:0;
    +	height:3px;
    +	text-decoration:none;
    +	width:370px;
    +}
    +
    +.tp-caption.large_bold_darkblue,.large_bold_darkblue
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#34495e;
    +	font-family:"Open Sans";
    +	font-size:58px;
    +	font-weight:800;
    +	line-height:60px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.medium_bg_darkblue,.medium_bg_darkblue
    +{
    +	background-color:#34495e;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:20px;
    +	font-weight:800;
    +	line-height:20px;
    +	padding:10px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.medium_bold_red,.medium_bold_red
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#e33a0c;
    +	font-family:"Open Sans";
    +	font-size:24px;
    +	font-weight:800;
    +	line-height:30px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.medium_light_red,.medium_light_red
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#e33a0c;
    +	font-family:"Open Sans";
    +	font-size:21px;
    +	font-weight:300;
    +	line-height:26px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.medium_bg_red,.medium_bg_red
    +{
    +	background-color:#e33a0c;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:20px;
    +	font-weight:800;
    +	line-height:20px;
    +	padding:10px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.medium_bold_orange,.medium_bold_orange
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#f39c12;
    +	font-family:"Open Sans";
    +	font-size:24px;
    +	font-weight:800;
    +	line-height:30px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.medium_bg_orange,.medium_bg_orange
    +{
    +	background-color:#f39c12;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:20px;
    +	font-weight:800;
    +	line-height:20px;
    +	padding:10px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.grassfloor,.grassfloor
    +{
    +	background-color:rgba(160,179,151,1);
    +	border-color:#222;
    +	border-style:none;
    +	border-width:0;
    +	height:150px;
    +	text-decoration:none;
    +	width:4000px;
    +}
    +
    +.tp-caption.large_bold_white,.large_bold_white
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:58px;
    +	font-weight:800;
    +	line-height:60px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.medium_light_white,.medium_light_white
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:30px;
    +	font-weight:300;
    +	line-height:36px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.mediumlarge_light_white,.mediumlarge_light_white
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:34px;
    +	font-weight:300;
    +	line-height:40px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.mediumlarge_light_white_center,.mediumlarge_light_white_center
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:34px;
    +	font-weight:300;
    +	line-height:40px;
    +	padding:0;
    +	text-align:center;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.medium_bg_asbestos,.medium_bg_asbestos
    +{
    +	background-color:#7f8c8d;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:20px;
    +	font-weight:800;
    +	line-height:20px;
    +	padding:10px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.medium_light_black,.medium_light_black
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#000;
    +	font-family:"Open Sans";
    +	font-size:30px;
    +	font-weight:300;
    +	line-height:36px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.large_bold_black,.large_bold_black
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#000;
    +	font-family:"Open Sans";
    +	font-size:58px;
    +	font-weight:800;
    +	line-height:60px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.mediumlarge_light_darkblue,.mediumlarge_light_darkblue
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#34495e;
    +	font-family:"Open Sans";
    +	font-size:34px;
    +	font-weight:300;
    +	line-height:40px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.small_light_white,.small_light_white
    +{
    +	background-color:transparent;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:17px;
    +	font-weight:300;
    +	line-height:28px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.roundedimage,.roundedimage
    +{
    +	border-color:#222;
    +	border-style:none;
    +	border-width:0;
    +}
    +
    +.tp-caption.large_bg_black,.large_bg_black
    +{
    +	background-color:#000;
    +	border-color:#ffd658;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Open Sans";
    +	font-size:40px;
    +	font-weight:800;
    +	line-height:40px;
    +	padding:10px 20px 15px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.mediumwhitebg,.mediumwhitebg
    +{
    +	background-color:#fff;
    +	border-color:#000;
    +	border-style:none;
    +	border-width:0;
    +	color:#000;
    +	font-family:"Open Sans";
    +	font-size:30px;
    +	font-weight:300;
    +	line-height:30px;
    +	padding:5px 15px 10px;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.maincaption,.maincaption
    +{
    +	background-color:transparent;
    +	border-color:#000;
    +	border-style:none;
    +	border-width:0;
    +	color:#212a40;
    +	font-family:roboto;
    +	font-size:33px;
    +	font-weight:500;
    +	line-height:43px;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.miami_title_60px,.miami_title_60px
    +{
    +	background-color:transparent;
    +	border-color:#000;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Source Sans Pro";
    +	font-size:60px;
    +	font-weight:700;
    +	letter-spacing:1px;
    +	line-height:60px;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.miami_subtitle,.miami_subtitle
    +{
    +	background-color:transparent;
    +	border-color:#000;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,0.65);
    +	font-family:"Source Sans Pro";
    +	font-size:17px;
    +	font-weight:400;
    +	letter-spacing:2px;
    +	line-height:24px;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.divideline30px,.divideline30px
    +{
    +	background:#fff;
    +	background-color:#fff;
    +	border-color:#222;
    +	border-style:none;
    +	border-width:0;
    +	height:2px;
    +	min-width:30px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Miami_nostyle,.Miami_nostyle
    +{
    +	border-color:#222;
    +	border-style:none;
    +	border-width:0;
    +}
    +
    +.tp-caption.miami_content_light,.miami_content_light
    +{
    +	background-color:transparent;
    +	border-color:#000;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:"Source Sans Pro";
    +	font-size:22px;
    +	font-weight:400;
    +	letter-spacing:0;
    +	line-height:28px;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.miami_title_60px_dark,.miami_title_60px_dark
    +{
    +	background-color:transparent;
    +	border-color:#000;
    +	border-style:none;
    +	border-width:0;
    +	color:#333;
    +	font-family:"Source Sans Pro";
    +	font-size:60px;
    +	font-weight:700;
    +	letter-spacing:1px;
    +	line-height:60px;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.miami_content_dark,.miami_content_dark
    +{
    +	background-color:transparent;
    +	border-color:#000;
    +	border-style:none;
    +	border-width:0;
    +	color:#666;
    +	font-family:"Source Sans Pro";
    +	font-size:22px;
    +	font-weight:400;
    +	letter-spacing:0;
    +	line-height:28px;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.divideline30px_dark,.divideline30px_dark
    +{
    +	background-color:#333;
    +	border-color:#222;
    +	border-style:none;
    +	border-width:0;
    +	height:2px;
    +	min-width:30px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.ellipse70px,.ellipse70px
    +{
    +	background-color:rgba(0,0,0,0.14902);
    +	border-color:#222;
    +	border-radius:50px 50px 50px 50px;
    +	border-style:none;
    +	border-width:0;
    +	cursor:pointer;
    +	line-height:1px;
    +	min-height:70px;
    +	min-width:70px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.arrowicon,.arrowicon
    +{
    +	border-color:#222;
    +	border-style:none;
    +	border-width:0;
    +	line-height:1px;
    +}
    +
    +.tp-caption.MarkerDisplay,.MarkerDisplay
    +{
    +	background-color:transparent;
    +	border-color:#000;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	font-family:Permanent Marker;
    +	font-style:normal;
    +	padding:0;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.Restaurant-Display,.Restaurant-Display
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:Roboto;
    +	font-size:120px;
    +	font-style:normal;
    +	font-weight:700;
    +	line-height:120px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Restaurant-Cursive,.Restaurant-Cursive
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:Nothing you could do;
    +	font-size:30px;
    +	font-style:normal;
    +	font-weight:400;
    +	letter-spacing:2px;
    +	line-height:30px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Restaurant-ScrollDownText,.Restaurant-ScrollDownText
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:Roboto;
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:400;
    +	letter-spacing:2px;
    +	line-height:17px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Restaurant-Description,.Restaurant-Description
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:Roboto;
    +	font-size:20px;
    +	font-style:normal;
    +	font-weight:300;
    +	letter-spacing:3px;
    +	line-height:30px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Restaurant-Price,.Restaurant-Price
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:#fff;
    +	font-family:Roboto;
    +	font-size:30px;
    +	font-style:normal;
    +	font-weight:300;
    +	letter-spacing:3px;
    +	line-height:30px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Restaurant-Menuitem,.Restaurant-Menuitem
    +{
    +	background-color:rgba(0,0,0,1.00);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Roboto;
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:400;
    +	letter-spacing:2px;
    +	line-height:17px;
    +	padding:10px 30px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Furniture-LogoText,.Furniture-LogoText
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(230,207,163,1.00);
    +	font-family:Raleway;
    +	font-size:160px;
    +	font-style:normal;
    +	font-weight:300;
    +	line-height:150px;
    +	padding:0;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.Furniture-Plus,.Furniture-Plus
    +{
    +	background-color:rgba(255,255,255,1.00);
    +	border-color:transparent;
    +	border-radius:30px 30px 30px 30px;
    +	border-style:none;
    +	border-width:0;
    +	box-shadow:rgba(0,0,0,0.1) 0 1px 3px;
    +	color:rgba(230,207,163,1.00);
    +	font-family:Raleway;
    +	font-size:20px;
    +	font-style:normal;
    +	font-weight:400;
    +	line-height:20px;
    +	padding:6px 7px 4px;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.Furniture-Title,.Furniture-Title
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(0,0,0,1.00);
    +	font-family:Raleway;
    +	font-size:20px;
    +	font-style:normal;
    +	font-weight:700;
    +	letter-spacing:3px;
    +	line-height:20px;
    +	padding:0;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.Furniture-Subtitle,.Furniture-Subtitle
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(0,0,0,1.00);
    +	font-family:Raleway;
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:300;
    +	line-height:20px;
    +	padding:0;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.Gym-Display,.Gym-Display
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:80px;
    +	font-style:normal;
    +	font-weight:900;
    +	line-height:70px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Gym-Subline,.Gym-Subline
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:30px;
    +	font-style:normal;
    +	font-weight:100;
    +	letter-spacing:5px;
    +	line-height:30px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Gym-SmallText,.Gym-SmallText
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:300;
    +	line-height:22;
    +	padding:0;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.Fashion-SmallText,.Fashion-SmallText
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:12px;
    +	font-style:normal;
    +	font-weight:600;
    +	letter-spacing:2px;
    +	line-height:20px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Fashion-BigDisplay,.Fashion-BigDisplay
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(0,0,0,1.00);
    +	font-family:Raleway;
    +	font-size:60px;
    +	font-style:normal;
    +	font-weight:900;
    +	letter-spacing:2px;
    +	line-height:60px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Fashion-TextBlock,.Fashion-TextBlock
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(0,0,0,1.00);
    +	font-family:Raleway;
    +	font-size:20px;
    +	font-style:normal;
    +	font-weight:400;
    +	letter-spacing:2px;
    +	line-height:40px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Sports-Display,.Sports-Display
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:130px;
    +	font-style:normal;
    +	font-weight:100;
    +	letter-spacing:13px;
    +	line-height:130px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Sports-DisplayFat,.Sports-DisplayFat
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:130px;
    +	font-style:normal;
    +	font-weight:900;
    +	line-height:130px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Sports-Subline,.Sports-Subline
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(0,0,0,1.00);
    +	font-family:Raleway;
    +	font-size:32px;
    +	font-style:normal;
    +	font-weight:400;
    +	letter-spacing:4px;
    +	line-height:32px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Instagram-Caption,.Instagram-Caption
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Roboto;
    +	font-size:20px;
    +	font-style:normal;
    +	font-weight:900;
    +	line-height:20px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.News-Title,.News-Title
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Roboto Slab;
    +	font-size:70px;
    +	font-style:normal;
    +	font-weight:400;
    +	line-height:60px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.News-Subtitle,.News-Subtitle
    +{
    +	background-color:rgba(255,255,255,0);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Roboto Slab;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:300;
    +	line-height:24px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.News-Subtitle:hover,.News-Subtitle:hover
    +{
    +	background-color:rgba(255,255,255,0);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:0;
    +	color:rgba(255,255,255,0.65);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Photography-Display,.Photography-Display
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:80px;
    +	font-style:normal;
    +	font-weight:100;
    +	letter-spacing:5px;
    +	line-height:70px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Photography-Subline,.Photography-Subline
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(119,119,119,1.00);
    +	font-family:Raleway;
    +	font-size:20px;
    +	font-style:normal;
    +	font-weight:300;
    +	letter-spacing:3px;
    +	line-height:30px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Photography-ImageHover,.Photography-ImageHover
    +{
    +	background-color:transparent;
    +	border-color:rgba(255,255,255,0);
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-size:20px;
    +	font-style:normal;
    +	font-weight:400;
    +	line-height:22;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Photography-ImageHover:hover,.Photography-ImageHover:hover
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Photography-Menuitem,.Photography-Menuitem
    +{
    +	background-color:rgba(0,0,0,0.65);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:20px;
    +	font-style:normal;
    +	font-weight:300;
    +	letter-spacing:2px;
    +	line-height:20px;
    +	padding:3px 5px 3px 8px;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Photography-Menuitem:hover,.Photography-Menuitem:hover
    +{
    +	background-color:rgba(0,255,222,0.65);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Photography-Textblock,.Photography-Textblock
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:300;
    +	letter-spacing:2px;
    +	line-height:30px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Photography-Subline-2,.Photography-Subline-2
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,0.35);
    +	font-family:Raleway;
    +	font-size:20px;
    +	font-style:normal;
    +	font-weight:300;
    +	letter-spacing:3px;
    +	line-height:30px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Photography-ImageHover2,.Photography-ImageHover2
    +{
    +	background-color:transparent;
    +	border-color:rgba(255,255,255,0);
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Arial;
    +	font-size:20px;
    +	font-style:normal;
    +	font-weight:400;
    +	line-height:22;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Photography-ImageHover2:hover,.Photography-ImageHover2:hover
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.WebProduct-Title,.WebProduct-Title
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(51,51,51,1.00);
    +	font-family:Raleway;
    +	font-size:90px;
    +	font-style:normal;
    +	font-weight:100;
    +	line-height:90px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.WebProduct-SubTitle,.WebProduct-SubTitle
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(153,153,153,1.00);
    +	font-family:Raleway;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:400;
    +	line-height:20px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.WebProduct-Content,.WebProduct-Content
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(153,153,153,1.00);
    +	font-family:Raleway;
    +	font-size:16px;
    +	font-style:normal;
    +	font-weight:600;
    +	line-height:24px;
    +	padding:0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.WebProduct-Menuitem,.WebProduct-Menuitem
    +{
    +	background-color:rgba(51,51,51,1.00);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:500;
    +	letter-spacing:2px;
    +	line-height:20px;
    +	padding:3px 5px 3px 8px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.WebProduct-Menuitem:hover,.WebProduct-Menuitem:hover
    +{
    +	background-color:rgba(255,255,255,1.00);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(153,153,153,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.WebProduct-Title-Light,.WebProduct-Title-Light
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:90px;
    +	font-style:normal;
    +	font-weight:100;
    +	line-height:90px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.WebProduct-SubTitle-Light,.WebProduct-SubTitle-Light
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,0.35);
    +	font-family:Raleway;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:400;
    +	line-height:20px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.WebProduct-Content-Light,.WebProduct-Content-Light
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,0.65);
    +	font-family:Raleway;
    +	font-size:16px;
    +	font-style:normal;
    +	font-weight:600;
    +	line-height:24px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.FatRounded,.FatRounded
    +{
    +	background-color:rgba(0,0,0,0.50);
    +	border-color:rgba(211,211,211,1.00);
    +	border-radius:50px 50px 50px 50px;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:30px;
    +	font-style:normal;
    +	font-weight:900;
    +	line-height:30px;
    +	padding:20px 22px 20px 25px;
    +	text-align:left;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.FatRounded:hover,.FatRounded:hover
    +{
    +	background-color:rgba(0,0,0,1.00);
    +	border-color:rgba(211,211,211,1.00);
    +	border-radius:50px 50px 50px 50px;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.NotGeneric-Title,.NotGeneric-Title
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:70px;
    +	font-style:normal;
    +	font-weight:800;
    +	line-height:70px;
    +	padding:10px 0;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.NotGeneric-SubTitle,.NotGeneric-SubTitle
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:13px;
    +	font-style:normal;
    +	font-weight:500;
    +	letter-spacing:4px;
    +	line-height:20px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.NotGeneric-CallToAction,.NotGeneric-CallToAction
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,0.50);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:14px;
    +	font-style:normal;
    +	font-weight:500;
    +	letter-spacing:3px;
    +	line-height:14px;
    +	padding:10px 30px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.NotGeneric-CallToAction:hover,.NotGeneric-CallToAction:hover
    +{
    +	background-color:transparent;
    +	border-color:rgba(255,255,255,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.NotGeneric-Icon,.NotGeneric-Icon
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,0);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:30px;
    +	font-style:normal;
    +	font-weight:400;
    +	letter-spacing:3px;
    +	line-height:30px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.NotGeneric-Menuitem,.NotGeneric-Menuitem
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,0.15);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:14px;
    +	font-style:normal;
    +	font-weight:500;
    +	letter-spacing:3px;
    +	line-height:14px;
    +	padding:27px 30px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.NotGeneric-Menuitem:hover,.NotGeneric-Menuitem:hover
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.MarkerStyle,.MarkerStyle
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:"Permanent Marker";
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:100;
    +	line-height:30px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Gym-Menuitem,.Gym-Menuitem
    +{
    +	background-color:rgba(0,0,0,1.00);
    +	border-color:rgba(255,255,255,0);
    +	border-radius:3px 3px 3px 3px;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:20px;
    +	font-style:normal;
    +	font-weight:300;
    +	letter-spacing:2px;
    +	line-height:20px;
    +	padding:3px 5px 3px 8px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Gym-Menuitem:hover,.Gym-Menuitem:hover
    +{
    +	background-color:rgba(0,0,0,1.00);
    +	border-color:rgba(255,255,255,0.25);
    +	border-radius:3px 3px 3px 3px;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Newspaper-Button,.Newspaper-Button
    +{
    +	background-color:rgba(255,255,255,0);
    +	border-color:rgba(255,255,255,0.25);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Roboto;
    +	font-size:13px;
    +	font-style:normal;
    +	font-weight:700;
    +	letter-spacing:2px;
    +	line-height:17px;
    +	padding:12px 35px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Newspaper-Button:hover,.Newspaper-Button:hover
    +{
    +	background-color:rgba(255,255,255,1.00);
    +	border-color:rgba(255,255,255,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(0,0,0,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Newspaper-Subtitle,.Newspaper-Subtitle
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(168,216,238,1.00);
    +	font-family:Roboto;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:900;
    +	line-height:20px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Newspaper-Title,.Newspaper-Title
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:"Roboto Slab";
    +	font-size:50px;
    +	font-style:normal;
    +	font-weight:400;
    +	line-height:55px;
    +	padding:0 0 10px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Newspaper-Title-Centered,.Newspaper-Title-Centered
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:"Roboto Slab";
    +	font-size:50px;
    +	font-style:normal;
    +	font-weight:400;
    +	line-height:55px;
    +	padding:0 0 10px;
    +	text-align:center;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Hero-Button,.Hero-Button
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,0.50);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:14px;
    +	font-style:normal;
    +	font-weight:500;
    +	letter-spacing:3px;
    +	line-height:14px;
    +	padding:10px 30px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Hero-Button:hover,.Hero-Button:hover
    +{
    +	background-color:rgba(255,255,255,1.00);
    +	border-color:rgba(255,255,255,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(0,0,0,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Video-Title,.Video-Title
    +{
    +	background-color:rgba(0,0,0,1.00);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:30px;
    +	font-style:normal;
    +	font-weight:900;
    +	line-height:30px;
    +	padding:5px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Video-SubTitle,.Video-SubTitle
    +{
    +	background-color:rgba(0,0,0,0.35);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:12px;
    +	font-style:normal;
    +	font-weight:600;
    +	letter-spacing:2px;
    +	line-height:12px;
    +	padding:5px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.NotGeneric-Button,.NotGeneric-Button
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,0.50);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:14px;
    +	font-style:normal;
    +	font-weight:500;
    +	letter-spacing:3px;
    +	line-height:14px;
    +	padding:10px 30px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.NotGeneric-Button:hover,.NotGeneric-Button:hover
    +{
    +	background-color:transparent;
    +	border-color:rgba(255,255,255,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.NotGeneric-BigButton,.NotGeneric-BigButton
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,0.15);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:14px;
    +	font-style:normal;
    +	font-weight:500;
    +	letter-spacing:3px;
    +	line-height:14px;
    +	padding:27px 30px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.NotGeneric-BigButton:hover,.NotGeneric-BigButton:hover
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.WebProduct-Button,.WebProduct-Button
    +{
    +	background-color:rgba(51,51,51,1.00);
    +	border-color:rgba(0,0,0,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:16px;
    +	font-style:normal;
    +	font-weight:600;
    +	letter-spacing:1px;
    +	line-height:48px;
    +	padding:0 40px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.WebProduct-Button:hover,.WebProduct-Button:hover
    +{
    +	background-color:rgba(255,255,255,1.00);
    +	border-color:rgba(0,0,0,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:2px;
    +	color:rgba(51,51,51,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Restaurant-Button,.Restaurant-Button
    +{
    +	background-color:rgba(10,10,10,0);
    +	border-color:rgba(255,255,255,0.50);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Roboto;
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:500;
    +	letter-spacing:3px;
    +	line-height:17px;
    +	padding:12px 35px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Restaurant-Button:hover,.Restaurant-Button:hover
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,224,129,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Gym-Button,.Gym-Button
    +{
    +	background-color:rgba(139,192,39,1.00);
    +	border-color:rgba(0,0,0,0);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:600;
    +	letter-spacing:1px;
    +	line-height:15px;
    +	padding:13px 35px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Gym-Button:hover,.Gym-Button:hover
    +{
    +	background-color:rgba(114,168,0,1.00);
    +	border-color:rgba(0,0,0,0);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Gym-Button-Light,.Gym-Button-Light
    +{
    +	background-color:transparent;
    +	border-color:rgba(255,255,255,0.25);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:600;
    +	line-height:15px;
    +	padding:12px 35px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Gym-Button-Light:hover,.Gym-Button-Light:hover
    +{
    +	background-color:rgba(114,168,0,0);
    +	border-color:rgba(139,192,39,1.00);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Sports-Button-Light,.Sports-Button-Light
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,0.50);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:600;
    +	letter-spacing:2px;
    +	line-height:17px;
    +	padding:12px 35px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Sports-Button-Light:hover,.Sports-Button-Light:hover
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Sports-Button-Red,.Sports-Button-Red
    +{
    +	background-color:rgba(219,28,34,1.00);
    +	border-color:rgba(219,28,34,0);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:600;
    +	letter-spacing:2px;
    +	line-height:17px;
    +	padding:12px 35px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Sports-Button-Red:hover,.Sports-Button-Red:hover
    +{
    +	background-color:rgba(0,0,0,1.00);
    +	border-color:rgba(0,0,0,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Photography-Button,.Photography-Button
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,0.25);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Raleway;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:600;
    +	letter-spacing:1px;
    +	line-height:15px;
    +	padding:13px 35px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Photography-Button:hover,.Photography-Button:hover
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,1.00);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:1px;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Newspaper-Button-2,.Newspaper-Button-2
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,0.50);
    +	border-radius:3px 3px 3px 3px;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Roboto;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:900;
    +	line-height:15px;
    +	padding:10px 30px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Newspaper-Button-2:hover,.Newspaper-Button-2:hover
    +{
    +	background-color:rgba(0,0,0,0);
    +	border-color:rgba(255,255,255,1.00);
    +	border-radius:3px 3px 3px 3px;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Feature-Tour,.Feature-Tour
    +{
    +	background-color:rgba(139,192,39,1.00);
    +	border-color:rgba(0,0,0,0);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Roboto;
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:700;
    +	line-height:17px;
    +	padding:17px 35px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Feature-Tour:hover,.Feature-Tour:hover
    +{
    +	background-color:rgba(114,168,0,1.00);
    +	border-color:rgba(0,0,0,0);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Feature-Examples,.Feature-Examples
    +{
    +	background-color:transparent;
    +	border-color:rgba(33,42,64,0.15);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(33,42,64,0.50);
    +	font-family:Roboto;
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:700;
    +	line-height:17px;
    +	padding:15px 35px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Feature-Examples:hover,.Feature-Examples:hover
    +{
    +	background-color:transparent;
    +	border-color:rgba(139,192,39,1.00);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(139,192,39,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.subcaption,.subcaption
    +{
    +	background-color:transparent;
    +	border-color:rgba(0,0,0,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(111,124,130,1.00);
    +	font-family:roboto;
    +	font-size:19px;
    +	font-style:normal;
    +	font-weight:400;
    +	line-height:24px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.menutab,.menutab
    +{
    +	background-color:transparent;
    +	border-color:rgba(0,0,0,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(41,46,49,1.00);
    +	font-family:roboto;
    +	font-size:25px;
    +	font-style:normal;
    +	font-weight:300;
    +	line-height:30px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.menutab:hover,.menutab:hover
    +{
    +	background-color:transparent;
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(213,0,0,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.maincontent,.maincontent
    +{
    +	background-color:transparent;
    +	border-color:rgba(0,0,0,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(41,46,49,1.00);
    +	font-family:roboto;
    +	font-size:21px;
    +	font-style:normal;
    +	font-weight:300;
    +	line-height:26px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.minitext,.minitext
    +{
    +	background-color:transparent;
    +	border-color:rgba(0,0,0,1.00);
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(185,186,187,1.00);
    +	font-family:roboto;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:400;
    +	line-height:20px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +	text-shadow:none;
    +}
    +
    +.tp-caption.Feature-Buy,.Feature-Buy
    +{
    +	background-color:rgba(0,154,238,1.00);
    +	border-color:rgba(0,0,0,0);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Roboto;
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:700;
    +	line-height:17px;
    +	padding:17px 35px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Feature-Buy:hover,.Feature-Buy:hover
    +{
    +	background-color:rgba(0,133,214,1.00);
    +	border-color:rgba(0,0,0,0);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Feature-Examples-Light,.Feature-Examples-Light
    +{
    +	background-color:transparent;
    +	border-color:rgba(255,255,255,0.15);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Roboto;
    +	font-size:17px;
    +	font-style:normal;
    +	font-weight:700;
    +	line-height:17px;
    +	padding:15px 35px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Feature-Examples-Light:hover,.Feature-Examples-Light:hover
    +{
    +	background-color:transparent;
    +	border-color:rgba(255,255,255,1.00);
    +	border-radius:30px 30px 30px 30px;
    +	border-style:solid;
    +	border-width:2px;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Facebook-Likes,.Facebook-Likes
    +{
    +	background-color:rgba(59,89,153,1.00);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	font-family:Roboto;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:500;
    +	line-height:22px;
    +	padding:5px 15px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Twitter-Favorites,.Twitter-Favorites
    +{
    +	background-color:rgba(255,255,255,0);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(136,153,166,1.00);
    +	font-family:Roboto;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:500;
    +	line-height:22px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Twitter-Link,.Twitter-Link
    +{
    +	background-color:rgba(255,255,255,1.00);
    +	border-color:transparent;
    +	border-radius:30px 30px 30px 30px;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(135,153,165,1.00);
    +	font-family:Roboto;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:500;
    +	line-height:15px;
    +	padding:11px 11px 9px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Twitter-Link:hover,.Twitter-Link:hover
    +{
    +	background-color:rgba(0,132,180,1.00);
    +	border-color:transparent;
    +	border-radius:30px 30px 30px 30px;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(255,255,255,1.00);
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Twitter-Retweet,.Twitter-Retweet
    +{
    +	background-color:rgba(255,255,255,0);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(136,153,166,1.00);
    +	font-family:Roboto;
    +	font-size:15px;
    +	font-style:normal;
    +	font-weight:500;
    +	line-height:22px;
    +	padding:0;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.tp-caption.Twitter-Content,.Twitter-Content
    +{
    +	background-color:rgba(255,255,255,1.00);
    +	border-color:transparent;
    +	border-radius:0 0 0 0;
    +	border-style:none;
    +	border-width:0;
    +	color:rgba(41,47,51,1.00);
    +	font-family:Roboto;
    +	font-size:20px;
    +	font-style:normal;
    +	font-weight:500;
    +	line-height:28px;
    +	padding:30px 30px 70px;
    +	text-align:left;
    +	text-decoration:none;
    +}
    +
    +.revtp-searchform input[type="text"],
    +.revtp-searchform input[type="email"],
    +.revtp-form input[type="text"],
    +.revtp-form input[type="email"]{
    +	font-family: "Arial", sans-serif;
    +    font-size: 15px;
    +    color: #000;
    +    background-color: #fff;
    +    line-height: 46px;
    +    padding: 0 20px;
    +    cursor: text;
    +    border: 0;
    +    width: 400px;
    +    margin-bottom: 0px;
    +    -webkit-transition: background-color 0.5s;
    +    -moz-transition: background-color 0.5s;
    +    -o-transition: background-color 0.5s;
    +    -ms-transition: background-color 0.5s;
    +    transition: background-color 0.5s;
    +    -webkit-border-radius: 0px;
    +    -moz-border-radius: 0px;
    +    border-radius: 0px;
    +}
    +
    +
    +.tp-caption.BigBold-Title,
    +.BigBold-Title {
    +    color: rgba(255, 255, 255, 1.00);
    +    font-size: 110px;
    +    line-height: 100px;
    +    font-weight: 800;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 10px 0px 10px 0;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.BigBold-SubTitle,
    +.BigBold-SubTitle {
    +    color: rgba(255, 255, 255, 0.50);
    +    font-size: 15px;
    +    line-height: 24px;
    +    font-weight: 500;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 0 0 0 0px;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left;
    +    letter-spacing: 1px
    +}
    +.tp-caption.BigBold-Button,
    +.BigBold-Button {
    +    color: rgba(255, 255, 255, 1.00);
    +    font-size: 13px;
    +    line-height: 13px;
    +    font-weight: 500;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 15px 50px 15px 50px;
    +    text-decoration: none;
    +    background-color: rgba(0, 0, 0, 0);
    +    border-color: rgba(255, 255, 255, 0.50);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 0px 0px 0px 0px;
    +    text-align: left;
    +    letter-spacing: 1px
    +}
    +.tp-caption.BigBold-Button:hover,
    +.BigBold-Button:hover {
    +    color: rgba(255, 255, 255, 1.00);
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: rgba(255, 255, 255, 1.00);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 0px 0px 0px 0px
    +}
    +.tp-caption.FoodCarousel-Content,
    +.FoodCarousel-Content {
    +    color: rgba(41, 46, 49, 1.00);
    +    font-size: 17px;
    +    line-height: 28px;
    +    font-weight: 500;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 30px 30px 30px 30px;
    +    text-decoration: none;
    +    background-color: rgba(255, 255, 255, 1.00);
    +    border-color: rgba(41, 46, 49, 1.00);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.FoodCarousel-Button,
    +.FoodCarousel-Button {
    +    color: rgba(41, 46, 49, 1.00);
    +    font-size: 13px;
    +    line-height: 13px;
    +    font-weight: 700;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 15px 70px 15px 50px;
    +    text-decoration: none;
    +    background-color: rgba(255, 255, 255, 1.00);
    +    border-color: rgba(41, 46, 49, 1.00);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 0px 0px 0px 0px;
    +    text-align: left;
    +    letter-spacing: 1px
    +}
    +.tp-caption.FoodCarousel-Button:hover,
    +.FoodCarousel-Button:hover {
    +    color: rgba(255, 255, 255, 1.00);
    +    text-decoration: none;
    +    background-color: rgba(41, 46, 49, 1.00);
    +    border-color: rgba(41, 46, 49, 1.00);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 0px 0px 0px 0px
    +}
    +.tp-caption.FoodCarousel-CloseButton,
    +.FoodCarousel-CloseButton {
    +    color: rgba(41, 46, 49, 1.00);
    +    font-size: 20px;
    +    line-height: 20px;
    +    font-weight: 700;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 14px 14px 14px 16px;
    +    text-decoration: none;
    +    background-color: rgba(0, 0, 0, 0);
    +    border-color: rgba(41, 46, 49, 0);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 30px 30px 30px 30px;
    +    text-align: left;
    +    letter-spacing: 1px
    +}
    +.tp-caption.FoodCarousel-CloseButton:hover,
    +.FoodCarousel-CloseButton:hover {
    +    color: rgba(255, 255, 255, 1.00);
    +    text-decoration: none;
    +    background-color: rgba(41, 46, 49, 1.00);
    +    border-color: rgba(41, 46, 49, 0);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 30px 30px 30px 30px
    +}
    +.tp-caption.Video-SubTitle,
    +.Video-SubTitle {
    +    color: rgba(255, 255, 255, 1.00);
    +    font-size: 12px;
    +    line-height: 12px;
    +    font-weight: 600;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 5px 5px 5px 5px;
    +    text-decoration: none;
    +    background-color: rgba(0, 0, 0, 0.35);
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    letter-spacing: 2px;
    +    text-align: left
    +}
    +.tp-caption.Video-Title,
    +.Video-Title {
    +    color: rgba(255, 255, 255, 1.00);
    +    font-size: 30px;
    +    line-height: 30px;
    +    font-weight: 900;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 5px 5px 5px 5px;
    +    text-decoration: none;
    +    background-color: rgba(0, 0, 0, 1.00);
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.Travel-BigCaption,
    +.Travel-BigCaption {
    +    color: rgba(255, 255, 255, 1.00);
    +    font-size: 50px;
    +    line-height: 50px;
    +    font-weight: 400;
    +    font-style: normal;
    +    font-family: Roboto;
    +    padding: 0 0 0 0px;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.Travel-SmallCaption,
    +.Travel-SmallCaption {
    +    color: rgba(255, 255, 255, 1.00);
    +    font-size: 25px;
    +    line-height: 30px;
    +    font-weight: 300;
    +    font-style: normal;
    +    font-family: Roboto;
    +    padding: 0 0 0 0px;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.Travel-CallToAction,
    +.Travel-CallToAction {
    +    color: rgba(255, 255, 255, 1.00);
    +    font-size: 25px;
    +    line-height: 25px;
    +    font-weight: 500;
    +    font-style: normal;
    +    font-family: Roboto;
    +    padding: 12px 20px 12px 20px;
    +    text-decoration: none;
    +    background-color: rgba(255, 255, 255, 0.05);
    +    border-color: rgba(255, 255, 255, 1.00);
    +    border-style: solid;
    +    border-width: 2px;
    +    border-radius: 5px 5px 5px 5px;
    +    text-align: left;
    +    letter-spacing: 1px
    +}
    +.tp-caption.Travel-CallToAction:hover,
    +.Travel-CallToAction:hover {
    +    color: rgba(255, 255, 255, 1.00);
    +    text-decoration: none;
    +    background-color: rgba(255, 255, 255, 0.15);
    +    border-color: rgba(255, 255, 255, 1.00);
    +    border-style: solid;
    +    border-width: 2px;
    +    border-radius: 5px 5px 5px 5px
    +}
    +
    +
    +.tp-caption.RotatingWords-TitleWhite,
    +.RotatingWords-TitleWhite {
    +    color: rgba(255, 255, 255, 1.00);
    +    font-size: 70px;
    +    line-height: 70px;
    +    font-weight: 800;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 0px 0px 0px 0;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.RotatingWords-Button,
    +.RotatingWords-Button {
    +    color: rgba(255, 255, 255, 1.00);
    +    font-size: 20px;
    +    line-height: 20px;
    +    font-weight: 700;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 20px 50px 20px 50px;
    +    text-decoration: none;
    +    background-color: rgba(0, 0, 0, 0);
    +    border-color: rgba(255, 255, 255, 0.15);
    +    border-style: solid;
    +    border-width: 2px;
    +    border-radius: 0px 0px 0px 0px;
    +    text-align: left;
    +    letter-spacing: 3px
    +}
    +.tp-caption.RotatingWords-Button:hover,
    +.RotatingWords-Button:hover {
    +    color: rgba(255, 255, 255, 1.00);
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: rgba(255, 255, 255, 1.00);
    +    border-style: solid;
    +    border-width: 2px;
    +    border-radius: 0px 0px 0px 0px
    +}
    +.tp-caption.RotatingWords-SmallText,
    +.RotatingWords-SmallText {
    +    color: rgba(255, 255, 255, 1.00);
    +    font-size: 14px;
    +    line-height: 20px;
    +    font-weight: 400;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 0 0 0 0px;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left;
    +    text-shadow: none
    +}
    +
    +
    +
    +
    +.tp-caption.ContentZoom-SmallTitle,
    +.ContentZoom-SmallTitle {
    +    color: rgba(41, 46, 49, 1.00);
    +    font-size: 33px;
    +    line-height: 45px;
    +    font-weight: 600;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 0 0 0 0px;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.ContentZoom-SmallSubtitle,
    +.ContentZoom-SmallSubtitle {
    +    color: rgba(111, 124, 130, 1.00);
    +    font-size: 16px;
    +    line-height: 24px;
    +    font-weight: 600;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 0 0 0 0px;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.ContentZoom-SmallIcon,
    +.ContentZoom-SmallIcon {
    +    color: rgba(41, 46, 49, 1.00);
    +    font-size: 20px;
    +    line-height: 20px;
    +    font-weight: 400;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 10px 10px 10px 10px;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.ContentZoom-SmallIcon:hover,
    +.ContentZoom-SmallIcon:hover {
    +    color: rgba(111, 124, 130, 1.00);
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px
    +}
    +.tp-caption.ContentZoom-DetailTitle,
    +.ContentZoom-DetailTitle {
    +    color: rgba(41, 46, 49, 1.00);
    +    font-size: 70px;
    +    line-height: 70px;
    +    font-weight: 500;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 0 0 0 0px;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.ContentZoom-DetailSubTitle,
    +.ContentZoom-DetailSubTitle {
    +    color: rgba(111, 124, 130, 1.00);
    +    font-size: 25px;
    +    line-height: 25px;
    +    font-weight: 500;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 0 0 0 0px;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.ContentZoom-DetailContent,
    +.ContentZoom-DetailContent {
    +    color: rgba(111, 124, 130, 1.00);
    +    font-size: 17px;
    +    line-height: 28px;
    +    font-weight: 500;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 0 0 0 0px;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.ContentZoom-Button,
    +.ContentZoom-Button {
    +    color: rgba(41, 46, 49, 1.00);
    +    font-size: 13px;
    +    line-height: 13px;
    +    font-weight: 700;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 15px 50px 15px 50px;
    +    text-decoration: none;
    +    background-color: rgba(0, 0, 0, 0);
    +    border-color: rgba(41, 46, 49, 0.50);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 0px 0px 0px 0px;
    +    text-align: left;
    +    letter-spacing: 1px
    +}
    +.tp-caption.ContentZoom-Button:hover,
    +.ContentZoom-Button:hover {
    +    color: rgba(255, 255, 255, 1.00);
    +    text-decoration: none;
    +    background-color: rgba(41, 46, 49, 1.00);
    +    border-color: rgba(41, 46, 49, 1.00);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 0px 0px 0px 0px
    +}
    +.tp-caption.ContentZoom-ButtonClose,
    +.ContentZoom-ButtonClose {
    +    color: rgba(41, 46, 49, 1.00);
    +    font-size: 13px;
    +    line-height: 13px;
    +    font-weight: 700;
    +    font-style: normal;
    +    font-family: Raleway;
    +    padding: 14px 14px 14px 16px;
    +    text-decoration: none;
    +    background-color: rgba(0, 0, 0, 0);
    +    border-color: rgba(41, 46, 49, 0.50);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 30px 30px 30px 30px;
    +    text-align: left;
    +    letter-spacing: 1px
    +}
    +.tp-caption.ContentZoom-ButtonClose:hover,
    +.ContentZoom-ButtonClose:hover {
    +    color: rgba(255, 255, 255, 1.00);
    +    text-decoration: none;
    +    background-color: rgba(41, 46, 49, 1.00);
    +    border-color: rgba(41, 46, 49, 1.00);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 30px 30px 30px 30px
    +}
    +.tp-caption.Newspaper-Title,
    +.Newspaper-Title {
    +    color: rgba(255, 255, 255, 1.00);
    +    font-size: 50px;
    +    line-height: 55px;
    +    font-weight: 400;
    +    font-style: normal;
    +    font-family: "Roboto Slab";
    +    padding: 0 0 10px 0;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.Newspaper-Subtitle,
    +.Newspaper-Subtitle {
    +    color: rgba(168, 216, 238, 1.00);
    +    font-size: 15px;
    +    line-height: 20px;
    +    font-weight: 900;
    +    font-style: normal;
    +    font-family: Roboto;
    +    padding: 0 0 0 0px;
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-color: transparent;
    +    border-style: none;
    +    border-width: 0px;
    +    border-radius: 0 0 0 0px;
    +    text-align: left
    +}
    +.tp-caption.Newspaper-Button,
    +.Newspaper-Button {
    +    color: rgba(255, 255, 255, 1.00);
    +    font-size: 13px;
    +    line-height: 17px;
    +    font-weight: 700;
    +    font-style: normal;
    +    font-family: Roboto;
    +    padding: 12px 35px 12px 35px;
    +    text-decoration: none;
    +    background-color: rgba(255, 255, 255, 0);
    +    border-color: rgba(255, 255, 255, 0.25);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 0px 0px 0px 0px;
    +    letter-spacing: 2px;
    +    text-align: left
    +}
    +.tp-caption.Newspaper-Button:hover,
    +.Newspaper-Button:hover {
    +    color: rgba(0, 0, 0, 1.00);
    +    text-decoration: none;
    +    background-color: rgba(255, 255, 255, 1.00);
    +    border-color: rgba(255, 255, 255, 1.00);
    +    border-style: solid;
    +    border-width: 1px;
    +    border-radius: 0px 0px 0px 0px
    +}
    +.tp-caption.rtwhitemedium,
    +.rtwhitemedium {
    +    font-size: 22px;
    +    line-height: 26px;
    +    color: rgb(255, 255, 255);
    +    text-decoration: none;
    +    background-color: transparent;
    +    border-width: 0px;
    +    border-color: rgb(0, 0, 0);
    +    border-style: none;
    +    text-shadow: none
    +}
    +
    +@media only screen and (max-width: 767px) {
    +	.revtp-searchform input[type="text"],
    +	.revtp-searchform input[type="email"],
    +	.revtp-form input[type="text"],
    +	.revtp-form input[type="email"] { width: 200px !important; }
    +}
    +
    +.revtp-searchform input[type="submit"],
    +.revtp-form input[type="submit"] {
    +	font-family: "Arial", sans-serif;
    +    line-height: 46px;
    +    letter-spacing: 1px;
    +    text-transform: uppercase;
    +    font-size: 15px;
    +    font-weight: 700;
    +    padding: 0 20px;
    +    border: 0;
    +    background: #009aee;
    +    color: #fff;
    +    -webkit-border-radius: 0px;
    +    -moz-border-radius: 0px;
    +    border-radius: 0px;
    +}
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + ARES SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +.ares.tparrows {
    +  cursor:pointer;
    +  background:#fff;
    +  min-width:60px;
    +    min-height:60px;
    +  position:absolute;
    +  display:block;
    +  z-index:100;
    +    border-radius:50%;
    +}
    +.ares.tparrows:hover {
    +}
    +.ares.tparrows:before {
    +  font-family: "revicons";
    +  font-size:25px;
    +  color:#aaa;
    +  display:block;
    +  line-height: 60px;
    +  text-align: center;
    +    -webkit-transition: color 0.3s;
    +    -moz-transition: color 0.3s;
    +    transition: color 0.3s;
    +    z-index:2;
    +    position:relative;
    +}
    +.ares.tparrows.tp-leftarrow:before {
    +  content: "\e81f";
    +}
    +.ares.tparrows.tp-rightarrow:before {
    +  content: "\e81e";
    +}
    +.ares.tparrows:hover:before {
    + color:#000;
    +      }
    +.ares .tp-title-wrap {
    +  position:absolute;
    +  z-index:1;
    +  display:inline-block;
    +  background:#fff;
    +  min-height:60px;
    +  line-height:60px;
    +  top:0px;
    +  margin-left:30px;
    +  border-radius:0px 30px 30px 0px;
    +  overflow:hidden;
    +  -webkit-transition: -webkit-transform 0.3s;
    +  transition: transform 0.3s;
    +  transform:scaleX(0);
    +  -webkit-transform:scaleX(0);
    +  transform-origin:0% 50%;
    +   -webkit-transform-origin:0% 50%;
    +}
    + .ares.tp-rightarrow .tp-title-wrap {
    +   right:0px;
    +   margin-right:30px;margin-left:0px;
    +   -webkit-transform-origin:100% 50%;
    +border-radius:30px 0px 0px 30px;
    + }
    +.ares.tparrows:hover .tp-title-wrap {
    +  transform:scaleX(1) scaleY(1);
    +    -webkit-transform:scaleX(1) scaleY(1);
    +}
    +.ares .tp-arr-titleholder {
    +  position:relative;
    +  -webkit-transition: -webkit-transform 0.3s;
    +  transition: transform 0.3s;
    +  transform:translateX(200px);
    +  text-transform:uppercase;
    +  color:#000;
    +  font-weight:400;
    +  font-size:14px;
    +  line-height:60px;
    +  white-space:nowrap;
    +  padding:0px 20px;
    +  margin-left:10px;
    +  opacity:0;
    +}
    +
    +.ares.tp-rightarrow .tp-arr-titleholder {
    +   transform:translateX(-200px);
    +   margin-left:0px; margin-right:10px;
    +      }
    +
    +.ares.tparrows:hover .tp-arr-titleholder {
    +   transform:translateX(0px);
    +   -webkit-transform:translateX(0px);
    +  transition-delay: 0.1s;
    +  opacity:1;
    +}
    +
    +/* BULLETS */
    +.ares.tp-bullets {
    +}
    +.ares.tp-bullets:before {
    +	content:" ";
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	background:transparent;
    +	padding:10px;
    +	margin-left:-10px;margin-top:-10px;
    +	box-sizing:content-box;
    +}
    +.ares .tp-bullet {
    +	width:13px;
    +	height:13px;
    +	position:absolute;
    +	background:#e5e5e5;
    +	border-radius:50%;
    +	cursor: pointer;
    +	box-sizing:content-box;
    +}
    +.ares .tp-bullet:hover,
    +.ares .tp-bullet.selected {
    +	background:#fff;
    +}
    +.ares .tp-bullet-title {
    +  position:absolute;
    +  color:#888;
    +  font-size:12px;
    +  padding:0px 10px;
    +  font-weight:600;
    +  right:27px;
    +  top:-4px;
    +  background:#fff;
    +  background:rgba(255,255,255,0.75);
    +  visibility:hidden;
    +  transform:translateX(-20px);
    +  -webkit-transform:translateX(-20px);
    +  transition:transform 0.3s;
    +  -webkit-transition:transform 0.3s;
    +  line-height:20px;
    +  white-space:nowrap;
    +}
    +
    +.ares .tp-bullet-title:after {
    +    width: 0px;
    +	height: 0px;
    +	border-style: solid;
    +	border-width: 10px 0 10px 10px;
    +	border-color: transparent transparent transparent rgba(255,255,255,0.75);
    +	content:" ";
    +    position:absolute;
    +    right:-10px;
    +	top:0px;
    +}
    +
    +.ares .tp-bullet:hover .tp-bullet-title{
    +  visibility:visible;
    +   transform:translateX(0px);
    +  -webkit-transform:translateX(0px);
    +}
    +
    +.ares .tp-bullet.selected:hover .tp-bullet-title {
    +    background:#fff;
    +        }
    +.ares .tp-bullet.selected:hover .tp-bullet-title:after {
    +  border-color:transparent transparent transparent #fff;
    +}
    +.ares.tp-bullets:hover .tp-bullet-title {
    +        visibility:hidden;
    +}
    +.ares.tp-bullets:hover .tp-bullet:hover .tp-bullet-title {
    +    visibility:visible;
    +      }
    +
    +/* TABS */
    +.ares .tp-tab {
    +  opacity:1;
    +  padding:10px;
    +  box-sizing:border-box;
    +  font-family: "Roboto", sans-serif;
    +  border-bottom: 1px solid #e5e5e5;
    + }
    +.ares .tp-tab-image
    +{
    +  width:60px;
    +  height:60px; max-height:100%; max-width:100%;
    +  position:relative;
    +  display:inline-block;
    +  float:left;
    +
    +}
    +.ares .tp-tab-content
    +{
    +    background:rgba(0,0,0,0);
    +    position:relative;
    +    padding:15px 15px 15px 85px;
    + left:0px;
    + overflow:hidden;
    + margin-top:-15px;
    +    box-sizing:border-box;
    +    color:#333;
    +    display: inline-block;
    +    width:100%;
    +    height:100%;
    + position:absolute; }
    +.ares .tp-tab-date
    +  {
    +  display:block;
    +  color: #aaa;
    +  font-weight:500;
    +  font-size:12px;
    +  margin-bottom:0px;
    +  }
    +.ares .tp-tab-title
    +{
    +    display:block;
    +    text-align:left;
    +    color:#333;
    +    font-size:14px;
    +    font-weight:500;
    +    text-transform:none;
    +    line-height:17px;
    +}
    +.ares .tp-tab:hover,
    +.ares .tp-tab.selected {
    +	background:#eee;
    +}
    +
    +.ares .tp-tab-mask {
    +}
    +
    +/* MEDIA QUERIES */
    +@media only screen and (max-width: 960px) {
    +
    +}
    +@media only screen and (max-width: 768px) {
    +
    +}
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + CUSTOM SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +.custom.tparrows {
    +	cursor:pointer;
    +	background:#000;
    +	background:rgba(0,0,0,0.5);
    +	width:40px;
    +	height:40px;
    +	position:absolute;
    +	display:block;
    +	z-index:100;
    +}
    +.custom.tparrows:hover {
    +	background:#000;
    +}
    +.custom.tparrows:before {
    +	font-family: "revicons";
    +	font-size:15px;
    +	color:#fff;
    +	display:block;
    +	line-height: 40px;
    +	text-align: center;
    +}
    +.custom.tparrows.tp-leftarrow:before {
    +	content: "\e824";
    +}
    +.custom.tparrows.tp-rightarrow:before {
    +	content: "\e825";
    +}
    +
    +
    +
    +/* BULLETS */
    +.custom.tp-bullets {
    +}
    +.custom.tp-bullets:before {
    +	content:" ";
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	background:transparent;
    +	padding:10px;
    +	margin-left:-10px;margin-top:-10px;
    +	box-sizing:content-box;
    +}
    +.custom .tp-bullet {
    +	width:12px;
    +	height:12px;
    +	position:absolute;
    +	background:#aaa;
    +    background:rgba(125,125,125,0.5);
    +	cursor: pointer;
    +	box-sizing:content-box;
    +}
    +.custom .tp-bullet:hover,
    +.custom .tp-bullet.selected {
    +	background:rgb(125,125,125);
    +}
    +.custom .tp-bullet-image {
    +}
    +.custom .tp-bullet-title {
    +}
    +
    +
    +/* THUMBS */
    +
    +
    +/* TABS */
    +
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + DIONE SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +.dione.tparrows {
    +  height:100%;
    +  width:100px;
    +  background:transparent;
    +  background:rgba(0,0,0,0);
    +  line-height:100%;
    +  transition:all 0.3s;
    +-webkit-transition:all 0.3s;
    +}
    +
    +.dione.tparrows:hover {
    + background:rgba(0,0,0,0.45);
    + }
    +.dione .tp-arr-imgwrapper {
    + width:100px;
    + left:0px;
    + position:absolute;
    + height:100%;
    + top:0px;
    + overflow:hidden;
    + }
    +.dione.tp-rightarrow .tp-arr-imgwrapper {
    +left:auto;
    +right:0px;
    +}
    +
    +.dione .tp-arr-imgholder {
    +background-position:center center;
    +background-size:cover;
    +width:100px;
    +height:100%;
    +top:0px;
    +visibility:hidden;
    +transform:translateX(-50px);
    +-webkit-transform:translateX(-50px);
    +transition:all 0.3s;
    +-webkit-transition:all 0.3s;
    +opacity:0;
    +left:0px;
    +}
    +
    +.dione.tparrows.tp-rightarrow .tp-arr-imgholder {
    +  right:0px;
    +  left:auto;
    +  transform:translateX(50px);
    + -webkit-transform:translateX(50px);
    +}
    +
    +.dione.tparrows:before {
    +position:absolute;
    +line-height:30px;
    +margin-left:-22px;
    +top:50%;
    +left:50%;
    +font-size:30px;
    +margin-top:-15px;
    +transition:all 0.3s;
    +-webkit-transition:all 0.3s;
    +}
    +
    +.dione.tparrows.tp-rightarrow:before {
    +margin-left:6px;
    +}
    +
    +.dione.tparrows:hover:before {
    +  transform:translateX(-20px);
    +-webkit-transform:translateX(-20px);
    +opacity:0;
    +}
    +
    +.dione.tparrows.tp-rightarrow:hover:before {
    +  transform:translateX(20px);
    +-webkit-transform:translateX(20px);
    +}
    +
    +.dione.tparrows:hover .tp-arr-imgholder {
    + transform:translateX(0px);
    +-webkit-transform:translateX(0px);
    +opacity:1;
    +visibility:visible;
    +}
    +
    +
    +
    +/* BULLETS */
    +.dione .tp-bullet {
    +    opacity:1;
    +    width:50px;
    +    height:50px;
    +    padding:3px;
    +    background:#000;
    +    background-color:rgba(0,0,0,0.25);
    +    margin:0px;
    +    box-sizing:border-box;
    +    transition:all 0.3s;
    +    -webkit-transition:all 0.3s;
    +
    +  }
    +
    +.dione .tp-bullet-image {
    +   display:block;
    +   box-sizing:border-box;
    +   position:relative;
    +    -webkit-box-shadow: inset 5px 5px 10px 0px rgba(0,0,0,0.25);
    +  -moz-box-shadow: inset 5px 5px 10px 0px rgba(0,0,0,0.25);
    +  box-shadow: inset 5px 5px 10px 0px rgba(0,0,0,0.25);
    +  width:44px;
    +  height:44px;
    +  background-size:cover;
    +  background-position:center center;
    + }
    +.dione .tp-bullet-title {
    +     position:absolute;
    +   bottom:65px;
    +     display:inline-block;
    +     left:50%;
    +     background:#000;
    +     background:rgba(0,0,0,0.75);
    +     color:#fff;
    +     padding:10px 30px;
    +     border-radius:4px;
    +   -webkit-border-radius:4px;
    +     opacity:0;
    +      transition:all 0.3s;
    +    -webkit-transition:all 0.3s;
    +    transform: translateZ(0.001px) translateX(-50%) translateY(14px);
    +    transform-origin:50% 100%;
    +    -webkit-transform: translateZ(0.001px) translateX(-50%) translateY(14px);
    +    -webkit-transform-origin:50% 100%;
    +    opacity:0;
    +    white-space:nowrap;
    + }
    +
    +.dione .tp-bullet:hover .tp-bullet-title {
    +     transform:rotateX(0deg) translateX(-50%);
    +    -webkit-transform:rotateX(0deg) translateX(-50%);
    +    opacity:1;
    +}
    +
    +.dione .tp-bullet.selected,
    +.dione .tp-bullet:hover  {
    +
    +   background: rgba(255,255,255,1);
    +  background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(255,255,255,1)), color-stop(100%, rgba(119,119,119,1)));
    +  background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: -o-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: linear-gradient(to bottom, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#ffffff", endColorstr="#777777", GradientType=0 );
    +
    +      }
    +.dione .tp-bullet-title:after {
    +        content:" ";
    +        position:absolute;
    +        left:50%;
    +        margin-left:-8px;
    +        width: 0;
    +    height: 0;
    +    border-style: solid;
    +    border-width: 8px 8px 0 8px;
    +    border-color: rgba(0,0,0,0.75) transparent transparent transparent;
    +        bottom:-8px;
    +   }
    +
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + ERINYEN SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +.erinyen.tparrows {
    +  cursor:pointer;
    +  background:#000;
    +  background:rgba(0,0,0,0.5);
    +  min-width:70px;
    +  min-height:70px;
    +  position:absolute;
    +  display:block;
    +  z-index:100;
    +  border-radius:35px;
    +}
    +
    +.erinyen.tparrows:before {
    +  font-family: "revicons";
    +  font-size:20px;
    +  color:#fff;
    +  display:block;
    +  line-height: 70px;
    +  text-align: center;
    +  z-index:2;
    +  position:relative;
    +}
    +.erinyen.tparrows.tp-leftarrow:before {
    +  content: "\e824";
    +}
    +.erinyen.tparrows.tp-rightarrow:before {
    +  content: "\e825";
    +}
    +
    +.erinyen .tp-title-wrap {
    +  position:absolute;
    +  z-index:1;
    +  display:inline-block;
    +  background:#000;
    +  background:rgba(0,0,0,0.5);
    +  min-height:70px;
    +  line-height:70px;
    +  top:0px;
    +  margin-left:0px;
    +  border-radius:35px;
    +  overflow:hidden;
    +  transition: opacity 0.3s;
    +  -webkit-transition:opacity 0.3s;
    +  -moz-transition:opacity 0.3s;
    +  -webkit-transform: scale(0);
    +  -moz-transform: scale(0);
    +  transform: scale(0);
    +  visibility:hidden;
    +  opacity:0;
    +}
    +
    +.erinyen.tparrows:hover .tp-title-wrap{
    +  -webkit-transform: scale(1);
    +  -moz-transform: scale(1);
    +  transform: scale(1);
    +  opacity:1;
    +  visibility:visible;
    +}
    +
    + .erinyen.tp-rightarrow .tp-title-wrap {
    +   right:0px;
    +   margin-right:0px;margin-left:0px;
    +   -webkit-transform-origin:100% 50%;
    +  border-radius:35px;
    +  padding-right:20px;
    +  padding-left:10px;
    + }
    +
    +
    +.erinyen.tp-leftarrow .tp-title-wrap {
    +   padding-left:20px;
    +  padding-right:10px;
    +}
    +
    +.erinyen .tp-arr-titleholder {
    +  letter-spacing: 3px;
    +   position:relative;
    +  -webkit-transition: -webkit-transform 0.3s;
    +  transition: transform 0.3s;
    +  transform:translateX(200px);
    +  text-transform:uppercase;
    +  color:#fff;
    +  font-weight:600;
    +  font-size:13px;
    +  line-height:70px;
    +  white-space:nowrap;
    +  padding:0px 20px;
    +  margin-left:11px;
    +  opacity:0;
    +}
    +
    +.erinyen .tp-arr-imgholder {
    +  width:100%;
    +  height:100%;
    +  position:absolute;
    +  top:0px;
    +  left:0px;
    +  background-position:center center;
    +  background-size:cover;
    +    }
    + .erinyen .tp-arr-img-over {
    +   width:100%;
    +  height:100%;
    +  position:absolute;
    +  top:0px;
    +  left:0px;
    +   background:#000;
    +   background:rgba(0,0,0,0.5);
    +        }
    +.erinyen.tp-rightarrow .tp-arr-titleholder {
    +   transform:translateX(-200px);
    +   margin-left:0px; margin-right:11px;
    +      }
    +
    +.erinyen.tparrows:hover .tp-arr-titleholder {
    +   transform:translateX(0px);
    +   -webkit-transform:translateX(0px);
    +  transition-delay: 0.1s;
    +  opacity:1;
    +}
    +
    +/* BULLETS */
    +.erinyen.tp-bullets {
    +}
    +.erinyen.tp-bullets:before {
    +	content:" ";
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	background: #555555; /* old browsers */
    +    background: -moz-linear-gradient(top,  #555555 0%, #222222 100%); /* ff3.6+ */
    +    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#555555), color-stop(100%,#222222)); /* chrome,safari4+ */
    +    background: -webkit-linear-gradient(top,  #555555 0%,#222222 100%); /* chrome10+,safari5.1+ */
    +    background: -o-linear-gradient(top,  #555555 0%,#222222 100%); /* opera 11.10+ */
    +    background: -ms-linear-gradient(top,  #555555 0%,#222222 100%); /* ie10+ */
    +    background: linear-gradient(to bottom,  #555555 0%,#222222 100%); /* w3c */
    +    filter: progid:dximagetransform.microsoft.gradient( startcolorstr="#555555", endcolorstr="#222222",gradienttype=0 ); /* ie6-9 */
    +	padding:10px 15px;
    +	margin-left:-15px;margin-top:-10px;
    +	box-sizing:content-box;
    +   border-radius:10px;
    +   box-shadow:0px 0px 2px 1px rgba(33,33,33,0.3);
    +}
    +.erinyen .tp-bullet {
    +	width:13px;
    +	height:13px;
    +	position:absolute;
    +	background:#111;
    +	border-radius:50%;
    +	cursor: pointer;
    +	box-sizing:content-box;
    +}
    +.erinyen .tp-bullet:hover,
    +.erinyen .tp-bullet.selected {
    +	background: #e5e5e5; /* old browsers */
    +background: -moz-linear-gradient(top,  #e5e5e5 0%, #999999 100%); /* ff3.6+ */
    +background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#e5e5e5), color-stop(100%,#999999)); /* chrome,safari4+ */
    +background: -webkit-linear-gradient(top,  #e5e5e5 0%,#999999 100%); /* chrome10+,safari5.1+ */
    +background: -o-linear-gradient(top,  #e5e5e5 0%,#999999 100%); /* opera 11.10+ */
    +background: -ms-linear-gradient(top,  #e5e5e5 0%,#999999 100%); /* ie10+ */
    +background: linear-gradient(to bottom,  #e5e5e5 0%,#999999 100%); /* w3c */
    +filter: progid:dximagetransform.microsoft.gradient( startcolorstr="#e5e5e5", endcolorstr="#999999",gradienttype=0 ); /* ie6-9 */
    +  border:1px solid #555;
    +  width:12px;height:12px;
    +}
    +.erinyen .tp-bullet-image {
    +}
    +.erinyen .tp-bullet-title {
    +}
    +
    +
    +/* THUMBS */
    +.erinyen .tp-thumb {
    +opacity:1
    +}
    +
    +.erinyen .tp-thumb-over {
    +  background:#000;
    +  background:rgba(0,0,0,0.25);
    +  width:100%;
    +  height:100%;
    +  position:absolute;
    +  top:0px;
    +  left:0px;
    +  z-index:1;
    +  -webkit-transition:all 0.3s;
    +  transition:all 0.3s;
    +}
    +
    +.erinyen .tp-thumb-more:before {
    +  font-family: "revicons";
    +  font-size:12px;
    +  color:#aaa;
    +  color:rgba(255,255,255,0.75);
    +  display:block;
    +  line-height: 12px;
    +  text-align: left;
    +  z-index:2;
    +  position:absolute;
    +  top:20px;
    +  right:20px;
    +  z-index:2;
    +}
    +.erinyen .tp-thumb-more:before {
    +  content: "\e825";
    +}
    +
    +.erinyen .tp-thumb-title {
    +  font-family:"Raleway";
    +  letter-spacing:1px;
    +  font-size:12px;
    +  color:#fff;
    +  display:block;
    +  line-height: 15px;
    +  text-align: left;
    +  z-index:2;
    +  position:absolute;
    +  top:0px;
    +  left:0px;
    +  z-index:2;
    +  padding:20px 35px 20px 20px;
    +  width:100%;
    +  height:100%;
    +  box-sizing:border-box;
    +  transition:all 0.3s;
    +  -webkit-transition:all 0.3s;
    +  font-weight:500;
    +}
    +
    +.erinyen .tp-thumb.selected .tp-thumb-more:before,
    +.erinyen .tp-thumb:hover .tp-thumb-more:before {
    + color:#aaa;
    +
    +}
    +
    +.erinyen .tp-thumb.selected .tp-thumb-over,
    +.erinyen .tp-thumb:hover .tp-thumb-over {
    + background:#fff;
    +}
    +.erinyen .tp-thumb.selected .tp-thumb-title,
    +.erinyen .tp-thumb:hover .tp-thumb-title {
    +  color:#000;
    +
    +}
    +
    +
    +/* TABS */
    +.erinyen .tp-tab-title {
    +    color:#a8d8ee;
    +    font-size:13px;
    +    font-weight:700;
    +    text-transform:uppercase;
    +    font-family:"Roboto Slab"
    +    margin-bottom:5px;
    +}
    +
    +.erinyen .tp-tab-desc {
    +	font-size:18px;
    +    font-weight:400;
    +    color:#fff;
    +    line-height:25px;
    +	font-family:"Roboto Slab";
    +}
    +
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + GYGES SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +
    +
    +/* BULLETS */
    +.gyges.tp-bullets {
    +}
    +.gyges.tp-bullets:before {
    +	content:" ";
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	background: #777777; /* Old browsers */
    +    background: -moz-linear-gradient(top,  #777777 0%, #666666 100%);
    +    background: -webkit-gradient(linear, left top, left bottom,
    +    color-stop(0%,#777777), color-stop(100%,#666666));
    +    background: -webkit-linear-gradient(top,  #777777 0%,#666666 100%);
    +    background: -o-linear-gradient(top,  #777777 0%,#666666 100%);
    +    background: -ms-linear-gradient(top,  #777777 0%,#666666 100%);
    +    background: linear-gradient(to bottom,  #777777 0%,#666666 100%);
    +    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#777777",
    +    endColorstr="#666666",GradientType=0 );
    +	padding:10px;
    +	margin-left:-10px;margin-top:-10px;
    +	box-sizing:content-box;
    +  border-radius:10px;
    +}
    +.gyges .tp-bullet {
    +	width:12px;
    +	height:12px;
    +	position:absolute;
    +	background:#333;
    +	border:3px solid #444;
    +	border-radius:50%;
    +	cursor: pointer;
    +	box-sizing:content-box;
    +}
    +.gyges .tp-bullet:hover,
    +.gyges .tp-bullet.selected {
    +	background: #ffffff; /* Old browsers */
    +    background: -moz-linear-gradient(top,  #ffffff 0%, #e1e1e1 100%); /* FF3.6+ */
    +    background: -webkit-gradient(linear, left top, left bottom,
    +    color-stop(0%,#ffffff), color-stop(100%,#e1e1e1)); /* Chrome,Safari4+ */
    +    background: -webkit-linear-gradient(top,  #ffffff 0%,#e1e1e1 100%); /* Chrome10+,Safari5.1+ */
    +    background: -o-linear-gradient(top,  #ffffff 0%,#e1e1e1 100%); /* Opera 11.10+ */
    +    background: -ms-linear-gradient(top,  #ffffff 0%,#e1e1e1 100%); /* IE10+ */
    +    background: linear-gradient(to bottom,  #ffffff 0%,#e1e1e1 100%); /* W3C */
    +    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#ffffff",
    +    endColorstr="#e1e1e1",GradientType=0 ); /* IE6-9 */
    +
    +}
    +.gyges .tp-bullet-image {
    +}
    +.gyges .tp-bullet-title {
    +}
    +
    +
    +/* THUMBS */
    +.gyges .tp-thumb {
    +      opacity:1
    +  }
    +.gyges .tp-thumb-img-wrap {
    +  padding:3px;
    +    background:#000;
    +  background-color:rgba(0,0,0,0.25);
    +  display:inline-block;
    +
    +  width:100%;
    +  height:100%;
    +  position:relative;
    +  margin:0px;
    +  box-sizing:border-box;
    +    transition:all 0.3s;
    +    -webkit-transition:all 0.3s;
    +}
    +.gyges .tp-thumb-image {
    +   padding:3px;
    +   display:block;
    +   box-sizing:border-box;
    +   position:relative;
    +    -webkit-box-shadow: inset 5px 5px 10px 0px rgba(0,0,0,0.25);
    +  -moz-box-shadow: inset 5px 5px 10px 0px rgba(0,0,0,0.25);
    +  box-shadow: inset 5px 5px 10px 0px rgba(0,0,0,0.25);
    + }
    +.gyges .tp-thumb-title {
    +     position:absolute;
    +     bottom:100%;
    +     display:inline-block;
    +     left:50%;
    +     background:rgba(255,255,255,0.8);
    +     padding:10px 30px;
    +     border-radius:4px;
    +	 -webkit-border-radius:4px;
    +     margin-bottom:20px;
    +     opacity:0;
    +      transition:all 0.3s;
    +    -webkit-transition:all 0.3s;
    +    transform: translateZ(0.001px) translateX(-50%) translateY(14px);
    +    transform-origin:50% 100%;
    +    -webkit-transform: translateZ(0.001px) translateX(-50%) translateY(14px);
    +    -webkit-transform-origin:50% 100%;
    +    white-space:nowrap;
    + }
    +.gyges .tp-thumb:hover .tp-thumb-title {
    +  	 transform:rotateX(0deg) translateX(-50%);
    +    -webkit-transform:rotateX(0deg) translateX(-50%);
    +    opacity:1;
    +}
    +
    +.gyges .tp-thumb:hover .tp-thumb-img-wrap,
    + .gyges .tp-thumb.selected .tp-thumb-img-wrap {
    +
    +  background: rgba(255,255,255,1);
    +  background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(255,255,255,1)), color-stop(100%, rgba(119,119,119,1)));
    +  background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: -o-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: linear-gradient(to bottom, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#ffffff", endColorstr="#777777", GradientType=0 );
    + }
    +.gyges .tp-thumb-title:after {
    +        content:" ";
    +        position:absolute;
    +        left:50%;
    +        margin-left:-8px;
    +        width: 0;
    +		height: 0;
    +		border-style: solid;
    +		border-width: 8px 8px 0 8px;
    +		border-color: rgba(255,255,255,0.8) transparent transparent transparent;
    +        bottom:-8px;
    +   }
    +
    +
    +/* TABS */
    +.gyges .tp-tab {
    +  opacity:1;
    +  padding:10px;
    +  box-sizing:border-box;
    +  font-family: "Roboto", sans-serif;
    +  border-bottom: 1px solid rgba(255,255,255,0.15);
    + }
    +.gyges .tp-tab-image
    +{
    +  width:60px;
    +  height:60px; max-height:100%; max-width:100%;
    +  position:relative;
    +  display:inline-block;
    +  float:left;
    +
    +}
    +.gyges .tp-tab-content
    +{
    +    background:rgba(0,0,0,0);
    +    position:relative;
    +    padding:15px 15px 15px 85px;
    + left:0px;
    +  overflow:hidden;
    + margin-top:-15px;
    +    box-sizing:border-box;
    +    color:#333;
    +    display: inline-block;
    +    width:100%;
    +    height:100%;
    + position:absolute; }
    +.gyges .tp-tab-date
    +  {
    +  display:block;
    +  color: rgba(255,255,255,0.25);
    +  font-weight:500;
    +  font-size:12px;
    +  margin-bottom:0px;
    +  }
    +.gyges .tp-tab-title
    +{
    +    display:block;
    +    text-align:left;
    +    color:#fff;
    +    font-size:14px;
    +    font-weight:500;
    +    text-transform:none;
    +    line-height:17px;
    +}
    +.gyges .tp-tab:hover,
    +.gyges .tp-tab.selected {
    +  background:rgba(0,0,0,0.5);
    +}
    +
    +.gyges .tp-tab-mask {
    +}
    +
    +/* MEDIA QUERIES */
    +@media only screen and (max-width: 960px) {
    +
    +}
    +@media only screen and (max-width: 768px) {
    +
    +}
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + HADES SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +.hades.tparrows {
    +	cursor:pointer;
    +	background:#000;
    +	background:rgba(0,0,0,0.15);
    +	width:100px;
    +	height:100px;
    +	position:absolute;
    +	display:block;
    +	z-index:100;
    +}
    +
    +.hades.tparrows:before {
    +	font-family: "revicons";
    +	font-size:30px;
    +	color:#fff;
    +	display:block;
    +	line-height: 100px;
    +	text-align: center;
    +  transition: background 0.3s, color 0.3s;
    +}
    +.hades.tparrows.tp-leftarrow:before {
    +	content: "\e824";
    +}
    +.hades.tparrows.tp-rightarrow:before {
    +	content: "\e825";
    +}
    +
    +.hades.tparrows:hover:before {
    +   color:#aaa;
    +   background:#fff;
    +   background:rgba(255,255,255,1);
    + }
    +.hades .tp-arr-allwrapper {
    +  position:absolute;
    +  left:100%;
    +  top:0px;
    +  background:#888;
    +  width:100px;height:100px;
    +  -webkit-transition: all 0.3s;
    +  transition: all 0.3s;
    +  -ms-filter: "progid:dximagetransform.microsoft.alpha(opacity=0)";
    +  filter: alpha(opacity=0);
    +  -moz-opacity: 0.0;
    +  -khtml-opacity: 0.0;
    +  opacity: 0.0;
    +  -webkit-transform: rotatey(-90deg);
    +  transform: rotatey(-90deg);
    +  -webkit-transform-origin: 0% 50%;
    +  transform-origin: 0% 50%;
    +}
    +.hades.tp-rightarrow .tp-arr-allwrapper {
    +   left:auto;
    +   right:100%;
    +   -webkit-transform-origin: 100% 50%;
    +  transform-origin: 100% 50%;
    +   -webkit-transform: rotatey(90deg);
    +  transform: rotatey(90deg);
    +}
    +
    +.hades:hover .tp-arr-allwrapper {
    +   -ms-filter: "progid:dximagetransform.microsoft.alpha(opacity=100)";
    +  filter: alpha(opacity=100);
    +  -moz-opacity: 1;
    +  -khtml-opacity: 1;
    +  opacity: 1;
    +    -webkit-transform: rotatey(0deg);
    +  transform: rotatey(0deg);
    +
    + }
    +
    +.hades .tp-arr-iwrapper {
    +}
    +.hades .tp-arr-imgholder {
    +  background-size:cover;
    +  position:absolute;
    +  top:0px;left:0px;
    +  width:100%;height:100%;
    +}
    +.hades .tp-arr-titleholder {
    +}
    +.hades .tp-arr-subtitleholder {
    +}
    +
    +
    +/* BULLETS */
    +.hades.tp-bullets {
    +}
    +.hades.tp-bullets:before {
    +	content:" ";
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	background:transparent;
    +	padding:10px;
    +	margin-left:-10px;margin-top:-10px;
    +	box-sizing:content-box;
    +}
    +.hades .tp-bullet {
    +	width:3px;
    +	height:3px;
    +	position:absolute;
    +	background:#888;
    +	cursor: pointer;
    +    border:5px solid #fff;
    +	box-sizing:content-box;
    +    box-shadow:0px 0px 3px 1px rgba(0,0,0,0.2);
    +    -webkit-perspective:400;
    +    perspective:400;
    +    -webkit-transform:translatez(0.01px);
    +    transform:translatez(0.01px);
    +}
    +.hades .tp-bullet:hover,
    +.hades .tp-bullet.selected {
    +	background:#555;
    +
    +}
    +
    +.hades .tp-bullet-image {
    +  position:absolute;top:-80px; left:-60px;width:120px;height:60px;
    +  background-position:center center;
    +  background-size:cover;
    +  visibility:hidden;
    +  opacity:0;
    +  transition:all 0.3s;
    +  -webkit-transform-style:flat;
    +  transform-style:flat;
    +  perspective:600;
    +  -webkit-perspective:600;
    +  transform: rotatex(-90deg);
    +  -webkit-transform: rotatex(-90deg);
    +  box-shadow:0px 0px 3px 1px rgba(0,0,0,0.2);
    +  transform-origin:50% 100%;
    +  -webkit-transform-origin:50% 100%;
    +
    +
    +}
    +.hades .tp-bullet:hover .tp-bullet-image {
    +  display:block;
    +  opacity:1;
    +  transform: rotatex(0deg);
    +  -webkit-transform: rotatex(0deg);
    +  visibility:visible;
    +    }
    +.hades .tp-bullet-title {
    +}
    +
    +
    +/* THUMBS */
    +.hades .tp-thumb {
    +      opacity:1
    +  }
    +.hades .tp-thumb-img-wrap {
    +  border-radius:50%;
    +  padding:3px;
    +  display:inline-block;
    +background:#000;
    +  background-color:rgba(0,0,0,0.25);
    +  width:100%;
    +  height:100%;
    +  position:relative;
    +  margin:0px;
    +  box-sizing:border-box;
    +    transition:all 0.3s;
    +    -webkit-transition:all 0.3s;
    +}
    +.hades .tp-thumb-image {
    +   padding:3px;
    +   border-radius:50%;
    +   display:block;
    +   box-sizing:border-box;
    +   position:relative;
    +    -webkit-box-shadow: inset 5px 5px 10px 0px rgba(0,0,0,0.25);
    +  -moz-box-shadow: inset 5px 5px 10px 0px rgba(0,0,0,0.25);
    +  box-shadow: inset 5px 5px 10px 0px rgba(0,0,0,0.25);
    + }
    +
    +
    +.hades .tp-thumb:hover .tp-thumb-img-wrap,
    +.hades .tp-thumb.selected .tp-thumb-img-wrap {
    +
    +   background: rgba(255,255,255,1);
    +  background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(255,255,255,1)), color-stop(100%, rgba(119,119,119,1)));
    +  background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: -o-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: linear-gradient(to bottom, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#ffffff", endColorstr="#777777", GradientType=0 );
    +
    +      }
    +.hades .tp-thumb-title:after {
    +        content:" ";
    +        position:absolute;
    +        left:50%;
    +        margin-left:-8px;
    +        width: 0;
    +		height: 0;
    +		border-style: solid;
    +		border-width: 8px 8px 0 8px;
    +		border-color: rgba(0,0,0,0.75) transparent transparent transparent;
    +        bottom:-8px;
    +   }
    +
    +
    +/* TABS */
    +.hades .tp-tab {
    +  opacity:1;
    + }
    +
    +.hades .tp-tab-title
    + {
    +      display:block;
    +      color:#333;
    +      font-weight:600;
    +      font-size:18px;
    +      text-align:center;
    +      line-height:25px;
    +    }
    +.hades .tp-tab-price
    + {
    +	display:block;
    +    text-align:center;
    +    color:#999;
    +    font-size:16px;
    +    margin-top:10px;
    +   line-height:20px
    +}
    +
    +.hades .tp-tab-button {
    +    display:inline-block;
    +    margin-top:15px;
    +    text-align:center;
    +	padding:5px 15px;
    +  	color:#fff;
    +  	font-size:14px;
    +  	background:#219bd7;
    +   	border-radius:4px;
    +   font-weight:400;
    +}
    +.hades .tp-tab-inner {
    +	text-align:center;
    +}
    +
    +
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + HEBE SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +.hebe.tparrows {
    +  cursor:pointer;
    +  background:#fff;
    +  min-width:70px;
    +    min-height:70px;
    +  position:absolute;
    +  display:block;
    +  z-index:100;
    +}
    +.hebe.tparrows:hover {
    +}
    +.hebe.tparrows:before {
    +  font-family: "revicons";
    +  font-size:30px;
    +  color:#aaa;
    +  display:block;
    +  line-height: 70px;
    +  text-align: center;
    +  -webkit-transition: color 0.3s;
    +  -moz-transition: color 0.3s;
    +  transition: color 0.3s;
    +  z-index:2;
    +  position:relative;
    +   background:#fff;
    +  min-width:70px;
    +    min-height:70px;
    +}
    +.hebe.tparrows.tp-leftarrow:before {
    +  content: "\e824";
    +}
    +.hebe.tparrows.tp-rightarrow:before {
    +  content: "\e825";
    +}
    +.hebe.tparrows:hover:before {
    + color:#000;
    +      }
    +.hebe .tp-title-wrap {
    +  position:absolute;
    +  z-index:0;
    +  display:inline-block;
    +  background:#000;
    +  background:rgba(0,0,0,0.75);
    +  min-height:60px;
    +  line-height:60px;
    +  top:-10px;
    +  margin-left:0px;
    +  -webkit-transition: -webkit-transform 0.3s;
    +  transition: transform 0.3s;
    +  transform:scaleX(0);
    +  -webkit-transform:scaleX(0);
    +  transform-origin:0% 50%;
    +   -webkit-transform-origin:0% 50%;
    +}
    + .hebe.tp-rightarrow .tp-title-wrap {
    +   right:0px;
    +   -webkit-transform-origin:100% 50%;
    + }
    +.hebe.tparrows:hover .tp-title-wrap {
    +  transform:scaleX(1);
    +  -webkit-transform:scaleX(1);
    +}
    +.hebe .tp-arr-titleholder {
    +  position:relative;
    +  text-transform:uppercase;
    +  color:#fff;
    +  font-weight:600;
    +  font-size:12px;
    +  line-height:90px;
    +  white-space:nowrap;
    +  padding:0px 20px 0px 90px;
    +}
    +
    +.hebe.tp-rightarrow .tp-arr-titleholder {
    +   margin-left:0px;
    +   padding:0px 90px 0px 20px;
    + }
    +
    +.hebe.tparrows:hover .tp-arr-titleholder {
    +   transform:translateX(0px);
    +   -webkit-transform:translateX(0px);
    +  transition-delay: 0.1s;
    +  opacity:1;
    +}
    +
    +.hebe .tp-arr-imgholder{
    +      width:90px;
    +      height:90px;
    +      position:absolute;
    +      left:100%;
    +      display:block;
    +      background-size:cover;
    +      background-position:center center;
    +  	 top:0px; right:-90px;
    +    }
    +.hebe.tp-rightarrow .tp-arr-imgholder{
    +        right:auto;left:-90px;
    +      }
    +
    +/* BULLETS */
    +.hebe.tp-bullets {
    +}
    +.hebe.tp-bullets:before {
    +  content:" ";
    +  position:absolute;
    +  width:100%;
    +  height:100%;
    +  background:transparent;
    +  padding:10px;
    +  margin-left:-10px;margin-top:-10px;
    +  box-sizing:content-box;
    +}
    +
    +.hebe .tp-bullet {
    +  width:3px;
    +  height:3px;
    +  position:absolute;
    +  background:#fff;
    +  cursor: pointer;
    +  border:5px solid #222;
    +  border-radius:50%;
    +  box-sizing:content-box;
    +  -webkit-perspective:400;
    +  perspective:400;
    +  -webkit-transform:translateZ(0.01px);
    +  transform:translateZ(0.01px);
    +   transition:all 0.3s;
    +}
    +.hebe .tp-bullet:hover,
    +.hebe .tp-bullet.selected {
    +  background:#222;
    +  border-color:#fff;
    +}
    +
    +.hebe .tp-bullet-image {
    +  position:absolute;
    +  top:-90px; left:-40px;
    +  width:70px;
    +  height:70px;
    +  background-position:center center;
    +  background-size:cover;
    +  visibility:hidden;
    +  opacity:0;
    +  transition:all 0.3s;
    +  -webkit-transform-style:flat;
    +  transform-style:flat;
    +  perspective:600;
    +  -webkit-perspective:600;
    +  transform: scale(0);
    +  -webkit-transform: scale(0);
    +  transform-origin:50% 100%;
    +  -webkit-transform-origin:50% 100%;
    +border-radius:6px;
    +
    +
    +}
    +.hebe .tp-bullet:hover .tp-bullet-image {
    +  display:block;
    +  opacity:1;
    +  transform: scale(1);
    +  -webkit-transform: scale(1);
    +  visibility:visible;
    +    }
    +.hebe .tp-bullet-title {
    +}
    +
    +
    +/* TABS */
    +.hebe .tp-tab-title {
    +    color:#a8d8ee;
    +    font-size:13px;
    +    font-weight:700;
    +    text-transform:uppercase;
    +    font-family:"Roboto Slab"
    +    margin-bottom:5px;
    +}
    +
    +.hebe .tp-tab-desc {
    +	font-size:18px;
    +    font-weight:400;
    +    color:#fff;
    +    line-height:25px;
    +	font-family:"Roboto Slab";
    +}
    +
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + HEPHAISTOS SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +.hephaistos.tparrows {
    +	cursor:pointer;
    +	background:#000;
    +	background:rgba(0,0,0,0.5);
    +	width:40px;
    +	height:40px;
    +	position:absolute;
    +	display:block;
    +	z-index:100;
    +    border-radius:50%;
    +}
    +.hephaistos.tparrows:hover {
    +	background:#000;
    +}
    +.hephaistos.tparrows:before {
    +	font-family: "revicons";
    +	font-size:18px;
    +	color:#fff;
    +	display:block;
    +	line-height: 40px;
    +	text-align: center;
    +}
    +.hephaistos.tparrows.tp-leftarrow:before {
    +	content: "\e82c";
    +  margin-left:-2px;
    +
    +}
    +.hephaistos.tparrows.tp-rightarrow:before {
    +	content: "\e82d";
    +   margin-right:-2px;
    +}
    +
    +
    +
    +/* BULLETS */
    +.hephaistos.tp-bullets {
    +}
    +.hephaistos.tp-bullets:before {
    +	content:" ";
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	background:transparent;
    +	padding:10px;
    +	margin-left:-10px;margin-top:-10px;
    +	box-sizing:content-box;
    +}
    +.hephaistos .tp-bullet {
    +	width:12px;
    +	height:12px;
    +	position:absolute;
    +	background:#999;
    +	border:3px solid #f5f5f5;
    +	border-radius:50%;
    +	cursor: pointer;
    +	box-sizing:content-box;
    +  box-shadow: 0px 0px 2px 1px rgba(130,130,130, 0.3);
    +
    +}
    +.hephaistos .tp-bullet:hover,
    +.hephaistos .tp-bullet.selected {
    +	background:#fff;
    +    border-color:#000;
    +}
    +.hephaistos .tp-bullet-image {
    +}
    +.hephaistos .tp-bullet-title {
    +}
    +
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + HERMES SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +.hermes.tparrows {
    +	cursor:pointer;
    +	background:#000;
    +	background:rgba(0,0,0,0.5);
    +	width:30px;
    +	height:110px;
    +	position:absolute;
    +	display:block;
    +	z-index:100;
    +}
    +
    +.hermes.tparrows:before {
    +	font-family: "revicons";
    +	font-size:15px;
    +	color:#fff;
    +	display:block;
    +	line-height: 110px;
    +	text-align: center;
    +    transform:translateX(0px);
    +    -webkit-transform:translateX(0px);
    +    transition:all 0.3s;
    +    -webkit-transition:all 0.3s;
    +}
    +.hermes.tparrows.tp-leftarrow:before {
    +	content: "\e824";
    +}
    +.hermes.tparrows.tp-rightarrow:before {
    +	content: "\e825";
    +}
    +.hermes.tparrows.tp-leftarrow:hover:before {
    +    transform:translateX(-20px);
    +    -webkit-transform:translateX(-20px);
    +     opacity:0;
    +}
    +.hermes.tparrows.tp-rightarrow:hover:before {
    +    transform:translateX(20px);
    +    -webkit-transform:translateX(20px);
    +     opacity:0;
    +}
    +
    +.hermes .tp-arr-allwrapper {
    +    overflow:hidden;
    +    position:absolute;
    +	width:180px;
    +    height:140px;
    +    top:0px;
    +    left:0px;
    +    visibility:hidden;
    +      -webkit-transition: -webkit-transform 0.3s 0.3s;
    +  transition: transform 0.3s 0.3s;
    +  -webkit-perspective: 1000px;
    +  perspective: 1000px;
    +    }
    +.hermes.tp-rightarrow .tp-arr-allwrapper {
    +   right:0px;left:auto;
    +      }
    +.hermes.tparrows:hover .tp-arr-allwrapper {
    +   visibility:visible;
    +          }
    +.hermes .tp-arr-imgholder {
    +  width:180px;position:absolute;
    +  left:0px;top:0px;height:110px;
    +  transform:translateX(-180px);
    +  -webkit-transform:translateX(-180px);
    +  transition:all 0.3s;
    +  transition-delay:0.3s;
    +}
    +.hermes.tp-rightarrow .tp-arr-imgholder{
    +    transform:translateX(180px);
    +  -webkit-transform:translateX(180px);
    +      }
    +
    +.hermes.tparrows:hover .tp-arr-imgholder {
    +   transform:translateX(0px);
    +   -webkit-transform:translateX(0px);
    +}
    +.hermes .tp-arr-titleholder {
    +  top:110px;
    +  width:180px;
    +  text-align:left;
    +  display:block;
    +  padding:0px 10px;
    +  line-height:30px; background:#000;
    +  background:rgba(0,0,0,0.75);color:#fff;
    +  font-weight:600; position:absolute;
    +  font-size:12px;
    +  white-space:nowrap;
    +  letter-spacing:1px;
    +  -webkit-transition: all 0.3s;
    +  transition: all 0.3s;
    +  -webkit-transform: rotateX(-90deg);
    +  transform: rotateX(-90deg);
    +  -webkit-transform-origin: 50% 0;
    +  transform-origin: 50% 0;
    +  box-sizing:border-box;
    +
    +}
    +.hermes.tparrows:hover .tp-arr-titleholder {
    +    -webkit-transition-delay: 0.6s;
    +  transition-delay: 0.6s;
    +  -webkit-transform: rotateX(0deg);
    +  transform: rotateX(0deg);
    +}
    +
    +
    +/* BULLETS */
    +.hermes.tp-bullets {
    +}
    +
    +.hermes .tp-bullet {
    +    overflow:hidden;
    +    border-radius:50%;
    +    width:16px;
    +    height:16px;
    +    background-color: rgba(0, 0, 0, 0);
    +    box-shadow: inset 0 0 0 2px #FFF;
    +    -webkit-transition: background 0.3s ease;
    +    transition: background 0.3s ease;
    +    position:absolute;
    +}
    +
    +.hermes .tp-bullet:hover {
    +	  background-color: rgba(0, 0, 0, 0.2);
    +}
    +.hermes .tp-bullet:after {
    +  content: ' ';
    +  position: absolute;
    +  bottom: 0;
    +  height: 0;
    +  left: 0;
    +  width: 100%;
    +  background-color: #FFF;
    +  box-shadow: 0 0 1px #FFF;
    +  -webkit-transition: height 0.3s ease;
    +  transition: height 0.3s ease;
    +}
    +.hermes .tp-bullet.selected:after {
    +  height:100%;
    +}
    +
    +
    +/* TABS */
    +.hermes .tp-tab {
    +  opacity:1;
    +  padding-right:10px;
    +  box-sizing:border-box;
    + }
    +.hermes .tp-tab-image
    +{
    +  width:100%;
    +  height:60%;
    +  position:relative;
    +}
    +.hermes .tp-tab-content
    +{
    +    background:rgb(54,54,54);
    +    position:absolute;
    +    padding:20px 20px 20px 30px;
    +    box-sizing:border-box;
    +    color:#fff;
    +  display:block;
    +  width:100%;
    +  min-height:40%;
    +  bottom:0px;
    +  left:-10px;
    +  }
    +.hermes .tp-tab-date
    +  {
    +  display:block;
    +  color:#888;
    +  font-weight:600;
    +  font-size:12px;
    +  margin-bottom:10px;
    +  }
    +.hermes .tp-tab-title
    +{
    +    display:block;
    +    color:#fff;
    +    font-size:16px;
    +    font-weight:800;
    +    text-transform:uppercase;
    +   line-height:19px;
    +}
    +
    +.hermes .tp-tab.selected .tp-tab-title:after {
    +    width: 0px;
    +	height: 0px;
    +	border-style: solid;
    +	border-width: 30px 0 30px 10px;
    +	border-color: transparent transparent transparent rgb(54,54,54);
    +	content:" ";
    +    position:absolute;
    +    right:-9px;
    +    bottom:50%;
    +    margin-bottom:-30px;
    +}
    +.hermes .tp-tab-mask {
    +     padding-right:10px !important;
    +          }
    +
    +/* MEDIA QUERIES */
    +@media only screen and (max-width: 960px) {
    +  .hermes .tp-tab .tp-tab-title {font-size:14px;line-height:16px;}
    +  .hermes .tp-tab-date { font-size:11px; line-height:13px;margin-bottom:10px;}
    +  .hermes .tp-tab-content { padding:15px 15px 15px 25px;}
    +}
    +@media only screen and (max-width: 768px) {
    +  .hermes .tp-tab .tp-tab-title {font-size:12px;line-height:14px;}
    +  .hermes .tp-tab-date {font-size:10px; line-height:12px;margin-bottom:5px;}
    +  .hermes .tp-tab-content {padding:10px 10px 10px 20px;}
    +}
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + HESPERIDEN SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +.hesperiden.tparrows {
    +	cursor:pointer;
    +	background:#000;
    +	background:rgba(0,0,0,0.5);
    +	width:40px;
    +	height:40px;
    +	position:absolute;
    +	display:block;
    +	z-index:100;
    +    border-radius: 50%;
    +}
    +.hesperiden.tparrows:hover {
    +	background:#000;
    +}
    +.hesperiden.tparrows:before {
    +	font-family: "revicons";
    +	font-size:20px;
    +	color:#fff;
    +	display:block;
    +	line-height: 40px;
    +	text-align: center;
    +}
    +.hesperiden.tparrows.tp-leftarrow:before {
    +	content: "\e82c";
    +    margin-left:-3px;
    +}
    +.hesperiden.tparrows.tp-rightarrow:before {
    +	content: "\e82d";
    +    margin-right:-3px;
    +}
    +
    +/* BULLETS */
    +.hesperiden.tp-bullets {
    +}
    +.hesperiden.tp-bullets:before {
    +	content:" ";
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	background:transparent;
    +	padding:10px;
    +	margin-left:-10px;margin-top:-10px;
    +	box-sizing:content-box;
    +   border-radius:8px;
    +
    +}
    +.hesperiden .tp-bullet {
    +	width:12px;
    +	height:12px;
    +	position:absolute;
    +	background: #999999; /* old browsers */
    +    background: -moz-linear-gradient(top,  #999999 0%, #e1e1e1 100%); /* ff3.6+ */
    +    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#999999),
    +    color-stop(100%,#e1e1e1)); /* chrome,safari4+ */
    +    background: -webkit-linear-gradient(top,  #999999 0%,#e1e1e1 100%); /* chrome10+,safari5.1+ */
    +    background: -o-linear-gradient(top,  #999999 0%,#e1e1e1 100%); /* opera 11.10+ */
    +    background: -ms-linear-gradient(top,  #999999 0%,#e1e1e1 100%); /* ie10+ */
    +    background: linear-gradient(to bottom,  #999999 0%,#e1e1e1 100%); /* w3c */
    +    filter: progid:dximagetransform.microsoft.gradient(
    +    startcolorstr="#999999", endcolorstr="#e1e1e1",gradienttype=0 ); /* ie6-9 */
    +	border:3px solid #e5e5e5;
    +	border-radius:50%;
    +	cursor: pointer;
    +	box-sizing:content-box;
    +}
    +.hesperiden .tp-bullet:hover,
    +.hesperiden .tp-bullet.selected {
    +	background:#666;
    +}
    +.hesperiden .tp-bullet-image {
    +}
    +.hesperiden .tp-bullet-title {
    +}
    +
    +
    +/* THUMBS */
    +.hesperiden .tp-thumb {
    +  opacity:1;
    +  -webkit-perspective: 600px;
    +  perspective: 600px;
    +}
    +.hesperiden .tp-thumb .tp-thumb-title {
    +    font-size:12px;
    +    position:absolute;
    +    margin-top:-10px;
    +    color:#fff;
    +    display:block;
    +    z-index:1000;
    +    background-color:#000;
    +    padding:5px 10px;
    +    bottom:0px;
    +    left:0px;
    +    width:100%;
    +  box-sizing:border-box;
    +    text-align:center;
    +    overflow:hidden;
    +    white-space:nowrap;
    +    transition:all 0.3s;
    +    -webkit-transition:all 0.3s;
    +    transform:rotatex(90deg) translatez(0.001px);
    +    transform-origin:50% 100%;
    +    -webkit-transform:rotatex(90deg) translatez(0.001px);
    +    -webkit-transform-origin:50% 100%;
    +    opacity:0;
    + }
    +.hesperiden .tp-thumb:hover .tp-thumb-title {
    +  	 transform:rotatex(0deg);
    +    -webkit-transform:rotatex(0deg);
    +    opacity:1;
    +}
    +
    +/* TABS */
    +.hesperiden .tp-tab {
    +  opacity:1;
    +  padding:10px;
    +  box-sizing:border-box;
    +  font-family: "Roboto", sans-serif;
    +  border-bottom: 1px solid #e5e5e5;
    + }
    +.hesperiden .tp-tab-image
    +{
    +  width:60px;
    +  height:60px; max-height:100%; max-width:100%;
    +  position:relative;
    +  display:inline-block;
    +  float:left;
    +
    +}
    +.hesperiden .tp-tab-content
    +{
    +    background:rgba(0,0,0,0);
    +    position:relative;
    +    padding:15px 15px 15px 85px;
    + left:0px;
    + overflow:hidden;
    + margin-top:-15px;
    +    box-sizing:border-box;
    +    color:#333;
    +    display: inline-block;
    +    width:100%;
    +    height:100%;
    + position:absolute; }
    +.hesperiden .tp-tab-date
    +  {
    +  display:block;
    +  color: #aaa;
    +  font-weight:500;
    +  font-size:12px;
    +  margin-bottom:0px;
    +  }
    +.hesperiden .tp-tab-title
    +{
    +    display:block;
    +    text-align:left;
    +    color:#333;
    +    font-size:14px;
    +    font-weight:500;
    +    text-transform:none;
    +    line-height:17px;
    +}
    +.hesperiden .tp-tab:hover,
    +.hesperiden .tp-tab.selected {
    +	background:#eee;
    +}
    +
    +.hesperiden .tp-tab-mask {
    +}
    +
    +/* MEDIA QUERIES */
    +@media only screen and (max-width: 960px) {
    +
    +}
    +@media only screen and (max-width: 768px) {
    +
    +}
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + METIS SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +.metis.tparrows {
    +  background:#fff;
    +  padding:10px;
    +  transition:all 0.3s;
    +  -webkit-transition:all 0.3s;
    +  width:60px;
    +  height:60px;
    +  box-sizing:border-box;
    + }
    +
    + .metis.tparrows:hover {
    +   background:#fff;
    +   background:rgba(255,255,255,0.75);
    + }
    +
    + .metis.tparrows:before {
    +  color:#000;
    +   transition:all 0.3s;
    +  -webkit-transition:all 0.3s;
    + }
    +
    + .metis.tparrows:hover:before {
    +   transform:scale(1.5);
    +  }
    +
    +
    +/* BULLETS */
    +.metis .tp-bullet {
    +    opacity:1;
    +    width:50px;
    +    height:50px;
    +    padding:3px;
    +    background:#000;
    +    background-color:rgba(0,0,0,0.25);
    +    margin:0px;
    +    box-sizing:border-box;
    +    transition:all 0.3s;
    +    -webkit-transition:all 0.3s;
    +    border-radius:50%;
    +  }
    +
    +.metis .tp-bullet-image {
    +
    +   border-radius:50%;
    +   display:block;
    +   box-sizing:border-box;
    +   position:relative;
    +    -webkit-box-shadow: inset 5px 5px 10px 0px rgba(0,0,0,0.25);
    +  -moz-box-shadow: inset 5px 5px 10px 0px rgba(0,0,0,0.25);
    +  box-shadow: inset 5px 5px 10px 0px rgba(0,0,0,0.25);
    +  width:44px;
    +  height:44px;
    +  background-size:cover;
    +  background-position:center center;
    + }
    +.metis .tp-bullet-title {
    +     position:absolute;
    +	 bottom:65px;
    +     display:inline-block;
    +     left:50%;
    +     background:#000;
    +     background:rgba(0,0,0,0.75);
    +     color:#fff;
    +     padding:10px 30px;
    +     border-radius:4px;
    +	 -webkit-border-radius:4px;
    +     opacity:0;
    +      transition:all 0.3s;
    +    -webkit-transition:all 0.3s;
    +    transform: translateZ(0.001px) translateX(-50%) translateY(14px);
    +    transform-origin:50% 100%;
    +    -webkit-transform: translateZ(0.001px) translateX(-50%) translateY(14px);
    +    -webkit-transform-origin:50% 100%;
    +    opacity:0;
    +    white-space:nowrap;
    + }
    +
    +.metis .tp-bullet:hover .tp-bullet-title {
    +  	 transform:rotateX(0deg) translateX(-50%);
    +    -webkit-transform:rotateX(0deg) translateX(-50%);
    +    opacity:1;
    +}
    +
    +.metis .tp-bullet.selected,
    +.metis .tp-bullet:hover  {
    +
    +   background: rgba(255,255,255,1);
    +  background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(255,255,255,1)), color-stop(100%, rgba(119,119,119,1)));
    +  background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: -o-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  background: linear-gradient(to bottom, rgba(255,255,255,1) 0%, rgba(119,119,119,1) 100%);
    +  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#ffffff", endColorstr="#777777", GradientType=0 );
    +
    +      }
    +.metis .tp-bullet-title:after {
    +        content:" ";
    +        position:absolute;
    +        left:50%;
    +        margin-left:-8px;
    +        width: 0;
    +		height: 0;
    +		border-style: solid;
    +		border-width: 8px 8px 0 8px;
    +		border-color: rgba(0,0,0,0.75) transparent transparent transparent;
    +        bottom:-8px;
    +   }
    +
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + PERSEPHONE SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +.persephone.tparrows {
    +	cursor:pointer;
    +	background:#aaa;
    +	background:rgba(200,200,200,0.5);
    +	width:40px;
    +	height:40px;
    +	position:absolute;
    +	display:block;
    +	z-index:100;
    +  border:1px solid #f5f5f5;
    +}
    +.persephone.tparrows:hover {
    +	background:#333;
    +}
    +.persephone.tparrows:before {
    +	font-family: "revicons";
    +	font-size:15px;
    +	color:#fff;
    +	display:block;
    +	line-height: 40px;
    +	text-align: center;
    +}
    +.persephone.tparrows.tp-leftarrow:before {
    +	content: "\e824";
    +}
    +.persephone.tparrows.tp-rightarrow:before {
    +	content: "\e825";
    +}
    +
    +
    +
    +/* BULLETS */
    +.persephone.tp-bullets {
    +}
    +.persephone.tp-bullets:before {
    +	content:" ";
    +	position:absolute;
    +	width:100%;
    +	height:100%;
    +	background:#transparent;
    +	padding:10px;
    +	margin-left:-10px;margin-top:-10px;
    +	box-sizing:content-box;
    +}
    +.persephone .tp-bullet {
    +	width:12px;
    +	height:12px;
    +	position:absolute;
    +	background:#aaa;
    +	border:1px solid #e5e5e5;
    +	cursor: pointer;
    +	box-sizing:content-box;
    +}
    +.persephone .tp-bullet:hover,
    +.persephone .tp-bullet.selected {
    +	background:#222;
    +}
    +.persephone .tp-bullet-image {
    +}
    +.persephone .tp-bullet-title {
    +}
    +
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + URANUS SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +.uranus.tparrows {
    +  width:50px;
    +  height:50px;
    +  background:transparent;
    + }
    + .uranus.tparrows:before {
    + width:50px;
    + height:50px;
    + line-height:50px;
    + font-size:40px;
    + transition:all 0.3s;
    +-webkit-transition:all 0.3s;
    + }
    +
    +  .uranus.tparrows:hover:before {
    +    opacity:0.75;
    +  }
    +
    +/* BULLETS */
    +.uranus .tp-bullet{
    +	border-radius: 50%;
    +  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0);
    +  -webkit-transition: box-shadow 0.3s ease;
    +  transition: box-shadow 0.3s ease;
    +  background:transparent;
    +}
    +.uranus .tp-bullet.selected,
    +.uranus .tp-bullet:hover {
    +  box-shadow: 0 0 0 2px #FFF;
    +  border:none;
    +  border-radius: 50%;
    +
    +   background:transparent;
    +}
    +
    +
    +
    +.uranus .tp-bullet-inner {
    +  background-color: rgba(255, 255, 255, 0.7);
    +  -webkit-transition: background-color 0.3s ease, -webkit-transform 0.3s ease;
    +  transition: background-color 0.3s ease, transform 0.3s ease;
    +  top: 0;
    +  left: 0;
    +  width: 100%;
    +  height: 100%;
    +  outline: none;
    +  border-radius: 50%;
    +  background-color: #FFF;
    +  background-color: rgba(255, 255, 255, 0.3);
    +  text-indent: -999em;
    +  cursor: pointer;
    +  position: absolute;
    +}
    +
    +.uranus .tp-bullet.selected .tp-bullet-inner,
    +.uranus .tp-bullet:hover .tp-bullet-inner{
    + transform: scale(0.4);
    + -webkit-transform: scale(0.4);
    + background-color:#fff;
    +}
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + ZEUS SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +/* ARROWS */
    +.zeus.tparrows {
    +  cursor:pointer;
    +  min-width:70px;
    +  min-height:70px;
    +  position:absolute;
    +  display:block;
    +  z-index:100;
    +  border-radius:35px;
    +  overflow:hidden;
    +  background:rgba(0,0,0,0.10);
    +}
    +
    +.zeus.tparrows:before {
    +  font-family: "revicons";
    +  font-size:20px;
    +  color:#fff;
    +  display:block;
    +  line-height: 70px;
    +  text-align: center;
    +  z-index:2;
    +  position:relative;
    +}
    +.zeus.tparrows.tp-leftarrow:before {
    +  content: "\e824";
    +}
    +.zeus.tparrows.tp-rightarrow:before {
    +  content: "\e825";
    +}
    +
    +.zeus .tp-title-wrap {
    +  background:#000;
    +  background:rgba(0,0,0,0.5);
    +  width:100%;
    +  height:100%;
    +  top:0px;
    +  left:0px;
    +  position:absolute;
    +  opacity:0;
    +  transform:scale(0);
    +  -webkit-transform:scale(0);
    +   transition: all 0.3s;
    +  -webkit-transition:all 0.3s;
    +  -moz-transition:all 0.3s;
    +   border-radius:50%;
    + }
    +.zeus .tp-arr-imgholder {
    +  width:100%;
    +  height:100%;
    +  position:absolute;
    +  top:0px;
    +  left:0px;
    +  background-position:center center;
    +  background-size:cover;
    +  border-radius:50%;
    +  transform:translateX(-100%);
    +  -webkit-transform:translateX(-100%);
    +   transition: all 0.3s;
    +  -webkit-transition:all 0.3s;
    +  -moz-transition:all 0.3s;
    +
    + }
    +.zeus.tp-rightarrow .tp-arr-imgholder {
    +    transform:translateX(100%);
    +  -webkit-transform:translateX(100%);
    +      }
    +.zeus.tparrows:hover .tp-arr-imgholder {
    +  transform:translateX(0);
    +  -webkit-transform:translateX(0);
    +  opacity:1;
    +}
    +
    +.zeus.tparrows:hover .tp-title-wrap {
    +  transform:scale(1);
    +  -webkit-transform:scale(1);
    +  opacity:1;
    +}
    +
    +
    +/* BULLETS */
    +.zeus .tp-bullet {
    +     box-sizing:content-box; -webkit-box-sizing:content-box; border-radius:50%;
    +      background-color: rgba(0, 0, 0, 0);
    +      -webkit-transition: opacity 0.3s ease;
    +      transition: opacity 0.3s ease;
    +	  width:13px;height:13px;
    +	  border:2px solid #fff;
    + }
    +.zeus .tp-bullet:after {
    +  content: "";
    +  position: absolute;
    +  width: 100%;
    +  height: 100%;
    +  left: 0;
    +  border-radius: 50%;
    +  background-color: #FFF;
    +  -webkit-transform: scale(0);
    +  transform: scale(0);
    +  -webkit-transform-origin: 50% 50%;
    +  transform-origin: 50% 50%;
    +  -webkit-transition: -webkit-transform 0.3s ease;
    +  transition: transform 0.3s ease;
    +}
    +.zeus .tp-bullet:hover:after,
    +.zeus .tp-bullet.selected:after{
    +    -webkit-transform: scale(1.2);
    +  transform: scale(1.2);
    +}
    +
    + .zeus .tp-bullet-image,
    + .zeus .tp-bullet-imageoverlay{
    +        width:135px;
    +        height:60px;
    +        position:absolute;
    +        background:#000;
    +        background:rgba(0,0,0,0.5);
    +        bottom:25px;
    +        left:50%;
    +        margin-left:-65px;
    +        box-sizing:border-box;
    +        background-size:cover;
    +        background-position:center center;
    +        visibility:hidden;
    +        opacity:0;
    +         -webkit-backface-visibility: hidden;
    +      	backface-visibility: hidden;
    +        -webkit-transform-origin: 50% 50%;
    +		transform-origin: 50% 50%;
    +  		-webkit-transition: all 0.3s ease;
    +  		transition: all 0.3s ease;
    +        border-radius:4px;
    +
    +}
    +
    +
    +.zeus .tp-bullet-title,
    +.zeus .tp-bullet-imageoverlay {
    +        z-index:2;
    +        -webkit-transition: all 0.5s ease;
    +	  	transition: all 0.5s ease;
    +}
    +.zeus .tp-bullet-title {
    +        color:#fff;
    +        text-align:center;
    +        line-height:15px;
    +        font-size:13px;
    +        font-weight:600;
    +        z-index:3;
    +         visibility:hidden;
    +        opacity:0;
    +         -webkit-backface-visibility: hidden;
    +      	backface-visibility: hidden;
    +        -webkit-transform-origin: 50% 50%;
    +		transform-origin: 50% 50%;
    +  		-webkit-transition: all 0.3s ease;
    +  		transition: all 0.3s ease;
    +        position:absolute;
    +        bottom:45px;
    +        width:135px;
    +    	vertical-align:middle;
    +        left:-57px;
    +}
    +
    +.zeus .tp-bullet:hover .tp-bullet-title,
    +.zeus .tp-bullet:hover .tp-bullet-image,
    +.zeus .tp-bullet:hover .tp-bullet-imageoverlay{
    +      opacity:1;
    +      visibility:visible;
    +	  -webkit-transform:translateY(0px);
    +      transform:translateY(0px);
    +    }
    +
    +/* THUMBS */
    +.zeus .tp-thumb {
    +opacity:1
    +}
    +
    +.zeus .tp-thumb-over {
    +  background:#000;
    +  background:rgba(0,0,0,0.25);
    +  width:100%;
    +  height:100%;
    +  position:absolute;
    +  top:0px;
    +  left:0px;
    +  z-index:1;
    +  -webkit-transition:all 0.3s;
    +  transition:all 0.3s;
    +}
    +
    +.zeus .tp-thumb-more:before {
    +  font-family: "revicons";
    +  font-size:12px;
    +  color:#aaa;
    +  color:rgba(255,255,255,0.75);
    +  display:block;
    +  line-height: 12px;
    +  text-align: left;
    +  z-index:2;
    +  position:absolute;
    +  top:20px;
    +  right:20px;
    +  z-index:2;
    +}
    +.zeus .tp-thumb-more:before {
    +  content: "\e825";
    +}
    +
    +.zeus .tp-thumb-title {
    +  font-family:"Raleway";
    +  letter-spacing:1px;
    +  font-size:12px;
    +  color:#fff;
    +  display:block;
    +  line-height: 15px;
    +  text-align: left;
    +  z-index:2;
    +  position:absolute;
    +  top:0px;
    +  left:0px;
    +  z-index:2;
    +  padding:20px 35px 20px 20px;
    +  width:100%;
    +  height:100%;
    +  box-sizing:border-box;
    +  transition:all 0.3s;
    +  -webkit-transition:all 0.3s;
    +  font-weight:500;
    +}
    +
    +.zeus .tp-thumb.selected .tp-thumb-more:before,
    +.zeus .tp-thumb:hover .tp-thumb-more:before {
    + color:#aaa;
    +
    +}
    +
    +.zeus .tp-thumb.selected .tp-thumb-over,
    +.zeus .tp-thumb:hover .tp-thumb-over {
    + background:#000;
    +}
    +.zeus .tp-thumb.selected .tp-thumb-title,
    +.zeus .tp-thumb:hover .tp-thumb-title {
    +  color:#fff;
    +
    +}
    +
    +
    +/* TABS */
    +.zeus .tp-tab {
    +  opacity:1;
    +  box-sizing:border-box;
    +}
    +
    +.zeus .tp-tab-title {
    +display: block;
    +text-align: center;
    +background: rgba(0,0,0,0.25);
    +font-family: "Roboto Slab", serif;
    +font-weight: 700;
    +font-size: 13px;
    +line-height: 13px;
    +color: #fff;
    +padding: 9px 10px; }
    +
    +.zeus .tp-tab:hover .tp-tab-title,
    +.zeus .tp-tab.selected .tp-tab-title {
    + color: #000;
    +  background:rgba(255,255,255,1);
    +}
    +
    +
    +
    +/*-----------------------------------------------------------------------------
    +
    +- Revolution Slider 5.0 Navigatin Skin Style  -
    +
    + ZEUS SKIN
    +
    +author:  ThemePunch
    +email:      info@themepunch.com
    +website:    http://www.themepunch.com
    +-----------------------------------------------------------------------------*/
    +
    +
    +.post-tabs .tp-thumb {
    +opacity:1
    +}
    +
    +.post-tabs .tp-thumb-over {
    +  background:#252525;
    +  width:100%;
    +  height:100%;
    +  position:absolute;
    +  top:0px;
    +  left:0px;
    +  z-index:1;
    +  -webkit-transition:all 0.3s;
    +  transition:all 0.3s;
    +}
    +
    +.post-tabs .tp-thumb-more:before {
    +  font-family: "revicons";
    +  font-size:12px;
    +  color:#aaa;
    +  color:rgba(255,255,255,0.75);
    +  display:block;
    +  line-height: 12px;
    +  text-align: left;
    +  z-index:2;
    +  position:absolute;
    +  top:15px;
    +  right:15px;
    +  z-index:2;
    +}
    +.post-tabs .tp-thumb-more:before {
    +  content: "\e825";
    +}
    +
    +.post-tabs .tp-thumb-title {
    +  font-family:"raleway";
    +  letter-spacing:1px;
    +  font-size:12px;
    +  color:#fff;
    +  display:block;
    +  line-height: 15px;
    +  text-align: left;
    +  z-index:2;
    +  position:absolute;
    +  top:0px;
    +  left:0px;
    +  z-index:2;
    +  padding:15px 30px 15px 15px;
    +  width:100%;
    +  height:100%;
    +  box-sizing:border-box;
    +  transition:all 0.3s;
    +  -webkit-transition:all 0.3s;
    +  font-weight:500;
    +}
    +
    +.post-tabs .tp-thumb.selected .tp-thumb-more:before,
    +.post-tabs .tp-thumb:hover .tp-thumb-more:before {
    + color:#aaa;
    +
    +}
    +
    +.post-tabs .tp-thumb.selected .tp-thumb-over,
    +.post-tabs .tp-thumb:hover .tp-thumb-over {
    + background:#fff;
    +}
    +.post-tabs .tp-thumb.selected .tp-thumb-title,
    +.post-tabs .tp-thumb:hover .tp-thumb-title {
    +  color:#000;
    +
    +}
    +
    +.feature-img:hover figure a,.full-heading.main-bg:before,.accordion.style-1 .panel>.panel-heading h4 a:not(.collapsed):before,.accordion.style-3 .panel>.panel-heading h4 a:not(.collapsed),.black-bg:hover>a,.blog-posts .post-item:hover .post-content,.box-5:hover,.bquote-2,.comment-list .comment-content h6,.dark-bg:not(.top-head):hover a,.darker-bg:hover a,.diamond.colored:after,.diamonds:hover,.diamonds:hover a,.feature-img2:hover figure a,.filter-by ul li:after,.filter-by.style-2 ul li.active a,.filter-by.style-3 ul li.active a,.filter-by:not(.style-2) ul li.active a,.filter-by:not(.style-3) ul li.active a,.flex-control-paging li a.flex-active,.footer-3 .footer-top .social-list li a:hover,.footer-middle h3:after,.head-4:after,.head-5:after,.head-8:before,.header-9 .top-nav>ul>li.mega-menu:hover>span:after,.header-9 .top-nav>ul>li.mega-menu:hover>span:before,.header-9 .top-nav>ul>li:not(.mega-menu):hover:after,.header-9 .top-nav>ul>li:not(.mega-menu):hover:before,.heading-full [class*=head-]:after,.heading-full [class*=head-]:before,.icon-box .filled i:hover,.icon-box.box-1 .outlined i:after,.icon-box.box-1.bordered .inner:after,.icon-box.box-1.bordered .inner:before,.icon-box.box-1.bordered:after,.icon-box.box-1.bordered:before,.icon-box.gry-border-1:hover,.icon-box.gry-border-2:hover h3,.icon-box:hover .filled i,.icons-style-1:hover .btn,.item-img .product-buttons a:hover,.list-grid a.selected,.login-box-lg .login-inner:after,.main-bg,.main-heading .heading-separator:after,.minimal-socials li a:hover,.modal-header,.nav-border-bottom li.mega-menu .inner-mega:after,.nav-border-bottom>ul>li:after,.nav-border-left li.mega-menu .inner-mega:after,.nav-border-left>ul>li:after,.nav-border-right li.mega-menu .inner-mega:after,.nav-border-right>ul>li:after,.nav-border-top li.mega-menu .inner-mega:after,.nav-border-top>ul>li:after,.on-sale,.owl-theme .owl-controls .owl-page.active span,.owl-theme .owl-controls.clickable .owl-page:hover span,.pagination ul li.selected,.pagination.bar-1 ul li a:hover,.pagination.bar-3 ul:after,.pagination.bottom-border ul li:hover,.portfolio-item .fav:hover,.portfolio-item .link:hover,.portfolio-item .zoom:hover,.post-icon,.post-item:hover .bottom_tools a,.pricing-tbl.style-1.selected .btn,.pricing-tbl.style-1:hover .btn,.pricing-tbl.style-2.selected .btn,.pricing-tbl.style-2.selected h3,.pricing-tbl.style-2:hover .btn,.pricing-tbl.style-2:hover h3,.pricing-tbl.style-3.selected,.pricing-tbl.style-3:hover,.pricing-tbl.style-4.selected .btn,.pricing-tbl.style-4.selected .plan-head,.pricing-tbl.style-4.selected .plan-head:after,.pricing-tbl.style-4.selected .plan-head:before,.pricing-tbl.style-4:hover .btn,.pricing-tbl.style-4:hover .plan-head,.pricing-tbl.style-4:hover .plan-head:after,.pricing-tbl.style-4:hover .plan-head:before,.progress-bars .bar .bar-in,.saf-tags.hover-effect li:hover,.side-one li a,.sidebar_widgets .widget-head:after,.sidebar_widgets li.widget:after,.sidebar_widgets li.widget:before,.slick-dots li.slick-active button,.social-list li:not(.main-bg) a:hover,.tabs-style-ballon .nav-tabs>li.active>a,.tabs-style-bg .nav-tabs>li.active a:after,.tabs-style-bottomline li.active:after,.tabs-style-lg.style-1 .nav-tabs>li.active>a,.team-box.box-1:hover .team-details,.team-box.box-2:hover,.team-box.box-2:hover .team-pos,.timeline .post-item .timeline_date .inner_date:before,.timeline .post-item .timeline_date:before,.top-bar .social-list li a:hover,.top-bar.main-bg li.dropdown ul,.top-head.boxed-transparent .bot-line,.top-head.boxed-transparent .logo:after,.top-head.boxed-transparent .logo:before,.top-head.header-2 .top-cart>a:before,.top-head.header-2 .top-nav>ul>li.selected>a,.top-head.header-2 .top-nav>ul>li.selected>span>a,.top-head.header-2 .top-nav>ul>li:hover>a,.top-head.header-2 .top-nav>ul>li:hover>span>a,.top-head.header-2 .top-search>a:before,.top-head.header-5 .top-nav>ul>li .inner-mega:before,.top-head.header-5 .top-nav>ul>li:before,.top-head.header-6 .top-nav>ul>li .inner-mega:before,.top-head.header-6 .top-nav>ul>li.mega-menu:hover>a,.top-head.header-6 .top-nav>ul>li:hover:before,.top-head.header-6 .top-nav>ul>li:hover>a:before,.top-head.header-6 .top-nav>ul>li>span>a:before,.top-head.header-8 .top-nav>ul>li.selected>a,.top-head.header-8 .top-nav>ul>li.selected>span>a,.top-head.header-8 .top-nav>ul>li:hover>a,.top-head.header-8 .top-nav>ul>li:hover>span>a,.top-nav.colored-submenu ul li ul,.top-shop-links a:hover,.tri-line:before,footer .tags li a:hover,footer .tags.hover-effect a:after,input[type=radio]:checked+label>span>span,li.outlined.rectangle:hover{
    +	background-color:#bf3404;
    +	color:#fff;
    +	text-shadow:1px 1px 1px rgba(0,0,0,.15)
    +}
    +.inner-magazine .blog-posts .post-item:hover .post-content,.tp-caption.Photography-Menuitem:hover, .p-style5 figure .icon-links a:hover:before,.Photography-Menuitem:hover{
    +	background-color:#bf3404 !important;
    +}
    +.accordion.style-1 .panel>.panel-heading h4 a:not(.collapsed),.accordion.style-4 .panel>.panel-heading h4 a:not(.collapsed),.big-heart:before,.blog-posts .post-item:hover .post-content .post-icon,.btn.main-border.btn-outlined,.divider i.to-top,.footer-bottom .footer-menu li a:hover,.footer-menu a:hover,.icon-box.box-1:hover .transparent i,.icon-box.box-1:hover h3,.icon-box.gry-border-1:hover i,.icons-style-1:hover .heading,.icons-style-1:hover i.animat-icon,.icons-style-2:hover .heading,.item-price,.main-color,.main-color a,.menu-widget li a:hover,.nav-animate>ul>li>a span:after,.nav-animate>ul>li>span>a span:after,.post-item .post-info h2 a,.pricing-tbl.style-1.selected .price-lg,.pricing-tbl.style-1.selected h3,.pricing-tbl.style-1:hover .price-lg,.pricing-tbl.style-1:hover h3,.pricing-tbl.style-2.selected .price-lg,.pricing-tbl.style-2:hover .price-lg,.pricing-tbl.style-4.selected .plan-head i,.pricing-tbl.style-4:hover .plan-head i,.side-nav>ul>li.hasChildren.selected:after,.side-nav>ul>li.hasChildren:hover:after,.side-nav>ul>li.selected>a,.side-nav>ul>li:hover>a,.social-list li.main-color a,.tabs nav ul li.active a,.testimonials-2 p:after,.testimonials-2 p:before,.timeline .post-item:nth-child(even) .timeline_date .day,.timeline .post-item:nth-child(even) .timeline_date .month,.top-bar ul li i,.top-head .top-nav>ul>li.selected>a,.top-head .top-nav>ul>li.selected>span>a,.top-head.dark-transparent .top-nav>ul>li:hover>a,.top-head.transparent .top-nav>ul>li.hasChildren:hover>a:after,.top-head.transparent .top-nav>ul>li:hover>a,.top-nav ul li a span:before,.top-nav ul li.selected>a,.top-nav ul li.selected>span>a,.top-nav ul li:hover>a,.top-nav>ul>li.hasChildren:hover>a:after,.top-nav>ul>li.hasChildren:hover>span>a:after,.tweets-widget .tweets_txt span,.widget-tweets a,.widget.custom-menu-widget ul li.selected:before,a:hover{
    +	color:#bf3404
    +}
    +.close-modal.main-color,.new-nav>ul>li.selected>a,.one-page .current a{
    +	color:#bf3404 !important;
    +}
    +.accordion .panel.main-bg,.btn.main-bg,.contact-widget .social-list .diamond.outlined a:hover:after,.feature-img:hover figure:before,.flex-control-paging li a.flex-active,.heading-full [class*=head-],.icon-box.gry-border-2:hover,.icons-style-2 i,.img-icon,.main-border,.owl-theme .owl-controls .owl-page.active span,.owl-theme .owl-controls.clickable .owl-page:hover span,.pricing-tbl.selected,.pricing-tbl.style-4.no-margin.selected,.pricing-tbl.style-4.selected .plan-head:before,.pricing-tbl.style-4:hover .plan-head:before,.pricing-tbl:hover,.testimonials-2 .testimonials-img,.tri-line,footer .tags li:hover,footer .tags.hover-effect a:hover,li.outlined.circle:hover,li.outlined.rectangle:hover{
    +	border-color:#bf3404!important
    +}
    +.accordion.style-1 .panel>.panel-heading h4 a:not(.collapsed),.accordion.style-4 .panel>.panel-heading h4 a:not(.collapsed),.bquote-3,.filter-by,.head-3 b:before,.head-4 b:before,.icons-style-2:hover .heading,.inner-menu ul ul,.p-style4 .name-holder,.page-title.title-5 h3,.pagination.bottom-border ul li,.pricing-tbl.style-2:hover h3,.sidebar_widgets li.widget,.tabs-style-ballon .tab-content .tab-pane,.testimonials-3 .testimonials-bg,.toolsBar,.top-bar li ul,.top-search .search-box{
    +	border-bottom-color:#bf3404
    +}
    +.tabs-style-ballon.vertical .tab-content .tab-pane{
    +	border-right-color:#bf3404
    +}
    +.head-3 b:after,.pricing-tbl.style-2:hover h3:before,.pricing-tbl.style-2:hover h3:after,.pricing-tbl.style-2.selected h3:after,.cart-box,.tabs-style-default .nav-tabs>li.active>a{
    +	border-top-color:#bf3404
    +}
    +.bquote-3 span.bottom,.top-nav ul ul ul:before,.icon-box-small i.left-angle.main-bg b:before{
    +	border-color:transparent #bf3404 transparent transparent
    +}
    +.icon-box-small i.right-angle.main-bg b:before,.head-triangle:after,.right-arrow.main-bg:after{
    +	border-color:transparent transparent transparent #bf3404
    +}
    +.bquote-3 .bottom:after,.bquote-4 span.main-bg:after,.tabs-style-bottomline li.active:before,#to-top:before{
    +	border-color:transparent transparent #bf3404
    +}
    +.accordion.style-4 .panel>.panel-heading h4 a:not(.collapsed):before,.filter-by.style-2 ul li.active:after,.filter-by.style-3 ul li.active:after,.heading-full-color .tri-angle-down,.tabs-style-ballon li.active a:after,.tabs-style-lg.style-1 .nav-tabs>li.active>a:before,.testimonials-3 .testimonials-bg:after{
    +	border-color:#bf3404 transparent transparent
    +}
    +.tabs-style-bottomline li:last-child::after{
    +	border-color:transparent #bf3404 transparent
    +}
    +.section-full-bg.main-bg .tri,.fun-icon.main-bg.lg-icon:after,.filter-by ul li.active a:after{
    +	border-color:#bf3404 transparent transparent transparent
    +}
    +.icon-box .filled i:after{
    +	box-shadow:0 0 0 1px #bf3404
    +}
    +.btn.main-bg.btn-3d{
    +	-webkit-box-shadow:0 5px 0 #bf3404;box-shadow:0 4px 0 #bf3404
    +}
    +.inner-menu ul>li.selected>a,.inner-menu ul>li:hover>a,.post-item:hover .bottom_tools,.testimonials-1 .testimonials-bg:after,.testimonials-1 .testimonials-bg:before,.top-bar.main-bg .social-list li a:hover,.top-head .full.main-bg .top-nav>ul>li:hover,a.main-bg:hover{
    +	background-color:#a11600
    +}
    +.section-full-bg.alter-bg:before,.section-full-bg.alter-bg:after,.alter-bg,.btn.main-bg:hover,.side-nav>ul>li>ul li.selected,.side-nav>ul>li>ul li:hover,.social-list li.diamond:hover,.team-box .team-details .social-list li a:hover,.team-box.box-2:hover .team-name,.top-bar ul>li.dropdown.open>a,.top-bar ul>li>a:hover,.top-head .full.main-bg .top-nav>ul>li.selected{
    +	background-color:#a11600;color:#fff
    +}
    +.lg-box:hover,.top-head.header-8 .top-nav>ul>li.selected>a,.top-head.header-8 .top-nav>ul>li.selected>span>a,.top-head.header-8 .top-nav>ul>li:hover>a,.top-head.header-8 .top-nav>ul>li:hover>span>a,.top-nav ul{
    +	border-color:#a11600
    +}
    +.testimonials-1 .testimonials-img:before{
    +	border-color:transparent transparent transparent #a11600
    +}
    +.testimonials-1 .testimonials-img:after{
    +	border-color:transparent #a11600 transparent transparent
    +}
    +
    +/*body {
    +  font-family: ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif;
    +  padding-top: 50px;
    +}
    +
    +.starter-template {
    +  padding: 40px 15px;
    +  text-align: center;
    +}
    +
    +.navbar-logo {
    +  background: url(../img/Octamis_Logo_no_bg.png);
    +  background-size: 290px 60px;
    +  height: 60px;
    +  width: 290px;
    +  margin-right: 100px;
    +  margin-top: 10px;
    +  margin-bottom: 10px;
    +}
    +
    +.nav-pills-margins {
    +  margin-top: 15px;
    +}
    +
    +.nav-pills > li.active > a, .nav-pills > li.active > a:focus, .nav-pills > li.active > a:hover {
    +    background-color: #f44336;
    +}
    +
    +.nav-pills > li > a, .nav-pills > li > a:focus, .nav-pills > li > a:hover {
    +    color: #f44336;
    +}
    +
    +.nav-pills > li {
    +    margin-right: 20px;
    +}*/
    +
    +.ms-amber-color {
    +  color: #ffc107;
    +}
    +
    +.ms-red-color {
    +  color: #f44336;
    +}
    +
    +.ms-blue-color {
    +  color: #2e3fa2;
    +}
    +
    +.splunk-color {
    +  color: #43D220;
    +}
    +
    +.ms-txt-italic{
    +  font-style: italic;
    +}
    +
    +.captcha {
    +  height: 60px;
    +}
    +
    +.captcha-div-ms {
    +  width: 100%;
    +}
    +
    +.ms-background-gradient {
    +  background: rgba(169,3,41,1);
    +  background: -moz-linear-gradient(left, rgba(169,3,41,1) 0%, rgba(143,2,34,1) 44%, rgba(109,0,25,1) 100%);
    +  background: -webkit-gradient(left top, right top, color-stop(0%, rgba(169,3,41,1)), color-stop(44%, rgba(143,2,34,1)), color-stop(100%, rgba(109,0,25,1)));
    +  background: -webkit-linear-gradient(left, rgba(169,3,41,1) 0%, rgba(143,2,34,1) 44%, rgba(109,0,25,1) 100%);
    +  background: -o-linear-gradient(left, rgba(169,3,41,1) 0%, rgba(143,2,34,1) 44%, rgba(109,0,25,1) 100%);
    +  background: -ms-linear-gradient(left, rgba(169,3,41,1) 0%, rgba(143,2,34,1) 44%, rgba(109,0,25,1) 100%);
    +  background: linear-gradient(to right, rgba(169,3,41,1) 0%, rgba(143,2,34,1) 44%, rgba(109,0,25,1) 100%);
    +  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a90329', endColorstr='#6d0019', GradientType=1 );
    +}
    +
    +.ms-amber-bg {
    +  background-color: #ffc107;
    +}
    +
    +.ms-red-bg {
    +  background-color: #b71c1c;
    +}
    +
    +.ms-grey-bg {
    +  background-color: #eeeeee;
    +}
    +
    +/*.testimonials-bg p .main-color {
    +  text-shadow: 1px 1px ;
    +}*/
    +
    +.tp-caption.NotGeneric-Title,.NotGeneric-Title {
    +  font-family: Ubuntu;
    +}
    +
    +.full-heading:before {
    +  background-color: #b71c1c;
    +  color: white;
    +}
    +
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/panel_decoration.css b/deployment-apps/metricator-for-nmon/appserver/static/panel_decoration.css
    new file mode 100644
    index 0000000..e825f0d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/panel_decoration.css
    @@ -0,0 +1,60 @@
    +
    +[id^=cpu] h2.panel-title {
    +	background: url('icons/grey_theme/cpu.png') no-repeat center left;
    +	background-size: 30px 30px;
    +    padding: 7px 55px 7px 38px !important;
    +}
    +
    +[id^=mem] h2.panel-title {
    +	background: url('icons/grey_theme/memory.png') no-repeat center left;
    +	background-size: 30px 30px;
    +    padding: 7px 55px 7px 38px !important;
    +}
    +
    +[id^=disk] h2.panel-title {
    +	background: url('icons/grey_theme/drive.png') no-repeat center left;
    +	background-size: 30px 30px;
    +    padding: 7px 55px 7px 38px !important;
    +}
    +
    +[id^=process] h2.panel-title {
    +	background: url('icons/grey_theme/process.png') no-repeat center left;
    +	background-size: 30px 30px;
    +    padding: 7px 55px 7px 38px !important;
    +}
    +
    +[id^=network] h2.panel-title {
    +	background: url('icons/grey_theme/network.png') no-repeat center left;
    +	background-size: 30px 30px;
    +    padding: 7px 55px 7px 38px !important;
    +}
    +
    +[id^=fs] h2.panel-title {
    +	background: url('icons/grey_theme/filesystem.png') no-repeat center left;
    +	background-size: 30px 30px;
    +    padding: 7px 55px 7px 38px !important;
    +}
    +
    +[id^=settings] h2.panel-title {
    +	background: url('icons/grey_theme/settings.png') no-repeat center left;
    +	background-size: 30px 30px;
    +    padding: 7px 55px 7px 38px !important;
    +}
    +
    +[id^=info] h2.panel-title {
    +	background: url('icons/grey_theme/info.png') no-repeat center left;
    +	background-size: 30px 30px;
    +    padding: 7px 55px 7px 38px !important;
    +}
    +
    +[id^=predict] h2.panel-title {
    +	background: url('icons/grey_theme/predict.png') no-repeat center left;
    +	background-size: 30px 30px;
    +    padding: 7px 55px 7px 38px !important;
    +}
    +
    +[id^=cost] h2.panel-title {
    +	background: url('icons/grey_theme/dollar.png') no-repeat center left;
    +	background-size: 30px 30px;
    +    padding: 7px 55px 7px 38px !important;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/panel_resize.js b/deployment-apps/metricator-for-nmon/appserver/static/panel_resize.js
    new file mode 100644
    index 0000000..079db5b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/panel_resize.js
    @@ -0,0 +1,25 @@
    +/* This will fix Splunk 6.3.x from failing to resize html panels
    +Special thanks to the Great VP. F.toulouse !
    + */
    +
    +require(['splunkjs/mvc/simplexml/ready!'], function(){
    +    require(['splunkjs/ready!'], function(){
    +
    +        // Search for rows containing at less 3 panels
    +        $('body .dashboard-row').each(function(row){
    +            var $row = $(this);
    +
    +            // Found one -> adjust panels height to highest one
    +            if( $row.find('.dashboard-cell').length > 2){
    +
    +                var max_height = Math.max.apply(null, $row.find('.dashboard-cell .dashboard-panel').map(function(){
    +                    return $(this).height();
    +                }).get());
    +
    +                $row.find('.dashboard-cell .dashboard-panel').map(function(){
    +                    $(this).css('height', max_height+'px');
    +                });
    +            }
    +        });
    +    });
    +});
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/safecenter.css b/deployment-apps/metricator-for-nmon/appserver/static/safecenter.css
    new file mode 100644
    index 0000000..af840ac
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/safecenter.css
    @@ -0,0 +1,66 @@
    +/* Custom title style of simple xml views */
    +
    +h1 {
    +  /* color: lightslategrey; */
    +}
    +
    +.safecenter h1 {
    +  font-size: 30px;
    +  font-weight: bold;
    +  /* color: #ffffff; */
    +  text-align: center;
    +  position: relative;
    +}
    +
    +/*Back Ground color for Category Panel */
    +
    +div#cpu {
    +  background-color: #444444;
    +}
    +
    +div#mem {
    +  background-color: #444444;
    +}
    +
    +div#swap {
    +  background-color: #444444;
    +}
    +
    +div#filesystem {
    +  background-color: #444444;
    +}
    +
    +/* Force margin for single block color */
    +.splunk-single {
    +  margin-left: 1px;
    +  margin-right: 1px;
    +}
    +
    +/* Fix single label trouble with Splunk 6.3.0 */
    +
    +.before-label {
    +  font-size: medium !important;
    +}
    +
    +.after-label {
    +  font-size: medium !important;
    +}
    +
    +.single-result-unit {
    +  font-size: medium !important;
    +}
    +
    +/* Fix link input object align */
    +.input-linklist {
    +  display: inline !important;
    +}
    +
    +/* Fix link input object align for Splunk 6.5 */
    +.input-link {
    +  display: inline !important;
    +}
    +
    +/* Increase the default max-width for links */
    +.btn-pill {
    +  max-width: 600px !important;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/screenshot.png b/deployment-apps/metricator-for-nmon/appserver/static/screenshot.png
    new file mode 100644
    index 0000000..453311d
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/screenshot.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/screenshot2.png b/deployment-apps/metricator-for-nmon/appserver/static/screenshot2.png
    new file mode 100644
    index 0000000..ca23ea3
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/screenshot2.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/screenshot3.png b/deployment-apps/metricator-for-nmon/appserver/static/screenshot3.png
    new file mode 100644
    index 0000000..5e1a1df
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/screenshot3.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/screenshot4.png b/deployment-apps/metricator-for-nmon/appserver/static/screenshot4.png
    new file mode 100644
    index 0000000..27e8c6d
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/screenshot4.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/screenshot5.png b/deployment-apps/metricator-for-nmon/appserver/static/screenshot5.png
    new file mode 100644
    index 0000000..5bd44ea
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/screenshot5.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/table_data_bar.css b/deployment-apps/metricator-for-nmon/appserver/static/table_data_bar.css
    new file mode 100644
    index 0000000..2894a7b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/table_data_bar.css
    @@ -0,0 +1,21 @@
    +td.data-bar-cell {
    +    padding: 4px 8px;
    +}
    +
    +td.data-bar-cell .data-bar-wrapper .data-bar {
    +    height: 16px;
    +    min-width: 1px;
    +    background-color: #5479AF;
    +	
    +	font-weight: bold;
    +}
    +
    +.data-bar-over { color: #FFFFFF; }
    +.data-bar-under { color: #000000; }
    +
    +.data-bar-wrapper {
    +	
    +	border-style: solid;
    +	border-width: 1px;
    +}
    +
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/table_data_bar.js b/deployment-apps/metricator-for-nmon/appserver/static/table_data_bar.js
    new file mode 100644
    index 0000000..95b4a01
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/table_data_bar.js
    @@ -0,0 +1,40 @@
    +require([
    +    'jquery',
    +    'underscore',
    +    'splunkjs/mvc',
    +    'views/shared/results_table/renderers/BaseCellRenderer',
    +    'splunkjs/mvc/simplexml/ready!'
    +], function($, _, mvc, BaseCellRenderer) {
    +
    +    var DataBarCellRenderer = BaseCellRenderer.extend({
    +        canRender: function(cell) {
    +            return (cell.field === 'UsedPct');
    +        },
    +        render: function($td, cell) {
    +var pColor="data-bar-under"
    +if(cell.value > 15){ pColor="data-bar-over" }
    +            $td.addClass('data-bar-cell').html(_.template('<div class="data-bar-wrapper"><div class="data-bar <%- pColor %>" style="width:<%- percent %>%">&nbsp;<%- ppp %>%</div></div>', {
    +                percent: Math.min(Math.max(parseFloat(cell.value), 0), 100),
    +ppp: parseFloat(cell.value).toFixed(2),
    +pColor: pColor
    +            }));
    +        }
    +    });
    +
    +    mvc.Components.get('tablebar').getVisualization(function(tableView) {
    +        tableView.table.addCellRenderer(new DataBarCellRenderer());
    +        tableView.table.render();
    +    });
    +
    +    mvc.Components.get('tablebar1').getVisualization(function(tableView) {
    +        tableView.table.addCellRenderer(new DataBarCellRenderer());
    +        tableView.table.render();
    +    });
    +
    +    mvc.Components.get('tablebar2').getVisualization(function(tableView) {
    +        tableView.table.addCellRenderer(new DataBarCellRenderer());
    +        tableView.table.render();
    +    });
    +
    +});
    +
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/table_decorations.css b/deployment-apps/metricator-for-nmon/appserver/static/table_decorations.css
    new file mode 100644
    index 0000000..bc1be8e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/table_decorations.css
    @@ -0,0 +1,81 @@
    +/* Custom Icons */
    +
    +td.icon {
    +    text-align: center;
    +}
    +
    +td.icon i {
    +    font-size: 25px;
    +    text-shadow: 1px 1px #aaa;
    +}
    +
    +td.icon .severe {
    +    color: red;
    +}
    +
    +td.icon .elevated {
    +    color: orangered;
    +}
    +
    +td.icon .low {
    +    color: #006400;
    +}
    +
    +td.icon .arrow_green_decrease_48px {
    +    background-image: url('icons/color_theme/arrow_green_decrease_48px.png') !important;
    +    background-size:20px 20px;
    +}
    +
    +td.icon .arrow_red_increase_48px {
    +    background-image: url('icons/color_theme/arrow_red_increase_48px.png') !important;
    +    background-size:20px 20px;
    +}
    +
    +td.icon .equal-sign-48px {
    +    background-image: url('icons/color_theme/equal-sign-48px.png') !important;
    +    background-size:20px 20px;
    +}
    +
    +td.icon .myicon {
    +    width: 20px;
    +    height: 20px;
    +    margin-left: auto;
    +    margin-right: auto
    +}
    +
    +/* Row Coloring */
    +
    +#highlight tr td {
    +    background-color: #c1ffc3 !important;
    +}
    +
    +#highlight tr.range-elevated td {
    +    background-color: #ffc57a !important;
    +}
    +
    +#highlight tr.range-severe td {
    +    background-color: #d59392 !important;
    +}
    +
    +
    +#highlight .table td {
    +    border-top: 1px solid #fff;
    +}
    +
    +#highlight td.range-severe, td.range-elevated {
    +    font-weight: bold;
    +}
    +
    +.icon-inline i {
    +    font-size: 18px;
    +    margin-left: 5px;
    +}
    +.icon-inline i.icon-alert-circle {
    +    color: #ef392c;
    +}
    +.icon-inline i.icon-alert {
    +    color: #ff9c1a;
    +}
    +.icon-inline i.icon-check {
    +    color: #5fff5e;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/table_icons_rangemap.js b/deployment-apps/metricator-for-nmon/appserver/static/table_icons_rangemap.js
    new file mode 100644
    index 0000000..8d6e84e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/table_icons_rangemap.js
    @@ -0,0 +1,42 @@
    +require([
    +    'underscore',
    +    'jquery',
    +    'splunkjs/mvc',
    +    'splunkjs/mvc/tableview',
    +    'splunkjs/mvc/simplexml/ready!'
    +], function(_, $, mvc, TableView) {
    +
    +    // Translations from rangemap results to CSS class
    +    var ICONS = {
    +        equal: 'equal-sign-48px',
    +        increase: 'arrow_red_increase_48px',
    +        decrease: 'arrow_green_decrease_48px'
    +    };
    +
    +    var RangeMapIconRenderer = TableView.BaseCellRenderer.extend({
    +        canRender: function(cell) {
    +            // Only use the cell renderer for the range field
    +            return cell.field === 'range';
    +        },
    +        render: function($td, cell) {
    +            var icon = 'question';
    +            // Fetch the icon for the value
    +            if (ICONS.hasOwnProperty(cell.value)) {
    +                icon = ICONS[cell.value];
    +            }
    +            // Create the icon element and add it to the table cell
    +            $td.addClass('icon').html(_.template('<div class="myicon <%- icon%> title="<%- range %>"></div>', {
    +                icon: icon,
    +                range: cell.value
    +            }));
    +        }
    +    });
    +
    +    mvc.Components.get('table1').getVisualization(function(tableView){
    +        // Register custom cell renderer
    +        tableView.table.addCellRenderer(new RangeMapIconRenderer());
    +        // Force the table to re-render
    +        tableView.table.render();
    +    });
    +
    +});
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/OS_logos.png b/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/OS_logos.png
    new file mode 100644
    index 0000000..31db7a8
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/OS_logos.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/advanced_dashboards.png b/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/advanced_dashboards.png
    new file mode 100644
    index 0000000..da03995
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/advanced_dashboards.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/main.png b/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/main.png
    new file mode 100644
    index 0000000..e106eba
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/main.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/metrics_showcase.png b/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/metrics_showcase.png
    new file mode 100644
    index 0000000..b833dbc
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/metrics_showcase.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/tco.png b/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/tco.png
    new file mode 100644
    index 0000000..93ab4df
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/tco.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/thresholds.png b/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/thresholds.png
    new file mode 100644
    index 0000000..aad73c9
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/take_the_tour/thresholds.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/togglepanel.js b/deployment-apps/metricator-for-nmon/appserver/static/togglepanel.js
    new file mode 100644
    index 0000000..c18f2f6
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/togglepanel.js
    @@ -0,0 +1,70 @@
    +/**
    + * @fileoverview Setup the paths and load the Developer Gadgets components
    + * @author Ryan Thibodeaux
    + * @version 1.0.0
    + */
    +
    +/*
    + * Copyright (c) 2017, Ryan Thibodeaux. All Rights Reserved
    + * see included LICENSE file (BSD 3-clause) in the app's root directory
    + */
    +
    +(function() {
    +  "use strict";
    +
    +  // configure the RequrieJS paths
    +  require.config({
    +    paths: {
    +      "appBase"     : "../app/metricator-for-nmon",
    +      "TogglePanel" : "../app/metricator-for-nmon/components/togglepanel/togglepanel",
    +    }
    +  });
    +
    +}).call(this);
    +
    +
    +// from app/developer_gadgets/components/togglepanel/wrapper.js
    +/*
    + * Copyright (c) 2016-2017, OctoInsight Inc., All rights reserved.
    + * Authored by Ryan Thibodeaux
    + * see included LICENSE file (BSD 3-clause) in the folder components/togglepanel
    + */
    +
    +/*
    + * This file implements the autodiscover function
    + * that finds panels in SimpleXML that should
    + * be turned into Toggle Panels based on their
    + * HTML IDs matching a specific pattern.
    + */
    +
    +(function() {
    +  require([
    +    "underscore",
    +    "jquery",
    +    "splunkjs/mvc",
    +    "TogglePanel",
    +], function(_, $, mvc, TogglePanel) {
    +
    +    "use strict";
    +
    +    const regex = /_togglepanel/i;
    +    const regexHide = /_togglepanel_true/i;
    +
    +    _(mvc.Components.toJSON())
    +      .chain()
    +      .filter(function(el) {
    +        var id = $(el).attr("id");
    +        var dom = $(el).attr("$el");
    +        if (typeof id !== "undefined" && typeof dom !== "undefined") {
    +          if (id.match(regex) !== null && dom.hasClass('dashboard-cell')) {
    +            return el;
    +          }
    +        }
    +      }).each(function(el) {
    +        var id = $(el).attr("id");
    +        var hide = (id.match(regexHide) !== null ? true : false);
    +        new TogglePanel(id).setup(hide);
    +      });
    +
    +  });
    +}).call(this);
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/ui_simple.css b/deployment-apps/metricator-for-nmon/appserver/static/ui_simple.css
    new file mode 100644
    index 0000000..2be572a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/static/ui_simple.css
    @@ -0,0 +1,496 @@
    +/* Custom title style of simple xml views */
    +
    +/*
    +.dashboard-header h2 {
    +	font-size: 22px;
    +	font-weight: bold;
    +	color: #157EFB;
    +}*/
    +
    +.dashboard-row .dashboard-panel h2.panel-title {
    +  font-size: 18px;
    +  font-weight: bold;
    +  color: #d3d3d3;
    +}
    +
    +/* Now deactivated 
    +
    +Insert NMON simple logo (48px) and set margin bottom
    +
    +.dashboard-header h2 {
    +  background-image: url(/../../static/app/nmon/logos/NMON_simplelogo_48px.svg);
    +  background-repeat: no-repeat; 
    +  background-position: left;
    +  padding-top:	90px;
    +  margin-bottom:20px;  
    +  float: left;
    +}
    +
    +*/
    +
    +/* margin left required for Firefox */
    +
    +.list li {
    +  /*margin-left: 4px; */
    +  margin-left: 10px;
    +  padding-left: 10px;
    +}
    +
    +.list {
    +  display: inline-block;
    +  margin-right: 50px;
    +}
    +
    +/* Various styles */
    +
    +.html h1 {
    +  font-size: 20px;
    +  font-weight: bold;
    +  color: ##adbacd;
    +}
    +
    +.html h2 {
    +  font-size: 18px;
    +  margin: 10px 0;
    +  font-weight: normal;
    +  color: #adbacd;
    +  font-weight: bold;
    +}
    +
    +.custom h1 {
    +  font-size: 18px;
    +  font-weight: bold;
    +  color: #3e83bd;
    +  text-align: center;
    +}
    +
    +/* main category icons and titles */
    +
    +.imgheader {
    +  margin-bottom: 40px;
    +}
    +
    +.imgheader img {
    +  float: left;
    +  width: 48px;
    +  height: 48px;
    +}
    +
    +.imgheader h4 {
    +  position: relative;
    +  top: 18px;
    +  left: 10px;
    +}
    +
    +.imgheader2 img {
    +  float: left;
    +  width: 48px;
    +  height: 48px;
    +}
    +
    +.imgheader2 h4 {
    +  position: relative;
    +  top: 10px;
    +  left: 10px;
    +}
    +
    +/* custom link with icon */
    +
    +.customlink img {
    +  float: left;
    +  width: 28px;
    +  height: 28px;
    +}
    +
    +.customlink h3 {
    +  position: relative;
    +  top: 9px;
    +  left: 10px;
    +  font-size: 12px;
    +  font-weight: normal;
    +  font-style: italic;
    +}
    +
    +/* Fix single label trouble with Splunk 6.3.0 */
    +
    +.before-label {
    +  font-size: medium !important;
    +}
    +
    +.after-label {
    +  font-size: medium !important;
    +}
    +
    +.single-result-unit {
    +  font-size: medium !important;
    +}
    +
    +/* Fix link input object align */
    +.input-linklist {
    +  display: inline !important;
    +}
    +
    +/* Fix link input object align for Splunk 6.5 */
    +.input-link {
    +  display: inline !important;
    +}
    +
    +/* Increase the default max-width for links */
    +.btn-pill {
    +  max-width: 600px !important;
    +}
    +
    +/* Prevents modal window from generating troubles within Splunk interfaces */
    +.modal {
    +  display: none;
    +}
    +/* Custom Modals widths */
    +
    +.modal[class^="custom-modal"] {
    +  left: 50%;
    +  border: 1px solid green;
    +}
    +
    +.custom-modal-30 {
    +  width: 30%;
    +  margin-left: -15%;
    +}
    +
    +.custom-modal-50 {
    +  width: 50%;
    +  margin-left: -25%;
    +}
    +
    +.custom-modal-60 {
    +  width: 60%;
    +  margin-left: -30%;
    +}
    +
    +.custom-modal-70 {
    +  width: 70%;
    +  margin-left: -35%;
    +}
    +
    +.custom-modal-80 {
    +  width: 80%;
    +  margin-left: -40%;
    +}
    +
    +.custom-modal-96 {
    +  width: 96%;
    +  margin-left: -48%;
    +}
    +
    +/* Main button containers */
    +.mainbutton_container {
    +  text-align: center;
    +  margin-top: 25px;
    +  margin-bottom: 50px;
    +}
    +
    +.mainbutton_container_nomargin {
    +  text-align: center;
    +}
    +
    +.mainbutton {
    +  display: inline-block;
    +  margin-left: 30px;
    +  margin-right: 30px;
    +}
    +
    +.mainbutton_highmargin {
    +  display: inline-block;
    +  margin-left: 90px;
    +  margin-right: 90px;
    +}
    +
    +/* Home Button */
    +
    +.round-button {
    +  width: 3%;
    +  height: 0;
    +  padding-bottom: 3%;
    +  border-radius: 50%;
    +  border: 2px solid #f5f5f5;
    +  overflow: hidden;
    +  background: #464646;
    +  box-shadow: 0 0 3px gray;
    +}
    +.round-button:hover {
    +  background: #262626;
    +}
    +.round-button img {
    +  display: block;
    +  width: 76%;
    +  padding: 12%;
    +  height: auto;
    +}
    +
    +.cat_title {
    +  color: #5379af;
    +  margin-bottom: 10px;
    +}
    +
    +.bootstrap_title {
    +  color: #5379af;
    +  margin-bottom: 5px;
    +  margin-top: 5px;
    +}
    +
    +span:hover {
    +  position: relative;
    +  font-weight: bolder;
    +}
    +
    +/* Home page button links, inspired from http://www.w3schools.com */
    +
    +a.tryitbtn,
    +a.tryitbtn:link,
    +a.tryitbtn:visited,
    +a.showbtn,
    +a.showbtn:link,
    +a.showbtn:visited {
    +  display: inline-block;
    +  color: #469496;
    +  background-color: #1f1f1f;
    +  font-weight: bold;
    +  font-size: 12px;
    +  text-align: center;
    +  padding-left: 10px;
    +  padding-right: 10px;
    +  padding-top: 3px;
    +  padding-bottom: 4px;
    +  text-decoration: none;
    +  margin-left: 0;
    +  /* margin-left: 5px; */
    +  margin-right: 10px;
    +  margin-top: 0px;
    +  margin-bottom: 5px;
    +  border: 1px solid #aaaaaa;
    +  border: 1px solid #469496;
    +  border-radius: 5px;
    +  white-space: nowrap;
    +  min-width: 60px;
    +}
    +
    +a.tryitbtn:hover,
    +a.tryitbtn:active,
    +a.tryitbtn:hover,
    +a.tryitbtn:active {
    +  background-color: #469496;
    +  color: #1f1f1f;
    +}
    +
    +a.tryitbtnxl,
    +a.tryitbtnxl:link,
    +a.tryitbtnxl:visited,
    +a.showbtnxl,
    +a.showbtnxl:link,
    +a.showbtnxl:visited {
    +  display: inline-block;
    +  color: #469496;
    +  background-color: #1f1f1f;
    +  font-weight: bold;
    +  font-size: 12px;
    +  text-align: center;
    +  padding-left: 10px;
    +  padding-right: 10px;
    +  padding-top: 3px;
    +  padding-bottom: 4px;
    +  text-decoration: none;
    +  margin-left: 0;
    +  /* margin-left: 5px; */
    +  margin-right: 10px;
    +  margin-top: 5px;
    +  margin-bottom: 5px;
    +  border: 1px solid #aaaaaa;
    +  border: 1px solid #469496;
    +  border-radius: 5px;
    +  white-space: nowrap;
    +  min-width: 150px;
    +}
    +
    +a.tryitbtnxl:hover,
    +a.tryitbtnxl:active,
    +a.tryitbtnxl:hover,
    +a.tryitbtnxl:active {
    +  background-color: #469496;
    +  color: #1f1f1f;
    +}
    +
    +a.tryitbtnxxl,
    +a.tryitbtnxxl:link,
    +a.tryitbtnxxl:visited,
    +a.showbtnxxl,
    +a.showbtnxxl:link,
    +a.showbtnxxl:visited {
    +  display: inline-block;
    +  color: #469496;
    +  background-color: #1f1f1f;
    +  font-weight: bold;
    +  font-size: 12px;
    +  text-align: center;
    +  padding-left: 10px;
    +  padding-right: 10px;
    +  padding-top: 3px;
    +  padding-bottom: 4px;
    +  text-decoration: none;
    +  margin-left: 0;
    +  /* margin-left: 5px; */
    +  margin-right: 10px;
    +  margin-top: 10px;
    +  margin-bottom: 10px;
    +  border: 1px solid #aaaaaa;
    +  border: 1px solid #469496;
    +  border-radius: 5px;
    +  white-space: nowrap;
    +  min-width: 220px;
    +}
    +
    +a.tryitbtnxxl:hover,
    +a.tryitbtnxxl:active,
    +a.tryitbtnxxl:hover,
    +a.tryitbtnxxl:active {
    +  background-color: #469496;
    +  color: #1f1f1f;
    +}
    +
    +a.tryitbtn-alt,
    +a.tryitbtn-alt:link,
    +a.tryitbtn-alt:visited,
    +a.tryitbtn-alt,
    +a.tryitbtn-alt:link,
    +a.tryitbtn-alt:visited {
    +  display: inline-block;
    +  color: #c171b1;
    +  background-color: #1f1f1f;
    +  font-weight: bold;
    +  font-size: 12px;
    +  text-align: center;
    +  padding-left: 10px;
    +  padding-right: 10px;
    +  padding-top: 3px;
    +  padding-bottom: 4px;
    +  text-decoration: none;
    +  margin-left: 0;
    +  /* margin-left: 5px; */
    +  margin-right: 10px;
    +  margin-top: 0px;
    +  margin-bottom: 5px;
    +  border: 1px solid #aaaaaa;
    +  border: 1px solid #c171b1;
    +  border-radius: 5px;
    +  white-space: nowrap;
    +  min-width: 60px;
    +}
    +
    +a.tryitbtn-alt:hover,
    +a.tryitbtn-alt:active,
    +a.tryitbtn-alt:hover,
    +a.tryitbtn-alt:active {
    +  background-color: #c171b1;
    +  color: #1f1f1f;
    +}
    +
    +a.rt {
    +  margin-left: 10px;
    +}
    +
    +a.rt {
    +  -webkit-transition: all 1s ease; /* Safari and Chrome */
    +  -moz-transition: all 1s ease; /* Firefox */
    +  -ms-transition: all 1s ease; /* IE 9 */
    +  -o-transition: all 1s ease; /* Opera */
    +  transition: all 1s ease;
    +}
    +
    +a.rt:hover img {
    +  -webkit-transform: scale(1.1); /* Safari and Chrome */
    +  -moz-transform: scale(1.1); /* Firefox */
    +  -ms-transform: scale(1.1); /* IE 9 */
    +  -o-transform: scale(1.1); /* Opera */
    +  transform: scale(1.1);
    +}
    +
    +/*
    +        ---------------------
    +        Multi depends buttons
    +        ---------------------
    +*/
    +
    +/* Button style */
    +.custom-sub-nav button {
    +  display: inline-block;
    +  margin: 0 1em;
    +}
    +
    +/* Style when button is active */
    +.custom-sub-nav button.active {
    +  background: #bbdaf6;
    +}
    +
    +/*
    +        ---------------------
    +        Filled colored panel
    +        ---------------------
    +*/
    +
    +.dashseparator {
    +  text-align: center;
    +  border: 3px dashed #ccc;
    +}
    +
    +.dashseparator h1 {
    +  font-size: 18px;
    +  font-weight: bold;
    +  color: #999999;
    +  text-align: center;
    +  font-style: italic;
    +}
    +
    +/*
    +        ---------------------
    +        Help the user panels
    +        ---------------------
    +*/
    +
    +.red_help_user {
    +  color: indianred;
    +  text-align: center;
    +  font-size: 20px;
    +  margin-bottom: 15px;
    +  margin-top: 15px;
    +}
    +
    +.blue_help_user {
    +  color: blue;
    +  text-align: center;
    +  font-size: 20px;
    +  font-style: italic;
    +  margin-bottom: 15px;
    +  margin-top: 15px;
    +}
    +
    +/* Panels title bar customization */
    +
    +.dashboard-row .dashboard-panel h2.panel-title {
    +  /* text-align: center; */
    +  font-size: 20px;
    +  font-weight: 500;
    +  background-color: #444444;
    +  padding: 5px 5px 5px 5px;
    +}
    +
    +/*
    +        ---------------------
    +        form specific width
    +        ---------------------
    +*/
    +
    +#metric_name .select2-container {
    +  min-width: 360px;
    +}
    +
    +#metric_name2 .select2-container {
    +  min-width: 360px;
    +}
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minichart.png b/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minichart.png
    new file mode 100644
    index 0000000..ca30e1a
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minichart.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minicolumn.png b/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minicolumn.png
    new file mode 100644
    index 0000000..f09b6f7
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minicolumn.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minigauge.png b/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minigauge.png
    new file mode 100644
    index 0000000..407f649
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minigauge.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minisingle.png b/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minisingle.png
    new file mode 100644
    index 0000000..f58fc13
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minisingle.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minitable.png b/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minitable.png
    new file mode 100644
    index 0000000..e079d37
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/various/mini/minitable.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/various/mini/single_trend.png b/deployment-apps/metricator-for-nmon/appserver/static/various/mini/single_trend.png
    new file mode 100644
    index 0000000..b16aca9
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/various/mini/single_trend.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/static/various/online_doc.png b/deployment-apps/metricator-for-nmon/appserver/static/various/online_doc.png
    new file mode 100644
    index 0000000..e25be8b
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/appserver/static/various/online_doc.png differ
    diff --git a/deployment-apps/metricator-for-nmon/appserver/templates/base.html b/deployment-apps/metricator-for-nmon/appserver/templates/base.html
    new file mode 100644
    index 0000000..480c171
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/appserver/templates/base.html
    @@ -0,0 +1,40 @@
    +<!--
    +  ~ Copyright 2021 Splunk Inc.
    +  ~
    +  ~ Licensed 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.
    +  ~
    +-->
    +<%! app_name = cherrypy.request.path_info.split('/')[3] %>\
    +<!DOCTYPE html>
    +<html class="no-js" lang="">
    +    <head>
    +        <meta charset="utf-8" />
    +        <meta http-equiv="x-ua-compatible" content="ie=edge" />
    +        <title>${_('Loading')}</title>
    +        <meta name="viewport" content="width=device-width, initial-scale=1" />
    +        <link rel="apple-touch-icon" href="apple-touch-icon.png" />
    +    </head>
    +
    +    <body>
    +        <script src="${make_url('/config?autoload=1')}" crossorigin="use-credentials"></script>
    +        <script src="${make_url('/static/js/i18n.js')}"></script>
    +        <script src="${make_url('/i18ncatalog?autoload=1')}"></script>
    +        <script>
    +            __splunkd_partials__ = ${json_decode(splunkd)};
    +        </script>
    +
    +        <% page_path = "/static/app/" + app_name + "/js/build/entry_page.js" %>
    +
    +        <script src="${make_url(page_path)}"></script>
    +    </body>
    +</html>
    diff --git a/deployment-apps/metricator-for-nmon/bin/import_declare_test.py b/deployment-apps/metricator-for-nmon/bin/import_declare_test.py
    new file mode 100644
    index 0000000..453e0a3
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/bin/import_declare_test.py
    @@ -0,0 +1,12 @@
    +
    +import os
    +import sys
    +import re
    +from os.path import dirname
    +
    +ta_name = 'metricator-for-nmon'
    +pattern = re.compile(r'[\\/]etc[\\/]apps[\\/][^\\/]+[\\/]bin[\\/]?$')
    +new_paths = [path for path in sys.path if not pattern.search(path) or ta_name in path]
    +new_paths.append(os.path.join(dirname(dirname(__file__)), "lib"))
    +new_paths.insert(0, os.path.sep.join([os.path.dirname(__file__), ta_name]))
    +sys.path = new_paths
    diff --git a/deployment-apps/metricator-for-nmon/bin/metricator_for_nmon_rh_settings.py b/deployment-apps/metricator-for-nmon/bin/metricator_for_nmon_rh_settings.py
    new file mode 100644
    index 0000000..8652bcc
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/bin/metricator_for_nmon_rh_settings.py
    @@ -0,0 +1,42 @@
    +
    +import import_declare_test
    +
    +from splunktaucclib.rest_handler.endpoint import (
    +    field,
    +    validator,
    +    RestModel,
    +    MultipleModel,
    +)
    +from splunktaucclib.rest_handler import admin_external, util
    +from splunktaucclib.rest_handler.admin_external import AdminExternalHandler
    +import logging
    +
    +util.remove_http_proxy_env_vars()
    +
    +
    +fields_logging = [
    +    field.RestField(
    +        'loglevel',
    +        required=False,
    +        encrypted=False,
    +        default='INFO',
    +        validator=None
    +    )
    +]
    +model_logging = RestModel(fields_logging, name='logging')
    +
    +
    +endpoint = MultipleModel(
    +    'metricator_for_nmon_settings',
    +    models=[
    +        model_logging
    +    ],
    +)
    +
    +
    +if __name__ == '__main__':
    +    logging.getLogger().addHandler(logging.NullHandler())
    +    admin_external.handle(
    +        endpoint,
    +        handler=AdminExternalHandler,
    +    )
    diff --git a/deployment-apps/metricator-for-nmon/default/app.conf b/deployment-apps/metricator-for-nmon/default/app.conf
    new file mode 100644
    index 0000000..9fcf401
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/app.conf
    @@ -0,0 +1,28 @@
    +#
    +# Splunk app configuration file
    +#
    +
    +[install]
    +is_configured = 0
    +build = 1676623086
    +
    +[package]
    +id = metricator-for-nmon
    +check_for_updates = true
    +
    +[ui]
    +is_visible = 1
    +label = Metricator for Nmon
    +
    +[triggers]
    +reload.metricator_for_nmon_settings = simple
    +
    +[id]
    +name = metricator-for-nmon
    +version = 2.0.0
    +
    +[launcher]
    +author = Octamis
    +description = Metricator for Nmon provides rich and efficient monitoring and capacity planning for Linux, IBM AIX and Oracle Solaris
    +version = 2.0.0
    +
    diff --git a/deployment-apps/metricator-for-nmon/default/collections.conf b/deployment-apps/metricator-for-nmon/default/collections.conf
    new file mode 100644
    index 0000000..7532268
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/collections.conf
    @@ -0,0 +1,70 @@
    +# collections.conf
    +
    +#
    +# Splunk app KV store collection file
    +#
    +
    +# In distributed mode, replicating the KVstore to indexer is mandatory for auto-lookup
    +[kv_nmon_inventory]
    +replicate = true
    +
    +# Nmon baseline kvstore collections, one collection per performance metric
    +
    +# CPU_ALL, CPU statistics for All OS
    +[kv_nmon_baseline_CPU_ALL]
    +accelerated_fields.kv_nmon_baseline = { "date_wday":1, "local_time":1, "frameID":1, "hostname":1 }
    +
    +# LPAR, AIX Micro-partitions and shared pool CPU statistics
    +[kv_nmon_baseline_LPAR]
    +accelerated_fields.kv_nmon_baseline = { "date_wday":1, "local_time":1, "frameID":1, "hostname":1 }
    +
    +# MEM, Memory statistics for All OS
    +[kv_nmon_baseline_MEM]
    +accelerated_fields.kv_nmon_baseline = { "date_wday":1, "local_time":1, "frameID":1, "hostname":1 }
    +
    +# DISKXFER, Disks I/O per sec statistics
    +[kv_nmon_baseline_DISKXFER]
    +accelerated_fields.kv_nmon_baseline = { "date_wday":1, "local_time":1, "frameID":1, "hostname":1 }
    +
    +# KVstore collection for frameID mapping, must be replicated with indexers for auto lookup
    +# frameID mapping:
    +[kv_nmon_frameID_mapping]
    +replicate = true
    +
    +# Used to store up to 6 previous days of known hosts to the application, to be used for optimization purposes
    +[kv_nmon_hosts_last_7days]
    +
    +# File systems excluding for file systems usage alerting
    +# 3 collections are available:
    +# - nmon_alerting_filesystem_global_exclusion: will be applied for all systems to exclude file systems
    +# - nmon_alerting_filesystem_template_exclusion: will be applied for matched systems to exclude file systems
    +# - nmon_alerting_filesystem_per_server_exclusion: file system exclusion on per server basis
    +
    +[kv_nmon_alerting_filesystem_global_exclusion]
    +replicate = false
    +
    +[kv_nmon_alerting_filesystem_template_exclusion]
    +replicate = false
    +
    +[kv_nmon_alerting_filesystem_per_server_exclusion]
    +replicate = false
    +
    +# Alerting tenplate threshold management
    +# Used to provide template capabilities to define threshold levels for cpu, physical and virtual memory percentage usage
    +[kv_nmon_alerting_threshold_template]
    +replicate = false
    +
    +# Alerting threshold management per server
    +# Used to provide by server capabilities to define threshold levels for cpu, physical and virtual memory percentage usage
    +[kv_nmon_alerting_threshold]
    +replicate = false
    +
    +# Alerting template threshold management for filesystems
    +# Used to provide by server capabilities to define threshold levels for file-systems usage on a per server / file-system basis
    +[kv_nmon_alerting_threshold_template_filesystem]
    +replicate = false
    +
    +# Alerting threshold management per server for filesystems
    +# Used to provide by server capabilities to define threshold levels for file-systems usage on a per server / file-system basis
    +[kv_nmon_alerting_threshold_filesystem]
    +replicate = false
    diff --git a/deployment-apps/metricator-for-nmon/default/data/models/metricator-nmon-config.json b/deployment-apps/metricator-for-nmon/default/data/models/metricator-nmon-config.json
    new file mode 100644
    index 0000000..094c84b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/models/metricator-nmon-config.json
    @@ -0,0 +1,1685 @@
    +{
    +    "modelName": "metricator-nmon-config",
    +    "displayName": "NMON Config - Inventory Items extracted from Nmon raw data",
    +    "description": "Configuration Items extracted from Nmon files raw data during data conversion, formerly AAA and BBB sections of Nmon",
    +    "objectSummary": {
    +        "Event-Based": 2,
    +        "Transaction-Based": 0,
    +        "Search-Based": 0
    +    },
    +    "objects": [
    +        {
    +            "objectName": "Nmon_Config",
    +            "displayName": "Nmon Config",
    +            "parentName": "BaseEvent",
    +            "comment": "",
    +            "fields": [
    +                {
    +                    "fieldName": "uptime",
    +                    "owner": "Nmon_Config",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "uptime",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "OStype",
    +                    "owner": "Nmon_Config",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "OStype",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "_time",
    +                    "owner": "BaseEvent",
    +                    "type": "timestamp",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "_time",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "host",
    +                    "owner": "BaseEvent",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "host",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "source",
    +                    "owner": "BaseEvent",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "source",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "sourcetype",
    +                    "owner": "BaseEvent",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "sourcetype",
    +                    "comment": ""
    +                }
    +            ],
    +            "calculations": [
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "hostname",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "hostname",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "lhdt9ze28bz0vn29",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "(?i),host,(?P<hostname>.+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "nmon_version",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "nmon_version",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "e8lnyo90pbfenrk9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "(?i),version,(?P<nmon_version>.+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "nmon_command",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "nmon_command",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "88chrxwn9gbbuik9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "(?i),command,(?P<nmon_command>.+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "OS",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "OS",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "jcedujs1ktbuik9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "(?i),OS,(?P<OS>[^,]+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "cpu_cores_position1",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "cpu_cores_position1",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "ea2yz4wfub2fn7b9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "AAA,cpus,(?P<cpu_cores_position1>\\d+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "cpu_cores_position2",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "cpu_cores_position2",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "fb57vy93ygzgds4i",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "AAA,cpus,\\d+,(?P<cpu_cores_position2>\\d+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_LEVEL",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_LEVEL",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "en7787whturtfbt9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "AAA,AIX,(?P<AIX_LEVEL>.+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_virtualcpus",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_virtualcpus",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "xkp663uk5qj8aor",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lparstat.+,\\\"Online\\sVirtual\\sCPUs\\s+\\:\\s(?P<AIX_virtualcpus>\\d+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_memory_MB",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_memory_MB",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "7s93d3dvqk2wqaor",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,online\\sMemory,(?P<AIX_memory_MB>\\d+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_pagingspace_MB",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_pagingspace_MB",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "1z7xe35h49qf47vi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lsconf,\\\"\\s+Total\\sPaging\\sSpace:\\s(?P<AIX_pagingspace_MB>\\d+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_processor_mode",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_processor_mode",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "v9gn2caephbk2o6r",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lsconf,\\\"Processor\\sImplementation\\sMode:\\s(?P<AIX_processor_mode>.+\\w)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_processor_clockspeed",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_processor_clockspeed",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "1n6iy95biz5s714i",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lsconf,\\\"Processor\\sClock\\sSpeed:\\s(?P<AIX_processor_clockspeed>.+\\w)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_cpu_type",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_cpu_type",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "8a3tjz556wasjor",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lsconf,\\\"CPU\\sType:\\s(?P<AIX_cpu_type>.+\\w)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_kernel_type",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_kernel_type",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "lfdm6az7dokcsor",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lsconf,\\\"Kernel\\sType:\\s(?P<AIX_kernel_type>.+\\w)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_plateform_firmware_level",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_plateform_firmware_level",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "lgebqsiby7v9ggb9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lsconf,\\\"Platform\\sFirmware\\slevel:\\s(?P<AIX_plateform_firmware_level>.+\\w)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_std_Machine_SerialNumber",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_std_Machine_SerialNumber",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "zikmw9mi6hv3g14i",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lsconf,\\\"Machine\\sSerial\\sNumber:\\s(?P<AIX_std_Machine_SerialNumber>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_alt_Machine_SerialNumber",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_alt_Machine_SerialNumber",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "fv40jctguxvzehfr",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "AAA,SerialNumber,(?P<AIX_alt_Machine_SerialNumber>\\w+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_Machine_SerialNumber",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_Machine_SerialNumber",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "yg6i5g9slh00be29",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "if(isnotnull(AIX_std_Machine_SerialNumber), AIX_std_Machine_SerialNumber, AIX_alt_Machine_SerialNumber)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_extracted_PoolID",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_extracted_PoolID",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "0al5wto52xk73nmi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lparstat.+,\\\"Shared\\sPool\\sID\\s+\\:\\s(?P<AIX_extracted_PoolID>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_PoolID",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_PoolID",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "e2xigyjn1v48ia4i",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "if(AIX_extracted_PoolID==\"-\",\"N/A\" ,AIX_extracted_PoolID)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_system_installed_CPUs",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_system_installed_CPUs",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "7am1e8z91azia4i",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lparstat.+,\\\"Maximum\\sPhysical\\sCPUs\\sin\\ssystem\\s+\\:\\s(?P<AIX_system_installed_CPUs>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_system_active_CPUs",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_system_active_CPUs",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "asb8hez5rpet57b9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lparstat.+,\\\"Active\\sPhysical\\sCPUs\\sin\\ssystem\\s+\\:\\s(?P<AIX_system_active_CPUs>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_extracted_PoolCPUs",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_extracted_PoolCPUs",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "dvzplipwtvjkyb9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lparstat.+,\\\"Active\\sCPUs\\sin\\sPool\\s+\\:\\s(?P<AIX_extracted_PoolCPUs>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_PoolCPUs",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_PoolCPUs",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "mxx337o1dhqqto6r",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "if(AIX_extracted_PoolCPUs==\"-\",\"N/A\" ,AIX_extracted_PoolCPUs)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_entitled",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_entitled",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "nj9phsxfgoqiwwmi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lparstat.+,\\\"Entitled\\sCapacity\\s+\\:\\s(?P<AIX_entitled>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_processor",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_processor",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "7csb7fz840u23xr",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lsconf,\\\"Processor\\sType:\\s(?P<AIX_processor>.+\\w)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_partition_type",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_partition_type",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "1qhgmbmjtdxqfmelwyugg2pgb9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lparstat -i,\\\"Type\\s{0,}:(?P<AIX_partition_type>.+\\w)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_partition_mode",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_partition_mode",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "xhsg9w2sdsnvayk24vkdfgvi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lparstat -i,\\\"Mode\\s{0,}:(?P<AIX_partition_mode>.+\\w)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_max_physical_CPUs_in_system",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_max_physical_CPUs_in_system",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "z58sccdma0j60k3t8m7fu5wmi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lparstat -i,\\\"Maximum\\sPhysical\\sCPUs\\sin\\ssystem\\s{0,}:\\s{0,}(?P<AIX_max_physical_CPUs_in_system>.+\\w)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "AIX_logicalcores",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "AIX_logicalcores",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "jaovx5qb3ytfyldi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "case(OStype==\"AIX\", if(isnotnull(cpu_cores_position2), cpu_cores_position2, cpu_cores_position1))"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_LEVEL",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_LEVEL",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "buohdn976k3jif6r",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "AAA,OS,Linux,(?P<Linux_LEVEL>.+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_arch",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_arch",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "mr5mx7xy1tkik85z07ha4te29",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+lscpu,.+(Architecture)\\s*:\\s+(?P<Linux_arch>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_processor_lscpu",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_processor_lscpu",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "ifdkxulqyuvxi529",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+lscpu,.+(Model\\sname|Model|Vendor\\sID)\\s*:\\s+(?P<Linux_processor_lscpu>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_processor_cpuinfo",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_processor_cpuinfo",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "f4nl8hxy8679swfn8doyldi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+cpuinfo,.+(model\\sname)\\s*:\\s+(?P<Linux_processor_cpuinfo>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_release_distribution",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_release_distribution",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "s1yinv2mqc2l0udi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,.+etc+.release,\\\"(?!LSB_VERSION|DISTRIB|NAME|ID|VERSION|VARIANT)(?:s|PRETTY_NAME=Q){0,1}(?:s|PRETTY_NAME=){0,1}(?P<Linux_release_distribution>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_lsb_distribution",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_lsb_distribution",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "9vfbvrquy27nl8fr",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lsb_release,\\\"Description:\\s*(?<Linux_lsb_distribution>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_distribution",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_distribution",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "pjqye6nruketu6fp0vifnu3di",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "case(isnotnull(Linux_lsb_distribution), Linux_lsb_distribution,\nisnotnull(Linux_release_distribution), Linux_release_distribution)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_lsb_distibutorid",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_lsb_distibutorid",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "4bo6vrb07ac92j4i",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lsb_release,\\\"Distributor\\s*ID:\\s*(?<Linux_lsb_distibutorid>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_lsb_releaseid",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_lsb_releaseid",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "y2w77ae8g89i19k9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lsb_release,\\\"Release:\\s*(?<Linux_lsb_releaseid>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_vendor",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_vendor",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "xe7szov480nt57b9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "if(isnotnull(Linux_lsb_distibutorid), Linux_lsb_distibutorid, \"Undeterminated\")"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_version",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_version",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "c2dkordeuel5l8fr",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,lsb\\_release,\\\"Release:\\s+(?P<Linux_version>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_memory_kB",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_memory_kB",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "04aqz4btayh9f6r",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,.proc.meminfo,\\\"MemTotal:\\s+(?P<Linux_memory_kB>\\d+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_memory_MB",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_memory_MB",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "d2hwa4y1y9lwstt9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "round(Linux_memory_kB/1024,0)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_swap_kB",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_swap_kB",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "iup7m1z62tv2huxr",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,.proc.meminfo,\\\"SwapTotal:\\s+(?P<Linux_swap_kB>\\d+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_swap_MB",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_swap_MB",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "076rys97yi16pqfr",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "round(Linux_swap_kB/1024,0)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_kernelversion",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_kernelversion",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "er03rsuvok6e0zfr",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "AAA,OS,Linux,(?P<Linux_kernelversion>\\d+.\\d+).+,#"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_kernel",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_kernel",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "3tmsfw7nmavpldi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "AAA,OS,Linux,(?P<Linux_kernel>.+),#"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Linux_fullkernel",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Linux_fullkernel",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "xop04li64fclq5mi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "AAA,OS,Linux,(?P<Linux_fullkernel>.+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Solaris_LEVEL",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Solaris_LEVEL",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "8nu2r62ggxbhuxr",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "AAA,OS,Solaris,(?P<Solaris_LEVEL>.+)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Solaris_phy_mem_MB_extract",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Solaris_phy_mem_MB_extract",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "qtinojxt2tdxilf0a3qrozuxr",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.,.*,prtdiag,\\\"Memory\\s*size:\\s*(?<Solaris_phy_mem_MB_extract>\\d*)\\s*Megabytes\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Solaris_phy_mem_GB_extract",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Solaris_phy_mem_GB_extract",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "w8z7pbyss9cxk2c90juelv7vi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.,.*,prtdiag,\\\"Memory\\s*size:\\s*(?<Solaris_phy_mem_GB_extract>\\d*)\\s*GB"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Solaris_physical_memory_MB",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Solaris_physical_memory_MB",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "syftxzogd8mjqdhdhhhncdi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "case( OStype == \"Solaris\", case(isnotnull(Solaris_phy_mem_MB_extract), Solaris_phy_mem_MB_extract, isnotnull(Solaris_phy_mem_GB_extract), (Solaris_phy_mem_GB_extract/1024)) )"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Solaris_kernel",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Solaris_kernel",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "xs8og491kiall3di",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "AAA,OS,Solaris,.+,(?P<Solaris_kernel>.+),.+,.+"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Solaris_sunOS_version",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Solaris_sunOS_version",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "4licpdnxtvrevcxr",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "AAA,OS,Solaris,(?P<Solaris_sunOS_version>.+),.+,.+,.+"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Solaris_version",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Solaris_version",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "rmy2nnotqllq5mi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+,.+etc+.release,\\\"\\s+(?P<Solaris_version>.+)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Solaris_processor_primary",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Solaris_processor_primary",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "erzxcfrhlwxt7qfr",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+psrinfo\\s\\-pv,\\\"\\s+(?P<Solaris_processor_primary>.+)\\s*\\(.+clock.+\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Solaris_processor_clock_primary",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Solaris_processor_clock_primary",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "spi82j182etawcdi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+psrinfo\\s\\-pv,.+clock\\s(?P<Solaris_processor_clock_primary>.+)\\)\\\""
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Solaris_processor_alt",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Solaris_processor_alt",
    +                            "comment": ""
    +                        },
    +                        {
    +                            "fieldName": "Solaris_processor_clock_alt",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Solaris_processor_clock_alt",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "inputField": "_raw",
    +                    "calculationID": "fqh7xokpt3yjzkum3ccz4u0udi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Rex",
    +                    "expression": "BBB.+,[0-9].+prtdiag,\\\"0\\s*(?<Solaris_processor_clock_alt>[\\d|\\.]*\\s*\\w*)\\s*(?P<Solaris_processor_alt>[\\w|-]*)\\s*"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Solaris_processor_clockspeed",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Solaris_processor_clockspeed",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "5u6bef2gukczqgy780ta603sor",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "case( OStype == \"Solaris\", if(isnotnull(Solaris_processor_clock_primary), Solaris_processor_clock_primary, Solaris_processor_clock_alt) )"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "OS_Level",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "OS_Level",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "xsnrryemzr4cmcxr",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "case(isnotnull(AIX_LEVEL), AIX_LEVEL, isnotnull(Solaris_version), Solaris_version, isnotnull(Linux_distribution), Linux_distribution)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "cpu_cores_with_vp",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "cpu_cores_with_vp",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "bsqas22opsc",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "AIX_virtualcpus . \" / \" . cpu_cores_position2"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "cpu_cores",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "cpu_cores",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "jb6kr5ya00kn8kt9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "if(isnotnull(AIX_virtualcpus), cpu_cores_with_vp, cpu_cores_position1)"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "Processor",
    +                            "owner": "Nmon_Config",
    +                            "type": "string",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Processor",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "q70144l2w3oywrk9",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "case(OStype == \"AIX\", AIX_processor, OStype == \"Solaris\", case(isnotnull(Solaris_processor_primary), Solaris_processor_primary, isnotnull(Solaris_processor_alt), Solaris_processor_alt), OStype == \"Linux\",  case(isnotnull(Linux_processor_lscpu), Linux_processor_lscpu + \" (arch: \" + Linux_arch + \")\" , isnull(Linux_processor_lscpu), Linux_processor_cpuinfo) )"
    +                },
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "event_epoch",
    +                            "owner": "Nmon_Config",
    +                            "type": "number",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "event_epoch",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "0798lb6p9hy78u3o2dn7l7syvi",
    +                    "owner": "Nmon_Config",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "strftime('_time', \"%s\")"
    +                }
    +            ],
    +            "constraints": [
    +                {
    +                    "search": "(eventtype=nmon:config)",
    +                    "owner": "Nmon_Config"
    +                }
    +            ],
    +            "lineage": "Nmon_Config"
    +        },
    +        {
    +            "objectName": "Uptime",
    +            "displayName": "Uptime (nmon external)",
    +            "parentName": "BaseEvent",
    +            "comment": "",
    +            "fields": [
    +                {
    +                    "fieldName": "uptime",
    +                    "owner": "Uptime",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "uptime",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "OStype",
    +                    "owner": "Uptime",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "OStype",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "_time",
    +                    "owner": "BaseEvent",
    +                    "type": "timestamp",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "_time",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "host",
    +                    "owner": "BaseEvent",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "host",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "source",
    +                    "owner": "BaseEvent",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "source",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "sourcetype",
    +                    "owner": "BaseEvent",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "sourcetype",
    +                    "comment": ""
    +                }
    +            ],
    +            "calculations": [
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "event_epoch",
    +                            "owner": "Uptime",
    +                            "type": "number",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "event_epoch",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "iyd3wjcd8245z6hh09u6dpldi",
    +                    "owner": "Uptime",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "strftime('_time', \"%s\")"
    +                }
    +            ],
    +            "constraints": [
    +                {
    +                    "search": "(eventtype=nmon:events type=UPTIME)",
    +                    "owner": "Uptime"
    +                }
    +            ],
    +            "lineage": "Uptime"
    +        }
    +    ],
    +    "objectNameList": [
    +        "Nmon_Config",
    +        "Uptime"
    +    ]
    +}
    diff --git a/deployment-apps/metricator-for-nmon/default/data/models/metricator-nmon-processing.json b/deployment-apps/metricator-for-nmon/default/data/models/metricator-nmon-processing.json
    new file mode 100644
    index 0000000..c2aa574
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/models/metricator-nmon-processing.json
    @@ -0,0 +1,657 @@
    +{
    +    "modelName": "metricator-nmon-collect",
    +    "displayName": "NMON Processing - Data Collect",
    +    "description": "Collect and Processing statistics and events of NMON raw data files",
    +    "objectSummary": {
    +        "Event-Based": 2,
    +        "Transaction-Based": 0,
    +        "Search-Based": 0
    +    },
    +    "objects": [
    +        {
    +            "objectName": "NMON_Processing",
    +            "displayName": "NMON Processing - Conversion of Nmon Raw Data",
    +            "parentName": "BaseEvent",
    +            "fields": [
    +                {
    +                    "fieldName": "Date_of_Nmon_Data",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Date of Nmon Data",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "INTERVAL",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Interval between measures",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "Nmon_ID",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Nmon raw file ID",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "Nmon_version",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Version of Nmon",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "SNAPSHOTS",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Nbr of Snapshots",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "Time_of_Nmon_Data",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Time of Nmon Data",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "elapsed_in_seconds",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Elapsed in Seconds",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "hostname",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "hostname",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "logical_cpus",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Nbr of Logical CPUs",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "nbr_lines",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Nbr of Lines",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "nmonparser_version",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Version of nmonparser",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "operating_system",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Operating System",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "python_version",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Version of Python",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "size_in_bytes",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Size in Bytes of Nmon raw file",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "splunk_home",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "splunk_home",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "virtual_cpus",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Nbr of Virtual CPUs",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "converter_inuse",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "converter_inuse",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "interpreter_version",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "interpreter_version",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "perl_version",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Version of Perl",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "addon_type",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "addon_type",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "addon_version",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "addon_version",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "_time",
    +                    "owner": "BaseEvent",
    +                    "type": "timestamp",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "_time",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "host",
    +                    "owner": "BaseEvent",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "host",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "source",
    +                    "owner": "BaseEvent",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "source",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "sourcetype",
    +                    "owner": "BaseEvent",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "sourcetype",
    +                    "comment": ""
    +                }
    +            ],
    +            "calculations": [
    +                {
    +                    "outputFields": [
    +                        {
    +                            "fieldName": "size_in_MB",
    +                            "owner": "NMON_Processing",
    +                            "type": "number",
    +                            "fieldSearch": "",
    +                            "required": false,
    +                            "multivalue": false,
    +                            "hidden": false,
    +                            "editable": true,
    +                            "displayName": "Size in MB of Nmon raw file",
    +                            "comment": ""
    +                        }
    +                    ],
    +                    "calculationID": "a9oa6mjlvy7rpb9",
    +                    "owner": "NMON_Processing",
    +                    "editable": true,
    +                    "comment": "",
    +                    "calculationType": "Eval",
    +                    "expression": "round((size_in_bytes/1000/1000),2)"
    +                }
    +            ],
    +            "constraints": [
    +                {
    +                    "search": "eventtype=nmon:processing",
    +                    "owner": "NMON_Processing"
    +                }
    +            ],
    +            "lineage": "NMON_Processing"
    +        },
    +        {
    +            "objectName": "Errors_in_Processing",
    +            "displayName": "Errors in Processing",
    +            "parentName": "NMON_Processing",
    +            "fields": [
    +                {
    +                    "fieldName": "Date_of_Nmon_Data",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Date of Nmon Data",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "INTERVAL",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Interval between measures",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "Nmon_ID",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Nmon raw file ID",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "Nmon_version",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Version of Nmon",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "SNAPSHOTS",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Nbr of Snapshots",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "Time_of_Nmon_Data",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Time of Nmon Data",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "elapsed_in_seconds",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Elapsed in Seconds",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "hostname",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "hostname",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "logical_cpus",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Nbr of Logical CPUs",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "nbr_lines",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Nbr of Lines",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "nmonparser_version",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Version of nmonparser",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "operating_system",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Operating System",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "python_version",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Version of Python",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "size_in_bytes",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Size in Bytes of Nmon raw file",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "splunk_home",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "splunk_home",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "virtual_cpus",
    +                    "owner": "NMON_Processing",
    +                    "type": "number",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Nbr of Virtual CPUs",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "converter_inuse",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "converter_inuse",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "interpreter_version",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "interpreter_version",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "perl_version",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "Version of Perl",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "addon_type",
    +                    "owner": "NMON_Processing",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "addon_type",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "_time",
    +                    "owner": "BaseEvent",
    +                    "type": "timestamp",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "_time",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "host",
    +                    "owner": "BaseEvent",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "host",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "source",
    +                    "owner": "BaseEvent",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "source",
    +                    "comment": ""
    +                },
    +                {
    +                    "fieldName": "sourcetype",
    +                    "owner": "BaseEvent",
    +                    "type": "string",
    +                    "fieldSearch": "",
    +                    "required": false,
    +                    "multivalue": false,
    +                    "hidden": false,
    +                    "editable": true,
    +                    "displayName": "sourcetype",
    +                    "comment": ""
    +                }
    +            ],
    +            "calculations": [],
    +            "constraints": [
    +                {
    +                    "search": "ERROR",
    +                    "owner": "NMON_Processing.Errors_in_Processing"
    +                }
    +            ],
    +            "lineage": "NMON_Processing.Errors_in_Processing"
    +        }
    +    ],
    +    "objectNameList": [
    +        "NMON_Processing",
    +        "Errors_in_Processing"
    +    ]
    +}
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/nav/default.xml b/deployment-apps/metricator-for-nmon/default/data/ui/nav/default.xml
    new file mode 100644
    index 0000000..cc6d290
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/nav/default.xml
    @@ -0,0 +1,419 @@
    +<nav search_view="search" color="#778899">
    +    <view name="Overview" default="true"/>
    +    <a href="Home">Start &gt;</a>
    +
    +    <!--
    +    ####################################################################################################################
    +    This is the AIX dedicated menu
    +    ####################################################################################################################
    +    -->
    +
    +    <collection label="AIX">
    +        <a href="Home_AIX">Start for AIX Systems</a>
    +
    +        <collection label="METRICS EXPLORATION">
    +            <a href="Nmon_mexplorer?form.osfilter=AIX">M-EXPLORER</a>
    +        </collection>
    +
    +        <collection label="ANALYSE &amp; TROUBLESHOOT">
    +            <a href="Nmon_Summary?form.osfilter=AIX">SUMMARY OVERVIEW</a>
    +            <a href="Nmon_WOF?form.OStype=AIX">NMON WALL OF PERFORMANCE</a>
    +            <a href="Nmon_ANALYSER_AIX?form.osfilter=AIX">NMON ANALYSER</a>
    +        </collection>
    +
    +        <collection label="COMPARE, PREDICT &amp; FORECAST">
    +            <a href="Nmon_compare?form.osfilter1=AIX&amp;form.osfilter2=AIX">COMPARATIVE ANALYSIS</a>
    +            <a href="Nmon_predict?form.osfilter=AIX">PREDICTIVE ANALYSIS</a>
    +            <a href="Nmon_baseline_AIX">BASELINE FORECASTING</a>
    +        </collection>
    +
    +        <collection label="CPU">
    +            <a href="UI_Nmon_CPU_ALL?form.osfilter=AIX">CPU_ALL >> Pct of CPU Utilization</a>
    +            <a href="UI_Nmon_LOAD_AVG?form.osfilter=AIX">SYS LOAD AVERAGE >> UPTIME load average statistics</a>
    +            <a href="UI_Nmon_CPUnn?form.osfilter=AIX">CPUnn >> Pct of CPU Utilization per logical core</a>
    +            <a href="UI_Nmon_LPAR_AIX">LPAR >> Virtual Partition CPU Utilization</a>
    +            <a href="UI_Nmon_LPAR_AIX_poolconso">LPAR >> Pool Virtual CPU Utilization</a>
    +            <a href="UI_Nmon_POOLS">POOLS >> PSeries Pools statistics</a>
    +            <a href="UI_Nmon_WLM_AIX?form.monitor=os.unix.nmon.processes.wlmcpu">WLM CPU >> CPU load for Workload manager</a>
    +        </collection>
    +
    +        <collection label="PROCESS/KERNEL/IO">
    +            <a href="UI_Nmon_TOP_AIX">TOP >> Main Processes System Resources Usage</a>
    +            <a href="UI_Nmon_UARG_AIX">UARG >> PIDs, Commands and Arguments</a>
    +            <a href="UI_Nmon_FILE?form.osfilter=AIX">FILE >> Kernel File statistics</a>
    +            <a href="UI_Nmon_IOADAPT">IOADAPT >> I/O Adapters Read/Write Operations</a>
    +            <a href="UI_Nmon_FC">FC >> Fiber Channel Read/Write Operations</a>
    +            <a href="UI_Nmon_PROC?form.osfilter=AIX">PROC >> Kernel Internal statistics</a>
    +            <a href="UI_Nmon_PAGE_AIX">PAGE >> Paging statistics</a>
    +            <a href="UI_Nmon_WLM_AIX?form.monitor=os.unix.nmon.processes.wlmbio">WLM BIO >> Block I/O load for Workload manager</a>
    +        </collection>
    +
    +        <collection label="MEMORY">
    +            <a href="UI_Nmon_MEMNEW_AIX">MEMNEW >> Percentage of Memory Allocation</a>
    +            <a href="UI_Nmon_MEM_AIX">MEM >> Real and Virtual Memory statistics</a>
    +            <a href="UI_Nmon_MEMUSE_AIX">MEMUSE >> Various Memory statistics</a>
    +            <a href="UI_Nmon_WLM_AIX?form.monitor=os.unix.nmon.processes.wlmmem">WLM MEM >> Memory load for Workload manager</a>
    +        </collection>
    +
    +        <collection label="DISKS/FILESYSTEMS">
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbsize&amp;form.osfilter=AIX">DISKBSIZE >> Transfer rates per Disk</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbusy&amp;form.osfilter=AIX">DISKBUSY >> Percentage of Time Busy Disk</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskread&amp;form.osfilter=AIX">DISKREAD >> Disks Read Data rate</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwrite&amp;form.osfilter=AIX">DISKWRITE >> Disks Write Data rate</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskxfer&amp;form.osfilter=AIX">DISKXFER >> Disks I/O per second</a>
    +            <a href="UI_Nmon_STORAGE?form.osfilter=AIX">STORAGE >> File Systems utilization statistics</a>
    +        </collection>
    +
    +        <collection label="NETWORK">
    +            <a href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.net&amp;form.osfilter=AIX">NET >> In/Out network bandwidth</a>
    +            <a href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.netpacket&amp;form.osfilter=AIX">NETPACKET >> In/Out nbr of network packets</a>
    +            <a href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.neterror&amp;form.osfilter=AIX">NETERROR >> Nbr of network errors</a>
    +            <a href="UI_Nmon_NFS?form.osfilter=AIX">NFS >> Network File System statistics</a>
    +            <a href="UI_Nmon_SEATRAFFIC">SEATRAFFIC >> Shared Ethernet Adapters statistics</a>
    +            <a href="UI_Nmon_SEAPACKET">SEAPACKET >> Share Ethernet Adapters packets</a>
    +        </collection>
    +
    +        <collection label="CONFIGURATION">
    +            <a href="UI_Nmon_CONFIG?form.osfilter=AIX">CONFIG » Raw configuration viewer</a>
    +            <a href="UI_Nmon_CONFIG_simple_inventory_AIX">INVENTORY » Inventory Interface</a>
    +        </collection>
    +
    +        <collection label="DASHBOARDS">
    +            <a href="Dashboard_BubbleChart_top_hosts?form.osfilter=AIX" class="tryitbtn-alt">TOP CPU » Main hosts CPU Usage in bubblecharts</a>
    +            <a href="Dashboard_bulletcharts?form.osfilter=AIX" class="tryitbtn-alt">TOP CPU/MEMORY » Main hosts Usage in bulletcharts</a>
    +            <a href="Dashboard_Bubblechart_top_processes?form.osfilter=AIX">TOP Processes >> Main processes usage</a>
    +            <a href="Dashboard_heatmap_daily_usage?form.osfilter=AIX">CALENDAR >> heatmap calendar daily CPU usage</a>
    +            <a href="Dashboard_uptime?form.osfilter=AIX" class="tryitbtn-alt">UPTIME » Uptime evolution over time</a>
    +        </collection>
    +
    +        <collection label="Reports">
    +            <saved source="all" match="AIX" />
    +        </collection>
    +
    +    </collection>
    +
    +    <!--
    +    ####################################################################################################################
    +    This is the LINUX dedicated menu
    +    ####################################################################################################################
    +    -->
    +
    +    <collection label="LINUX">
    +        <a href="Home_LINUX">Start for Linux systems</a>
    +
    +        <collection label="METRICS EXPLORATION">
    +            <a href="Nmon_mexplorer?form.osfilter=Linux">M-EXPLORER</a>
    +        </collection>
    +
    +        <collection label="ANALYSE &amp; TROUBLESHOOT">
    +            <a href="Nmon_Summary?form.osfilter=Linux">SUMMARY OVERVIEW</a>
    +            <a href="Nmon_WOF?form.OStype=Linux">NMON WALL OF PERFORMANCE</a>
    +            <a href="Nmon_ANALYSER_LINUX">NMON ANALYSER</a>
    +        </collection>
    +
    +        <collection label="COMPARE, PREDICT &amp; FORECAST">
    +            <a href="Nmon_compare?form.osfilter1=Linux&amp;form.osfilter2=Linux">COMPARATIVE ANALYSIS</a>
    +            <a href="Nmon_predict?form.osfilter=Linux">PREDICTIVE ANALYSIS</a>
    +            <a href="Nmon_baseline?form.osfilter=Linux">BASELINE FORECASTING</a>
    +        </collection>
    +
    +        <collection label="CPU">
    +            <a href="UI_Nmon_CPU_ALL?form.osfilter=Linux">CPU_ALL >> Pct of CPU Utilization</a>
    +            <a href="UI_Nmon_LOAD_AVG?form.osfilter=Linux">SYS LOAD AVERAGE >> UPTIME load average statistics</a>
    +            <a href="UI_Nmon_CPUnn?form.osfilter=Linux">CPUnn >> Pct of CPU Utilization per logical core</a>
    +        </collection>
    +
    +        <collection label="PROCESS/KERNEL/IO">
    +            <a href="UI_Nmon_TOP_LINUX">TOP >> Main Processes System Resources Usage</a>
    +            <a href="UI_Nmon_UARG_LINUX">UARG >> PIDs, Commands and Arguments</a>
    +            <a href="UI_Nmon_PROC?form.osfilter=Linux">PROC >> Kernel Internal statistics</a>
    +            <a href="UI_Nmon_VM_LINUX">VM >> Kernel Virtual Memory statistics</a>
    +        </collection>
    +
    +        <collection label="MEMORY">
    +            <a href="UI_Nmon_MEM_LINUX">MEM >> Real and Virtual Memory statistics</a>
    +        </collection>
    +
    +        <collection label="DISKS/FILESYSTEMS">
    +            <a href="UI_Nmon_DG?form.osfilter=Linux">DG >> Disks extended statistics</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbsize&amp;form.osfilter=Linux">DISKBSIZE >> Transfer rates per Disk</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbusy&amp;form.osfilter=Linux">DISKBUSY >> Percentage of Time Busy Disk</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskread&amp;form.osfilter=Linux">DISKREAD >> Disks Read Data rate</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwrite&amp;form.osfilter=Linux">DISKWRITE >> Disks Write Data rate</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskxfer&amp;form.osfilter=Linux">DISKXFER >> Disks I/O per second</a>
    +            <a href="UI_Nmon_STORAGE?form.osfilter=Linux">STORAGE >> File Systems utilization statistics</a>
    +        </collection>
    +
    +        <collection label="NETWORK">
    +            <a href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.net&amp;form.osfilter=Linux">NET >> In/Out network bandwidth</a>
    +            <a href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.netpacket&amp;form.osfilter=Linux">NETPACKET >> In/Out nbr of network packets</a>
    +            <a href="UI_Nmon_NFS?form.osfilter=Linux">NFS >> Network File System statistics</a>
    +        </collection>
    +
    +        <collection label="CONFIGURATION">
    +            <a href="UI_Nmon_CONFIG?form.osfilter=Linux">CONFIG » Raw configuration viewer</a>
    +            <a href="UI_Nmon_CONFIG_simple_inventory_LINUX">INVENTORY » Inventory Interface</a>
    +        </collection>
    +
    +        <collection label="DASHBOARDS">
    +            <a href="Dashboard_BubbleChart_top_hosts?form.osfilter=Linux" class="tryitbtn-alt">TOP CPU » Main hosts CPU Usage in bubblecharts</a>
    +            <a href="Dashboard_bulletcharts?form.osfilter=Linux" class="tryitbtn-alt">TOP CPU/MEMORY » Main hosts Usage in bulletcharts</a>
    +            <a href="Dashboard_Bubblechart_top_processes?form.osfilter=Linux">TOP Processes >> Main processes usage</a>
    +            <a href="Dashboard_heatmap_daily_usage?form.osfilter=Linux">CALENDAR >> heatmap calendar daily CPU usage</a>
    +            <a href="Dashboard_uptime?form.osfilter=Linux" class="tryitbtn-alt">UPTIME » Uptime evolution over time</a>
    +        </collection>
    +
    +        <collection label="Reports">
    +            <saved source="all" match="Linux" />
    +        </collection>
    +
    +    </collection>
    +
    +    <!--
    +    ####################################################################################################################
    +    This is the SOLARIS dedicated menu
    +    ####################################################################################################################
    +    -->
    +
    +    <collection label="SOLARIS">
    +        <a href="Home_SOLARIS">Start for Solaris Systems</a>
    +
    +        <collection label="METRICS EXPLORATION">
    +            <a href="Nmon_mexplorer?form.osfilter=Solaris">M-EXPLORER</a>
    +        </collection>
    +
    +        <collection label="ANALYSE &amp; TROUBLESHOOT">
    +            <a href="Nmon_Summary?form.osfilter=Solaris">SUMMARY OVERVIEW</a>
    +            <a href="Nmon_WOF?form.OStype=Solaris">NMON WALL OF PERFORMANCE</a>
    +            <a href="Nmon_ANALYSER_SOLARIS">NMON ANALYSER</a>
    +        </collection>
    +
    +        <collection label="COMPARE, PREDICT &amp; FORECAST">
    +            <a href="Nmon_compare?form.osfilter1=Solaris&amp;form.osfilter2=Solaris">COMPARATIVE ANALYSIS</a>
    +            <a href="Nmon_predict?form.osfilter=Solaris">PREDICTIVE ANALYSIS</a>
    +            <a href="Nmon_baseline?form.osfilter=Solaris">BASELINE FORECASTING</a>
    +        </collection>
    +
    +        <collection label="CPU">
    +            <a href="UI_Nmon_CPU_ALL?form.osfilter=Solaris">CPU_ALL >> Pct of CPU Utilization</a>
    +            <a href="UI_Nmon_LOAD_AVG?form.osfilter=Solaris">SYS LOAD AVERAGE >> UPTIME load average statistics</a>
    +            <a href="UI_Nmon_CPUnn?form.osfilter=Solaris">CPUnn >> Pct of CPU Utilization per logical core</a>
    +            <a href="UI_Nmon_WLM_SOLARIS?form.type_monitor=CPU">WLM CPU >> CPU load for Projects, Tasks, Zones, Users</a>
    +        </collection>
    +
    +        <collection label="PROCESS/KERNEL/IO">
    +            <a href="UI_Nmon_TOP_SOLARIS">TOP >> Main Processes System Resources Usage</a>
    +            <a href="UI_Nmon_UARG_SOLARIS">UARG >> PIDs, Commands and Arguments</a>
    +            <a href="UI_Nmon_FILE?form.osfilter=Solaris">FILE >> Kernel File statistics</a>
    +            <a href="UI_Nmon_PROC?form.osfilter=Solaris">PROC >> Kernel Internal statistics</a>
    +            <a href="UI_Nmon_PROCSOL_SOLARIS">PROCSOL >> Percentage of Time Processes have spent in</a>
    +            <a href="UI_Nmon_VM_SOLARIS">VM >> Kernel Virtual Memory statistics</a>
    +        </collection>
    +
    +        <collection label="MEMORY">
    +            <a href="UI_Nmon_MEM_SOLARIS">MEM >> Real and Virtual Memory statistics</a>
    +            <a href="UI_Nmon_MEMUSE_SOLARIS">MEMUSE >> Various Memory statistics</a>
    +            <a href="UI_Nmon_WLM_SOLARIS?form.type_monitor=MEM">WLM MEM >> Memory load for Projects, Tasks, Zones, Users</a>
    +        </collection>
    +
    +        <collection label="DISKS/FILESYSTEMS">
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbsize&amp;form.osfilter=Solaris">DISKBSIZE >> Transfer rates per Disk</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbusy&amp;form.osfilter=Solaris">DISKBUSY >> Percentage of Time Busy Disk</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskread&amp;form.osfilter=Solaris">DISKREAD >> Disks Read Data rate</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwrite&amp;form.osfilter=Solaris">DISKWRITE >> Disks Write Data rate</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskxfer&amp;form.osfilter=Solaris">DISKXFER >> Disks I/O per second</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.disksvctm&amp;form.osfilter=Solaris">DISKSVCTM >> Disk Average Service time</a>
    +            <a href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwaittm&amp;form.osfilter=Solaris">DISKWAITTM >> Disk Average Wait time</a>
    +            <a href="UI_Nmon_STORAGE?form.osfilter=Solaris">STORAGE >> File Systems utilization statistics</a>
    +        </collection>
    +
    +        <collection label="NETWORK">
    +            <a href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.net&amp;form.osfilter=Solaris">NET >> In/Out network bandwidth</a>
    +            <a href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.netpacket&amp;form.osfilter=Solaris">NETPACKET >> In/Out nbr of network packets</a>
    +            <a href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.neterror&amp;form.osfilter=Solaris">NETERROR >> Nbr of network errors</a>
    +        </collection>
    +
    +        <collection label="CONFIGURATION">
    +            <a href="UI_Nmon_CONFIG?form.osfilter=Solaris">CONFIG » Raw configuration viewer</a>
    +            <a href="UI_Nmon_CONFIG_simple_inventory_SOLARIS">INVENTORY » Inventory Interface</a>
    +        </collection>
    +
    +        <collection label="DASHBOARDS">
    +            <a href="Dashboard_BubbleChart_top_hosts?form.osfilter=Solaris" class="tryitbtn-alt">TOP CPU » Main hosts CPU Usage in bubblecharts</a>
    +            <a href="Dashboard_bulletcharts?form.osfilter=Solaris" class="tryitbtn-alt">TOP CPU/MEMORY » Main hosts Usage in bulletcharts</a>
    +            <a href="Dashboard_Bubblechart_top_processes?form.osfilter=Solaris">TOP Processes >> Main processes usage</a>
    +            <a href="Dashboard_heatmap_daily_usage?form.osfilter=Solaris">CALENDAR >> heatmap calendar daily CPU usage</a>
    +            <a href="Dashboard_WLM_Solaris">WLM >> Solaris Workload Manager dashboard</a>
    +            <a href="Dashboard_uptime?form.osfilter=Solaris" class="tryitbtn-alt">UPTIME » Uptime evolution over time</a>
    +        </collection>
    +
    +        <collection label="Reports">
    +            <saved source="all" match="Solaris" />
    +        </collection>
    +
    +    </collection>
    +
    +    <!--
    +    ####################################################################################################################
    +    This is HOWTOS dedicated menu
    +    ####################################################################################################################
    +    -->
    +
    +    <collection label="HOWTOs">
    +        <a href="Howto_CPU_ALL_spl">CPU_ALL: percentage CPU usage statistics</a>
    +        <a href="Howto_LPAR_spl">LPAR: IBM Pseries partitions and pools statistics</a>
    +        <a href="Howto_MEM_spl">MEM: physical/virtual memory usage statistics</a>
    +        <a href="Howto_TOP_spl">TOP: processes usage statistics</a>
    +    </collection>
    +
    +    <!--
    +    ####################################################################################################################
    +    This is the Safe Center dedicated menu
    +    ####################################################################################################################
    +    -->
    +
    +    <collection label="ALERT CENTER">
    +        <a href="UI_Alert_Center">ALERT CENTER DASHBOARD</a>
    +        <a href="alerts">Splunk alerts builtin home</a>
    +
    +        <collection label="Threshold configuration">
    +            <a href="Manage_template_alerting_threshold">TEMPLATE alerting threshold for cpu &amp; memory</a>
    +            <a href="Manage_alerting_threshold">SERVER alerting threshold for cpu &amp; memory</a>
    +            <a href="Manage_template_alerting_threshold_filesystem">TEMPLATE alerting threshold for file-systems</a>
    +            <a href="Manage_alerting_threshold_filesystem">SERVER alerting threshold for file-systems</a>
    +        </collection>
    +
    +        <collection label="Exclusion configuration">
    +            <a href="Manage_file_systems_global_exclusion">GLOBAL alerting exclusion for file-systems</a>
    +            <a href="Manage_file_systems_template_exclusion">TEMPLATE alerting exclusion for file-systems</a>
    +            <a href="Manage_file_systems_exclusion">SERVER alerting exclusion for file-systems</a>
    +        </collection>
    +
    +        <collection label="Active Alerts reports">
    +            <saved name="ALERT CENTER - Number of active CPU alerts" />
    +            <saved name="ALERT CENTER - Number of active Real Memory alerts" />
    +            <saved name="ALERT CENTER - Number of active Virtual Memory alerts" />
    +            <saved name="ALERT CENTER - Number of active FS alerts" />
    +        </collection>
    +
    +        <collection label="Historical Alerts reports">
    +            <saved name="ALERT CENTER - CPU issues" />
    +            <saved name="ALERT CENTER - Real Memory issues" />
    +            <saved name="ALERT CENTER - Virtual Memory issues" />
    +            <saved name="ALERT CENTER - FS issues" />
    +        </collection>
    +
    +    </collection>
    +
    +    <!--
    +    ####################################################################################################################
    +    TA-nmon agents
    +    ####################################################################################################################
    +    -->
    +
    +    <collection label="ADD-ONS DEPLOYMENT">
    +        <a href="Dashboard_addons_reporting">Add-ons reporting</a>
    +
    +        <collection label="Reports">
    +            <saved source="all" match="Add-on" />
    +            <saved source="all" match="TA-metricator" />
    +            <saved source="all" match="Universal Forwarders" />
    +            <saved name="List of interpreter and interpreter versions per host" />
    +        </collection>
    +
    +    </collection>
    +
    +    <!--
    +    ####################################################################################################################
    +    Data models
    +    ####################################################################################################################
    +    -->
    +
    +    <collection label="Datasets">
    +        <a href="datasets">Datasets</a>
    +        <a href="data_model_manager">Data model manager</a>
    +
    +        <collection label="CONFIGURATION">
    +            <a href="pivot?model=%2FservicesNS%2Fnobody%2Fmetricator-for-nmon%2Fdatamodel%2Fmodel%2Fmetricator-nmon-config">Nmon Config</a>
    +        </collection>
    +
    +        <collection label="INTERNAL">
    +            <a href="pivot?model=%2FservicesNS%2Fnobody%2Fmetricator-for-nmon%2Fdatamodel%2Fmodel%2Fmetricator-nmon-processing">Nmon Processing - Data Collect</a>
    +        </collection>
    +
    +    </collection>
    +
    +    <!--
    +    ####################################################################################################################
    +    Splunk built-in
    +    ####################################################################################################################
    +    -->
    +
    +    <collection label="Search">
    +        <view name="search" />
    +        <view name="reports" />
    +        <view name="dashboards" />
    +        <view name="alerts" />
    +    </collection>
    +    <!--
    +    ####################################################################################################################
    +    Total Cost of Ownership
    +    ####################################################################################################################
    +    -->
    +
    +    <collection label="TCO">
    +        <a href="Dashboard_Internal_Stats">Total Cost of Ownership dashboard</a>
    +
    +        <collection label="Reports">
    +            <saved name="Volume of Data indexed Today" />
    +            <saved source="all" match="TCO -" />
    +        </collection>
    +
    +    </collection>
    +
    +    <!--
    +    ####################################################################################################################
    +    Settings
    +    ####################################################################################################################
    +    -->
    +
    +    <collection label="Settings">
    +        <a href="/manager/metricator-for-nmon/saved/searches?app=metricator-for-nmon">Reports settings</a>
    +        <a href="manage_frameid_mapping_v2">FRAMEID mapping enrichment</a>
    +
    +        <collection label="Alerting threshold configuration">
    +            <a href="manage_template_alerting_threshold_v2">TEMPLATE alerting threshold for cpu &amp; memory</a>
    +            <a href="manage_alerting_threshold_v2">SERVER alerting threshold for cpu &amp; memory</a>
    +            <a href="manage_template_alerting_threshold_filesystem_v2">TEMPLATE alerting threshold for file-systems</a>
    +            <a href="manage_alerting_threshold_filesystem_v2">SERVER alerting threshold for file-systems</a>
    +        </collection>
    +
    +        <collection label="Alerting exclusion configuration">
    +            <a href="manage_file_systems_global_exclusion_v2">GLOBAL alerting exclusion for file-systems</a>
    +            <a href="manage_file_systems_template_exclusion_v2">TEMPLATE alerting exclusion for file-systems</a>
    +            <a href="manage_file_systems_exclusion_v2">SERVER alerting exclusion for file-systems</a>
    +        </collection>
    +
    +    </collection>
    +
    +    <!--
    +    ####################################################################################################################
    +    Help
    +    ####################################################################################################################
    +    -->
    +
    +    <collection label="Help &amp; Support">
    +        <a href="https://www.octamis.com/services/metricator">Support plans</a>
    +        <a href="https://www.octamis.com/metricator-docs">Online Documentation</a>
    +        <a href="https://www.octamis.com/">OCTAMIS Website</a>
    +    </collection>
    +
    +    <!--
    +    ####################################################################################################################
    +    Run a search
    +    ####################################################################################################################
    +    -->
    +
    +    <a href="search">Run a search</a>
    +
    +</nav>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_BubbleChart_top_hosts.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_BubbleChart_top_hosts.xml
    new file mode 100644
    index 0000000..99249c8
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_BubbleChart_top_hosts.xml
    @@ -0,0 +1,249 @@
    +<form script="autodiscover.js" stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +    <label>Dashboard TOP Hosts, Higher CPU Load Hosts for All OS</label>
    +    <description>Easily visualize hosts with high level of resources utilization using Bubble charts</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype=</prefix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>avg</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Search based for post processing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.*" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="baseSearch">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.PhysicalCPU OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs OR metric_name=os.unix.nmon.cpu.lpar.partition_active_processors) host=$host-prefilter$ $host_query$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| stats $statsmode$(cpu_load_percent) AS cpu_load_percent by host
    +| eval cpu_load_percent=round(cpu_load_percent, 2)
    +| fields frameID,host,cpu_load_percent,*</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <title>TOP 100: Graphical Representation of Hosts (ordered by CPU Usage)</title>
    +            <html>
    +                <div id="bubbleSearch"
    +                     class="splunk-manager"
    +                     data-require="splunkjs/mvc/searchmanager"
    +                     data-options='{
    +                    "search": {
    +								"type": "token_safe",
    +                    		"value": "| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.PhysicalCPU OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs OR metric_name=os.unix.nmon.cpu.lpar.partition_active_processors) host=$$host-prefilter$$ $$host_query$$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| stats $$statsmode$$(cpu_load_percent) AS usage by host
    +| eval usage=round(usage, 2) | sort - usage | head 100"
    +						  },
    +          			  "earliest_time": {
    +            				"type": "token_safe",
    +            				"value": "$$timerange.earliest$$"
    +          				},
    +          				"latest_time": {
    +            				"type": "token_safe",
    +            				"value": "$$timerange.latest$$"
    +          				},
    +                    "auto_cancel": 90,
    +                    "preview": true
    +                 }'>
    +                </div>
    +                <div id="bubbleChart"
    +                     class="splunk-view"
    +                     data-require="app/metricator-for-nmon/components/bubblechart/bubblechart"
    +                     data-options='{
    +                    "managerid": "bubbleSearch",
    +                    "nameField": "host",
    +                    "categoryField": "host",
    +                    "valueField": "usage",
    +                    "height": 600
    +                 }'>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>TOP 50 CPU Usage Hosts (ordered by CPU Usage percentage of capacity)</title>
    +            <chart>
    +                <search base="baseSearch">
    +                    <query>sort - 0 cpu_load_percent | head 50
    +| eval xlabel=""| chart max(cpu_load_percent) AS cpu_load_percent useother=f limit=0 by xlabel,host
    +| rename xlabel AS "CPU % usage"</query>
    +                </search>
    +                <option name="charting.chart.columnSpacing">5</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleY.text">% CPU usage</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Hosts CPU Usage Table Stats (ordered by host)</title>
    +
    +            <table>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.PhysicalCPU OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs OR metric_name=os.unix.nmon.cpu.lpar.partition_active_processors) host=$host-prefilter$ $host_query$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| stats min(cpu_load_percent) AS min_cpu_load_percent avg(cpu_load_percent) AS avg_cpu_load_percent median(cpu_load_percent) AS median_cpu_load_percent max(cpu_load_percent) AS max_cpu_load_percent sparkline(avg(cpu_load_percent),) As sparkline by host
    +| eval cpu_load_percent=round(cpu_load_percent, 2)
    +| foreach *_percent [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 3) ]
    +| `mapping_frameID`
    +| fields frameID, host, min_cpu_load_percent, avg_cpu_load_percent, median_cpu_load_percent, max_cpu_load_percent, sparkline</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">50</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="min_cpu_load_percent">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_cpu_load_percent">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="median_cpu_load_percent">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="max_cpu_load_percent">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_Bubblechart_top_processes.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_Bubblechart_top_processes.xml
    new file mode 100644
    index 0000000..cd7f736
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_Bubblechart_top_processes.xml
    @@ -0,0 +1,336 @@
    +<form script="autodiscover.js,custom_layout.js" stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +    <label>NMON TOP: Resources Usage per Command Invocation</label>
    +    <description>TOP Processes CPU and Memory utilization using Bubble charts</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype=</prefix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>avg</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="text" token="dimension_Command" searchWhenChanged="true">
    +            <label>Optional: Filter by Command</label>
    +            <prefix>dimension_Command="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.*" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Search based for post processing -->
    +
    +    <search id="tablestats_cpu_per_command">
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.pct_CPU host=$host-prefilter$ $host_query$ ($dimension_Command$) by host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| `$timefilter$`
    +| eval usage_per_core=(pct_CPU/100)
    +| stats $statsmode$(usage_per_core) as usage by dimension_Command
    +| rename dimension_Command as Command
    +| eval usage=round(usage, 3)
    +| sort - usage</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="tablestats_cpu_per_host">
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.pct_CPU host=$host-prefilter$ $host_query$ ($dimension_Command$) by host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| `$timefilter$`
    +| eval usage_per_core=(pct_CPU/100)
    +| stats $statsmode$(usage_per_core) as usage by host, dimension_Command
    +| rename dimension_Command as Command
    +| eval usage=round(usage, 3)
    +| sort - usage</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>CPU Single Core Usage per Command Invocation (PIDs aggregation per interval)</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="panela1_setWidth_50">
    +            <title>Graphical Representation</title>
    +            <html>
    +                <div id="bubbleSearch"
    +                     class="splunk-manager"
    +                     data-require="splunkjs/mvc/searchmanager"
    +                     data-options="{&quot;search&quot;:
    +                     {
    +                     &quot;type&quot;:
    +                     &quot;token_safe&quot;,
    +                     &quot;value&quot;: &quot;| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.pct_CPU host=$$host-prefilter$$ $$host_query$$ ($$dimension_Command$$) by host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| `$$timefilter$$`
    +| eval usage_per_core=(pct_CPU/100)
    +| stats $$statsmode$$(usage_per_core) as usage by dimension_Command
    +| rename dimension_Command as Command
    +| eval usage=round(usage, 3)
    +| sort - usage | head 100&quot;},
    +                    &quot;earliest_time&quot;:
    +                    {&quot;type&quot;: &quot;token_safe&quot;,
    +                    &quot;value&quot;: &quot;$$timerange.earliest$$&quot;
    +                    },
    +                    &quot;latest_time&quot;: {&quot;type&quot;: &quot;token_safe&quot;,
    +                    &quot;value&quot;: &quot;$$timerange.latest$$&quot;
    +                    },
    +                    &quot;auto_cancel&quot;: 90,
    +                    &quot;preview&quot;: true
    +                    }">
    +                </div>
    +                <div id="bubbleChart" class="splunk-view" data-require="app/metricator-for-nmon/components/bubblechart/bubblechart" data-options="{
    +                &quot;managerid&quot;: &quot;bubbleSearch&quot;,
    +                &quot;nameField&quot;: &quot;Command&quot;,
    +                &quot;categoryField&quot;: &quot;Command&quot;,
    +                &quot;valueField&quot;: &quot;usage&quot;,
    +                &quot;height&quot;: 600
    +                }">
    +                </div>
    +            </html>
    +        </panel>
    +        <panel id="panela2_setWidth_25">
    +            <title>Stats by Commands</title>
    +            <table>
    +                <search base="tablestats_cpu_per_command">
    +                    <query></query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">20</option>
    +            </table>
    +        </panel>
    +        <panel id="panela3_setWidth_25">
    +            <title>Stats by Hosts</title>
    +            <table>
    +                <search base="tablestats_cpu_per_host">
    +                    <query></query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">20</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>MEMORY Statistics per Command Invocation (PIDs aggregation per interval)</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Search based for post processing -->
    +
    +    <search id="tablestats_memory_per_command">
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData host=$host-prefilter$ $host_query$ ($dimension_Command$) by metric_name, OStype, host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, metric_name, OStype, host, dimension_Command
    +| `$timefilter$`
    +| `def_all_os_top_memory`
    +| stats sum(mem_usage_mb) As mem_usage_mb by _time, host, dimension_Command
    +| stats $statsmode$(mem_usage_mb) as mem_usage_mb by dimension_Command
    +| rename dimension_Command as Command
    +| eval mem_usage_mb=round(mem_usage_mb, 2)
    +| sort - mem_usage_mb</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="tablestats_memory_per_host">
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData host=$host-prefilter$ $host_query$ ($dimension_Command$) by metric_name, OStype, host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, metric_name, OStype, host, dimension_Command
    +| `$timefilter$`
    +| `def_all_os_top_memory`
    +| stats sum(mem_usage_mb) As mem_usage_mb by _time, host, dimension_Command
    +| stats $statsmode$(mem_usage_mb) as mem_usage_mb by host, dimension_Command
    +| rename dimension_Command as Command
    +| eval mem_usage_mb=round(mem_usage_mb, 2)
    +| sort - mem_usage_mb</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel id="panelb1_setWidth_50">
    +            <title>Graphical Representation</title>
    +            <html>
    +                <div id="bubbleSearch2"
    +                     class="splunk-manager"
    +                     data-require="splunkjs/mvc/searchmanager"
    +                     data-options="{&quot;search&quot;:
    +                     {
    +                     &quot;type&quot;:
    +                     &quot;token_safe&quot;,
    +                     &quot;value&quot;: &quot;| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData host=$$host-prefilter$$ $$host_query$$ ($$dimension_Command$$) by metric_name, OStype, host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, metric_name, OStype, host, dimension_Command
    +| `$$timefilter$$`
    +| `def_all_os_top_memory`
    +| stats sum(mem_usage_mb) As mem_usage_mb by _time, host, dimension_Command
    +| stats max(mem_usage_mb) as mem_usage_mb by dimension_Command
    +| rename dimension_Command as Command
    +| eval mem_usage_mb=round(mem_usage_mb, 2)
    +| sort - mem_usage_mb | head 100&quot;},
    +                    &quot;earliest_time&quot;:
    +                    {&quot;type&quot;: &quot;token_safe&quot;,
    +                    &quot;value&quot;: &quot;$$timerange.earliest$$&quot;
    +                    },
    +                    &quot;latest_time&quot;: {&quot;type&quot;: &quot;token_safe&quot;,
    +                    &quot;value&quot;: &quot;$$timerange.latest$$&quot;
    +                    },
    +                    &quot;auto_cancel&quot;: 90,
    +                    &quot;preview&quot;: true
    +                    }">
    +                </div>
    +                <div id="bubbleChart2" class="splunk-view" data-require="app/metricator-for-nmon/components/bubblechart/bubblechart" data-options="{
    +                &quot;managerid&quot;: &quot;bubbleSearch2&quot;,
    +                &quot;nameField&quot;: &quot;Command&quot;,
    +                &quot;categoryField&quot;: &quot;Command&quot;,
    +                &quot;valueField&quot;: &quot;mem_usage_mb&quot;,
    +                &quot;height&quot;: 600
    +                }">
    +                </div>
    +            </html>
    +        </panel>
    +        <panel id="panelb2_setWidth_25">
    +            <title>Stats by Commands</title>
    +            <table>
    +                <search base="tablestats_memory_per_command">
    +                    <query></query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">20</option>
    +            </table>
    +        </panel>
    +        <panel id="panelb3_setWidth_25">
    +            <title>Stats by Hosts</title>
    +            <table>
    +                <search base="tablestats_memory_per_host">
    +                    <query></query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">20</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_Internal_Stats.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_Internal_Stats.xml
    new file mode 100644
    index 0000000..2d80523
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_Internal_Stats.xml
    @@ -0,0 +1,1080 @@
    +<dashboard stylesheet="ui_simple.css,hover.css,panel_decoration.css" script="active_button.js" isVisible="true" version="1.1" theme="dark">
    +    <label>Nmon Performance Monitor application - Total Cost of Ownership dashboard</label>
    +
    +    <row depends="$hidden_element$">
    +        <panel>
    +            <title>Hidden form</title>
    +            <single>
    +                <!-- This search will be used to verify if the user that run the dashboard has enough privilege to do so -->
    +                <search>
    +                    <query>index=_internal | head 100 | stats count | where count>0</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <!-- Progress event has access to job properties only -->
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_admin_required">True</set>
    +                        </condition>
    +                        <condition>
    +                            <unset token="show_admin_required"/>
    +                            <set token="start_admin_searches">True</set>
    +                        </condition>
    +                    </progress>
    +                </search>
    +            </single>
    +            <single>
    +                <!-- This search will be used to verify if we must show the null global indexing message, this performs best than integrating the progress condition with the search -->
    +                <search>
    +                    <query>| mcatalog values(metric_name) as metrics where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.*
    +| rename metrics as metric_name
    +| mvexpand metric_name | stats count | where count>0</query>
    +                    <earliest>@d</earliest>
    +                    <latest>@h</latest>
    +                    <!-- Progress event has access to job properties only -->
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_null_per_server_indexing">True</set>
    +                        </condition>
    +                        <condition>
    +                            <set token="start_indexing_per_server_search">True</set>
    +                            <unset token="show_null_per_server_indexing"></unset>
    +                        </condition>
    +                    </progress>
    +                </search>
    +            </single>
    +            <single>
    +                <!-- This search will be used to verify if we must show the null global indexing message, this performs best than integrating the progress condition with the search -->
    +                <search>
    +                    <query>index=_internal source=*license_usage.log* type=Usage `nmon_idx` | stats count | where count>0</query>
    +                    <earliest>-1d@d</earliest>
    +                    <latest>@d</latest>
    +                    <!-- Progress event has access to job properties only -->
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_null_global_indexing">True</set>
    +                        </condition>
    +                        <condition>
    +                            <set token="start_global_indexing_search">True</set>
    +                            <unset token="show_null_global_indexing"></unset>
    +                        </condition>
    +                    </progress>
    +                </search>
    +            </single>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cost1">
    +            <title>LICENCING: Total Cost of Ownership per server</title>
    +            <single rejects="$show_admin_required$ $show_null_per_server_indexing$">
    +                <search rejects="$show_admin_required$ $show_null_per_server_indexing$">
    +                    <query>index=_internal source=*license_usage.log* type=Usage `nmon_idx` | where b>0 | timechart span=1h sum(b) AS b  | eval volume_MB = round(b/1024/1024,2)
    +| fillnull value=0
    +| appendcols [ | mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.*" by host span=1h |  timechart span=1h dc(host) as dcount ]
    +| eval cost_per_server_MB=(volume_MB/dcount) | stats avg(cost_per_server_MB) AS cost_per_server_MB
    +| eval estimated_cost_per_server_MB=round(cost_per_server_MB*24, 2)
    +| fields estimated_cost_per_server_MB</query>
    +                    <earliest>-7d@d</earliest>
    +                    <latest>@h</latest>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="underLabel">ESTIMATED PER DAY/SERVER COST</option>
    +                <option name="unit">MB</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">0</option>
    +                <option name="useThousandSeparators">1</option>
    +            </single>
    +            <html depends="$show_null_per_server_indexing$" rejects="$show_admin_required$">
    +                <div style="color:blue;margin-left:30px;font-size:14px;text-align:left;font-style:italic">
    +                    <br /><br/><br />
    +                    <p>Data not yet available, calculation is performed on a full per hour basis and will start being available 1 hour after application deployment and indexing activity.</p>
    +                </div>
    +            </html>
    +            <html depends="$show_admin_required$">
    +                <div style="color:red;margin-left:30px;font-size:18px;text-align:center;">
    +                    <p>Oops ! Admin privileges required to access these statistics !</p>
    +                </div>
    +            </html>
    +            <html>
    +                <div style="color:grey;margin-left:30px;font-size:12px;font-style:italic">
    +                    <p>* AVERAGE LICENCING COST PER SERVER: Calculation over last 7 days of the per hour volume of data generated per server multiplied per 24 hours</p>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel id="cost2">
    +            <title>LICENCING: Total Cost of Ownership of global indexing</title>
    +            <single rejects="$show_admin_required$ $show_null_global_indexing$">
    +                <search rejects="$show_admin_required$ $show_null_global_indexing$">
    +                    <query>index=_internal source=*license_usage.log* type=Usage `nmon_idx` | where b>0 | timechart span=1d sum(b) AS b
    +| fillnull value=0
    +| stats avg(b) AS avg_volume_per_day
    +| eval avg_volume_per_day_GB=round((avg_volume_per_day/1024/1024/1024),2)
    +| fields avg_volume_per_day_GB</query>
    +                    <earliest>-7d@d</earliest>
    +                    <latest>@d</latest>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="underLabel">TOTAL LICENCING COST PER DAY</option>
    +                <option name="unit">GB</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">0</option>
    +                <option name="useThousandSeparators">1</option>
    +            </single>
    +            <html depends="$show_null_global_indexing$" rejects="$show_admin_required$">
    +                <div style="color:blue;margin-left:30px;font-size:14px;text-align:left;font-style:italic">
    +                    <br /><br/><br />
    +                    <p>Data not yet available, calculation is performed on a full per day basis and will start being available 1 day after application deployment.</p>
    +                </div>
    +            </html>
    +            <html depends="$show_admin_required$">
    +                <div style="color:red;margin-left:30px;font-size:18px;text-align:center;">
    +                    <p>Oops ! Admin privileges required to access these statistics !</p>
    +                </div>
    +            </html>
    +            <html>
    +                <div style="color:grey;margin-left:30px;font-size:12px;font-style:italic">
    +                    <p>* TOTAL LICENCING COST PER DAY: Calculation over last 7 full full days of the per day total volume indexed for the nmon index</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Meta metrics -->
    +
    +    <row>
    +        <panel>
    +            <title>META METRICS:</title>
    +
    +            <html>
    +                <div style="font-style: italic;">
    +                    <p>
    +                        <b>Meta metrics</b> are volume calculations based on the application metrics design and naming convention.
    +                        <br />
    +                        This provides accurate and easy insights to analyse the volume of data related to each category of metric, Nmon metric section or even specific servers.
    +                        <br /> <br />
    +                        You can manage metrics to be generated within the <b>nmon.conf</b> file, globally for your Technical Addon deployment with a local/nmon.conf, or on per server basis in /etc/nmon.conf
    +                    </p>
    +                </div>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="meta_volume_by_metric_category">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by metric_name span=1d
    +| rex field=metric_name "os\.unix\.nmon\.(?&lt;metric_category&gt;[^\.]*)\."
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, metric_category
    +| stats avg(size_MB) as size_MB by metric_category
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_metric_section">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by metric_name span=1d
    +| rex field=metric_name "os\.unix\.nmon\.[^\.]*.(?&lt;metric_section&gt;[^\.]*)"
    +| stats sum(count) as count by _time, metric_section
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, metric_section
    +| stats avg(size_MB) as size_MB by metric_section
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_host">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by host span=1d
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, host
    +| stats avg(size_MB) as size_MB by host
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_ostype">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by OStype span=1d
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, OStype
    +| stats avg(size_MB) as size_MB by OStype
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <title>metric_category daily volumes</title>
    +        </panel>
    +        <panel>
    +            <title>metric_section daily volumes</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_metric_category">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_metric_section">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_metric_category">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_metric_section">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>hosts daily volumes</title>
    +        </panel>
    +        <panel>
    +            <title>Operating systems daily volumes</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_host">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_ostype">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_host">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_ostype">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <!-- main search for scheduling cost -->
    +    <search id="scheduling_mainsearch" depends="$start_admin_searches$">
    +        <query>index=_internal host="*" source=*scheduler.log status="*" NOT (status="continued" OR status=delegated*) savedsearch_name!="*_ACCELERATE_*" app="metricator-for-nmon"
    +| timechart span=1d avg(run_time) AS avg_run_time, max(run_time) AS max_run_time, sum(run_time) AS sum_run_time
    +| stats avg(avg_run_time) AS avg_run_time, avg(max_run_time) AS max_run_time, avg(sum_run_time) AS sum_run_time</query>
    +        <earliest>-24h</earliest>
    +        <latest>now</latest>
    +        <sampleRatio>1</sampleRatio>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <title>SCHEDULING COST</title>
    +            <single rejects="$show_admin_required$">
    +                <search depends="$start_admin_searches$">
    +                    <query>index=_internal host="*" source=*scheduler.log status="*" NOT (status="continued" OR status=delegated*) savedsearch_name!="*_ACCELERATE_*" app="metricator-for-nmon"
    +| bucket _time span=5m
    +| stats count AS count by _time
    +| stats avg(count) AS avg_scheduled_per_5min</query>
    +                    <earliest>-24h</earliest>
    +                    <latest>now</latest>
    +                    <sampleRatio>1</sampleRatio>
    +                </search>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="underLabel">AVERAGE NUMBER OF SCHEDULED SEARCHED PER 5 MIN</option>
    +                <option name="unit">Scheduled searches / 5 min</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">0</option>
    +                <option name="useThousandSeparators">1</option>
    +            </single>
    +            <single rejects="$show_admin_required$">
    +                <search base="scheduling_mainsearch">
    +                    <query>fields avg_run_time</query>
    +                </search>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="underLabel">AVERAGE RUN TIME PER DAY</option>
    +                <option name="unit">seconds</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">0</option>
    +                <option name="useThousandSeparators">1</option>
    +            </single>
    +            <single rejects="$show_admin_required$">
    +                <search base="scheduling_mainsearch">
    +                    <query>fields max_run_time</query>
    +                </search>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="underLabel">MAX RUN TIME PER DAY</option>
    +                <option name="unit">seconds</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">0</option>
    +                <option name="useThousandSeparators">1</option>
    +            </single>
    +            <single rejects="$show_admin_required$">
    +                <search base="scheduling_mainsearch">
    +                    <query>fields sum_run_time</query>
    +                </search>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="underLabel">AVERAGE SUM RUN TIME PER DAY</option>
    +                <option name="unit">seconds</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">0</option>
    +                <option name="useThousandSeparators">1</option>
    +            </single>
    +        </panel>
    +    </row>
    +
    +    <search id="dbinspect">
    +        <query>| dbinspect `nmon_index`
    +| eval rawSize_MB=(rawSize/1024/1024)
    +| stats sum(rawSize_MB) AS rawSize_MB, sum(sizeOnDiskMB) AS sizeOnDiskMB, dc(bucketId) AS dcount_bucket
    +| eval compress_ratio = round(rawSize_MB / sizeOnDiskMB, 2)." : 1"
    +| eval rawSize_GB=round(rawSize_MB/1024, 2), sizeOnDiskGB=round(sizeOnDiskMB/1024, 2)
    +| eval avg_size_perbucket_GB=round(((sizeOnDiskMB/dcount_bucket)/1024), 2)</query>
    +        <earliest>0</earliest>
    +        <latest></latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <title>INDEX STORAGE DETAILS</title>
    +            <single>
    +                <search base="dbinspect">
    +                    <query>fields sizeOnDiskGB</query>
    +                </search>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="underLabel">SIZE OF INDEX</option>
    +                <option name="unit">GB</option>
    +            </single>
    +            <single>
    +                <search base="dbinspect">
    +                    <query>fields rawSize_GB</query>
    +                </search>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="underLabel">TOTAL SIZE OF UNCOMPRESSED DATA</option>
    +                <option name="unit">GB</option>
    +            </single>
    +            <single>
    +                <search base="dbinspect">
    +                    <query>fields compress_ratio</query>
    +                </search>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="underLabel">Raw to Index Size Ratio</option>
    +            </single>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_indexing_storage_details" data-alt-label="HIDE PER INDEX DETAILS" data-token-value="true">SHOW PER INDEX DETAILS</button>
    +                </div>
    +            </html>
    +            <table depends="$show_indexing_storage_details$">
    +                <search depends="$show_indexing_storage_details$">
    +                    <query>| dbinspect `nmon_index`
    +| eval rawSize_MB=(rawSize/1024/1024)
    +| stats sum(rawSize_MB) AS rawSize_MB, sum(sizeOnDiskMB) AS sizeOnDiskMB, dc(bucketId) AS dcount_bucket by index
    +| eval compress_ratio = round(rawSize_MB / sizeOnDiskMB, 2)." : 1"
    +| eval rawSize_GB=round(rawSize_MB/1024, 2), sizeOnDiskGB=round(sizeOnDiskMB/1024, 2)
    +| eval avg_size_perbucket_GB=round(((sizeOnDiskMB/dcount_bucket)/1024), 2), rawSize_MB=round(rawSize_MB, 2), sizeOnDiskMB=round(sizeOnDiskMB, 2)</query>
    +                    <earliest>0</earliest>
    +                    <latest>now</latest>
    +                </search>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <title>INDEX BUCKETS DETAILS</title>
    +            <single>
    +                <search base="dbinspect">
    +                    <query>fields avg_size_perbucket_GB</query>
    +                </search>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="underLabel">AVERAGE BUCKET SIZE</option>
    +                <option name="unit">GB</option>
    +            </single>
    +            <single>
    +                <search base="dbinspect">
    +                    <query>fields dcount_bucket</query>
    +                </search>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="underLabel">TOTAL BUCKETS</option>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| dbinspect `nmon_index`
    +| stats dc(bucketId) AS dcount by state
    +| search state=hot | fields dcount</query>
    +                    <earliest>0</earliest>
    +                    <latest></latest>
    +                </search>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="underLabel">HOT BUCKETS</option>
    +            </single>
    +            <single rejects="$show_null_warm$">
    +                <search>
    +                    <query>| dbinspect `nmon_index`
    +| stats dc(bucketId) AS dcount by state
    +| search state=warm | fields dcount</query>
    +                    <earliest>0</earliest>
    +                    <latest></latest>
    +                    <!-- Progress event has access to job properties only -->
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_null_warm">True</set>
    +                        </condition>
    +                        <condition>
    +                            <unset token="show_null_warm"></unset>
    +                        </condition>
    +                    </progress>
    +                </search>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="underLabel">WARM BUCKETS</option>
    +            </single>
    +            <html depends="$show_null_warm$">
    +                <p style="color:blue;margin-left:30px;font-size:14px;font-style:italic">Currently no warm buckets.</p>
    +            </html>
    +            <single rejects="$show_null_cold$">
    +                <search>
    +                    <query>| dbinspect `nmon_index`
    +| stats dc(bucketId) AS dcount by state
    +| search state=cold | fields dcount</query>
    +                    <earliest>0</earliest>
    +                    <latest></latest>
    +                    <!-- Progress event has access to job properties only -->
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_null_cold">True</set>
    +                        </condition>
    +                        <condition>
    +                            <unset token="show_null_cold"></unset>
    +                        </condition>
    +                    </progress>
    +                </search>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="underLabel">COLD BUCKETS</option>
    +            </single>
    +            <html depends="$show_null_cold$">
    +                <p style="color:blue;margin-left:30px;font-size:14px;font-style:italic">Currently no cold buckets.</p>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Search based for post processing -->
    +
    +    <!-- Nmon Processing statistics -->
    +
    +    <search id="nmon_processing" depends="$show_processing$">
    +        <query>| pivot metricator-nmon-processing NMON_Processing sum(nbr_lines) AS "sum_nbr_lines" avg(nbr_lines) AS "avg_nbr_lines" max(size_in_bytes) AS "max_size"
    +avg(size_in_bytes) AS "avg_size" sum(size_in_bytes) AS "sum_size" avg(elapsed_in_seconds) AS "avg_elapsed_in_seconds" sum(elapsed_in_seconds) AS "sum_elapsed"
    +ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1 | eval avg_size_MB=round((avg_size/1000/1000),2) | eval max_size_MB=round((max_size/1000/1000),2)
    +| eval sum_size_GB=round((sum_size/1000/1000/1000),2) | eval elapsed_in_seconds=round(elapsed_in_seconds,2) | eval sum_elapsed=tostring(sum_elapsed,"duration")
    +| eval avg_nbr_lines=round(avg_nbr_lines,0) | eval sum_nbr_lines_in_millions=round((sum_nbr_lines/1000/1000),2)
    +| fields - show_processing</query>
    +        <earliest>$timerange_processing.earliest$</earliest>
    +        <latest>$timerange_processing.latest$</latest>
    +    </search>
    +
    +    <search id="nmon_processing_countnmon" depends="$show_processing$">
    +        <query>| pivot metricator-nmon-processing NMON_Processing count(NMON_Processing) AS "count" ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1
    +| fields - show_processing</query>
    +        <earliest>$timerange_processing.earliest$</earliest>
    +        <latest>$timerange_processing.latest$</latest>
    +    </search>
    +
    +    <search id="nmon_processing_elapsed_bytime" depends="$show_processing$">
    +        <query>| pivot metricator-nmon-processing NMON_Processing avg(elapsed_in_seconds) AS "avg_elapsed_in_seconds" SPLITROW _time AS _time PERIOD auto SORT 0 _time ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1 | eval avg_elapsed_in_seconds=round(avg_elapsed_in_seconds,2)
    +| fields - show_processing</query>
    +        <earliest>$timerange_processing.earliest$</earliest>
    +        <latest>$timerange_processing.latest$</latest>
    +    </search>
    +
    +    <search id="nmon_processing_errors">
    +        <query>| pivot metricator-nmon-processing Errors_in_Processing count(Errors_in_Processing) AS "count" ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1</query>
    +        <earliest>$timerange_processing.earliest$</earliest>
    +        <latest>$timerange_processing.latest$</latest>
    +    </search>
    +
    +    <search id="nmon_collect_errors">
    +        <query>eventtype=nmon:collect error | stats count As nbr_errors</query>
    +        <earliest>$timerange_processing.earliest$</earliest>
    +        <latest>$timerange_processing.latest$</latest>
    +    </search>
    +
    +    <!-- Event Count -->
    +
    +    <search id="eventcount_search" depends="$show_eventcount$">
    +        <query>| eventcount summarize=false report_size=true `nmon_index`
    +| stats sum(count) as count, sum(size_bytes) as size_bytes
    +| eval "Size (MB)" = round(size_bytes/1024/1024,2) | eval "Millions of Events" = round(count/1000000,2)
    +| fields index, server, "Size (MB)", "Millions of Events"</query>
    +        <earliest>0</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <!-- Metadata -->
    +
    +    <search id="metadata_search" depends="$show_eventcount$">
    +        <query>| `indexes_datestats`</query>
    +        <earliest>0</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <!-- Application Activity -->
    +
    +    <!-- Hits per page -->
    +
    +    <search id="hitsperpage_search">
    +        <query>index=_internal sourcetype=*web_access* OR sourcetype=*django_access* uri=*/app/metricator-for-nmon/* OR uri=*/dj/*/nmon/* method=GET file!=*.png AND file!=*.css AND file!=*.js AND file!=*.svg AND file!=Home* AND file!=report</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Scheduler Activity for the Application -->
    +
    +    <search id="scheduler_chart_search">
    +        <query>index=_internal host="*" source=*scheduler.log status="*" AND status!="continued" app="metricator-for-nmon" | timechart limit=0 count by app</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- ######################################### Active Buttons #########################################  -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_indexing_overtime" data-alt-label="HIDE INDEXING VOLUME OVER TIME" data-token-value="true">SHOW INDEXING VOLUME OVER TIME</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_eventcount" data-alt-label="HIDE INDEX EVENTCOUNT STATS" data-token-value="true">SHOW INDEX EVENTCOUNT STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_scheduled_stats" data-alt-label="HIDE PER REPORT SCHEDULED STATS" data-token-value="true">SHOW PER REPORT SCHEDULED STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_processing" data-alt-label="HIDE NMON PROCESSING STATS" data-token-value="true">SHOW NMON PROCESSING STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### Indexing volume over time #########################################  -->
    +
    +    <row depends="$show_indexing_overtime$">
    +        <panel>
    +            <title>Indexing volume over time (GB)</title>
    +            <input type="time" token="timerange_volume" searchWhenChanged="true">
    +                <label>Time Range:</label>
    +                <default>
    +                    <earliest>-30d@d</earliest>
    +                    <latest>now</latest>
    +                </default>
    +            </input>
    +            <chart rejects="$show_admin_required$">
    +                <search id="metric_timechartsearch" depends="$start_admin_searches$">
    +                    <query>index=_internal source=*license_usage.log* type=Usage `nmon_idx`
    +| where b>0 | bucket _time span=1m
    +| stats sum(b) AS b by _time,idx
    +| timechart span=1d sum(b) AS b
    +| eval volume_per_day_GB=round((b/1024/1024/1024),2)
    +| fields _time,volume_per_day_GB</query>
    +                    <earliest>$timerange_volume.earliest$</earliest>
    +                    <latest>$timerange_volume.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">400</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Gigabytes</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +            <html depends="$show_admin_required$">
    +                <div style="color:red;margin-left:30px;font-size:18px;text-align:center;">
    +                    <p>Oops ! Admin privileges required to access these statistics !</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### Processing statistics #########################################  -->
    +
    +    <row depends="$show_processing$">
    +
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>Nmon Processing statistics</h1>
    +                </div>
    +            </html>
    +            <input type="time" token="timerange_processing" searchWhenChanged="true">
    +                <label>Time Range:</label>
    +                <default>
    +                    <earliest>-24h</earliest>
    +                    <latest>now</latest>
    +                </default>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_processing$">
    +        <panel>
    +
    +            <single>
    +                <search base="nmon_processing">
    +                    <query>fields avg_nbr_lines</query>
    +                </search>
    +                <option name="underLabel">Avg nbr of lines per nmon file</option>
    +                <option name="unit">lines</option>
    +                <option name="drilldown">all</option>
    +                <drilldown target="search">
    +                    <link>search?q=| pivot metricator-nmon-processing NMON_Processing sum(nbr_lines) AS "sum_nbr_lines" avg(nbr_lines) AS "avg_nbr_lines" max(size_in_bytes) AS "max_size" avg(size_in_bytes) AS "avg_size" sum(size_in_bytes) AS "sum_size" avg(elapsed_in_seconds) AS "avg_elapsed_in_seconds" sum(elapsed_in_seconds) AS "sum_elapsed" ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1 | eval avg_size_MB=round((avg_size/1000/1000),2) | eval max_size_MB=round((max_size/1000/1000),2)
    +| eval sum_size_GB=round((sum_size/1000/1000/1000),2) | eval elapsed_in_seconds=round(elapsed_in_seconds,2) | eval sum_elapsed=tostring(sum_elapsed,"duration")
    +| eval avg_nbr_lines=round(avg_nbr_lines,0) | eval sum_nbr_lines_in_millions=round((sum_nbr_lines/1000/1000),2)</link>
    +                </drilldown>
    +            </single>
    +
    +            <single>
    +                <search base="nmon_processing">
    +                    <query>fields sum_nbr_lines_in_millions</query>
    +                </search>
    +                <option name="underLabel">Number of lines proceeded</option>
    +                <option name="unit">Millions</option>
    +                <option name="drilldown">all</option>
    +                <drilldown target="search">
    +                    <link>search?q=| pivot metricator-nmon-processing NMON_Processing sum(nbr_lines) AS "sum_nbr_lines" avg(nbr_lines) AS "avg_nbr_lines" max(size_in_bytes) AS "max_size" avg(size_in_bytes) AS "avg_size" sum(size_in_bytes) AS "sum_size" avg(elapsed_in_seconds) AS "avg_elapsed_in_seconds" sum(elapsed_in_seconds) AS "sum_elapsed" ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1
    +| eval avg_size_MB=round((avg_size/1000/1000),2) | eval max_size_MB=round((max_size/1000/1000),2)
    +| eval sum_size_GB=round((sum_size/1000/1000/1000),2) | eval elapsed_in_seconds=round(elapsed_in_seconds,2) | eval sum_elapsed=tostring(sum_elapsed,"duration")
    +| eval avg_nbr_lines=round(avg_nbr_lines,0) | eval sum_nbr_lines_in_millions=round((sum_nbr_lines/1000/1000),2)</link>
    +                </drilldown>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single>
    +                <search base="nmon_processing">
    +                    <query>fields sum_size_GB</query>
    +                </search>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="underLabel">Total nmon raw data converted</option>
    +                <option name="unit">GB</option>
    +                <drilldown target="search">
    +                    <link>search?q=| pivot metricator-nmon-processing NMON_Processing sum(nbr_lines) AS "sum_nbr_lines" avg(nbr_lines) AS "avg_nbr_lines" max(size_in_bytes) AS "max_size" avg(size_in_bytes) AS "avg_size" sum(size_in_bytes) AS "sum_size" avg(elapsed_in_seconds) AS "avg_elapsed_in_seconds" sum(elapsed_in_seconds) AS "sum_elapsed" ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1
    +| eval avg_size_MB=round((avg_size/1000/1000),2)| eval max_size_MB=round((max_size/1000/1000),2)
    +| eval sum_size_GB=round((sum_size/1000/1000/1000),2) | eval elapsed_in_seconds=round(elapsed_in_seconds,2) | eval sum_elapsed=tostring(sum_elapsed,"duration")
    +| eval avg_nbr_lines=round(avg_nbr_lines,0) | eval sum_nbr_lines_in_millions=round((sum_nbr_lines/1000/1000),2)</link>
    +                </drilldown>
    +            </single>
    +
    +            <single>
    +                <search base="nmon_processing_countnmon">
    +                    <query>fields count</query>
    +                </search>
    +                <option name="underLabel">Number of nmon files proceeded</option>
    +                <drilldown target="search">
    +                    <link>search?q=| pivot metricator-nmon-processing NMON_Processing count(NMON_Processing) AS "count" ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1</link>
    +                </drilldown>
    +            </single>
    +
    +            <single>
    +                <search base="nmon_processing_errors">
    +                    <query></query>
    +                </search>
    +                <option name="underLabel">Errors found in Data Processing</option>
    +                <drilldown target="search">
    +                    <link>search?q=| pivot metricator-nmon-processing Errors_in_Processing count(Errors_in_Processing) AS "count" ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1</link>
    +                </drilldown>
    +            </single>
    +
    +            <single>
    +                <search base="nmon_collect_errors">
    +                    <query></query>
    +                </search>
    +                <option name="underLabel">Errors found in Data Collect</option>
    +                <drilldown target="search">
    +                    <link>search?q=eventtype=nmon:collect error | stats count As nbr_errors</link>
    +                </drilldown>
    +            </single>
    +
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_processing$">
    +        <panel>
    +            <title>Nmon Raw Data conversion: Volumes proceeded over time (MB)</title>
    +
    +            <single>
    +                <search base="nmon_processing">
    +                    <query>fields avg_size_MB</query>
    +                </search>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="underLabel">Avg size of Nmon files</option>
    +                <option name="unit">MB</option>
    +                <drilldown target="search">
    +                    <link>search?q=| pivot metricator-nmon-processing NMON_Processing sum(nbr_lines) AS "sum_nbr_lines" avg(nbr_lines) AS "avg_nbr_lines" max(size_in_bytes) AS "max_size" avg(size_in_bytes) AS "avg_size" sum(size_in_bytes) AS "sum_size" avg(elapsed_in_seconds) AS "avg_elapsed_in_seconds" sum(elapsed_in_seconds) AS "sum_elapsed" ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1
    +| eval avg_size_MB=round((avg_size/1000/1000),2) | eval max_size_MB=round((max_size/1000/1000),2)
    +| eval sum_size_GB=round((sum_size/1000/1000/1000),2) | eval elapsed_in_seconds=round(elapsed_in_seconds,2) | eval sum_elapsed=tostring(sum_elapsed,"duration")
    +| eval avg_nbr_lines=round(avg_nbr_lines,0) | eval sum_nbr_lines_in_millions=round((sum_nbr_lines/1000/1000),2)</link>
    +                </drilldown>
    +            </single>
    +
    +            <single>
    +                <search base="nmon_processing">
    +                    <query>fields max_size_MB</query>
    +                </search>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="underLabel">Max size of Nmon files</option>
    +                <option name="unit">MB</option>
    +                <drilldown target="search">
    +                    <link>search?q=| pivot metricator-nmon-processing NMON_Processing sum(nbr_lines) AS "sum_nbr_lines" avg(nbr_lines) AS "avg_nbr_lines" max(size_in_bytes) AS "max_size" avg(size_in_bytes) AS "avg_size" sum(size_in_bytes) AS "sum_size" avg(elapsed_in_seconds) AS "avg_elapsed_in_seconds" sum(elapsed_in_seconds) AS "sum_elapsed" ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1
    +| eval avg_size_MB=round((avg_size/1000/1000),2) | eval max_size_MB=round((max_size/1000/1000),2)
    +| eval sum_size_GB=round((sum_size/1000/1000/1000),2) | eval elapsed_in_seconds=round(elapsed_in_seconds,2) | eval sum_elapsed=tostring(sum_elapsed,"duration")
    +| eval avg_nbr_lines=round(avg_nbr_lines,0) | eval sum_nbr_lines_in_millions=round((sum_nbr_lines/1000/1000),2)</link>
    +                </drilldown>
    +            </single>
    +
    +            <chart>
    +                <search depends="$show_processing$">
    +                    <query>| pivot metricator-nmon-processing NMON_Processing sum(size_in_bytes) AS "sum_size_MB" SPLITROW _time AS _time PERIOD auto SORT 0 _time ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1
    +| eval sum_size_MB=round((sum_size_MB/1000/1000),2)
    +| fields - show_processing</query>
    +                    <earliest>$timerange_processing.earliest$</earliest>
    +                    <latest>$timerange_processing.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">400</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +
    +        </panel>
    +
    +        <panel>
    +            <title>Nmon Raw Data conversion: Average elapsed time per Nmon file (seconds)</title>
    +
    +            <single>
    +                <search base="nmon_processing">
    +                    <query>fields avg_elapsed_in_seconds</query>
    +                </search>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="underLabel">Avg Time required to convert an Nmon File</option>
    +                <option name="unit">seconds</option>
    +                <drilldown target="search">
    +                    <link>search?q=| pivot metricator-nmon-processing NMON_Processing sum(nbr_lines) AS "sum_nbr_lines" avg(nbr_lines) AS "avg_nbr_lines" max(size_in_bytes) AS "max_size" avg(size_in_bytes) AS "avg_size" sum(size_in_bytes) AS "sum_size" avg(elapsed_in_seconds) AS "avg_elapsed_in_seconds" sum(elapsed_in_seconds) AS "sum_elapsed" ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1
    +| eval avg_size_MB=round((avg_size/1000/1000),2) | eval max_size_MB=round((max_size/1000/1000),2)
    +| eval sum_size_GB=round((sum_size/1000/1000/1000),2) | eval elapsed_in_seconds=round(elapsed_in_seconds,2) | eval sum_elapsed=tostring(sum_elapsed,"duration")
    +| eval avg_nbr_lines=round(avg_nbr_lines,0) | eval sum_nbr_lines_in_millions=round((sum_nbr_lines/1000/1000),2)</link>
    +                </drilldown>
    +            </single>
    +
    +            <single>
    +                <search base="nmon_processing">
    +                    <query>fields sum_elapsed</query>
    +                </search>
    +                <option name="underLabel">Total Time Spent in converting Nmon Data</option>
    +                <option name="unit">Time (HH:MM:SS...)</option>
    +                <drilldown target="search">
    +                    <link>search?q=| pivot metricator-nmon-processing NMON_Processing sum(nbr_lines) AS "sum_nbr_lines" avg(nbr_lines) AS "avg_nbr_lines" max(size_in_bytes) AS "max_size" avg(size_in_bytes) AS "avg_size" sum(size_in_bytes) AS "sum_size" avg(elapsed_in_seconds) AS "avg_elapsed_in_seconds" sum(elapsed_in_seconds) AS "sum_elapsed" ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1
    +| eval avg_size_MB=round((avg_size/1000/1000),2) | eval max_size_MB=round((max_size/1000/1000),2)
    +| eval sum_size_GB=round((sum_size/1000/1000/1000),2) | eval elapsed_in_seconds=round(elapsed_in_seconds,2) | eval sum_elapsed=tostring(sum_elapsed,"duration")
    +| eval avg_nbr_lines=round(avg_nbr_lines,0) | eval sum_nbr_lines_in_millions=round((sum_nbr_lines/1000/1000),2)</link>
    +                </drilldown>
    +            </single>
    +
    +
    +            <chart>
    +                <search depends="$show_processing$">
    +                    <query>| pivot metricator-nmon-processing NMON_Processing avg(elapsed_in_seconds) AS "avg_elapsed_in_seconds" SPLITROW _time AS _time PERIOD auto SORT 0 _time ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1
    +| eval avg_elapsed_in_seconds=round(avg_elapsed_in_seconds,2) | fields - show_processing</query>
    +                    <earliest>$timerange_processing.earliest$</earliest>
    +                    <latest>$timerange_processing.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">400</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Seconds</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <!-- ######################################### Eventcount statistics #########################################  -->
    +
    +    <row depends="$show_eventcount$">
    +
    +        <panel>
    +            <title>Eventcount / Metadata Statistics: Indexes first and last event dates</title>
    +
    +            <single>
    +                <search base="eventcount_search">
    +                    <query>sort - "Size (MB)" | head 1 | fields "Millions of Events"</query>
    +                </search>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="underLabel">NMON EVENTS COUNT</option>
    +                <option name="unit">Millions</option>
    +                <drilldown target="search">
    +                    <link>search?q=| eventcount summarize=false report_size=true `nmon_index` | eval "Size (MB)" = round(size_bytes/1024/1024,2) | eval "Millions of Events" = round(count/1000000,2) | fields index, server, "Size (MB)", "Millions of Events"</link>
    +                </drilldown>
    +            </single>
    +
    +            <single>
    +                <search base="metadata_search">
    +                    <query>sort - recentTime | fields "First Event"</query>
    +                </search>
    +                <option name="underLabel">DATA FIRST EVENT</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `indexes_datestats`</link>
    +                </drilldown>
    +            </single>
    +
    +            <single>
    +                <search base="metadata_search">
    +                    <query>sort - lastTime | fields "Last Event"</query>
    +                </search>
    +                <option name="underLabel">DATA LAST EVENT</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `indexes_datestats`</link>
    +                </drilldown>
    +            </single>
    +
    +            <table>
    +                <search base="metadata_search">
    +                    <query>fields index,sourcetype,*Event</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="spk_readch">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="sparkline" field="spk_writech">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### Scheduled searches #########################################  -->
    +
    +    <row depends="$show_scheduled_stats$">
    +
    +        <panel>
    +            <title>SCHEDULING - Statistics per report</title>
    +            <input type="time" token="timerange_scheduled" searchWhenChanged="true">
    +                <label>Time Range:</label>
    +                <default>
    +                    <earliest>-30d</earliest>
    +                    <latest>now</latest>
    +                </default>
    +            </input>
    +            <table rejects="$show_admin_required$">
    +                <search depends="$start_admin_searches$ $show_scheduled_stats$">
    +                    <query>index=_internal host="*" source=*scheduler.log status="*" AND status!="continued" savedsearch_name!="*_ACCELERATE_*" app="metricator-for-nmon"
    +| stats avg(run_time) AS avg_run_time, max(run_time) AS max_run_time, latest(run_time) AS latest_run_time, max(_time) AS "last_run (dd/mm/YYYY H:M:S)" by app,savedsearch_name
    +| eval "last_run (dd/mm/YYYY H:M:S)"=strftime('last_run (dd/mm/YYYY H:M:S)', "%d/%m/%Y %H:%M:%S")
    +| foreach *_run_time [ eval &lt;&lt;FIELD&gt;&gt;=round('&lt;&lt;FIELD&gt;&gt;', 2) ]
    +| sort savedsearch_name | rename savedsearch_name AS "report (savedsearch_name)"
    +| eval duration_avg=tostring(avg_run_time, "duration"), duration_max=tostring(max_run_time, "duration"), duration_latest=tostring(latest_run_time, "duration")
    +| eval "Avg run time (seconds / duration)" = avg_run_time + " sec / " + duration_avg + " (HH:MM:SSS)"
    +| eval "Max run time (seconds / duration)" = max_run_time + " sec / " + duration_avg + " (HH:MM:SSS)"
    +| eval "Latest run time (seconds / duration)" = latest_run_time + " sec / " + duration_avg + " (HH:MM:SSS)"
    +| fields app,report*,Avg*,Max*,Latest*,"last_run (dd/mm/YYYY H:M:S)"</query>
    +                    <earliest>$timerange_scheduled.earliest$</earliest>
    +                    <latest>$timerange_scheduled.latest$</latest>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +            </table>
    +            <html depends="$show_admin_required$">
    +                <div style="color:red;margin-left:30px;font-size:18px;text-align:center;">
    +                    <p>Oops ! Admin privileges required to access these statistics !</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +</dashboard>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_WLM_Solaris.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_WLM_Solaris.xml
    new file mode 100644
    index 0000000..9ed1e14
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_WLM_Solaris.xml
    @@ -0,0 +1,320 @@
    +<form script="autodiscover.js,custom_layout.js" stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +    <label>NMON Solaris WLM: CPU and Memory Statistics of Projects / Zones / Tasks / Users</label>
    +    <description>WLM Statistics dashboard for Solaris systems</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input id="device" type="multiselect" token="device" searchWhenChanged="true">
    +            <label>Project / Zone / Task / User:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ $host$
    +| stats count by dimension_device | dedup dimension_device | sort 0 dimension_device</query>
    +            </search>
    +            <valuePrefix>dimension_device="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>dimension_device</fieldForLabel>
    +            <fieldForValue>dimension_device</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="monitor" searchWhenChanged="true">
    +            <label>Type:</label>
    +            <choice value="project">project</choice>
    +            <choice value="zone">zone</choice>
    +            <choice value="task">task</choice>
    +            <choice value="user">user</choice>
    +            <default>zone</default>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>avg</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Search based for post processing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.wlm*" OStype="Solaris" by host, dimension_device
    +| `mapping_frameID`
    +| stats count by frameID, host, dimension_device | sort 0 host
    +        </query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="tablestats_cpu_per_monitor">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlm$monitor$cpu host=$host-prefilter$ $host_query$ ($device$) by host dimension_device span=1m
    +| `$timefilter$`
    +| stats min(value) as min_value avg(value) as avg_value max(value) as max_value by dimension_device
    +| foreach "*_value" [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 2) ] | sort - avg_value | rename "*_value" AS "*"</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="tablestats_cpu_per_host">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlm$monitor$cpu host=$host-prefilter$ $host_query$ ($device$) by host dimension_device span=1m
    +| `$timefilter$`
    +| stats min(value) as min_value avg(value) as avg_value max(value) as max_value by host, dimension_device
    +| foreach "*_value" [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 2) ] | sort - avg_value | rename "*_value" AS "*"</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>CPU Usage Statistics of Solaris Projects / Zones / Tasks / Users</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="panela1_setWidth_50">
    +            <title>Graphical Representation by $monitor$</title>
    +            <html>
    +                <div id="bubbleSearch"
    +                     class="splunk-manager"
    +                     data-require="splunkjs/mvc/searchmanager"
    +                     data-options="{&quot;search&quot;:
    +                     {
    +                     &quot;type&quot;:
    +                     &quot;token_safe&quot;,
    +                     &quot;value&quot;: &quot;| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlm$$monitor$$cpu host=$$host-prefilter$$ $$host_query$$ ($$device$$) by host dimension_device span=1m
    +| `$$timefilter$$`
    +| stats $$statsmode$$(value) as value by dimension_device
    +| sort limit=0 dimension_device
    +| eval value=round(value,2)
    +| sort - avg_value | head 100&quot;},
    +                    &quot;earliest_time&quot;:
    +                    {&quot;type&quot;: &quot;token_safe&quot;,
    +                    &quot;value&quot;: &quot;$$timerange.earliest$$&quot;
    +                    },
    +                    &quot;latest_time&quot;: {&quot;type&quot;: &quot;token_safe&quot;,
    +                    &quot;value&quot;: &quot;$$timerange.latest$$&quot;
    +                    },
    +                    &quot;auto_cancel&quot;: 90,
    +                    &quot;preview&quot;: true
    +                    }">
    +                </div>
    +                <div id="bubbleChart" class="splunk-view" data-require="app/metricator-for-nmon/components/bubblechart/bubblechart" data-options="{
    +                &quot;managerid&quot;: &quot;bubbleSearch&quot;,
    +                &quot;nameField&quot;: &quot;dimension_device&quot;,
    +                &quot;categoryField&quot;: &quot;dimension_device&quot;,
    +                &quot;valueField&quot;: &quot;value&quot;,
    +                &quot;height&quot;: 600
    +                }">
    +                </div>
    +            </html>
    +        </panel>
    +        <panel id="panela2_setWidth_25">
    +            <title>Stats by $monitor$</title>
    +            <table>
    +                <search base="tablestats_cpu_per_monitor">
    +                    <query></query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">20</option>
    +            </table>
    +        </panel>
    +        <panel id="panela3_setWidth_25">
    +            <title>Stats by Hosts,$monitor$</title>
    +            <table>
    +                <search base="tablestats_cpu_per_host">
    +                    <query></query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">20</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>Memory % Usage Statistics of Solaris Projects / Zones / Tasks / Users</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Search based for post processing -->
    +
    +    <search id="tablestats_memory_per_monitor">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlm$monitor$mem host=$host-prefilter$ $host_query$ ($device$) by host dimension_device span=1m
    +| `$timefilter$`
    +| stats min(value) as min_value avg(value) as avg_value max(value) as max_value by dimension_device
    +| foreach "*_value" [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 2) ] | sort - avg_value | rename "*_value" AS "*"</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="tablestats_memory_per_host">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlm$monitor$mem host=$host-prefilter$ $host_query$ ($device$) by host dimension_device span=1m
    +| `$timefilter$`
    +| stats min(value) as min_value avg(value) as avg_value max(value) as max_value by host, dimension_device
    +| foreach "*_value" [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 2) ] | sort - avg_value | rename "*_value" AS "*"</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel id="panelb1_setWidth_50">
    +            <title>Graphical Representation by $monitor$</title>
    +            <html>
    +                <div id="bubbleSearch2"
    +                     class="splunk-manager"
    +                     data-require="splunkjs/mvc/searchmanager"
    +                     data-options="{&quot;search&quot;:
    +                     {
    +                     &quot;type&quot;:
    +                     &quot;token_safe&quot;,
    +                     &quot;value&quot;: &quot;| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlm$$monitor$$mem host=$$host-prefilter$$ $$host_query$$ ($$device$$) by host dimension_device span=1m
    +| `$$timefilter$$`
    +| stats $$statsmode$$(value) as value by dimension_device
    +| sort limit=0 dimension_device
    +| eval value=round(value,2)
    +| sort - avg_value | head 100&quot;},
    +                    &quot;earliest_time&quot;:
    +                    {&quot;type&quot;: &quot;token_safe&quot;,
    +                    &quot;value&quot;: &quot;$$timerange.earliest$$&quot;
    +                    },
    +                    &quot;latest_time&quot;: {&quot;type&quot;: &quot;token_safe&quot;,
    +                    &quot;value&quot;: &quot;$$timerange.latest$$&quot;
    +                    },
    +                    &quot;auto_cancel&quot;: 90,
    +                    &quot;preview&quot;: true
    +                    }">
    +                </div>
    +                <div id="bubbleChart2" class="splunk-view" data-require="app/metricator-for-nmon/components/bubblechart/bubblechart" data-options="{
    +                &quot;managerid&quot;: &quot;bubbleSearch2&quot;,
    +                &quot;nameField&quot;: &quot;dimension_device&quot;,
    +                &quot;categoryField&quot;: &quot;dimension_device&quot;,
    +                &quot;valueField&quot;: &quot;value&quot;,
    +                &quot;height&quot;: 600
    +                }">
    +                </div>
    +            </html>
    +        </panel>
    +        <panel id="panelb2_setWidth_25">
    +            <title>Stats by $monitor$</title>
    +            <table>
    +                <search base="tablestats_memory_per_monitor">
    +                    <query></query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">20</option>
    +            </table>
    +        </panel>
    +        <panel id="panelb3_setWidth_25">
    +            <title>Stats by Hosts,$monitor$</title>
    +            <table>
    +                <search base="tablestats_memory_per_host">
    +                    <query></query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">20</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_addons_reporting.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_addons_reporting.xml
    new file mode 100644
    index 0000000..a95fc55
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_addons_reporting.xml
    @@ -0,0 +1,452 @@
    +<dashboard stylesheet="ui_simple.css" script="autodiscover.js" isVisible="true" version="1.1" theme="dark">
    +    <label>Add-ons reporting dashboard</label>
    +    <description>Deployment Reporting of add-ons within last 30 days</description>
    +
    +    <search id="addon_report" ref="Add-on version per host">
    +    </search>
    +
    +    <search id="Global_deploy" ref="TA-metricator package deployment reporting (requires _internal access)">
    +    </search>
    +
    +    <search id="Global_clients" ref="Universal Forwarders Configuration Report">
    +    </search>
    +
    +    <search id="Global_interpreter">
    +        <query>| pivot metricator-nmon-processing NMON_Processing last(converter_inuse) AS converter_inuse last(interpreter_version) AS interpreter_version SPLITROW _time AS _time PERIOD minute SPLITROW hostname AS hostname SORT 0 _time ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1
    +| dedup hostname converter_inuse interpreter_version | fields - _time</query>
    +        <earliest>-30d@d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="Python_interpreter">
    +        <query>| pivot metricator-nmon-processing NMON_Processing last(converter_inuse) AS converter_inuse last(interpreter_version) AS interpreter_version SPLITROW hostname AS hostname FILTER converter_inuse is Python
    +SORT 0 hostname ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1</query>
    +        <earliest>-30d@d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="Perl_interpreter">
    +        <query>| pivot metricator-nmon-processing NMON_Processing last(converter_inuse) AS converter_inuse last(interpreter_version) AS interpreter_version SPLITROW hostname AS hostname FILTER converter_inuse is Perl
    +SORT 0 hostname ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1</query>
    +        <earliest>-30d@d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <row>
    +
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>Add-ons deployment reporting:</h1>
    +                    <h4>Report of add-ons version currently deployed</h4>
    +                </div>
    +            </html>
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Add-on reporting:</title>
    +
    +            <single>
    +                <search base="addon_report">
    +                    <query>stats dc(host) AS dcount</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">HOSTS REPORTED</option>
    +            </single>
    +
    +            <single>
    +                <search base="addon_report">
    +                    <query>stats dc(addon_type) AS dcount</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">DISTINCT ADD-ON TYPES REPORTED</option>
    +            </single>
    +
    +            <single>
    +                <search base="addon_report">
    +                    <query>stats dc(addon_version) AS dcount</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">DISTINCT VERSIONS REPORTED</option>
    +            </single>
    +
    +            <chart>
    +                <search base="addon_report">
    +                    <query>top addon_version</query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="height">400</option>
    +            </chart>
    +
    +            <table>
    +                <search base="addon_report">
    +                    <query>fields host,addon_type,addon_version,latest_time</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>Deployment Activity:</h1>
    +                    <h4>Deployment Server(s) events in relation with the publishing action of the TA-metricator package to clients (initial deployment or update)</h4>
    +                </div>
    +            </html>
    +        </panel>
    +
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>Deployment Server Clients configuration:</h1>
    +                    <h4>Configuration of Splunk Clients instances (not necessary running the TA-metricator), either Universal Forwarders (uf) or Heavy Forwarders (full)</h4>
    +                </div>
    +            </html>
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +
    +        <!-- TA-metricator deployment statistics -->
    +
    +        <panel>
    +            <single>
    +                <search base="Global_deploy">
    +                    <query>stats dc(host) AS dcount</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">HOSTS HAVE BEEN DEPLOYED</option>
    +            </single>
    +            <single>
    +                <search base="Global_deploy">
    +                    <query>stats count AS count</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">NUMBER OF DEPLOYMENTS ACTIONS (initial deploy or upgrade)</option>
    +            </single>
    +
    +            <input type="link" token="linkinput1">
    +                <label></label>
    +                <choice value="deploy_chart1">Chart</choice>
    +                <choice value="deploy_chart2">Events</choice>
    +                <default>deploy_chart1</default>
    +                <change>
    +                    <condition value="deploy_chart1">
    +                        <set token="deploy_chart1">true</set>
    +                        <unset token="deploy_chart2"></unset>
    +                    </condition>
    +                    <condition value="deploy_chart2">
    +                        <set token="deploy_chart2">true</set>
    +                        <unset token="deploy_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$deploy_chart1$">
    +                <title></title>
    +                <search ref="TA-metricator package deployment reporting over time (requires _internal access)"></search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">true</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.overlayFields">Nbr_of_deployment_actions</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisTitleY.text">Nbr Hosts</option>
    +                <option name="charting.axisTitleY2.text">Nbr Actions</option>
    +                <option name="height">400</option>
    +            </chart>
    +            <table depends="$deploy_chart2$">
    +                <title></title>
    +                <search base="Global_deploy">
    +                    <query>| table _time, host, _raw</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +            </table>
    +        </panel>
    +
    +        <!-- Deployment Server Configuration -->
    +
    +        <panel>
    +            <single>
    +                <search base="Global_clients">
    +                    <query>stats dc(hostname) AS dcount</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">NUMBER OF DEPLOYMENT SERVER CLIENTS</option>
    +            </single>
    +
    +            <input type="link" token="linkinput2">
    +                <label></label>
    +                <choice value="client_chart1">Chart by version</choice>
    +                <choice value="client_chart2">Chart by os</choice>
    +                <choice value="client_chart3">Chart by arch</choice>
    +                <choice value="client_chart4">Chart by type</choice>
    +                <default>client_chart1</default>
    +                <change>
    +                    <condition value="client_chart1">
    +                        <set token="client_chart1">true</set>
    +                        <unset token="client_chart2"></unset>
    +                        <unset token="client_chart3"></unset>
    +                        <unset token="client_chart4"></unset>
    +                    </condition>
    +                    <condition value="client_chart2">
    +                        <set token="client_chart2">true</set>
    +                        <unset token="client_chart1"></unset>
    +                        <unset token="client_chart3"></unset>
    +                        <unset token="client_chart4"></unset>
    +                    </condition>
    +                    <condition value="client_chart3">
    +                        <set token="client_chart3">true</set>
    +                        <unset token="client_chart1"></unset>
    +                        <unset token="client_chart2"></unset>
    +                        <unset token="client_chart4"></unset>
    +                    </condition>
    +                    <condition value="client_chart4">
    +                        <set token="client_chart4">true</set>
    +                        <unset token="client_chart1"></unset>
    +                        <unset token="client_chart2"></unset>
    +                        <unset token="client_chart3"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$client_chart1$">
    +                <title></title>
    +                <search base="Global_clients">
    +                    <query>stats count by version</query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="height">400</option>
    +            </chart>
    +            <chart depends="$client_chart2$">
    +                <title></title>
    +                <search base="Global_clients">
    +                    <query>stats count by os</query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="height">400</option>
    +            </chart>
    +            <chart depends="$client_chart3$">
    +                <title></title>
    +                <search base="Global_clients">
    +                    <query>stats count by arch</query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="height">400</option>
    +            </chart>
    +            <chart depends="$client_chart4$">
    +                <title></title>
    +                <search base="Global_clients">
    +                    <query>stats count by fwdType</query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="height">400</option>
    +            </chart>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +
    +        <panel>
    +            <title>Details of Nmon hosts:</title>
    +            <table>
    +                <search base="Global_interpreter">
    +                    <query>| lookup nmon_inventory hostname OUTPUT OStype, nmon_version | sort hostname</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +            </table>
    +        </panel>
    +
    +        <panel>
    +            <title>Details of Clients hosts:</title>
    +            <table>
    +                <search base="Global_clients">
    +                    <query></query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +            </table>
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>Python / Perl Interpreter Distribution:</h1>
    +                    <h4>Repartition of hosts using the Python/Perl version of the nmonparser converter</h4>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>Python Versions Distribution:</h1>
    +                    <h4>Python versions of hosts using the nmonparser.py converter</h4>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>Perl Versions Distribution:</h1>
    +                    <h4>Perl versions of hosts using the nmonparser.pl converter</h4>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +
    +        <panel>
    +            <single>
    +                <search base="Global_interpreter">
    +                    <query>search converter_inuse="Python" | stats dc(hostname) AS dcount</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">HOSTS HAVE USED PYTHON</option>
    +            </single>
    +            <single>
    +                <search base="Global_interpreter">
    +                    <query>search converter_inuse="Perl" | stats dc(hostname) AS dcount</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">HOSTS HAVE USED PERL</option>
    +            </single>
    +            <html>
    +                <!-- Placeholder/container for the link switcher to appear -->
    +                <div class="link-switcher" data-items="link7,link8">Select a view:<!--Links go here-->
    +                </div>
    +            </html>
    +            <chart id="link7">
    +                <title>Pie chart</title>
    +                <search base="Global_interpreter">
    +                    <query>top converter_inuse</query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="height">300</option>
    +            </chart>
    +            <table id="link8">
    +                <title>Table</title>
    +                <search base="Global_interpreter">
    +                    <query>top converter_inuse | eval percent=round(percent,2)</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="drilldown">row</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +            </table>
    +        </panel>
    +
    +        <panel>
    +            <single>
    +                <search base="Python_interpreter">
    +                    <query>search converter_inuse="Python" | stats dc(interpreter_version) AS dcount</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">DIFFERENT PYTHON VERSIONS</option>
    +            </single>
    +            <html>
    +                <!-- Placeholder/container for the link switcher to appear -->
    +                <div class="link-switcher" data-items="link9,link10">Select a view:<!--Links go here-->
    +                </div>
    +            </html>
    +            <chart id="link9">
    +                <title>Pie chart</title>
    +                <search base="Python_interpreter">
    +                    <query>top interpreter_version</query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="height">300</option>
    +            </chart>
    +            <table id="link10">
    +                <title>Table</title>
    +                <search base="Python_interpreter">
    +                    <query>top interpreter_version | eval percent=round(percent,2)</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="drilldown">row</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +            </table>
    +        </panel>
    +
    +        <panel>
    +            <single>
    +                <search base="Perl_interpreter">
    +                    <query>stats dc(interpreter_version) AS dcount</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">DIFFERENT PERL VERSIONS</option>
    +            </single>
    +            <html>
    +                <!-- Placeholder/container for the link switcher to appear -->
    +                <div class="link-switcher" data-items="link11,link12">Select a view:<!--Links go here-->
    +                </div>
    +            </html>
    +            <chart id="link11">
    +                <title>Pie chart</title>
    +                <search base="Perl_interpreter">
    +                    <query>top interpreter_version</query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="height">300</option>
    +            </chart>
    +            <table id="link12">
    +                <title>Table</title>
    +                <search base="Perl_interpreter">
    +                    <query>top interpreter_version | eval percent=round(percent,2)</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="drilldown">row</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +</dashboard>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_bulletcharts.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_bulletcharts.xml
    new file mode 100644
    index 0000000..5b85135
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_bulletcharts.xml
    @@ -0,0 +1,794 @@
    +<form stylesheet="ui_simple.css,hover.css,hide_timeindicator.css,panel_decoration.css" script="active_button.js,autodiscover.js" isVisible="true" version="1.1" theme="dark">
    +    <label>Bullet Dashboard - TOP servers by CPU/Memory, TOP Processes by CPU</label>
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-4h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +            <!--
    +            Reset the form token changed
    +            -->
    +       		<change>
    +         		<unset token="drilldown_cpuhost"></unset>
    +                <unset token="drilldown_memhost"></unset>
    +                <unset token="drilldown_swaphost"></unset>
    +       		</change>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +            <!--
    +            Reset the form token changed
    +            -->
    +       		<change>
    +         		<unset token="drilldown_cpuhost"></unset>
    +                <unset token="drilldown_memhost"></unset>
    +                <unset token="drilldown_swaphost"></unset>
    +       		</change>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +            <!--
    +            Reset the form token changed
    +            -->
    +       		<change>
    +         		<unset token="drilldown_cpuhost"></unset>
    +                <unset token="drilldown_memhost"></unset>
    +                <unset token="drilldown_swaphost"></unset>
    +       		</change>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +                <unset token="drilldown_cpuhost"></unset>
    +                <unset token="drilldown_memhost"></unset>
    +                <unset token="drilldown_swaphost"></unset>
    +                <unset token="form.host_query_input"></unset>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.*" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- ############################# CPU stats ############################# -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>PROCESSOR - TOP servers by CPU / Physical and Virtual memory % utilization - Dynamic drilldown: Click on the server line to see over time statistics</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <search id="main_cpu">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.PhysicalCPU OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs OR metric_name=os.unix.nmon.cpu.lpar.partition_active_processors) host=$host-prefilter$ $host_query$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| stats max(cpu_load_percent) AS max_usage avg(cpu_load_percent) AS avg_usage median(cpu_load_percent) AS median_usage by host
    +| foreach *_usage [ eval &lt;&lt;FIELD&gt;&gt;=round('&lt;&lt;FIELD&gt;&gt;', 2) ]</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="main_memory">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| stats avg(mem_used_effective_PCT) AS mem_usage_pct, avg(swap_used_effective_PCT) AS swap_usage_pct by host
    +| foreach *_usage_pct [ eval &lt;&lt;FIELD&gt;&gt;=round('&lt;&lt;FIELD&gt;&gt;', 2) ]</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <title>TOP 5 hosts by Average CPU percentage usage (%)</title>
    +            <viz type="bullet_graph_app.bullet_graph">
    +                <search base="main_cpu">
    +                    <query>sort - avg_usage | head 5 | eval range_low=50,range_med=85,range_high=100,target=100 | table host,avg_usage,range_low,range_med,range_high,target | sort host</query>
    +                </search>
    +                <option name="bullet_graph_app.bullet_graph.bulletColor">#778899</option>
    +                <option name="bullet_graph_app.bullet_graph.targetMarkerColor">#ff0000</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeLowColor">#77dd77</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeMidColor">#f7bc38</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeHighColor">#FF7878</option>
    +                <option name="height">300</option>
    +                <option name="refresh.display">preview</option>
    +                <drilldown>
    +                    <set token="drilldown_cpuhost">$row.host$</set>
    +                </drilldown>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <title>TOP 5 hosts by Average physical memory usage (%)</title>
    +            <viz type="bullet_graph_app.bullet_graph">
    +                <search base="main_memory">
    +                    <query>sort - mem_usage_pct | head 5 | eval range_low=50,range_med=85,range_high=100,target=100 | table host,mem_usage_pct,range_low,range_med,range_high,target | sort host</query>
    +                </search>
    +                <option name="bullet_graph_app.bullet_graph.bulletColor">#778899</option>
    +                <option name="bullet_graph_app.bullet_graph.targetMarkerColor">#FF7878</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeLowColor">#77dd77</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeMidColor">#f7bc38</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeHighColor">#FF7878</option>
    +                <option name="height">300</option>
    +                <option name="refresh.display">preview</option>
    +                <drilldown>
    +                    <set token="drilldown_memhost">$row.host$</set>
    +                </drilldown>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <title>TOP 5 hosts by Average swap memory usage (%)</title>
    +            <viz type="bullet_graph_app.bullet_graph">
    +                <search base="main_memory">
    +                    <query>sort - swap_usage_pct | head 5 | eval range_low=50,range_med=85,range_high=100,target=100 | table host,swap_usage_pct,range_low,range_med,range_high,target | sort host</query>
    +                </search>
    +                <option name="bullet_graph_app.bullet_graph.bulletColor">#778899</option>
    +                <option name="bullet_graph_app.bullet_graph.targetMarkerColor">#FF7878</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeLowColor">#77dd77</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeMidColor">#f7bc38</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeHighColor">#FF7878</option>
    +                <option name="height">300</option>
    +                <option name="refresh.display">preview</option>
    +                <drilldown>
    +                    <set token="drilldown_swaphost">$row.host$</set>
    +                </drilldown>
    +            </viz>
    +        </panel>
    +    </row>
    +
    +    <row depends="$drilldown_cpuhost$">
    +        <panel>
    +            <title>Server $drilldown_cpuhost$ - % CPU utilization over time</title>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +            <input type="checkbox" token="cpu_scale" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="cpu_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="100">Ends scale at 100 %</choice>
    +                <initialValue>100</initialValue>
    +            </input>
    +            <input type="dropdown" token="chart" searchWhenChanged="true" depends="$cpu_chart_options$">
    +                <label>Type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true" depends="$cpu_chart_options$">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true" depends="$cpu_chart_options$">
    +                <label>Legend:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <chart>
    +                <search depends="$drilldown_cpuhost$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.PhysicalCPU OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs OR metric_name=os.unix.nmon.cpu.lpar.partition_active_processors) host=$drilldown_cpuhost$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart $span$ avg(cpu_load_percent) AS cpu_load_percent | trendline sma5(cpu_load_percent) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">400</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPUs</option>
    +                <option name="charting.axisY.minimumNumber">$cpu_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$cpu_scaleend$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$drilldown_memhost$">
    +        <panel>
    +            <title>Server $drilldown_memhost$ - % Physical memory utilization over time</title>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +            <input type="checkbox" token="mem_scale" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="mem_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="100">Ends scale at 100 %</choice>
    +                <initialValue>100</initialValue>
    +            </input>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <chart>
    +                <search depends="$drilldown_memhost$">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$drilldown_memhost$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart $span$ dedup_splitvals=t avg(mem_used_effective_PCT) AS avg_mem_used_pct | trendline sma5(avg_mem_used_pct) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">400</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% physical memory</option>
    +                <option name="charting.axisY.minimumNumber">$mem_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$mem_scaleend$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$drilldown_swaphost$">
    +        <panel>
    +            <title>Server $drilldown_swaphost$ - % Virtual memory utilization over time</title>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +            <input type="checkbox" token="swap_scale" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="swap_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="100">Ends scale at 100 %</choice>
    +                <initialValue>100</initialValue>
    +            </input>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <chart>
    +                <search depends="$drilldown_swaphost$">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$drilldown_swaphost$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart $span$ avg(swap_used_effective_PCT) AS avg_swap_used_pct | trendline sma5(avg_swap_used_pct) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">400</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% virtual memory</option>
    +                <option name="charting.axisY.minimumNumber">$swap_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$swap_scaleend$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <!-- ############################# TOP stats ############################# -->
    +
    +    <search id="TOPSearch_cpu">
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| eval usage_per_core=(value/100)
    +| lookup nmon_inventory hostname as host OUTPUT cpu_logicalcores
    +| eval usage_pct=(usage_per_core/cpu_logicalcores)*100
    +| stats avg(usage_pct) as avg_usage_pct, max(usage_pct) as max_usage_pct by dimension_Command
    +| sort - avg_usage_pct</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>PROCESSES - TOP Commands in CPU % utilization - Dynamic drilldown: Click on the Command line to see over time statistics</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>TOP 5 Commands by Average CPU usage (% usage by sum of logical CPUs)</title>
    +            <viz type="bullet_graph_app.bullet_graph">
    +                <search base="TOPSearch_cpu">
    +                    <query>sort - avg_usage_pct | head 5 | eval range_low=50,range_med=85,range_high=100,target=100 | table dimension_Command,avg_usage_pct,range_low,range_med,range_high,target | sort dimension_Command</query>
    +                </search>
    +                <option name="bullet_graph_app.bullet_graph.bulletColor">#778899</option>
    +                <option name="bullet_graph_app.bullet_graph.targetMarkerColor">#FF7878</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeLowColor">#77dd77</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeMidColor">#f7bc38</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeHighColor">#FF7878</option>
    +                <option name="height">300</option>
    +                <option name="refresh.display">preview</option>
    +                <drilldown>
    +                    <set token="drilldown_topcpu">$row.dimension_Command$</set>
    +                    <set token="top_statsmode">avg</set>
    +                    <set token="top_statsmode_label">Average</set>
    +                </drilldown>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <title>TOP 5 Commands by Max CPU usage (% usage by sum of logical CPUs)</title>
    +            <viz type="bullet_graph_app.bullet_graph">
    +                <search base="TOPSearch_cpu">
    +                    <query>sort - max_usage_pct | head 5 | eval range_low=50,range_med=85,range_high=100,target=100 | table dimension_Command,max_usage_pct,range_low,range_med,range_high,target | sort dimension_Command</query>
    +                </search>
    +                <option name="bullet_graph_app.bullet_graph.bulletColor">#778899</option>
    +                <option name="bullet_graph_app.bullet_graph.targetMarkerColor">#FF7878</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeLowColor">#77dd77</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeMidColor">#f7bc38</option>
    +                <option name="bullet_graph_app.bullet_graph.rangeHighColor">#FF7878</option>
    +                <option name="height">300</option>
    +                <option name="refresh.display">preview</option>
    +                <drilldown>
    +                    <set token="drilldown_topcpu">$row.dimension_Command$</set>
    +                    <set token="top_statsmode">max</set>
    +                    <set token="top_statsmode_label">Max</set>
    +                </drilldown>
    +            </viz>
    +        </panel>
    +    </row>
    +
    +    <row depends="$drilldown_topcpu$">
    +        <panel>
    +            <title>Command $drilldown_topcpu$ - $top_statsmode_label$ % CPU utilization over time</title>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +            <input type="checkbox" token="top_scale" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="top_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="100">Ends scale at 100 %</choice>
    +                <initialValue>100</initialValue>
    +            </input>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <chart>
    +                <search>
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ dimension_Command=$drilldown_topcpu$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| eval usage_per_core=(value/100)
    +| lookup nmon_inventory hostname as host OUTPUT cpu_logicalcores
    +| eval usage_pct=(usage_per_core/cpu_logicalcores)*100
    +| timechart $span$ $top_statsmode$(usage_pct) AS usage_pct by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">400</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPU utilization</option>
    +                <option name="charting.axisY.minimumNumber">$top_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$top_scaleend$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$drilldown_topcpu$">
    +        <panel>
    +            <title>Command $drilldown_topcpu$ - $top_statsmode_label$ % CPU utilization over time by server</title>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +            <input type="checkbox" token="topserver_scale" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="topserver_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="100">Ends scale at 100 %</choice>
    +                <initialValue>100</initialValue>
    +            </input>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <chart>
    +                <search>
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ dimension_Command=$drilldown_topcpu$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| eval usage_per_core=(value/100)
    +| lookup nmon_inventory hostname as host OUTPUT cpu_logicalcores
    +| eval usage_pct=(usage_per_core/cpu_logicalcores)*100
    +| eval key = host . ":" . dimension_Command
    +| timechart $span$ $top_statsmode$(usage_pct) AS usage_pct by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">400</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPU utilization</option>
    +                <option name="charting.axisY.minimumNumber">$topserver_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$topserver_scaleend$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_heatmap_daily_usage.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_heatmap_daily_usage.xml
    new file mode 100644
    index 0000000..a375eac
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_heatmap_daily_usage.xml
    @@ -0,0 +1,317 @@
    +<form script="autodiscover.js,custom_layout.js" stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +    <label>Dashboard heatmap calendar daily CPU usage</label>
    +    <description>This dashboard provides mass visualization of daily peak CPU utilization with top hosts drilldown features</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-30d@d</earliest>
    +                <latest>now</latest>
    +            </default>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>avg</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- BaseSearch for post processing -->
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.*" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="daily_usage">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.PhysicalCPU OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs OR metric_name=os.unix.nmon.cpu.lpar.partition_active_processors) host=$host-prefilter$ $host_query$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart span=1d $statsmode$(cpu_load_percent) AS cpu_load_percent | eval cpu_load_percent=round(cpu_load_percent, 3)</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +
    +        <panel>
    +            <title>Daily average CPU percentage utilization</title>
    +
    +            <single>
    +                <search base="daily_usage">
    +                    <query>stats max(cpu_load_percent) AS value | eval value=round(value,0)</query>
    +                </search>
    +                <option name="unit">%</option>
    +                <option name="underLabel">Max daily CPU %</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single>
    +                <search base="daily_usage">
    +                    <query>stats avg(cpu_load_percent) AS value | eval value=round(value,0)</query>
    +                </search>
    +                <option name="unit">%</option>
    +                <option name="underLabel">Avg CPU % over period</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single>
    +                <search base="daily_usage">
    +                    <query>stats median(cpu_load_percent) AS value | eval value=round(value,0)</query>
    +                </search>
    +                <option name="unit">%</option>
    +                <option name="underLabel">Median CPU % over period</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single>
    +                <search base="daily_usage">
    +                    <query>sort 0 - cpu_load_percent | head 1 | eval time=strftime(_time, "%d/%m/%Y") | fields time</query>
    +                </search>
    +                <option name="underLabel">Peak day (dd/mm/YYYY)</option>
    +            </single>
    +
    +            <html>
    +                <div id="calendarheatmap" class="splunk-view" data-require="app/metricator-for-nmon/components/calendarheatmap/calendarheatmap" data-options='{
    +          "managerid": "daily_usage",
    +          "domain": "month",
    +          "subDomain": "x_day",
    +          "subDomainTextFormat": "%d",
    +          "cellRadius": "5"
    +        }'>
    +                </div>
    +            </html>
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Daily CPU percentage utilization over time- Active drilldown: click on a day to see top consuming hosts</title>
    +            <chart>
    +                <search base="daily_usage">
    +                    <query>sort 0 _time</query>
    +                </search>
    +                <option name="charting.chart.columnSpacing">5</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="height">350</option>
    +                <option name="charting.axisTitleY.text">% CPU usage</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <drilldown>
    +                    <set token="show_hosts_drilldown">true</set>
    +                    <set token="drilldown_earliest">$earliest$</set>
    +                    <set token="drilldown_latest">$latest$</set>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_hosts_drilldown$">
    +        <panel>
    +            <title>TOP hosts drilldown</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +            <input type="checkbox" token="cpu_scale" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="cpu_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="100">Ends scale at 100 %</choice>
    +                <initialValue>100</initialValue>
    +            </input>
    +            <chart>
    +                <search depends="$show_hosts_drilldown$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.PhysicalCPU OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs OR metric_name=os.unix.nmon.cpu.lpar.partition_active_processors) host=$host-prefilter$ $host_query$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart $span$ useother=f limit=40 $statsmode$(cpu_load_percent) AS cpu_load_percent by host</query>
    +                    <earliest>$drilldown_earliest$</earliest>
    +                    <latest>$drilldown_latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">350</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPU usage</option>
    +                <option name="charting.axisY.minimumNumber">$cpu_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$cpu_scaleend$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_uptime.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_uptime.xml
    new file mode 100644
    index 0000000..90a6111
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Dashboard_uptime.xml
    @@ -0,0 +1,178 @@
    +<form stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UPTIME evolution over time</label>
    +    <description>Uptime evolution over time, evaluated in days</description>
    +    <row>
    +        <panel>
    +            <input type="time" token="timerange" searchWhenChanged="true">
    +                <label>Time Range:</label>
    +                <default>
    +                    <earliest>-1y@d</earliest>
    +                    <latest>now</latest>
    +                </default>
    +            </input>
    +            <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +                <label>Filter OS Type:</label>
    +                <default>Linux</default>
    +                <prefix>OStype="</prefix>
    +                <suffix>"</suffix>
    +                <choice value="*">Any OS</choice>
    +                <choice value="AIX">AIX</choice>
    +                <choice value="Linux">Linux</choice>
    +                <choice value="Solaris">Solaris</choice>
    +            </input>
    +            <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +                <label>Frame IDs:</label>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate">
    +                    <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +                </search>
    +                <valuePrefix>frameID="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">Any</choice>
    +                <initialValue>*</initialValue>
    +                <fieldForLabel>frameID</fieldForLabel>
    +                <fieldForValue>frameID</fieldForValue>
    +            </input>
    +            <input type="text" token="host-prefilter" searchWhenChanged="true">
    +                <label>Optional: Filter hosts populating</label>
    +                <default>*</default>
    +            </input>
    +            <input id="host" type="dropdown" token="host" searchWhenChanged="true">
    +                <label>Hosts Selection:</label>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate">
    +                    <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +                </search>
    +                <prefix>host="</prefix>
    +                <suffix>"</suffix>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| tstats count as count where `nmon_events_index` type=UPTIME $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <search id="GlobalSearch">
    +        <query>| tstats latest("metricator-nmon-config.uptime") AS uptime_seconds, latest("metricator-nmon-config.event_epoch") AS last_report from datamodel=metricator-nmon-config where (nodename = metricator-nmon-config) (sourcetype=nmon_config) $host$ by host prestats=true
    +| tstats latest("Uptime.uptime") AS external_uptime_seconds latest(Uptime.event_epoch) as external_last_report from datamodel=metricator-nmon-config.Uptime where (nodename = Uptime) (Uptime.OStype = "Linux") (Uptime.uptime = "*") $host$ by host append=true prestats=true
    +| stats dedup_splitvals=t
    +latest("metricator-nmon-config.uptime") AS uptime_seconds, latest("metricator-nmon-config.event_epoch") AS last_report, latest("Uptime.uptime") AS external_uptime_seconds latest(Uptime.event_epoch) as external_last_report by host
    +| eval last_known_uptime=if(isnotnull(external_uptime_seconds), external_uptime_seconds, uptime_seconds)
    +| eval epoch=if(isnotnull(external_last_report), external_last_report, last_report)
    +| eval reporting_date=strftime(epoch, "%m/%d/%Y %H:%M")
    +| eval now=now()
    +| eval last_known_uptime=(last_known_uptime+(now-epoch))
    +| sort host
    +| eval "Date of last system startup (mm/dd/Y HH:MM)"=strftime((now()-last_known_uptime), "%m/%d/%Y %H:%M")
    +| eval "uptime (human duration)"=tostring(last_known_uptime, "duration")
    +| fields host,last_known_uptime,"uptime (human duration)","Date of last system startup (mm/dd/Y HH:MM)",reporting_date | fields - _time
    +| rename last_known_uptime AS "uptime (in seconds)", reporting_date AS "Last reporting date (mm/dd/Y HH:MM)"</query>
    +        <earliest>-7d@h</earliest>
    +        <latest>now</latest>
    +    </search>
    +    <row>
    +        <panel>
    +            <single>
    +                <search base="GlobalSearch">
    +                    <query>fields "Date of last system startup (mm/dd/Y HH:MM)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="trendInterval">auto</option>
    +                <option name="underLabel">LAST SYSTEM STARTUP DATE</option>
    +                <option name="useColors">0</option>
    +                <option name="useThousandSeparators">1</option>
    +            </single>
    +            <single>
    +                <search base="GlobalSearch">
    +                    <query>fields "uptime (human duration)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="trendInterval">auto</option>
    +                <option name="underLabel">LAST UPTIME DURATION (dd:HH:MM:SS)</option>
    +                <option name="useColors">0</option>
    +                <option name="useThousandSeparators">1</option>
    +            </single>
    +            <chart>
    +                <search>
    +                    <query>| tstats latest("metricator-nmon-config.uptime") AS uptime_seconds from datamodel=metricator-nmon-config where (nodename = metricator-nmon-config) (sourcetype=nmon_config) (metricator-nmon-config.OStype = "Linux") ($host$) by _time, host prestats=true span=1d
    +| tstats latest("Uptime.uptime") AS external_uptime_seconds from datamodel=metricator-nmon-config.Uptime where (nodename = Uptime) (Uptime.OStype = "Linux") (Uptime.uptime = "*") ($host$) by _time, host append=true prestats=true span=1d
    +| stats dedup_splitvals=t
    +latest("metricator-nmon-config.uptime") AS uptime_seconds, latest("Uptime.uptime") AS external_uptime_seconds by _time, host
    +| eval last_known_uptime=if(isnotnull(external_uptime_seconds), external_uptime_seconds, uptime_seconds)
    +| eval uptime=if(isnotnull(external_uptime_seconds), external_uptime_seconds, uptime_seconds)
    +| eval uptime=(uptime/86400)
    +| timechart span=1d limit=0 useother=f values(uptime) AS uptime by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.text">Days</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">uptime in days</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">400</option>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Home.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Home.xml
    new file mode 100644
    index 0000000..be862f3
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Home.xml
    @@ -0,0 +1,2700 @@
    +<dashboard script="autodiscover.js,panel_resize.js,active_button.js,modal.js" stylesheet="Home.css,ui_simple.css,hover.css,hide_timeindicator.css" hideTitle="true" hideEdit="true" isVisible="true" version="1.1" theme="dark">
    +    <label>Home</label>
    +    <description></description>
    +
    +    <!-- Take the tour ! -->
    +	<row >
    +		<panel>
    +			<html>
    +				<div class = "splunk-view" data-require = "app/metricator-for-nmon/components/scc_takethetour/scc_takethetour"
    +					data-options = '{
    +						"user_slides":"scc-takethetour-slides",
    +						"width":"60",
    +						"title":"Metricator for Nmon: Take the tour !",
    +						"close_btn_label":"Close",
    +						"no_more_label":"Do not show this again",
    +						"cookie_name_suffix":"metricator-for-nmon-v1.0",
    +						"hide_container":false,
    +						"show_credits":true
    +					}'>
    +				</div>
    +				<ul id="scc-takethetour-slides" class="hide">
    +
    +					<li>
    +
    +                        <h1>WELCOME IN THE METRICATOR APPLICATION FOR SPLUNK ENTERPRISE</h1>
    +
    +                        <h2>The super fast, rich and definitive monitoring and performance application suite for Unix and Linux.</h2>
    +
    +                        <div style="text-align: left;">
    +                            <a href="http://www.octamis.com" target="_blank">
    +                                <img src="../../static/app/metricator-for-nmon/Octamis/Octamis_Logo_v3_no_bg.png" alt="Octamis"/>
    +                            </a>
    +                        </div>
    +
    +                        <b>Contact us at: </b><a target="_top" href="mailto:sales@octamis.com?subject=Nmon%20Performance%20for%20Splunk">sales@octamis.com</a>
    +                        <br />
    +                        <b>Share your testimonial: </b><a target="_top" href="mailto:nmon@octamis.com?subject=Nmon%20Performance%20for%20Splunk">nmon@octamis.com</a>
    +                        <br />
    +                        <b>We are looking for talent, <a target="_blank" href="https://www.octamis.com/careers/">find a job opportunity at Octamis</a></b>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/main.png" alt="main.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +
    +                        <h1>Metrics on steroids with Splunk 7 metric store</h1>
    +
    +                        <h2>Native metrics implementation</h2>
    +
    +                        <p>
    +                            The Metricator application fully implements Splunk time series metrics ingested within the metric store indexes.
    +                            <br />
    +                            We make good usage of it, and bring you one of the most performer user experience on Splunk Enterprise.
    +                            <br />
    +                            Access easily any metric available, use high performance mstats and mcatalog commands and retrieve results in seconds.
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/metrics_showcase.png" alt="metrics_showcase.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +
    +                        <h1>The most advanced dynamic dashboards and user interfaces for the highest quality of user experience</h1>
    +
    +                        <h2>We've got you covered. Find replies to your questions and get back in control with your systems</h2>
    +
    +                        <p>
    +                            Use our advanced dashboards to easily perform the best performance analysis.
    +                            <br />
    +                            More than simple dashboards, we provide rich, powerful and well designed user interfaces.
    +                            <br />
    +                            Dashboards and user interfaces are easily accessible from the application home page, we have a dashboard for all use cases.
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/advanced_dashboards.png" alt="advanced_dashboards.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +						<h1>Certified Technical Addon, low footprint and highly configurable</h1>
    +
    +                        <h2>Our Technical Addons are heavily tested, qualified and certified against numbers of architectures and Operating Systems, this includes:</h2>
    +
    +                        <p>
    +                            - IBM AIX 7.1 / 7.2<br />
    +                            - PowerLinux Linux (RHEL/Ubuntu/SLES...)<br />
    +                            - X86 (RHEL/Ubuntu/SLES...)<br />
    +                            - Oracle Solaris 11 on X86 and SPARC<br />
    +                        </p>
    +
    +                        The Technical Addons are as well compatible with ARM platforms, IBM zLinux!
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/OS_logos.png" alt="OS_logos.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +						<h1>Builtin costs of ownership analytic and metrics volume optimizations</h1>
    +
    +                        <h2>Get the insight vision of every cost related to your deployment</h2>
    +
    +                        <p>
    +                            - The DCO dashboard provides you builtin analytic features against application costs, daily average volume and metric metadatas, and even more<br />
    +                            - The Add-on dashboard provides automatic reporting your servers deployment, which versions are deployed on which servers<br />
    +                            - Don't pay for a zero ! The Technical Addons have been slighty optimized to remove any useless data from the metrics generation, you only pay for what is useful<br />
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/tco.png" alt="tco.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +						<h1>Threshold management, frameID mapping and thresholds templating</h1>
    +
    +                        <h2>The alerting features implements a multi-layer thresholds system based on:</h2>
    +
    +                        <p>
    +                            - The frameID that allows logically grouping server assets<br />
    +                            - FrameID mapping is achieved either at the raw level with different options (static definition, pre-ation scripts) or at search time with the KVstore management interface for frameID mapping<br />
    +                            - Alerting thresholds values can be defined using macros default, on a per frameID template basis or on a per server basis using the KVstore collection management interfaces<br />
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/thresholds.png" alt="thresholds.png"/>
    +                        </div>
    +
    +					</li>
    +
    +                </ul>
    +			</html>
    +		</panel>
    +	</row>
    +
    +    <row>
    +        <panel>
    +            <title>Metrics exploration:</title>
    +
    +            <html>
    +
    +                    <div class="mainbutton_container_nomargin">
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_mexplorer">  M-EXPLORER  </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin custom-modal">
    +                            <a class="button2_lowpadding glow" data-modal-name="appinfo_modal">M-STRUCTURE</a>
    +                        </div>
    +
    +                    </div>
    +
    +                    <!-- Modal -->
    +                    <div class="modal custom-modal-60 fade" id="appinfo_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                        <div class="modal-dialog" role="document">
    +                            <div class="modal-content">
    +                                <div class="modal-header">
    +                                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                    <div style="text-align: left;">
    +                                        <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                    </div>
    +                                </div>
    +                                <div class="modal-body">
    +
    +                                    <div style="text-align: left;">
    +                                        <h1>
    +                                            METRICS STORAGE AND NAMING CONVENTION:
    +                                        </h1>
    +                                    </div>
    +
    +                                    <div>
    +                                        <br />
    +                                        By default, all metrics are indexed in the metric index called <b>os-unix-nmon-metrics</b>
    +                                        <br />
    +                                        Dashboards and reports globally refer to a macro named <b>nmon_metrics_index</b> that can be customized up to your needs and matches by default any index starting by <b>os-unix-nmon-metrics*</b>
    +
    +                                        <h2 style="color: lightslategrey;">Metrics scheme:</h2>
    +
    +                                        The metric generation process applies a common scheme easy to exploit, mostly: <b>os.unix.nmon.&lt;metric_category&gt;.&lt;nmon_section&gt;.&lt;metric&gt;.&lt;sub_metric&gt;</b>
    +
    +                                        <h2 style="color: lightslategrey;">Metrics dimensions:</h2>
    +
    +                                        Optional dimensions are available depending on metrics, such as the network interface names, and always start by <b>dimension_</b>, example: <b>dimension_device</b>
    +                                        <br />
    +                                        Dimensions can be retrieved automatically by the mcatalog command using the special field <b>"_dims"</b> field: <b>values(_dims) as dimensions</b>
    +
    +                                        <h2 style="color: lightslategrey;">Special dimensions:</h2>
    +
    +                                        The Technical addons creates some special dimensions to be used in servers filtering queries:
    +                                        <br />
    +                                        <lu>
    +                                            <li><b>OStype:</b> type of Operating System for the server</li>
    +                                            <li><b>serialnum:</b> serial number registered for the server (linked to the frameID)</li>
    +                                        </lu>
    +
    +                                        <h2 style="color: lightslategrey;">mcatalog queries:</h2>
    +
    +                                        mcatalog queries can be easily achieved such as the following example that reports all metrics available on a per host basis:
    +
    +                                        <br />
    +                                        <code>| mcatalog values(_dims) as dimensions where `nmon_metrics_index` metric_name=os.unix.nmon.* host=* by metric_name | stats values(dimensions) as dimensions, values(metric_name) as metric_name</code>
    +
    +                                        <h2 style="color: lightslategrey;">mstats queries:</h2>
    +
    +                                        mstats queries retrieve the metrics values eventually filtered out and reported per dimensions, the following example reports the system space CPU usage percentage:
    +
    +                                        <br />
    +                                        <code>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT host=* by host span=1m</code>
    +
    +                                        <br />
    +
    +                                        <div style="text-align: center;" class="cat_title">
    +
    +                                            <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(_dims)%20as%20dimensions%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.*%20host%3D*%20by%20host" class="tryitbtnxl">mcatalog query example »
    +                                            </a>
    +
    +                                            <a target="_blank" href="UI_data_dictionary" class="tryitbtnxl">mcatalog data dictionary »
    +                                            </a>
    +
    +                                            <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats query example »
    +                                            </a>
    +
    +                                        </div>
    +
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div class="modal-footer">
    +                                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                                </div>
    +
    +                            </div>
    +                        </div>
    +                    </div>
    +
    +            </html>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Analyse and troubleshoot:</title>
    +
    +            <html>
    +
    +                    <div class="mainbutton_container_nomargin">
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_Summary">  SUMMARY OVERVIEW  </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_WOF"> WALL OF PERFORMANCE </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_Dark"> DARK MONITORING </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin custom-modal">
    +                            <a class="button2_lowpadding glow" data-modal-name="Nmon_Analyser_modal">NMON ANALYSER</a>
    +                        </div>
    +
    +                    </div>
    +
    +                    <!-- Modal -->
    +                    <div class="modal custom-modal-60 fade" id="Nmon_Analyser_modal" tabindex="-1" role="dialog" aria-labelledby="Nmon_Analyser_modal_Label">
    +                        <div class="modal-dialog" role="document">
    +                            <div class="modal-content">
    +                                <div class="modal-header">
    +                                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                    <div style="text-align: left;">
    +                                        <h4 class="modal-title" id="Nmon_Analyser_modal_Label">NMON ANALYSER: Choice menu</h4>
    +                                    </div>
    +                                </div>
    +                                <div class="modal-body">
    +
    +                                    <div style="text-align: left;">
    +                                        <h1>Select your Operating System:</h1>
    +                                    </div>
    +
    +                                    <div class="mainbutton_container">
    +
    +                                        <div class="mainbutton">
    +                                            <a class="button2_lowpadding glow" href="Nmon_ANALYSER_AIX">  AIX SYSTEM  </a>
    +                                        </div>
    +
    +                                        <div class="mainbutton">
    +                                            <a class="button2_lowpadding glow" href="Nmon_ANALYSER_LINUX"> LINUX SYSTEM </a>
    +                                        </div>
    +
    +                                        <div class="mainbutton">
    +                                            <a class="button2_lowpadding glow" href="Nmon_ANALYSER_SOLARIS">SOLARIS SYSTEM</a>
    +                                        </div>
    +
    +                                    </div>
    +
    +                                    <div style="text-align: left;">
    +
    +                                        <p>
    +                                            <b>Nmon Analyser interfaces provides full reporting of almost every monitor available within the application and for the operating system concerned.</b>
    +                                            <br />
    +                                            <i>Nmon Analyser interfaces have been designed for focused time ranges, very large time ranges may require time to be fully processed.
    +                                            <br />
    +                                            For long time analysis, please consider using metric dedicated interfaces available from App home pages</i>
    +                                        </p>
    +
    +                                    </div>
    +
    +                                </div>
    +                                <div class="modal-footer">
    +                                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                                </div>
    +                            </div>
    +                        </div>
    +                    </div>
    +
    +            </html>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Compare, predict and forecast:</title>
    +
    +            <html>
    +
    +                    <div class="mainbutton_container_nomargin">
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_compare"> COMPARATIVE ANALYSIS </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_predict"> PREDICTIVE ANALYSIS </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin custom-modal">
    +                            <a class="button2_lowpadding glow" data-modal-name="Nmon_Baseline_modal">BASELINE FORECASTING</a>
    +                        </div>
    +
    +                    </div>
    +
    +
    +                    <!-- Modal -->
    +                    <div class="modal custom-modal-60 fade" id="Nmon_Baseline_modal" tabindex="-1" role="dialog" aria-labelledby="Nmon_Baseline_modal_Label">
    +                        <div class="modal-dialog" role="document">
    +                            <div class="modal-content">
    +                                <div class="modal-header">
    +                                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +
    +                                    <div style="text-align: left;">
    +                                        <h4 class="modal-title" id="Nmon_Baseline_modal_Label">NMON BASELINE: Choice menu</h4>
    +                                    </div>
    +
    +                                </div>
    +                                <div class="modal-body">
    +                                    <div style="text-align: left;">
    +                                        <h1>Select your Operating System:</h1>
    +                                    </div>
    +
    +                                    <div class="mainbutton_container">
    +
    +                                        <div class="mainbutton">
    +                                            <a class="button2_lowpadding glow" href="Nmon_baseline_AIX">  AIX SYSTEM  </a>
    +                                        </div>
    +
    +                                        <div class="mainbutton">
    +                                            <a class="button2_lowpadding glow" href="Nmon_baseline?form.osfilter=Linux">LINUX SYSTEM</a>
    +                                        </div>
    +
    +                                        <div class="mainbutton">
    +                                            <a class="button2_lowpadding glow" href="Nmon_baseline?form.osfilter=Solaris">SOLARIS SYSTEM</a>
    +                                        </div>
    +
    +                                    </div>
    +
    +                                    <div style="text-align: left;">
    +
    +                                        <p>
    +                                            NMON BASELINE interfaces provides an advanced system key metrics reporting to help detecting derivation anomalies based on past data history analysed and stored in KV stores.
    +                                            <br />
    +                                            The baseline is evaluated over a large dataset of past resources usage and allows determining if the current utilization level represents a potential derivation or normal conditions of use.
    +                                            <br />
    +                                            With the capacity of charting in the future, you can follow within the day resources usage and easily estimate what is probably not a normal situation for your specific system usage.
    +                                        </p>
    +
    +                                    </div>
    +
    +                                </div>
    +                                <div class="modal-footer">
    +                                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                                </div>
    +                            </div>
    +                        </div>
    +                    </div>
    +
    +
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +
    +    <row>
    +        <panel>
    +            <title>Application information:</title>
    +            <html>
    +
    +                <div class="imgminiheader custom-modal">
    +                    <h4>
    +                        <i>
    +                            Data Categories:  <a data-modal-name="exploreall_modal">Explore All</a> /
    +                            Event Types: <a data-modal-name="performance_modal">nmon:events</a> (Nmon events data),
    +                            <a data-modal-name="config_modal">nmon:config</a> (Configuration data),
    +                            <a data-modal-name="collect_modal">nmon:collect</a> (Nmon raw data generation),
    +                            <a data-modal-name="processing_modal" target="_blank">nmon:processing</a> (Nmon raw data processing)
    +                            &#160;-&#160;&#160;&#160;<a href="https://www.octamis.com/services/metricator" target="_blank">About this application</a>
    +                        </i>
    +                    </h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="exploreall_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Events data navigation</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:events" class="tryitbtnxxl">eventtype=nmon:events »
    +                                        </a>
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:config" class="tryitbtnxxl">eventtype=nmon:config »
    +                                        </a>
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:collect" class="tryitbtnxxl">eventtype=nmon:collect »
    +                                        </a>
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:processing" class="tryitbtnxxl">eventtype=nmon:processing »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Information:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>eventtype=nmon:events:</b> contains Nmon data stored as events (opposed to the metric store)</li>
    +                                            <br />
    +                                            <li><b>eventtype=nmon:config:</b> contains the multi-line nmon configuration data</li>
    +                                            <br />
    +                                            <li><b>eventtype=nmon:collect:</b> contains the application internal events related to the Nmon data collection activity</li>
    +                                            <br />
    +                                            <li><b>eventtype=nmon:processing:</b> contains the application internal events related to the Nmon data processing and parsing activity</li>
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="performance_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:events eventtype contains all nmon data ingested as events.
    +                                    <br />
    +                                    In the nmon:events data, the "key" is the <b>type</b> field.
    +                                    <br />
    +                                    This field contains the monitor identifier that matches a category of metrics or events, such as "type=UPTIME". (uptime and load averages)
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:events" class="tryitbtnxxl">eventtype=nmon:events »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="config_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:config eventtype contains all the data related to the configuration of your systems.
    +                                    <br />
    +                                    These are the AAA and BBB* sections of nmon raw data, generated during the nmon binary startup.
    +                                    <br />
    +                                    The events are long multi-lines events stored per host, in default configuration these data will be extracted almost every 2 hours as the data will not change unless
    +                                    a new nmon process gets launched.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:config" class="tryitbtnxxl">eventtype=nmon:config »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div>
    +                                    The nmon:config data is associated with the generation of the nmon_inventory lookup and the metricator-nmon-config data model.
    +                                    <br />
    +                                    The nmon_inventory lookup table is being generated by a scheduled report (which runs by default every hour) that extracts main configuration items (number of CPUs, volume of physical memory...)
    +                                    from the nmon:configuration data over the metricator-nmon-config data model.
    +                                    <br />
    +                                    Once the nmon_inventory data has been generated, it is ready to be used and explored within various interfaces.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="UI_Nmon_CONFIG" class="tryitbtnxxl">CONFIG interface (raw config viewer) »
    +                                        </a>
    +
    +                                        <a target="_blank" href="UI_Nmon_CONFIG_simple_inventory" class="tryitbtnxxl">INVENTORY interface (config reporting) »
    +                                        </a>
    +
    +                                        <a target="_blank" href="pivot?model=%2FservicesNS%2Fnobody%2Fnmon%2Fdatamodel%2Fmodel%2Fmetricator-nmon-config" class="tryitbtnxxl">metricator-nmon-config datamodel »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="collect_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:collect eventtype contains all the data related to the nmon processes generation on your systems.
    +                                    <br />
    +                                    These are the ouput of the input script "metricator_helper.sh" thats gets automatically launched by Splunk when deploying the Nmon App.
    +                                    <br />
    +                                    By default, the metricator_helper.sh script gets started every minute, its main job is to verify the status of the current nmon process, and start a new one if conditions requires it.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:collect" class="tryitbtnxxl">eventtype=nmon:collect »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div>
    +                                    Many nmon starting options can be controlled through the "nmon.conf" configuration file during the deployment of the App, get more information on the online Wiki:
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="https://www.octamis.com/metricator-docs/binaries.html#scripts-and-binaries" class="tryitbtnxxl">Online help: metricator_helper.sh »
    +                                        </a>
    +
    +                                        <a target="_blank" href="https://www.octamis.com/metricator-docs/metrics_collection.html" class="tryitbtnxxl">Online help: manage nmon collection »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="processing_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:processing eventtype contains all the data related to the nmon processing steps that converts nmon data into usable data for Splunk.
    +                                    <br />
    +                                    These are the ouput of nmonparser Python and Perl parsers provided within the App.
    +                                    <br />
    +                                    Every time an existing raw nmon file is updated, or a new one gets created, Splunk will call parsers scripts and generate appropriated data.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:processing" class="tryitbtnxxl">eventtype=nmon:processing »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div>
    +                                    Many nmon starting options can be controlled through the "nmon.conf" configuration file during the deployment of the App, get more information on the online Wiki:
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="http://ta-nmon.readthedocs.io/en/latest/nmon_config.html" class="tryitbtnxxl">Online help: brief description »
    +                                        </a>
    +
    +                                        <a target="_blank" href="http://ta-nmon.readthedocs.io/en/latest/data_processing.html" class="tryitbtnxxl">Online help: parsers documentation »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +
    +            <!-- large scale: this search has a very minimal (almost null) cost even at large scale
    +            refresh every 60 seconds
    +            -->
    +
    +            <single>
    +                <search ref="Dates of first and last event within indexes"></search>
    +                <option name="underLabel">DATE OF FIRST AND LAST PERF EVENT (dd/mm/YY HH:MM)</option>
    +                <option name="drilldown">all</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `indexes_datestats` | eval summary='First Event' . " - " . 'Last Event'</link>
    +                </drilldown>
    +            </single>
    +
    +            <!-- large scale: this search has been slightly optimized, even at large scale (more than 1K servers), we expect a run time of 2 sec max
    +            too short refresh have low interest, refresh every 10 minutes
    +            -->
    +
    +            <single>
    +                <search ref="Hosts with data within last 7 days">
    +                    <refresh>600s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +                <option name="rangeValues">[18]</option>
    +                <option name="refresh.display">progressbar</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="underLabel">IN THE LAST 7 DAYS</option>
    +                <option name="unit">Host(s) with activity</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=%7C%20tstats%20dc(host)%20as%20dcount%20where%20%60nmon_index%60%20sourcetype%3Dnmon_data%20by%20_time%20span%3D1d&amp;earliest=-7d%40h&amp;latest=now&amp;display.general.type=visualizations&amp;display.page.search.tab=visualizations&amp;display.visualizations.type=singlevalue</link>
    +                </drilldown>
    +            </single>
    +
    +            <!-- large scale: this search has been slightly optimized (specially using an accelerated report), even at large scale (more than 1K servers), we expect a run time of 2 sec max
    +            refresh approx. every 2 minutes
    +            -->
    +
    +            <single>
    +                <search base="base_search_volume_indexed">
    +                    <query>addinfo
    +| eval time=strftime(_time, "%H%M"), lasttime=strftime(info_search_time, "%H%M")
    +| where time&lt;=lasttime
    +| timechart span=1d sum(volume) as volume
    +| where volume&gt;0</query>
    +                </search>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +                <option name="rangeValues">[18]</option>
    +                <option name="refresh.display">progressbar</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="underLabel">TODAY / EVOLUTION VS YESTERDAY</option>
    +                <option name="unit">MB Indexed</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +            </single>
    +
    +            <!-- large scale: we don't expect any cost with this search
    +            refresh approx. every 2 minutes
    +            -->
    +
    +            <single>
    +                <search ref="Number of notable events in Data Processing or Data Collect since last 24 Hours">
    +                    <refresh>140s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="underLabel">PROCESSING/COLLECT LAST 24 HOURS</option>
    +                <option name="field">value</option>
    +                <option name="drilldown">all</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?q=(eventtype=nmon:processing OR eventtype=nmon:collect error) OR (index=_internal sourcetype=splunkd ERROR ExecProcessor nmon) NOT ("There is no python in" OR "python: not found") earliest="-24h" latest="now"</link>
    +                </drilldown>
    +            </single>
    +
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_meta_metrics" data-alt-label="HIDE META METRICS" data-token-value="true"> META METRICS</button>
    +                </div>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    # The report used as the base search generates the detailed vision of nmon data indexed within the app
    +    # This report is using report acceleration for performances purposes
    +    # However, we need to exclude relative time to report the indexed situation relatively to the current time, which is not compatible with report acceleration
    +    # which is why we first creates the detailed vision, and then post-process the results with the relevant filtering
    +
    +    <search id="base_search_volume_indexed" ref="Volume of data indexed within last 7 days">
    +        <refresh>130s</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Meta metrics -->
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <title>META METRICS:</title>
    +
    +            <html>
    +                <div style="font-style: italic;">
    +                    <p>
    +                        <b>Meta metrics</b> are volume calculations based on the application metrics design and naming convention.
    +                        <br />
    +                        This provides accurate and easy insights to analyse the volume of data related to each category of metric, Nmon metric section or even specific servers.
    +                        <br />
    +                        You can manage metrics to be generated within the <b>nmon.conf</b> file, globally for your Technical Addon deployment with a local/nmon.conf, or on per server basis in /etc/nmon.conf
    +                    </p>
    +                </div>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="meta_volume_by_metric_category" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by metric_name span=1d
    +| rex field=metric_name "os\.unix\.nmon\.(?&lt;metric_category&gt;[^\.]*)\."
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, metric_category
    +| stats avg(size_MB) as size_MB by metric_category
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_metric_section" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by metric_name span=1d
    +| rex field=metric_name "os\.unix\.nmon\.[^\.]*.(?&lt;metric_section&gt;[^\.]*)"
    +| stats sum(count) as count by _time, metric_section
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, metric_section
    +| stats avg(size_MB) as size_MB by metric_section
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_host" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by host span=1d
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, host
    +| stats avg(size_MB) as size_MB by host
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_ostype" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by OStype span=1d
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, OStype
    +| stats avg(size_MB) as size_MB by OStype
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <title>metric_category daily volumes</title>
    +        </panel>
    +        <panel>
    +            <title>metric_section daily volumes</title>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_metric_category">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_metric_section">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_metric_category">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_metric_section">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <title>hosts daily volumes</title>
    +        </panel>
    +        <panel>
    +            <title>Operating systems daily volumes</title>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_host">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_ostype">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_host">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_ostype">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Monitor:</title>
    +            <html>
    +
    +                <div class="customleft custom-modal">
    +
    +                    <h4><i>
    +                        Enter <a href="../../alerts/metricator-for-nmon">Splunk Triggered Alerts for Nmon App</a> -
    +                        Enter <a href="UI_Alert_Center">Nmon ALERT CENTER dashboard</a> -
    +                        Enter <a data-modal-name="Help_Alerting">ALERTING THRESHOLD MANAGEMENT</a> -
    +                        Or click to drilldown on active alerts
    +                    </i></h4>
    +
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_Alerting" tabindex="-1" role="dialog" aria-labelledby="Help_Alerting_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_Alerting_Label">ALERTING MANAGEMENT: Choice menu</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <h1>ALERTING THRESHOLD MANAGEMENT</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    <div style="text-align: center;">
    +                                        <img src="../../static/app/metricator-for-nmon/diagrams/threshold_management.png" alt="threshold_management.png"/>
    +                                    </div>
    +                                    <br />
    +
    +                                    <b>Thresholds are applied the following way:</b>
    +                                    <lu>
    +                                        <li>If a server has per server thresholds configured, these values have the highest priority</li>
    +                                        <li>If a template threshold matches a server (against its frameID), values are applied after per server thresholds</li>
    +                                        <li>If none of those have matches, default macro threshold values will be applied</li>
    +                                    </lu>
    +                                    <br />
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +                                    <a target="_blank" href="Manage_frameID_mapping" class="tryitbtnxl">FRAMEID MAPPING »
    +                                    </a>
    +                                    <a target="_blank" href="Manage_template_alerting_threshold" class="tryitbtnxl">TEMPLATE CPU &amp; MEM THRESHOLDS »
    +                                    </a>
    +                                    <a target="_blank" href="Manage_template_alerting_threshold" class="tryitbtnxl">TEMPLATE FILE-SYSTEMS THRESHOLDS »
    +                                    </a>
    +                                    <a target="_blank" href="Manage_alerting_threshold" class="tryitbtnxl">SERVERS CPU &amp; MEM THRESHOLDS »
    +                                    </a>
    +                                    <a target="_blank" href="Manage_alerting_threshold_filesystem" class="tryitbtnxl">SERVERS FILE-SYSTEMS THRESHOLDS »
    +                                    </a>
    +                                    <a target="_blank" href="Manage_file_systems_global_exclusion" class="tryitbtnxl">GLOBAL EXCLUSION FILE-SYSTEMS »
    +                                    </a>
    +                                    <a target="_blank" href="Manage_file_systems_exclusion" class="tryitbtnxl">SERVERS EXCLUSION FILE-SYSTEMS »
    +                                    </a>
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +
    +            <!-- large scale: All searches are being refreshed approx every 2-3 minutes, with 10 sec of
    +             difference beetween each of the searches
    +            -->
    +
    +            <single>
    +                <search>
    +                    <query>| `alerting_cpu_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>150s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">cpu percentage saturation</option>
    +                <option name="unit">cpu active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_cpu_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_realmemory_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>160s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">physical memory percentage saturation</option>
    +                <option name="unit">physical memory active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_realmemory_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_virtualmemory_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>170s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">virtual memory saturation</option>
    +                <option name="unit">virtual memory active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_virtualmemory_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_filesystem_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>180s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">file-systems under usage saturation</option>
    +                <option name="unit">file systems active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_filesystem_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>All interfaces:</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +
    +        <!-- ############################################ CPU CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" target="_blank">CPU Usage Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CPU_ALL" class="tryitbtn">CPU_ALL »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CPU_ALL">
    +                        <span title="CPU Utilization statistics in Percentage (%) &#013;
    +&#013;
    +• Represents the percentage of CPU system load for all available cores &#013;
    +&#013;
    +• Statistics can be returned in global usage or main category: Sys,User,Wait,Idle">
    +                            ALL OS: Percentage of CPU Utilization
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_LOAD_AVG" class="tryitbtn">SYS LOAD AVERAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_LOAD_AVG">
    +                        <span title="UPTIME load average statistics &#013;
    +&#013;
    +• system load averages for the past 1, 5, and 15 minutes &#013;
    +&#013;
    +• statistics retrieved from external uptime collection">
    +                            ALL OS: uptime system load averages
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CPUnn" class="tryitbtn">CPUnn »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CPUnn">
    +                        <span title="CPU Utilization per logical core statistics in Percentage (%) &#013;
    +&#013;
    +• Represents the percentage of CPU system load by logical core (lower level of CPU usage details) &#013;
    +&#013;
    +• Statistics can be returned in global usage or main category: Sys,User,Wait,Idle">
    +                            ALL OS: Percentage of CPU Utilization per logical core
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title custom-modal">
    +
    +                    <a data-modal-name="LPAR_modal" class="tryitbtn">LPAR »
    +                    </a>
    +
    +                    <a data-modal-name="LPAR_modal">
    +                        <span title="IBM Power partitions statistics &#013;
    +&#013;
    +• A Micro Power Partition (AIX or PowerLinux) returns various CPU utilization statistics in virtual CPUs units &#013;
    +&#013;
    +• Additionnaly, the Partition is able to return statistics about the Pool that hosts the partition">
    +                            AIX / PowerLinux: Virtual Partition and Pools CPU Utilization
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="LPAR_modal" tabindex="-1" role="dialog" aria-labelledby="LPAR_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="LPAR_Label">Integrated Navigation:</h4>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/manufactors/IBM_logo_72px.png" alt="IBM"/>
    +                                    <h1>Power Partitions and Pools statistics</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <p>
    +                                        The LPAR monitor contains various CPU related metrics about Partitions and Pools utilization.
    +                                        <br />
    +                                        These metrics are available on AIX and PowerLinux partitions. (PowerLinux must run at least nmon 16e versions)
    +                                        <br />
    +                                        To be able to retrieve Pools related statistics, the partition must be authorized to do so in the HMC configuration for the Pseries.
    +                                    </p>
    +
    +                                </div>
    +
    +                                <br />
    +
    +                                <div style="text-align: left;">
    +                                    <h1>For AIX systems:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container_nomargin" style="text-align: left;">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_LPAR_AIX">  PARTITIONS STATISTICS  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_LPAR_AIX_poolconso">POOLS STATISTICS</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <br />
    +
    +                                <div style="text-align: left;">
    +                                    <h1>For PowerLinux systems:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container_nomargin" style="text-align: left;">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_LPAR_LINUX">  PARTITIONS STATISTICS  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_LPAR_LINUX_poolconso">POOLS STATISTICS</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_POOLS" class="tryitbtn">POOLS »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_POOLS">
    +                        <span title="Virtual CPU Utilization of PSeries Pools (same as part of LPAR with some additional monitors) &#013;
    +&#013;
    +• For IBM P5 generation and less, a Micro Partition that has App access will return the load of the PSeries &#013;
    +&#013;
    +• For IBM P6 generation and more, a Micro Partition that has App access will return the load of it's Pool, and the load of the PSeries if it is part of the DefaultPool">
    +                            AIX: PSeries Pools statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title custom-modal">
    +
    +                    <a data-modal-name="WLMCPU_modal" class="tryitbtn">WLM CPU »
    +                    </a>
    +
    +                    <a data-modal-name="WLMCPU_modal">
    +                        <span title="CPU Utilization statistics in Percentage (%) for Workload Manager &#013;">
    +                            AIX, Solaris: Workload Manager CPU %
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- WLM has specific interfaces per type of operating system, use a modal window for user choice -->
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="WLMCPU_modal" tabindex="-1" role="dialog" aria-labelledby="WLMCPU_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="WLMCPU_modal_Label">WLM monitor: Choice menu</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: left;">
    +                                    <h1>Select your Operating System:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_WLM_AIX?form.monitor=os.unix.nmon.processes.wlmcpu">  AIX SYSTEM  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_WLM_SOLARIS?form.type_monitor=CPU">SOLARIS SYSTEM</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <p>
    +                                        <b>Workload Manager statistics for AIX and Solaris contains various performance metrics about Workload classes.</b>
    +                                        <br />
    +                                        Depending on the operating system, this monitor includes CPU, Memory, Block I/O statistics.
    +                                        <br />
    +                                    </p>
    +
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ KERNEL CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="Process"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=KERNEL%20STATISTICS&amp;form.itemfilter=PROCESSES%20STATISTICS&amp;form.itemfilter=PAGING%20STATISTICS&amp;form.itemfilter=FIBER%20CHANNEL%20STATISTICS&amp;form.itemfilter=BLOCK%20STATISTICS" target="_blank">Process, Kernel, I/O Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title custom-modal">
    +
    +                    <a data-modal-name="TOP_modal" class="tryitbtn">TOP »
    +                    </a>
    +
    +                    <a data-modal-name="TOP_modal">
    +                        <span title="Statistics of Main Processes System Resources Usage &#013;
    +&#013;
    +• Get the CPU core utilization of main processes aggregated by Command invocations &#013;
    +&#013;
    +• Others Statistics available: Real/Virtual memory usage, minor and major faults and more &#013;
    +&#013;
    +• With UARG information, filter PIDs from Command to get accurate measures of complex processes
    +&#013;">
    +                            ALL OS: Main Processes System Resources Usage
    +                        </span>
    +                    </a>
    +
    +                </div>
    +                
    +                <!-- TOP has specific interfaces per type of operating system, use a modal window for user choice -->
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="TOP_modal" tabindex="-1" role="dialog" aria-labelledby="TOP_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="TOP_modal_Label">TOP monitor: Choice menu</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: left;">
    +                                    <h1>Select your Operating System:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_TOP_AIX">  AIX SYSTEM  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_TOP_LINUX"> LINUX SYSTEM </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_TOP_SOLARIS">SOLARIS SYSTEM</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <p>
    +                                        <b>The TOP monitor provides essential resource usage statistics of processes, and has specific interfaces per operating system.</b>
    +                                        <br />
    +                                        Depending on the operating system, this monitor may include on a per process level CPU usage, Physical and Vitual memory usage, number of threads, Major and Minor faults...
    +                                        <br />
    +                                    </p>
    +
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <div class="cat_title custom-modal">
    +
    +                    <a data-modal-name="UARG_modal" class="tryitbtn">UARG »
    +                    </a>
    +
    +                    <a data-modal-name="UARG_modal">
    +                        <span title="Search for PIDs, Commands and Full Arguments of Processes &#013;
    +&#013;
    +• With UARG, get detailed information about Commands registered: PID, Full arguments and more &#013;
    +&#013;
    +• These information can also be very useful within TOP interfaces for accurate analysis">
    +                            ALL OS: Search for PIDs, Commands and Arguments
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- UARG has specific interfaces per type of operating system, use a modal window for user choice -->
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="UARG_modal" tabindex="-1" role="dialog" aria-labelledby="UARG_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="UARG_modal_Label">UARG monitor: Choice menu</h4>
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: left;">
    +                                    <h1>Select your Operating System:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_UARG_AIX">  AIX SYSTEM  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_UARG_LINUX"> LINUX SYSTEM </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_UARG_SOLARIS">SOLARIS SYSTEM</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <p>
    +                                        <b>The UARG monitor provides PID information with full commands arguments, and has specific interfaces per operating system.</b>
    +                                        <br />
    +                                    </p>
    +
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +                
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_FILE" class="tryitbtn">FILE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_FILE">
    +                        <span title="Various Kernel File statistics &#013;
    +&#013;
    +• Read / Write System calls and other statistics">
    +                            AIX, SOLARIS: Kernel File Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_IOADAPT" class="tryitbtn">IOADAPT »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_IOADAPT">
    +                        <span title="I/O Adapters Statistics &#013;
    +&#013;
    +• Data Rate (Kbytes/sec) and Total I/O Operations (tps) per Adapter Interfaces">
    +                            AIX: I/O Adapters Read/Write Operations
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_FC" class="tryitbtn">FC »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_FC">
    +                        <span title="Fiber Chanel Interfaces Statistics &#013;
    +&#013;
    +• Data Rate (Kbytes/sec) and Total I/O Operations (tps) per Fiber Channel Interfaces">
    +                            AIX: Fiber Channel Read/Write Operations
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_PROC" class="tryitbtn">PROC »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_PROC">
    +                        <span title="Kernel Internal Statistics &#013;
    +&#013;
    +• RunQueue, Swap-In, pswitch, syscall, fork, exec and more">
    +                            ALL OS: Kernel Internal Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_PROCSOL_SOLARIS" class="tryitbtn">PROCSOL »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_PROCSOL_SOLARIS">
    +                        <span title="Solaris Processes Activity Statistics &#013;
    +&#013;
    +This interface will return the percentage of time processes have spent in, such as &#013;
    +&#013;
    +• % of Time in User / System / mode, % of Time processing system traps &#013;
    +&#013;
    +• % of Time waiting for CPU, and more">
    +                            SOLARIS: Percentage of Time Processes have spent in
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_PAGE_AIX" class="tryitbtn">PAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_PAGE_AIX">
    +                        <span title="Paging Statistics &#013;
    +&#013;
    +• Pages In / Pages Out (pgsin / pgsout) &#013;
    + &#013;
    +• Fs In / Fs Out (sum of pgin/pgsin and pgout/pgsout per interval) &#013;
    + &#013;
    +• Scan Free Ratio (Pages scans by reclaims per interval) &#013;
    + &#013;
    +And more">
    +                            AIX: Paging Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_WLM_AIX?form.monitor=WLMBIO" class="tryitbtn">WLM BIO »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_WLM_AIX?form.monitor=os.unix.nmon.processes.wlmbio">
    +                        <span title="Block I/O statistics in Percentage (%) for Workload Manager &#013;">
    +                            AIX: Workload Manager Block I/O %
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ MEMORY CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/memory.png" alt="Memory"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=MEMORY%20STATISTICS" target="_blank">Memory Statistics</a></h2>
    +
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_MEMNEW_AIX" class="tryitbtn">MEMNEW »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_MEMNEW_AIX">
    +                        <span title="Memory Allocation Statistics&#013;
    +&#013;
    +• Analyse Memory allocation by main categories: FSCache, Process, System, Free &#013;
    +&#013;
    +• Global Memory rate utilization">
    +                            AIX: Percentage of Memory Allocation
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title custom-modal">
    +
    +                    <a data-modal-name="MEM_modal" class="tryitbtn">MEM »
    +                    </a>
    +
    +                    <a data-modal-name="MEM_modal">
    +                        <span title="Real and Virtual Memory Statistics &#013;
    +&#013;
    +• Memory Usage in Data Volume (MB) or Percentage &#013;
    +&#013;
    +• Specific System Stats (for Linux: Buffers / Cached / Active / Inactive...)">
    +                            ALL OS: Real and Virtual Memory Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- MEM has specific interfaces per type of operating system, use a modal window for user choice -->
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="MEM_modal" tabindex="-1" role="dialog" aria-labelledby="MEM_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="MEM_modal_Label">MEM monitor: Choice menu</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: left;">
    +                                    <h1>Select your Operating System:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_MEM_AIX">  AIX SYSTEM  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_MEM_LINUX"> LINUX SYSTEM </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_MEM_SOLARIS">SOLARIS SYSTEM</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <p>
    +                                        <b>The MEM monitor provides various essential memory utilization statistics and has specific interfaces per operating system.</b>
    +                                        <br />
    +                                    </p>
    +
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <div class="cat_title custom-modal">
    +
    +                    <a data-modal-name="MEMUSE_modal" class="tryitbtn">MEMUSE »
    +                    </a>
    +
    +                    <a data-modal-name="MEMUSE_modal">
    +                        <span title="Various Memory Statistics &#013;
    +&#013;
    +• Cache Hit Ratio, System Buffer Accesses...">
    +                            AIX, SOLARIS: Various Memory Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- MEM has specific interfaces per type of operating system, use a modal window for user choice -->
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-50 fade" id="MEMUSE_modal" tabindex="-1" role="dialog" aria-labelledby="MEMUSE_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="MEMUSE_modal_Label">MEMUSE monitor: Choice menu</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: left;">
    +                                    <h1>Select your Operating System:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_MEMUSE_AIX">  AIX SYSTEM  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_MEMUSE_SOLARIS">SOLARIS SYSTEM</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <p>
    +                                        <b>The MEMUSE monitor is dedicated to AIX and Solaris systems only, and it has specific interfaces per operating system.</b>
    +                                        <br />
    +                                    </p>
    +
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <div class="cat_title custom-modal">
    +
    +                    <a data-modal-name="VM_modal" class="tryitbtn">VM »
    +                    </a>
    +
    +                    <a data-modal-name="VM_modal">
    +                        <span title="Various Virtual Memory statistics &#013;
    +&#013;
    +• Pageins / Pageout &#013;
    +&#013;
    +• Swapins / Swapout &#013;
    +&#013;
    +• Minor and Major faults &#013;
    +&#013;
    +And more">
    +                            LINUX, SOLARIS: Kernel Virtual Memory Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- UARG has specific interfaces per type of operating system, use a modal window for user choice -->
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-50 fade" id="VM_modal" tabindex="-1" role="dialog" aria-labelledby="VM_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="VM_modal_Label">VM monitor: Choice menu</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: left;">
    +                                    <h1>Select your Operating System:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_VM_LINUX"> LINUX SYSTEM </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_VM_SOLARIS">SOLARIS SYSTEM</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <p>
    +                                        <b>The VM monitor provides advanced virtual memory statistics for Linux and Solaris systems, and has specific interfaces per operating system.</b>
    +                                        <br />
    +                                    </p>
    +
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <div class="cat_title custom-modal">
    +
    +                    <a data-modal-name="WLMMEM_modal" class="tryitbtn">WLM MEM »
    +                    </a>
    +
    +                    <a data-modal-name="WLMMEM_modal">
    +                        <span title="Memory Utilization statistics in Percentage (%) for Workload Manager &#013;">
    +                            AIX, Solaris: Workload Manager MEM %
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- WLM has specific interfaces per type of operating system, use a modal window for user choice -->
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="WLMMEM_modal" tabindex="-1" role="dialog" aria-labelledby="WLMMEM_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="WLMMEM_modal_Label">WLM monitor: Choice menu</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: left;">
    +                                    <h1>Select your Operating System:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_WLM_AIX?form.monitor=os.unix.nmon.processes.wlmmem">  AIX SYSTEM  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_WLM_SOLARIS?form.type_monitor=MEM">SOLARIS SYSTEM</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <p>
    +                                        <b>Workload Manager statistics for AIX and Solaris contains various performance metrics about Workload classes.</b>
    +                                        <br />
    +                                        Depending on the operating system, this monitor includes CPU, Memory, Block I/O statistics.
    +                                        <br />
    +                                    </p>
    +
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ DISKS AND FS CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/drive.png" alt="Drive"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=DISKS%20STATISTICS&amp;form.itemfilter=FILESYSTEMS%20STATISTICS" target="_blank">Disks and Filesystems Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DG" class="tryitbtn">DG »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DG">
    +                        <span title="Disks extended statistics (DG*) &#013;
    +&#013;
    +• Disks aggregated statistics: I/O, read / write performance and latency...">
    +                            Linux: Disks extended statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbsize" class="tryitbtn">DISKBSIZE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbsize">
    +                        <span title="Transfer Statistics per Disk &#013;
    +&#013;
    +• Average data size per block device transfer per disk (KBytes per transfer)">
    +                            ALL OS: Average Data Transfer Size
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbusy" class="tryitbtn">DISKBUSY »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbusy">
    +                        <span title="Percentage of Time Busy Disk &#013;
    +&#013;
    +• Analyse the Percentage of Time a disk was busy">
    +                            ALL OS: The Percentage of time a disk was Busy
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskread" class="tryitbtn">DISKREAD »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskread">
    +                        <span title="Disks Read Data rate &#013;
    +&#013;
    +• Analyse Disk Read operation Data rate in Kbytes/sec">
    +                            ALL OS: Disk Read Data Rate
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwrite" class="tryitbtn">DISKWRITE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwrite">
    +                        <span title="Disks Write Data rate &#013;
    +&#013;
    +• Analyse Disk Write operation Data rate in Kbytes/sec">
    +                            ALL OS: Disk Write Data Rate
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskxfer" class="tryitbtn">DISKXFER »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskxfer">
    +                        <span title="Disks I/O per second &#013;
    +&#013;
    +• Numbers of Input / Output operations per second (formerly IOPS) by disk">
    +                            ALL OS: Disk I/O Operations per second (IOPS)
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.disksvctm&amp;form.osfilter=Solaris" class="tryitbtn">DISKSVCTM »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.disksvctm&amp;form.osfilter=Solaris">
    +                        <span title="(ms) Average service time by disk&#013;
    +&#013;
    +• Same as 'sar -d.avserv' &#013;
    +&#013;
    +• Same as 'iostat -xn.asvc_t'. For iostat, a disk is referred as a device' &#013;
    +
    +">
    +                            Solaris: Disk Average Service time
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwaittm&amp;form.osfilter=Solaris" class="tryitbtn">DISKWAITTM »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwaittm&amp;form.osfilter=Solaris">
    +                        <span title="(ms) Average wait time by disk&#013;
    +&#013;
    +• Same as 'sar -d.avwait' &#013;
    +&#013;
    +• Same as 'iostat -xn.wsvc_t'. For iostat, a disk is referred as a device' &#013;
    +
    +">
    +                            Solaris: Disk Average Wait time
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_STORAGE" class="tryitbtn">STORAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_STORAGE">
    +                        <span title="File Systems usage statistics &#013;
    +&#013;
    +• Usage statistics of file systems: volume, volume used and free, percentages...">
    +                            ALL OS: File systems utilisation statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +    </row>
    +
    +    <!-- ###################################################################################################### -->
    +
    +    <!-- ############################################ NET CATEGORY ############################################ -->
    +
    +    <row>
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/network.png" alt="Network"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=NETWORK*" target="_blank">Network Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.net" class="tryitbtn">NET »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.net">
    +                        <span title="Network Traffic per interface &#013;
    +&#013;
    +• Analyse Traffic Data per interface in Kbps / Mbps / Gbps and per host">
    +                            ALL OS: Traffic Data Rate per Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.netpacket" class="tryitbtn">NETPACKET »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.netpacket">
    +                        <span title="Network Packets per interface &#013;
    +&#013;
    +• Analyse the Number of Read and Write Network packets per interface and per host">
    +                            ALL OS: Read/Write packets per Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.neterror" class="tryitbtn">NETERROR »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.neterror">
    +                        <span title="Network Packets in Error per interface &#013;
    +&#013;
    +• Analyse the Number of Network packets that in error per interface and per host">
    +                            AIX, SOLARIS: Error packets per Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NFS" class="tryitbtn">NFS »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NFS">
    +                        <span title="Network File System (NFS) Server and Client Statistics &#013;
    +&#013;
    +• Analyse various NFS Client and Server Statistics, eligible for NFS version 2/3/4">
    +                            AIX, LINUX: Network FileSystem Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_SEA" class="tryitbtn">SEA »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_SEA">
    +                        <span title="Ethernet (Shared and Physical) Adapters Traffic Analysis &#013;
    +&#013;
    +• Analyse Traffic Data for Shared and Physical Ethernet Adapters in Kbps / Mbps / Gbps and per host
    +&#013;
    +• Analyse network packets for Shared and Physical Ethernet Adapters">
    +                            AIX: Shared Ethernet Adapters Traffic
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ PREDICT AND COMPARE ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/predict.png" alt="Prediction"/>
    +                    <h2>Data Prediction</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title custom-modal">
    +
    +                    <a target="_blank" data-modal-name="Nmon_Baseline_modal" class="tryitbtn-alt">BASELINE »
    +                    </a>
    +
    +                    <a target="_blank" data-modal-name="Nmon_Baseline_modal">
    +                        <span title="Nmon Baseline Analysis &#013;
    +&#013;
    +• With the baseline Nmon KV Store, use this interface to analyse historical data and detect key system metrics derivations &#013;
    +&#013;
    +• Key system metrics (CPU usage, Real and Virtual Memory, IOPS disk statistics) charted over the baseline &#013;
    +&#013;
    +• Optionally chart current statistics over the future baseline and get realtime situation of system resources utilization">
    +                            System Key Metrics over Baseline
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Nmon_predict" class="tryitbtn-alt">PREDICTIVE »
    +                    </a>
    +
    +                    <a target="_blank" href="Nmon_predict">
    +                        <span title="CPU Predictive Analysis Interface &#013;
    +&#013;
    +• Using the predict Splunk command, this interface will help trying to estimate future load of your systems &#013;
    +&#013;
    +• Choose between available algorithms: Local Level (LL), Seasonal Local Level (LLP), Local Level Trend (LLT) and LLP5 (combine LLT and LLP)&#013;">
    +                            Predictive interface, forecast future using predict
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/compare.png" alt="Compare"/>
    +                    <h2>Data Comparison</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Nmon_compare" class="tryitbtn-alt">COMPARE »
    +                    </a>
    +
    +                    <a target="_blank" href="Nmon_compare">
    +                        <span title="Nmon Comparison Interface &#013;
    +&#013;
    +• Compare System Resources usage between 2 periods, a reference Period and arrival Period &#013;
    +&#013;
    +• Choose between Main Monitors: CPU usage (CPU_ALL / LPAR), Memory, I/O, Network &#013;
    +&#013;
    +• Evaluate the trend with Evolution Rate and graphical decorations to help instantly discover the comparison result">
    +                            Nmon Comparison Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ DASHBOARDS ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/dashboard.png" alt="Dashboard"/>
    +                    <h2>Dashboards</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title custom-modal">
    +
    +                    <a data-modal-name="TOP_bubblechart_modal" class="tryitbtn-alt">TOP HOSTS DASH »
    +                    </a>
    +
    +                    <a data-modal-name="TOP_bubblechart_modal">
    +                        <span title="BubbleChart: TOP hosts CPU Usage &#013;
    +&#013;
    +• Evaluate the TOP 100 hosts CPU load represented in Bubble Charts to instantly discover hosts responsible of the global load average &#013;
    +&#013;
    +• Evaluate the TOP 20 hosts CPU load represented in d3chart bar chart &#013;
    +&#013;
    +• Evaluate the full Statistics table of hosts CPU load with main hosts information">
    +                            BubbleChart: TOP hosts CPU Usage
    +                        </span>
    +                    </a>
    +
    +                </div>
    +                
    +                <!-- TOP bubblechart has specific interfaces per type of operating system, use a modal window for user choice -->
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="TOP_bubblechart_modal" tabindex="-1" role="dialog" aria-labelledby="TOP_bubblechart_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="TOP_bubblechart_modal_Label">TOP bubblechart dashboard: Choice menu</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: left;">
    +                                    <h1>Select your Operating System:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="Dashboard_BubbleChart_top_hosts?&amp;form.osfilter=AIX">  AIX SYSTEM  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="Dashboard_BubbleChart_top_hosts?&amp;form.osfilter=Linux"> LINUX SYSTEM </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="Dashboard_BubbleChart_top_hosts?&amp;form.osfilter=Solaris">SOLARIS SYSTEM</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <p>
    +                                        <b>The TOP bubble chart dashboard provides a graphical view of TOP hosts using CPU, and has specific versions and/or options per operating system.</b>
    +                                        <br />
    +                                    </p>
    +
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_bulletcharts" class="tryitbtn-alt">BULLET DASH »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_bulletcharts">
    +                        <span title="Bullet charts Dashboard: Analysis of main system metrics in bullet charts &#013;
    +&#013;
    +• TOP hosts by CPU usage / TOP hosts by physical and virtual memory usage &#013;
    +&#013;
    +• TOP Commands (processes) consumming CPU and Memory in your deployment &#013;
    +&#013;
    +• Advanced drilldown facilities for insight analysis">
    +                            Bullet Chart: TOP Servers / TOP Processes
    +                        </span>
    +                    </a>
    +
    +                </div>
    +                
    +                <div class="cat_title custom-modal">
    +
    +                    <a data-modal-name="TOP_processes_dashboard" class="tryitbtn-alt">TOP PROCESSES DASH »
    +                    </a>
    +
    +                    <a data-modal-name="TOP_processes_dashboard">
    +                        <span title="Dashboard: Processes CPU and Memory Usage &#013;
    +&#013;
    +• Evaluate Processes CPU and Memory usage in d3chart BubbleChart to instantly represent major Command invocations &#013;
    +&#013;
    +• Represent this CPU / Memory usage in a d3chart chart over time &#013;
    +&#013;">
    +                            Processes CPU and Memory Usage
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_heatmap_daily_usage" class="tryitbtn-alt">CALENDAR DAILY CPU USAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_heatmap_daily_usage">
    +                        <span title="Dashboard: CALENDAR DAILY CPU USAGE &#013;
    +&#013;
    +• Evaluate daily CPU usage of multiple servers within the heatmap calendar visualization &#013;
    +&#013;
    +• Zoom within the TOP consumers by chart drilldown &#013;
    +&#013;">
    +                            Daily CPU usage calendar with drilldown
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- TOP processes dashboard has specific interfaces per type of operating system, use a modal window for user choice -->
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="TOP_processes_dashboard" tabindex="-1" role="dialog" aria-labelledby="TOP_processes_dashboard_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="TOP_processes_dashboard_Label">TOP processes dashboard: Choice menu</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: left;">
    +                                    <h1>Select your Operating System:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="Dashboard_Bubblechart_top_processes?&amp;form.osfilter=AIX">  AIX SYSTEM  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="Dashboard_Bubblechart_top_processes?&amp;form.osfilter=Linux"> LINUX SYSTEM </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="Dashboard_Bubblechart_top_processes?&amp;form.osfilter=Solaris">SOLARIS SYSTEM</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <p>
    +                                        <b>The TOP processes dashboard provides a graphical view of TOP hosts / processes using CPU / Memory, and has specific versions and/or options per operating system.</b>
    +                                        <br />
    +                                    </p>
    +
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +                
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_WLM_Solaris" class="tryitbtn-alt">DASHBOARD WLM »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_WLM_Solaris">
    +                        <span title="D3chart: Solaris Projects / Zones / Tasks / Users CPU and Memory statistics &#013;
    +&#013;
    +• Evaluate Major CPU and MEM usage items, choose between available monitors &#013;
    +&#013;
    +• Represent this CPU / Memory usage in a d3chart bubblechart and statistic tables &#013;
    +&#013;">
    +                            Solaris WLM CPU and Memory Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- ###################################################################################################### -->
    +
    +                <!-- ############################################ CONFIG ############################################ -->
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/server_info.png" alt="ServerInfo"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=CONFIGURATION%20DATA" target="_blank">Hosts Configuration</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG" class="tryitbtn-alt">CONFIG »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG">
    +                        <span title="Hosts Configuration Show Interface &#013;
    +&#013;
    +• Explore the raw configuration of hosts &#013;
    +&#013;
    +• The full raw host configuration is part of AAA and BBB sections of raw Nmon files">
    +                            CONFIG: Hosts Configuration Show Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG_simple_inventory" class="tryitbtn-alt">INVENTORY »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG_simple_inventory">
    +                        <span title="Nmon Configuration Inventory &#013;
    +&#013;
    +• Explore the Nmon inventory of known hosts from your system to get valuable information &#013;
    +&#013;
    +• Main configuration Items depends on Operating System: type of OS, OS version, CPU / Mem configuration and more">
    +                            Nmon Configuration Inventory
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ PROCESSING ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h2>Application Information and costs</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_Internal_Stats" class="tryitbtn-alt">TCO ANALYSIS »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_Internal_Stats">
    +                        <span title="Application Internal Statistics &#013;
    +&#013;
    +• Estimate the average cost of licence per server &#013;
    +&#013;
    +• Monitor the global licence cost associated with the Nmon Performance application &#013;
    +&#013;
    +• Monitor run time metrics of scheduled searches  &#013;
    +&#013;
    +• Immediately view storage details of the Nmon index
    +">
    +                            Total Cost of Ownership Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/dictionary.png" alt="Dictionary"/>
    +                    <h2>Data Dictionary</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_data_dictionary" class="tryitbtn-alt">
    +                        <span title="Data Dictionary &#013;
    +&#013;
    +• Discover and Explore available data within the Nmon Splunk Application &#013;
    +&#013;
    +• Filter relevant Data for AIX, Linux and Solaris systems &#013;
    +&#013;
    +• Access to full metric definition: brieve and full description, relevant unity, formula...">
    +
    +                            Explore The Data Dictionary »
    +
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +    </row>
    +</dashboard>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Home_AIX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Home_AIX.xml
    new file mode 100644
    index 0000000..63f9d65
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Home_AIX.xml
    @@ -0,0 +1,2067 @@
    +<dashboard script="autodiscover.js,panel_resize.js,active_button.js,modal.js" stylesheet="Home.css,ui_simple.css,hover.css,hide_timeindicator.css" hideEdit="true" isVisible="false" version="1.1" theme="dark">
    +    <label>Home AIX</label>
    +    <description></description>
    +
    +    <!-- Take the tour ! -->
    +	<row >
    +		<panel>
    +			<html>
    +				<div class = "splunk-view" data-require = "app/metricator-for-nmon/components/scc_takethetour/scc_takethetour"
    +					data-options = '{
    +						"user_slides":"scc-takethetour-slides",
    +						"width":"60",
    +						"title":"Metricator for Nmon: Take the tour !",
    +						"close_btn_label":"Close",
    +						"no_more_label":"Do not show this again",
    +						"cookie_name_suffix":"metricator-for-nmon-v1.0",
    +						"hide_container":false,
    +						"show_credits":true
    +					}'>
    +				</div>
    +				<ul id="scc-takethetour-slides" class="hide">
    +
    +					<li>
    +
    +                        <h1>WELCOME IN THE METRICATOR APPLICATION FOR SPLUNK ENTERPRISE</h1>
    +
    +                        <h2>The super fast, rich and definitive monitoring and performance application suite for Unix and Linux.</h2>
    +
    +                        <div style="text-align: left;">
    +                            <a href="http://www.octamis.com" target="_blank">
    +                                <img src="../../static/app/metricator-for-nmon/Octamis/Octamis_Logo_v3_no_bg.png" alt="Octamis"/>
    +                            </a>
    +                        </div>
    +
    +                        <b>Contact us at: </b><a target="_top" href="mailto:sales@octamis.com?subject=Nmon%20Performance%20for%20Splunk">sales@octamis.com</a>
    +                        <br />
    +                        <b>Share your testimonial: </b><a target="_top" href="mailto:nmon@octamis.com?subject=Nmon%20Performance%20for%20Splunk">nmon@octamis.com</a>
    +                        <br />
    +                        <b>We are looking for talent, <a target="_blank" href="https://www.octamis.com/careers/">find a job opportunity at Octamis</a></b>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/main.png" alt="main.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +
    +                        <h1>Metrics on steroids with Splunk 7 metric store</h1>
    +
    +                        <h2>Native metrics implementation</h2>
    +
    +                        <p>
    +                            The Metricator application fully implements Splunk time series metrics ingested within the metric store indexes.
    +                            <br />
    +                            We make good usage of it, and bring you one of the most performer user experience on Splunk Enterprise.
    +                            <br />
    +                            Access easily any metric available, use high performance mstats and mcatalog commands and retrieve results in seconds.
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/metrics_showcase.png" alt="metrics_showcase.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +
    +                        <h1>The most advanced dynamic dashboards and user interfaces for the highest quality of user experience</h1>
    +
    +                        <h2>We've got you covered. Find replies to your questions and get back in control with your systems</h2>
    +
    +                        <p>
    +                            Use our advanced dashboards to easily perform the best performance analysis.
    +                            <br />
    +                            More than simple dashboards, we provide rich, powerful and well designed user interfaces.
    +                            <br />
    +                            Dashboards and user interfaces are easily accessible from the application home page, we have a dashboard for all use cases.
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/advanced_dashboards.png" alt="advanced_dashboards.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +						<h1>Certified Technical Addon, low footprint and highly configurable</h1>
    +
    +                        <h2>Our Technical Addons are heavily tested, qualified and certified against numbers of architectures and Operating Systems, this includes:</h2>
    +
    +                        <p>
    +                            - IBM AIX 7.1 / 7.2<br />
    +                            - PowerLinux Linux (RHEL/Ubuntu/SLES...)<br />
    +                            - X86 (RHEL/Ubuntu/SLES...)<br />
    +                            - Oracle Solaris 11 on X86 and SPARC<br />
    +                        </p>
    +
    +                        The Technical Addons are as well compatible with ARM platforms, IBM zLinux!
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/OS_logos.png" alt="OS_logos.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +						<h1>Builtin costs of ownership analytic and metrics volume optimizations</h1>
    +
    +                        <h2>Get the insight vision of every cost related to your deployment</h2>
    +
    +                        <p>
    +                            - The DCO dashboard provides you builtin analytic features against application costs, daily average volume and metric metadatas, and even more<br />
    +                            - The Add-on dashboard provides automatic reporting your servers deployment, which versions are deployed on which servers<br />
    +                            - Don't pay for a zero ! The Technical Addons have been slighty optimized to remove any useless data from the metrics generation, you only pay for what is useful<br />
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/tco.png" alt="tco.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +						<h1>Threshold management, frameID mapping and thresholds templating</h1>
    +
    +                        <h2>The alerting features implements a multi-layer thresholds system based on:</h2>
    +
    +                        <p>
    +                            - The frameID that allows logically grouping server assets<br />
    +                            - FrameID mapping is achieved either at the raw level with different options (static definition, pre-ation scripts) or at search time with the KVstore management interface for frameID mapping<br />
    +                            - Alerting thresholds values can be defined using macros default, on a per frameID template basis or on a per server basis using the KVstore collection management interfaces<br />
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/thresholds.png" alt="thresholds.png"/>
    +                        </div>
    +
    +					</li>
    +
    +                </ul>
    +			</html>
    +		</panel>
    +	</row>
    +
    +    <row>
    +        <panel>
    +
    +            <single>
    +                <search id="HostsCount">
    +                    <query>| inputlookup nmon_inventory | search OStype="AIX" | stats count</query>
    +                    <refresh>60s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="underLabel">KNOWN IN NMON INVENTORY</option>
    +                <option name="field">count</option>
    +                <option name="drilldown">all</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0xd93f3c","0x006d9c"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="unit">found AIX host(s)</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype=AIX
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </single>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Metrics exploration:</title>
    +
    +            <html>
    +
    +                    <div class="mainbutton_container_nomargin">
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_mexplorer">  M-EXPLORER  </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin custom-modal">
    +                            <a class="button2_lowpadding glow" data-modal-name="appinfo_modal">M-STRUCTURE</a>
    +                        </div>
    +
    +                    </div>
    +
    +                    <!-- Modal -->
    +                    <div class="modal custom-modal-60 fade" id="appinfo_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                        <div class="modal-dialog" role="document">
    +                            <div class="modal-content">
    +                                <div class="modal-header">
    +                                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                    <div style="text-align: left;">
    +                                        <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                    </div>
    +                                </div>
    +                                <div class="modal-body">
    +
    +                                    <div style="text-align: left;">
    +                                        <h1>
    +                                            METRICS STORAGE AND NAMING CONVENTION:
    +                                        </h1>
    +                                    </div>
    +
    +                                    <div>
    +                                        <br />
    +                                        By default, all metrics are indexed in the metric index called <b>os-unix-nmon-metrics</b>
    +                                        <br />
    +                                        Dashboards and reports globally refer to a macro named <b>nmon_metrics_index</b> that can be customized up to your needs and matches by default any index starting by <b>os-unix-nmon-metrics*</b>
    +
    +                                        <h2 style="color: lightslategrey;">Metrics scheme:</h2>
    +
    +                                        The metric generation process applies a common scheme easy to exploit, mostly: <b>os.unix.nmon.&lt;metric_category&gt;.&lt;nmon_section&gt;.&lt;metric&gt;.&lt;sub_metric&gt;</b>
    +
    +                                        <h2 style="color: lightslategrey;">Metrics dimensions:</h2>
    +
    +                                        Optional dimensions are available depending on metrics, such as the network interface names, and always start by <b>dimension_</b>, example: <b>dimension_device</b>
    +                                        <br />
    +                                        Dimensions can be retrieved automatically by the mcatalog command using the special field <b>"_dims"</b> field: <b>values(_dims) as dimensions</b>
    +
    +                                        <h2 style="color: lightslategrey;">Special dimensions:</h2>
    +
    +                                        The Technical addons creates some special dimensions to be used in servers filtering queries:
    +                                        <br />
    +                                        <lu>
    +                                            <li><b>OStype:</b> type of Operating System for the server</li>
    +                                            <li><b>serialnum:</b> serial number registered for the server (linked to the frameID)</li>
    +                                        </lu>
    +
    +                                        <h2 style="color: lightslategrey;">mcatalog queries:</h2>
    +
    +                                        mcatalog queries can be easily achieved such as the following example that reports all metrics available on a per host basis:
    +
    +                                        <br />
    +                                        <code>| mcatalog values(_dims) as dimensions where `nmon_metrics_index` metric_name=os.unix.nmon.* host=* by metric_name | stats values(dimensions) as dimensions, values(metric_name) as metric_name</code>
    +
    +                                        <h2 style="color: lightslategrey;">mstats queries:</h2>
    +
    +                                        mstats queries retrieve the metrics values eventually filtered out and reported per dimensions, the following example reports the system space CPU usage percentage:
    +
    +                                        <br />
    +                                        <code>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT host=* by host span=1m</code>
    +
    +                                        <br />
    +
    +                                        <div style="text-align: center;" class="cat_title">
    +
    +                                            <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(_dims)%20as%20dimensions%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.*%20host%3D*%20by%20host" class="tryitbtnxl">mcatalog query example »
    +                                            </a>
    +
    +                                            <a target="_blank" href="UI_data_dictionary?form.show_OStype_tk=true&amp;form.osfilter=AIX" class="tryitbtnxl">mcatalog data dictionary »
    +                                            </a>
    +
    +                                            <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats query example »
    +                                            </a>
    +
    +                                        </div>
    +
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div class="modal-footer">
    +                                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                                </div>
    +
    +                            </div>
    +                        </div>
    +                    </div>
    +
    +            </html>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Analyse and troubleshoot:</title>
    +
    +            <html>
    +
    +                    <div class="mainbutton_container_nomargin">
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_Summary">  SUMMARY OVERVIEW  </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_WOF"> WALL OF PERFORMANCE </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_Dark"> DARK MONITORING </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_ANALYSER_AIX">NMON ANALYSER</a>
    +                        </div>
    +
    +                    </div>
    +
    +            </html>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Compare, predict and forecast:</title>
    +
    +            <html>
    +
    +                    <div class="mainbutton_container_nomargin">
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_compare"> COMPARATIVE ANALYSIS </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_predict"> PREDICTIVE ANALYSIS </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_baseline_AIX">BASELINE FORECASTING</a>
    +                        </div>
    +
    +                    </div>
    +
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +
    +    <row>
    +        <panel>
    +            <title>Application information:</title>
    +            <html>
    +
    +                <div class="imgminiheader custom-modal">
    +                    <h4>
    +                        <i>
    +                            Data Categories:  <a data-modal-name="exploreall_modal">Explore All</a> /
    +                            Event Types: <a data-modal-name="performance_modal">nmon:events</a> (Nmon events data),
    +                            <a data-modal-name="config_modal">nmon:config</a> (Configuration data),
    +                            <a data-modal-name="collect_modal">nmon:collect</a> (Nmon raw data generation),
    +                            <a data-modal-name="processing_modal" target="_blank">nmon:processing</a> (Nmon raw data processing)
    +                            &#160;-&#160;&#160;&#160;<a href="https://www.octamis.com/services/metricator" target="_blank">About this application</a>
    +                        </i>
    +                    </h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="exploreall_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Events data navigation</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:events" class="tryitbtnxxl">eventtype=nmon:events »
    +                                        </a>
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:config" class="tryitbtnxxl">eventtype=nmon:config »
    +                                        </a>
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:collect" class="tryitbtnxxl">eventtype=nmon:collect »
    +                                        </a>
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:processing" class="tryitbtnxxl">eventtype=nmon:processing »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Information:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>eventtype=nmon:events:</b> contains Nmon data stored as events (opposed to the metric store)</li>
    +                                            <br />
    +                                            <li><b>eventtype=nmon:config:</b> contains the multi-line nmon configuration data</li>
    +                                            <br />
    +                                            <li><b>eventtype=nmon:collect:</b> contains the application internal events related to the Nmon data collection activity</li>
    +                                            <br />
    +                                            <li><b>eventtype=nmon:processing:</b> contains the application internal events related to the Nmon data processing and parsing activity</li>
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="performance_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:events eventtype contains all nmon data ingested as events.
    +                                    <br />
    +                                    In the nmon:events data, the "key" is the <b>type</b> field.
    +                                    <br />
    +                                    This field contains the monitor identifier that matches a category of metrics or events, such as "type=UPTIME". (uptime and load averages)
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:events" class="tryitbtnxxl">eventtype=nmon:events »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="config_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:config eventtype contains all the data related to the configuration of your systems.
    +                                    <br />
    +                                    These are the AAA and BBB* sections of nmon raw data, generated during the nmon binary startup.
    +                                    <br />
    +                                    The events are long multi-lines events stored per host, in default configuration these data will be extracted almost every 2 hours as the data will not change unless
    +                                    a new nmon process gets launched.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:config" class="tryitbtnxxl">eventtype=nmon:config »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div>
    +                                    The nmon:config data is associated with the generation of the nmon_inventory lookup and the metricator-nmon-config data model.
    +                                    <br />
    +                                    The nmon_inventory lookup table is being generated by a scheduled report (which runs by default every hour) that extracts main configuration items (number of CPUs, volume of physical memory...)
    +                                    from the nmon:configuration data over the metricator-nmon-config data model.
    +                                    <br />
    +                                    Once the nmon_inventory data has been generated, it is ready to be used and explored within various interfaces.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="UI_Nmon_CONFIG" class="tryitbtnxxl">CONFIG interface (raw config viewer) »
    +                                        </a>
    +
    +                                        <a target="_blank" href="UI_Nmon_CONFIG_simple_inventory_AIX" class="tryitbtnxxl">INVENTORY interface (config reporting) »
    +                                        </a>
    +
    +                                        <a target="_blank" href="pivot?model=%2FservicesNS%2Fnobody%2Fnmon%2Fdatamodel%2Fmodel%2Fmetricator-nmon-config" class="tryitbtnxxl">metricator-nmon-config datamodel »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="collect_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:collect eventtype contains all the data related to the nmon processes generation on your systems.
    +                                    <br />
    +                                    These are the ouput of the input script "metricator_helper.sh" thats gets automatically launched by Splunk when deploying the Nmon App.
    +                                    <br />
    +                                    By default, the metricator_helper.sh script gets started every minute, its main job is to verify the status of the current nmon process, and start a new one if conditions requires it.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:collect" class="tryitbtnxxl">eventtype=nmon:collect »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div>
    +                                    Many nmon starting options can be controlled through the "nmon.conf" configuration file during the deployment of the App, get more information on the online Wiki:
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="https://www.octamis.com/metricator-docs/binaries.html#scripts-and-binaries" class="tryitbtnxxl">Online help: metricator_helper.sh »
    +                                        </a>
    +
    +                                        <a target="_blank" href="https://www.octamis.com/metricator-docs/metrics_collection.html" class="tryitbtnxxl">Online help: manage nmon collection »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="processing_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:processing eventtype contains all the data related to the nmon processing steps that converts nmon data into usable data for Splunk.
    +                                    <br />
    +                                    These are the ouput of nmonparser Python and Perl parsers provided within the App.
    +                                    <br />
    +                                    Every time an existing raw nmon file is updated, or a new one gets created, Splunk will call parsers scripts and generate appropriated data.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:processing" class="tryitbtnxxl">eventtype=nmon:processing »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div>
    +                                    Many nmon starting options can be controlled through the "nmon.conf" configuration file during the deployment of the App, get more information on the online Wiki:
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="http://ta-nmon.readthedocs.io/en/latest/nmon_config.html" class="tryitbtnxxl">Online help: brief description »
    +                                        </a>
    +
    +                                        <a target="_blank" href="http://ta-nmon.readthedocs.io/en/latest/data_processing.html" class="tryitbtnxxl">Online help: parsers documentation »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +
    +            <!-- large scale: this search has a very minimal (almost null) cost even at large scale
    +            refresh every 60 seconds
    +            -->
    +
    +            <single>
    +                <search ref="Dates of first and last event within indexes"></search>
    +                <option name="underLabel">DATE OF FIRST AND LAST PERF EVENT (dd/mm/YY HH:MM)</option>
    +                <option name="drilldown">all</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `indexes_datestats` | eval summary='First Event' . " - " . 'Last Event'</link>
    +                </drilldown>
    +            </single>
    +
    +            <!-- large scale: this search has been slightly optimized, even at large scale (more than 1K servers), we expect a run time of 2 sec max
    +            too short refresh have low interest, refresh every 10 minutes
    +            -->
    +
    +            <single>
    +                <search ref="Hosts with data within last 7 days">
    +                    <refresh>600s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +                <option name="rangeValues">[18]</option>
    +                <option name="refresh.display">progressbar</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="underLabel">IN THE LAST 7 DAYS</option>
    +                <option name="unit">Host(s) with activity</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=%7C%20tstats%20dc(host)%20as%20dcount%20where%20%60nmon_index%60%20sourcetype%3Dnmon_data%20by%20_time%20span%3D1d&amp;earliest=-7d%40h&amp;latest=now&amp;display.general.type=visualizations&amp;display.page.search.tab=visualizations&amp;display.visualizations.type=singlevalue</link>
    +                </drilldown>
    +            </single>
    +
    +            <!-- large scale: this search has been slightly optimized (specially using an accelerated report), even at large scale (more than 1K servers), we expect a run time of 2 sec max
    +            refresh approx. every 2 minutes
    +            -->
    +
    +            <single>
    +                <search base="base_search_volume_indexed">
    +                    <query>addinfo
    +| eval time=strftime(_time, "%H%M"), lasttime=strftime(info_search_time, "%H%M")
    +| where time&lt;=lasttime
    +| timechart span=1d sum(volume) as volume
    +| where volume&gt;0</query>
    +                </search>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +                <option name="rangeValues">[18]</option>
    +                <option name="refresh.display">progressbar</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="underLabel">TODAY / EVOLUTION VS YESTERDAY</option>
    +                <option name="unit">MB Indexed</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +            </single>
    +
    +            <!-- large scale: we don't expect any cost with this search
    +            refresh approx. every 2 minutes
    +            -->
    +
    +            <single>
    +                <search ref="Number of notable events in Data Processing or Data Collect since last 24 Hours">
    +                    <refresh>140s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="underLabel">PROCESSING/COLLECT LAST 24 HOURS</option>
    +                <option name="field">value</option>
    +                <option name="drilldown">all</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?q=(eventtype=nmon:processing OR eventtype=nmon:collect error) OR (index=_internal sourcetype=splunkd ERROR ExecProcessor nmon) NOT ("There is no python in" OR "python: not found") earliest="-24h" latest="now"</link>
    +                </drilldown>
    +            </single>
    +
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_meta_metrics" data-alt-label="HIDE META METRICS" data-token-value="true"> META METRICS</button>
    +                </div>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    # The report used as the base search generates the detailed vision of nmon data indexed within the app
    +    # This report is using report acceleration for performances purposes
    +    # However, we need to exclude relative time to report the indexed situation relatively to the current time, which is not compatible with report acceleration
    +    # which is why we first creates the detailed vision, and then post-process the results with the relevant filtering
    +
    +    <search id="base_search_volume_indexed" ref="Volume of data indexed within last 7 days">
    +        <refresh>130s</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Meta metrics -->
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <title>META METRICS:</title>
    +
    +            <html>
    +                <div style="font-style: italic;">
    +                    <p>
    +                        <b>Meta metrics</b> are volume calculations based on the application metrics design and naming convention.
    +                        <br />
    +                        This provides accurate and easy insights to analyse the volume of data related to each category of metric, Nmon metric section or even specific servers.
    +                        <br />
    +                        You can manage metrics to be generated within the <b>nmon.conf</b> file, globally for your Technical Addon deployment with a local/nmon.conf, or on per server basis in /etc/nmon.conf
    +                    </p>
    +                </div>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="meta_volume_by_metric_category" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by metric_name span=1d
    +| rex field=metric_name "os\.unix\.nmon\.(?&lt;metric_category&gt;[^\.]*)\."
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, metric_category
    +| stats avg(size_MB) as size_MB by metric_category
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_metric_section" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by metric_name span=1d
    +| rex field=metric_name "os\.unix\.nmon\.[^\.]*.(?&lt;metric_section&gt;[^\.]*)"
    +| stats sum(count) as count by _time, metric_section
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, metric_section
    +| stats avg(size_MB) as size_MB by metric_section
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_host" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by host span=1d
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, host
    +| stats avg(size_MB) as size_MB by host
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_ostype" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by OStype span=1d
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, OStype
    +| stats avg(size_MB) as size_MB by OStype
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <title>metric_category daily volumes</title>
    +        </panel>
    +        <panel>
    +            <title>metric_section daily volumes</title>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_metric_category">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_metric_section">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_metric_category">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_metric_section">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <title>hosts daily volumes</title>
    +        </panel>
    +        <panel>
    +            <title>Operating systems daily volumes</title>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_host">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_ostype">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_host">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_ostype">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Monitor:</title>
    +            <html>
    +
    +                <div class="customleft custom-modal">
    +
    +                    <h4><i>
    +                        Enter <a href="../../alerts/metricator-for-nmon">Splunk Triggered Alerts for Nmon App</a> -
    +                        Enter <a href="UI_Alert_Center">Nmon ALERT CENTER dashboard</a> -
    +                        Enter <a data-modal-name="Help_Alerting">Alerting threshold management interfaces</a> -
    +                        Or click to drilldown on active alerts
    +                    </i></h4>
    +
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_Alerting" tabindex="-1" role="dialog" aria-labelledby="Help_Alerting_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_Alerting_Label">ALERTING MANAGEMENT: Choice menu</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: left;">
    +                                    <h1>Management of alerting thresholds:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button_pastelred_lowpadding glow" target="_blank" href="Manage_alerting_threshold">  THRESHOLD FOR CPU &amp; MEMORY  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button_pastelred_lowpadding glow" target="_blank" href="Manage_alerting_threshold_filesystem">  THRESHOLD FOR FILE-SYSTEM  </a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +                                    <p>
    +                                        <i>Threshold management interfaces allow configuring on a per server basis the altering thresholds for CPU, physical and virtual memory usage and file-systems utilization</i>
    +                                        <br />
    +                                    </p>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +                                    <h1>Management of alerting exclusions:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button_pastelred_lowpadding glow" target="_blank" href="Manage_file_systems_global_exclusion">  FILE-SYSTEMS GLOBAL EXCLUSION  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button_pastelred_lowpadding glow" target="_blank" href="Manage_file_systems_exclusion">  FILE-SYSTEMS SERVER EXCLUSION  </a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +                                    <p>
    +                                        <i>Use exclusion interfaces to manage exceptions for alerting, such as ignoring automatically specific mount point patterns for file-systems</i>
    +                                        <br />
    +                                    </p>
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +
    +            <!-- large scale: All searches are being refreshed approx every 2-3 minutes, with 10 sec of
    +             difference beetween each of the searches
    +            -->
    +
    +            <single>
    +                <search>
    +                    <query>| `alerting_cpu_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>150s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">cpu percentage saturation</option>
    +                <option name="unit">cpu active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_cpu_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_realmemory_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>160s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">physical memory percentage saturation</option>
    +                <option name="unit">real memory active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_realmemory_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_virtualmemory_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>170s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">virtual memory saturation</option>
    +                <option name="unit">virtual memory active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_virtualmemory_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_filesystem_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>180s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">file-systems under usage saturation</option>
    +                <option name="unit">file systems active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_filesystem_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>All interfaces:</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +
    +        <!-- ############################################ CPU CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" target="_blank">CPU Usage Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CPU_ALL" class="tryitbtn">CPU_ALL »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CPU_ALL">
    +                        <span title="CPU Utilization statistics in Percentage (%) &#013;
    +&#013;
    +• Represents the percentage of CPU system load for all available cores &#013;
    +&#013;
    +• Statistics can be returned in global usage or main category: Sys,User,Wait,Idle">
    +                            Percentage of CPU Utilization
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_LOAD_AVG" class="tryitbtn">SYS LOAD AVERAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_LOAD_AVG">
    +                        <span title="UPTIME load average statistics &#013;
    +&#013;
    +• system load averages for the past 1, 5, and 15 minutes &#013;
    +&#013;
    +• statistics retrieved from external uptime collection">
    +                            uptime system load averages
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CPUnn" class="tryitbtn">CPUnn »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CPUnn">
    +                        <span title="CPU Utilization per logical core statistics in Percentage (%) &#013;
    +&#013;
    +• Represents the percentage of CPU system load by logical core (lower level of CPU usage details) &#013;
    +&#013;
    +• Statistics can be returned in global usage or main category: Sys,User,Wait,Idle">
    +                            Percentage of CPU Utilization per logical core
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title custom-modal">
    +
    +                    <a data-modal-name="LPAR_modal" class="tryitbtn">LPAR »
    +                    </a>
    +
    +                    <a data-modal-name="LPAR_modal">
    +                        <span title="IBM Power partitions statistics &#013;
    +&#013;
    +• A Micro Power Partition (AIX or PowerLinux) returns various CPU utilization statistics in virtual CPUs units &#013;
    +&#013;
    +• Additionnaly, the Partition is able to return statistics about the Pool that hosts the partition">
    +                            Virtual Partition and Pools CPU Utilization
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="LPAR_modal" tabindex="-1" role="dialog" aria-labelledby="LPAR_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="LPAR_Label">Integrated Navigation:</h4>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/manufactors/IBM_logo_72px.png" alt="IBM"/>
    +                                    <h1>Power Partitions and Pools statistics</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <p>
    +                                        The LPAR monitor contains various CPU related metrics about Partitions and Pools utilization.
    +                                        <br />
    +                                        These metrics are available on AIX and PowerLinux partitions. (PowerLinux must run at least nmon 16e versions)
    +                                        <br />
    +                                        To be able to retrieve Pools related statistics, the partition must be authorized to do so in the HMC configuration for the Pseries.
    +                                    </p>
    +
    +                                </div>
    +
    +                                <br />
    +
    +                                <div style="text-align: left;">
    +                                    <h1>For AIX systems:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container_nomargin" style="text-align: left;">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_LPAR_AIX">  PARTITIONS STATISTICS  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_LPAR_AIX_poolconso">POOLS STATISTICS</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <br />
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_POOLS" class="tryitbtn">POOLS »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_POOLS">
    +                        <span title="Virtual CPU Utilization of PSeries Pools (same as part of LPAR with some additional monitors) &#013;
    +&#013;
    +• For IBM P5 generation and less, a Micro Partition that has App access will return the load of the PSeries &#013;
    +&#013;
    +• For IBM P6 generation and more, a Micro Partition that has App access will return the load of it's Pool, and the load of the PSeries if it is part of the DefaultPool">
    +                            PSeries Pools statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_WLM_AIX?form.monitor=os.unix.nmon.processes.wlmcpu" class="tryitbtn">WLM CPU »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_WLM_AIX?form.monitor=os.unix.nmon.processes.wlmcpu">
    +                        <span title="CPU Utilization statistics in Percentage (%) for Workload Manager &#013;">
    +                            Workload Manager CPU %
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ KERNEL CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="Process"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=KERNEL%20STATISTICS&amp;form.itemfilter=PROCESSES%20STATISTICS&amp;form.itemfilter=PAGING%20STATISTICS&amp;form.itemfilter=FIBER%20CHANNEL%20STATISTICS&amp;form.itemfilter=BLOCK%20STATISTICS" target="_blank">Process, Kernel, I/O Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_TOP_AIX" class="tryitbtn">TOP »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_TOP_AIX">
    +                        <span title="Statistics of Main Processes System Resources Usage &#013;
    +&#013;
    +• Get the CPU core utilization of main processes aggregated by Command invocations &#013;
    +&#013;
    +• Others Statistics available: Real/Virtual memory usage, minor and major faults and more &#013;
    +&#013;
    +• With UARG information, filter PIDs from Command to get accurate measures of complex processes
    +&#013;">
    +                            Main Processes System Resources Usage
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_UARG_AIX" class="tryitbtn">UARG »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_UARG_AIX">
    +                        <span title="Search for PIDs, Commands and Full Arguments of Processes &#013;
    +&#013;
    +• With UARG, get detailed information about Commands registered: PID, Full arguments and more &#013;
    +&#013;
    +• These information can also be very useful within TOP interfaces for accurate analysis">
    +                            Search for PIDs, Commands and Arguments
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_FILE" class="tryitbtn">FILE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_FILE">
    +                        <span title="Various Kernel File statistics &#013;
    +&#013;
    +• Read / Write System calls and other statistics">
    +                            Kernel File Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_IOADAPT" class="tryitbtn">IOADAPT »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_IOADAPT">
    +                        <span title="I/O Adapters Statistics &#013;
    +&#013;
    +• Data Rate (Kbytes/sec) and Total I/O Operations (tps) per Adapter Interfaces">
    +                            I/O Adapters Read/Write Operations
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_FC" class="tryitbtn">FC »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_FC">
    +                        <span title="Fiber Chanel Interfaces Statistics &#013;
    +&#013;
    +• Data Rate (Kbytes/sec) and Total I/O Operations (tps) per Fiber Channel Interfaces">
    +                            Fiber Channel Read/Write Operations
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_PROC" class="tryitbtn">PROC »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_PROC">
    +                        <span title="Kernel Internal Statistics &#013;
    +&#013;
    +• RunQueue, Swap-In, pswitch, syscall, fork, exec and more">
    +                            Kernel Internal Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_PAGE_AIX" class="tryitbtn">PAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_PAGE_AIX">
    +                        <span title="Paging Statistics &#013;
    +&#013;
    +• Pages In / Pages Out (pgsin / pgsout) &#013;
    + &#013;
    +• Fs In / Fs Out (sum of pgin/pgsin and pgout/pgsout per interval) &#013;
    + &#013;
    +• Scan Free Ratio (Pages scans by reclaims per interval) &#013;
    + &#013;
    +And more">
    +                            Paging Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_WLM_AIX?form.monitor=WLMBIO" class="tryitbtn">WLM BIO »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_WLM_AIX?form.monitor=os.unix.nmon.processes.wlmbio">
    +                        <span title="Block I/O statistics in Percentage (%) for Workload Manager &#013;">
    +                            Workload Manager Block I/O %
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ MEMORY CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/memory.png" alt="Memory"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=MEMORY%20STATISTICS" target="_blank">Memory Statistics</a></h2>
    +
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_MEMNEW_AIX" class="tryitbtn">MEMNEW »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_MEMNEW_AIX">
    +                        <span title="Memory Allocation Statistics&#013;
    +&#013;
    +• Analyse Memory allocation by main categories: FSCache, Process, System, Free &#013;
    +&#013;
    +• Global Memory rate utilization">
    +                            Percentage of Memory Allocation
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_MEM_AIX" class="tryitbtn">MEM »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_MEM_AIX">
    +                        <span title="Real and Virtual Memory Statistics &#013;
    +&#013;
    +• Memory Usage in Data Volume (MB) or Percentage &#013;
    +&#013;
    +• Specific System Stats (for Linux: Buffers / Cached / Active / Inactive...)">
    +                            Real and Virtual Memory Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_MEMUSE_AIX" class="tryitbtn">MEMUSE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_MEMUSE_AIX">
    +                        <span title="Various Memory Statistics &#013;
    +&#013;
    +• Cache Hit Ratio, System Buffer Accesses...">
    +                            Various Memory Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_WLM_AIX?form.monitor=os.unix.nmon.processes.wlmmem" class="tryitbtn">WLM MEM »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_WLM_AIX?form.monitor=os.unix.nmon.processes.wlmmem">
    +                        <span title="Memory Utilization statistics in Percentage (%) for Workload Manager &#013;">
    +                            Workload Manager MEM %
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ DISKS AND FS CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/drive.png" alt="Drive"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=DISKS%20STATISTICS&amp;form.itemfilter=FILESYSTEMS%20STATISTICS" target="_blank">Disks and Filesystems Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbsize" class="tryitbtn">DISKBSIZE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbsize">
    +                        <span title="Transfer Statistics per Disk &#013;
    +&#013;
    +• Average data size per block device transfer per disk (KBytes per transfer)">
    +                            Average Data Transfer Size
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbusy" class="tryitbtn">DISKBUSY »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbusy">
    +                        <span title="Percentage of Time Busy Disk &#013;
    +&#013;
    +• Analyse the Percentage of Time a disk was busy">
    +                            The Percentage of time a disk was Busy
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskread" class="tryitbtn">DISKREAD »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskread">
    +                        <span title="Disks Read Data rate &#013;
    +&#013;
    +• Analyse Disk Read operation Data rate in Kbytes/sec">
    +                            Disk Read Data Rate
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwrite" class="tryitbtn">DISKWRITE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwrite">
    +                        <span title="Disks Write Data rate &#013;
    +&#013;
    +• Analyse Disk Write operation Data rate in Kbytes/sec">
    +                            Disk Write Data Rate
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskxfer" class="tryitbtn">DISKXFER »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskxfer">
    +                        <span title="Disks I/O per second &#013;
    +&#013;
    +• Numbers of Input / Output operations per second (formerly IOPS) by disk">
    +                            Disk I/O Operations per second (IOPS)
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_STORAGE" class="tryitbtn">STORAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_STORAGE">
    +                        <span title="File Systems usage statistics &#013;
    +&#013;
    +• Usage statistics of file systems: volume, volume used and free, percentages...">
    +                            File systems utilisation statictics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +    </row>
    +
    +    <!-- ###################################################################################################### -->
    +
    +    <!-- ############################################ NET CATEGORY ############################################ -->
    +
    +    <row>
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/network.png" alt="Network"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=NETWORK*" target="_blank">Network Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.net" class="tryitbtn">NET »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.net">
    +                        <span title="Network Traffic per interface &#013;
    +&#013;
    +• Analyse Traffic Data per interface in Kbps / Mbps / Gbps and per host">
    +                            Traffic Data Rate per Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.netpacket" class="tryitbtn">NETPACKET »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.netpacket">
    +                        <span title="Network Packets per interface &#013;
    +&#013;
    +• Analyse the Number of Read and Write Network packets per interface and per host">
    +                            Read/Write packets per Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.neterror" class="tryitbtn">NETERROR »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.neterror">
    +                        <span title="Network Packets in Error per interface &#013;
    +&#013;
    +• Analyse the Number of Network packets that in error per interface and per host">
    +                            Error packets per Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NFS" class="tryitbtn">NFS »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NFS">
    +                        <span title="Network File System (NFS) Server and Client Statistics &#013;
    +&#013;
    +• Analyse various NFS Client and Server Statistics, eligible for NFS version 2/3/4">
    +                            Network FileSystem Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_SEA" class="tryitbtn">SEA »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_SEA">
    +                        <span title="Ethernet (Shared and Physical) Adapters Traffic Analysis &#013;
    +&#013;
    +• Analyse Traffic Data for Shared and Physical Ethernet Adapters in Kbps / Mbps / Gbps and per host
    +&#013;
    +• Analyse network packets for Shared and Physical Ethernet Adapters">
    +                            Shared Ethernet Adapters Traffic
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ PREDICT AND COMPARE ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/predict.png" alt="Prediction"/>
    +                    <h2>Data Prediction</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Nmon_baseline_AIX" class="tryitbtn-alt">BASELINE »
    +                    </a>
    +
    +                    <a target="_blank" href="Nmon_baseline_AIX" data-target="#Nmon_Baseline_modal">
    +                        <span title="Nmon Baseline Analysis &#013;
    +&#013;
    +• With the baseline Nmon KV Store, use this interface to analyse historical data and detect key system metrics derivations &#013;
    +&#013;
    +• Key system metrics (CPU usage, Real and Virtual Memory, IOPS disk statistics) charted over the baseline &#013;
    +&#013;
    +• Optionally chart current statistics over the future baseline and get realtime situation of system resources utilization">
    +                            System Key Metrics over Baseline
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Nmon_predict" class="tryitbtn-alt">PREDICTIVE »
    +                    </a>
    +
    +                    <a target="_blank" href="Nmon_predict">
    +                        <span title="CPU Predictive Analysis Interface &#013;
    +&#013;
    +• Using the predict Splunk command, this interface will help trying to estimate future load of your systems &#013;
    +&#013;
    +• Choose between available algorithms: Local Level (LL), Seasonal Local Level (LLP), Local Level Trend (LLT) and LLP5 (combine LLT and LLP)&#013;">
    +                            Predictive interface, forecast future using predict
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/compare.png" alt="Compare"/>
    +                    <h2>Data Comparison</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Nmon_compare" class="tryitbtn-alt">COMPARE »
    +                    </a>
    +
    +                    <a target="_blank" href="Nmon_compare">
    +                        <span title="Nmon Comparison Interface &#013;
    +&#013;
    +• Compare System Resources usage between 2 periods, a reference Period and arrival Period &#013;
    +&#013;
    +• Choose between Main Monitors: CPU usage (CPU_ALL / LPAR), Memory, I/O, Network &#013;
    +&#013;
    +• Evaluate the trend with Evolution Rate and graphical decorations to help instantly discover the comparison result">
    +                            Nmon Comparison Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ DASHBOARDS ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/dashboard.png" alt="Dashboard"/>
    +                    <h2>Dashboards</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_BubbleChart_top_hosts?&amp;form.osfilter=AIX" class="tryitbtn-alt">TOP HOSTS DASH »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_BubbleChart_top_hosts?&amp;form.osfilter=AIX">
    +                        <span title="BubbleChart: TOP hosts CPU Usage &#013;
    +&#013;
    +• Evaluate the TOP 100 hosts CPU load represented in Bubble Charts to instantly discover hosts responsible of the global load average &#013;
    +&#013;
    +• Evaluate the TOP 20 hosts CPU load represented in d3chart bar chart &#013;
    +&#013;
    +• Evaluate the full Statistics table of hosts CPU load with main hosts information">
    +                            BubbleChart: TOP hosts CPU Usage
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_bulletcharts" class="tryitbtn-alt">BULLET DASH »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_bulletcharts">
    +                        <span title="Bullet charts Dashboard: Analysis of main system metrics in bullet charts &#013;
    +&#013;
    +• TOP hosts by CPU usage / TOP hosts by physical and virtual memory usage &#013;
    +&#013;
    +• TOP Commands (processes) consumming CPU and Memory in your deployment &#013;
    +&#013;
    +• Advanced drilldown facilities for insight analysis">
    +                            Bullet Chart: TOP Servers / TOP Processes
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?&amp;form.osfilter=AIX" class="tryitbtn-alt">TOP PROCESSES DASH »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?&amp;form.osfilter=AIX">
    +                        <span title="Dashboard: Processes CPU and Memory Usage &#013;
    +&#013;
    +• Evaluate Processes CPU and Memory usage in d3chart BubbleChart to instantly represent major Command invocations &#013;
    +&#013;
    +• Represent this CPU / Memory usage in a d3chart chart over time &#013;
    +&#013;">
    +                            Processes CPU and Memory Usage
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_heatmap_daily_usage" class="tryitbtn-alt">CALENDAR DAILY CPU USAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_heatmap_daily_usage">
    +                        <span title="Dashboard: CALENDAR DAILY CPU USAGE &#013;
    +&#013;
    +• Evaluate daily CPU usage of multiple servers within the heatmap calendar visualization &#013;
    +&#013;
    +• Zoom within the TOP consumers by chart drilldown &#013;
    +&#013;">
    +                            Daily CPU usage calendar with drilldown
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- ###################################################################################################### -->
    +
    +                <!-- ############################################ CONFIG ############################################ -->
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/server_info.png" alt="ServerInfo"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=CONFIGURATION%20DATA" target="_blank">Hosts Configuration</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG" class="tryitbtn-alt">CONFIG »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG">
    +                        <span title="Hosts Configuration Show Interface &#013;
    +&#013;
    +• Explore the raw configuration of hosts &#013;
    +&#013;
    +• The full raw host configuration is part of AAA and BBB sections of raw Nmon files">
    +                            CONFIG: Hosts Configuration Show Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG_simple_inventory_AIX" class="tryitbtn-alt">INVENTORY »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG_simple_inventory_AIX">
    +                        <span title="Nmon Configuration Inventory &#013;
    +&#013;
    +• Explore the Nmon inventory of known hosts from your system to get valuable information &#013;
    +&#013;
    +• Main configuration Items depends on Operating System: type of OS, OS version, CPU / Mem configuration and more">
    +                            Nmon Configuration Inventory
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ PROCESSING ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h2>Application Information and costs</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_Internal_Stats" class="tryitbtn-alt">TCO ANALYSIS »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_Internal_Stats">
    +                        <span title="Application Internal Statistics &#013;
    +&#013;
    +• Estimate the average cost of licence per server &#013;
    +&#013;
    +• Monitor the global licence cost associated with the Nmon Performance application &#013;
    +&#013;
    +• Monitor run time metrics of scheduled searches  &#013;
    +&#013;
    +• Immediately view storage details of the Nmon index
    +">
    +                            Total Cost of Ownership Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/dictionary.png" alt="Dictionary"/>
    +                    <h2>Data Dictionary</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_data_dictionary" class="tryitbtn-alt">
    +                        <span title="Data Dictionary &#013;
    +&#013;
    +• Discover and Explore available data within the Nmon Splunk Application &#013;
    +&#013;
    +• Filter relevant Data for AIX, Linux and Solaris systems &#013;
    +&#013;
    +• Access to full metric definition: brieve and full description, relevant unity, formula...">
    +
    +                            Explore The Data Dictionary »
    +
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +    </row>
    +</dashboard>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Home_LINUX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Home_LINUX.xml
    new file mode 100644
    index 0000000..63a9f71
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Home_LINUX.xml
    @@ -0,0 +1,1913 @@
    +<dashboard script="autodiscover.js,panel_resize.js,active_button.js,modal.js" stylesheet="Home.css,ui_simple.css,hover.css,hide_timeindicator.css" hideEdit="true" isVisible="false" version="1.1" theme="dark">
    +    <label>Home Linux</label>
    +    <description></description>
    +
    +    <!-- Take the tour ! -->
    +	<row >
    +		<panel>
    +			<html>
    +				<div class = "splunk-view" data-require = "app/metricator-for-nmon/components/scc_takethetour/scc_takethetour"
    +					data-options = '{
    +						"user_slides":"scc-takethetour-slides",
    +						"width":"60",
    +						"title":"Metricator for Nmon: Take the tour !",
    +						"close_btn_label":"Close",
    +						"no_more_label":"Do not show this again",
    +						"cookie_name_suffix":"metricator-for-nmon-v1.0",
    +						"hide_container":false,
    +						"show_credits":true
    +					}'>
    +				</div>
    +				<ul id="scc-takethetour-slides" class="hide">
    +
    +					<li>
    +
    +                        <h1>WELCOME IN THE METRICATOR APPLICATION FOR SPLUNK ENTERPRISE</h1>
    +
    +                        <h2>The super fast, rich and definitive monitoring and performance application suite for Unix and Linux.</h2>
    +
    +                        <div style="text-align: left;">
    +                            <a href="http://www.octamis.com" target="_blank">
    +                                <img src="../../static/app/metricator-for-nmon/Octamis/Octamis_Logo_v3_no_bg.png" alt="Octamis"/>
    +                            </a>
    +                        </div>
    +
    +                        <b>Contact us at: </b><a target="_top" href="mailto:sales@octamis.com?subject=Nmon%20Performance%20for%20Splunk">sales@octamis.com</a>
    +                        <br />
    +                        <b>Share your testimonial: </b><a target="_top" href="mailto:nmon@octamis.com?subject=Nmon%20Performance%20for%20Splunk">nmon@octamis.com</a>
    +                        <br />
    +                        <b>We are looking for talent, <a target="_blank" href="https://www.octamis.com/careers/">find a job opportunity at Octamis</a></b>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/main.png" alt="main.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +
    +                        <h1>Metrics on steroids with Splunk 7 metric store</h1>
    +
    +                        <h2>Native metrics implementation</h2>
    +
    +                        <p>
    +                            The Metricator application fully implements Splunk time series metrics ingested within the metric store indexes.
    +                            <br />
    +                            We make good usage of it, and bring you one of the most performer user experience on Splunk Enterprise.
    +                            <br />
    +                            Access easily any metric available, use high performance mstats and mcatalog commands and retrieve results in seconds.
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/metrics_showcase.png" alt="metrics_showcase.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +
    +                        <h1>The most advanced dynamic dashboards and user interfaces for the highest quality of user experience</h1>
    +
    +                        <h2>We've got you covered. Find replies to your questions and get back in control with your systems</h2>
    +
    +                        <p>
    +                            Use our advanced dashboards to easily perform the best performance analysis.
    +                            <br />
    +                            More than simple dashboards, we provide rich, powerful and well designed user interfaces.
    +                            <br />
    +                            Dashboards and user interfaces are easily accessible from the application home page, we have a dashboard for all use cases.
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/advanced_dashboards.png" alt="advanced_dashboards.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +						<h1>Certified Technical Addon, low footprint and highly configurable</h1>
    +
    +                        <h2>Our Technical Addons are heavily tested, qualified and certified against numbers of architectures and Operating Systems, this includes:</h2>
    +
    +                        <p>
    +                            - IBM AIX 7.1 / 7.2<br />
    +                            - PowerLinux Linux (RHEL/Ubuntu/SLES...)<br />
    +                            - X86 (RHEL/Ubuntu/SLES...)<br />
    +                            - Oracle Solaris 11 on X86 and SPARC<br />
    +                        </p>
    +
    +                        The Technical Addons are as well compatible with ARM platforms, IBM zLinux!
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/OS_logos.png" alt="OS_logos.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +						<h1>Builtin costs of ownership analytic and metrics volume optimizations</h1>
    +
    +                        <h2>Get the insight vision of every cost related to your deployment</h2>
    +
    +                        <p>
    +                            - The DCO dashboard provides you builtin analytic features against application costs, daily average volume and metric metadatas, and even more<br />
    +                            - The Add-on dashboard provides automatic reporting your servers deployment, which versions are deployed on which servers<br />
    +                            - Don't pay for a zero ! The Technical Addons have been slighty optimized to remove any useless data from the metrics generation, you only pay for what is useful<br />
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/tco.png" alt="tco.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +						<h1>Threshold management, frameID mapping and thresholds templating</h1>
    +
    +                        <h2>The alerting features implements a multi-layer thresholds system based on:</h2>
    +
    +                        <p>
    +                            - The frameID that allows logically grouping server assets<br />
    +                            - FrameID mapping is achieved either at the raw level with different options (static definition, pre-ation scripts) or at search time with the KVstore management interface for frameID mapping<br />
    +                            - Alerting thresholds values can be defined using macros default, on a per frameID template basis or on a per server basis using the KVstore collection management interfaces<br />
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/thresholds.png" alt="thresholds.png"/>
    +                        </div>
    +
    +					</li>
    +
    +                </ul>
    +			</html>
    +		</panel>
    +	</row>
    +
    +    <row>
    +        <panel>
    +
    +            <single>
    +                <search id="HostsCount">
    +                    <query>| inputlookup nmon_inventory | search OStype="Linux" | stats count</query>
    +                </search>
    +                <option name="underLabel">KNOWN IN NMON INVENTORY</option>
    +                <option name="field">count</option>
    +                <option name="drilldown">all</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0xd93f3c","0x006d9c"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="unit">found LINUX host(s)</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux"
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </single>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Metrics exploration:</title>
    +
    +            <html>
    +
    +                    <div class="mainbutton_container_nomargin">
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_mexplorer">  M-EXPLORER  </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin custom-modal">
    +                            <a class="button2_lowpadding glow" data-modal-name="appinfo_modal">M-STRUCTURE</a>
    +                        </div>
    +
    +                    </div>
    +
    +                    <!-- Modal -->
    +                    <div class="modal custom-modal-60 fade" id="appinfo_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                        <div class="modal-dialog" role="document">
    +                            <div class="modal-content">
    +                                <div class="modal-header">
    +                                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                    <div style="text-align: left;">
    +                                        <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                    </div>
    +                                </div>
    +                                <div class="modal-body">
    +
    +                                    <div style="text-align: left;">
    +                                        <h1>
    +                                            METRICS STORAGE AND NAMING CONVENTION:
    +                                        </h1>
    +                                    </div>
    +
    +                                    <div>
    +                                        <br />
    +                                        By default, all metrics are indexed in the metric index called <b>os-unix-nmon-metrics</b>
    +                                        <br />
    +                                        Dashboards and reports globally refer to a macro named <b>nmon_metrics_index</b> that can be customized up to your needs and matches by default any index starting by <b>os-unix-nmon-metrics*</b>
    +
    +                                        <h2 style="color: lightslategrey;">Metrics scheme:</h2>
    +
    +                                        The metric generation process applies a common scheme easy to exploit, mostly: <b>os.unix.nmon.&lt;metric_category&gt;.&lt;nmon_section&gt;.&lt;metric&gt;.&lt;sub_metric&gt;</b>
    +
    +                                        <h2 style="color: lightslategrey;">Metrics dimensions:</h2>
    +
    +                                        Optional dimensions are available depending on metrics, such as the network interface names, and always start by <b>dimension_</b>, example: <b>dimension_device</b>
    +                                        <br />
    +                                        Dimensions can be retrieved automatically by the mcatalog command using the special field <b>"_dims"</b> field: <b>values(_dims) as dimensions</b>
    +
    +                                        <h2 style="color: lightslategrey;">Special dimensions:</h2>
    +
    +                                        The Technical addons creates some special dimensions to be used in servers filtering queries:
    +                                        <br />
    +                                        <lu>
    +                                            <li><b>OStype:</b> type of Operating System for the server</li>
    +                                            <li><b>serialnum:</b> serial number registered for the server (linked to the frameID)</li>
    +                                        </lu>
    +
    +                                        <h2 style="color: lightslategrey;">mcatalog queries:</h2>
    +
    +                                        mcatalog queries can be easily achieved such as the following example that reports all metrics available on a per host basis:
    +
    +                                        <br />
    +                                        <code>| mcatalog values(_dims) as dimensions where `nmon_metrics_index` metric_name=os.unix.nmon.* host=* by metric_name | stats values(dimensions) as dimensions, values(metric_name) as metric_name</code>
    +
    +                                        <h2 style="color: lightslategrey;">mstats queries:</h2>
    +
    +                                        mstats queries retrieve the metrics values eventually filtered out and reported per dimensions, the following example reports the system space CPU usage percentage:
    +
    +                                        <br />
    +                                        <code>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT host=* by host span=1m</code>
    +
    +                                        <br />
    +
    +                                        <div style="text-align: center;" class="cat_title">
    +
    +                                            <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(_dims)%20as%20dimensions%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.*%20host%3D*%20by%20host" class="tryitbtnxl">mcatalog query example »
    +                                            </a>
    +
    +                                            <a target="_blank" href="UI_data_dictionary?form.show_OStype_tk=true&amp;form.osfilter=Linux" class="tryitbtnxl">mcatalog data dictionary »
    +                                            </a>
    +
    +                                            <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats query example »
    +                                            </a>
    +
    +                                        </div>
    +
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div class="modal-footer">
    +                                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                                </div>
    +
    +                            </div>
    +                        </div>
    +                    </div>
    +
    +            </html>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Analyse and troubleshoot:</title>
    +
    +            <html>
    +
    +                    <div class="mainbutton_container_nomargin">
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_Summary">  SUMMARY OVERVIEW  </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_WOF"> WALL OF PERFORMANCE </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_Dark"> DARK MONITORING </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_ANALYSER_LINUX">NMON ANALYSER</a>
    +                        </div>
    +
    +                    </div>
    +
    +            </html>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Compare, predict and forecast:</title>
    +
    +            <html>
    +
    +                    <div class="mainbutton_container_nomargin">
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_compare"> COMPARATIVE ANALYSIS </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_predict"> PREDICTIVE ANALYSIS </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_baseline?form.osfilter=Linux">BASELINE FORECASTING</a>
    +                        </div>
    +
    +                    </div>
    +
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +
    +    <row>
    +        <panel>
    +            <title>Application information:</title>
    +            <html>
    +
    +                <div class="imgminiheader custom-modal">
    +                    <h4>
    +                        <i>
    +                            Data Categories:  <a data-modal-name="exploreall_modal">Explore All</a> /
    +                            Event Types: <a data-modal-name="performance_modal">nmon:events</a> (Nmon events data),
    +                            <a data-modal-name="config_modal">nmon:config</a> (Configuration data),
    +                            <a data-modal-name="collect_modal">nmon:collect</a> (Nmon raw data generation),
    +                            <a data-modal-name="processing_modal" target="_blank">nmon:processing</a> (Nmon raw data processing)
    +                            &#160;-&#160;&#160;&#160;<a href="https://www.octamis.com/services/metricator" target="_blank">About this application</a>
    +                        </i>
    +                    </h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="exploreall_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Events data navigation</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:events" class="tryitbtnxxl">eventtype=nmon:events »
    +                                        </a>
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:config" class="tryitbtnxxl">eventtype=nmon:config »
    +                                        </a>
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:collect" class="tryitbtnxxl">eventtype=nmon:collect »
    +                                        </a>
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:processing" class="tryitbtnxxl">eventtype=nmon:processing »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Information:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>eventtype=nmon:events:</b> contains Nmon data stored as events (opposed to the metric store)</li>
    +                                            <br />
    +                                            <li><b>eventtype=nmon:config:</b> contains the multi-line nmon configuration data</li>
    +                                            <br />
    +                                            <li><b>eventtype=nmon:collect:</b> contains the application internal events related to the Nmon data collection activity</li>
    +                                            <br />
    +                                            <li><b>eventtype=nmon:processing:</b> contains the application internal events related to the Nmon data processing and parsing activity</li>
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="performance_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:events eventtype contains all nmon data ingested as events.
    +                                    <br />
    +                                    In the nmon:events data, the "key" is the <b>type</b> field.
    +                                    <br />
    +                                    This field contains the monitor identifier that matches a category of metrics or events, such as "type=UPTIME". (uptime and load averages)
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:events" class="tryitbtnxxl">eventtype=nmon:events »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="config_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:config eventtype contains all the data related to the configuration of your systems.
    +                                    <br />
    +                                    These are the AAA and BBB* sections of nmon raw data, generated during the nmon binary startup.
    +                                    <br />
    +                                    The events are long multi-lines events stored per host, in default configuration these data will be extracted almost every 2 hours as the data will not change unless
    +                                    a new nmon process gets launched.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:config" class="tryitbtnxxl">eventtype=nmon:config »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div>
    +                                    The nmon:config data is associated with the generation of the nmon_inventory lookup and the metricator-nmon-config data model.
    +                                    <br />
    +                                    The nmon_inventory lookup table is being generated by a scheduled report (which runs by default every hour) that extracts main configuration items (number of CPUs, volume of physical memory...)
    +                                    from the nmon:configuration data over the metricator-nmon-config data model.
    +                                    <br />
    +                                    Once the nmon_inventory data has been generated, it is ready to be used and explored within various interfaces.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="UI_Nmon_CONFIG" class="tryitbtnxxl">CONFIG interface (raw config viewer) »
    +                                        </a>
    +
    +                                        <a target="_blank" href="UI_Nmon_CONFIG_simple_inventory_LINUX" class="tryitbtnxxl">INVENTORY interface (config reporting) »
    +                                        </a>
    +
    +                                        <a target="_blank" href="pivot?model=%2FservicesNS%2Fnobody%2Fnmon%2Fdatamodel%2Fmodel%2Fmetricator-nmon-config" class="tryitbtnxxl">metricator-nmon-config datamodel »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="collect_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:collect eventtype contains all the data related to the nmon processes generation on your systems.
    +                                    <br />
    +                                    These are the ouput of the input script "metricator_helper.sh" thats gets automatically launched by Splunk when deploying the Nmon App.
    +                                    <br />
    +                                    By default, the metricator_helper.sh script gets started every minute, its main job is to verify the status of the current nmon process, and start a new one if conditions requires it.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:collect" class="tryitbtnxxl">eventtype=nmon:collect »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div>
    +                                    Many nmon starting options can be controlled through the "nmon.conf" configuration file during the deployment of the App, get more information on the online Wiki:
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="https://www.octamis.com/metricator-docs/binaries.html#scripts-and-binaries" class="tryitbtnxxl">Online help: metricator_helper.sh »
    +                                        </a>
    +
    +                                        <a target="_blank" href="https://www.octamis.com/metricator-docs/metrics_collection.html" class="tryitbtnxxl">Online help: manage nmon collection »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="processing_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:processing eventtype contains all the data related to the nmon processing steps that converts nmon data into usable data for Splunk.
    +                                    <br />
    +                                    These are the ouput of nmonparser Python and Perl parsers provided within the App.
    +                                    <br />
    +                                    Every time an existing raw nmon file is updated, or a new one gets created, Splunk will call parsers scripts and generate appropriated data.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:processing" class="tryitbtnxxl">eventtype=nmon:processing »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div>
    +                                    Many nmon starting options can be controlled through the "nmon.conf" configuration file during the deployment of the App, get more information on the online Wiki:
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="http://ta-nmon.readthedocs.io/en/latest/nmon_config.html" class="tryitbtnxxl">Online help: brief description »
    +                                        </a>
    +
    +                                        <a target="_blank" href="http://ta-nmon.readthedocs.io/en/latest/data_processing.html" class="tryitbtnxxl">Online help: parsers documentation »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +
    +            <!-- large scale: this search has a very minimal (almost null) cost even at large scale
    +            refresh every 60 seconds
    +            -->
    +
    +            <single>
    +                <search ref="Dates of first and last event within indexes"></search>
    +                <option name="underLabel">DATE OF FIRST AND LAST PERF EVENT (dd/mm/YY HH:MM)</option>
    +                <option name="drilldown">all</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `indexes_datestats` | eval summary='First Event' . " - " . 'Last Event'</link>
    +                </drilldown>
    +            </single>
    +
    +            <!-- large scale: this search has been slightly optimized, even at large scale (more than 1K servers), we expect a run time of 2 sec max
    +            too short refresh have low interest, refresh every 10 minutes
    +            -->
    +
    +            <single>
    +                <search ref="Hosts with data within last 7 days">
    +                    <refresh>600s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +                <option name="rangeValues">[18]</option>
    +                <option name="refresh.display">progressbar</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="underLabel">IN THE LAST 7 DAYS</option>
    +                <option name="unit">Host(s) with activity</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=%7C%20tstats%20dc(host)%20as%20dcount%20where%20%60nmon_index%60%20sourcetype%3Dnmon_data%20by%20_time%20span%3D1d&amp;earliest=-7d%40h&amp;latest=now&amp;display.general.type=visualizations&amp;display.page.search.tab=visualizations&amp;display.visualizations.type=singlevalue</link>
    +                </drilldown>
    +            </single>
    +
    +            <!-- large scale: this search has been slightly optimized (specially using an accelerated report), even at large scale (more than 1K servers), we expect a run time of 2 sec max
    +            refresh approx. every 2 minutes
    +            -->
    +
    +            <single>
    +                <search base="base_search_volume_indexed">
    +                    <query>addinfo
    +| eval time=strftime(_time, "%H%M"), lasttime=strftime(info_search_time, "%H%M")
    +| where time&lt;=lasttime
    +| timechart span=1d sum(volume) as volume
    +| where volume&gt;0</query>
    +                </search>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +                <option name="rangeValues">[18]</option>
    +                <option name="refresh.display">progressbar</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="underLabel">TODAY / EVOLUTION VS YESTERDAY</option>
    +                <option name="unit">MB Indexed</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +            </single>
    +
    +            <!-- large scale: we don't expect any cost with this search
    +            refresh approx. every 2 minutes
    +            -->
    +
    +            <single>
    +                <search ref="Number of notable events in Data Processing or Data Collect since last 24 Hours">
    +                    <refresh>140s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="underLabel">PROCESSING/COLLECT LAST 24 HOURS</option>
    +                <option name="field">value</option>
    +                <option name="drilldown">all</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?q=(eventtype=nmon:processing OR eventtype=nmon:collect error) OR (index=_internal sourcetype=splunkd ERROR ExecProcessor nmon) NOT ("There is no python in" OR "python: not found") earliest="-24h" latest="now"</link>
    +                </drilldown>
    +            </single>
    +
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_meta_metrics" data-alt-label="HIDE META METRICS" data-token-value="true"> META METRICS</button>
    +                </div>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    # The report used as the base search generates the detailed vision of nmon data indexed within the app
    +    # This report is using report acceleration for performances purposes
    +    # However, we need to exclude relative time to report the indexed situation relatively to the current time, which is not compatible with report acceleration
    +    # which is why we first creates the detailed vision, and then post-process the results with the relevant filtering
    +
    +    <search id="base_search_volume_indexed" ref="Volume of data indexed within last 7 days">
    +        <refresh>130s</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Meta metrics -->
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <title>META METRICS:</title>
    +
    +            <html>
    +                <div style="font-style: italic;">
    +                    <p>
    +                        <b>Meta metrics</b> are volume calculations based on the application metrics design and naming convention.
    +                        <br />
    +                        This provides accurate and easy insights to analyse the volume of data related to each category of metric, Nmon metric section or even specific servers.
    +                        <br />
    +                        You can manage metrics to be generated within the <b>nmon.conf</b> file, globally for your Technical Addon deployment with a local/nmon.conf, or on per server basis in /etc/nmon.conf
    +                    </p>
    +                </div>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="meta_volume_by_metric_category" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by metric_name span=1d
    +| rex field=metric_name "os\.unix\.nmon\.(?&lt;metric_category&gt;[^\.]*)\."
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, metric_category
    +| stats avg(size_MB) as size_MB by metric_category
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_metric_section" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by metric_name span=1d
    +| rex field=metric_name "os\.unix\.nmon\.[^\.]*.(?&lt;metric_section&gt;[^\.]*)"
    +| stats sum(count) as count by _time, metric_section
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, metric_section
    +| stats avg(size_MB) as size_MB by metric_section
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_host" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by host span=1d
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, host
    +| stats avg(size_MB) as size_MB by host
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_ostype" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by OStype span=1d
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, OStype
    +| stats avg(size_MB) as size_MB by OStype
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <title>metric_category daily volumes</title>
    +        </panel>
    +        <panel>
    +            <title>metric_section daily volumes</title>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_metric_category">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_metric_section">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_metric_category">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_metric_section">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <title>hosts daily volumes</title>
    +        </panel>
    +        <panel>
    +            <title>Operating systems daily volumes</title>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_host">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_ostype">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_host">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_ostype">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Monitor:</title>
    +            <html>
    +
    +                <div class="customleft custom-modal">
    +
    +                    <h4><i>
    +                        Enter <a href="../../alerts/metricator-for-nmon">Splunk Triggered Alerts for Nmon App</a> -
    +                        Enter <a href="UI_Alert_Center">Nmon ALERT CENTER dashboard</a> -
    +                        Enter <a data-modal-name="Help_Alerting">Alerting threshold management interfaces</a> -
    +                        Or click to drilldown on active alerts
    +                    </i></h4>
    +
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_Alerting" tabindex="-1" role="dialog" aria-labelledby="Help_Alerting_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_Alerting_Label">ALERTING MANAGEMENT: Choice menu</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: left;">
    +                                    <h1>Management of alerting thresholds:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button_pastelred_lowpadding glow" target="_blank" href="Manage_alerting_threshold">  THRESHOLD FOR CPU &amp; MEMORY  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button_pastelred_lowpadding glow" target="_blank" href="Manage_alerting_threshold_filesystem">  THRESHOLD FOR FILE-SYSTEM  </a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +                                    <p>
    +                                        <i>Threshold management interfaces allow configuring on a per server basis the altering thresholds for CPU, physical and virtual memory usage and file-systems utilization</i>
    +                                        <br />
    +                                    </p>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +                                    <h1>Management of alerting exclusions:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button_pastelred_lowpadding glow" target="_blank" href="Manage_file_systems_global_exclusion">  FILE-SYSTEMS GLOBAL EXCLUSION  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button_pastelred_lowpadding glow" target="_blank" href="Manage_file_systems_exclusion">  FILE-SYSTEMS SERVER EXCLUSION  </a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +                                    <p>
    +                                        <i>Use exclusion interfaces to manage exceptions for alerting, such as ignoring automatically specific mount point patterns for file-systems</i>
    +                                        <br />
    +                                    </p>
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +
    +            <!-- large scale: All searches are being refreshed approx every 2-3 minutes, with 10 sec of
    +             difference beetween each of the searches
    +            -->
    +
    +            <single>
    +                <search>
    +                    <query>| `alerting_cpu_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>150s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">cpu percentage saturation</option>
    +                <option name="unit">cpu active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_cpu_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_realmemory_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>160s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">physical Memory percentage saturation</option>
    +                <option name="unit">physical memory active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_realmemory_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_virtualmemory_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>170s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">virtual memory saturation</option>
    +                <option name="unit">virtual memory active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_virtualmemory_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_filesystem_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>180s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">file-systems under usage saturation</option>
    +                <option name="unit">file systems active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_filesystem_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>All interfaces:</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +
    +        <!-- ############################################ CPU CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" target="_blank">CPU Usage Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CPU_ALL" class="tryitbtn">CPU_ALL »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CPU_ALL">
    +                        <span title="CPU Utilization statistics in Percentage (%) &#013;
    +&#013;
    +• Represents the percentage of CPU system load for all available cores &#013;
    +&#013;
    +• Statistics can be returned in global usage or main category: Sys,User,Wait,Idle">
    +                            Percentage of CPU Utilization
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_LOAD_AVG" class="tryitbtn">SYS LOAD AVERAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_LOAD_AVG">
    +                        <span title="UPTIME load average statistics &#013;
    +&#013;
    +• system load averages for the past 1, 5, and 15 minutes &#013;
    +&#013;
    +• statistics retrieved from external uptime collection">
    +                            uptime system load averages
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CPUnn" class="tryitbtn">CPUnn »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CPUnn">
    +                        <span title="CPU Utilization per logical core statistics in Percentage (%) &#013;
    +&#013;
    +• Represents the percentage of CPU system load by logical core (lower level of CPU usage details) &#013;
    +&#013;
    +• Statistics can be returned in global usage or main category: Sys,User,Wait,Idle">
    +                            Percentage of CPU Utilization per logical core
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title custom-modal">
    +
    +                    <a data-modal-name="LPAR_modal" class="tryitbtn">LPAR »
    +                    </a>
    +
    +                    <a data-modal-name="LPAR_modal">
    +                        <span title="IBM Power partitions statistics &#013;
    +&#013;
    +• A Micro Power Partition (AIX or PowerLinux) returns various CPU utilization statistics in virtual CPUs units &#013;
    +&#013;
    +• Additionnaly, the Partition is able to return statistics about the Pool that hosts the partition">
    +                            PowerLinux: Virtual Partition and Pools CPU Utilization
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="LPAR_modal" tabindex="-1" role="dialog" aria-labelledby="LPAR_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="LPAR_Label">Integrated Navigation:</h4>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/manufactors/IBM_logo_72px.png" alt="IBM"/>
    +                                    <h1>Power Partitions and Pools statistics</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <p>
    +                                        The LPAR monitor contains various CPU related metrics about Partitions and Pools utilization.
    +                                        <br />
    +                                        These metrics are available on AIX and PowerLinux partitions. (PowerLinux must run at least nmon 16e versions)
    +                                        <br />
    +                                        To be able to retrieve Pools related statistics, the partition must be authorized to do so in the HMC configuration for the Pseries.
    +                                    </p>
    +
    +                                </div>
    +
    +                                <br />
    +
    +                                <div style="text-align: left;">
    +                                    <h1>For PowerLinux systems:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container_nomargin" style="text-align: left;">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_LPAR_LINUX">  PARTITIONS STATISTICS  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button2_lowpadding glow" target="_blank" href="UI_Nmon_LPAR_LINUX_poolconso">POOLS STATISTICS</a>
    +                                    </div>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ KERNEL CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="Process"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=KERNEL%20STATISTICS&amp;form.itemfilter=PROCESSES%20STATISTICS&amp;form.itemfilter=PAGING%20STATISTICS&amp;form.itemfilter=FIBER%20CHANNEL%20STATISTICS&amp;form.itemfilter=BLOCK%20STATISTICS" target="_blank">Process, Kernel, I/O Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_TOP_LINUX" class="tryitbtn">TOP »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_TOP_LINUX">
    +                        <span title="Statistics of Main Processes System Resources Usage &#013;
    +&#013;
    +• Get the CPU core utilization of main processes aggregated by Command invocations &#013;
    +&#013;
    +• Others Statistics available: Real/Virtual memory usage, minor and major faults and more &#013;
    +&#013;
    +• With UARG information, filter PIDs from Command to get accurate measures of complex processes
    +&#013;">
    +                            Main Processes System Resources Usage
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_UARG_LINUX" class="tryitbtn">UARG »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_UARG_LINUX">
    +                        <span title="Search for PIDs, Commands and Full Arguments of Processes &#013;
    +&#013;
    +• With UARG, get detailed information about Commands registered: PID, Full arguments and more &#013;
    +&#013;
    +• These information can also be very useful within TOP interfaces for accurate analysis">
    +                            Search for PIDs, Commands and Arguments
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_PROC" class="tryitbtn">PROC »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_PROC">
    +                        <span title="Kernel Internal Statistics &#013;
    +&#013;
    +• RunQueue, Swap-In, pswitch, syscall, fork, exec and more">
    +                            Kernel Internal Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ MEMORY CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/memory.png" alt="Memory"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=MEMORY%20STATISTICS" target="_blank">Memory Statistics</a></h2>
    +
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_MEM_LINUX" class="tryitbtn">MEM »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_MEM_LINUX">
    +                        <span title="Real and Virtual Memory Statistics &#013;
    +&#013;
    +• Memory Usage in Data Volume (MB) or Percentage &#013;
    +&#013;
    +• Specific System Stats (for Linux: Buffers / Cached / Active / Inactive...)">
    +                            Real and Virtual Memory Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_VM_LINUX" class="tryitbtn">VM »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_VM_LINUX">
    +                        <span title="Various Virtual Memory statistics &#013;
    +&#013;
    +• Pageins / Pageout &#013;
    +&#013;
    +• Swapins / Swapout &#013;
    +&#013;
    +• Minor and Major faults &#013;
    +&#013;
    +And more">
    +                            Kernel Virtual Memory Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ DISKS AND FS CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/drive.png" alt="Drive"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=DISKS%20STATISTICS&amp;form.itemfilter=FILESYSTEMS%20STATISTICS" target="_blank">Disks and Filesystems Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DG" class="tryitbtn">DG »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DG">
    +                        <span title="Disks extended statistics (DG*) &#013;
    +&#013;
    +• Disks aggregated statistics: I/O, read / write performance and latency...">
    +                            Linux: Disks extended statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbsize" class="tryitbtn">DISKBSIZE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbsize">
    +                        <span title="Transfer Statistics per Disk &#013;
    +&#013;
    +• Average data size per block device transfer per disk (KBytes per transfer)">
    +                            Average Data Transfer Size
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbusy" class="tryitbtn">DISKBUSY »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbusy">
    +                        <span title="Percentage of Time Busy Disk &#013;
    +&#013;
    +• Analyse the Percentage of Time a disk was busy">
    +                            The Percentage of time a disk was Busy
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskread" class="tryitbtn">DISKREAD »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskread">
    +                        <span title="Disks Read Data rate &#013;
    +&#013;
    +• Analyse Disk Read operation Data rate in Kbytes/sec">
    +                            Disk Read Data Rate
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwrite" class="tryitbtn">DISKWRITE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwrite">
    +                        <span title="Disks Write Data rate &#013;
    +&#013;
    +• Analyse Disk Write operation Data rate in Kbytes/sec">
    +                            Disk Write Data Rate
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskxfer" class="tryitbtn">DISKXFER »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskxfer">
    +                        <span title="Disks I/O per second &#013;
    +&#013;
    +• Numbers of Input / Output operations per second (formerly IOPS) by disk">
    +                            Disk I/O Operations per second (IOPS)
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_STORAGE" class="tryitbtn">STORAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_STORAGE">
    +                        <span title="File Systems usage statistics &#013;
    +&#013;
    +• Usage statistics of file systems: volume, volume used and free, percentages...">
    +                            File systems utilisation statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +    </row>
    +
    +    <!-- ###################################################################################################### -->
    +
    +    <!-- ############################################ NET CATEGORY ############################################ -->
    +
    +    <row>
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/network.png" alt="Network"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=NETWORK*" target="_blank">Network Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.net" class="tryitbtn">NET »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.net">
    +                        <span title="Network Traffic per interface &#013;
    +&#013;
    +• Analyse Traffic Data per interface in Kbps / Mbps / Gbps and per host">
    +                            Traffic Data Rate per Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.netpacket" class="tryitbtn">NETPACKET »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.netpacket">
    +                        <span title="Network Packets per interface &#013;
    +&#013;
    +• Analyse the Number of Read and Write Network packets per interface and per host">
    +                            Read/Write packets per Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NFS" class="tryitbtn">NFS »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NFS">
    +                        <span title="Network File System (NFS) Server and Client Statistics &#013;
    +&#013;
    +• Analyse various NFS Client and Server Statistics, eligible for NFS version 2/3/4">
    +                            Network FileSystem Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ PREDICT AND COMPARE ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/predict.png" alt="Prediction"/>
    +                    <h2>Data Prediction</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Nmon_baseline?form.osfilter=Linux" class="tryitbtn-alt">BASELINE »
    +                    </a>
    +
    +                    <a target="_blank" href="Nmon_baseline?form.osfilter=Linux">
    +                        <span title="Nmon Baseline Analysis &#013;
    +&#013;
    +• With the baseline Nmon KV Store, use this interface to analyse historical data and detect key system metrics derivations &#013;
    +&#013;
    +• Key system metrics (CPU usage, Real and Virtual Memory, IOPS disk statistics) charted over the baseline &#013;
    +&#013;
    +• Optionally chart current statistics over the future baseline and get realtime situation of system resources utilization">
    +                            System Key Metrics over Baseline
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Nmon_predict" class="tryitbtn-alt">PREDICTIVE »
    +                    </a>
    +
    +                    <a target="_blank" href="Nmon_predict">
    +                        <span title="CPU Predictive Analysis Interface &#013;
    +&#013;
    +• Using the predict Splunk command, this interface will help trying to estimate future load of your systems &#013;
    +&#013;
    +• Choose between available algorithms: Local Level (LL), Seasonal Local Level (LLP), Local Level Trend (LLT) and LLP5 (combine LLT and LLP)&#013;">
    +                            Predictive interface, forecast future using predict
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/compare.png" alt="Compare"/>
    +                    <h2>Data Comparison</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Nmon_compare" class="tryitbtn-alt">COMPARE »
    +                    </a>
    +
    +                    <a target="_blank" href="Nmon_compare">
    +                        <span title="Nmon Comparison Interface &#013;
    +&#013;
    +• Compare System Resources usage between 2 periods, a reference Period and arrival Period &#013;
    +&#013;
    +• Choose between Main Monitors: CPU usage (CPU_ALL / LPAR), Memory, I/O, Network &#013;
    +&#013;
    +• Evaluate the trend with Evolution Rate and graphical decorations to help instantly discover the comparison result">
    +                            Nmon Comparison Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ DASHBOARDS ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/dashboard.png" alt="Dashboard"/>
    +                    <h2>Dashboards</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_BubbleChart_top_hosts?&amp;form.osfilter=Linux" class="tryitbtn-alt">TOP HOSTS DASH »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_BubbleChart_top_hosts?&amp;form.osfilter=Linux">
    +                        <span title="BubbleChart: TOP hosts CPU Usage &#013;
    +&#013;
    +• Evaluate the TOP 100 hosts CPU load represented in Bubble Charts to instantly discover hosts responsible of the global load average &#013;
    +&#013;
    +• Evaluate the TOP 20 hosts CPU load represented in d3chart bar chart &#013;
    +&#013;
    +• Evaluate the full Statistics table of hosts CPU load with main hosts information">
    +                            BubbleChart: TOP hosts CPU Usage
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_bulletcharts" class="tryitbtn-alt">BULLET DASH »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_bulletcharts">
    +                        <span title="Bullet charts Dashboard: Analysis of main system metrics in bullet charts &#013;
    +&#013;
    +• TOP hosts by CPU usage / TOP hosts by physical and virtual memory usage &#013;
    +&#013;
    +• TOP Commands (processes) consumming CPU and Memory in your deployment &#013;
    +&#013;
    +• Advanced drilldown facilities for insight analysis">
    +                            Bullet Chart: TOP Servers / TOP Processes
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?&amp;form.osfilter=Linux" class="tryitbtn-alt">TOP PROCESSES DASH »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?&amp;form.osfilter=Linux">
    +                        <span title="Dashboard: Processes CPU and Memory Usage &#013;
    +&#013;
    +• Evaluate Processes CPU and Memory usage in d3chart BubbleChart to instantly represent major Command invocations &#013;
    +&#013;
    +• Represent this CPU / Memory usage in a d3chart chart over time &#013;
    +&#013;">
    +                            Processes CPU and Memory Usage
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_heatmap_daily_usage" class="tryitbtn-alt">CALENDAR DAILY CPU USAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_heatmap_daily_usage">
    +                        <span title="Dashboard: CALENDAR DAILY CPU USAGE &#013;
    +&#013;
    +• Evaluate daily CPU usage of multiple servers within the heatmap calendar visualization &#013;
    +&#013;
    +• Zoom within the TOP consumers by chart drilldown &#013;
    +&#013;">
    +                            CALENDAR DAILY CPU USAGE
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- ###################################################################################################### -->
    +
    +                <!-- ############################################ CONFIG ############################################ -->
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/server_info.png" alt="ServerInfo"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=CONFIGURATION%20DATA" target="_blank">Hosts Configuration</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG" class="tryitbtn-alt">CONFIG »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG">
    +                        <span title="Hosts Configuration Show Interface &#013;
    +&#013;
    +• Explore the raw configuration of hosts &#013;
    +&#013;
    +• The full raw host configuration is part of AAA and BBB sections of raw Nmon files">
    +                            CONFIG: Hosts Configuration Show Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG_simple_inventory_LINUX" class="tryitbtn-alt">INVENTORY »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG_simple_inventory_LINUX">
    +                        <span title="Nmon Configuration Inventory &#013;
    +&#013;
    +• Explore the Nmon inventory of known hosts from your system to get valuable information &#013;
    +&#013;
    +• Main configuration Items depends on Operating System: type of OS, OS version, CPU / Mem configuration and more">
    +                            Nmon Configuration Inventory
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ PROCESSING ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h2>Application Information and costs</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_Internal_Stats" class="tryitbtn-alt">TCO ANALYSIS »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_Internal_Stats">
    +                        <span title="Application Internal Statistics &#013;
    +&#013;
    +• Estimate the average cost of licence per server &#013;
    +&#013;
    +• Monitor the global licence cost associated with the Nmon Performance application &#013;
    +&#013;
    +• Monitor run time metrics of scheduled searches  &#013;
    +&#013;
    +• Immediately view storage details of the Nmon index
    +">
    +                            Total Cost of Ownership Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/dictionary.png" alt="Dictionary"/>
    +                    <h2>Data Dictionary</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_data_dictionary" class="tryitbtn-alt">
    +                        <span title="Data Dictionary &#013;
    +&#013;
    +• Discover and Explore available data within the Nmon Splunk Application &#013;
    +&#013;
    +• Filter relevant Data for AIX, Linux and Solaris systems &#013;
    +&#013;
    +• Access to full metric definition: brieve and full description, relevant unity, formula...">
    +
    +                            Explore The Data Dictionary »
    +
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +    </row>
    +</dashboard>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Home_SOLARIS.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Home_SOLARIS.xml
    new file mode 100644
    index 0000000..bbe0dda
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Home_SOLARIS.xml
    @@ -0,0 +1,1953 @@
    +<dashboard script="autodiscover.js,panel_resize.js,active_button.js,modal.js" stylesheet="Home.css,ui_simple.css,hover.css,hide_timeindicator.css" hideEdit="true" isVisible="false" version="1.1" theme="dark">
    +    <label>Home Solaris</label>
    +    <description></description>
    +
    +    <!-- Take the tour ! -->
    +	<row >
    +		<panel>
    +			<html>
    +				<div class = "splunk-view" data-require = "app/metricator-for-nmon/components/scc_takethetour/scc_takethetour"
    +					data-options = '{
    +						"user_slides":"scc-takethetour-slides",
    +						"width":"60",
    +						"title":"Metricator for Nmon: Take the tour !",
    +						"close_btn_label":"Close",
    +						"no_more_label":"Do not show this again",
    +						"cookie_name_suffix":"metricator-for-nmon-v1.0",
    +						"hide_container":false,
    +						"show_credits":true
    +					}'>
    +				</div>
    +				<ul id="scc-takethetour-slides" class="hide">
    +
    +					<li>
    +
    +                        <h1>WELCOME IN THE METRICATOR APPLICATION FOR SPLUNK ENTERPRISE</h1>
    +
    +                        <h2>The super fast, rich and definitive monitoring and performance application suite for Unix and Linux.</h2>
    +
    +                        <div style="text-align: left;">
    +                            <a href="http://www.octamis.com" target="_blank">
    +                                <img src="../../static/app/metricator-for-nmon/Octamis/Octamis_Logo_v3_no_bg.png" alt="Octamis"/>
    +                            </a>
    +                        </div>
    +
    +                        <b>Contact us at: </b><a target="_top" href="mailto:sales@octamis.com?subject=Nmon%20Performance%20for%20Splunk">sales@octamis.com</a>
    +                        <br />
    +                        <b>Share your testimonial: </b><a target="_top" href="mailto:nmon@octamis.com?subject=Nmon%20Performance%20for%20Splunk">nmon@octamis.com</a>
    +                        <br />
    +                        <b>We are looking for talent, <a target="_blank" href="https://www.octamis.com/careers/">find a job opportunity at Octamis</a></b>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/main.png" alt="main.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +
    +                        <h1>Metrics on steroids with Splunk 7 metric store</h1>
    +
    +                        <h2>Native metrics implementation</h2>
    +
    +                        <p>
    +                            The Metricator application fully implements Splunk time series metrics ingested within the metric store indexes.
    +                            <br />
    +                            We make good usage of it, and bring you one of the most performer user experience on Splunk Enterprise.
    +                            <br />
    +                            Access easily any metric available, use high performance mstats and mcatalog commands and retrieve results in seconds.
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/metrics_showcase.png" alt="metrics_showcase.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +
    +                        <h1>The most advanced dynamic dashboards and user interfaces for the highest quality of user experience</h1>
    +
    +                        <h2>We've got you covered. Find replies to your questions and get back in control with your systems</h2>
    +
    +                        <p>
    +                            Use our advanced dashboards to easily perform the best performance analysis.
    +                            <br />
    +                            More than simple dashboards, we provide rich, powerful and well designed user interfaces.
    +                            <br />
    +                            Dashboards and user interfaces are easily accessible from the application home page, we have a dashboard for all use cases.
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/advanced_dashboards.png" alt="advanced_dashboards.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +						<h1>Certified Technical Addon, low footprint and highly configurable</h1>
    +
    +                        <h2>Our Technical Addons are heavily tested, qualified and certified against numbers of architectures and Operating Systems, this includes:</h2>
    +
    +                        <p>
    +                            - IBM AIX 7.1 / 7.2<br />
    +                            - PowerLinux Linux (RHEL/Ubuntu/SLES...)<br />
    +                            - X86 (RHEL/Ubuntu/SLES...)<br />
    +                            - Oracle Solaris 11 on X86 and SPARC<br />
    +                        </p>
    +
    +                        The Technical Addons are as well compatible with ARM platforms, IBM zLinux!
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/OS_logos.png" alt="OS_logos.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +						<h1>Builtin costs of ownership analytic and metrics volume optimizations</h1>
    +
    +                        <h2>Get the insight vision of every cost related to your deployment</h2>
    +
    +                        <p>
    +                            - The DCO dashboard provides you builtin analytic features against application costs, daily average volume and metric metadatas, and even more<br />
    +                            - The Add-on dashboard provides automatic reporting your servers deployment, which versions are deployed on which servers<br />
    +                            - Don't pay for a zero ! The Technical Addons have been slighty optimized to remove any useless data from the metrics generation, you only pay for what is useful<br />
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/tco.png" alt="tco.png"/>
    +                        </div>
    +
    +					</li>
    +
    +					<li>
    +						<h1>Threshold management, frameID mapping and thresholds templating</h1>
    +
    +                        <h2>The alerting features implements a multi-layer thresholds system based on:</h2>
    +
    +                        <p>
    +                            - The frameID that allows logically grouping server assets<br />
    +                            - FrameID mapping is achieved either at the raw level with different options (static definition, pre-ation scripts) or at search time with the KVstore management interface for frameID mapping<br />
    +                            - Alerting thresholds values can be defined using macros default, on a per frameID template basis or on a per server basis using the KVstore collection management interfaces<br />
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/thresholds.png" alt="thresholds.png"/>
    +                        </div>
    +
    +					</li>
    +
    +                </ul>
    +			</html>
    +		</panel>
    +	</row>
    +
    +    <row>
    +        <panel>
    +
    +            <single>
    +                <search id="HostsCount">
    +                    <query>| inputlookup nmon_inventory | search OStype="Solaris" | stats count</query>
    +                </search>
    +                <option name="underLabel">KNOWN IN NMON INVENTORY</option>
    +                <option name="field">count</option>
    +                <option name="drilldown">all</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0xd93f3c","0x006d9c"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="unit">found SOLARIS host(s)</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype=Solaris
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </single>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Metrics exploration:</title>
    +
    +            <html>
    +
    +                    <div class="mainbutton_container_nomargin">
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_mexplorer">  M-EXPLORER  </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin custom-modal">
    +                            <a class="button2_lowpadding glow" data-modal-name="appinfo_modal">M-STRUCTURE</a>
    +                        </div>
    +
    +                    </div>
    +
    +                    <!-- Modal -->
    +                    <div class="modal custom-modal-60 fade" id="appinfo_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                        <div class="modal-dialog" role="document">
    +                            <div class="modal-content">
    +                                <div class="modal-header">
    +                                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                    <div style="text-align: left;">
    +                                        <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                    </div>
    +                                </div>
    +                                <div class="modal-body">
    +
    +                                    <div style="text-align: left;">
    +                                        <h1>
    +                                            METRICS STORAGE AND NAMING CONVENTION:
    +                                        </h1>
    +                                    </div>
    +
    +                                    <div>
    +                                        <br />
    +                                        By default, all metrics are indexed in the metric index called <b>os-unix-nmon-metrics</b>
    +                                        <br />
    +                                        Dashboards and reports globally refer to a macro named <b>nmon_metrics_index</b> that can be customized up to your needs and matches by default any index starting by <b>os-unix-nmon-metrics*</b>
    +
    +                                        <h2 style="color: lightslategrey;">Metrics scheme:</h2>
    +
    +                                        The metric generation process applies a common scheme easy to exploit, mostly: <b>os.unix.nmon.&lt;metric_category&gt;.&lt;nmon_section&gt;.&lt;metric&gt;.&lt;sub_metric&gt;</b>
    +
    +                                        <h2 style="color: lightslategrey;">Metrics dimensions:</h2>
    +
    +                                        Optional dimensions are available depending on metrics, such as the network interface names, and always start by <b>dimension_</b>, example: <b>dimension_device</b>
    +                                        <br />
    +                                        Dimensions can be retrieved automatically by the mcatalog command using the special field <b>"_dims"</b> field: <b>values(_dims) as dimensions</b>
    +
    +                                        <h2 style="color: lightslategrey;">Special dimensions:</h2>
    +
    +                                        The Technical addons creates some special dimensions to be used in servers filtering queries:
    +                                        <br />
    +                                        <lu>
    +                                            <li><b>OStype:</b> type of Operating System for the server</li>
    +                                            <li><b>serialnum:</b> serial number registered for the server (linked to the frameID)</li>
    +                                        </lu>
    +
    +                                        <h2 style="color: lightslategrey;">mcatalog queries:</h2>
    +
    +                                        mcatalog queries can be easily achieved such as the following example that reports all metrics available on a per host basis:
    +
    +                                        <br />
    +                                        <code>| mcatalog values(_dims) as dimensions where `nmon_metrics_index` metric_name=os.unix.nmon.* host=* by metric_name | stats values(dimensions) as dimensions, values(metric_name) as metric_name</code>
    +
    +                                        <h2 style="color: lightslategrey;">mstats queries:</h2>
    +
    +                                        mstats queries retrieve the metrics values eventually filtered out and reported per dimensions, the following example reports the system space CPU usage percentage:
    +
    +                                        <br />
    +                                        <code>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT host=* by host span=1m</code>
    +
    +                                        <br />
    +
    +                                        <div style="text-align: center;" class="cat_title">
    +
    +                                            <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(_dims)%20as%20dimensions%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.*%20host%3D*%20by%20host" class="tryitbtnxl">mcatalog query example »
    +                                            </a>
    +
    +                                            <a target="_blank" href="UI_data_dictionary?form.show_OStype_tk=true&amp;form.osfilter=Solaris" class="tryitbtnxl">mcatalog data dictionary »
    +                                            </a>
    +
    +                                            <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats query example »
    +                                            </a>
    +
    +                                        </div>
    +
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div class="modal-footer">
    +                                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                                </div>
    +
    +                            </div>
    +                        </div>
    +                    </div>
    +
    +            </html>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Analyse and troubleshoot:</title>
    +
    +            <html>
    +
    +                    <div class="mainbutton_container_nomargin">
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_Summary">  SUMMARY OVERVIEW  </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_WOF"> WALL OF PERFORMANCE </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_Dark"> DARK MONITORING </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_ANALYSER_SOLARIS">NMON ANALYSER</a>
    +                        </div>
    +
    +                    </div>
    +
    +            </html>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Compare, predict and forecast:</title>
    +
    +            <html>
    +
    +                    <div class="mainbutton_container_nomargin">
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_compare"> COMPARATIVE ANALYSIS </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_predict"> PREDICTIVE ANALYSIS </a>
    +                        </div>
    +
    +                        <div class="mainbutton_highmargin">
    +                            <a class="button2_lowpadding glow" href="Nmon_baseline?form.osfilter=Solaris">BASELINE FORECASTING</a>
    +                        </div>
    +
    +                    </div>
    +
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +
    +    <row>
    +        <panel>
    +            <title>Application information:</title>
    +            <html>
    +
    +                <div class="imgminiheader custom-modal">
    +                    <h4>
    +                        <i>
    +                            Data Categories:  <a data-modal-name="exploreall_modal">Explore All</a> /
    +                            Event Types: <a data-modal-name="performance_modal">nmon:events</a> (Nmon events data),
    +                            <a data-modal-name="config_modal">nmon:config</a> (Configuration data),
    +                            <a data-modal-name="collect_modal">nmon:collect</a> (Nmon raw data generation),
    +                            <a data-modal-name="processing_modal" target="_blank">nmon:processing</a> (Nmon raw data processing)
    +                            &#160;-&#160;&#160;&#160;<a href="https://www.octamis.com/services/metricator" target="_blank">About this application</a>
    +                        </i>
    +                    </h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="exploreall_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Events data navigation</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:events" class="tryitbtnxxl">eventtype=nmon:events »
    +                                        </a>
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:config" class="tryitbtnxxl">eventtype=nmon:config »
    +                                        </a>
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:collect" class="tryitbtnxxl">eventtype=nmon:collect »
    +                                        </a>
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:processing" class="tryitbtnxxl">eventtype=nmon:processing »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Information:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>eventtype=nmon:events:</b> contains Nmon data stored as events (opposed to the metric store)</li>
    +                                            <br />
    +                                            <li><b>eventtype=nmon:config:</b> contains the multi-line nmon configuration data</li>
    +                                            <br />
    +                                            <li><b>eventtype=nmon:collect:</b> contains the application internal events related to the Nmon data collection activity</li>
    +                                            <br />
    +                                            <li><b>eventtype=nmon:processing:</b> contains the application internal events related to the Nmon data processing and parsing activity</li>
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="performance_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:events eventtype contains all nmon data ingested as events.
    +                                    <br />
    +                                    In the nmon:events data, the "key" is the <b>type</b> field.
    +                                    <br />
    +                                    This field contains the monitor identifier that matches a category of metrics or events, such as "type=UPTIME". (uptime and load averages)
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:events" class="tryitbtnxxl">eventtype=nmon:events »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="config_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:config eventtype contains all the data related to the configuration of your systems.
    +                                    <br />
    +                                    These are the AAA and BBB* sections of nmon raw data, generated during the nmon binary startup.
    +                                    <br />
    +                                    The events are long multi-lines events stored per host, in default configuration these data will be extracted almost every 2 hours as the data will not change unless
    +                                    a new nmon process gets launched.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:config" class="tryitbtnxxl">eventtype=nmon:config »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div>
    +                                    The nmon:config data is associated with the generation of the nmon_inventory lookup and the metricator-nmon-config data model.
    +                                    <br />
    +                                    The nmon_inventory lookup table is being generated by a scheduled report (which runs by default every hour) that extracts main configuration items (number of CPUs, volume of physical memory...)
    +                                    from the nmon:configuration data over the metricator-nmon-config data model.
    +                                    <br />
    +                                    Once the nmon_inventory data has been generated, it is ready to be used and explored within various interfaces.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="UI_Nmon_CONFIG" class="tryitbtnxxl">CONFIG interface (raw config viewer) »
    +                                        </a>
    +
    +                                        <a target="_blank" href="UI_Nmon_CONFIG_simple_inventory_SOLARIS" class="tryitbtnxxl">INVENTORY interface (config reporting) »
    +                                        </a>
    +
    +                                        <a target="_blank" href="pivot?model=%2FservicesNS%2Fnobody%2Fnmon%2Fdatamodel%2Fmodel%2Fmetricator-nmon-config" class="tryitbtnxxl">metricator-nmon-config datamodel »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="collect_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:collect eventtype contains all the data related to the nmon processes generation on your systems.
    +                                    <br />
    +                                    These are the ouput of the input script "metricator_helper.sh" thats gets automatically launched by Splunk when deploying the Nmon App.
    +                                    <br />
    +                                    By default, the metricator_helper.sh script gets started every minute, its main job is to verify the status of the current nmon process, and start a new one if conditions requires it.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:collect" class="tryitbtnxxl">eventtype=nmon:collect »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div>
    +                                    Many nmon starting options can be controlled through the "nmon.conf" configuration file during the deployment of the App, get more information on the online Wiki:
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="https://www.octamis.com/metricator-docs/binaries.html#scripts-and-binaries" class="tryitbtnxxl">Online help: metricator_helper.sh »
    +                                        </a>
    +
    +                                        <a target="_blank" href="https://www.octamis.com/metricator-docs/metrics_collection.html" class="tryitbtnxxl">Online help: manage nmon collection »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="processing_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center; color: lightslategrey;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/appIconAlt_2x.png" alt="logo"/>
    +                                    <h1>Nmon data navigation</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The nmon:processing eventtype contains all the data related to the nmon processing steps that converts nmon data into usable data for Splunk.
    +                                    <br />
    +                                    These are the ouput of nmonparser Python and Perl parsers provided within the App.
    +                                    <br />
    +                                    Every time an existing raw nmon file is updated, or a new one gets created, Splunk will call parsers scripts and generate appropriated data.
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="search?q=search%20eventtype=nmon:processing" class="tryitbtnxxl">eventtype=nmon:processing »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                                <div>
    +                                    Many nmon starting options can be controlled through the "nmon.conf" configuration file during the deployment of the App, get more information on the online Wiki:
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <div class="bootstrap_title">
    +
    +                                        <a target="_blank" href="http://ta-nmon.readthedocs.io/en/latest/nmon_config.html" class="tryitbtnxxl">Online help: brief description »
    +                                        </a>
    +
    +                                        <a target="_blank" href="http://ta-nmon.readthedocs.io/en/latest/data_processing.html" class="tryitbtnxxl">Online help: parsers documentation »
    +                                        </a>
    +
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +
    +            <!-- large scale: this search has a very minimal (almost null) cost even at large scale
    +            refresh every 60 seconds
    +            -->
    +
    +            <single>
    +                <search ref="Dates of first and last event within indexes"></search>
    +                <option name="underLabel">DATE OF FIRST AND LAST PERF EVENT (dd/mm/YY HH:MM)</option>
    +                <option name="drilldown">all</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `indexes_datestats` | eval summary='First Event' . " - " . 'Last Event'</link>
    +                </drilldown>
    +            </single>
    +
    +            <!-- large scale: this search has been slightly optimized, even at large scale (more than 1K servers), we expect a run time of 2 sec max
    +            too short refresh have low interest, refresh every 10 minutes
    +            -->
    +
    +            <single>
    +                <search ref="Hosts with data within last 7 days">
    +                    <refresh>600s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +                <option name="rangeValues">[18]</option>
    +                <option name="refresh.display">progressbar</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="underLabel">IN THE LAST 7 DAYS</option>
    +                <option name="unit">Host(s) with activity</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=%7C%20tstats%20dc(host)%20as%20dcount%20where%20%60nmon_index%60%20sourcetype%3Dnmon_data%20by%20_time%20span%3D1d&amp;earliest=-7d%40h&amp;latest=now&amp;display.general.type=visualizations&amp;display.page.search.tab=visualizations&amp;display.visualizations.type=singlevalue</link>
    +                </drilldown>
    +            </single>
    +
    +            <!-- large scale: this search has been slightly optimized (specially using an accelerated report), even at large scale (more than 1K servers), we expect a run time of 2 sec max
    +            refresh approx. every 2 minutes
    +            -->
    +
    +            <single>
    +                <search base="base_search_volume_indexed">
    +                    <query>addinfo
    +| eval time=strftime(_time, "%H%M"), lasttime=strftime(info_search_time, "%H%M")
    +| where time&lt;=lasttime
    +| timechart span=1d sum(volume) as volume
    +| where volume&gt;0</query>
    +                </search>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +                <option name="rangeValues">[18]</option>
    +                <option name="refresh.display">progressbar</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="underLabel">TODAY / EVOLUTION VS YESTERDAY</option>
    +                <option name="unit">MB Indexed</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +            </single>
    +
    +            <!-- large scale: we don't expect any cost with this search
    +            refresh approx. every 2 minutes
    +            -->
    +
    +            <single>
    +                <search ref="Number of notable events in Data Processing or Data Collect since last 24 Hours">
    +                    <refresh>140s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="underLabel">PROCESSING/COLLECT LAST 24 HOURS</option>
    +                <option name="field">value</option>
    +                <option name="drilldown">all</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?q=(eventtype=nmon:processing OR eventtype=nmon:collect error) OR (index=_internal sourcetype=splunkd ERROR ExecProcessor nmon) NOT ("There is no python in" OR "python: not found") earliest="-24h" latest="now"</link>
    +                </drilldown>
    +            </single>
    +
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_meta_metrics" data-alt-label="HIDE META METRICS" data-token-value="true"> META METRICS</button>
    +                </div>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    # The report used as the base search generates the detailed vision of nmon data indexed within the app
    +    # This report is using report acceleration for performances purposes
    +    # However, we need to exclude relative time to report the indexed situation relatively to the current time, which is not compatible with report acceleration
    +    # which is why we first creates the detailed vision, and then post-process the results with the relevant filtering
    +
    +    <search id="base_search_volume_indexed" ref="Volume of data indexed within last 7 days">
    +        <refresh>130s</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Meta metrics -->
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <title>META METRICS:</title>
    +
    +            <html>
    +                <div style="font-style: italic;">
    +                    <p>
    +                        <b>Meta metrics</b> are volume calculations based on the application metrics design and naming convention.
    +                        <br />
    +                        This provides accurate and easy insights to analyse the volume of data related to each category of metric, Nmon metric section or even specific servers.
    +                        <br />
    +                        You can manage metrics to be generated within the <b>nmon.conf</b> file, globally for your Technical Addon deployment with a local/nmon.conf, or on per server basis in /etc/nmon.conf
    +                    </p>
    +                </div>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="meta_volume_by_metric_category" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by metric_name span=1d
    +| rex field=metric_name "os\.unix\.nmon\.(?&lt;metric_category&gt;[^\.]*)\."
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, metric_category
    +| stats avg(size_MB) as size_MB by metric_category
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_metric_section" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by metric_name span=1d
    +| rex field=metric_name "os\.unix\.nmon\.[^\.]*.(?&lt;metric_section&gt;[^\.]*)"
    +| stats sum(count) as count by _time, metric_section
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, metric_section
    +| stats avg(size_MB) as size_MB by metric_section
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_host" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by host span=1d
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, host
    +| stats avg(size_MB) as size_MB by host
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <search id="meta_volume_by_ostype" depends="$show_meta_metrics$">
    +        <query>| mstats count where `nmon_metrics_index` metric_name=os.unix.nmon.* by OStype span=1d
    +| eval estimated_size_bytes=(count*150)
    +| stats sum(estimated_size_bytes) as size_MB by _time, OStype
    +| stats avg(size_MB) as size_MB by OStype
    +| eval size_MB=round(size_MB/1024/1024, 2)</query>
    +        <earliest>-30d</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <title>metric_category daily volumes</title>
    +        </panel>
    +        <panel>
    +            <title>metric_section daily volumes</title>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_metric_category">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_metric_section">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_metric_category">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_metric_section">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <title>hosts daily volumes</title>
    +        </panel>
    +        <panel>
    +            <title>Operating systems daily volumes</title>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_host">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <search base="meta_volume_by_ostype">
    +                    <query></query>
    +                </search>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="height">350</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_meta_metrics$">
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_host">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <search base="meta_volume_by_ostype">
    +                    <query>sort 0 - size_MB | rename size_MB as "Avg daily volume (MB)"</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Monitor:</title>
    +            <html>
    +
    +                <div class="customleft custom-modal">
    +
    +                    <h4><i>
    +                        Enter <a href="../../alerts/metricator-for-nmon">Splunk Triggered Alerts for Nmon App</a> -
    +                        Enter <a href="UI_Alert_Center">Nmon ALERT CENTER dashboard</a> -
    +                        Enter <a data-modal-name="Help_Alerting">Alerting threshold management interfaces</a> -
    +                        Or click to drilldown on active alerts
    +                    </i></h4>
    +
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_Alerting" tabindex="-1" role="dialog" aria-labelledby="Help_Alerting_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_Alerting_Label">ALERTING MANAGEMENT: Choice menu</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: left;">
    +                                    <h1>Management of alerting thresholds:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button_pastelred_lowpadding glow" target="_blank" href="Manage_alerting_threshold">  THRESHOLD FOR CPU &amp; MEMORY  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button_pastelred_lowpadding glow" target="_blank" href="Manage_alerting_threshold_filesystem">  THRESHOLD FOR FILE-SYSTEM  </a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +                                    <p>
    +                                        <i>Threshold management interfaces allow configuring on a per server basis the altering thresholds for CPU, physical and virtual memory usage and file-systems utilization</i>
    +                                        <br />
    +                                    </p>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +                                    <h1>Management of alerting exclusions:</h1>
    +                                </div>
    +
    +                                <div class="mainbutton_container">
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button_pastelred_lowpadding glow" target="_blank" href="Manage_file_systems_global_exclusion">  FILE-SYSTEMS GLOBAL EXCLUSION  </a>
    +                                    </div>
    +
    +                                    <div class="mainbutton">
    +                                        <a class="button_pastelred_lowpadding glow" target="_blank" href="Manage_file_systems_exclusion">  FILE-SYSTEMS SERVER EXCLUSION  </a>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +                                    <p>
    +                                        <i>Use exclusion interfaces to manage exceptions for alerting, such as ignoring automatically specific mount point patterns for file-systems</i>
    +                                        <br />
    +                                    </p>
    +                                </div>
    +
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +
    +            <!-- large scale: All searches are being refreshed approx every 2-3 minutes, with 10 sec of
    +             difference beetween each of the searches
    +            -->
    +
    +            <single>
    +                <search>
    +                    <query>| `alerting_cpu_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>150s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">cpu percentage saturation</option>
    +                <option name="unit">cpu active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_cpu_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_realmemory_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>160s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">physical memory percentage saturation</option>
    +                <option name="unit">physical memory active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_realmemory_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_virtualmemory_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>170s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">virtual memory saturation</option>
    +                <option name="unit">virtual memory active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_virtualmemory_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_filesystem_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>180s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">file-systems under usage saturation</option>
    +                <option name="unit">file systems active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_filesystem_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>All interfaces:</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +
    +        <!-- ############################################ CPU CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" target="_blank">CPU Usage Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CPU_ALL" class="tryitbtn">CPU_ALL »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CPU_ALL">
    +                        <span title="CPU Utilization statistics in Percentage (%) &#013;
    +&#013;
    +• Represents the percentage of CPU system load for all available cores &#013;
    +&#013;
    +• Statistics can be returned in global usage or main category: Sys,User,Wait,Idle">
    +                            Percentage of CPU Utilization
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_LOAD_AVG" class="tryitbtn">SYS LOAD AVERAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_LOAD_AVG">
    +                        <span title="UPTIME load average statistics &#013;
    +&#013;
    +• system load averages for the past 1, 5, and 15 minutes &#013;
    +&#013;
    +• statistics retrieved from external uptime collection">
    +                            uptime system load averages
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CPUnn" class="tryitbtn">CPUnn »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CPUnn">
    +                        <span title="CPU Utilization per logical core statistics in Percentage (%) &#013;
    +&#013;
    +• Represents the percentage of CPU system load by logical core (lower level of CPU usage details) &#013;
    +&#013;
    +• Statistics can be returned in global usage or main category: Sys,User,Wait,Idle">
    +                            Percentage of CPU Utilization per logical core
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_WLM_SOLARIS?form.type_monitor=CPU" class="tryitbtn">WLM CPU »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_WLM_SOLARIS?form.type_monitor=CPU">
    +                        <span title="CPU Utilization statistics in Percentage (%) for Workload Manager &#013;">
    +                            Workload Manager CPU %
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ KERNEL CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="Process"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=KERNEL%20STATISTICS&amp;form.itemfilter=PROCESSES%20STATISTICS&amp;form.itemfilter=PAGING%20STATISTICS&amp;form.itemfilter=FIBER%20CHANNEL%20STATISTICS&amp;form.itemfilter=BLOCK%20STATISTICS" target="_blank">Process, Kernel, I/O Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_TOP_SOLARIS" class="tryitbtn">TOP »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_TOP_SOLARIS">
    +                        <span title="Statistics of Main Processes System Resources Usage &#013;
    +&#013;
    +• Get the CPU core utilization of main processes aggregated by Command invocations &#013;
    +&#013;
    +• Others Statistics available: Real/Virtual memory usage, minor and major faults and more &#013;
    +&#013;
    +• With UARG information, filter PIDs from Command to get accurate measures of complex processes
    +&#013;">
    +                            Main Processes System Resources Usage
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_UARG_SOLARIS" class="tryitbtn">UARG »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_UARG_SOLARIS">
    +                        <span title="Search for PIDs, Commands and Full Arguments of Processes &#013;
    +&#013;
    +• With UARG, get detailed information about Commands registered: PID, Full arguments and more &#013;
    +&#013;
    +• These information can also be very useful within TOP interfaces for accurate analysis">
    +                            Search for PIDs, Commands and Arguments
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_FILE" class="tryitbtn">FILE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_FILE">
    +                        <span title="Various Kernel File statistics &#013;
    +&#013;
    +• Read / Write System calls and other statistics">
    +                            Kernel File Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_PROC" class="tryitbtn">PROC »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_PROC">
    +                        <span title="Kernel Internal Statistics &#013;
    +&#013;
    +• RunQueue, Swap-In, pswitch, syscall, fork, exec and more">
    +                            Kernel Internal Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_PROCSOL_SOLARIS" class="tryitbtn">PROCSOL »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_PROCSOL_SOLARIS">
    +                        <span title="Solaris Processes Activity Statistics &#013;
    +&#013;
    +This interface will return the percentage of time processes have spent in, such as &#013;
    +&#013;
    +• % of Time in User / System / mode, % of Time processing system traps &#013;
    +&#013;
    +• % of Time waiting for CPU, and more">
    +                            Percentage of Time Processes have spent in
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_VM_SOLARIS" class="tryitbtn">VM »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_VM_SOLARIS">
    +                        <span title="Various Virtual Memory statistics &#013;
    +&#013;
    +• Pageins / Pageout &#013;
    +&#013;
    +• Swapins / Swapout &#013;
    +&#013;
    +• Minor and Major faults &#013;
    +&#013;
    +And more">
    +                            Kernel Virtual Memory Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ MEMORY CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/memory.png" alt="Memory"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=MEMORY%20STATISTICS" target="_blank">Memory Statistics</a></h2>
    +
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_MEM_SOLARIS" class="tryitbtn">MEM »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_MEM_SOLARIS">
    +                        <span title="Real and Virtual Memory Statistics &#013;
    +&#013;
    +• Memory Usage in Data Volume (MB) or Percentage &#013;
    +&#013;
    +• Specific System Stats (for Linux: Buffers / Cached / Active / Inactive...)">
    +                            Real and Virtual Memory Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_MEMUSE_SOLARIS" class="tryitbtn">MEMUSE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_MEMUSE_SOLARIS">
    +                        <span title="Various Memory Statistics &#013;
    +&#013;
    +• Cache Hit Ratio, System Buffer Accesses...">
    +                            Various Memory Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_WLM_SOLARIS?form.type_monitor=MEM" class="tryitbtn">WLM MEM »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_WLM_SOLARIS?form.type_monitor=MEM">
    +                        <span title="Memory Utilization statistics in Percentage (%) for Workload Manager &#013;">
    +                            Workload Manager MEM %
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ DISKS AND FS CATEGORY ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/drive.png" alt="Drive"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=DISKS%20STATISTICS&amp;form.itemfilter=FILESYSTEMS%20STATISTICS" target="_blank">Disks and Filesystems Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbsize" class="tryitbtn">DISKBSIZE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbsize">
    +                        <span title="Transfer Statistics per Disk &#013;
    +&#013;
    +• Average data size per block device transfer per disk (KBytes per transfer)">
    +                            Average Data Transfer Size
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbusy" class="tryitbtn">DISKBUSY »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskbusy">
    +                        <span title="Percentage of Time Busy Disk &#013;
    +&#013;
    +• Analyse the Percentage of Time a disk was busy">
    +                            The Percentage of time a disk was Busy
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskread" class="tryitbtn">DISKREAD »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskread">
    +                        <span title="Disks Read Data rate &#013;
    +&#013;
    +• Analyse Disk Read operation Data rate in Kbytes/sec">
    +                            Disk Read Data Rate
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwrite" class="tryitbtn">DISKWRITE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwrite">
    +                        <span title="Disks Write Data rate &#013;
    +&#013;
    +• Analyse Disk Write operation Data rate in Kbytes/sec">
    +                            Disk Write Data Rate
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskxfer" class="tryitbtn">DISKXFER »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskxfer">
    +                        <span title="Disks I/O per second &#013;
    +&#013;
    +• Numbers of Input / Output operations per second (formerly IOPS) by disk">
    +                            Disk I/O Operations per second (IOPS)
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.disksvctm&amp;form.osfilter=Solaris" class="tryitbtn">DISKSVCTM »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.disksvctm&amp;form.osfilter=Solaris">
    +                        <span title="(ms) Average service time by disk&#013;
    +&#013;
    +• Same as 'sar -d.avserv' &#013;
    +&#013;
    +• Same as 'iostat -xn.asvc_t'. For iostat, a disk is referred as a device' &#013;
    +
    +">
    +                            Solaris: Disk Average Service time
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwaittm&amp;form.osfilter=Solaris" class="tryitbtn">DISKWAITTM »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_DISK?form.metric_name=os.unix.nmon.storage.diskwaittm&amp;form.osfilter=Solaris">
    +                        <span title="(ms) Average wait time by disk&#013;
    +&#013;
    +• Same as 'sar -d.avwait' &#013;
    +&#013;
    +• Same as 'iostat -xn.wsvc_t'. For iostat, a disk is referred as a device' &#013;
    +
    +">
    +                            Solaris: Disk Average Wait time
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_STORAGE" class="tryitbtn">STORAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_STORAGE">
    +                        <span title="File Systems usage statistics &#013;
    +&#013;
    +• Usage statistics of file systems: volume, volume used and free, percentages...">
    +                            File systems utilisation statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +    </row>
    +
    +    <!-- ###################################################################################################### -->
    +
    +    <!-- ############################################ NET CATEGORY ############################################ -->
    +
    +    <row>
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/network.png" alt="Network"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=NETWORK*" target="_blank">Network Statistics</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.net" class="tryitbtn">NET »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.net">
    +                        <span title="Network Traffic per interface &#013;
    +&#013;
    +• Analyse Traffic Data per interface in Kbps / Mbps / Gbps and per host">
    +                            Traffic Data Rate per Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.netpacket" class="tryitbtn">NETPACKET »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.netpacket">
    +                        <span title="Network Packets per interface &#013;
    +&#013;
    +• Analyse the Number of Read and Write Network packets per interface and per host">
    +                            Read/Write packets per Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.neterror" class="tryitbtn">NETERROR »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_NET?form.metric_name=os.unix.nmon.network.neterror">
    +                        <span title="Network Packets in Error per interface &#013;
    +&#013;
    +• Analyse the Number of Network packets that in error per interface and per host">
    +                            Error packets per Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ PREDICT AND COMPARE ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/predict.png" alt="Prediction"/>
    +                    <h2>Data Prediction</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Nmon_baseline?form.osfilter=Solaris" class="tryitbtn-alt">BASELINE »
    +                    </a>
    +
    +                    <a target="_blank" href="Nmon_baseline?form.osfilter=Solaris">
    +                        <span title="Nmon Baseline Analysis &#013;
    +&#013;
    +• With the baseline Nmon KV Store, use this interface to analyse historical data and detect key system metrics derivations &#013;
    +&#013;
    +• Key system metrics (CPU usage, Real and Virtual Memory, IOPS disk statistics) charted over the baseline &#013;
    +&#013;
    +• Optionally chart current statistics over the future baseline and get realtime situation of system resources utilization">
    +                            System Key Metrics over Baseline
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Nmon_predict" class="tryitbtn-alt">PREDICTIVE »
    +                    </a>
    +
    +                    <a target="_blank" href="Nmon_predict">
    +                        <span title="CPU Predictive Analysis Interface &#013;
    +&#013;
    +• Using the predict Splunk command, this interface will help trying to estimate future load of your systems &#013;
    +&#013;
    +• Choose between available algorithms: Local Level (LL), Seasonal Local Level (LLP), Local Level Trend (LLT) and LLP5 (combine LLT and LLP)&#013;">
    +                            Predictive interface, forecast future using predict
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/compare.png" alt="Compare"/>
    +                    <h2>Data Comparison</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Nmon_compare" class="tryitbtn-alt">COMPARE »
    +                    </a>
    +
    +                    <a target="_blank" href="Nmon_compare">
    +                        <span title="Nmon Comparison Interface &#013;
    +&#013;
    +• Compare System Resources usage between 2 periods, a reference Period and arrival Period &#013;
    +&#013;
    +• Choose between Main Monitors: CPU usage (CPU_ALL / LPAR), Memory, I/O, Network &#013;
    +&#013;
    +• Evaluate the trend with Evolution Rate and graphical decorations to help instantly discover the comparison result">
    +                            Nmon Comparison Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ DASHBOARDS ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/dashboard.png" alt="Dashboard"/>
    +                    <h2>Dashboards</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a href="Dashboard_BubbleChart_top_hosts?&amp;form.osfilter=Solaris" class="tryitbtn-alt">TOP HOSTS DASH »
    +                    </a>
    +
    +                    <a href="Dashboard_BubbleChart_top_hosts?&amp;form.osfilter=Solaris">
    +                        <span title="BubbleChart: TOP hosts CPU Usage &#013;
    +&#013;
    +• Evaluate the TOP 100 hosts CPU load represented in Bubble Charts to instantly discover hosts responsible of the global load average &#013;
    +&#013;
    +• Evaluate the TOP 20 hosts CPU load represented in d3chart bar chart &#013;
    +&#013;
    +• Evaluate the full Statistics table of hosts CPU load with main hosts information">
    +                            BubbleChart: TOP hosts CPU Usage
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_bulletcharts" class="tryitbtn-alt">BULLET DASH »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_bulletcharts">
    +                        <span title="Bullet charts Dashboard: Analysis of main system metrics in bullet charts &#013;
    +&#013;
    +• TOP hosts by CPU usage / TOP hosts by physical and virtual memory usage &#013;
    +&#013;
    +• TOP Commands (processes) consumming CPU and Memory in your deployment &#013;
    +&#013;
    +• Advanced drilldown facilities for insight analysis">
    +                            Bullet Chart: TOP Servers / TOP Processes
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?&amp;form.osfilter=Solaris" class="tryitbtn-alt">TOP PROCESSES DASH »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?&amp;form.osfilter=Solaris">
    +                        <span title="Dashboard: Processes CPU and Memory Usage &#013;
    +&#013;
    +• Evaluate Processes CPU and Memory usage in d3chart BubbleChart to instantly represent major Command invocations &#013;
    +&#013;
    +• Represent this CPU / Memory usage in a d3chart chart over time &#013;
    +&#013;">
    +                            Processes CPU and Memory Usage
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_heatmap_daily_usage" class="tryitbtn-alt">CALENDAR DAILY CPU USAGE »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_heatmap_daily_usage">
    +                        <span title="Dashboard: CALENDAR DAILY CPU USAGE &#013;
    +&#013;
    +• Evaluate daily CPU usage of multiple servers within the heatmap calendar visualization &#013;
    +&#013;
    +• Zoom within the TOP consumers by chart drilldown &#013;
    +&#013;">
    +                            CALENDAR DAILY CPU USAGE
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_WLM_Solaris" class="tryitbtn-alt">DASHBOARD WLM »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_WLM_Solaris">
    +                        <span title="D3chart: Solaris Projects / Zones / Tasks / Users CPU and Memory statistics &#013;
    +&#013;
    +• Evaluate Major CPU and MEM usage items, choose between available monitors &#013;
    +&#013;
    +• Represent this CPU / Memory usage in a d3chart bubblechart and statistic tables &#013;
    +&#013;">
    +                            Solaris WLM CPU and Memory Statistics
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <!-- ###################################################################################################### -->
    +
    +                <!-- ############################################ CONFIG ############################################ -->
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/server_info.png" alt="ServerInfo"/>
    +                    <h2><a href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.osfilter=Linux%3Dtrue&amp;form.osfilter=Solaris%3Dtrue&amp;form.itemfilter=CONFIGURATION%20DATA" target="_blank">Hosts Configuration</a></h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG" class="tryitbtn-alt">CONFIG »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG">
    +                        <span title="Hosts Configuration Show Interface &#013;
    +&#013;
    +• Explore the raw configuration of hosts &#013;
    +&#013;
    +• The full raw host configuration is part of AAA and BBB sections of raw Nmon files">
    +                            CONFIG: Hosts Configuration Show Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG_simple_inventory_SOLARIS" class="tryitbtn-alt">INVENTORY »
    +                    </a>
    +
    +                    <a target="_blank" href="UI_Nmon_CONFIG_simple_inventory_SOLARIS">
    +                        <span title="Nmon Configuration Inventory &#013;
    +&#013;
    +• Explore the Nmon inventory of known hosts from your system to get valuable information &#013;
    +&#013;
    +• Main configuration Items depends on Operating System: type of OS, OS version, CPU / Mem configuration and more">
    +                            Nmon Configuration Inventory
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +        <!-- ###################################################################################################### -->
    +
    +        <!-- ############################################ PROCESSING ############################################ -->
    +
    +        <panel>
    +            <html>
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h2>Application Information and costs</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="Dashboard_Internal_Stats" class="tryitbtn-alt">TCO ANALYSIS »
    +                    </a>
    +
    +                    <a target="_blank" href="Dashboard_Internal_Stats">
    +                        <span title="Application Internal Statistics &#013;
    +&#013;
    +• Estimate the average cost of licence per server &#013;
    +&#013;
    +• Monitor the global licence cost associated with the Nmon Performance application &#013;
    +&#013;
    +• Monitor run time metrics of scheduled searches  &#013;
    +&#013;
    +• Immediately view storage details of the Nmon index
    +">
    +                            Total Cost of Ownership Interface
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +                <hr />
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/dictionary.png" alt="Dictionary"/>
    +                    <h2>Data Dictionary</h2>
    +                </div>
    +
    +                <hr />
    +
    +                <div class="cat_title">
    +
    +                    <a target="_blank" href="UI_data_dictionary" class="tryitbtn-alt">
    +                        <span title="Data Dictionary &#013;
    +&#013;
    +• Discover and Explore available data within the Nmon Splunk Application &#013;
    +&#013;
    +• Filter relevant Data for AIX, Linux and Solaris systems &#013;
    +&#013;
    +• Access to full metric definition: brieve and full description, relevant unity, formula...">
    +
    +                            Explore The Data Dictionary »
    +
    +                        </span>
    +                    </a>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +
    +    </row>
    +</dashboard>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Howto_CPU_ALL_spl.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Howto_CPU_ALL_spl.xml
    new file mode 100644
    index 0000000..b5e93e5
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Howto_CPU_ALL_spl.xml
    @@ -0,0 +1,403 @@
    +<form script="panel_resize.js,modal.js" stylesheet="howto.css,ui_simple.css" hideEdit="True" isVisible="true" version="1.1" theme="dark">
    +	<label>HOWTO CPU_ALL: Generate stats and charts with Splunk Search Processing Language (SPL)</label>
    +	<description>This collection of request samples will help you generating your own reports, dashboards and alerts for Nmon Performance data using the native Search Processing Language</description>
    +
    +	<row>
    +		<panel>
    +
    +			<html>
    +
    +				<div class="imgheader custom-modal">
    +					<img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +					<h2><a data-modal-name="Help_modal">CPU Percentage Usage Statistics (click here for more information)</a></h2>
    +				</div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                                    <h1>
    +                                        CPU global percentage statistics
    +                                        <br />
    +                                        (metric_name=os.unix.nmon.cpu.cpu_all.*)
    +                                    </h1>
    +
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    <br />
    +                                    <i>The CPU_ALL monitor represents average metrics for all available logical CPUs to the system.</i>
    +                                    <br />
    +                                    <i>These metrics are common to every supported operating systems.</i>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>raw metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Sys_PCT:</b> % of CPU time spent in kernel mode</li>
    +                                            <li><b>User_PCT:</b> % of CPU time spent in user mode</li>
    +                                            <li><b>Wait_PCT:</b> % of CPU time spent in waiting for resources</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Idle_PCT:</b> % of CPU time free, meaning not having task to do</li>
    +                                            <li><b>CPUs:</b> Number of CPUs cores available to the system</li>
    +                                        </lu>
    +                                        <br />
    +                                    </div>
    +
    +                                    <h1>calculated metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>cpu_load_percent:</b> % of CPU usage for all available cores (Sys_PCT+User_PCT+Wait_PCT)</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.cpu.cpu_all.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_cpu_load_percent%60" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" class="tryitbtnxl">CPU Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D$host$%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +			</html>
    +
    +		</panel>
    +
    +		<panel>
    +			<title>Optionally preset host and press Enter:</title>
    +
    +			<input type="text" token="host" searchWhenChanged="true">
    +				<label>Host:</label>
    +				<default>*</default>
    +			</input>
    +
    +		</panel>
    +
    +	</row>
    +
    +	<row>
    +		<panel>
    +			<title>Time oriented and statistics oriented charts:</title>
    +
    +			<html>
    +
    +				<div>
    +					<h2>Time Oriented Charts:</h2>
    +					<br />
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minichart.png" alt="minichart"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Average CPU Usage in Percentage over last 24 hours using the custom span macro, in a line chart by server names</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT host=$host$ by metric_name, host span=1m
    +| `def_cpu_load_percent` | timechart `nmon_span` avg(cpu_load_percent) AS cpu_load_percent by host</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Wait_PCT%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_cpu_load_percent%60%20%7C%20timechart%20%60nmon_span%60%20avg(cpu_load_percent)%20AS%20cpu_load_percent%20by%20host&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.chart=line&amp;display.visualizations.charting.axisY.maximumNumber=100&amp;display.visualizations.charting.legend.placement=top&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Average Sys / User / Wait /Idle CPU Usage in a 100% stack area chart of a specific server over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT) host=$host$ by metric_name, host span=1m
    +| `def_cpu_all_cpu_load_percent_by_category` | timechart `nmon_span` avg(Sys_PCT) AS Sys_PCT, avg(User_PCT) AS User_PCT, avg(Wait_PCT) AS Wait_PCT, avg(Idle_PCT) AS Idle_PCT</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20(metric_name%3Dos.unix.nmon.cpu.cpu_all.Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Wait_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Idle_PCT)%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_cpu_all_cpu_load_percent_by_category%60%7C%20timechart%20%60nmon_span%60%20avg(Sys_PCT)%20AS%20Sys_PCT%2C%20avg(User_PCT)%20AS%20User_PCT%2C%20avg(Wait_PCT)%20AS%20Wait_PCT%2C%20avg(Idle_PCT)%20AS%20Idle_PCT&amp;earliest=-24h&amp;latest=now&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart=area&amp;display.visualizations.charting.legend.placement=top&amp;display.visualizations.charting.chart.stackMode=stacked100" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Average CPU Usage in Percentage over last 30 days for Working hours Business days only (monday to friday, 08h to 19h) with auto span (custom macro span definition) in a line chart by server names</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT host=$host$ by metric_name, host span=1m
    +| `Day_BusinessDays_8h-19h`
    +| `def_cpu_load_percent` | timechart `nmon_span` avg(cpu_load_percent) AS cpu_load_percent by host</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Wait_PCT%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60Day_BusinessDays_8h-19h%60%0A%7C%20%60def_cpu_load_percent%60%20%7C%20timechart%20%60nmon_span%60%20avg(cpu_load_percent)%20AS%20cpu_load_percent%20by%20host&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.chart=line&amp;display.visualizations.charting.axisY.maximumNumber=100&amp;display.visualizations.charting.legend.placement=top&amp;earliest=-30d%40d&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Compare Average CPU usage of yesterday versus today in a line chart of a specific server with a static span of 5 minutes (time reference of yesterday)</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT host=$host$ earliest="-1d@d" latest="@d" by metric_name, host span=1m
    +| `def_cpu_load_percent` | timechart `nmon_span` avg(cpu_load_percent) AS yesterday_cpu_load_percent
    +| appendcols [ | mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT host=$host$ earliest="@d" latest="+1d@d" by metric_name, host span=1m
    +| `def_cpu_load_percent` | timechart `nmon_span` avg(cpu_load_percent) AS today_cpu_load_percent | fields - _time ]</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Wait_PCT%20host%3D$host$%20earliest%3D&quot;-1d%40d&quot;%20latest%3D&quot;%40d&quot;%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_cpu_load_percent%60%20%7C%20timechart%20%60nmon_span%60%20avg(cpu_load_percent)%20AS%20yesterday_cpu_load_percent%0A%7C%20appendcols%20%5B%20%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Wait_PCT%20host%3D$host$%20earliest%3D&quot;%40d&quot;%20latest%3D&quot;%2B1d%40d&quot;%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_cpu_load_percent%60%20%7C%20timechart%20%60nmon_span%60%20avg(cpu_load_percent)%20AS%20today_cpu_load_percent%20%7C%20fields%20-%20_time%20%5D&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.chart=line&amp;display.visualizations.charting.axisY.maximumNumber=100&amp;display.visualizations.charting.legend.placement=top&amp;earliest=%40d&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/single_trend.png" alt="minichart"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Single trend physical memory usage in percentage over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT host=$host$ by metric_name, host span=1m
    +| `def_cpu_load_percent` | timechart `nmon_span` avg(cpu_load_percent) AS avg | eval avg=round(avg, 2) | where isnum(avg)</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Wait_PCT%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_cpu_load_percent%60%20%7C%20timechart%20%60nmon_span%60%20avg(cpu_load_percent)%20AS%20avg%20%7C%20eval%20avg%3Dround(avg%2C%202)%20%7C%20where%20isnum(avg)&amp;display.page.search.mode=smart&amp;dispatch.sample_ratio=1&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.singlevalue.trendDisplayMode=percent&amp;display.visualizations.singlevalue.useColors=1&amp;display.visualizations.singlevalue.colorBy=trend&amp;display.visualizations.singlevalue.trendColorInterpretation=inverse&amp;display.visualizations.singlevalue.numberPrecision=0.00" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Stats oriented Charts:</h2>
    +					<br />
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minigauge.png" alt="minichart"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Gauge chart of average CPU Usage in Percentage over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT host=$host$ by metric_name, host span=1m
    +| `def_cpu_load_percent` | stats avg(cpu_load_percent) AS cpu_load_percent</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Wait_PCT%20host%3D$host$*%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_cpu_load_percent%60%20%7C%20stats%20avg(cpu_load_percent)%20AS%20cpu_load_percent&amp;earliest=-24h&amp;latest=now&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minicolumn.png" alt="minicolumn"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Column chart of TOP 10 average CPU Usage in Percentage over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT host=$host$ by metric_name, host span=1m
    +| `def_cpu_load_percent` | stats avg(cpu_load_percent) as cpu_load_percent by host | eval cpu_load_percent=round(cpu_load_percent, 2) | sort 0 - cpu_load_percent | head 10
    +| eval xlabel=""
    +| chart useother=f limit=0 values(cpu_load_percent) AS "Avg CPU %" by xlabel,host | rename xlabel AS "TOP 10 CPU % usage"</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Wait_PCT%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_cpu_load_percent%60%20%7C%20stats%20avg(cpu_load_percent)%20as%20cpu_load_percent%20by%20host%20%7C%20eval%20cpu_load_percent%3Dround(cpu_load_percent%2C%202)%20%7C%20sort%200%20-%20cpu_load_percent%20%7C%20head%2010%0A%7C%20eval%20xlabel%3D&quot;&quot;%0A%7C%20chart%20useother%3Df%20limit%3D0%20values(cpu_load_percent)%20AS%20&quot;Avg%20CPU%20%25&quot;%20by%20xlabel%2Chost%20%7C%20rename%20xlabel%20AS%20&quot;TOP%2010%20CPU%20%25%20usage&quot;&amp;earliest=%40y&amp;latest=now&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart=column&amp;display.visualizations.charting.legend.placement=top&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.axisY.maximumNumber=100" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +			</html>
    +
    +		</panel>
    +	</row>
    +
    +	<row>
    +		<panel>
    +			<title>Table Statistics:</title>
    +
    +			<html>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minitable.png" alt="minitable"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>CPU global usage and usage by category in percentage over the last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT) host=$host$ by metric_name, host span=1m
    +| `def_cpu_all_cpu_load_percent_by_category`
    +| eval cpu_load_percent=(Sys_PCT+User_PCT+Wait_PCT)
    +| stats avg(cpu_load_percent) as cpu_load_percent, avg(Sys_PCT) as Sys_percent, avg(User_PCT) as User_percent, avg(Wait_PCT) as Wait_percent, avg(Idle_PCT) as Idle_percent, sparkline(avg(cpu_load_percent),) As sparkline by host
    +| foreach *_percent [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 3) ]
    +| rename *_percent AS "* (%)"</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20(metric_name%3Dos.unix.nmon.cpu.cpu_all.Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Wait_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Idle_PCT)%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_cpu_all_cpu_load_percent_by_category%60%0A%7C%20eval%20cpu_load_percent%3D(Sys_PCT%2BUser_PCT%2BWait_PCT)%0A%7C%20stats%20avg(cpu_load_percent)%20as%20cpu_load_percent%2C%20avg(Sys_PCT)%20as%20Sys_percent%2C%20avg(User_PCT)%20as%20User_percent%2C%20avg(Wait_PCT)%20as%20Wait_percent%2C%20avg(Idle_PCT)%20as%20Idle_percent%2C%20sparkline(avg(cpu_load_percent)%2C)%20As%20sparkline%20by%20host%0A%7C%20foreach%20*_percent%20%5B%20eval%20&lt;&lt;FIELD&gt;&gt;%20%3D%20round(%27&lt;&lt;FIELD&gt;&gt;%27%2C%203)%20%5D%0A%7C%20rename%20*_percent%20AS%20&quot;*%20(%25)&quot;&amp;display.page.search.tab=statistics&amp;display.general.type=statistics&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Min / Average / Median / Max and Average sparkline of CPU Usage in Percentage over last 24 hours ordered and sorted by frame ID, host</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT) host=$host$ by metric_name, host span=1m
    +| `def_cpu_load_percent`
    +| stats min(cpu_load_percent) as min_cpu_load_percent, avg(cpu_load_percent) as avg_cpu_load_percent, median(cpu_load_percent) as median_cpu_load_percent, max(cpu_load_percent) as max_cpu_load_percent, sparkline(avg(cpu_load_percent),) As sparkline by host
    +| foreach *_percent [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 3) ]
    +| rename *_percent AS "* (%)"</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20(metric_name%3Dos.unix.nmon.cpu.cpu_all.Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Wait_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Idle_PCT)%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_cpu_load_percent%60%0A%7C%20stats%20min(cpu_load_percent)%20as%20min_cpu_load_percent%2C%20avg(cpu_load_percent)%20as%20avg_cpu_load_percent%2C%20median(cpu_load_percent)%20as%20median_cpu_load_percent%2C%20max(cpu_load_percent)%20as%20max_cpu_load_percent%2C%20sparkline(avg(cpu_load_percent)%2C)%20As%20sparkline%20by%20host%0A%7C%20foreach%20*_percent%20%5B%20eval%20&lt;&lt;FIELD&gt;&gt;%20%3D%20round(%27&lt;&lt;FIELD&gt;&gt;%27%2C%203)%20%5D%0A%7C%20rename%20*_percent%20AS%20&quot;*%20(%25)&quot;&amp;display.page.search.tab=statistics&amp;display.general.type=statistics&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +			</html>
    +
    +		</panel>
    +	</row>
    +
    +	<row>
    +		<panel>
    +			<title>Alerting:</title>
    +
    +			<html>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minisingle.png" alt="minisingle"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Find servers having an average CPU usage higher than 90% for a minimal contiguous period of 5 minutes</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT) host=$host$ by metric_name, OStype, host span=1m
    +| `def_cpu_load_percent`
    +| fields _time, host, cpu_load_percent
    +| where cpu_load_percent&gt;90
    +| stats latest(_time) as _time range(_time) as duration latest(cpu_load_percent) as latest_cpu_load_percent by host
    +| where (latest_cpu_load_percent&gt;=90) AND (duration &gt;= 300)
    +| eval "duration (hh:mm:ss)"=tostring(duration,"duration")
    +| fields host,_time,duration,"duration (hh:mm:ss)",latest_cpu_load_percent</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20(metric_name%3Dos.unix.nmon.cpu.cpu_all.Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Wait_PCT)%20host%3D$host$%20by%20metric_name%2C%20OStype%2C%20host%20span%3D1m%0A%7C%20%60def_cpu_load_percent%60%0A%7C%20fields%20_time%2C%20host%2C%20cpu_load_percent%0A%7C%20where%20cpu_load_percent&gt;90%0A%7C%20stats%20latest(_time)%20as%20_time%20range(_time)%20as%20duration%20latest(cpu_load_percent)%20as%20latest_cpu_load_percent%20by%20host%0A%7C%20where%20(latest_cpu_load_percent&gt;%3D90)%20AND%20(duration%20&gt;%3D%20300)%0A%7C%20eval%20&quot;duration%20(hh%3Amm%3Ass)&quot;%3Dtostring(duration%2C&quot;duration&quot;)%0A%7C%20fields%20host%2C_time%2Cduration%2C&quot;duration%20(hh%3Amm%3Ass)&quot;%2Clatest_cpu_load_percent&amp;display.page.search.tab=statistics&amp;display.general.type=statistics&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Find servers having an average CPU usage higher than 90% for a minimal contiguous period of 5 minutes, restricted to Open hours and Business days (monday to friday, 08h to 19h)</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT) host=$host$ by metric_name, OStype, host span=1m
    +| `Day_BusinessDays_8h-19h`
    +| `def_cpu_load_percent`
    +| fields _time, host, cpu_load_percent
    +| where cpu_load_percent&gt;90
    +| stats latest(_time) as _time range(_time) as duration latest(cpu_load_percent) as latest_cpu_load_percent by host
    +| where (latest_cpu_load_percent&gt;=90) AND (duration &gt;= 300)
    +| eval "duration (hh:mm:ss)"=tostring(duration,"duration")
    +| fields host,_time,duration,"duration (hh:mm:ss)",latest_cpu_load_percent</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20(metric_name%3Dos.unix.nmon.cpu.cpu_all.Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.cpu_all.Wait_PCT)%20host%3D$host$%20by%20metric_name%2C%20OStype%2C%20host%20span%3D1m%0A%7C%20%60Day_BusinessDays_8h-19h%60%0A%7C%20%60def_cpu_load_percent%60%0A%7C%20fields%20_time%2C%20host%2C%20cpu_load_percent%0A%7C%20where%20cpu_load_percent&gt;90%0A%7C%20stats%20latest(_time)%20as%20_time%20range(_time)%20as%20duration%20latest(cpu_load_percent)%20as%20latest_cpu_load_percent%20by%20host%0A%7C%20where%20(latest_cpu_load_percent&gt;%3D90)%20AND%20(duration%20&gt;%3D%20300)%0A%7C%20eval%20&quot;duration%20(hh%3Amm%3Ass)&quot;%3Dtostring(duration%2C&quot;duration&quot;)%0A%7C%20fields%20host%2C_time%2Cduration%2C&quot;duration%20(hh%3Amm%3Ass)&quot;%2Clatest_cpu_load_percent&amp;display.page.search.tab=statistics&amp;display.general.type=statistics&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +			</html>
    +
    +		</panel>
    +
    +	</row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Howto_LPAR_spl.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Howto_LPAR_spl.xml
    new file mode 100644
    index 0000000..51bb80c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Howto_LPAR_spl.xml
    @@ -0,0 +1,394 @@
    +<form stylesheet="howto.css,ui_simple.css" script="modal.js" hideEdit="True" isVisible="true" version="1.1" theme="dark">
    +	<label>HOWTO LPAR: Generate stats and charts with Splunk Search Processing Language (SPL) for IBM Pseries micro-partitions</label>
    +	<description>This collection of request samples will help you generating your own reports, dashboards and alerts for Nmon Performance data using the native Search Processing Language</description>
    +
    +	<row>
    +		<panel>
    +
    +			<html>
    +
    +				<div class="imgheader custom-modal">
    +					<img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +					<h2><a data-modal-name="Help_modal">CPU Usage Statistics for IBM PSeries Micro-Partitions (click here for more information)</a></h2>
    +				</div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                                    <h1>CPU global percentage statistics for IBM AIX partitions
    +                                    <br />
    +                                    (metric_name=os.unix.nmon.cpu.lpar.*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div>
    +                                    <i>The LPAR monitor contains IBM Power partitions specific CPU statistics.</i>
    +                                    <br />
    +                                    <i>These metrics are available only for IBM Pseries and partitions running AIX or PowerLinux.</i>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>raw metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>entitled:</b> Entitled capacity of the partition</li>
    +                                            <li><b>virtualCPUs:</b> Number of virtual processors in the LPAR definition</li>
    +                                            <li><b>VP_Idle_PCT/EC_Idle_PCT:</b> % of CPU time free, meaning not having task to do</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>VP_Sys_PCT/EC_Sys_PCT:</b> % of CPU time spent in kernel mode</li>
    +                                            <li><b>VP_User_PCT/EC_User_PCT:</b> % of CPU time spent in user mode</li>
    +                                            <li><b>VP_Wait_PCT/VP_Wait_PCT:</b> % of CPU time spent in waiting for resources</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <h1>calculated metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>lpar_load_cores:</b> partition CPU cores usage versus VP/EC</li>
    +                                            <li><b>lpar_load_percent:</b> partition CPU percentage usage versus VP/EC</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.cpu.lpar.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_load_vp_aix_cores%60" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_LPAR_partitions_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_Summary" class="tryitbtnxl">NMON SUMMARY Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_ANALYSER_AIX" class="tryitbtnxl">NMON ANALYSER Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" class="tryitbtnxl">CPU Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +			</html>
    +
    +		</panel>
    +
    +		<panel>
    +			<title>Optionally preset host and press Enter:</title>
    +
    +			<input type="text" token="host" searchWhenChanged="true">
    +				<label>Host:</label>
    +				<default>*</default>
    +			</input>
    +
    +		</panel>
    +
    +	</row>
    +
    +
    +	<row>
    +		<panel>
    +			<title>Time oriented and statistics oriented charts:</title>
    +
    +			<html>
    +
    +				<div>
    +					<i><h2>Time Oriented Charts:</h2></i>
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minichart.png" alt="minichart"/>
    +					<br />
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>AIX Micro-Partitions average CPU Usage in cores (calculated over VP) for the last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.PhysicalCPU host=$host$ by host span=1m
    +| timechart `nmon_span` useother=f limit=0 avg(PhysicalCPU) as lpar_load_cores by host</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.PhysicalCPU%20host%3D$host$%20by%20host%20span%3D1m%0A%7C%20timechart%20%60nmon_span%60%20useother%3Df%20limit%3D0%20avg(value)%20as%20lpar_load_cores%20by%20host&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=&amp;display.visualizations.charting.chart=line&amp;display.visualizations.charting.axisY.maximumNumber=&amp;display.visualizations.charting.legend.placement=top&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>AIX Micro-Partitions average CPU Usage in cores with entitlement and virtualCPUs (calculated over VP) for the last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.entitled  OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs host=$host$ by metric_name, host span=1m
    +| `def_lpar_load_vp_aix_cores`
    +| timechart `nmon_span` useother=f limit=0 max(lpar_load_cores) as lpar_load_cores max(entitled) as entitled max(virtualCPUs) as virtualCPUs by host</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Wait_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Idle_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.entitled%20%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.virtualCPUs%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_load_vp_aix_cores%60%0A%7C%20timechart%20%60nmon_span%60%20useother%3Df%20limit%3D0%20max(lpar_load_cores)%20as%20lpar_load_cores%20max(entitled)%20as%20entitled%20max(virtualCPUs)%20as%20virtualCPUs%20by%20host&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=&amp;display.visualizations.charting.chart=line&amp;display.visualizations.charting.axisY.maximumNumber=&amp;display.visualizations.charting.legend.placement=top&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>AIX Micro-Partitions average CPU Usage percentage (calculated over VP against partition capacity) for the last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.entitled  OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs host=$host$ by metric_name, host span=1m
    +| `def_lpar_load_vp_aix_percent`
    +| timechart `nmon_span` useother=f limit=0 avg(lpar_load_percent) as lpar_load_percent by host</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Wait_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Idle_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.entitled%20%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.virtualCPUs%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_load_vp_aix_percent%60%0A%7C%20timechart%20%60nmon_span%60%20useother%3Df%20limit%3D0%20avg(lpar_load_percent)%20as%20lpar_load_percent%20by%20host&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=&amp;display.visualizations.charting.chart=line&amp;display.visualizations.charting.axisY.maximumNumber=&amp;display.visualizations.charting.legend.placement=top&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>AIX Pool average CPU Usage in cores with number of CPUs in pool for the last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.lpar.poolCPUs OR metric_name=os.unix.nmon.cpu.lpar.Pool_id OR metric_name=os.unix.nmon.cpu.lpar.PoolIdle) host=$host$ by metric_name, OStype, host span=1m
    +| `def_lpar_pool_load_aix_cores`
    +| timechart useother=f limit=0 `nmon_span` max(lpar_pool_usage) as lpar_pool_usage max(poolCPUs) AS poolCPUs by host</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20(metric_name%3Dos.unix.nmon.cpu.lpar.poolCPUs%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.Pool_id%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.PoolIdle)%20host%3D$host$%20by%20metric_name%2C%20OStype%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_pool_load_aix_cores%60%0A%7C%20timechart%20useother%3Df%20limit%3D0%20%60nmon_span%60%20max(lpar_pool_usage)%20as%20lpar_pool_usage%20max(poolCPUs)%20AS%20poolCPUs%20by%20host&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=&amp;display.visualizations.charting.chart=line&amp;display.visualizations.charting.axisY.maximumNumber=&amp;display.visualizations.charting.legend.placement=top&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<i><h2>Stats oriented Charts:</h2></i>
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minigauge.png" alt="minichart"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Gauge chart of AIX Micro-Partitions average CPU percentage Usage (percentage evaluated over VP usage and capacity) over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.entitled  OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs host=$host$ by metric_name, host span=1m
    +| `def_lpar_load_vp_aix_percent`
    +| stats avg(lpar_load_percent) AS value | eval value=round(value,2)</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.PhysicalCPU%20host%3D$host$%20by%20host%20span%3D1m%0A%7C%20stats%20avg(value)%20AS%20value%20%7C%20eval%20value%3Dround(value%2C2)&amp;earliest=-24h&amp;latest=now&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Gauge chart of AIX Pool average CPU percentage Usage (percentage evaluated over VP usage and capacity) over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.lpar.poolCPUs OR metric_name=os.unix.nmon.cpu.lpar.Pool_id OR metric_name=os.unix.nmon.cpu.lpar.PoolIdle) host=$host$ by metric_name, OStype, host span=1m
    +| `def_lpar_pool_load_aix_percent` | rename lpar_pool_usage_percent as lpar_pool_usage
    +| stats avg(lpar_pool_usage) AS lpar_pool_usage | eval lpar_pool_usage=round(lpar_pool_usage,2)</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20(metric_name%3Dos.unix.nmon.cpu.lpar.poolCPUs%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.Pool_id%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.PoolIdle)%20host%3D$host$%20by%20metric_name%2C%20OStype%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_pool_load_aix_percent%60%20%7C%20rename%20lpar_pool_usage_percent%20as%20lpar_pool_usage%0A%7C%20stats%20avg(lpar_pool_usage)%20AS%20lpar_pool_usage%20%7C%20eval%20lpar_pool_usage%3Dround(lpar_pool_usage%2C2)&amp;earliest=-24h&amp;latest=now&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minicolumn.png" alt="minicolumn"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Column chart of TOP 10 average CPU Percentage Usage (Percentage evaluated over VP usage and capacity) over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.entitled  OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs host=SPH0073B by metric_name, host span=1m
    +| `def_lpar_load_vp_aix_percent`
    +| stats avg(lpar_load_percent) as lpar_load_percent by host
    +| sort - lpar_load_percent | head 10
    +| eval xlabel=""
    +| chart useother=f limit=0 values(lpar_load_percent) AS "Avg CPU %" by xlabel,host | rename xlabel AS "TOP 10 CPU % usage"</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Wait_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Idle_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.entitled%20%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.virtualCPUs%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_load_vp_aix_percent%60%0A%7C%20stats%20avg(lpar_load_percent)%20as%20lpar_load_percent%20by%20host%0A%7C%20sort%20-%20lpar_load_percent%20%7C%20head%2010%0A%7C%20eval%20xlabel%3D&quot;&quot;%0A%7C%20chart%20useother%3Df%20limit%3D0%20values(lpar_load_percent)%20AS%20&quot;Avg%20CPU%20%25&quot;%20by%20xlabel%2Chost%20%7C%20rename%20xlabel%20AS%20&quot;TOP%2010%20CPU%20%25%20usage&quot;&amp;earliest=-24h%40h&amp;latest=now&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart=column&amp;display.visualizations.charting.legend.placement=top&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.axisY.maximumNumber=" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +			</html>
    +
    +		</panel>
    +	</row>
    +
    +	<row>
    +		<panel>
    +			<title>Table Statistics:</title>
    +
    +			<html>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minitable.png" alt="minitable"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Min / Average / Max CPU Usage in VP (evaluated over VP) over last 24 hours ordered and sorted by frame ID, host</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.entitled  OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs host=$host$ by metric_name, host span=1m
    +| `def_lpar_load_vp_aix_cores`
    +| `mapping_frameID`
    +| where lpar_load_cores>0
    +| stats min(lpar_load_cores) As min_lpar_load_cores, avg(lpar_load_cores) As avg_lpar_load_cores, max(lpar_load_cores) As max_lpar_load_cores, max(entitled) As entitled, max(virtualCPUs) As virtualCPUs, sparkline(max(lpar_load_cores)) As sparkline by frameID,host
    +| sort limit=0 frameID | eval avg_lpar_load_cores=round(avg_lpar_load_cores,3) | foreach max_lpar_load_cores,avg_lpar_load_cores,min_lpar_load_cores [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 3) ] | fields frameID,host,max_lpar_load_cores,avg_lpar_load_cores,min_lpar_load_cores,entitled,virtualCPUs,sparkline</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Wait_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Idle_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.entitled%20%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.virtualCPUs%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_load_vp_aix_cores%60%0A%7C%20%60mapping_frameID%60%0A%7C%20where%20lpar_load_cores&gt;0%0A%7C%20stats%20min(lpar_load_cores)%20As%20min_lpar_load_cores%2C%20avg(lpar_load_cores)%20As%20avg_lpar_load_cores%2C%20max(lpar_load_cores)%20As%20max_lpar_load_cores%2C%20max(entitled)%20As%20entitled%2C%20max(virtualCPUs)%20As%20virtualCPUs%2C%20sparkline(max(lpar_load_cores))%20As%20sparkline%20by%20frameID%2Chost%0A%7C%20sort%20limit%3D0%20frameID%20%7C%20eval%20avg_lpar_load_cores%3Dround(avg_lpar_load_cores%2C3)%20%7C%20foreach%20max_lpar_load_cores%2Cavg_lpar_load_cores%2Cmin_lpar_load_cores%20%5B%20eval%20&quot;&lt;&lt;FIELD&gt;&gt;&quot;%3Dround(%27&lt;&lt;FIELD&gt;&gt;%27%2C%203)%20%5D%20%7C%20fields%20frameID%2Chost%2Cmax_lpar_load_cores%2Cavg_lpar_load_cores%2Cmin_lpar_load_cores%2Centitled%2CvirtualCPUs%2Csparkline&amp;display.page.search.tab=statistics&amp;display.general.type=statistics&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +			</html>
    +
    +		</panel>
    +	</row>
    +
    +	<row>
    +		<panel>
    +			<title>Alerting:</title>
    +
    +			<html>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minisingle.png" alt="minisingle"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>IBM Micro-Partitions having an average CPU usage higher than 90% for a minimal contiguous period of 5 minutes</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.entitled  OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs host=$host$ by metric_name, host span=1m
    +| `def_lpar_load_vp_aix_percent`
    +| where lpar_load_percent>90
    +| stats latest(_time) as _time range(_time) as duration latest(lpar_load_percent) as latest_lpar_load_percent by host
    +| where (latest_lpar_load_percent>=90) AND (duration >= 300)
    +| eval "duration (hh:mm:ss)"=tostring(duration,"duration")
    +| fields host,_time,duration,"duration (hh:mm:ss)",latest_lpar_load_percent</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Sys_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_User_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Wait_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.VP_Idle_PCT%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.entitled%20%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.virtualCPUs%20host%3D$host$%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_load_vp_aix_percent%60%0A%7C%20where%20lpar_load_percent&gt;90%0A%7C%20stats%20latest(_time)%20as%20_time%20range(_time)%20as%20duration%20latest(lpar_load_percent)%20as%20latest_lpar_load_percent%20by%20host%0A%7C%20where%20(latest_lpar_load_percent&gt;%3D90)%20AND%20(duration%20&gt;%3D%20300)%0A%7C%20eval%20&quot;duration%20(hh%3Amm%3Ass)&quot;%3Dtostring(duration%2C&quot;duration&quot;)%0A%7C%20fields%20host%2C_time%2Cduration%2C&quot;duration%20(hh%3Amm%3Ass)&quot;%2Clatest_lpar_load_percent&amp;display.page.search.tab=statistics&amp;display.general.type=statistics&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>IBM Pools having an average CPU usage higher than 90% for a minimal contiguous period of 5 minutes</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.lpar.poolCPUs OR metric_name=os.unix.nmon.cpu.lpar.PoolIdle OR metric_name=os.unix.nmon.cpu.lpar.pool_idle_time OR metric_name=os.unix.nmon.cpu.lpar.pool_capacity OR metric_name=os.unix.nmon.cpu.lpar.smt_mode OR metric_name=os.unix.nmon.cpu.lpar.Pool_id) (host=$host$) by metric_name, OStype, host span=1m
    +| `def_all_os_lpar_pool_load_percent`
    +| where PoolIdle>0
    +| fields _time, host, lpar_pool_vp_usage_PCT
    +| where lpar_pool_vp_usage_PCT>90
    +| lookup nmon_frameID_mapping host as host OUTPUT frameID
    +| eval frameID=if(isnull(frameID),host,frameID)
    +| lookup nmon_inventory hostname as host OUTPUT AIX_PoolID as PoolID
    +| search frameID="*" PoolID="0"
    +| stats latest(_time) as _time range(_time) as duration latest(lpar_pool_vp_usage_PCT) as latest_lpar_pool_vp_usage_percent, latest(PoolID) as Pool_id by frameID,host
    +| where (latest_lpar_pool_vp_usage_percent>=90) AND (duration >= 300)
    +| dedup frameID, Pool_id
    +| eval "duration (hh:mm:ss)"=tostring(duration,"duration")
    +| fields frameID,host,_time,Pool_id,duration,"duration (hh:mm:ss)",latest_lpar_pool_vp_usage_percent</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20(metric_name%3Dos.unix.nmon.cpu.lpar.poolCPUs%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.PoolIdle%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.pool_idle_time%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.pool_capacity%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.smt_mode%20OR%20metric_name%3Dos.unix.nmon.cpu.lpar.Pool_id)%20(host%3D$host$)%20by%20metric_name%2C%20OStype%2C%20host%20span%3D1m%0A%7C%20%60def_all_os_lpar_pool_load_percent%60%0A%7C%20where%20PoolIdle&gt;0%0A%7C%20fields%20_time%2C%20host%2C%20lpar_pool_vp_usage_PCT%0A%7C%20where%20lpar_pool_vp_usage_PCT&gt;90%0A%7C%20lookup%20nmon_frameID_mapping%20host%20as%20host%20OUTPUT%20frameID%0A%7C%20eval%20frameID%3Dif(isnull(frameID)%2Chost%2CframeID)%0A%7C%20lookup%20nmon_inventory%20hostname%20as%20host%20OUTPUT%20AIX_PoolID%20as%20PoolID%0A%7C%20search%20frameID%3D&quot;*&quot;%20PoolID%3D&quot;0&quot;%0A%7C%20stats%20latest(_time)%20as%20_time%20range(_time)%20as%20duration%20latest(lpar_pool_vp_usage_PCT)%20as%20latest_lpar_pool_vp_usage_percent%2C%20latest(PoolID)%20as%20Pool_id%20by%20frameID%2Chost%0A%7C%20where%20(latest_lpar_pool_vp_usage_percent&gt;%3D90)%20AND%20(duration%20&gt;%3D%20300)%0A%7C%20dedup%20frameID%2C%20Pool_id%0A%7C%20eval%20&quot;duration%20(hh%3Amm%3Ass)&quot;%3Dtostring(duration%2C&quot;duration&quot;)%0A%7C%20fields%20frameID%2Chost%2C_time%2CPool_id%2Cduration%2C&quot;duration%20(hh%3Amm%3Ass)&quot;%2Clatest_lpar_pool_vp_usage_percent&amp;display.page.search.tab=statistics&amp;display.general.type=statistics&amp;earliest=-24h%40h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +			</html>
    +
    +		</panel>
    +
    +	</row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Howto_MEM_spl.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Howto_MEM_spl.xml
    new file mode 100644
    index 0000000..851ac5c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Howto_MEM_spl.xml
    @@ -0,0 +1,498 @@
    +<form script="panel_resize.js,modal.js" stylesheet="howto.css,ui_simple.css" hideEdit="True" isVisible="true" version="1.1" theme="dark">
    +	<label>HOWTO MEM: Generate stats and charts with Splunk Search Processing Language (SPL)</label>
    +	<description>This collection of request samples will help you generating your own reports, dashboards and alerts for Nmon Performance data using the native Search Processing Language</description>
    +
    +	<row>
    +		<panel>
    +
    +			<html>
    +
    +				<div class="imgheader custom-modal">
    +					<img src="../../static/app/metricator-for-nmon/icons/dark_theme/memory.png" alt="Memory"/>
    +					<h2><a data-modal-name="Help_modal">Physical and virtual Memory Statistics (click here for more information)</a></h2>
    +				</div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/memory.png" alt="Linux"/>
    +                                    <h1>Memory statistics</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <i>Effective fields: Effective statistics will deduce buffers and cached memory, This amount of memory can be freed by the kernel if it is required by the system or programs.</i>
    +                                    <br />
    +                                    <i>Available units: All fields (but total fields) are available in volume (Megabytes) or in percentage.</i>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Physical memory statistics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>memused:</b> Total amount of physical RAM used</li>
    +                                            <li><b>memfree:</b> Total amount of physical RAM left unused by the system</li>
    +                                            <li><b>memtotal:</b> Total amount of physical RAM</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>buffers:</b> The amount of physical RAM, used for file buffers</li>
    +                                            <li><b>cached:</b> The amount of physical RAM, used as cache memory</li>
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>active:</b> The total amount of buffer or page cache memory, that is in active use. This is memory that has been recently used and is usually not reclaimed for other purposes</li>
    +                                            <li><b>inactive:</b> The total amount of buffer or page cache memory, that are free and available. This is memory that has not been recently used and can be reclaimed for other purposes</li>
    +                                        </lu>
    +                                    </div>
    +
    +
    +                                    <br />
    +                                    <br />
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>mem_used_effective:</b> Total amount of physical RAM used, less buffers and cached</li>
    +                                            <li><b>mem_free_effective:</b> Total amount of physical RAM left unused by the system, less buffers and cached</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <h1>Swap memory statistics:</h1>
    +
    +                                    <div class="list" style="display: inline-block">
    +                                        <lu>
    +                                            <li><b>swapfree:</b> The total amount of swap free</li>
    +                                            <li><b>swapused:</b> The total amount of swap used</li>
    +                                            <li><b>swaptotal:</b> The total amount of swap available</li>
    +                                            <li><b>swapcached:</b> The amount of swap, used as cache memory</li>
    +                                        </lu>
    +                                    </div>
    +
    +
    +                                    <div class="list" style="display: inline-block">
    +                                        <lu>
    +                                            <li><b>swap_used_effective:</b> The total amount of swap used, less swap cached</li>
    +                                            <li><b>swap_free_effective:</b> The total amount of swap free, less swap cached</li>
    +                                            <br />
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="bootstrap_title">
    +
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.memory.mem.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20(host%3D*)%20(host%3D*)%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_volume_MB%60" class="tryitbtnxl">mstats volume pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20(host%3D*)%20(host%3D*)%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent_all_metrics%60" class="tryitbtnxl">mstats percentage pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary" class="tryitbtnxl">Data Dictionary »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_baseline?form.osfilter=Linux" class="tryitbtnxl">Baseline Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?form.osfilter=Linux" class="tryitbtnxl">TOP Dashboard »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +			</html>
    +
    +		</panel>
    +
    +		<panel>
    +			<title>Optionally preset host and press Enter:</title>
    +
    +			<input type="text" token="host" searchWhenChanged="true">
    +				<label>Host:</label>
    +				<default>*</default>
    +			</input>
    +
    +		</panel>
    +
    +	</row>
    +
    +	<row>
    +		<panel>
    +			<title>Time oriented and statistics oriented charts:</title>
    +
    +			<html>
    +
    +				<div>
    +					<h2>Time Oriented Charts:</h2>
    +					<br />
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minichart.png" alt="minichart"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Average percentage physical and virtual memory usage over last 24 hours in a line chart by server names (all OS)</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart `nmon_span` dedup_splitvals=t avg(mem_used_effective_PCT) AS mem_used_PCT, avg(swap_used_effective_PCT) AS swap_used_PCT</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent%60%0A%7C%20timechart%20%60nmon_span%60%20dedup_splitvals%3Dt%20avg(mem_used_effective_PCT)%20AS%20mem_used_PCT%2C%20avg(swap_used_effective_PCT)%20AS%20swap_used_PCT&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.chart=line&amp;display.visualizations.charting.axisY.maximumNumber=100&amp;display.visualizations.charting.legend.placement=top&amp;earliest=-24h&amp;latest=now&amp;display.visualizations.charting.axisTitleY.text=%25%20Memory" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Average total/used physical and virtual memory over last 24 hours (all OS)</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| eval memtotal=if(isnum(Real_total_MB), Real_total_MB, memtotal), swaptotal=if(isnum(Virtual_total_MB), Virtual_total_MB, swaptotal)
    +| timechart `nmon_span` useother=f limit=0 avg(mem_used_effective) as mem_used_effective, avg(memtotal) as memtotal, avg(swap_used_effective) as swap_used_effective, avg(swaptotal) as swaptotal by host</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_volume_MB%60%0A%7C%20eval%20memtotal%3Dif(isnum(Real_total_MB)%2C%20Real_total_MB%2C%20memtotal)%2C%20swaptotal%3Dif(isnum(Virtual_total_MB)%2C%20Virtual_total_MB%2C%20swaptotal)%0A%7C%20timechart%20%60nmon_span%60%20useother%3Df%20limit%3D0%20avg(mem_used_effective)%20as%20mem_used_effective%2C%20avg(memtotal)%20as%20memtotal%2C%20avg(swap_used_effective)%20as%20swap_used_effective%2C%20avg(swaptotal)%20as%20swaptotal%20by%20host&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.chart=line&amp;display.visualizations.charting.axisY.maximumNumber=&amp;display.visualizations.charting.legend.placement=top&amp;earliest=-24h&amp;latest=now&amp;display.visualizations.charting.axisTitleY.text=MB" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Linux memory volume report over the last 24 hours (Linux only)</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| timechart `nmon_span` avg(memfree) AS memfree, avg(cached) as cached, avg(buffers) as buffers, avg(mem_used_effective) as mem_used_effective, avg(memtotal) as memtotal</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_linux_metric_filters`%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_volume_MB%60%0A%7C%20timechart%20%60nmon_span%60%20useother%3Df%20limit%3D0%20avg(mem_used_effective)%20as%20mem_used_effective%2C%20avg(memtotal)%20as%20memtotal%2C%20avg(swap_used_effective)%20as%20swap_used_effective%2C%20avg(swaptotal)%20as%20swaptotal%20by%20host&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.chart=line&amp;display.visualizations.charting.axisY.maximumNumber=&amp;display.visualizations.charting.legend.placement=top&amp;earliest=-24h&amp;latest=now&amp;display.visualizations.charting.axisTitleY.text=MB" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +
    +				<div>
    +					<h2>Average percentage physical and virtual memory usage over last 30 days for Working hours Business days only (monday to friday, 08h to 19h)</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ by OStype, host, metric_name span=1m
    +| `Day_BusinessDays_8h-19h`
    +| `def_memory_load_percent`
    +| timechart `nmon_span` dedup_splitvals=t avg(mem_used_effective_PCT) AS mem_used_PCT, avg(swap_used_effective_PCT) AS swap_used_PCT</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60Day_BusinessDays_8h-19h%60%0A%7C%20%60def_memory_load_percent%60%0A%7C%20timechart%20%60nmon_span%60%20dedup_splitvals%3Dt%20avg(mem_used_effective_PCT)%20AS%20mem_used_PCT%2C%20avg(swap_used_effective_PCT)%20AS%20swap_used_PCT&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.chart=line&amp;display.visualizations.charting.axisY.maximumNumber=100&amp;display.visualizations.charting.legend.placement=top&amp;earliest=-30d%40d&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Compare average physical memory usage of yesterday versus today in a line chart (time reference of yesterday)</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ earliest="-1d@d" latest="@d" by OStype, metric_name, host span=1m
    +| `def_memory_load_percent` | timechart `nmon_span` avg(mem_used_effective_PCT) AS yesterday_mem_used_effective_PCT
    +| appendcols [ | mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ earliest="@d" latest="+1d@d" by OStype, metric_name, host span=1m
    +| `def_memory_load_percent` | timechart `nmon_span` avg(mem_used_effective_PCT) AS today_mem_used_effective_PCT | fields - _time ]</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D$host$*%20earliest%3D-1d%40d%20latest%3D%40d%20by%20OStype%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_memory_load_percent%60%20%7C%20timechart%20%60nmon_span%60%20avg(mem_used_effective_PCT)%20AS%20yesterday_mem_used_effective_PCT%0A%7C%20appendcols%20%5B%20%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D$host$%20earliest%3D%40d%20latest%3D%2B1d%40d%20by%20OStype%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_memory_load_percent%60%20%7C%20timechart%20%60nmon_span%60%20avg(mem_used_effective_PCT)%20AS%20today_mem_used_effective_PCT%20%7C%20fields%20-%20_time%20%5D&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.chart=line&amp;display.visualizations.charting.axisY.maximumNumber=100&amp;display.visualizations.charting.legend.placement=top&amp;earliest=%40d&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/single_trend.png" alt="minichart"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Single trend physical memory usage in percentage over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart `nmon_span` avg(mem_used_effective_PCT) AS avg | eval avg=round(avg, 2) | where isnum(avg)</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent%60%0A%7C%20timechart%20%60nmon_span%60%20avg(mem_used_effective_PCT)%20AS%20avg%20%7C%20eval%20avg%3Dround(avg%2C%202)%20%7C%20where%20isnum(avg)&amp;display.page.search.mode=smart&amp;dispatch.sample_ratio=1&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.singlevalue.trendDisplayMode=percent&amp;display.visualizations.singlevalue.useColors=1&amp;display.visualizations.singlevalue.colorBy=trend&amp;display.visualizations.singlevalue.trendColorInterpretation=inverse&amp;display.visualizations.singlevalue.numberPrecision=0.00" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Single trend virtual memory usage in percentage over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart `nmon_span` avg(swap_used_effective_PCT) AS avg | eval avg=round(avg, 2) | where isnum(avg)</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent%60%0A%7C%20timechart%20%60nmon_span%60%20avg(swap_used_effective_PCT)%20AS%20avg%20%7C%20eval%20avg%3Dround(avg%2C%202)%20%7C%20where%20isnum(avg)&amp;display.page.search.mode=smart&amp;dispatch.sample_ratio=1&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.singlevalue.trendDisplayMode=percent&amp;display.visualizations.singlevalue.useColors=1&amp;display.visualizations.singlevalue.colorBy=trend&amp;display.visualizations.singlevalue.trendColorInterpretation=inverse&amp;display.visualizations.singlevalue.numberPrecision=0.00" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Stats oriented Charts:</h2>
    +					<br />
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minigauge.png" alt="minichart"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Gauge chart of average physical memory usage in percentage over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| stats avg(mem_used_effective_PCT) AS avg | eval avg=round(avg, 2)</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent%60%0A%7C%20stats%20avg(mem_used_effective_PCT)%20AS%20avg%20%7C%20eval%20avg%3Dround(avg%2C%202)&amp;earliest=-24h&amp;latest=now&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart=radialGauge&amp;display.page.search.mode=smart&amp;dispatch.sample_ratio=1&amp;display.visualizations.type=charting" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Gauge chart of average virtual memory usage in percentage over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| stats avg(swap_used_effective_PCT) AS avg | eval avg=round(avg, 2)</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent%60%0A%7C%20stats%20avg(swap_used_effective_PCT)%20AS%20avg%20%7C%20eval%20avg%3Dround(avg%2C%202)&amp;earliest=-24h&amp;latest=now&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart=radialGauge&amp;display.page.search.mode=smart&amp;dispatch.sample_ratio=1&amp;display.visualizations.type=charting" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minicolumn.png" alt="minicolumn"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Column chart of TOP 10 average physical memory usage in percentage over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| stats avg(mem_used_effective_PCT) AS avg by host | sort - avg | head 10
    +| eval xlabel=""
    +| chart useother=f limit=0 values(avg) AS "Avg Real Mem %" by xlabel,host | rename xlabel AS "TOP 10 Real Mem % usage"</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent%60%0A%7C%20stats%20avg(mem_used_effective_PCT)%20AS%20avg%20by%20host%20%7C%20sort%20-%20avg%20%7C%20head%2010%0A%7C%20eval%20xlabel%3D&quot;&quot;%0A%7C%20chart%20useother%3Df%20limit%3D0%20values(avg)%20AS%20&quot;Avg%20Real%20Mem%20%25&quot;%20by%20xlabel%2Chost%20%7C%20rename%20xlabel%20AS%20&quot;TOP%2010%20Real%20Mem%20%25%20usage&quot;&amp;earliest=-24h%40h&amp;latest=now&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart=column&amp;display.visualizations.charting.legend.placement=top&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.axisY.maximumNumber=100" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Column chart of TOP 10 average virtual memory usage in percentage over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| stats avg(swap_used_effective_PCT) AS avg by host | sort - avg | head 10
    +| eval xlabel=""
    +| chart useother=f limit=0 values(avg) AS "Avg Virtual Mem %" by xlabel,host | rename xlabel AS "TOP 10 Virtual Mem % usage"</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent%60%0A%7C%20stats%20avg(swap_used_effective_PCT)%20AS%20avg%20by%20host%20%7C%20sort%20-%20avg%20%7C%20head%2010%0A%7C%20eval%20xlabel%3D&quot;&quot;%0A%7C%20chart%20useother%3Df%20limit%3D0%20values(avg)%20AS%20&quot;Avg%20Real%20Mem%20%25&quot;%20by%20xlabel%2Chost%20%7C%20rename%20xlabel%20AS%20&quot;TOP%2010%20Real%20Mem%20%25%20usage&quot;&amp;earliest=-24h%40h&amp;latest=now&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart=column&amp;display.visualizations.charting.legend.placement=top&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.axisY.maximumNumber=100" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +			</html>
    +
    +		</panel>
    +	</row>
    +
    +	<row>
    +		<panel>
    +			<title>Table Statistics:</title>
    +
    +			<html>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minitable.png" alt="minitable"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Average physical and virtual memory usage in percentage over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| stats avg(mem_used_effective_PCT) as mem_used_effective_PCT, avg(swap_used_effective_PCT) as swap_used_effective_PCT, sparkline(avg(mem_used_effective_PCT),) As sparkline_mem_used_effective_PCT, sparkline(avg(swap_used_effective_PCT),) As sparkline_swap_used_effective_PCT by host
    +| eval mem_used_effective_PCT=round(mem_used_effective_PCT, 2), swap_used_effective_PCT=round(swap_used_effective_PCT, 2)</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20`def_memory_all_os_metric_filters`%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent%60%0A%7C%20stats%20avg(mem_used_effective_PCT)%20as%20mem_used_effective_PCT%2C%20avg(swap_used_effective_PCT)%20as%20swap_used_effective_PCT%2C%20sparkline(avg(mem_used_effective_PCT)%2C)%20As%20sparkline_mem_used_effective_PCT%2C%20sparkline(avg(swap_used_effective_PCT)%2C)%20As%20sparkline_swap_used_effective_PCT%20by%20host%0A%7C%20eval%20mem_used_effective_PCT%3Dround(mem_used_effective_PCT%2C%202)%2C%20swap_used_effective_PCT%3Dround(swap_used_effective_PCT%2C%202)&amp;display.page.search.tab=statistics&amp;display.general.type=statistics&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Linux average percentage memory report over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` OStype=Linux host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_percentage_linux_report`</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20%60def_memory_linux_metric_filters%60%20OStype%3DLinux%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_percentage_linux_report%60&amp;display.page.search.tab=statistics&amp;display.general.type=statistics&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Linux average volume memory report over last 24 hours</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` OStype=Linux host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_linux_report`</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20%60def_memory_linux_metric_filters%60%20OStype%3DLinux%20host%3D$host$%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_volume_linux_report%60&amp;display.page.search.tab=statistics&amp;display.general.type=statistics&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +			</html>
    +
    +		</panel>
    +	</row>
    +
    +	<row>
    +		<panel>
    +			<title>Alerting:</title>
    +
    +			<html>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minisingle.png" alt="minisingle"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Find servers having an average physical memory usage higher than 90% for a minimal contiguous period of 5 minutes</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.mem.Real_total_MB OR metric_name=os.unix.nmon.memory.mem.Real_free_MB OR metric_name=os.unix.nmon.memory.mem.memtotal OR metric_name=os.unix.nmon.memory.mem.buffers OR metric_name=os.unix.nmon.memory.mem.cached OR metric_name=os.unix.nmon.memory.mem.memfree host="$host$" by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| fields _time, host,mem_used_effective_PCT
    +| where mem_used_effective_PCT&gt;90
    +| stats latest(_time) as _time range(_time) as duration latest(mem_used_effective_PCT) as latest_mem_used_effective_PCT by host
    +| where (latest_mem_used_effective_PCT>=90) AND (duration &gt;= 300)
    +| eval "duration (hh:mm:ss)"=tostring(duration,"duration")
    +| fields frameID,host,_time,duration,"duration (hh:mm:ss)",latest_mem_used_effective_PCT</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.Real_total_MB%20OR%20metric_name%3Dos.unix.nmon.memory.mem.Real_free_MB%20OR%20metric_name%3Dos.unix.nmon.memory.mem.memtotal%20OR%20metric_name%3Dos.unix.nmon.memory.mem.buffers%20OR%20metric_name%3Dos.unix.nmon.memory.mem.cached%20OR%20metric_name%3Dos.unix.nmon.memory.mem.memfree%20host%3D&quot;$host$&quot;%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent%60%0A%7C%20fields%20_time%2C%20host%2Cmem_used_effective_PCT%0A%7C%20where%20mem_used_effective_PCT&gt;90%0A%7C%20stats%20latest(_time)%20as%20_time%20range(_time)%20as%20duration%20latest(mem_used_effective_PCT)%20as%20latest_mem_used_effective_PCT%20by%20host%0A%7C%20where%20(latest_mem_used_effective_PCT&gt;%3D90)%20AND%20(duration%20&gt;%3D%20300)%0A%7C%20eval%20&quot;duration%20(hh%3Amm%3Ass)&quot;%3Dtostring(duration%2C&quot;duration&quot;)%0A%7C%20fields%20host%2C_time%2Cduration%2C&quot;duration%20(hh%3Amm%3Ass)&quot;%2Clatest_mem_used_effective_PCT&amp;display.page.search.tab=statistics&amp;display.general.type=statistics&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Find servers having an average physical usage higher than 90% for a minimal contiguous period of 5 minutes, restricted to Open hours and Business days (monday to friday, 08h to 19h)</h2>
    +					<pre>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.mem.Real_total_MB OR metric_name=os.unix.nmon.memory.mem.Real_free_MB OR metric_name=os.unix.nmon.memory.mem.memtotal OR metric_name=os.unix.nmon.memory.mem.buffers OR metric_name=os.unix.nmon.memory.mem.cached OR metric_name=os.unix.nmon.memory.mem.memfree host="$host$" by OStype, host, metric_name span=1m
    +| `Day_BusinessDays_8h-19h`
    +| `def_memory_load_percent`
    +| fields _time, host,mem_used_effective_PCT
    +| where mem_used_effective_PCT&gt;90
    +| stats latest(_time) as _time range(_time) as duration latest(mem_used_effective_PCT) as latest_mem_used_effective_PCT by host
    +| where (latest_mem_used_effective_PCT>=90) AND (duration &gt;= 300)
    +| eval "duration (hh:mm:ss)"=tostring(duration,"duration")
    +| fields frameID,host,_time,duration,"duration (hh:mm:ss)",latest_mem_used_effective_PCT</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.Real_total_MB%20OR%20metric_name%3Dos.unix.nmon.memory.mem.Real_free_MB%20OR%20metric_name%3Dos.unix.nmon.memory.mem.memtotal%20OR%20metric_name%3Dos.unix.nmon.memory.mem.buffers%20OR%20metric_name%3Dos.unix.nmon.memory.mem.cached%20OR%20metric_name%3Dos.unix.nmon.memory.mem.memfree%20host%3D&quot;$host$&quot;%20by%20OStype%20%2Chost%2C%20metric_name%20span%3D1m%0A%7C%20%60Day_BusinessDays_8h-19h%60%0A%7C%20%60def_memory_load_percent%60%0A%7C%20fields%20_time%2C%20host%2Cmem_used_effective_PCT%0A%7C%20where%20mem_used_effective_PCT&gt;90%0A%7C%20stats%20latest(_time)%20as%20_time%20range(_time)%20as%20duration%20latest(mem_used_effective_PCT)%20as%20latest_mem_used_effective_PCT%20by%20host%0A%7C%20where%20(latest_mem_used_effective_PCT&gt;%3D90)%20AND%20(duration%20&gt;%3D%20300)%0A%7C%20eval%20&quot;duration%20(hh%3Amm%3Ass)&quot;%3Dtostring(duration%2C&quot;duration&quot;)%0A%7C%20fields%20host%2C_time%2Cduration%2C&quot;duration%20(hh%3Amm%3Ass)&quot;%2Clatest_mem_used_effective_PCT&amp;display.page.search.tab=statistics&amp;display.general.type=statistics&amp;earliest=-24h&amp;latest=now" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +			</html>
    +
    +		</panel>
    +
    +	</row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Howto_TOP_spl.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Howto_TOP_spl.xml
    new file mode 100644
    index 0000000..8726ad5
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Howto_TOP_spl.xml
    @@ -0,0 +1,287 @@
    +<form stylesheet="howto.css,ui_simple.css" script="modal.js" hideEdit="True" isVisible="true" version="1.1" theme="dark">
    +	<label>HOWTO TOP: Generate stats and charts with Splunk Search Processing Language (SPL)</label>
    +	<description>This collection of request samples will help you generating your own reports, dashboards and alerts for Nmon Performance data using the native Search Processing Language</description>
    +
    +	<row>
    +		<panel>
    +
    +			<html>
    +
    +				<div class="imgheader custom-modal">
    +					<img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="Process"/>
    +					<h2><a data-modal-name="Help_modal">Process Resources Usage Statistics (click here for more information)</a></h2>
    +				</div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="CPU"/>
    +                                    <h1>Processes statistics (metric_name=os.unix.nmon.processes.top.*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div>
    +                                    The TOP monitor captures processes statistics for system resources metrics such as CPU, memory and more.
    +                                    <br />
    +                                    This section is available in any supported operating systems, but some metrics are specifics for some systems.
    +                                    <br />
    +                                    The <b>UARG monitor</b> is associated with the TOP monitor as it will capture the full list of processes arguments.
    +                                    <br />
    +                                    <br />
    +                                    Processes statistics are generated at the PID level for a given "Command" invocation, as such, calculation will aggregate statistics of all PIDs for that given Command.
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>raw metrics and dimensions:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>dimension_Command:</b> The name of the global command that generated the process</li>
    +                                            <li><b>dimension_PID:</b> The PID number of the process</li>
    +                                            <li><b>pct_CPU:</b> (%) average amount of CPU used by this process</li>
    +                                            <li><b>pct_Usr:</b> (%) average amount of user-mode CPU used by this process</li>
    +                                            <li><b>pct_Sys:</b> (%) average amount of kernel-mode CPU used by this process</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Size:</b> The size of the pages in kilobytes.</li>
    +                                            <li><b>ResSet:</b> The sum of real-memory data used by the process</li>
    +                                            <li><b>ResText:</b> The real-memory text size of the process.</li>
    +                                            <li><b>ResData:</b> The real-memory data size of the process.</li>
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.processes.top.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20dimension_Command%3D*%20dimension_PID%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20sum(_value)%20as%20pct_CPU%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.pct_CPU%20host%3D*%20dimension_Command%3D*%20by%20dimension_Command%20span%3D1m%0A%7C%20eval%20usage_per_core%3D(pct_CPU%2F100)%0A%7C%20timechart%20%60nmon_span%60%20useother%3Df%20limit%3D50%20max(usage_per_core)%20as%20usage_per_core%20by%20dimension_Command" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_TOP_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=PROCESSES%20STATISTICS" class="tryitbtnxl">Processes Data Dictionary »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?form.osfilter=Linux" class="tryitbtnxl">Bubblechart dashboard »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +			</html>
    +
    +		</panel>
    +
    +		<panel>
    +			<title>Optionally preset host, Command and press Enter:</title>
    +
    +			<input type="text" token="host" searchWhenChanged="true">
    +				<label>Host:</label>
    +				<default>*</default>
    +			</input>
    +
    +			<input type="text" token="Command" searchWhenChanged="true">
    +				<label>Command:</label>
    +				<default>*</default>
    +			</input>
    +
    +		</panel>
    +
    +	</row>
    +
    +	<row>
    +		<panel>
    +			<title>Time oriented and statistics oriented charts:</title>
    +
    +			<html>
    +
    +				<div>
    +					<h2>Time Oriented Charts:</h2>
    +					<br />
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minichart.png" alt="minichart"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>By Server / Program Analysis: Core CPU usage of main processes</h2>
    +					<pre>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.pct_CPU host=$host$ (dimension_Command=$Command$) (dimension_PID=*) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| where (usage_per_core>0)
    +| eval key=host . ":" . dimension_Command
    +| timechart `nmon_span` limit=50 useother=f max(usage_per_core) as cpu_usage_per_core by key</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20max(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.pct_CPU%20host%3D$host$%20(dimension_Command%3D$Command$)%20(dimension_PID%3D*)%20by%20host%20dimension_Command%20dimension_PID%20span%3D1m%0A%7C%20stats%20sum(value)%20as%20pct_CPU%20by%20_time%2C%20host%2C%20dimension_Command%0A%7C%20eval%20usage_per_core%3D(pct_CPU%2F100)%0A%7C%20where%20(usage_per_core>0)%0A%7C%20eval%20key%3Dhost%20.%20&quot;%3A&quot;%20.%20dimension_Command%0A%7C%20timechart%20%60nmon_span%60%20limit%3D50%20useother%3Df%20max(usage_per_core)%20as%20cpu_usage_per_core%20by%20key&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.chart=area&amp;display.visualizations.charting.axisY.maximumNumber=&amp;display.visualizations.charting.legend.placement=top&amp;earliest=-24h&amp;latest=now&amp;display.visualizations.charting.chart.stackMode=stacked&amp;display.visualizations.charting.axisTitleY.text=Logical%20Core%20CPU%20usage" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>By Server / Program Analysis: Core memory usage of main processes</h2>
    +					<pre>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData host=$host$ dimension_Command=$Command$ by OStype, host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, OStype, host, metric_name, dimension_Command
    +| `extract_metrics`
    +| eval {metric}=value
    +| stats values(ResSet) as ResSet, values(ResText) as ResText, values(ResData) as ResData by _time, OStype, host, dimension_Command
    +| fillnull value=0 ResSet ResText ResData
    +| eval mem_usage_mb=case(match(OStype, "Linux"), ((ResSet)/1024), match(OStype, "AIX"), ((ResData+ResText)/1024), match(OStype, "Solaris"), (ResSize/1024) )
    +| timechart `nmon_span` limit=10 useother=f max(mem_usage_mb) AS mem_usage_mb by dimension_Command</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20max(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.ResSet%20OR%20metric_name%3Dos.unix.nmon.processes.top.ResText%20OR%20metric_name%3Dos.unix.nmon.processes.top.ResData%20host%3D$host$%20dimension_Command%3D$Command$%20by%20OStype%2C%20host%2C%20metric_name%2C%20dimension_Command%2C%20dimension_PID%20span%3D1m%0A%7C%20stats%20sum(value)%20as%20value%20by%20_time%2C%20OStype%2C%20host%2C%20metric_name%2C%20dimension_Command%0A%7C%20%60extract_metrics%60%0A%7C%20eval%20%7Bmetric%7D%3Dvalue%0A%7C%20stats%20values(ResSet)%20as%20ResSet%2C%20values(ResText)%20as%20ResText%2C%20values(ResData)%20as%20ResData%20by%20_time%2C%20OStype%2C%20host%2C%20dimension_Command%0A%7C%20fillnull%20value%3D0%20ResSet%20ResText%20ResData%0A%7C%20eval%20mem_usage_mb%3Dcase(match(OStype%2C%20&quot;Linux&quot;)%2C%20((ResSet)%2F1024)%2C%20match(OStype%2C%20&quot;AIX&quot;)%2C%20((ResData%2BResText)%2F1024)%2C%20match(OStype%2C%20&quot;Solaris&quot;)%2C%20(ResSize%2F1024)%20)%0A%7C%20timechart%20%60nmon_span%60%20limit%3D10%20useother%3Df%20max(mem_usage_mb)%20AS%20mem_usage_mb%20by%20dimension_Command&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.axisY.minimumNumber=0&amp;display.visualizations.charting.chart=area&amp;display.visualizations.charting.axisY.maximumNumber=&amp;display.visualizations.charting.legend.placement=top&amp;earliest=-24h&amp;latest=now&amp;display.visualizations.charting.chart.stackMode=stacked&amp;display.visualizations.charting.axisTitleY.text=Logical%20Core%20CPU%20usage" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div style="text-align: left;">
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minicolumn.png" alt="minicolumn"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Column chart of TOP 20 average CPU usage in percentage over last 24 hours</h2>
    +					<pre>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.pct_CPU host=$host$ (dimension_Command=$Command$) (dimension_PID=*) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| eval xlabel=""
    +| chart useother=f limit=20 avg(usage_per_core) as usage_per_core by xlabel, dimension_Command | rename xlabel AS "TOP 10 CPU % usage"</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20max(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.pct_CPU%20host%3D$host$%20(dimension_Command%3D$Command$)%20(dimension_PID%3D*)%20by%20host%20dimension_Command%20dimension_PID%20span%3D1m%0A%7C%20stats%20sum(value)%20as%20pct_CPU%20by%20_time%2C%20dimension_Command%0A%7C%20eval%20usage_per_core%3D(pct_CPU%2F100)%0A%7C%20eval%20xlabel%3D&quot;&quot;%0A%7C%20chart%20useother%3Df%20limit%3D20%20avg(usage_per_core)%20as%20usage_per_core%20by%20xlabel%2C%20dimension_Command%20%7C%20rename%20xlabel%20AS%20&quot;TOP%2010%20CPU%20%25%20usage&quot;&amp;earliest=-24h&amp;latest=now&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Column chart of TOP 20 average memory usage MB over last 24 hours</h2>
    +					<pre>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData host=$host$ dimension_Command=$Command$ by OStype, host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, metric_name, OStype, host, dimension_Command
    +| `extract_metrics`
    +| eval {metric}=value
    +| stats values(ResSet) as ResSet, values(ResText) as ResText, values(ResData) as ResData by _time, OStype, host, dimension_Command
    +| fillnull value=0 ResSet ResText ResData
    +| eval mem_usage_mb=case(match(OStype, "Linux"), ((ResSet)/1024), match(OStype, "AIX"), ((ResData+ResText)/1024), match(OStype, "Solaris"), (ResSize/1024) )
    +| eval xlabel=""
    +| chart useother=f limit=0 avg(mem_usage_mb) as mem_usage_mb by xlabel,dimension_Command | rename xlabel AS "TOP 10 memory MB usage"</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20max(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.ResSet%20OR%20metric_name%3Dos.unix.nmon.processes.top.ResText%20OR%20metric_name%3Dos.unix.nmon.processes.top.ResData%20host%3D$host$%20dimension_Command%3D$Command$%20by%20OStype%2C%20host%2C%20metric_name%2C%20dimension_Command%2C%20dimension_PID%20span%3D1m%0A%7C%20stats%20sum(value)%20as%20value%20by%20_time%2C%20metric_name%2C%20OStype%2C%20host%2C%20dimension_Command%0A%7C%20%60extract_metrics%60%0A%7C%20eval%20%7Bmetric%7D%3Dvalue%0A%7C%20stats%20values(ResSet)%20as%20ResSet%2C%20values(ResText)%20as%20ResText%2C%20values(ResData)%20as%20ResData%20by%20_time%2C%20OStype%2C%20host%2C%20dimension_Command%0A%7C%20fillnull%20value%3D0%20ResSet%20ResText%20ResData%0A%7C%20eval%20mem_usage_mb%3Dcase(match(OStype%2C%20&quot;Linux&quot;)%2C%20((ResSet)%2F1024)%2C%20match(OStype%2C%20&quot;AIX&quot;)%2C%20((ResData%2BResText)%2F1024)%2C%20match(OStype%2C%20&quot;Solaris&quot;)%2C%20(ResSize%2F1024)%20)%0A%7C%20eval%20xlabel%3D&quot;&quot;%0A%7C%20chart%20useother%3Df%20limit%3D0%20avg(mem_usage_mb)%20as%20mem_usage_mb%20by%20xlabel%2Cdimension_Command%20%7C%20rename%20xlabel%20AS%20&quot;TOP%2010%20memory%20MB%20usage&quot;&amp;earliest=-24h&amp;latest=now&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +			</html>
    +
    +		</panel>
    +	</row>
    +
    +	<row>
    +		<panel>
    +			<title>Table Statistics:</title>
    +
    +			<html>
    +
    +				<div style="text-align: left;">
    +					<br />
    +					<img src="../../static/app/metricator-for-nmon/various/mini/minitable.png" alt="minitable"/>
    +					<br />
    +					<br />
    +				</div>
    +
    +				<div>
    +					<h2>Max / Average CPU Usage in Logical Cores and Global % usage over last 24 hours ordered and sorted by Max Core Usage, frame ID, host</h2>
    +					<pre>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.pct_CPU host=$host$ (dimension_Command=$Command$) (dimension_PID=*) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| where (usage_per_core>0)
    +| stats max(usage_per_core) AS max_usage_per_core, avg(usage_per_core) AS avg_usage_per_core,
    +median(usage_per_core) AS median_usage_per_core, min(usage_per_core) AS min_usage_per_core, sparkline(avg(usage_per_core)) As sparkline by host,dimension_Command
    +| sort - avg_usage_per_core,host
    +| foreach max_* avg_* median_* min_* [ eval &lt;&lt;FIELD&gt;&gt;=round(&lt;&lt;FIELD&gt;&gt;, 2) ]</pre>
    +				</div>
    +
    +				<div>
    +					<div class="cat_title">
    +						<a target="_blank" href="search?q=%7C%20mstats%20max(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.pct_CPU%20host%3D$host$%20(dimension_Command%3D$Command$)%20(dimension_PID%3D*)%20by%20host%20dimension_Command%20dimension_PID%20span%3D1m%0A%7C%20stats%20sum(value)%20as%20pct_CPU%20by%20_time%2C%20host%2C%20dimension_Command%0A%7C%20eval%20usage_per_core%3D(pct_CPU%2F100)%0A%7C%20where%20(usage_per_core&gt;0)%0A%7C%20stats%20max(usage_per_core)%20AS%20max_usage_per_core%2C%20avg(usage_per_core)%20AS%20avg_usage_per_core%2C%0Amedian(usage_per_core)%20AS%20median_usage_per_core%2C%20min(usage_per_core)%20AS%20min_usage_per_core%2C%20sparkline(avg(usage_per_core))%20As%20sparkline%20by%20host%2Cdimension_Command%0A%7C%20sort%20-%20avg_usage_per_core%2Chost%0A%7C%20foreach%20max_*%20avg_*%20median_*%20min_*%20%5B%20eval%20&lt;&lt;FIELD&gt;&gt;%3Dround(&lt;&lt;FIELD&gt;&gt;%2C%202)%20%5D&amp;earliest=-24h&amp;latest=now&amp;display.page.search.tab=statistics&amp;display.general.type=statistics" class="tryitbtn-blue">Open in search »
    +						</a>
    +					</div>
    +					<br />
    +				</div>
    +
    +			</html>
    +
    +		</panel>
    +	</row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_ANALYSER_AIX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_ANALYSER_AIX.xml
    new file mode 100644
    index 0000000..6d50ec6
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_ANALYSER_AIX.xml
    @@ -0,0 +1,3250 @@
    +<form stylesheet="ui_simple.css,hide_timeindicator.css,table_data_bar.css,panel_decoration.css" script="autodiscover.js,table_data_bar.js" isVisible="true" version="1.1" theme="dark">
    +    <label>NMON Analyser AIX</label>
    +
    +    <!--
    +    base search for main dropdown populating
    +    -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $osfilter$ host="$host-prefilter$" by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Information panel -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader2">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +
    +                    <h4>Nmon Analyser interfaces have been designed for focused time ranges, very large time ranges may require time to be fully processed</h4>
    +                    <h4>For long time analysis, please consider using metric dedicated interfaces available from App home pages</h4>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Selection panel -->
    +
    +    <row>
    +        <panel>
    +
    +            <input type="time" token="timerange" searchWhenChanged="true">
    +                <label>Time Range:</label>
    +                <default>
    +                    <earliest>-24h</earliest>
    +                    <latest>now</latest>
    +                </default>
    +            </input>
    +
    +            <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +                <label>Filter OS Type:</label>
    +                <default>AIX</default>
    +                <prefix>OStype="</prefix>
    +                <suffix>"</suffix>
    +                <choice value="*">Any OS</choice>
    +                <choice value="AIX">AIX</choice>
    +            </input>
    +
    +            <input id="frameID" type="dropdown" token="frameID" searchWhenChanged="true">
    +                <label>Frame IDs:</label>
    +                <search base="populate">
    +                    <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +                </search>
    +                <choice value="*">Any</choice>
    +                <initialValue>*</initialValue>
    +                <fieldForLabel>frameID</fieldForLabel>
    +                <fieldForValue>frameID</fieldForValue>
    +                <prefix>frameID="</prefix>
    +                <suffix>"</suffix>
    +            </input>
    +
    +            <input type="text" token="host-prefilter" searchWhenChanged="true">
    +                <label>Optional: Filter hosts populating</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input id="host" type="dropdown" token="host" searchWhenChanged="true">
    +                <label>Host:</label>
    +                <search base="populate">
    +                    <query>search $frameID$ | stats count by host | dedup host | sort 0 host</query>
    +                </search>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +                <prefix>host="</prefix>
    +                <suffix>"</suffix>
    +            </input>
    +
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- DF_STORAGE data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.Use_pct" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <set token="start_jfs_storage_search">true</set>
    +                    <set token="storage_usage_datasource">JFSFILE</set>
    +                    <set token="storage_inodes_usage_datasource">JFSINODE</set>
    +                    <unset token="start_df_storage_search"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_df_storage_search">true</set>
    +                    <set token="storage_usage_datasource">DF_STORAGE</set>
    +                    <set token="storage_inodes_usage_datasource">DF_INODES</set>
    +                    <unset token="start_jfs_storage_search"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- Configuration Search uses the nmon_inventory data over the report -->
    +
    +    <search ref="NMON Inventory AIX" id="configSearch">
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <title>SYSTEM SUMMARY OVERVIEW</title>
    +
    +            <table rejects="$show_null_config$">
    +                <title></title>
    +                <search base="configSearch">
    +                    <query>rename hostname AS host | search $host$
    +| fields AIX_Machine_SerialNumber,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_LEVEL,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs
    +| rename "AIX_*" AS *
    +                    </query>
    +                    <!-- Progress event has access to job properties only -->
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_null_config">True</set>
    +                        </condition>
    +                        <condition>
    +                            <unset token="show_null_config"/>
    +                        </condition>
    +                    </progress>
    +                </search>
    +            </table>
    +            <html depends="$show_null_config$">
    +                <p style="color:blue;margin-left:30px;font-size:14px">SYSTEM SUMMARY OVERVIEW Search returned no results, The nmon inventory data may not be available yet for this host, manually run the Nmon Inventory Generation report or wait for the auto update. (occurs every hour by default)</p>
    +            </html>
    +
    +            <search>
    +                <query>| mcatalog values(metric_name) as metrics where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.*" OR metric_name="os.unix.nmon.cpu.lpar.*"
    +| rename metrics as metric_name
    +| mvexpand metric_name | rex field=metric_name "os\.unix\.nmon\.cpu\.(?&lt;type&gt;\w*)\."
    +| stats count by type
    +| sort - type | head 1
    +| eval datasource=case(match(type, "lpar"), "LPAR (Virtual Processor usage)", match(type, "cpu_all"), "CPU_ALL (Percentage usage)") | stats values(datasource) as datasource</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +                <progress>
    +                    <condition>
    +                        <set token="cpu_data_source">$result.datasource$</set>
    +                    </condition>
    +                </progress>
    +            </search>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label></label>
    +                <default>max</default>
    +                <choice value="max">max</choice>
    +                <choice value="avg">avg</choice>
    +            </input>
    +
    +            <chart>
    +                <title>CPU Usage - $cpu_data_source$</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` $host$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart $span$ $statsmode$(cpu_load_percent) AS cpu_load_percent</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">CPU Usage</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` $host$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart $span$ $statsmode$(cpu_load_percent) AS cpu_load_percent
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +
    +        <panel>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label></label>
    +                <default>max</default>
    +                <choice value="max">max</choice>
    +                <choice value="avg">avg</choice>
    +            </input>
    +
    +            <chart>
    +                <title>I/O Per second</title>
    +                <search>
    +                    <query>| mstats sum(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgxfer" OR metric_name="os.unix.nmon.storage.diskxfer") $host$ by host, metric_name span=1m
    +| eval dgxfer_iops=case(metric_name=="os.unix.nmon.storage.dgxfer", value), diskxfer_iops=case(metric_name=="os.unix.nmon.storage.diskxfer", value)
    +| stats values(dgxfer_iops) as dgxfer_iops, values(diskxfer_iops) as diskxfer_iops by _time, host
    +| eval iops=if(isnum('dgxfer_iops'), 'dgxfer_iops', 'diskxfer_iops')
    +| timechart $span$ $statsmode$(iops) as avg_iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">I/O per Sec</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats sum(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgxfer" OR metric_name="os.unix.nmon.storage.diskxfer") $host$ by host, metric_name span=1m
    +| eval dgxfer_iops=case(metric_name=="os.unix.nmon.storage.dgxfer", value), diskxfer_iops=case(metric_name=="os.unix.nmon.storage.diskxfer", value)
    +| stats values(dgxfer_iops) as dgxfer_iops, values(diskxfer_iops) as diskxfer_iops by _time, host
    +| eval iops=if(isnum('dgxfer_iops'), 'dgxfer_iops', 'diskxfer_iops')
    +| timechart $span$ $statsmode$(iops) as avg_iops
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>CPU statistics</title>
    +        </panel>
    +    </row>
    +
    +    <search id="CPU_ALL">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT) $host$ by metric_name, host span=1m
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent by _time, host
    +| fillnull value=0 Sys_percent,User_percent,Wait_percent
    +| eval cpu_load_percent=(Sys_percent+User_percent+Wait_percent)
    +| timechart $span$
    +avg(Idle_percent) AS "Idle %",
    +avg(Sys_percent) AS "Sys %",
    +avg(User_percent) AS "User %",
    +avg(Wait_percent) AS "Wait %",
    +avg(cpu_load_percent) as "CPU %"</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- POOLS data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.pools.*" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_pools_search"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_pools_search">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="cpu_linkinput">
    +                <label></label>
    +                <choice value="cpu_chart1">CPU_ALL, % by category</choice>
    +                <choice value="cpu_chart2">CPU_ALL, % global usage</choice>
    +                <choice value="cpu_chart3">CPUnn, % global usage by processor</choice>
    +                <choice value="cpu_chart4">LPAR, Virtual CPU usage</choice>
    +                <choice value="cpu_chart5">LPAR, Pools Virtual CPU usage</choice>
    +                <default>cpu_chart1</default>
    +                <change>
    +                    <condition value="cpu_chart1">
    +                        <set token="cpu_chart1">true</set>
    +                        <unset token="cpu_chart2"></unset>
    +                        <unset token="cpu_chart3"></unset>
    +                        <unset token="cpu_chart4"></unset>
    +                        <unset token="cpu_chart5"></unset>
    +                    </condition>
    +                    <condition value="cpu_chart2">
    +                        <set token="cpu_chart2">true</set>
    +                        <unset token="cpu_chart1"></unset>
    +                        <unset token="cpu_chart3"></unset>
    +                        <unset token="cpu_chart4"></unset>
    +                        <unset token="cpu_chart5"></unset>
    +                    </condition>
    +                    <condition value="cpu_chart3">
    +                        <set token="cpu_chart3">true</set>
    +                        <unset token="cpu_chart1"></unset>
    +                        <unset token="cpu_chart2"></unset>
    +                        <unset token="cpu_chart4"></unset>
    +                        <unset token="cpu_chart5"></unset>
    +                    </condition>
    +                    <condition value="cpu_chart4">
    +                        <set token="cpu_chart4">true</set>
    +                        <unset token="cpu_chart1"></unset>
    +                        <unset token="cpu_chart2"></unset>
    +                        <unset token="cpu_chart3"></unset>
    +                        <unset token="cpu_chart5"></unset>
    +                    </condition>
    +                    <condition value="cpu_chart5">
    +                        <set token="cpu_chart5">true</set>
    +                        <unset token="cpu_chart1"></unset>
    +                        <unset token="cpu_chart2"></unset>
    +                        <unset token="cpu_chart3"></unset>
    +                        <unset token="cpu_chart4"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$cpu_chart1$">
    +                <title></title>
    +                <search base="CPU_ALL">
    +                    <query>fields _time,"Idle %","Sys %","User %","Wait %"</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPUs</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT) $host$ by metric_name, host span=1m
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent by _time, host
    +| eval cpu_load_percent=(Sys_percent%2BUser_percent%2BWait_percent)
    +| timechart $span$ avg(Idle_percent) AS Idle_percent, avg(Sys_percent) AS Sys_percent, avg(User_percent) AS User_percent, avg(Wait_percent) AS Wait_percent, avg(cpu_load_percent) as cpu_load_percent
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$cpu_chart2$">
    +                <title></title>
    +                <search base="CPU_ALL">
    +                    <query>fields _time,"CPU %"</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPUs</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT) $host$ by metric_name, host span=1m
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent by _time, host
    +| eval cpu_load_percent=(Sys_percent%2BUser_percent%2BWait_percent)
    +| timechart $span$ avg(Idle_percent) AS Idle_percent, avg(Sys_percent) AS Sys_percent, avg(User_percent) AS User_percent, avg(Wait_percent) AS Wait_percent, avg(cpu_load_percent) as cpu_load_percent
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$cpu_chart3$">
    +                <title></title>
    +                <search depends="$cpu_chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* $host$ by metric_name span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT by _time, cpu_core
    +| fillnull value=0 Sys_PCT,User_PCT,Wait_PCT
    +| eval cpu_PCT=(Sys_PCT+User_PCT+Wait_PCT)
    +| timechart $span$ useother=f limit=0 avg(cpu_PCT) AS cpu_PCT by cpu_core</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% of CPU utilization</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* $host$ by metric_name span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT by _time, cpu_core | fillnull value=0
    +| eval cpu_PCT=(Sys_PCT%2BUser_PCT%2BWait_PCT)
    +| timechart $span$ useother=f limit=0 avg(cpu_PCT) AS cpu_PCT by cpu_core
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$cpu_chart4$">
    +                <title></title>
    +                <search depends="$cpu_chart4$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.VP_User_PCT" OR metric_name="os.unix.nmon.cpu.lpar.VP_Sys_PCT" OR metric_name="os.unix.nmon.cpu.lpar.VP_Wait_PCT" OR metric_name="os.unix.nmon.cpu.lpar.VP_Idle_PCT" OR metric_name="os.unix.nmon.cpu.lpar.PhysicalCPU" OR metric_name="os.unix.nmon.cpu.lpar.entitled" OR metric_name="os.unix.nmon.cpu.lpar.virtualCPUs") $host$ by metric_name, OStype, host span=1m
    +| `def_lpar_load_cores`
    +| timechart $span$ avg(lpar_load_cores) AS "cpu load cores", max(entitled) as entitled, max(virtualCPUs) as virtualCPUs</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Virtual CPUs</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.VP_User_PCT" OR metric_name="os.unix.nmon.cpu.lpar.VP_Sys_PCT" OR metric_name="os.unix.nmon.cpu.lpar.VP_Wait_PCT" OR metric_name="os.unix.nmon.cpu.lpar.VP_Idle_PCT" OR metric_name="os.unix.nmon.cpu.lpar.PhysicalCPU" OR metric_name="os.unix.nmon.cpu.lpar.entitled" OR metric_name="os.unix.nmon.cpu.lpar.virtualCPUs") $host$ by metric_name, OStype, host span=1m
    +| `def_lpar_load_cores`
    +| timechart $span$ avg(lpar_load_cores) AS "cpu load cores", max(entitled) as entitled, max(virtualCPUs) as virtualCPUs
    +                    ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$cpu_chart5$">
    +                <title></title>
    +                <search depends="$cpu_chart5$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.poolCPUs" OR metric_name="os.unix.nmon.cpu.lpar.Pool_id" OR metric_name="os.unix.nmon.cpu.lpar.PoolIdle") $host$ by metric_name, OStype, host span=1m
    +| `def_lpar_pool_load_aix_cores`
    +| timechart $span$ avg(lpar_pool_usage) as lpar_pool_usage max(poolCPUs) AS poolCPUs</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Virtual CPUs</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.poolCPUs" OR metric_name="os.unix.nmon.cpu.lpar.Pool_id" OR metric_name="os.unix.nmon.cpu.lpar.PoolIdle") $host$ by metric_name, OStype, host span=1m
    +| `def_lpar_pool_load_aix_cores`
    +| timechart $span$ avg(lpar_pool_usage) as lpar_pool_usage max(poolCPUs) AS poolCPUs
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row depends="$start_pools_search$">
    +        <panel>
    +
    +            <input type="link" token="pools_linkinput">
    +                <label></label>
    +                <choice value="pools_chart1">POOLS, Pools extended statistics</choice>
    +                <default>pools_chart1</default>
    +                <change>
    +                    <condition value="pools_chart1">
    +                        <set token="pools_chart1">true</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$pools_chart1$">
    +                <title></title>
    +                <search depends="$start_pools_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.pools.*" $host$ by metric_name span=1m
    +| `extract_metrics("max_pool_capacity entitled_pool_capacity pool_busy_time")`
    +| stats values(max_pool_capacity) as max_pool_capacity, values(entitled_pool_capacity) as entitled_pool_capacity, values(pool_busy_time) as pool_busy_time by _time
    +| timechart $span$ max(max_pool_capacity) as max_pool_capacity, max(entitled_pool_capacity) as entitled_pool_capacity, avg(pool_busy_time) as pool_busy_time</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Virtual CPUs</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.pools.*" $host$ by metric_name span=1m
    +| `extract_metrics("max_pool_capacity entitled_pool_capacity pool_busy_time")`
    +| stats values(max_pool_capacity) as max_pool_capacity, values(entitled_pool_capacity) as entitled_pool_capacity, values(pool_busy_time) as pool_busy_time by _time
    +| timechart $span$ max(max_pool_capacity) as max_pool_capacity, max(entitled_pool_capacity) as entitled_pool_capacity, avg(pool_busy_time) as pool_busy_time
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +
    +    <row>
    +        <panel id="process">
    +            <title>Process, Kernel, I/O Statistics</title>
    +        </panel>
    +    </row>
    +
    +    <!-- TOP data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_top_search"></unset>
    +                    <set token="show_null_top"></set>
    +            </condition>
    +            <condition>
    +                    <set token="start_top_search">true</set>
    +                    <unset token="show_null_top"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="top_linkinput">
    +                <label></label>
    +                <choice value="top_chart1">TOP, CPU Usage per logical core</choice>
    +                <choice value="top_chart2">TOP: Memory Usage per command invocation</choice>
    +                <choice value="top_chart3">TOP: Read / Write System Calls</choice>
    +                <choice value="top_chart4">TOP: Paging, Sum of page faults</choice>
    +                <choice value="top_chart5">TOP: Threads per Command invocation</choice>
    +                <default>top_chart1</default>
    +                <change>
    +                    <condition value="top_chart1">
    +                        <set token="top_chart1">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                    </condition>
    +                    <condition value="top_chart2">
    +                        <set token="top_chart2">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                    </condition>
    +                    <condition value="top_chart3">
    +                        <set token="top_chart3">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                    </condition>
    +                    <condition value="top_chart4">
    +                        <set token="top_chart4">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart5"></unset>
    +                    </condition>
    +                    <condition value="top_chart5">
    +                        <set token="top_chart5">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$top_chart1$ $start_top_search$">
    +                <title></title>
    +                <search depends="$top_chart1$ $start_top_search$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" $host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| appendcols [ | mstats latest(_value) as logical_cpus where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $host$ by host ]
    +| appendcols [ | mstats latest(_value) as virtual_cpus where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.virtual_cpus" $host$ by host ]
    +| filldown logical_cpus, virtual_cpus
    +| stats values(pct_CPU) as pct_CPU, values(logical_cpus) as logical_cpus, values(virtual_cpus) as virtual_cpus by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100), smt_threads=(logical_cpus/virtual_cpus)
    +| eval usage_per_core=case(isnum(smt_threads) AND smt_threads>="2", usage_per_core*1.2, isnum(smt_threads) AND smt_threads>="4", usage_per_core*1.4, isnum(usage_per_core), usage_per_core)
    +| timechart span=4m useother=f limit="20" max(usage_per_core) as "CPU Usage per core" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Logical Core</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" dimension_Command="$click.name2$" $host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| appendcols [ | mstats latest(_value) as logical_cpus where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $host$ by host ]
    +| appendcols [ | mstats latest(_value) as virtual_cpus where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.virtual_cpus" $host$ by host ]
    +| filldown logical_cpus, virtual_cpus
    +| stats values(pct_CPU) as pct_CPU, values(logical_cpus) as logical_cpus, values(virtual_cpus) as virtual_cpus by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100), smt_threads=(logical_cpus/virtual_cpus)
    +| eval usage_per_core=case(isnum(smt_threads) AND smt_threads>="2", usage_per_core*1.2, isnum(smt_threads) AND smt_threads>="4", usage_per_core*1.4, isnum(usage_per_core), usage_per_core)
    +| timechart span=4m useother=f limit="20" max(usage_per_core) as "CPU Usage per core" by dimension_Command
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart2$ $start_top_search$">
    +                <title></title>
    +                <search depends="$top_chart2$ $start_top_search$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.processes.top.ResText" OR metric_name="os.unix.nmon.processes.top.ResData") $host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, metric_name, host, dimension_Command
    +| `extract_metrics("ResText ResData")`
    +| stats values(ResText) as ResText, values(ResData) as ResData by _time, host, dimension_Command
    +| fillnull value=0 ResText ResData
    +| eval Used_Mem_MB=((ResData+ResText)/1024)
    +| stats sum(Used_Mem_MB) as Used_Mem_MB by _time, host, dimension_Command
    +| timechart $span$ useother=f limit=0 max(Used_Mem_MB) as "Used_Memory" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats sum(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.processes.top.ResText" OR metric_name="os.unix.nmon.processes.top.ResData") dimension_Command="$click.name2$" $host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, metric_name, host, dimension_Command
    +| `extract_metrics("ResText ResData")`
    +| stats values(ResText) as ResText, values(ResData) as ResData by _time, host, dimension_Command
    +| fillnull value=0 ResText ResData
    +| eval Used_Mem_MB=((ResData%2BResText)/1024)
    +| stats sum(Used_Mem_MB) as Used_Mem_MB by _time, host, dimension_Command
    +| timechart $span$ useother=f limit=0 max(Used_Mem_MB) as "Used_Memory" by dimension_Command
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart3$ $start_top_search$">
    +                <title></title>
    +                <search depends="$top_chart3$ $start_top_search$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.CharIO" $host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as CharIO by _time, host, dimension_Command
    +| timechart $span$ useother=f limit=0 avg(CharIO) as "CharIO" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Char I/O</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.CharIO" dimension_Command="$click.name2$" $host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as CharIO by _time, host, dimension_Command
    +| timechart $span$ useother=f limit=0 avg(CharIO) as "CharIO" by dimension_Command
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart4$ $start_top_search$">
    +                <title></title>
    +                <search depends="$top_chart4$ $start_top_search$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Paging" $host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as Paging by _time, host, dimension_Command
    +| timechart $span$ useother=f limit=0 avg(Paging) as "Paging" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Paging" dimension_Command="$click.name2$" $host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as Paging by _time, host, dimension_Command
    +| timechart $span$ useother=f limit=0 avg(Paging) as "Paging" by dimension_Command
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart5$ $start_top_search$">
    +                <title></title>
    +                <search depends="$top_chart5$ $start_top_search$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Threads" $host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as Threads by _time, host, dimension_Command
    +| timechart $span$ useother=f limit=0 avg(Threads) as "Threads" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Threads</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Threads" dimension_Command="$click.name2$" $host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as Threads by _time, host, dimension_Command
    +| timechart $span$ useother=f limit=0 avg(Threads) as "Threads" by dimension_Command
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <html depends="$show_null_top$">
    +                <p style="color:blue;margin-left:30px;font-size:14px">Search returned no results, TOP collection (processes activity) has not been activated or no processes were captured due to lack of activity</p>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="FILE">
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.file.*" $host$ by metric_name span=1m
    +| `extract_metrics("readch writech iget namei dirblk ttycanch ttyoutch ttyrawch")`
    +| stats values(readch) as readch, values(writech) as writech
    +values(iget) as iget, values(namei) as namei, values(dirblk) as dirblk
    +values(ttycanch) as ttycanch, values(ttyoutch) as ttyoutch, values(ttyrawch) as ttyrawch by _time
    +| timechart $span$ max(readch) as readch, max(writech) as writech
    +max(iget) as iget, max(namei) as namei, max(dirblk) as dirblk
    +max(ttycanch) as ttycanch, max(ttyoutch) as ttyoutch, max(ttyrawch) as ttyrawch</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="file_linkinput">
    +                <label></label>
    +                <choice value="file_chart1">FILE, Read/Write system calls</choice>
    +                <choice value="file_chart2">FILE, Various statistics</choice>
    +                <default>file_chart1</default>
    +                <change>
    +                    <condition value="file_chart1">
    +                        <set token="file_chart1">true</set>
    +                        <unset token="file_chart2"></unset>
    +                    </condition>
    +                    <condition value="file_chart2">
    +                        <set token="file_chart2">true</set>
    +                        <unset token="file_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$file_chart1$">
    +                <title></title>
    +                <search base="FILE">
    +                    <query>fields _time,readch,writech</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rate/Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.file.*" $host$ by metric_name span=1m
    +| `extract_metrics("readch writech iget namei dirblk ttycanch ttyoutch ttyrawch")`
    +| stats values(readch) as readch, values(writech) as writech
    +values(iget) as iget, values(namei) as namei, values(dirblk) as dirblk
    +values(ttycanch) as ttycanch, values(ttyoutch) as ttyoutch, values(ttyrawch) as ttyrawch by _time
    +| timechart $span$ max(readch) as readch, max(writech) as writech
    +max(iget) as iget, max(namei) as namei, max(dirblk) as dirblk
    +max(ttycanch) as ttycanch, max(ttyoutch) as ttyoutch, max(ttyrawch) as ttyrawch
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$file_chart2$">
    +                <title></title>
    +                <search base="FILE">
    +                    <query>fields _time,iget,namei,dirblk,ttycanch,ttyoutch,ttyrawch</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rate/Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.file.*" $host$ by metric_name span=1m
    +| `extract_metrics("readch writech iget namei dirblk ttycanch ttyoutch ttyrawch")`
    +| stats values(readch) as readch, values(writech) as writech
    +values(iget) as iget, values(namei) as namei, values(dirblk) as dirblk
    +values(ttycanch) as ttycanch, values(ttyoutch) as ttyoutch, values(ttyrawch) as ttyrawch by _time
    +| timechart $span$ max(readch) as readch, max(writech) as writech
    +max(iget) as iget, max(namei) as namei, max(dirblk) as dirblk
    +max(ttycanch) as ttycanch, max(ttyoutch) as ttyoutch, max(ttyrawch) as ttyrawch
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="PROC">
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.proc.*" $host$ by metric_name span=1m
    +| `extract_metrics("Runnable Swap-in pswitch syscall fork exec")`
    +| stats values(Runnable) AS Runnable values(Swap-in) AS Swap-in, values(pswitch) AS pswitch values(syscall) AS syscall, values(fork) AS fork values(exec) AS exec by _time
    +| timechart $span$ avg(Runnable) AS Runnable, avg(Swap-in) AS Swap-in, avg(pswitch) AS pswitch, avg(syscall) AS syscall, avg(fork) AS fork, avg(exec) AS exec</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="proc_linkinput">
    +                <label></label>
    +                <choice value="proc_chart1">PROC, Kernel Threads in run queue and to be paged (RunQueue, Swap-In)</choice>
    +                <choice value="proc_chart2">PROC, Context switches and system calls (pswitch, syscall)</choice>
    +                <choice value="proc_chart3">PROC, Fork and Exec system calls (fork, exec)</choice>
    +                <default>proc_chart1</default>
    +                <change>
    +                    <condition value="proc_chart1">
    +                        <set token="proc_chart1">true</set>
    +                        <unset token="proc_chart2"></unset>
    +                        <unset token="proc_chart3"></unset>
    +                    </condition>
    +                    <condition value="proc_chart2">
    +                        <set token="proc_chart2">true</set>
    +                        <unset token="proc_chart1"></unset>
    +                        <unset token="proc_chart3"></unset>
    +                    </condition>
    +                    <condition value="proc_chart3">
    +                        <set token="proc_chart3">true</set>
    +                        <unset token="proc_chart1"></unset>
    +                        <unset token="proc_chart2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$proc_chart1$">
    +                <title></title>
    +                <search base="PROC">
    +                    <query>fields _time,Runnable,Swap-in</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Value</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.proc.*" $host$ by metric_name span=1m
    +| `extract_metrics("Runnable Swap-in pswitch syscall fork exec")`
    +| stats values(Runnable) AS Runnable values(Swap-in) AS Swap-in, values(pswitch) AS pswitch values(syscall) AS syscall, values(fork) AS fork values(exec) AS exec by _time
    +| timechart $span$ avg(Runnable) AS Runnable, avg(Swap-in) AS Swap-in, avg(pswitch) AS pswitch, avg(syscall) AS syscall, avg(fork) AS fork, avg(exec) AS exec
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$proc_chart2$">
    +                <title></title>
    +                <search base="PROC">
    +                    <query>fields _time,pswitch,syscall</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rates per Second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.proc.*" $host$ by metric_name span=1m
    +| `extract_metrics("Runnable Swap-in pswitch syscall fork exec")`
    +| stats values(Runnable) AS Runnable values(Swap-in) AS Swap-in, values(pswitch) AS pswitch values(syscall) AS syscall, values(fork) AS fork values(exec) AS exec by _time
    +| timechart $span$ avg(Runnable) AS Runnable, avg(Swap-in) AS Swap-in, avg(pswitch) AS pswitch, avg(syscall) AS syscall, avg(fork) AS fork, avg(exec) AS exec
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$proc_chart3$">
    +                <title></title>
    +                <search base="PROC">
    +                    <query>fields _time,fork,exec</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rates per Second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.proc.*" $host$ by metric_name span=1m
    +| `extract_metrics("Runnable Swap-in pswitch syscall fork exec")`
    +| stats values(Runnable) AS Runnable values(Swap-in) AS Swap-in, values(pswitch) AS pswitch values(syscall) AS syscall, values(fork) AS fork values(exec) AS exec by _time
    +| timechart $span$ avg(Runnable) AS Runnable, avg(Swap-in) AS Swap-in, avg(pswitch) AS pswitch, avg(syscall) AS syscall, avg(fork) AS fork, avg(exec) AS exec
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="PAGE">
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.page.*" $host$ by metric_name span=1m
    +| `extract_metrics("faults pgin pgout pgsin pgsout reclaims scans cycles")`
    +| stats values(pgin) as pgin, values(pgout) as pgout, values(pgsin) as pgsin, values(pgsout) as pgsout, values(reclaims) as reclaims, values(scans) as scans, values(cycles) as cycles by _time
    +| fillnull value=0 scans,reclaims,pgin,pgsin,pgout,pgsout
    +| eval scanfree_ratio=round((scans/reclaims),3), fsin=(pgin+pgsin), fsout=(pgout+pgsout)
    +| timechart $span$
    +avg(faults) AS faults avg(pgin) AS pgin avg(pgout) AS pgout avg(pgsin) AS pgsin
    +avg(pgsout) AS pgsout avg(reclaims) AS reclaims avg(scans) AS scans
    +avg(cycles) AS cycles avg(fsin) AS fsin avg(fsout) AS fsout avg(scanfree_ratio) AS scanfree_ratio</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="page_linkinput">
    +                <label></label>
    +                <choice value="page_chart1">PAGE, Pages In / Pages Out (pgsin / pgsout, pgin / pgout)</choice>
    +                <choice value="page_chart2">PAGE, Fs In / Fs Out (sum of pgin/pgsin and pgout/pgsout per interval)</choice>
    +                <choice value="page_chart3">PAGE, Scan Free Ratio (Pages scans by reclaims per interval)</choice>
    +                <default>page_chart1</default>
    +                <change>
    +                    <condition value="page_chart1">
    +                        <set token="page_chart1">true</set>
    +                        <unset token="page_chart2"></unset>
    +                        <unset token="page_chart3"></unset>
    +                    </condition>
    +                    <condition value="page_chart2">
    +                        <set token="page_chart2">true</set>
    +                        <unset token="page_chart1"></unset>
    +                        <unset token="page_chart3"></unset>
    +                    </condition>
    +                    <condition value="page_chart3">
    +                        <set token="page_chart3">true</set>
    +                        <unset token="page_chart1"></unset>
    +                        <unset token="page_chart2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +            
    +            <chart depends="$page_chart1$">
    +                <title></title>
    +                <search base="PAGE">
    +                    <query>fillnull value=0 pgsin,pgsout,pgin,pgout | fields _time,pgsin,pgsout,pgin,pgout</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.page.*" $host$ by metric_name span=1m
    +| `extract_metrics("faults pgin pgout pgsin pgsout reclaims scans cycles")`
    +| stats values(pgin) as pgin, values(pgout) as pgout, values(pgsin) as pgsin, values(pgsout) as pgsout, values(reclaims) as reclaims, values(scans) as scans, values(cycles) as cycles by _time
    +| eval scanfree_ratio=round((scans/reclaims),3), fsin=(pgin%2Bpgsin), fsout=(pgout%2Bpgsout)
    +| timechart $span$
    +avg(faults) AS faults avg(pgin) AS pgin avg(pgout) AS pgout avg(pgsin) AS pgsin
    +avg(pgsout) AS pgsout avg(reclaims) AS reclaims avg(scans) AS scans
    +avg(cycles) AS cycles avg(fsin) AS fsin avg(fsout) AS fsout avg(scanfree_ratio) AS scanfree_ratio
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +            <chart depends="$page_chart2$">
    +                <title></title>
    +                <search base="PAGE">
    +                    <query>fillnull value=0 fsin,fsout | fields _time,fsin,fsout</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.page.*" $host$ by metric_name span=1m
    +| `extract_metrics("faults pgin pgout pgsin pgsout reclaims scans cycles")`
    +| stats values(pgin) as pgin, values(pgout) as pgout, values(pgsin) as pgsin, values(pgsout) as pgsout, values(reclaims) as reclaims, values(scans) as scans, values(cycles) as cycles by _time
    +| eval scanfree_ratio=round((scans/reclaims),3), fsin=(pgin%2Bpgsin), fsout=(pgout%2Bpgsout)
    +| timechart $span$
    +avg(faults) AS faults avg(pgin) AS pgin avg(pgout) AS pgout avg(pgsin) AS pgsin
    +avg(pgsout) AS pgsout avg(reclaims) AS reclaims avg(scans) AS scans
    +avg(cycles) AS cycles avg(fsin) AS fsin avg(fsout) AS fsout avg(scanfree_ratio) AS scanfree_ratio
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +            <chart depends="$page_chart3$">
    +                <title></title>
    +                <search base="PAGE">
    +                    <query>fillnull value=0 scanfree_ratio | fields _time,scanfree_ratio</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.page.*" $host$ by metric_name span=1m
    +| `extract_metrics("faults pgin pgout pgsin pgsout reclaims scans cycles")`
    +| stats values(pgin) as pgin, values(pgout) as pgout, values(pgsin) as pgsin, values(pgsout) as pgsout, values(reclaims) as reclaims, values(scans) as scans, values(cycles) as cycles by _time
    +| eval scanfree_ratio=round((scans/reclaims),3), fsin=(pgin%2Bpgsin), fsout=(pgout%2Bpgsout)
    +| timechart $span$
    +avg(faults) AS faults avg(pgin) AS pgin avg(pgout) AS pgout avg(pgsin) AS pgsin
    +avg(pgsout) AS pgsout avg(reclaims) AS reclaims avg(scans) AS scans
    +avg(cycles) AS cycles avg(fsin) AS fsin avg(fsout) AS fsout avg(scanfree_ratio) AS scanfree_ratio
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- Workload Manager data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.wlm*" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_wlm_search"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_wlm_search">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <row depends="$start_wlm_search$">
    +        <panel>
    +
    +            <input type="link" token="wlm_linkinput">
    +                <label></label>
    +                <choice value="wlm_chart1">WLMCPU, Workload Manager CPU percent (%)</choice>
    +                <choice value="wlm_chart2">WLMMEM, Workload Manager Memory percent (%)</choice>
    +                <choice value="wlm_chart3">WLMIO, Workload Manager Block I/O percent (%)</choice>
    +                <default>wlm_chart1</default>
    +                <change>
    +                    <condition value="wlm_chart1">
    +                        <set token="wlm_chart1">true</set>
    +                        <unset token="wlm_chart2"></unset>
    +                        <unset token="wlm_chart3"></unset>
    +                    </condition>
    +                    <condition value="wlm_chart2">
    +                        <set token="wlm_chart2">true</set>
    +                        <unset token="wlm_chart1"></unset>
    +                        <unset token="wlm_chart3"></unset>
    +                    </condition>
    +                    <condition value="wlm_chart3">
    +                        <set token="wlm_chart3">true</set>
    +                        <unset token="wlm_chart1"></unset>
    +                        <unset token="wlm_chart2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$wlm_chart1$">
    +                <title></title>
    +                <search depends="$start_wlm_search$ $wlm_chart1$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmcpu $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">CPU percent (%)</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmcpu dimension_device="$click.value2$" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$wlm_chart2$">
    +                <title></title>
    +                <search depends="$start_wlm_search$ $wlm_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmmem $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Memory percent (%)</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmcpu dimension_device="$click.value2$" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$wlm_chart3$">
    +                <title></title>
    +                <search depends="$start_wlm_search$ $wlm_chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmbio $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Block I/O percent (%)</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmio dimension_device="$click.value2$" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +    
    +    <row>
    +        <panel id="memory">
    +            <title>MEMORY Usage Statistics</title>
    +        </panel>
    +    </row>
    +
    +    <search id="MEM">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" $host$ by metric_name span=1m
    +| `extract_metrics("Real_free_MB Real_total_MB Virtual_free_MB Virtual_total_MB")`
    +| stats values(Real_free_MB) as Real_free_MB, values(Real_total_MB) as Real_total_MB, values(Virtual_free_MB) as Virtual_free_MB, values(Virtual_total_MB) as Virtual_total_MB by _time
    +| eval Real_used_MB=(Real_total_MB-Real_free_MB), Virtual_used_MB=(Virtual_total_MB-Virtual_free_MB)
    +| timechart $span$ max(Real_total_MB) AS Real_total_MB max(Real_used_MB) AS Real_used_MB
    +max(Virtual_total_MB) AS Virtual_total_MB max(Virtual_used_MB) AS Virtual_used_MB</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="MEMNEW">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memnew.*" $host$ by metric_name span=1m
    +| `extract_metrics("Free_PCT FScache_PCT memused_PCT Process_PCT System_PCT")`
    +| stats values(Free_PCT) as Free_PCT, values(FScache_PCT) as FScache_PCT, values(Process_PCT) as Process_PCT, values(System_PCT) as System_PCT by _time
    +| fillnull value=0 FScache_PCT,Process_PCT,System_PCT
    +| eval memused_PCT=(FScache_PCT+Process_PCT+System_PCT)
    +| timechart $span$
    +avg(Free_PCT) AS Free_PCT avg(FScache_PCT) AS FScache_PCT avg(memused_PCT) AS memused_PCT
    +avg(Process_PCT) AS Process_PCT avg(System_PCT) AS System_PCT</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="mem_linkinput">
    +                <label></label>
    +                <choice value="mem_chart1">MEM, Real Memory usage</choice>
    +                <choice value="mem_chart2">MEM, Paging Space usage</choice>
    +                <choice value="mem_chart3">MEMNEW, % Memory Allocation by category</choice>
    +                <choice value="mem_chart4">MEMNEW, % Memory Usage</choice>
    +                <choice value="mem_chart5">MEMUSE, Vmtune Statistics</choice>
    +                <default>mem_chart1</default>
    +                <change>
    +                    <condition value="mem_chart1">
    +                        <set token="mem_chart1">true</set>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                    </condition>
    +                    <condition value="mem_chart2">
    +                        <set token="mem_chart2">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                    </condition>
    +                    <condition value="mem_chart3">
    +                        <set token="mem_chart3">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                    </condition>
    +                    <condition value="mem_chart4">
    +                        <set token="mem_chart4">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                    </condition>
    +                    <condition value="mem_chart5">
    +                        <set token="mem_chart5">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$mem_chart1$">
    +                <title></title>
    +                <search base="MEM">
    +                    <query>fields _time,Real_total_MB,Real_used_MB</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" $host$ by metric_name span=1m
    +| `extract_metrics("Real_free_MB Real_total_MB Virtual_free_MB Virtual_total_MB")`
    +| stats values(Real_free_MB) as Real_free_MB, values(Real_total_MB) as Real_total_MB, values(Virtual_free_MB) as Virtual_free_MB, values(Virtual_total_MB) as Virtual_total_MB by _time
    +| eval Real_used_MB=(Real_total_MB-Real_free_MB), Virtual_used_MB=(Virtual_total_MB-Virtual_free_MB)
    +| timechart $span$ max(Real_total_MB) AS Real_total_MB max(Real_used_MB) AS Real_used_MB
    +max(Virtual_total_MB) AS Virtual_total_MB max(Virtual_used_MB) AS Virtual_used_MB
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$mem_chart2$">
    +                <title></title>
    +                <search base="MEM">
    +                    <query>fields _time,Virtual_total_MB,Virtual_used_MB</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" $host$ by metric_name span=1m
    +| `extract_metrics("Real_free_MB Real_total_MB Virtual_free_MB Virtual_total_MB")`
    +| stats values(Real_free_MB) as Real_free_MB, values(Real_total_MB) as Real_total_MB, values(Virtual_free_MB) as Virtual_free_MB, values(Virtual_total_MB) as Virtual_total_MB by _time
    +| eval Real_used_MB=(Real_total_MB-Real_free_MB), Virtual_used_MB=(Virtual_total_MB-Virtual_free_MB)
    +| timechart $span$ max(Real_total_MB) AS Real_total_MB max(Real_used_MB) AS Real_used_MB
    +max(Virtual_total_MB) AS Virtual_total_MB max(Virtual_used_MB) AS Virtual_used_MB
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$mem_chart3$">
    +                <title></title>
    +                <search base="MEMNEW">
    +                    <query>fields _time,Free_PCT,FScache_PCT,Process_PCT,System_PCT</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Percentage (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memnew.*" $host$ by metric_name span=1m
    +| `extract_metrics("Free_PCT FScache_PCT memused_PCT Process_PCT System_PCT")`
    +| stats values(Free_PCT) as Free_PCT, values(FScache_PCT) as FScache_PCT, values(Process_PCT) as Process_PCT, values(System_PCT) as System_PCT by _time
    +| eval memused_PCT=(FScache_PCT%2BProcess_PCT%2BSystem_PCT)
    +| timechart $span$
    +avg(Free_PCT) AS Free_PCT avg(FScache_PCT) AS FScache_PCT avg(memused_PCT) AS memused_PCT
    +avg(Process_PCT) AS Process_PCT avg(System_PCT) AS System_PCT
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$mem_chart4$">
    +                <title></title>
    +                <search base="MEMNEW">
    +                    <query>fields _time,memused_PCT</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Percentage (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memnew.*" $host$ by metric_name span=1m
    +| `extract_metrics("Free_PCT FScache_PCT memused_PCT Process_PCT System_PCT")`
    +| stats values(Free_PCT) as Free_PCT, values(FScache_PCT) as FScache_PCT, values(Process_PCT) as Process_PCT, values(System_PCT) as System_PCT by _time
    +| eval memused_PCT=(FScache_PCT%2BProcess_PCT%2BSystem_PCT)
    +| timechart $span$
    +avg(Free_PCT) AS Free_PCT avg(FScache_PCT) AS FScache_PCT avg(memused_PCT) AS memused_PCT
    +avg(Process_PCT) AS Process_PCT avg(System_PCT) AS System_PCT
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$mem_chart5$">
    +                <title></title>
    +                <search depends="$mem_chart5$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memuse.*" $host$ by metric_name span=1m
    +| `extract_metrics("PCTmaxclient PCTmaxperm PCTminperm PCTnumclient PCTnumperm")`
    +| stats values(PCTmaxclient) as PCTmaxclient, values(PCTmaxperm) as PCTmaxperm, values(PCTminperm) as PCTminperm, values(PCTnumclient) as PCTnumclient, values(PCTnumperm) as PCTnumperm by _time
    +| timechart $span$
    +avg(PCTmaxclient) as PCTmaxclient, avg(PCTmaxperm) as PCTmaxperm, avg(PCTminperm) as PCTminperm, avg(PCTnumclient) as PCTnumclient, avg(PCTnumperm) as PCTnumperm</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Percentage (%)</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memuse.*" $host$ by metric_name span=1m
    +| `extract_metrics("PCTmaxclient PCTmaxperm PCTminperm PCTnumclient PCTnumperm")`
    +| stats values(PCTmaxclient) as PCTmaxclient, values(PCTmaxperm) as PCTmaxperm, values(PCTminperm) as PCTminperm, values(PCTnumclient) as PCTnumclient, values(PCTnumperm) as PCTnumperm by _time
    +| timechart $span$
    +avg(PCTmaxclient) as PCTmaxclient, avg(PCTmaxperm) as PCTmaxperm, avg(PCTminperm) as PCTminperm, avg(PCTnumclient) as PCTnumclient, avg(PCTnumperm) as PCTnumperm
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="disk">
    +            <title>Disks performance statistics (active drill-down: click on one of the charts for dimension devices)</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="disk_linkinput">
    +                <label></label>
    +                <choice value="disk_chart1">DISKBSIZE, Average data transfer size</choice>
    +                <choice value="disk_chart2">DISKBUSY, Disk Busy Activity</choice>
    +                <choice value="disk_chart3">DISKREAD/WRITE, Disk Read/Write Data Rate</choice>
    +                <choice value="disk_chart4">DISKXFER, Disk I/O Operations per second (IOPS)</choice>
    +                <choice value="disk_chart5">DISKREAD/WRITE by XFER, Disk Read/Write I/O Operations per second (IOPS)</choice>
    +                <default>disk_chart1</default>
    +                <change>
    +                    <condition value="disk_chart1">
    +                        <set token="disk_chart1">true</set>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                    </condition>
    +                    <condition value="disk_chart2">
    +                        <set token="disk_chart2">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                    </condition>
    +                    <condition value="disk_chart3">
    +                        <set token="disk_chart3">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                    </condition>
    +                    <condition value="disk_chart4">
    +                        <set token="disk_chart4">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                    </condition>
    +                    <condition value="disk_chart5">
    +                        <set token="disk_chart5">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +
    +            <chart depends="$disk_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbsize" $host$ by dimension_device span=1m
    +| stats sum(value) AS avg_transfer_size by _time
    +| timechart $span$ avg(avg_transfer_size) AS avg_transfer_size</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KBytes per Transfer</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbsize" $host$ by dimension_device span=1m
    +| timechart useother=f limit=0 $span$ avg(value) AS avg_transfer_size by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart2$">
    +                <title></title>
    +                <search depends="$disk_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbusy" $host$ by dimension_device span=1m
    +| stats avg(value) AS value by _time
    +| timechart $span$ avg(value) AS avg_busy_disk</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">% of Time Busy</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbusy" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) AS avg_busy_disk by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart3$">
    +                <title></title>
    +                <search depends="$disk_chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite") $host$ by metric_name, dimension_device span=1m
    +| eval disk_read=case(match(metric_name, "diskread"), value), diskwrite = case(match(metric_name, "diskwrite"), value)
    +| stats avg(disk_read) AS disk_read, avg(disk_write) AS disk_write by _time
    +| timechart $span$ avg(disk_read) AS disk_read, avg(disk_write) AS disk_write</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KBytes/Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite") $host$ by metric_name, dimension_device span=1m
    +| eval disk_read=case(match(metric_name, "diskread"), value), diskwrite = case(match(metric_name, "diskwrite"), value)
    +| timechart $span$ useother=f limit=0 avg(disk_read) AS disk_read, avg(disk_write) AS disk_write by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart4$">
    +                <title></title>
    +                <search depends="$disk_chart4$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" $host$ by dimension_device span=1m
    +| stats sum(value) AS iops by _time
    +| timechart $span$ avg(iops) AS iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">I/O per Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) AS iops by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart5$">
    +                <title></title>
    +                <search depends="$disk_chart5$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite" OR metric_name="os.unix.nmon.storage.diskbsize") $host$ by metric_name, dimension_device span=1m
    +| eval disk_read=case(match(metric_name, "diskread"), value), disk_write=case(match(metric_name, "diskwrite"), value), disk_size=case(match(metric_name, "diskbsize"), value)
    +| stats values(disk_read) as disk_read values(disk_write) as disk_write values(disk_size) as disk_size by _time, dimension_device
    +| eval disk_read_iops=(disk_read/disk_size), disk_write_iops=(disk_write/disk_size)
    +| stats sum(disk_read_iops) as disk_read_iops, sum(disk_write_iops) as disk_write_iops by _time
    +| timechart $span$ avg(disk_read_iops) as disk_read_iops, avg(disk_write_iops) as disk_write_iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">I/O per Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite" OR metric_name="os.unix.nmon.storage.diskbsize") $host$ by metric_name, dimension_device span=1m
    +| eval disk_read=case(match(metric_name, "diskread"), value), disk_write=case(match(metric_name, "diskwrite"), value), disk_size=case(match(metric_name, "diskbsize"), value)
    +| stats values(disk_read) as disk_read values(disk_write) as disk_write values(disk_size) as disk_size by _time, dimension_device
    +| eval disk_read_iops=(disk_read/disk_size), disk_write_iops=(disk_write/disk_size)
    +| stats sum(disk_read_iops) as disk_read_iops, sum(disk_write_iops) as disk_write_iops by _time, dimension_device
    +| timechart $span$ useother=f limit=0 avg(disk_read_iops) as disk_read_iops, avg(disk_write_iops) as disk_write_iops by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="disk2">
    +            <title>File-systems utilization statistics</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="jfs_linkinput">
    +                <label></label>
    +                <choice value="jfs_chart1">Summary of file-systems utilization</choice>
    +                <choice value="jfs_chart2">File-systems utilization over time</choice>
    +                <choice value="jfs_chart3">File-systems inodes utilization over time</choice>
    +                <default>jfs_chart1</default>
    +                <change>
    +                    <condition value="jfs_chart1">
    +                        <set token="jfs_chart1">true</set>
    +                        <unset token="jfs_chart2"></unset>
    +                        <unset token="jfs_chart3"></unset>
    +                    </condition>
    +                    <condition value="jfs_chart2">
    +                        <set token="jfs_chart2">true</set>
    +                        <unset token="jfs_chart1"></unset>
    +                        <unset token="jfs_chart3"></unset>
    +                    </condition>
    +                    <condition value="jfs_chart3">
    +                        <set token="jfs_chart3">true</set>
    +                        <unset token="jfs_chart1"></unset>
    +                        <unset token="jfs_chart2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <!--
    +
    +            ### file systems SUMMARY ###
    +
    +            file systems utilisation, either DF_STORAGE (default) or JFSFILE
    +            -->
    +
    +            <!-- DF_STORAGE -->
    +
    +            <table id="tablebar" depends="$start_df_storage_search$ $jfs_chart1$">
    +                <title>Data source: $storage_usage_datasource$</title>
    +                <search depends="$start_df_storage_search$">
    +                    <query>| mstats latest(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.*" $host$ by host, metric_name, dimension_mount
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)
    +| stats first(Available) as Available, first(Use_pct) as Use_pct, first(Used) as Used, first(blocks) as blocks by host, dimension_mount
    +| rename dimension_mount as mount
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free
    +| foreach storage, storage_free, storage_used [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;'/1024/1024, 2) ]
    +| foreach storage*percent [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]
    +| rename storage as "storage (GB)", storage_free as "storage free (GB)", storage_used as "storage used (GB)", storage_free_percent as "storage free (%)", storage_used_percent as "storage used (%)"
    +| eval UsedPct=if(isnum('storage used (%)'), 'storage used (%)', 0 )
    +| fields mount, "storage (GB)", "storage free (GB)", "storage used (GB)", "storage free (%)", "storage used (%)", UsedPct
    +| appendpipe [ stats sum("storage (GB)") as "storage (GB)", sum("storage free (GB)") as "storage free (GB)", sum("storage used (GB)") as "storage used (GB)" ]
    +| eval "storage free (%)" = if(isnull('storage free (%)'), (('storage free (GB)'/'storage (GB)')*100), 'storage free (%)'), "storage used (%)" = if(isnull('storage used (%)'), (('storage used (GB)'/'storage (GB)')*100), 'storage used (%)'), UsedPct = if(isnull(UsedPct), 'storage used (%)', UsedPct)
    +| fillnull value="*** TOTAL GB / AVERAGE % ****" mount
    +| foreach storage*%* UsedPct [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +
    +            <!-- JFSFILE -->
    +
    +            <table depends="$start_jfs_storage_search$ $jfs_chart1$">
    +                <title>Data source: $storage_usage_datasource$</title>
    +                <search depends="$start_jfs_storage_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsfile" $host$ by host, dimension_mount span=1m
    +| stats max(value) AS max_value, avg(value) AS avg_value, min(value) AS min_value, latest(value) AS UsedPct by dimension_mount
    +| sort limit=0 dimension_mount | rename dimension_mount AS "Mount point"
    +| eval value=round(value,2)
    +| fields "Mount point",max_value, avg_value, min_value, UsedPct | eval avg_value=round(avg_value,2)
    +| rename max_value AS "Max value in period (%)", avg_value AS "Average value in period (%)", min_value AS "Min value in Period (%)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +
    +            <!--
    +
    +            ### file systems utilisation over time ###
    +
    +            file systems utilisation, either DF_STORAGE (default) or JFSFILE
    +            -->
    +
    +            <!-- DF_STORAGE -->
    +
    +            <input type="text" token="df_storage_mount" depends="$start_df_storage_search$ $jfs_chart2$">
    +              <label>mount</label>
    +              <default>*</default>
    +            </input>
    +
    +            <input type="dropdown" token="df_storage_monitor" depends="$start_df_storage_search$ $jfs_chart2$">
    +                <label>Monitor:</label>
    +                <choice value="storage">storage (volume size)</choice>
    +                <choice value="storage_free">storage_free (volume free)</choice>
    +                <choice value="storage_used">storage_used (volume used)</choice>
    +                <choice value="storage_free_percent">storage_free_percent (%)</choice>
    +                <choice value="storage_used_percent">storage_used_percent (%)</choice>
    +                <default>storage_used_percent</default>
    +                <change>
    +                    <condition value="storage">
    +                        <unset token="form.df_storage_monitor_unit"></unset>
    +                        <set token="df_storage_show_unit">true</set>
    +                        <unset token="df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_free">
    +                        <unset token="form.df_storage_monitor_unit"></unset>
    +                        <set token="df_storage_show_unit">true</set>
    +                        <unset token="df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_used">
    +                        <unset token="form.df_storage_monitor_unit"></unset>
    +                        <set token="df_storage_show_unit">true</set>
    +                        <unset token="df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_free_percent">
    +                        <set token="df_storage_unit">%</set>
    +                        <unset token="df_storage_show_unit"></unset>
    +                        <set token="df_storage_monitor_max_chart">101</set>
    +                    </condition>
    +                    <condition value="storage_used_percent">
    +                        <set token="form.df_storage_monitor_unit">pct</set>
    +                        <set token="df_storage_monitor_max_chart">101</set>
    +                        <unset token="df_storage_show_unit"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="df_storage_monitor_unit" depends="$start_df_storage_search$ $df_storage_show_unit$ $jfs_chart2$">
    +                <label>Unit:</label>
    +                <choice value="MB">MB</choice>
    +                <choice value="GB">GB</choice>
    +                <choice value="TB">TB</choice>
    +                <default>GB</default>
    +                <change>
    +                    <condition value="MB">
    +                        <set token="df_storage_unit_math">value</set>
    +                        <set token="df_storage_unit_legend">MB</set>
    +                    </condition>
    +                    <condition value="GB">
    +                        <set token="df_storage_unit_math">value/1024</set>
    +                        <set token="df_storage_unit_legend">GB</set>
    +                    </condition>
    +                    <condition value="TB">
    +                        <set token="df_storage_unit_math">value/1024/1204</set>
    +                        <set token="df_storage_unit_legend">TB</set>
    +                    </condition>
    +                    <condition value="pct">
    +                        <set token="df_storage_unit_math">value</set>
    +                        <set token="df_storage_unit_legend">pct</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$start_df_storage_search$ $jfs_chart2$">
    +                <title>Data source: $storage_usage_datasource$</title>
    +                <search depends="$start_df_storage_search$ $jfs_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.*" $host$ dimension_mount="$df_storage_mount$" by host, metric_name, dimension_mount span=1m
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free
    +| foreach storage, storage_free, storage_used [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;'/1024, 2) ]
    +| stats latest(storage*) as "storage*" by _time, dimension_mount, host
    +| eval value=$df_storage_monitor$
    +| eval value=$df_storage_unit_math$
    +| timechart $span$ latest(value) as $df_storage_monitor$ by dimension_mount</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">$df_storage_unit_legend$</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">$df_storage_monitor_max_chart$</option>
    +            </chart>
    +
    +            <!-- JFSFILE -->
    +
    +            <input type="text" token="fsfilter" searchWhenChanged="true" depends="$start_jfs_storage_search$ $jfs_chart2$">
    +                <label>mount:</label>
    +                <default>*</default>
    +            </input>
    +
    +            <chart depends="$start_jfs_storage_search$ $jfs_chart2$">
    +                <title>Data source: $storage_usage_datasource$</title>
    +                <search depends="$start_jfs_storage_search$ $jfs_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsfile" $host$ dimension_mount="$fsfilter$" by host, dimension_device span=1m
    +| timechart $span$ limit=0 useother=f latest(value) As value by dimension_mount</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% Used</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +            <!--
    +
    +            ### file systems inodes utilisation over time ###
    +
    +            file systems inodes utilisation, either DF_INODES (default) or JFSINODE
    +            -->
    +
    +            <!-- DF_INODES -->
    +
    +            <input type="text" token="df_storage_mount" depends="$start_df_storage_search$ $jfs_chart3$">
    +              <label>mount</label>
    +              <default>*</default>
    +            </input>
    +
    +            <input type="dropdown" token="chart_df_inodes_monitor" depends="$start_df_storage_search$ $jfs_chart3$">
    +                <label>Monitor:</label>
    +                <choice value="storage_used_inodes">storage_used_inodes</choice>
    +                <choice value="storage_free_inodes_percent">storage_free_inodes_percent (%)</choice>
    +                <choice value="storage_used_inodes_percent">storage_used_inodes_percent (%)</choice>
    +                <default>storage_used_inodes_percent</default>
    +                <change>
    +                    <condition value="storage_used_inodes">
    +                        <set token="chart_df_inodes_unit_legend">nb inodes</set>
    +                    </condition>
    +                    <condition value="storage_free_inodes_percent">
    +                        <set token="chart_df_inodes_unit_legend">pct</set>
    +                    </condition>
    +                    <condition value="storage_used_inodes_percent">
    +                        <set token="chart_df_inodes_unit_legend">pct</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$start_df_storage_search$ $jfs_chart3$">
    +                <title>Data source: $storage_inodes_usage_datasource$</title>
    +                <search depends="$start_df_storage_search$ $jfs_chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_inodes.*" $host$ by host, metric_name, dimension_mount span=1m
    +| eval IUse_pct=case(metric_name=="os.unix.nmon.storage.df_inodes.IUse_pct", value), IUsed=case(metric_name=="os.unix.nmon.storage.df_inodes.IUsed", value)
    +| stats values(IUse_pct) as IUse_pct, values(IUsed) as IUsed by _time, dimension_mount
    +| eval IFree_pct=(100-IUse_pct)
    +| rename IUse_pct as storage_used_inodes_percent, IFree_pct as storage_free_inodes_percent, values(IUsed) as storage_used_inodes
    +| timechart $span$ latest($chart_df_inodes_monitor$) as $chart_df_inodes_monitor$ by dimension_mount</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">$chart_df_inodes_unit_legend$</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">$chart_df_inodes_monitor_max_chart$</option>
    +            </chart>
    +
    +            <!-- JFSINODE -->
    +
    +            <input type="text" token="fsfilter" searchWhenChanged="true" depends="$start_jfs_storage_search$ $jfs_chart3$">
    +                <label>mount:</label>
    +                <default>*</default>
    +            </input>
    +
    +            <chart depends="$start_jfs_storage_search$ $jfs_chart3$">
    +                <title>Data source: $storage_inodes_usage_datasource$</title>
    +                <search depends="$start_jfs_storage_search$ $jfs_chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsinode" $host$ dimension_mount="$fsfilter$" by host, dimension_device span=1m
    +| timechart $span$ limit=0 useother=f latest(value) As value by dimension_mount</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Percentage (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsinodes" $host$ dimension_mount="$fsfilter$" by host, dimension_mount span=1m
    +| timechart $span$ limit=0 useother=f latest(value) As value by dimension_mount
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="network1">
    +            <title>Adapters Statistics</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="ioadapt_linkinput">
    +                <label></label>
    +                <choice value="ioadapt_chart1">IOADAPT, Read/Write Operations (Kbytes/sec)</choice>
    +                <choice value="ioadapt_chart2">IOADAPT, Disks adapters Total I/O Operations (tps)</choice>
    +                <default>ioadapt_chart1</default>
    +                <change>
    +                    <condition value="ioadapt_chart1">
    +                        <set token="ioadapt_chart1">true</set>
    +                        <unset token="ioadapt_chart2"></unset>
    +                    </condition>
    +                    <condition value="ioadapt_chart2">
    +                        <set token="ioadapt_chart2">true</set>
    +                        <unset token="ioadapt_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$ioadapt_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.adapters.ioadapt" $host$ (dimension_device!="*tps*") by dimension_device span=1m
    +| timechart useother=f limit=0 $span$ avg(value) as value by "dimension_device"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KBytes/sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.adapters.ioadapt" $host$ (dimension_device!="*tps*") by dimension_device span=1m
    +| timechart useother=f limit=0 $span$ avg(value) as value by "dimension_device"
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$ioadapt_chart2$">
    +                <title></title>
    +                <search depends="$ioadapt_chart2$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.adapters.ioadapt" $host$ (dimension_device="*tps*") by dimension_device span=1m
    +| timechart useother=f limit=0 $span$ avg(value) as value by "dimension_device"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">I/O per Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.adapters.ioadapt" $host$ (dimension_device="*tps*") by dimension_device span=1m
    +| timechart useother=f limit=0 $span$ avg(value) as value by "dimension_device"
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <!--
    +    Fiber Channel adapters: only show the panels if we have data
    +    -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.adapters.fc*" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_fiber_searches"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_fiber_searches">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <row depends="$start_fiber_searches$">
    +        <panel>
    +
    +            <input type="link" token="fiberchannel_linkinput">
    +                <label></label>
    +                <choice value="fiberchannel_chart1">FCREAD/WRITE, Read / Write transfer rate (KB/sec)</choice>
    +                <choice value="fiberchannel_chart2">FCXFER, In/Out I/O transfer</choice>
    +                <default>fiberchannel_chart1</default>
    +                <change>
    +                    <condition value="fiberchannel_chart1">
    +                        <set token="fiberchannel_chart1">true</set>
    +                        <unset token="fiberchannel_chart2"></unset>
    +                    </condition>
    +                    <condition value="fiberchannel_chart2">
    +                        <set token="fiberchannel_chart2">true</set>
    +                        <unset token="fiberchannel_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$fiberchannel_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.adapters.fcread OR metric_name=os.unix.nmon.adapters.fcwrite) $host$ by metric_name, dimension_device span=1m
    +| `extract_metrics_by_key`
    +| timechart avg(value) as value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KBytes/sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.adapters.fcread OR metric_name=os.unix.nmon.adapters.fcwrite) $host$ by metric_name, dimension_device span=1m
    +| `extract_metrics_by_key`
    +| timechart avg(value) as value by key
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$fiberchannel_chart2$">
    +                <title></title>
    +                <search depends="$fiberchannel_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.fcxfer* $host$ by metric_name, dimension_device span=1m
    +| `extract_metrics_by_key`
    +| timechart avg(value) as value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">I/O per Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.fcxfer* $host$ by metric_name, dimension_device span=1m
    +| `extract_metrics_by_key`
    +| timechart avg(value) as value by key
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- SEA (Shared Ethernet Adapters) -->
    +    
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.adapters.sea*" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_sea_search"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_sea_search">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <row depends="$start_sea_search$">
    +        <panel>
    +
    +            <input type="link" token="sea_linkinput">
    +                <label></label>
    +                <choice value="sea_chart1">Shared Ethernet Adapters - SEA</choice>
    +                <choice value="sea_chart2">Shared Ethernet Adapters - SEACHPHY</choice>
    +                <choice value="sea_chart3">Shared Ethernet Adapters - SEAPACKET</choice>
    +                <default>sea_chart1</default>
    +                <change>
    +                    <condition value="sea_chart1">
    +                        <set token="sea_chart1">true</set>
    +                        <unset token="sea_chart2"></unset>
    +                        <unset token="sea_chart3"></unset>
    +                    </condition>
    +                    <condition value="sea_chart2">
    +                        <set token="sea_chart2">true</set>
    +                        <unset token="sea_chart1"></unset>
    +                        <unset token="sea_chart3"></unset>
    +                    </condition>
    +                    <condition value="sea_chart3">
    +                        <set token="sea_chart3">true</set>
    +                        <unset token="sea_chart1"></unset>
    +                        <unset token="sea_chart2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$sea_chart1$">
    +                <title></title>
    +                <search depends="$start_sea_search$ $sea_chart1$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.sea $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KB/sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.sea $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$sea_chart2$">
    +                <title></title>
    +                <search depends="$start_sea_search$ $sea_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.seachphy $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Various</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.seachphy $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$sea_chart3$">
    +                <title></title>
    +                <search depends="$start_sea_search$ $sea_chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.seapacket $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Packets</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.seapacket $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +    
    +    <row>
    +        <panel id="network2">
    +            <title>NETWORK Usage Statistics</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="net_linkinput">
    +                <label></label>
    +                <choice value="net_chart1">NET - Inbound/Outbound traffic</choice>
    +                <choice value="net_chart2">NETPACKET - Inbound/Outbound packets</choice>
    +                <choice value="net_chart3">NETERROR - Inbound/Outbound error packets</choice>
    +                <default>net_chart1</default>
    +                <change>
    +                    <condition value="net_chart1">
    +                        <set token="net_chart1">true</set>
    +                        <unset token="net_chart2"></unset>
    +                        <unset token="net_chart3"></unset>
    +                    </condition>
    +                    <condition value="net_chart2">
    +                        <set token="net_chart2">true</set>
    +                        <unset token="net_chart1"></unset>
    +                        <unset token="net_chart3"></unset>
    +                    </condition>
    +                    <condition value="net_chart3">
    +                        <set token="net_chart3">true</set>
    +                        <unset token="net_chart1"></unset>
    +                        <unset token="net_chart2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$net_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.net $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Outbound KBps / Inbound KBps</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.net $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$net_chart2$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.netpacket $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Outbound / Inbound packets</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.netpacket $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$net_chart3$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.neterror $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Number of Network Packets</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.neterror $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <!--
    +    NFS server / client: only show the panels if we have data
    +    -->
    +
    +    <!-- NFS v2 data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.network.nfs*v2.*" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_nfsv2_searches"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_nfsv2_searches">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- NFS v3 data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.network.nfs*v3.*" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_nfsv3_searches"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_nfsv3_searches">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- NFS v4 data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.network.nfs*v4.*" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_nfsv4_searches"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_nfsv4_searches">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- NFS v2 -->
    +
    +    <row depends="$start_nfsv2_searches$">
    +        <panel>
    +
    +            <input type="link" token="nfsv2_linkinput">
    +                <label></label>
    +                <choice value="nfssvrv2">NFS Server v2</choice>
    +                <choice value="nfscliv2">NFS Client v2</choice>
    +                <default>nfssvrv2</default>
    +                <change>
    +                    <condition value="nfssvrv2">
    +                        <set token="show_nfssvrv2">true</set>
    +                        <unset token="show_nfscliv2"></unset>
    +                    </condition>
    +                    <condition value="nfscliv2">
    +                        <set token="show_nfscliv2">true</set>
    +                        <unset token="show_nfssvrv2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$show_nfssvrv2$">
    +                <title></title>
    +                <search depends="$start_nfsv2_searches$ $show_nfssvrv2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv2.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nbr of Operations</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv2.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$show_nfscliv2$">
    +                <title></title>
    +                <search depends="$start_nfsv2_searches$ $show_nfscliv2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv2.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nbr of Operations</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv2.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +    
    +    <!-- NFS v3 -->
    +
    +    <row depends="$start_nfsv3_searches$">
    +        <panel>
    +
    +            <input type="link" token="nfsv3_linkinput">
    +                <label></label>
    +                <choice value="nfssvrv3">NFS Server v3</choice>
    +                <choice value="nfscliv3">NFS Client v3</choice>
    +                <default>nfssvrv3</default>
    +                <change>
    +                    <condition value="nfssvrv3">
    +                        <set token="show_nfssvrv3">true</set>
    +                        <unset token="show_nfscliv3"></unset>
    +                    </condition>
    +                    <condition value="nfscliv3">
    +                        <set token="show_nfscliv3">true</set>
    +                        <unset token="show_nfssvrv3"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$show_nfssvrv3$">
    +                <title></title>
    +                <search depends="$start_nfsv3_searches$ $show_nfssvrv3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv3.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nbr of Operations</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv3.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$show_nfscliv3$">
    +                <title></title>
    +                <search depends="$start_nfsv3_searches$ $show_nfscliv3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv3.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nbr of Operations</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv3.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +    
    +    <!-- NFS v4 -->
    +
    +    <row depends="$start_nfsv4_searches$">
    +        <panel>
    +
    +            <input type="link" token="nfsv4_linkinput">
    +                <label></label>
    +                <choice value="nfssvrv4">NFS Server v4</choice>
    +                <choice value="nfscliv4">NFS Client v4</choice>
    +                <default>nfssvrv4</default>
    +                <change>
    +                    <condition value="nfssvrv4">
    +                        <set token="show_nfssvrv4">true</set>
    +                        <unset token="show_nfscliv4"></unset>
    +                    </condition>
    +                    <condition value="nfscliv4">
    +                        <set token="show_nfscliv4">true</set>
    +                        <unset token="show_nfssvrv4"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$show_nfssvrv4$">
    +                <title></title>
    +                <search depends="$start_nfsv4_searches$ $show_nfssvrv4$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv4.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nbr of Operations</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv4.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$show_nfscliv4$">
    +                <title></title>
    +                <search depends="$start_nfsv4_searches$ $show_nfscliv4$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv4.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nbr of Operations</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv4.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_ANALYSER_LINUX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_ANALYSER_LINUX.xml
    new file mode 100644
    index 0000000..d18bf30
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_ANALYSER_LINUX.xml
    @@ -0,0 +1,3466 @@
    +<form stylesheet="ui_simple.css,hide_timeindicator.css,table_data_bar.css,panel_decoration.css" script="autodiscover.js,table_data_bar.js" isVisible="true" version="1.1" theme="dark">
    +    <label>NMON Analyser LINUX</label>
    +
    +    <!--
    +    base search for main dropdown populating
    +    -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $osfilter$ host="$host-prefilter$" by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Information panel -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader2">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +
    +                    <h4>Nmon Analyser interfaces have been designed for focused time ranges, very large time ranges may require time to be fully processed</h4>
    +                    <h4>For long time analysis, please consider using metric dedicated interfaces available from App home pages</h4>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Selection panel -->
    +
    +    <row>
    +        <panel>
    +
    +            <input type="time" token="timerange" searchWhenChanged="true">
    +                <label>Time Range:</label>
    +                <default>
    +                    <earliest>-24h</earliest>
    +                    <latest>now</latest>
    +                </default>
    +            </input>
    +
    +            <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +                <label>Filter OS Type:</label>
    +                <default>Linux</default>
    +                <prefix>OStype="</prefix>
    +                <suffix>"</suffix>
    +                <choice value="*">Any OS</choice>
    +                <choice value="Linux">Linux</choice>
    +            </input>
    +
    +            <input id="frameID" type="dropdown" token="frameID" searchWhenChanged="true">
    +                <label>Frame IDs:</label>
    +                <search base="populate">
    +                    <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +                </search>
    +                <choice value="*">Any</choice>
    +                <initialValue>*</initialValue>
    +                <fieldForLabel>frameID</fieldForLabel>
    +                <fieldForValue>frameID</fieldForValue>
    +                <prefix>frameID="</prefix>
    +                <suffix>"</suffix>
    +            </input>
    +
    +            <input type="text" token="host-prefilter" searchWhenChanged="true">
    +                <label>Optional: Filter hosts populating</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input id="host" type="dropdown" token="host" searchWhenChanged="true">
    +                <label>Host:</label>
    +                <search base="populate">
    +                    <query>search $frameID$ | stats count by host | dedup host | sort 0 host</query>
    +                </search>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +                <prefix>host="</prefix>
    +                <suffix>"</suffix>
    +                <!--
    +                Reset the form token changed
    +                -->
    +                <change>
    +                    <unset token="form.is_LPAR_input"></unset>
    +                    <unset token="form.DG_detection"></unset>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- CPU data source (CPU_ALL versus LPAR) -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.lpar.PhysicalCPU" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                <set token="is_not_LPAR">true</set>
    +                <unset token="is_LPAR"></unset>
    +                <set token="CPU_datasource">CPU_ALL usage</set>
    +                <set token="CPU_datasource_minilabel">CPU % usage</set>
    +            </condition>
    +            <condition>
    +                <set token="is_LPAR">true</set>
    +                <unset token="is_not_LPAR"></unset>
    +                <set token="CPU_datasource">LPAR usage</set>
    +                <set token="CPU_datasource_minilabel">partition vCPUs usage</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- DG data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgxfer" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <set token="start_disk_stats_search">_time,*</set>
    +                    <unset token="start_dg_stats_search"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_dg_stats_search">_time,*</set>
    +                    <unset token="start_disk_stats_search"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- DF_STORAGE data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.Use_pct" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <set token="start_jfs_storage_search">true</set>
    +                    <set token="storage_usage_datasource">JFSFILE</set>
    +                    <set token="storage_inodes_usage_datasource">JFSINODE</set>
    +                    <unset token="start_df_storage_search"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_df_storage_search">true</set>
    +                    <set token="storage_usage_datasource">DF_STORAGE</set>
    +                    <set token="storage_inodes_usage_datasource">DF_INODES</set>
    +                    <unset token="start_jfs_storage_search"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- Configuration Search uses the nmon_inventory data over the report -->
    +
    +    <search ref="NMON Inventory Linux" id="configSearch">
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <title>SYSTEM SUMMARY OVERVIEW</title>
    +
    +            <table rejects="$show_null_config$">
    +                <title></title>
    +                <search base="configSearch">
    +                    <query>rename hostname AS host | search $host$
    +| eval Linux_memory_GB = round((Linux_memory_MB/1024),2)
    +| eval Linux_swap_GB = round((Linux_swap_MB/1024),2)
    +| fields cpu_cores, Processor, Linux_memory_GB, Linux_swap_GB, Linux_distribution, Linux_kernelversion, nmon_version, uptime_duration, system_startup_date
    +| rename cpu_cores AS "Number of CPUs (logical CPUs)", Linux_memory_GB AS "Physical Memory (GB)", Linux_swap_GB AS "Swap Memory (GB)", Linux_distribution AS "Linux distribution", Linux_kernelversion AS "Kernel version", nmon_version AS "Version nmon", uptime_duration AS "Uptime duration (dd:HH:MM:SS)", system_startup_date AS "Last Known System startup date"
    +                    </query>
    +                    <!-- Progress event has access to job properties only -->
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_null_config">True</set>
    +                        </condition>
    +                        <condition>
    +                            <unset token="show_null_config"/>
    +                        </condition>
    +                    </progress>
    +                </search>
    +            </table>
    +            <html depends="$show_null_config$">
    +                <p style="color:blue;margin-left:30px;font-size:14px">SYSTEM SUMMARY OVERVIEW Search returned no results, The nmon inventory data may not be available yet for this host, manually run the Nmon Inventory Generation report or wait for the auto update. (occurs every hour by default)</p>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label></label>
    +                <default>max</default>
    +                <choice value="max">max</choice>
    +                <choice value="avg">avg</choice>
    +            </input>
    +
    +            <chart>
    +                <title>CPU Usage</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` $host$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart $span$ $statsmode$(cpu_load_percent) AS cpu_load_percent</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">CPU Usage</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` $host$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart $span$ $statsmode$(cpu_load_percent) AS cpu_load_percent
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +
    +            </chart>
    +
    +        </panel>
    +        <panel>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label></label>
    +                <default>max</default>
    +                <choice value="max">max</choice>
    +                <choice value="avg">avg</choice>
    +            </input>
    +
    +            <input type="dropdown" token="dg_monitors" depends="$start_dg_stats_search$">
    +              <label></label>
    +              <choice value="disk_read_iops*,disk_write_iops*">read/write iops</choice>
    +              <choice value="disk_total_iops*">total_iops</choice>
    +              <choice value="disk_read_iops*">read_iops</choice>
    +              <choice value="disk_write_iops*">write_iops</choice>
    +              <default>disk_read_iops*,disk_write_iops*</default>
    +            </input>
    +
    +            <chart depends="$start_dg_stats_search$">
    +                <title>I/O Per second</title>
    +                <search depends="$start_dg_stats_search$">
    +                    <query>| mstats sum(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgxfer" OR metric_name="os.unix.nmon.storage.diskxfer") $host$ by host, metric_name span=1m
    +| eval dgxfer_iops=case(metric_name=="os.unix.nmon.storage.dgxfer", value), diskxfer_iops=case(metric_name=="os.unix.nmon.storage.diskxfer", value)
    +| stats values(dgxfer_iops) as dgxfer_iops, values(diskxfer_iops) as diskxfer_iops by _time, host
    +| eval iops=if(isnum('dgxfer_iops'), 'dgxfer_iops', 'diskxfer_iops')
    +| timechart $span$ $statsmode$(iops) as avg_iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">I/O per sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats sum(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgxfer" OR metric_name="os.unix.nmon.storage.diskxfer") $host$ by host, metric_name span=1m
    +| eval dgxfer_iops=case(metric_name=="os.unix.nmon.storage.dgxfer", value), diskxfer_iops=case(metric_name=="os.unix.nmon.storage.diskxfer", value)
    +| stats values(dgxfer_iops) as dgxfer_iops, values(diskxfer_iops) as diskxfer_iops by _time, host
    +| eval iops=if(isnum('dgxfer_iops'), 'dgxfer_iops', 'diskxfer_iops')
    +| timechart $span$ $statsmode$(iops) as avg_iops
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$start_disk_stats_search$">
    +                <title>I/O Per second</title>
    +                <search depends="$start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" $host$ by host, dimension_device span=1m
    +| stats sum(value) AS iops by _time, host
    +| timechart $span$ $statsmode$(iops) as avg_iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">I/O per sec</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" $host$ by host, dimension_device span=1m
    +| stats sum(value) AS iops by _time, host
    +| timechart $span$ $statsmode$(iops) as avg_iops
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>CPU statistics</title>
    +        </panel>
    +    </row>
    +
    +    <search id="CPU_ALL">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT) $host$ by metric_name, host span=1m
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent by _time, host
    +| fillnull value=0 Sys_percent,User_percent,Wait_percent
    +| eval cpu_load_percent=(Sys_percent+User_percent+Wait_percent)
    +| timechart $span$
    +avg(Idle_percent) AS "Idle %",
    +avg(Sys_percent) AS "Sys %",
    +avg(User_percent) AS "User %",
    +avg(Wait_percent) AS "Wait %",
    +avg(cpu_load_percent) as "CPU %"</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="cpu_all_linkinput">
    +                <label></label>
    +                <choice value="cpu_all_chart1">CPU_ALL, % by category</choice>
    +                <choice value="cpu_all_chart2">CPU_ALL, % global usage</choice>
    +                <choice value="cpu_nn_chart1">CPUnn, % global usage by processor</choice>
    +                <default>cpu_all_chart1</default>
    +                <change>
    +                    <condition value="cpu_all_chart1">
    +                        <set token="cpu_all_chart1">true</set>
    +                        <unset token="cpu_all_chart2"></unset>
    +                        <unset token="cpu_nn_chart1"></unset>
    +                    </condition>
    +                    <condition value="cpu_all_chart2">
    +                        <set token="cpu_all_chart2">true</set>
    +                        <unset token="cpu_all_chart1"></unset>
    +                        <unset token="cpu_nn_chart1"></unset>
    +                    </condition>
    +                    <condition value="cpu_nn_chart1">
    +                        <set token="cpu_nn_chart1">true</set>
    +                        <unset token="cpu_all_chart1"></unset>
    +                        <unset token="cpu_all_chart2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$cpu_all_chart1$">
    +                <title></title>
    +                <search base="CPU_ALL">
    +                    <query>fields _time,"Idle %","Sys %","User %","Wait %"</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% of CPUs utilization</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT) $host$ by metric_name, host span=1m
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent by _time, host
    +| eval cpu_load_percent=(Sys_percent%2BUser_percent%2BWait_percent)
    +| timechart $span$ avg(Idle_percent) AS Idle_percent, avg(Sys_percent) AS Sys_percent, avg(User_percent) AS User_percent, avg(Wait_percent) AS Wait_percent, avg(cpu_load_percent) as cpu_load_percent
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$cpu_all_chart2$">
    +                <title></title>
    +                <search base="CPU_ALL">
    +                    <query>fields _time,"CPU %"</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% of CPUs utilization</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT) $host$ by metric_name, host span=1m
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent by _time, host
    +| eval cpu_load_percent=(Sys_percent%2BUser_percent%2BWait_percent)
    +| timechart $span$ avg(Idle_percent) AS Idle_percent, avg(Sys_percent) AS Sys_percent, avg(User_percent) AS User_percent, avg(Wait_percent) AS Wait_percent, avg(cpu_load_percent) as cpu_load_percent
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$cpu_nn_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* $host$ by metric_name span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT by _time, cpu_core | fillnull value=0
    +| fillnull value=0 Sys_PCT,User_PCT,Wait_PCT
    +| eval cpu_PCT=(Sys_PCT+User_PCT+Wait_PCT)
    +| timechart $span$ useother=f limit=0 avg(cpu_PCT) AS cpu_PCT by cpu_core</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% of CPU utilization</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* $host$ by metric_name span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT by _time, cpu_core | fillnull value=0
    +| eval cpu_PCT=(Sys_PCT%2BUser_PCT%2BWait_PCT)
    +| timechart $span$ useother=f limit=0 avg(cpu_PCT) AS cpu_PCT by cpu_core
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row depends="$is_LPAR$">
    +        <panel>
    +
    +            <input type="link" token="lpar_linkinput">
    +                <label></label>
    +                <choice value="lpar_chart1">LPAR, PowerLinux only, Partition statistics</choice>
    +                <choice value="lpar_chart2">LPAR, PowerLinux only, Pool statistics</choice>
    +                <default>lpar_chart1</default>
    +                <change>
    +                    <condition value="lpar_chart1">
    +                        <set token="lpar_chart1">true</set>
    +                        <unset token="lpar_chart2"></unset>
    +                    </condition>
    +                    <condition value="lpar_chart2">
    +                        <set token="lpar_chart2">true</set>
    +                        <unset token="lpar_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$lpar_chart1$">
    +                <title></title>
    +                <search depends="$is_LPAR$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.PhysicalCPU" OR metric_name="os.unix.nmon.cpu.lpar.partition_active_processors" OR metric_name="os.unix.nmon.cpu.lpar.partition_entitled_capacity") ($host$) by metric_name, host span=1m
    +| `def_lpar_load_linux_cores`
    +| timechart $span$ max(lpar_load_cores) AS "max cpu load cores", avg(lpar_load_cores) AS "avg cpu load cores", max(partition_active_processors) as partition_active_processors, max(partition_entitled_capacity) as partition_entitled_capacity</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">VirtualCPUs</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.PhysicalCPU" OR metric_name="os.unix.nmon.cpu.lpar.partition_active_processors" OR metric_name="os.unix.nmon.cpu.lpar.partition_entitled_capacity") ($host$) by metric_name, host span=1m
    +| `def_lpar_load_linux_cores`
    +| timechart $span$ max(lpar_load_cores) AS "max cpu load cores", avg(lpar_load_cores) AS "avg cpu load cores", max(partition_active_processors) as partition_active_processors, max(partition_entitled_capacity) as partition_entitled_capacity
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$lpar_chart2$">
    +                <title></title>
    +                <search depends="$is_LPAR$ $lpar_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.smt_mode" OR metric_name="os.unix.nmon.cpu.lpar.pool_idle_time" OR metric_name="os.unix.nmon.cpu.lpar.pool_capacity") ($host$) by metric_name, host span=1m
    +| `def_lpar_pool_load_linux_cores`
    +| timechart $span$ max(lpar_pool_vp_usage) As lpar_pool_vp_usage max(pool_capacity) AS pool_capacity</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">VirtualCPUs</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.smt_mode" OR metric_name="os.unix.nmon.cpu.lpar.pool_idle_time" OR metric_name="os.unix.nmon.cpu.lpar.pool_capacity") ($host$) by metric_name, host span=1m
    +| `def_lpar_pool_load_linux_cores`
    +| timechart $span$ max(lpar_pool_vp_usage) As lpar_pool_vp_usage max(pool_capacity) AS pool_capacity
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Process, Kernel, I/O Statistics</title>
    +        </panel>
    +    </row>
    +
    +    <!-- TOP data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_top_search"></unset>
    +                    <set token="show_null_top"></set>
    +            </condition>
    +            <condition>
    +                    <set token="start_top_search">true</set>
    +                    <unset token="show_null_top"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="top_linkinput">
    +                <label></label>
    +                <choice value="top_chart1">TOP, CPU Usage per logical core</choice>
    +                <choice value="top_chart2">TOP, Memory Usage per command invocation</choice>
    +                <choice value="top_chart3">TOP, Virtual Memory Usage per command invocation</choice>
    +                <choice value="top_chart4">TOP, MinorFault per Command invocation</choice>
    +                <choice value="top_chart5">TOP, MajorFault per Command invocation</choice>
    +                <choice value="top_chart6">TOP, Shared library pages per Command invocation</choice>
    +                <default>top_chart1</default>
    +                <change>
    +                    <condition value="top_chart1">
    +                        <set token="top_chart1">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                    </condition>
    +                    <condition value="top_chart2">
    +                        <set token="top_chart2">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                    </condition>
    +                    <condition value="top_chart3">
    +                        <set token="top_chart3">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                    </condition>
    +                    <condition value="top_chart4">
    +                        <set token="top_chart4">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                    </condition>
    +                    <condition value="top_chart5">
    +                        <set token="top_chart5">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart6"></unset>
    +                    </condition>
    +                    <condition value="top_chart6">
    +                        <set token="top_chart6">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$top_chart1$ $start_top_search$">
    +                <title></title>
    +                <search depends="$top_chart1$ $start_top_search$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| timechart $span$ useother=f limit="50" max(usage_per_core) as "CPU Usage per core" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">zero</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Logical Core</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as pct_CPU where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" dimension_Command="$click.name2$" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| timechart $span$ useother=f limit="50" max(usage_per_core) as "CPU Usage per core" by dimension_Command
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart2$ $start_top_search$">
    +                <title></title>
    +                <search depends="$top_chart2$ $start_top_search$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSet" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| eval Used_Mem_MB=((value)/1024)
    +| timechart $span$ useother=f limit="50" avg(Used_Mem_MB) as "memory usage (MB)" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">zero</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSet" dimension_Command="$click.name2$" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| eval Used_Mem_MB=((value)/1024)
    +| timechart $span$ useother=f limit="50" avg(Used_Mem_MB) as "memory usage (MB)" by dimension_Command&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart3$ $start_top_search$">
    +                <title></title>
    +                <search depends="$top_chart3$ $start_top_search$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Size" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| eval Virtual_Mem_MB=((value)/1024)
    +| timechart $span$ useother=f limit="50" avg(Virtual_Mem_MB) as "Virtual_Mem usage (MB)" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">zero</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Size" dimension_Command="$click.name2$" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| eval Virtual_Mem_MB=((value)/1024)
    +| timechart $span$ useother=f limit="50" avg(Virtual_Mem_MB) as "Virtual_Mem usage (MB)" by dimension_Command&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart4$ $start_top_search$">
    +                <title></title>
    +                <search depends="$top_chart4$ $start_top_search$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.MinorFault" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as MinorFault by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">zero</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.MinorFault" dimension_Command="$click.name2$" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as MinorFault by dimension_Command&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart5$ $start_top_search$">
    +                <title></title>
    +                <search depends="$top_chart5$ $start_top_search$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.MajorFault" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as MajorFault by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">zero</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.MinorFault" dimension_Command="$click.name2$" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as MajorFault by dimension_Command&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart6$ $start_top_search$">
    +                <title></title>
    +                <search depends="$top_chart6$ $start_top_search$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ShdLib" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as ShdLib by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">zero</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ShdLib" dimension_Command="$click.name2$" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as ShdLib by dimension_Command&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <html depends="$show_null_top$">
    +                <p style="color:blue;margin-left:30px;font-size:14px">Search returned no results, TOP collection (processes activity) has not been activated or no processes were captured due to lack of activity</p>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="PROC">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.proc.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="proc_linkinput">
    +                <label></label>
    +                <choice value="proc_chart1">PROC, Kernel Threads in run queue and to be paged (RunQueue, Swap-In)</choice>
    +                <choice value="proc_chart2">PROC, Context switches and system calls (pswitch, syscall)</choice>
    +                <choice value="proc_chart3">PROC, Fork and Exec system calls (fork, exec)</choice>
    +                <default>proc_chart1</default>
    +                <change>
    +                    <condition value="proc_chart1">
    +                        <set token="proc_chart1">true</set>
    +                        <unset token="proc_chart2"></unset>
    +                        <unset token="proc_chart3"></unset>
    +                    </condition>
    +                    <condition value="proc_chart2">
    +                        <set token="proc_chart2">true</set>
    +                        <unset token="proc_chart1"></unset>
    +                        <unset token="proc_chart3"></unset>
    +                    </condition>
    +                    <condition value="proc_chart3">
    +                        <set token="proc_chart3">true</set>
    +                        <unset token="proc_chart2"></unset>
    +                        <unset token="proc_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$proc_chart1$">
    +                <title></title>
    +                <search base="PROC">
    +                    <query>fields _time,Runnable,Swap_in</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Value</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.proc.Runnable OR metric_name=os.unix.nmon.kernel.proc.Swap_in $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$proc_chart2$">
    +                <title></title>
    +                <search base="PROC">
    +                    <query>fields _time,pswitch,syscall</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rates per Second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.proc.pswitch OR metric_name=os.unix.nmon.kernel.proc.syscall $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$proc_chart3$">
    +                <title></title>
    +                <search base="PROC">
    +                    <query>fields _time,fork,exec</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rates per Second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.proc.fork OR metric_name=os.unix.nmon.kernel.proc.exec $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="VM">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="vm_linkinput">
    +                <label></label>
    +                <choice value="vm_chart1">VM, Pages dirty, under writeback or unstable</choice>
    +                <choice value="vm_chart2">VM, Pages allocated to page tables, mapped by files or allocated by the kernel slab allocator</choice>
    +                <choice value="vm_chart3">VM, Pageins and pageouts (since last boot)</choice>
    +                <choice value="vm_chart4">VM, swapins and swapouts (since last boot)</choice>
    +                <choice value="vm_chart5">VM, Page allocations per zone (since last boot)</choice>
    +                <choice value="vm_chart6">VM, Page frees, activations and deactivations (since last boot)</choice>
    +                <choice value="vm_chart7">VM, Minor and major page faults (since last boot)</choice>
    +                <choice value="vm_chart8">VM, Page refills (per zone, since last boot)</choice>
    +                <choice value="vm_chart9">VM, Page steals (per zone, since last boot)</choice>
    +                <choice value="vm_chart10">VM, Pages scanned by kswapd daemon (per zone, since last boot)</choice>
    +                <choice value="vm_chart11">VM, Pages reclaimed directly (per zone, since last boot)</choice>
    +                <choice value="vm_chart12">VM, Miscellaneous statistics</choice>
    +                <default>vm_chart1</default>
    +                <change>
    +                    <condition value="vm_chart1">
    +                        <set token="vm_chart1">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                        <unset token="vm_chart7"></unset>
    +                        <unset token="vm_chart8"></unset>
    +                        <unset token="vm_chart9"></unset>
    +                        <unset token="vm_chart10"></unset>
    +                        <unset token="vm_chart11"></unset>
    +                        <unset token="vm_chart12"></unset>
    +                    </condition>
    +                    <condition value="vm_chart2">
    +                        <set token="vm_chart2">true</set>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                        <unset token="vm_chart7"></unset>
    +                        <unset token="vm_chart8"></unset>
    +                        <unset token="vm_chart9"></unset>
    +                        <unset token="vm_chart10"></unset>
    +                        <unset token="vm_chart11"></unset>
    +                        <unset token="vm_chart12"></unset>
    +                    </condition>
    +                    <condition value="vm_chart3">
    +                        <set token="vm_chart3">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                        <unset token="vm_chart7"></unset>
    +                        <unset token="vm_chart8"></unset>
    +                        <unset token="vm_chart9"></unset>
    +                        <unset token="vm_chart10"></unset>
    +                        <unset token="vm_chart11"></unset>
    +                        <unset token="vm_chart12"></unset>
    +                    </condition>
    +                    <condition value="vm_chart4">
    +                        <set token="vm_chart4">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                        <unset token="vm_chart7"></unset>
    +                        <unset token="vm_chart8"></unset>
    +                        <unset token="vm_chart9"></unset>
    +                        <unset token="vm_chart10"></unset>
    +                        <unset token="vm_chart11"></unset>
    +                        <unset token="vm_chart12"></unset>
    +                    </condition>
    +                    <condition value="vm_chart5">
    +                        <set token="vm_chart5">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                        <unset token="vm_chart7"></unset>
    +                        <unset token="vm_chart8"></unset>
    +                        <unset token="vm_chart9"></unset>
    +                        <unset token="vm_chart10"></unset>
    +                        <unset token="vm_chart11"></unset>
    +                        <unset token="vm_chart12"></unset>
    +                    </condition>
    +                    <condition value="vm_chart6">
    +                        <set token="vm_chart6">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart7"></unset>
    +                        <unset token="vm_chart8"></unset>
    +                        <unset token="vm_chart9"></unset>
    +                        <unset token="vm_chart10"></unset>
    +                        <unset token="vm_chart11"></unset>
    +                        <unset token="vm_chart12"></unset>
    +                    </condition>
    +                    <condition value="vm_chart7">
    +                        <set token="vm_chart7">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart8"></unset>
    +                        <unset token="vm_chart9"></unset>
    +                        <unset token="vm_chart10"></unset>
    +                        <unset token="vm_chart11"></unset>
    +                        <unset token="vm_chart12"></unset>
    +                    </condition>
    +                    <condition value="vm_chart8">
    +                        <set token="vm_chart8">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                        <unset token="vm_chart7"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart9"></unset>
    +                        <unset token="vm_chart10"></unset>
    +                        <unset token="vm_chart11"></unset>
    +                        <unset token="vm_chart12"></unset>
    +                    </condition>
    +                    <condition value="vm_chart9">
    +                        <set token="vm_chart9">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                        <unset token="vm_chart7"></unset>
    +                        <unset token="vm_chart8"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart10"></unset>
    +                        <unset token="vm_chart11"></unset>
    +                        <unset token="vm_chart12"></unset>
    +                    </condition>
    +                    <condition value="vm_chart10">
    +                        <set token="vm_chart10">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                        <unset token="vm_chart7"></unset>
    +                        <unset token="vm_chart8"></unset>
    +                        <unset token="vm_chart9"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart11"></unset>
    +                        <unset token="vm_chart12"></unset>
    +                    </condition>
    +                    <condition value="vm_chart11">
    +                        <set token="vm_chart11">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                        <unset token="vm_chart7"></unset>
    +                        <unset token="vm_chart8"></unset>
    +                        <unset token="vm_chart9"></unset>
    +                        <unset token="vm_chart10"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart12"></unset>
    +                    </condition>
    +                    <condition value="vm_chart12">
    +                        <set token="vm_chart12">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                        <unset token="vm_chart7"></unset>
    +                        <unset token="vm_chart8"></unset>
    +                        <unset token="vm_chart9"></unset>
    +                        <unset token="vm_chart10"></unset>
    +                        <unset token="vm_chart11"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +            
    +            <chart depends="$vm_chart1$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,nr_dirty,nr_writeback,nr_unstable</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,nr_dirty,nr_writeback,nr_unstable&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart2$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,nr_page_table_pages,nr_mapped,nr_slab</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,nr_page_table_pages,nr_mapped,nr_slab&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart3$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pgpgin,pgpgout</query>
    +                </search>      
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,pgpgin,pgpgout&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart4$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pswpin,pswpout</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,pswpin,pswpout&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart5$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pgalloc_high,pgalloc_normal,pgalloc_dma32,pgalloc_dma</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,pgalloc_high,pgalloc_normal,pgalloc_dma32,pgalloc_dma&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart6$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pgfree,pgactivate,pgdeactivate</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,pgfree,pgactivate,pgdeactivate&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart7$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pgfault,pgmajfault</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,pgfault,pgmajfault&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart8$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pgrefill_high,pgrefill_normal,pgrefill_dma32,pgrefill_dma</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,pgrefill_high,pgrefill_normal,pgrefill_dma32,pgrefill_dma&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart9$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pgsteal_high,pgsteal_normal,pgsteal_dma32,pgsteal_dma</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,pgsteal_high,pgsteal_normal,pgsteal_dma32,pgsteal_dma&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart10$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pgscan_kswapd_high,pgscan_kswapd_normal,pgscan_kswapd_dma32,pgscan_kswapd_dma</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,pgscan_kswapd_high,pgscan_kswapd_normal,pgscan_kswapd_dma32,pgscan_kswapd_dma&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart11$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pgscan_direct_high,pgscan_direct_normal,pgscan_direct_dma32,pgscan_direct_dma</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,pgscan_direct_high,pgscan_direct_normal,pgscan_direct_dma32,pgscan_direct_dma&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart12$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pginodesteal,slabs_scanned,kswapd_steal,kswapd_inodesteal,pageoutrun,allocstall,pgrotated,nr_bounce</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,pginodesteal,slabs_scanned,kswapd_steal,kswapd_inodesteal,pageoutrun,allocstall,pgrotated,nr_bounce&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="memory">
    +            <title>MEMORY Usage Statistics</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="mem_linkinput">
    +                <label></label>
    +                <choice value="mem_chart1">MEM, Memory usage (MB) by main metrics</choice>
    +                <choice value="mem_chart2">MEM, Effective memory/swap used (%)</choice>
    +                <choice value="mem_chart3">MEM, Swap effective used/cached/free/global (MB)</choice>
    +                <default>mem_chart1</default>
    +                <change>
    +                    <condition value="mem_chart1">
    +                        <set token="mem_chart1">true</set>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                    </condition>
    +                    <condition value="mem_chart2">
    +                        <set token="mem_chart2">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                    </condition>
    +                    <condition value="mem_chart3">
    +                        <set token="mem_chart3">true</set>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$mem_chart1$">
    +                <title></title>
    +                <search depends="$mem_chart1$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` $host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| timechart $span$ dedup_splitvals=t avg(memtotal) AS mem_total_MB, avg(mem_used_effective) as mem_used_effective_MB, avg(buffers) as mem_buffers_MB, avg(cached) as mem_cached_MB, avg(memfree) as mem_free_MB,
    +avg(swapfree) as swap_free_MB, avg(swap_used_effective) as swap_used_effective_MB, avg(swapcached) as swap_cached_MB, avg(swaptotal) as swap_total_MB
    +| fields _time, mem_free_MB, mem_cached_MB, mem_buffers_MB, mem_used_effective_MB, mem_total_MB</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.overlayFields">mem_total_MB</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.fieldColors">{"mem_total_MB": 0xe50000}</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` $host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| timechart $span$ dedup_splitvals=t avg(memtotal) AS mem_total_MB, avg(mem_used_effective) as mem_used_effective_MB, avg(buffers) as mem_buffers_MB, avg(cached) as mem_cached_MB, avg(memfree) as mem_free_MB,
    +avg(swapfree) as swap_free_MB, avg(swap_used_effective) as swap_used_effective_MB, avg(swapcached) as swap_cached_MB, avg(swaptotal) as swap_total_MB
    +| fields _time, mem_free_MB, mem_cached_MB, mem_buffers_MB, mem_used_effective_MB, mem_total_MB&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$mem_chart2$">
    +                <title></title>
    +                <search depends="$mem_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` $host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent_linux`
    +| timechart $span$ dedup_splitvals=t avg(mem_used_effective_PCT) AS mem_used_PCT, avg(swap_used_effective_PCT) AS swap_used_PCT</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">percentage (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` $host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent_linux`
    +| timechart $span$ dedup_splitvals=t avg(mem_used_effective_PCT) AS mem_used_PCT, avg(swap_used_effective_PCT) AS swap_used_PCT&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$mem_chart3$">
    +                <title></title>
    +                <search depends="$mem_chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` $host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| timechart $span$ dedup_splitvals=t avg(memtotal) AS mem_total_MB, avg(mem_used_effective) as mem_used_effective_MB, avg(buffers) as mem_buffers_MB, avg(cached) as mem_cached_MB, avg(memfree) as mem_free_MB,
    +avg(swapfree) as swap_free_MB, avg(swap_used_effective) as swap_used_effective_MB, avg(swapcached) as swap_cached_MB, avg(swaptotal) as swap_total_MB | fields _time, *swap_free_MB*, *swap_used_effective_MB*, *swap_cached_MB*, *swap_total_MB*</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.overlayFields">swap_total_MB</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.fieldColors">{"swap_total_MB": 0xe50000}</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` $host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| timechart $span$ dedup_splitvals=t avg(memtotal) AS mem_total_MB, avg(mem_used_effective) as mem_used_effective_MB, avg(buffers) as mem_buffers_MB, avg(cached) as mem_cached_MB, avg(memfree) as mem_free_MB,
    +avg(swapfree) as swap_free_MB, avg(swap_used_effective) as swap_used_effective_MB, avg(swapcached) as swap_cached_MB, avg(swaptotal) as swap_total_MB | fields _time, *swap_free_MB*, *swap_used_effective_MB*, *swap_cached_MB*, *swap_total_MB*&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="disk">
    +            <title>Disks performance statistics (active drill-down: click on one of the charts for dimension devices)</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="disk_linkinput">
    +                <label></label>
    +                <choice value="disk_chart1">DISKBSIZE, Average data transfer size</choice>
    +                <choice value="disk_chart2">DISKBUSY, Disk Busy Activity</choice>
    +                <choice value="disk_chart3">DISKREAD/WRITE, Disk Read/Write Data Rate</choice>
    +                <choice value="disk_chart4">DISKXFER, Disk I/O Operations per second (IOPS)</choice>
    +                <choice value="disk_chart5">DISKREAD/WRITE by XFER, Disk Read/Write I/O Operations per second (IOPS)</choice>
    +                <default>disk_chart1</default>
    +                <change>
    +                    <condition value="disk_chart1">
    +                        <set token="disk_chart1">true</set>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                    </condition>
    +                    <condition value="disk_chart2">
    +                        <set token="disk_chart2">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                    </condition>
    +                    <condition value="disk_chart3">
    +                        <set token="disk_chart3">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                    </condition>
    +                    <condition value="disk_chart4">
    +                        <set token="disk_chart4">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                    </condition>
    +                    <condition value="disk_chart5">
    +                        <set token="disk_chart5">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +
    +            <chart depends="$disk_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbsize" $host$ by dimension_device span=1m
    +| stats sum(value) AS avg_transfer_size by _time
    +| timechart $span$ avg(avg_transfer_size) AS avg_transfer_size</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KBytes per Transfer</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbsize" $host$ by dimension_device span=1m
    +| timechart useother=f limit=0 $span$ avg(value) AS avg_transfer_size by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart2$">
    +                <title></title>
    +                <search depends="$disk_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbusy" $host$ by dimension_device span=1m
    +| stats avg(value) AS value by _time
    +| timechart $span$ avg(value) AS avg_busy_disk</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">% of Time Busy</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbusy" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) AS avg_busy_disk by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart3$">
    +                <title></title>
    +                <search depends="$disk_chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite") $host$ by metric_name, dimension_device span=1m
    +| eval disk_read=case(match(metric_name, "diskread"), value), diskwrite = case(match(metric_name, "diskwrite"), value)
    +| stats avg(disk_read) AS disk_read, avg(disk_write) AS disk_write by _time
    +| timechart $span$ avg(disk_read) AS disk_read, avg(disk_write) AS disk_write</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KBytes/Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite") $host$ by metric_name, dimension_device span=1m
    +| eval disk_read=case(match(metric_name, "diskread"), value), diskwrite = case(match(metric_name, "diskwrite"), value)
    +| timechart $span$ useother=f limit=0 avg(disk_read) AS disk_read, avg(disk_write) AS disk_write by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart4$">
    +                <title></title>
    +                <search depends="$disk_chart4$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" $host$ by dimension_device span=1m
    +| stats sum(value) AS iops by _time
    +| timechart $span$ avg(iops) AS iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">I/O per Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) AS iops by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart5$">
    +                <title></title>
    +                <search depends="$disk_chart5$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite" OR metric_name="os.unix.nmon.storage.diskbsize") $host$ by metric_name, dimension_device span=1m
    +| eval disk_read=case(match(metric_name, "diskread"), value), disk_write=case(match(metric_name, "diskwrite"), value), disk_size=case(match(metric_name, "diskbsize"), value)
    +| stats values(disk_read) as disk_read values(disk_write) as disk_write values(disk_size) as disk_size by _time, dimension_device
    +| eval disk_read_iops=(disk_read/disk_size), disk_write_iops=(disk_write/disk_size)
    +| stats sum(disk_read_iops) as disk_read_iops, sum(disk_write_iops) as disk_write_iops by _time
    +| timechart $span$ avg(disk_read_iops) as disk_read_iops, avg(disk_write_iops) as disk_write_iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">I/O per Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite" OR metric_name="os.unix.nmon.storage.diskbsize") $host$ by metric_name, dimension_device span=1m
    +| eval disk_read=case(match(metric_name, "diskread"), value), disk_write=case(match(metric_name, "diskwrite"), value), disk_size=case(match(metric_name, "diskbsize"), value)
    +| stats values(disk_read) as disk_read values(disk_write) as disk_write values(disk_size) as disk_size by _time, dimension_device
    +| eval disk_read_iops=(disk_read/disk_size), disk_write_iops=(disk_write/disk_size)
    +| stats sum(disk_read_iops) as disk_read_iops, sum(disk_write_iops) as disk_write_iops by _time, dimension_device
    +| timechart $span$ useother=f limit=0 avg(disk_read_iops) as disk_read_iops, avg(disk_write_iops) as disk_write_iops by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row depends="$start_dg_stats_search$">
    +        <panel>
    +
    +            <input type="link" token="disk_dg_linkinput">
    +                <label></label>
    +                <choice value="disk_dg_chart1">DG, I/O Operations per second (DGXFER/DGREAD-DGWRITE by DGSIZE)</choice>
    +                <choice value="disk_dg_chart2">DG, % time busy (DGBUSY)</choice>
    +                <choice value="disk_dg_chart3">DG, read/write KB (DGREAD/DGWRITE)</choice>
    +                <choice value="disk_dg_chart4">DG, block size KB (DGSIZE)</choice>
    +                <choice value="disk_dg_chart5">DG, read/write service time ms (DGREADSERV/DGWRITESERV)</choice>
    +                <choice value="disk_dg_chart6">DG, read/write per sec (DGREADS/DGWRITES)</choice>
    +                <choice value="disk_dg_chart7">DG, merge read/write per sec (DGREADMERGE/DGWRITEMERGE)</choice>
    +                <choice value="disk_dg_chart8">DG, time spent (ms) for I/O (DGIOTIME)</choice>
    +                <choice value="disk_dg_chart9">DG, back log time (ms) (DGBACKLOG)</choice>
    +                <choice value="disk_dg_chart10">DG, In flight I/O (DGINFLIGHT)</choice>
    +                <default>disk_dg_chart1</default>
    +                <change>
    +                    <condition value="disk_dg_chart1">
    +                        <set token="disk_dg_chart1">true</set>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart2">
    +                        <set token="disk_dg_chart2">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart3">
    +                        <set token="disk_dg_chart3">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart4">
    +                        <set token="disk_dg_chart4">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart5">
    +                        <set token="disk_dg_chart5">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart6">
    +                        <set token="disk_dg_chart6">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart7">
    +                        <set token="disk_dg_chart7">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart8">
    +                        <set token="disk_dg_chart8">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart9">
    +                        <set token="disk_dg_chart9">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart10">
    +                        <set token="disk_dg_chart10">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$disk_dg_chart1$">
    +                <title></title>
    +                <search depends="$disk_dg_chart1$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dg*" $host$ by metric_name, dimension_device span=1m
    +| `extract_metrics("dgxfer dgread dgwrite dgsize")`
    +| stats max(dgxfer) as disk_total_iops max(dgread) as disk_read_KB_per_sec max(dgwrite) as disk_write_KB_per_sec max(dgsize) as disk_block_size_KB by _time, dimension_device
    +| eval disk_read_iops=(disk_read_KB_per_sec/disk_block_size_KB), disk_write_iops=(disk_write_KB_per_sec/disk_block_size_KB)
    +| stats sum(disk_*) as "disk_*" by _time
    +| timechart $span$ avg(disk_total_iops) as disk_total_iops, avg(disk_read_iops) as disk_read_iops avg(disk_write_iops) as disk_write_iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Transfers/s (IOPS)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dg*" $host$ by metric_name, dimension_device span=1m
    +| `extract_metrics("dgxfer dgread dgwrite dgsize")`
    +| stats max(dgxfer) as disk_total_iops max(dgread) as disk_read_KB_per_sec max(dgwrite) as disk_write_KB_per_sec max(dgsize) as disk_block_size_KB by _time, dimension_device
    +| eval disk_read_iops=(disk_read_KB_per_sec/disk_block_size_KB), disk_write_iops=(disk_write_KB_per_sec/disk_block_size_KB)
    +| stats sum(disk_*) as "disk_*" by _time, dimension_device
    +| timechart $span$ limit=0 useother=f  avg(disk_total_iops) as disk_total_iops, avg(disk_read_iops) as disk_read_iops avg(disk_write_iops) as disk_write_iops by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart2$">
    +                <title></title>
    +                <search depends="$disk_dg_chart2$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbusy" $host$ by host, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_busy_time_pct</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Pct busy (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbusy" $host$ by host, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_busy_time_pct by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart3$">
    +                <title></title>
    +                <search depends="$disk_dg_chart3$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgread" OR metric_name="os.unix.nmon.storage.dgwrite") $host$ by host, metric_name, dimension_device span=1m
    +| `extract_metrics("dgread dgwrite")`
    +| stats values(dgread) as disk_read_KB_per_sec, values(dgwrite) as disk_write_KB_per_sec by _time, host, dimension_device
    +| timechart $span$ avg(disk_read_KB_per_sec) as disk_read_KB_per_sec, avg(disk_write_KB_per_sec) as disk_write_KB_per_sec</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">KB/s</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgread" OR metric_name="os.unix.nmon.storage.dgwrite") $host$ by host, metric_name, dimension_device span=1m
    +| `extract_metrics("dgread dgwrite")`
    +| stats values(dgread) as disk_read_KB_per_sec, values(dgwrite) as disk_write_KB_per_sec by _time, host, dimension_device
    +| timechart $span$ limit=0 useother=f avg(disk_read_KB_per_sec) as disk_read_KB_per_sec, avg(disk_write_KB_per_sec) as disk_write_KB_per_sec by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart4$">
    +                <title></title>
    +                <search depends="$disk_dg_chart4$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgsize" $host$ by host, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_block_size_KB</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Kilobytes (KB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgsize" $host$ by host, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_block_size_KB by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart5$">
    +                <title></title>
    +                <search depends="$disk_dg_chart5$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreadserv" OR metric_name="os.unix.nmon.storage.dgwriteserv") $host$ by host, metric_name, dimension_device span=1m
    +| `extract_metrics("dgreadserv dgwriteserv")`
    +| stats values(dgreadserv) as disk_read_service_time_ms, values(dgwriteserv) as disk_write_service_time_ms by _time, host, dimension_device
    +| timechart $span$ avg(disk_read_service_time_ms) as disk_read_service_time_ms, avg(disk_write_service_time_ms) as disk_write_service_time_ms</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Milliseconds (ms)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreadserv" OR metric_name="os.unix.nmon.storage.dgwriteserv") $host$ by host, metric_name, dimension_device span=1m
    +| `extract_metrics("dgreadserv dgwriteserv")`
    +| stats values(dgreadserv) as disk_read_service_time_ms, values(dgwriteserv) as disk_write_service_time_ms by _time, host, dimension_device
    +| timechart $span$ limit=0 useother=f avg(disk_read_service_time_ms) as disk_read_service_time_ms, avg(disk_write_service_time_ms) as disk_write_service_time_ms by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart6$">
    +                <title></title>
    +                <search depends="$disk_dg_chart6$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreads" OR metric_name="os.unix.nmon.storage.dgwrites") $host$ by host, metric_name, dimension_device span=1m
    +| `extract_metrics("dgreads dgwrites")`
    +| timechart $span$ avg(dgreads) as disk_read_sec, avg(dgwrites) as disk_write_sec</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">read/write per sec</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreads" OR metric_name="os.unix.nmon.storage.dgwrites") $host$ by host, metric_name, dimension_device span=1m
    +| `extract_metrics("dgreads dgwrites")`
    +| timechart $span$ limit=0 useother=f avg(dgreads) as disk_read_sec, avg(dgwrites) as disk_write_sec by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart7$">
    +                <title></title>
    +                <search depends="$disk_dg_chart7$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreadmerge" OR metric_name="os.unix.nmon.storage.dgwritemerge") $host$ by host, metric_name, dimension_device span=1m
    +| `extract_metrics("dgreadmerge dgwritemerge")`
    +| timechart $span$ avg(dgreadmerge) as disk_merge_read_sec, avg(dgwritemerge) as disk_merge_write_sec</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">read/write per sec</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreadmerge" OR metric_name="os.unix.nmon.storage.dgwritemerge") $host$ by host, metric_name, dimension_device span=1m
    +| `extract_metrics("dgreadmerge dgwritemerge")`
    +| timechart $span$ limit=0 useother=f avg(dgreadmerge) as disk_merge_read_sec, avg(dgwritemerge) as disk_merge_write_sec by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart8$">
    +                <title></title>
    +                <search depends="$disk_dg_chart8$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgiotime" $host$ by host, metric_name, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_time_spent_for_io_ms</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Milliseconds (ms)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgiotime" $host$ by host, metric_name, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_time_spent_for_io_ms by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart9$">
    +                <title></title>
    +                <search depends="$disk_dg_chart9$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbacklog" $host$ by host, metric_name, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_backlog_time_ms</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Milliseconds (ms)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbacklog" $host$ by host, metric_name, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_backlog_time_ms by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart10$">
    +                <title></title>
    +                <search depends="$disk_dg_chart10$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dginflight" $host$ by host, metric_name, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_in_flight_io</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Tranfers/sec (IOPS)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dginflight" $host$ by host, metric_name, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_in_flight_io by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="disk2">
    +            <title>File-systems utilization statistics</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="jfs_linkinput">
    +                <label></label>
    +                <choice value="jfs_chart1">Summary of file-systems utilization</choice>
    +                <choice value="jfs_chart2">File-systems utilization over time</choice>
    +                <choice value="jfs_chart3">File-systems inodes utilization over time</choice>
    +                <default>jfs_chart1</default>
    +                <change>
    +                    <condition value="jfs_chart1">
    +                        <set token="jfs_chart1">true</set>
    +                        <unset token="jfs_chart2"></unset>
    +                        <unset token="jfs_chart3"></unset>
    +                    </condition>
    +                    <condition value="jfs_chart2">
    +                        <set token="jfs_chart2">true</set>
    +                        <unset token="jfs_chart1"></unset>
    +                        <unset token="jfs_chart3"></unset>
    +                    </condition>
    +                    <condition value="jfs_chart3">
    +                        <set token="jfs_chart3">true</set>
    +                        <unset token="jfs_chart1"></unset>
    +                        <unset token="jfs_chart2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <!--
    +
    +            ### file systems SUMMARY ###
    +
    +            file systems utilisation, either DF_STORAGE (default) or JFSFILE
    +            -->
    +
    +            <!-- DF_STORAGE -->
    +
    +            <table id="tablebar" depends="$start_df_storage_search$ $jfs_chart1$">
    +                <title>Data source: $storage_usage_datasource$</title>
    +                <search depends="$start_df_storage_search$">
    +                    <query>| mstats latest(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.*" $host$ by host, metric_name, dimension_mount
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)
    +| stats first(Available) as Available, first(Use_pct) as Use_pct, first(Used) as Used, first(blocks) as blocks by host, dimension_mount
    +| rename dimension_mount as mount
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free
    +| foreach storage, storage_free, storage_used [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;'/1024/1024, 2) ]
    +| foreach storage*percent [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]
    +| rename storage as "storage (GB)", storage_free as "storage free (GB)", storage_used as "storage used (GB)", storage_free_percent as "storage free (%)", storage_used_percent as "storage used (%)"
    +| eval UsedPct=if(isnum('storage used (%)'), 'storage used (%)', 0 )
    +| fields mount, "storage (GB)", "storage free (GB)", "storage used (GB)", "storage free (%)", "storage used (%)", UsedPct
    +| appendpipe [ stats sum("storage (GB)") as "storage (GB)", sum("storage free (GB)") as "storage free (GB)", sum("storage used (GB)") as "storage used (GB)" ]
    +| eval "storage free (%)" = if(isnull('storage free (%)'), (('storage free (GB)'/'storage (GB)')*100), 'storage free (%)'), "storage used (%)" = if(isnull('storage used (%)'), (('storage used (GB)'/'storage (GB)')*100), 'storage used (%)'), UsedPct = if(isnull(UsedPct), 'storage used (%)', UsedPct)
    +| fillnull value="*** TOTAL GB / AVERAGE % ****" mount
    +| foreach storage*%* UsedPct [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +
    +            <!-- JFSFILE -->
    +
    +            <table depends="$start_jfs_storage_search$ $jfs_chart1$">
    +                <title>Data source: $storage_usage_datasource$</title>
    +                <search depends="$start_jfs_storage_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsfile" $host$ by host, dimension_mount span=1m
    +| stats max(value) AS max_value, avg(value) AS avg_value, min(value) AS min_value, latest(value) AS UsedPct by dimension_mount
    +| sort limit=0 dimension_mount | rename dimension_mount AS "Mount point"
    +| eval value=round(value,2)
    +| fields "Mount point",max_value, avg_value, min_value, UsedPct | eval avg_value=round(avg_value,2)
    +| rename max_value AS "Max value in period (%)", avg_value AS "Average value in period (%)", min_value AS "Min value in Period (%)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +
    +            <!--
    +
    +            ### file systems utilisation over time ###
    +
    +            file systems utilisation, either DF_STORAGE (default) or JFSFILE
    +            -->
    +
    +            <!-- DF_STORAGE -->
    +
    +            <input type="text" token="df_storage_mount" depends="$start_df_storage_search$ $jfs_chart2$">
    +              <label>mount</label>
    +              <default>*</default>
    +            </input>
    +
    +            <input type="dropdown" token="df_storage_monitor" depends="$start_df_storage_search$ $jfs_chart2$">
    +                <label>Monitor:</label>
    +                <choice value="storage">storage (volume size)</choice>
    +                <choice value="storage_free">storage_free (volume free)</choice>
    +                <choice value="storage_used">storage_used (volume used)</choice>
    +                <choice value="storage_free_percent">storage_free_percent (%)</choice>
    +                <choice value="storage_used_percent">storage_used_percent (%)</choice>
    +                <default>storage_used_percent</default>
    +                <change>
    +                    <condition value="storage">
    +                        <unset token="form.df_storage_monitor_unit"></unset>
    +                        <set token="df_storage_show_unit">true</set>
    +                        <unset token="df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_free">
    +                        <unset token="form.df_storage_monitor_unit"></unset>
    +                        <set token="df_storage_show_unit">true</set>
    +                        <unset token="df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_used">
    +                        <unset token="form.df_storage_monitor_unit"></unset>
    +                        <set token="df_storage_show_unit">true</set>
    +                        <unset token="df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_free_percent">
    +                        <set token="df_storage_unit">%</set>
    +                        <unset token="df_storage_show_unit"></unset>
    +                        <set token="df_storage_monitor_max_chart">101</set>
    +                    </condition>
    +                    <condition value="storage_used_percent">
    +                        <set token="form.df_storage_monitor_unit">pct</set>
    +                        <set token="df_storage_monitor_max_chart">101</set>
    +                        <unset token="df_storage_show_unit"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="df_storage_monitor_unit" depends="$start_df_storage_search$ $df_storage_show_unit$ $jfs_chart2$">
    +                <label>Unit:</label>
    +                <choice value="MB">MB</choice>
    +                <choice value="GB">GB</choice>
    +                <choice value="TB">TB</choice>
    +                <default>GB</default>
    +                <change>
    +                    <condition value="MB">
    +                        <set token="df_storage_unit_math">value</set>
    +                        <set token="df_storage_unit_legend">MB</set>
    +                    </condition>
    +                    <condition value="GB">
    +                        <set token="df_storage_unit_math">value/1024</set>
    +                        <set token="df_storage_unit_legend">GB</set>
    +                    </condition>
    +                    <condition value="TB">
    +                        <set token="df_storage_unit_math">value/1024/1204</set>
    +                        <set token="df_storage_unit_legend">TB</set>
    +                    </condition>
    +                    <condition value="pct">
    +                        <set token="df_storage_unit_math">value</set>
    +                        <set token="df_storage_unit_legend">pct</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$start_df_storage_search$ $jfs_chart2$">
    +                <title>Data source: $storage_usage_datasource$</title>
    +                <search depends="$start_df_storage_search$ $jfs_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.*" $host$ dimension_mount="$df_storage_mount$" by host, metric_name, dimension_mount span=1m
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free
    +| foreach storage, storage_free, storage_used [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;'/1024, 2) ]
    +| stats latest(storage*) as "storage*" by _time, dimension_mount, host
    +| eval value=$df_storage_monitor$
    +| eval value=$df_storage_unit_math$
    +| timechart $span$ latest(value) as $df_storage_monitor$ by dimension_mount</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">$df_storage_unit_legend$</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">$df_storage_monitor_max_chart$</option>
    +            </chart>
    +
    +            <!-- JFSFILE -->
    +
    +            <input type="text" token="fsfilter" searchWhenChanged="true" depends="$start_jfs_storage_search$ $jfs_chart2$">
    +                <label>mount:</label>
    +                <default>*</default>
    +            </input>
    +
    +            <chart depends="$start_jfs_storage_search$ $jfs_chart2$">
    +                <title>Data source: $storage_usage_datasource$</title>
    +                <search depends="$start_jfs_storage_search$ $jfs_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsfile" $host$ dimension_mount="$fsfilter$" by host, dimension_mount span=1m
    +| timechart $span$ limit=0 useother=f latest(value) As value by dimension_mount</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% Used</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +            <!--
    +
    +            ### file systems inodes utilisation over time ###
    +
    +            file systems inodes utilisation, either DF_INODES (default) or JFSINODE
    +            -->
    +
    +            <!-- DF_INODES -->
    +
    +            <input type="text" token="df_storage_mount" depends="$start_df_storage_search$ $jfs_chart3$">
    +              <label>mount</label>
    +              <default>*</default>
    +            </input>
    +
    +            <input type="dropdown" token="chart_df_inodes_monitor" depends="$start_df_storage_search$ $jfs_chart3$">
    +                <label>Monitor:</label>
    +                <choice value="storage_used_inodes">storage_used_inodes</choice>
    +                <choice value="storage_free_inodes_percent">storage_free_inodes_percent (%)</choice>
    +                <choice value="storage_used_inodes_percent">storage_used_inodes_percent (%)</choice>
    +                <default>storage_used_inodes_percent</default>
    +                <change>
    +                    <condition value="storage_used_inodes">
    +                        <set token="chart_df_inodes_unit_legend">nb inodes</set>
    +                    </condition>
    +                    <condition value="storage_free_inodes_percent">
    +                        <set token="chart_df_inodes_unit_legend">pct</set>
    +                    </condition>
    +                    <condition value="storage_used_inodes_percent">
    +                        <set token="chart_df_inodes_unit_legend">pct</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$start_df_storage_search$ $jfs_chart3$">
    +                <title>Data source: $storage_inodes_usage_datasource$</title>
    +                <search depends="$start_df_storage_search$ $jfs_chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_inodes.*" $host$ by host, metric_name, dimension_mount span=1m
    +| eval IUse_pct=case(metric_name=="os.unix.nmon.storage.df_inodes.IUse_pct", value), IUsed=case(metric_name=="os.unix.nmon.storage.df_inodes.IUsed", value)
    +| stats values(IUse_pct) as IUse_pct, values(IUsed) as IUsed by _time, dimension_mount
    +| eval IFree_pct=(100-IUse_pct)
    +| rename IUse_pct as storage_used_inodes_percent, IFree_pct as storage_free_inodes_percent, values(IUsed) as storage_used_inodes
    +| timechart $span$ latest($chart_df_inodes_monitor$) as $chart_df_inodes_monitor$ by dimension_mount</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">$chart_df_inodes_unit_legend$</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">$chart_df_inodes_monitor_max_chart$</option>
    +            </chart>
    +
    +            <!-- JFSINODE -->
    +
    +            <html depends="$start_jfs_storage_search$ $jfs_chart3$">
    +                <p style="color:blue;margin-left:30px;font-size:14px">On Linux systems, the inodes statistics are only available within the DF_INODES external collection.</p>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="network">
    +            <title>NETWORK Usage Statistics</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="net_linkinput">
    +                <label></label>
    +                <choice value="net_chart1">NET - Inbound/Outbound traffic</choice>
    +                <choice value="net_chart2">NETPACKET - Inbound/Outbound packets</choice>
    +                <default>net_chart1</default>
    +                <change>
    +                    <condition value="net_chart1">
    +                        <set token="net_chart1">true</set>
    +                        <unset token="net_chart2"></unset>
    +                    </condition>
    +                    <condition value="net_chart2">
    +                        <set token="net_chart2">true</set>
    +                        <unset token="net_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$net_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.net $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Outbound KBps / Inbound KBps</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.net $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$net_chart2$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.netpacket $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Outbound / Inbound packets</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.netpacket $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <!--
    +    NFS server / client: only show the panels if we have data
    +    -->
    +
    +    <!-- NFS v2 data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.network.nfs*v2.*" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_nfsv2_searches"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_nfsv2_searches">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- NFS v3 data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.network.nfs*v3.*" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_nfsv3_searches"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_nfsv3_searches">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- NFS v4 data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.network.nfs*v4.*" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_nfsv4_searches"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_nfsv4_searches">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- NFS v2 -->
    +
    +    <row depends="$start_nfsv2_searches$">
    +        <panel>
    +
    +            <input type="link" token="nfsv2_linkinput">
    +                <label></label>
    +                <choice value="nfssvrv2">NFS Server v2</choice>
    +                <choice value="nfscliv2">NFS Client v2</choice>
    +                <default>nfssvrv2</default>
    +                <change>
    +                    <condition value="nfssvrv2">
    +                        <set token="show_nfssvrv2">true</set>
    +                        <unset token="show_nfscliv2"></unset>
    +                    </condition>
    +                    <condition value="nfscliv2">
    +                        <set token="show_nfscliv2">true</set>
    +                        <unset token="show_nfssvrv2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$show_nfssvrv2$">
    +                <title></title>
    +                <search depends="$start_nfsv2_searches$ $show_nfssvrv2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv2.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nbr of Operations</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv2.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$show_nfscliv2$">
    +                <title></title>
    +                <search depends="$start_nfsv2_searches$ $show_nfscliv2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv2.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nbr of Operations</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv2.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- NFS v3 -->
    +
    +    <row depends="$start_nfsv3_searches$">
    +        <panel>
    +
    +            <input type="link" token="nfsv3_linkinput">
    +                <label></label>
    +                <choice value="nfssvrv3">NFS Server v3</choice>
    +                <choice value="nfscliv3">NFS Client v3</choice>
    +                <default>nfssvrv3</default>
    +                <change>
    +                    <condition value="nfssvrv3">
    +                        <set token="show_nfssvrv3">true</set>
    +                        <unset token="show_nfscliv3"></unset>
    +                    </condition>
    +                    <condition value="nfscliv3">
    +                        <set token="show_nfscliv3">true</set>
    +                        <unset token="show_nfssvrv3"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$show_nfssvrv3$">
    +                <title></title>
    +                <search depends="$start_nfsv3_searches$ $show_nfssvrv3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv3.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nbr of Operations</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv3.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$show_nfscliv3$">
    +                <title></title>
    +                <search depends="$start_nfsv3_searches$ $show_nfscliv3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv3.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nbr of Operations</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv3.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- NFS v4 -->
    +
    +    <row depends="$start_nfsv4_searches$">
    +        <panel>
    +
    +            <input type="link" token="nfsv4_linkinput">
    +                <label></label>
    +                <choice value="nfssvrv4">NFS Server v4</choice>
    +                <choice value="nfscliv4">NFS Client v4</choice>
    +                <default>nfssvrv4</default>
    +                <change>
    +                    <condition value="nfssvrv4">
    +                        <set token="show_nfssvrv4">true</set>
    +                        <unset token="show_nfscliv4"></unset>
    +                    </condition>
    +                    <condition value="nfscliv4">
    +                        <set token="show_nfscliv4">true</set>
    +                        <unset token="show_nfssvrv4"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$show_nfssvrv4$">
    +                <title></title>
    +                <search depends="$start_nfsv4_searches$ $show_nfssvrv4$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv4.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nbr of Operations</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv4.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$show_nfscliv4$">
    +                <title></title>
    +                <search depends="$start_nfsv4_searches$ $show_nfscliv4$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv4.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nbr of Operations</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv4.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_ANALYSER_SOLARIS.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_ANALYSER_SOLARIS.xml
    new file mode 100644
    index 0000000..04eb00d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_ANALYSER_SOLARIS.xml
    @@ -0,0 +1,2832 @@
    +<form stylesheet="ui_simple.css,hide_timeindicator.css,table_data_bar.css,panel_decoration.css" script="autodiscover.js,table_data_bar.js" isVisible="true" version="1.1" theme="dark">
    +    <label>NMON Analyser SOLARIS</label>
    +
    +    <!--
    +    base search for main dropdown populating
    +    -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $osfilter$ host="$host-prefilter$" by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Information panel -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader2">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +
    +                    <h4>Nmon Analyser interfaces have been designed for focused time ranges, very large time ranges may require time to be fully processed</h4>
    +                    <h4>For long time analysis, please consider using metric dedicated interfaces available from App home pages</h4>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Selection panel -->
    +
    +    <row>
    +        <panel>
    +
    +            <input type="time" token="timerange" searchWhenChanged="true">
    +                <label>Time Range:</label>
    +                <default>
    +                    <earliest>-24h</earliest>
    +                    <latest>now</latest>
    +                </default>
    +            </input>
    +
    +            <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +                <label>Filter OS Type:</label>
    +                <default>Solaris</default>
    +                <prefix>OStype="</prefix>
    +                <suffix>"</suffix>
    +                <choice value="*">Any OS</choice>
    +                <choice value="Solaris">Solaris</choice>
    +            </input>
    +
    +            <input id="frameID" type="dropdown" token="frameID" searchWhenChanged="true">
    +                <label>Frame IDs:</label>
    +                <search base="populate">
    +                    <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +                </search>
    +                <choice value="*">Any</choice>
    +                <initialValue>*</initialValue>
    +                <fieldForLabel>frameID</fieldForLabel>
    +                <fieldForValue>frameID</fieldForValue>
    +                <prefix>frameID="</prefix>
    +                <suffix>"</suffix>
    +            </input>
    +
    +            <input type="text" token="host-prefilter" searchWhenChanged="true">
    +                <label>Optional: Filter hosts populating</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input id="host" type="dropdown" token="host" searchWhenChanged="true">
    +                <label>Host:</label>
    +                <search base="populate">
    +                    <query>search $frameID$ | stats count by host | dedup host | sort 0 host</query>
    +                </search>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +                <prefix>host="</prefix>
    +                <suffix>"</suffix>
    +            </input>
    +
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- DF_STORAGE data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.Use_pct" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <set token="start_jfs_storage_search">true</set>
    +                    <set token="storage_usage_datasource">JFSFILE</set>
    +                    <unset token="start_df_storage_search"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_df_storage_search">true</set>
    +                    <set token="storage_usage_datasource">DF_STORAGE</set>
    +                    <unset token="start_jfs_storage_search"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- Configuration Search uses the nmon_inventory data over the report -->
    +
    +    <search ref="NMON Inventory Solaris" id="configSearch">
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <title>SYSTEM SUMMARY OVERVIEW</title>
    +
    +            <table rejects="$show_null_config$">
    +                <title></title>
    +                <search base="configSearch">
    +                    <query>rename hostname AS host | search $host$ | fields - host,Virtual_mem_MB</query>
    +                    <!-- Progress event has access to job properties only -->
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_null_config">True</set>
    +                        </condition>
    +                        <condition>
    +                            <unset token="show_null_config"/>
    +                        </condition>
    +                    </progress>
    +                </search>
    +            </table>
    +            <html depends="$show_null_config$">
    +                <p style="color:blue;margin-left:30px;font-size:14px">SYSTEM SUMMARY OVERVIEW Search returned no results, The nmon inventory data may not be available yet for this host, manually run the Nmon Inventory Generation report or wait for the auto update. (occurs every hour by default)</p>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label></label>
    +                <default>max</default>
    +                <choice value="max">max</choice>
    +                <choice value="avg">avg</choice>
    +            </input>
    +
    +            <chart>
    +                <title>CPU Usage</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` $host$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart $span$ $statsmode$(cpu_load_percent) AS cpu_load_percent</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">CPU Usage</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` $host$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart $span$ $statsmode$(cpu_load_percent) AS cpu_load_percent
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +        <panel>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label></label>
    +                <default>max</default>
    +                <choice value="max">max</choice>
    +                <choice value="avg">avg</choice>
    +            </input>
    +
    +            <chart>
    +                <title>I/O Per second</title>
    +                <search>
    +                    <query>| mstats sum(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" $host$ by host, metric_name span=1m
    +| timechart $span$ $statsmode$(value) as avg_iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">I/O per Sec</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats sum(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" $host$ by host, metric_name span=1m
    +| timechart $span$ $statsmode$(value) as avg_iops
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>CPU statistics</title>
    +        </panel>
    +    </row>
    +
    +    <search id="CPU_ALL">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT) $host$ by metric_name, host span=1m
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent by _time, host
    +| fillnull value=0 Sys_percent,User_percent,Wait_percent
    +| eval cpu_load_percent=(Sys_percent+User_percent+Wait_percent)
    +| timechart $span$
    +avg(Idle_percent) AS "Idle %",
    +avg(Sys_percent) AS "Sys %",
    +avg(User_percent) AS "User %",
    +avg(Wait_percent) AS "Wait %",
    +avg(cpu_load_percent) as "CPU %"</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="cpu_all_linkinput">
    +                <label></label>
    +                <choice value="cpu_all_chart1">CPU_ALL, % by category</choice>
    +                <choice value="cpu_all_chart2">CPU_ALL, % global usage</choice>
    +                <choice value="cpu_nn_chart1">CPUnn, % global usage by processor</choice>
    +                <default>cpu_all_chart1</default>
    +                <change>
    +                    <condition value="cpu_all_chart1">
    +                        <set token="cpu_all_chart1">true</set>
    +                        <unset token="cpu_all_chart2"></unset>
    +                        <unset token="cpu_nn_chart1"></unset>
    +                    </condition>
    +                    <condition value="cpu_all_chart2">
    +                        <set token="cpu_all_chart2">true</set>
    +                        <unset token="cpu_all_chart1"></unset>
    +                        <unset token="cpu_nn_chart1"></unset>
    +                    </condition>
    +                    <condition value="cpu_nn_chart1">
    +                        <set token="cpu_nn_chart1">true</set>
    +                        <unset token="cpu_all_chart1"></unset>
    +                        <unset token="cpu_all_chart2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$cpu_all_chart1$">
    +                <title></title>
    +                <search base="CPU_ALL">
    +                    <query>fields _time,"Idle %","Sys %","User %","Wait %"</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% of CPUs utilization</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT) $host$ by metric_name, host span=1m
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent by _time, host
    +| eval cpu_load_percent=(Sys_percent%2BUser_percent%2BWait_percent)
    +| timechart $span$ avg(Idle_percent) AS Idle_percent, avg(Sys_percent) AS Sys_percent, avg(User_percent) AS User_percent, avg(Wait_percent) AS Wait_percent, avg(cpu_load_percent) as cpu_load_percent
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$cpu_all_chart2$">
    +                <title></title>
    +                <search base="CPU_ALL">
    +                    <query>fields _time,"CPU %"</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% of CPUs utilization</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT) $host$ by metric_name, host span=1m
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent by _time, host
    +| eval cpu_load_percent=(Sys_percent%2BUser_percent%2BWait_percent)
    +| timechart $span$ avg(Idle_percent) AS Idle_percent, avg(Sys_percent) AS Sys_percent, avg(User_percent) AS User_percent, avg(Wait_percent) AS Wait_percent, avg(cpu_load_percent) as cpu_load_percent
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$cpu_nn_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* $host$ by metric_name span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT by _time, cpu_core | fillnull value=0
    +| fillnull value=0 Sys_PCT,User_PCT,Wait_PCT
    +| eval cpu_PCT=(Sys_PCT+User_PCT+Wait_PCT)
    +| timechart $span$ useother=f limit=0 avg(cpu_PCT) AS cpu_PCT by cpu_core</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% of CPU utilization</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* $host$ by metric_name span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT by _time, cpu_core | fillnull value=0
    +| eval cpu_PCT=(Sys_PCT%2BUser_PCT%2BWait_PCT)
    +| timechart $span$ useother=f limit=0 avg(cpu_PCT) AS cpu_PCT by cpu_core
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="wlm_cpu_all_linkinput">
    +                <label></label>
    +                <choice value="wlm_cpu_all_chart1">WLM, % CPU by Zone</choice>
    +                <choice value="wlm_cpu_all_chart2">WLM, % CPU by Project</choice>
    +                <choice value="wlm_cpu_all_chart3">WLM, % CPU by Task</choice>
    +                <choice value="wlm_cpu_all_chart4">WLM, % CPU by User</choice>
    +                <default>wlm_cpu_all_chart1</default>
    +                <change>
    +                    <condition value="wlm_cpu_all_chart1">
    +                        <set token="wlm_cpu_all_chart1">true</set>
    +                        <unset token="wlm_cpu_all_chart2"></unset>
    +                        <unset token="wlm_cpu_all_chart3"></unset>
    +                        <unset token="wlm_cpu_all_chart4"></unset>
    +                    </condition>
    +                    <condition value="wlm_cpu_all_chart2">
    +                        <set token="wlm_cpu_all_chart2">true</set>
    +                        <unset token="wlm_cpu_all_chart1"></unset>
    +                        <unset token="wlm_cpu_all_chart3"></unset>
    +                        <unset token="wlm_cpu_all_chart4"></unset>
    +                    </condition>
    +                    <condition value="wlm_cpu_all_chart3">
    +                        <set token="wlm_cpu_all_chart3">true</set>
    +                        <unset token="wlm_cpu_all_chart1"></unset>
    +                        <unset token="wlm_cpu_all_chart2"></unset>
    +                        <unset token="wlm_cpu_all_chart4"></unset>
    +                    </condition>
    +                    <condition value="wlm_cpu_all_chart4">
    +                        <set token="wlm_cpu_all_chart4">true</set>
    +                        <unset token="wlm_cpu_all_chart1"></unset>
    +                        <unset token="wlm_cpu_all_chart2"></unset>
    +                        <unset token="wlm_cpu_all_chart3"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +            
    +            <chart depends="$wlm_cpu_all_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmzonecpu $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPUs</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmzonecpu dimension_device="$click.name2$" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$wlm_cpu_all_chart2$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmprojectcpu $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPUs</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmprojectcpu dimension_device="$click.name2$" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$wlm_cpu_all_chart3$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmtaskcpu $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPUs</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmtaskcpu dimension_device="$click.name2$" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$wlm_cpu_all_chart4$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmusercpu $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPUs</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmusercpu dimension_device="$click.name2$" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Process, Kernel, I/O Statistics</title>
    +        </panel>
    +    </row>
    +
    +    <!-- TOP data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_top_search"></unset>
    +                    <set token="show_null_top"></set>
    +            </condition>
    +            <condition>
    +                    <set token="start_top_search">true</set>
    +                    <unset token="show_null_top"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="top_linkinput">
    +                <label></label>
    +                <choice value="top_chart1">TOP, CPU Usage per logical core</choice>
    +                <choice value="top_chart2">TOP, Physical Memory (RSS) Usage per command invocation</choice>
    +                <choice value="top_chart3">TOP, Virtual Memory (SIZE) Usage per command invocation</choice>
    +                <choice value="top_chart4">TOP, Paging, Sum of page faults</choice>
    +                <choice value="top_chart5">TOP, Threads per Command invocation</choice>
    +                <choice value="top_chart6">TOP, Count of bytes/sec being passed via the read and write system calls</choice>
    +                <default>top_chart1</default>
    +                <change>
    +                    <condition value="top_chart1">
    +                        <set token="top_chart1">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                    </condition>
    +                    <condition value="top_chart2">
    +                        <set token="top_chart2">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                    </condition>
    +                    <condition value="top_chart3">
    +                        <set token="top_chart3">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                    </condition>
    +                    <condition value="top_chart4">
    +                        <set token="top_chart4">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                    </condition>
    +                    <condition value="top_chart5">
    +                        <set token="top_chart5">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart6"></unset>
    +                    </condition>
    +                    <condition value="top_chart6">
    +                        <set token="top_chart6">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$top_chart1$">
    +                <title></title>
    +                <search depends="$top_chart1$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| timechart $span$ useother=f limit="50" max(usage_per_core) as "CPU Usage per core" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Logical Core</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" dimension_Command="$click.name2$" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| timechart $span$ useother=f limit="50" max(usage_per_core) as "CPU Usage per core" by dimension_Command
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart2$">
    +                <title></title>
    +                <search depends="$top_chart2$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSize" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| eval Used_Mem_MB=((value)/1024)
    +| timechart $span$ useother=f limit="50" avg(Used_Mem_MB) as "memory usage (MB)" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSize" dimension_Command="$click.name2$" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| eval Used_Mem_MB=((value)/1024)
    +| timechart $span$ useother=f limit="50" avg(Used_Mem_MB) as "memory usage (MB)" by dimension_Command
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart3$">
    +                <title></title>
    +                <search depends="$top_chart3$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Size" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| eval Used_Mem_MB=((value)/1024)
    +| timechart $span$ useother=f limit="50" avg(Used_Mem_MB) as "memory usage (MB)" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Size" dimension_Command="$click.name2$" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| eval Used_Mem_MB=((value)/1024)
    +| timechart $span$ useother=f limit="50" avg(Used_Mem_MB) as "memory usage (MB)" by dimension_Command
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart4$">
    +                <title></title>
    +                <search depends="$top_chart4$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Paging" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as "Paging" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Page</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Paging" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as "Paging" by dimension_Command
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart5$">
    +                <title></title>
    +                <search depends="$top_chart5$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Threads" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as "Threads" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Threads</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Threads" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as "Paging" by dimension_Command
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart6$">
    +                <title></title>
    +                <search depends="$top_chart6$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.CharIO" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as "CharIO" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">bytes/sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.CharIO" $host$ by dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as "CharIO" by dimension_Command
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <html depends="$show_null_top$">
    +                <p style="color:blue;margin-left:30px;font-size:14px">Search returned no results, TOP collection (processes activity) has not been activated or no processes were captured due to lack of activity</p>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="FILE">
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.file.*" $host$ by metric_name span=1m
    +| `extract_metrics("readch writech iget namei dirblk ttycanch ttyoutch ttyrawch")`
    +| stats values(readch) as readch, values(writech) as writech
    +values(iget) as iget, values(namei) as namei, values(dirblk) as dirblk
    +values(ttycanch) as ttycanch, values(ttyoutch) as ttyoutch, values(ttyrawch) as ttyrawch by _time
    +| timechart $span$ max(readch) as readch, max(writech) as writech
    +max(iget) as iget, max(namei) as namei, max(dirblk) as dirblk
    +max(ttycanch) as ttycanch, max(ttyoutch) as ttyoutch, max(ttyrawch) as ttyrawch</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="file_linkinput">
    +                <label></label>
    +                <choice value="file_chart1">FILE, Read/Write system calls</choice>
    +                <choice value="file_chart2">FILE, Various statistics</choice>
    +                <default>file_chart1</default>
    +                <change>
    +                    <condition value="file_chart1">
    +                        <set token="file_chart1">true</set>
    +                        <unset token="file_chart2"></unset>
    +                    </condition>
    +                    <condition value="file_chart2">
    +                        <set token="file_chart2">true</set>
    +                        <unset token="file_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$file_chart1$">
    +                <title></title>
    +                <search base="FILE">
    +                    <query>fields _time,readch,writech</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rate/Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.file.*" $host$ by metric_name span=1m
    +| `extract_metrics("readch writech iget namei dirblk ttycanch ttyoutch ttyrawch")`
    +| stats values(readch) as readch, values(writech) as writech
    +values(iget) as iget, values(namei) as namei, values(dirblk) as dirblk
    +values(ttycanch) as ttycanch, values(ttyoutch) as ttyoutch, values(ttyrawch) as ttyrawch by _time
    +| timechart $span$ max(readch) as readch, max(writech) as writech
    +max(iget) as iget, max(namei) as namei, max(dirblk) as dirblk
    +max(ttycanch) as ttycanch, max(ttyoutch) as ttyoutch, max(ttyrawch) as ttyrawch
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$file_chart2$">
    +                <title></title>
    +                <search base="FILE">
    +                    <query>fields _time,iget,namei,dirblk,ttycanch,ttyoutch,ttyrawch</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rate/Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.file.*" $host$ by metric_name span=1m
    +| `extract_metrics("readch writech iget namei dirblk ttycanch ttyoutch ttyrawch")`
    +| stats values(readch) as readch, values(writech) as writech
    +values(iget) as iget, values(namei) as namei, values(dirblk) as dirblk
    +values(ttycanch) as ttycanch, values(ttyoutch) as ttyoutch, values(ttyrawch) as ttyrawch by _time
    +| timechart $span$ max(readch) as readch, max(writech) as writech
    +max(iget) as iget, max(namei) as namei, max(dirblk) as dirblk
    +max(ttycanch) as ttycanch, max(ttyoutch) as ttyoutch, max(ttyrawch) as ttyrawch
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="PROC">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.proc.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="proc_linkinput">
    +                <label></label>
    +                <choice value="proc_chart1">PROC, Kernel Threads in run queue and to be paged (RunQueue, Swap-In)</choice>
    +                <choice value="proc_chart2">PROC, Context switches and system calls (pswitch, syscall)</choice>
    +                <choice value="proc_chart3">PROC, Fork and Exec system calls (fork, exec)</choice>
    +                <default>proc_chart1</default>
    +                <change>
    +                    <condition value="proc_chart1">
    +                        <set token="proc_chart1">true</set>
    +                        <unset token="proc_chart2"></unset>
    +                        <unset token="proc_chart3"></unset>
    +                    </condition>
    +                    <condition value="proc_chart2">
    +                        <set token="proc_chart2">true</set>
    +                        <unset token="proc_chart1"></unset>
    +                        <unset token="proc_chart3"></unset>
    +                    </condition>
    +                    <condition value="proc_chart3">
    +                        <set token="proc_chart3">true</set>
    +                        <unset token="proc_chart2"></unset>
    +                        <unset token="proc_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$proc_chart1$">
    +                <title></title>
    +                <search base="PROC">
    +                    <query>fields _time,Runnable,Swap_in</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Value</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.proc.Runnable OR metric_name=os.unix.nmon.kernel.proc.Swap_in $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$proc_chart2$">
    +                <title></title>
    +                <search base="PROC">
    +                    <query>fields _time,pswitch,syscall</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rates per Second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.proc.pswitch OR metric_name=os.unix.nmon.kernel.proc.syscall $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$proc_chart3$">
    +                <title></title>
    +                <search base="PROC">
    +                    <query>fields _time,fork,exec</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rates per Second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.proc.fork OR metric_name=os.unix.nmon.kernel.proc.exec $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="procsol_linkinput">
    +                <label></label>
    +                <choice value="procsol_chart1">PROCSOL, Percentage of Time All processes have spent in: (estimation since terminated processes are not accounted)</choice>
    +                <default>procsol_chart1</default>
    +                <change>
    +                    <condition value="procsol_chart1">
    +                        <set token="procsol_chart1">true</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$procsol_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.procsol.* by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ avg(value) by metric
    +| rename USR as "USR (%time in User Mode)",
    +SYS as "SYS (%time in System Mode)",
    +TRP as "TRP (%time Processing system traps)",
    +TFL as "TFL (%time Processing text page faults)",
    +DFL as "DFL (%time Processing data page faults)",
    +LAT as "LAT (%time Waiting for CPU)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">% Of Time</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.procsol.* by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ avg(value) by metric
    +| rename USR as "USR (pct_time in User Mode)",
    +SYS as "SYS (pct_time in System Mode)",
    +TRP as "TRP (pct_time Processing system traps)",
    +TFL as "TFL (pct_time Processing text page faults)",
    +DFL as "DFL (pct_time Processing data page faults)",
    +LAT as "LAT (pct_time Waiting for CPU)"
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="VM">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="vm_linkinput">
    +                <label></label>
    +                <choice value="vm_chart1">VM, (pages/s) Minor faults and major faults</choice>
    +                <choice value="vm_chart2">VM, (pages/s) Pages IN and OUT</choice>
    +                <choice value="vm_chart3">VM, (pages/s) Pages examined and freed by pageout daemon</choice>
    +                <choice value="vm_chart4">VM, (KB/s) Pages paged IN and OUT</choice>
    +                <choice value="vm_chart5">VM, (KB/s) Pages swapped IN and OUT</choice>
    +                <choice value="vm_chart6">VM, (KB/s) Pages freed by daemon or auto</choice>
    +                <default>vm_chart1</default>
    +                <change>
    +                    <condition value="vm_chart1">
    +                        <set token="vm_chart1">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                    </condition>
    +                    <condition value="vm_chart2">
    +                        <set token="vm_chart2">true</set>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                    </condition>
    +                    <condition value="vm_chart3">
    +                        <set token="vm_chart3">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                    </condition>
    +                    <condition value="vm_chart4">
    +                        <set token="vm_chart4">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                    </condition>
    +                    <condition value="vm_chart5">
    +                        <set token="vm_chart5">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                        <unset token="vm_chart6"></unset>
    +                    </condition>
    +                    <condition value="vm_chart6">
    +                        <set token="vm_chart6">true</set>
    +                        <unset token="vm_chart2"></unset>
    +                        <unset token="vm_chart3"></unset>
    +                        <unset token="vm_chart4"></unset>
    +                        <unset token="vm_chart5"></unset>
    +                        <unset token="vm_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$vm_chart1$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,minfaults,majfaults</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,*minfaults*,*majfaults*
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart2$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pgin,pgout</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,*pgin*,*pgout*
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart3$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,scans,reclaims</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,*scans*,*reclaims*
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart4$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pgpgin,pgpgout</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,*pgpgin*,*pgpgout*
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart5$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pswpin,pswpout</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KB/s</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,*pswpin*,*pswpout*
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$vm_chart6$">
    +                <title></title>
    +                <search base="VM">
    +                    <query>fields _time,pgfree</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KB/s</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,*pgfree*
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="memory">
    +            <title>MEMORY Usage Statistics</title>
    +        </panel>
    +    </row>
    +
    +    <search id="MEM">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.memuse.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="MEMUSE">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.memuse.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="mem_linkinput">
    +                <label></label>
    +                <choice value="mem_chart1">MEM, Memory/Swap usage (% usage)</choice>
    +                <choice value="mem_chart2">MEM, Memory usage (Volume usage in MB)</choice>
    +                <choice value="mem_chart3">MEM, Swap usage (Volume usage in MB)</choice>
    +                <choice value="mem_chart4">MEMUSE, Cache Hit Ratio (%)</choice>
    +                <choice value="mem_chart5">MEMUSE, System Buffer Accesses</choice>
    +                <choice value="mem_chart6">MEMUSE, Transfers using raw (physical) device mechanism</choice>
    +                <choice value="mem_chart7">MEMUSE, Transfer of data between system buffers and disk or other block device</choice>
    +                <default>mem_chart1</default>
    +                <change>
    +                    <condition value="mem_chart1">
    +                        <set token="mem_chart1">true</set>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                        <unset token="mem_chart6"></unset>
    +                        <unset token="mem_chart7"></unset>
    +                    </condition>
    +                    <condition value="mem_chart2">
    +                        <set token="mem_chart2">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                        <unset token="mem_chart6"></unset>
    +                        <unset token="mem_chart7"></unset>
    +                    </condition>
    +                    <condition value="mem_chart3">
    +                        <set token="mem_chart3">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                        <unset token="mem_chart6"></unset>
    +                        <unset token="mem_chart7"></unset>
    +                    </condition>
    +                    <condition value="mem_chart4">
    +                        <set token="mem_chart4">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                        <unset token="mem_chart6"></unset>
    +                        <unset token="mem_chart7"></unset>
    +                    </condition>
    +                    <condition value="mem_chart5">
    +                        <set token="mem_chart5">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart6"></unset>
    +                        <unset token="mem_chart7"></unset>
    +                    </condition>
    +                    <condition value="mem_chart6">
    +                        <set token="mem_chart6">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                        <unset token="mem_chart7"></unset>
    +                    </condition>
    +                    <condition value="mem_chart7">
    +                        <set token="mem_chart7">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                        <unset token="mem_chart6"></unset>
    +                    </condition>
    +                    <condition value="mem_chart8">
    +                        <set token="mem_chart8">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                        <unset token="mem_chart6"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$mem_chart1$">
    +                <title></title>
    +                <search depends="$mem_chart1$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" $host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart $span$ avg(mem_used_effective_PCT) as "mem used (%)", avg(swap_used_effective_PCT) as "swap used (%)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" $host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart $span$ avg(mem_used_effective_PCT) as "mem used (pct)", avg(swap_used_effective_PCT) as "swap used (pct)"
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$mem_chart2$">
    +                <title></title>
    +                <search depends="$mem_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" $host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| timechart $span$ avg(mem_used_effective) as "memused (MB)", avg(memtotal) as "memtotal (MB)", avg(memfree) as "memfree (MB)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" $host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| timechart $span$ avg(mem_used_effective) as "memused (MB)", avg(memtotal) as "memtotal (MB)", avg(memfree) as "memfree (MB)"
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$mem_chart3$">
    +                <title></title>
    +                <search depends="$mem_chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" $host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| timechart $span$ avg(swap_used_effective) as "swapused (MB)", avg(swaptotal) as "swaptotal (MB)", avg(swapfree) as "swapfree (MB)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" $host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| timechart $span$ avg(swap_used_effective) as "swapused (MB)", avg(swaptotal) as "swaptotal (MB)", avg(swapfree) as "swapfree (MB)"
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$mem_chart4$">
    +                <title></title>
    +                <search base="MEMUSE">
    +                    <query>fields _time,PCTrcache,PCTwcache</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Memory %</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.memuse.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,PCTrcache,PCTwcache
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$mem_chart5$">
    +                <title></title>
    +                <search base="MEMUSE">
    +                    <query>fields _time,lread,lwrite</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Volume per second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.memuse.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,lread,lwrite
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$mem_chart6$">
    +                <title></title>
    +                <search base="MEMUSE">
    +                    <query>fields _time,pread,pwrite</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Volume per second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.memuse.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,pread,pwrite
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$mem_chart7$">
    +                <title></title>
    +                <search base="MEMUSE">
    +                    <query>fields _time,bread,bwrite</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Volume per second</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.memuse.* $host$ by metric_name span=1m
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric | fields _time,bread,bwrite
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="wlm_mem_linkinput">
    +                <label></label>
    +                <choice value="wlm_mem_chart1">WLM, % MEM by Zone</choice>
    +                <choice value="wlm_mem_chart2">WLM, % MEM by Project</choice>
    +                <choice value="wlm_mem_chart3">WLM, % MEM by Task</choice>
    +                <choice value="wlm_mem_chart4">WLM, % MEM by User</choice>
    +                <default>wlm_mem_chart1</default>
    +                <change>
    +                    <condition value="wlm_mem_chart1">
    +                        <set token="wlm_mem_chart1">true</set>
    +                        <unset token="wlm_mem_chart2"></unset>
    +                        <unset token="wlm_mem_chart3"></unset>
    +                        <unset token="wlm_mem_chart4"></unset>
    +                    </condition>
    +                    <condition value="wlm_mem_chart2">
    +                        <set token="wlm_mem_chart2">true</set>
    +                        <unset token="wlm_mem_chart1"></unset>
    +                        <unset token="wlm_mem_chart3"></unset>
    +                        <unset token="wlm_mem_chart4"></unset>
    +                    </condition>
    +                    <condition value="wlm_mem_chart3">
    +                        <set token="wlm_mem_chart3">true</set>
    +                        <unset token="wlm_mem_chart1"></unset>
    +                        <unset token="wlm_mem_chart2"></unset>
    +                        <unset token="wlm_mem_chart4"></unset>
    +                    </condition>
    +                    <condition value="wlm_mem_chart4">
    +                        <set token="wlm_mem_chart4">true</set>
    +                        <unset token="wlm_mem_chart1"></unset>
    +                        <unset token="wlm_mem_chart2"></unset>
    +                        <unset token="wlm_mem_chart3"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$wlm_mem_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmzonemem $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% MEM</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmzonemem dimension_device="$click.name2$" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$wlm_mem_chart2$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmprojectmem $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% MEM</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmprojectmem dimension_device="$click.name2$" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$wlm_mem_chart3$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmtaskmem $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% MEM</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmtaskmem dimension_device="$click.name2$" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$wlm_mem_chart4$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmusermem $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% MEM</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.wlmusermem dimension_device="$click.name2$" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="disk">
    +            <title>Disks performance statistics (active drill-down: click on one of the charts for dimension devices)</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="disk_linkinput">
    +                <label></label>
    +                <choice value="disk_chart1">DISKBSIZE, Average data transfer size</choice>
    +                <choice value="disk_chart2">DISKBUSY, Disk Busy Activity</choice>
    +                <choice value="disk_chart3">DISKREAD/WRITE, Disk Read/Write Data Rate</choice>
    +                <choice value="disk_chart4">DISKXFER, Disk I/O Operations per second (IOPS)</choice>
    +                <choice value="disk_chart5">DISKREAD/WRITE by XFER, Disk Read/Write I/O Operations per second (IOPS)</choice>
    +                <choice value="disk_chart6">DISKSVCTM, Disk Average service time (ms)</choice>
    +                <choice value="disk_chart7">DISKWAITTM, Disk Average wait time (ms)</choice>
    +                <default>disk_chart1</default>
    +                <change>
    +                    <condition value="disk_chart1">
    +                        <set token="disk_chart1">true</set>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                        <unset token="disk_chart6"></unset>
    +                        <unset token="disk_chart7"></unset>
    +                    </condition>
    +                    <condition value="disk_chart2">
    +                        <set token="disk_chart2">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                        <unset token="disk_chart6"></unset>
    +                        <unset token="disk_chart7"></unset>
    +                    </condition>
    +                    <condition value="disk_chart3">
    +                        <set token="disk_chart3">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                        <unset token="disk_chart6"></unset>
    +                        <unset token="disk_chart7"></unset>
    +                    </condition>
    +                    <condition value="disk_chart4">
    +                        <set token="disk_chart4">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                        <unset token="disk_chart6"></unset>
    +                        <unset token="disk_chart7"></unset>
    +                    </condition>
    +                    <condition value="disk_chart5">
    +                        <set token="disk_chart5">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                        <unset token="disk_chart6"></unset>
    +                        <unset token="disk_chart7"></unset>
    +                    </condition>
    +                    <condition value="disk_chart6">
    +                        <set token="disk_chart6">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                        <unset token="disk_chart7"></unset>
    +                    </condition>
    +                    <condition value="disk_chart7">
    +                        <set token="disk_chart7">true</set>
    +                        <unset token="disk_chart1"></unset>
    +                        <unset token="disk_chart2"></unset>
    +                        <unset token="disk_chart3"></unset>
    +                        <unset token="disk_chart4"></unset>
    +                        <unset token="disk_chart5"></unset>
    +                        <unset token="disk_chart6"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$disk_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbsize" $host$ by dimension_device span=1m
    +| stats sum(value) AS avg_transfer_size by _time
    +| timechart $span$ avg(avg_transfer_size) AS avg_transfer_size</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KBytes per Transfer</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbsize" $host$ by dimension_device span=1m
    +| timechart useother=f limit=0 $span$ avg(value) AS avg_transfer_size by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart2$">
    +                <title></title>
    +                <search depends="$disk_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbusy" $host$ by dimension_device span=1m
    +| stats avg(value) AS value by _time
    +| timechart $span$ avg(value) AS avg_busy_disk</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">% of Time Busy</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbusy" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) AS avg_busy_disk by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart3$">
    +                <title></title>
    +                <search depends="$disk_chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite") $host$ by metric_name, dimension_device span=1m
    +| eval disk_read=case(match(metric_name, "diskread"), value), diskwrite = case(match(metric_name, "diskwrite"), value)
    +| stats avg(disk_read) AS disk_read, avg(disk_write) AS disk_write by _time
    +| timechart $span$ avg(disk_read) AS disk_read, avg(disk_write) AS disk_write</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KBytes/Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite") $host$ by metric_name, dimension_device span=1m
    +| eval disk_read=case(match(metric_name, "diskread"), value), diskwrite = case(match(metric_name, "diskwrite"), value)
    +| timechart $span$ useother=f limit=0 avg(disk_read) AS disk_read, avg(disk_write) AS disk_write by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart4$">
    +                <title></title>
    +                <search depends="$disk_chart4$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" $host$ by dimension_device span=1m
    +| stats sum(value) AS iops by _time
    +| timechart $span$ avg(iops) AS iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">I/O per Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" $host$ by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) AS iops by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart5$">
    +                <title></title>
    +                <search depends="$disk_chart5$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite" OR metric_name="os.unix.nmon.storage.diskbsize") $host$ by metric_name, dimension_device span=1m
    +| eval disk_read=case(match(metric_name, "diskread"), value), disk_write=case(match(metric_name, "diskwrite"), value), disk_size=case(match(metric_name, "diskbsize"), value)
    +| stats values(disk_read) as disk_read values(disk_write) as disk_write values(disk_size) as disk_size by _time, dimension_device
    +| eval disk_read_iops=(disk_read/disk_size), disk_write_iops=(disk_write/disk_size)
    +| stats sum(disk_read_iops) as disk_read_iops, sum(disk_write_iops) as disk_write_iops by _time
    +| timechart $span$ avg(disk_read_iops) as disk_read_iops, avg(disk_write_iops) as disk_write_iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">I/O per Sec</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite" OR metric_name="os.unix.nmon.storage.diskbsize") $host$ by metric_name, dimension_device span=1m
    +| eval disk_read=case(match(metric_name, "diskread"), value), disk_write=case(match(metric_name, "diskwrite"), value), disk_size=case(match(metric_name, "diskbsize"), value)
    +| stats values(disk_read) as disk_read values(disk_write) as disk_write values(disk_size) as disk_size by _time, dimension_device
    +| eval disk_read_iops=(disk_read/disk_size), disk_write_iops=(disk_write/disk_size)
    +| stats sum(disk_read_iops) as disk_read_iops, sum(disk_write_iops) as disk_write_iops by _time, dimension_device
    +| timechart $span$ useother=f limit=0 avg(disk_read_iops) as disk_read_iops, avg(disk_write_iops) as disk_write_iops by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart6$">
    +                <title></title>
    +                <search depends="$disk_chart6$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.disksvctm" $host$ by metric_name, dimension_device span=1m
    +| timechart $span$ avg(value) as "Avg Service time"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Average service time (ms)</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.disksvctm" $host$ by metric_name, dimension_device span=1m
    +| timechart $span$ avg(value) as "Avg Service time" by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_chart7$">
    +                <title></title>
    +                <search depends="$disk_chart7$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskwaittm" $host$ by metric_name, dimension_device span=1m
    +| timechart $span$ avg(value) as "Avg Wait time"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Average wait time (ms)</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskwaittm" $host$ by metric_name, dimension_device span=1m
    +| timechart $span$ avg(value) as "Avg Wait time" by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="disk2">
    +            <title>File-systems utilization statistics</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="jfs_linkinput">
    +                <label></label>
    +                <choice value="jfs_chart1">Summary of file-systems utilization</choice>
    +                <choice value="jfs_chart2">File-systems utilization over time</choice>
    +                <default>jfs_chart1</default>
    +                <change>
    +                    <condition value="jfs_chart1">
    +                        <set token="jfs_chart1">true</set>
    +                        <unset token="jfs_chart2"></unset>
    +                        <unset token="jfs_chart3"></unset>
    +                    </condition>
    +                    <condition value="jfs_chart2">
    +                        <set token="jfs_chart2">true</set>
    +                        <unset token="jfs_chart1"></unset>
    +                        <unset token="jfs_chart3"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <!--
    +
    +            ### file systems SUMMARY ###
    +
    +            file systems utilisation, either DF_STORAGE (default) or JFSFILE
    +            -->
    +
    +            <!-- DF_STORAGE -->
    +
    +            <table id="tablebar" depends="$start_df_storage_search$ $jfs_chart1$">
    +                <title>Data source: $storage_usage_datasource$</title>
    +                <search depends="$start_df_storage_search$">
    +                    <query>| mstats latest(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.*" $host$ by host, metric_name, dimension_mount
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)
    +| stats first(Available) as Available, first(Use_pct) as Use_pct, first(Used) as Used, first(blocks) as blocks by host, dimension_mount
    +| rename dimension_mount as mount
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free
    +| foreach storage, storage_free, storage_used [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;'/1024/1024, 2) ]
    +| foreach storage*percent [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]
    +| rename storage as "storage (GB)", storage_free as "storage free (GB)", storage_used as "storage used (GB)", storage_free_percent as "storage free (%)", storage_used_percent as "storage used (%)"
    +| eval UsedPct=if(isnum('storage used (%)'), 'storage used (%)', 0 )
    +| fields mount, "storage (GB)", "storage free (GB)", "storage used (GB)", "storage free (%)", "storage used (%)", UsedPct
    +| appendpipe [ stats sum("storage (GB)") as "storage (GB)", sum("storage free (GB)") as "storage free (GB)", sum("storage used (GB)") as "storage used (GB)" ]
    +| eval "storage free (%)" = if(isnull('storage free (%)'), (('storage free (GB)'/'storage (GB)')*100), 'storage free (%)'), "storage used (%)" = if(isnull('storage used (%)'), (('storage used (GB)'/'storage (GB)')*100), 'storage used (%)'), UsedPct = if(isnull(UsedPct), 'storage used (%)', UsedPct)
    +| fillnull value="*** TOTAL GB / AVERAGE % ****" mount
    +| foreach storage*%* UsedPct [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +
    +            <!-- JFSFILE -->
    +
    +            <table depends="$start_jfs_storage_search$ $jfs_chart1$">
    +                <title>Data source: $storage_usage_datasource$</title>
    +                <search depends="$start_jfs_storage_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsfile" $host$ by host, dimension_mount span=1m
    +| stats max(value) AS max_value, avg(value) AS avg_value, min(value) AS min_value, latest(value) AS UsedPct by dimension_mount
    +| sort limit=0 dimension_mount | rename dimension_mount AS "Mount point"
    +| eval value=round(value,2)
    +| fields "Mount point",max_value, avg_value, min_value, UsedPct | eval avg_value=round(avg_value,2)
    +| rename max_value AS "Max value in period (%)", avg_value AS "Average value in period (%)", min_value AS "Min value in Period (%)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +
    +            <!--
    +
    +            ### file systems utilisation over time ###
    +
    +            file systems utilisation, either DF_STORAGE (default) or JFSFILE
    +            -->
    +
    +            <!-- DF_STORAGE -->
    +
    +            <input type="text" token="df_storage_mount" depends="$start_df_storage_search$ $jfs_chart2$">
    +              <label>mount</label>
    +              <default>*</default>
    +            </input>
    +
    +            <input type="dropdown" token="df_storage_monitor" depends="$start_df_storage_search$ $jfs_chart2$">
    +                <label>Monitor:</label>
    +                <choice value="storage">storage (volume size)</choice>
    +                <choice value="storage_free">storage_free (volume free)</choice>
    +                <choice value="storage_used">storage_used (volume used)</choice>
    +                <choice value="storage_free_percent">storage_free_percent (%)</choice>
    +                <choice value="storage_used_percent">storage_used_percent (%)</choice>
    +                <default>storage_used_percent</default>
    +                <change>
    +                    <condition value="storage">
    +                        <unset token="form.df_storage_monitor_unit"></unset>
    +                        <set token="df_storage_show_unit">true</set>
    +                        <unset token="df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_free">
    +                        <unset token="form.df_storage_monitor_unit"></unset>
    +                        <set token="df_storage_show_unit">true</set>
    +                        <unset token="df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_used">
    +                        <unset token="form.df_storage_monitor_unit"></unset>
    +                        <set token="df_storage_show_unit">true</set>
    +                        <unset token="df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_free_percent">
    +                        <set token="df_storage_unit">%</set>
    +                        <unset token="df_storage_show_unit"></unset>
    +                        <set token="df_storage_monitor_max_chart">101</set>
    +                    </condition>
    +                    <condition value="storage_used_percent">
    +                        <set token="form.df_storage_monitor_unit">pct</set>
    +                        <set token="df_storage_monitor_max_chart">101</set>
    +                        <unset token="df_storage_show_unit"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="df_storage_monitor_unit" depends="$start_df_storage_search$ $df_storage_show_unit$ $jfs_chart2$">
    +                <label>Unit:</label>
    +                <choice value="MB">MB</choice>
    +                <choice value="GB">GB</choice>
    +                <choice value="TB">TB</choice>
    +                <default>GB</default>
    +                <change>
    +                    <condition value="MB">
    +                        <set token="df_storage_unit_math">value</set>
    +                        <set token="df_storage_unit_legend">MB</set>
    +                    </condition>
    +                    <condition value="GB">
    +                        <set token="df_storage_unit_math">value/1024</set>
    +                        <set token="df_storage_unit_legend">GB</set>
    +                    </condition>
    +                    <condition value="TB">
    +                        <set token="df_storage_unit_math">value/1024/1204</set>
    +                        <set token="df_storage_unit_legend">TB</set>
    +                    </condition>
    +                    <condition value="pct">
    +                        <set token="df_storage_unit_math">value</set>
    +                        <set token="df_storage_unit_legend">pct</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$start_df_storage_search$ $jfs_chart2$">
    +                <title>Data source: $storage_usage_datasource$</title>
    +                <search depends="$start_df_storage_search$ $jfs_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.*" $host$ dimension_mount="$df_storage_mount$" by host, metric_name, dimension_mount span=1m
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free
    +| foreach storage, storage_free, storage_used [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;'/1024, 2) ]
    +| stats latest(storage*) as "storage*" by _time, dimension_mount, host
    +| eval value=$df_storage_monitor$
    +| eval value=$df_storage_unit_math$
    +| timechart $span$ latest(value) as $df_storage_monitor$ by dimension_mount</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">$df_storage_unit_legend$</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">$df_storage_monitor_max_chart$</option>
    +            </chart>
    +
    +            <!-- JFSFILE -->
    +
    +            <input type="text" token="fsfilter" searchWhenChanged="true" depends="$start_jfs_storage_search$ $jfs_chart2$">
    +                <label>mount:</label>
    +                <default>*</default>
    +            </input>
    +
    +            <chart depends="$start_jfs_storage_search$ $jfs_chart2$">
    +                <title>Data source: $storage_usage_datasource$</title>
    +                <search depends="$start_jfs_storage_search$ $jfs_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsfile" $host$ dimension_mount="$fsfilter$" by host, dimension_mount span=1m
    +| timechart $span$ limit=0 useother=f latest(value) As value by dimension_mount</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% Used</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="network2">
    +            <title>NETWORK Usage Statistics</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="link" token="net_linkinput">
    +                <label></label>
    +                <choice value="net_chart1">NET - Inbound/Outbound traffic</choice>
    +                <choice value="net_chart2">NETPACKET - Inbound/Outbound packets</choice>
    +                <choice value="net_chart3">NETERROR - Inbound/Outbound error packets</choice>
    +                <default>net_chart1</default>
    +                <change>
    +                    <condition value="net_chart1">
    +                        <set token="net_chart1">true</set>
    +                        <unset token="net_chart2"></unset>
    +                        <unset token="net_chart3"></unset>
    +                    </condition>
    +                    <condition value="net_chart2">
    +                        <set token="net_chart2">true</set>
    +                        <unset token="net_chart1"></unset>
    +                        <unset token="net_chart3"></unset>
    +                    </condition>
    +                    <condition value="net_chart3">
    +                        <set token="net_chart3">true</set>
    +                        <unset token="net_chart1"></unset>
    +                        <unset token="net_chart2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$net_chart1$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.net $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Outbound KBps / Inbound KBps</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.net $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$net_chart2$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.netpacket $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Outbound / Inbound packets</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.netpacket $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$net_chart3$">
    +                <title></title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.neterror $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Number of Network Packets</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.neterror $host$ (dimension_device!="*lo*") by dimension_device span=1m
    +| timechart $span$ useother=f limit=0 avg(value) as value by dimension_device
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_Dark.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_Dark.xml
    new file mode 100644
    index 0000000..b895d7d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_Dark.xml
    @@ -0,0 +1,449 @@
    +<form hideFooter="true" hideSplunkBar="false" hideAppBar="false" hideChrome="false" hideEdit="true" hideTitle="false" version="1.1" theme="dark">
    +    <label>Dark MONITORING</label>
    +
    +    <row>
    +        <panel>
    +
    +            <title>Select: Timerange - Auto-refresh - frameID - host</title>
    +
    +            <input type="time" token="timerange">
    +                <label>Time range:</label>
    +                <default>
    +                    <earliest>-24h@h</earliest>
    +                    <latest>now</latest>
    +                </default>
    +                <change>
    +                    <unset token="form.refresh"></unset>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="refresh" searchWhenChanged="true">
    +                <label>Auto-refresh:</label>
    +                <fieldForLabel>label</fieldForLabel>
    +                <fieldForValue>value</fieldForValue>
    +                <selectFirstChoice>true</selectFirstChoice>
    +                <search>
    +                    <query>| `def_auto_refresh`</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +            </input>
    +
    +            <input id="frameID" type="dropdown" token="frameID" searchWhenChanged="true">
    +                <label>Frame IDs:</label>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate">
    +                    <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +                </search>
    +                <prefix>frameID=</prefix>
    +                <choice value="*">Any</choice>
    +                <initialValue>*</initialValue>
    +                <fieldForLabel>frameID</fieldForLabel>
    +                <fieldForValue>frameID</fieldForValue>
    +            </input>
    +
    +            <input id="host" type="dropdown" token="host" searchWhenChanged="true">
    +                <label>Hosts Selection:</label>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate">
    +                    <query>search $frameID$
    +    | stats count by host | dedup host | sort 0 host</query>
    +                </search>
    +                <prefix>host="</prefix>
    +                <suffix>"</suffix>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" by host
    +| `mapping_frameID`
    +| stats count by frameID, host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- DF_STORAGE data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.Use_pct" $host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <set token="start_jfs_storage_search">true</set>
    +                    <unset token="start_df_storage_search"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_df_storage_search">true</set>
    +                    <unset token="start_jfs_storage_search"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <single>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` $host$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart `nmon_span` avg(cpu_load_percent) AS cpu_load_percent | where isnotnull(cpu_load_percent)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">none</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="underLabel">CPU %</option>
    +                <option name="useColors">1</option>
    +            </single>
    +        </panel>
    +        <panel>
    +            <single>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_phys_memory_all_os_metric_filters` $host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart `nmon_span` avg(mem_used_effective_PCT) AS mem_used_effective_PCT | where isnotnull(mem_used_effective_PCT)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">none</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="underLabel">MEMORY %</option>
    +                <option name="useColors">1</option>
    +            </single>
    +        </panel>
    +        <panel>
    +            <single>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.system.uptime.load_average_5min" $host$ by metric_name, host span=1m
    +| timechart `nmon_span` avg(value) as load_average_5min | where isnotnull(load_average_5min)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">none</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="underLabel">5 MIN LOAD AVG</option>
    +                <option name="useColors">1</option>
    +            </single>
    +        </panel>
    +        <panel>
    +            <single>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT) $host$ by metric_name, OStype, host span=1m prestats=f
    +| rex field="metric_name" "os.unix.nmon.cpu.[^\.]*.(?&lt;metric&gt;.*)"
    +| eval {metric}=value
    +| stats values(Wait_PCT) as Wait_PCT, values(VP_Wait_PCT) as VP_Wait_PCT by _time, host
    +| eventstats count(eval(VP_Wait_PCT>0)) as count_lpar by host
    +| eval cpu_wait_percent=if(count_lpar>0, VP_Wait_PCT, Wait_PCT)
    +| timechart `nmon_span` avg(cpu_wait_percent) AS cpu_wait_percent | where isnotnull(cpu_wait_percent)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">none</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="underLabel">WAIT/IO %</option>
    +                <option name="useColors">1</option>
    +            </single>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <title>CPU usage</title>
    +            <chart>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` $host$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart `nmon_span` avg(cpu_load_percent) AS cpu_load_percent</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsY.majorUnit">25</option>
    +                <option name="charting.axisY.maximumNumber">101</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">Percent</option>
    +                <!-- Set background color -->
    +                <option name="charting.backgroundColor">#292C33</option>
    +                <!-- Set foreground color -->
    +                <option name="charting.foregroundColor">#EBF5FF</option>
    +                <!-- Set font color (axis labels, legends) -->
    +                <option name="charting.fontColor">#BFBFBF</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="refresh.display">none</option>
    +                <option name="height">280</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <title>Load average</title>
    +            <chart>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.system.uptime.load_average_1min OR metric_name=os.unix.nmon.system.uptime.load_average_5min OR metric_name=os.unix.nmon.system.uptime.load_average_15min $host$ by metric_name, host span=1m
    +| `extract_metrics`
    +| eval {metric}=value
    +| fillnull value=0 load_average_1min load_average_5min load_average_15min
    +| timechart `nmon_span` avg(load_average_1min) as load_average_1min, avg(load_average_5min) as load_average_5min, avg(load_average_15min) as load_average_15min | fields _time,load_average_1min,load_average_5min,load_average_15min | fields _time,load_average_1min,load_average_5min,load_average_15min</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">Load average</option>
    +                <!-- Set background color -->
    +                <option name="charting.backgroundColor">#292C33</option>
    +                <!-- Set foreground color -->
    +                <option name="charting.foregroundColor">#EBF5FF</option>
    +                <!-- Set font color (axis labels, legends) -->
    +                <option name="charting.fontColor">#BFBFBF</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="refresh.display">none</option>
    +                <option name="height">280</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <title>Running processes</title>
    +            <chart>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.proccount.nb_running_processes $host$ span=1m
    +| timechart `nmon_span` avg(value) as running_processes</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nb running processes</option>
    +                <!-- Set background color -->
    +                <option name="charting.backgroundColor">#292C33</option>
    +                <!-- Set foreground color -->
    +                <option name="charting.foregroundColor">#EBF5FF</option>
    +                <!-- Set font color (axis labels, legends) -->
    +                <option name="charting.fontColor">#BFBFBF</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.legend.placement">none</option>
    +                <option name="refresh.display">none</option>
    +                <option name="height">280</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <title>Processes CPU usage</title>
    +            <chart>
    +                <search>
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" $host$ by host, metric_name, dimension_Command dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| appendcols [ | mstats latest(_value) as logical_cpus where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" host=GMD-LAPTOP by host ]
    +| appendcols [ | mstats latest(_value) as virtual_cpus where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.virtual_cpus" host=GMD-LAPTOP by host ]
    +| filldown logical_cpus, virtual_cpus
    +| stats values(pct_CPU) as pct_CPU, values(logical_cpus) as logical_cpus, values(virtual_cpus) as virtual_cpus by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100), smt_threads=(logical_cpus/virtual_cpus)
    +| eval usage_per_core=case(isnum(smt_threads) AND smt_threads>="2", usage_per_core*1.2, isnum(smt_threads) AND smt_threads>="4", usage_per_core*1.4, isnum(usage_per_core), usage_per_core)
    +| timechart `nmon_span` useother=f limit="20" max(usage_per_core) as "CPU Usage per core" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">core cpu</option>
    +                <!-- Set background color -->
    +                <option name="charting.backgroundColor">#292C33</option>
    +                <!-- Set foreground color -->
    +                <option name="charting.foregroundColor">#EBF5FF</option>
    +                <!-- Set font color (axis labels, legends) -->
    +                <option name="charting.fontColor">#BFBFBF</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="refresh.display">none</option>
    +                <option name="height">280</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <title>Memory usage</title>
    +            <chart>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` $host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart `nmon_span` dedup_splitvals=t avg(mem_used_effective_PCT) AS mem_used_PCT, avg(swap_used_effective_PCT) AS swap_used_PCT</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsY.majorUnit">25</option>
    +                <option name="charting.axisY.maximumNumber">101</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">Percent</option>
    +                <!-- Set background color -->
    +                <option name="charting.backgroundColor">#292C33</option>
    +                <!-- Set foreground color -->
    +                <option name="charting.foregroundColor">#EBF5FF</option>
    +                <!-- Set font color (axis labels, legends) -->
    +                <option name="charting.fontColor">#BFBFBF</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="refresh.display">none</option>
    +                <option name="height">280</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <title>Network traffic</title>
    +            <chart>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.net $host$ (dimension_device!="*lo*") by metric_name, host, dimension_device span=1m
    +| where value&gt;0
    +| eval traffic_type=case(match(dimension_device, ".+read.+"), "Inbound", match(dimension_device, ".+write.+"), "Outbound")
    +| eval value=case(traffic_type="Outbound", "-" . value, traffic_type="Inbound", value)
    +| timechart `nmon_span` avg(value) as value by traffic_type</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">KBps</option>
    +                <!-- Set background color -->
    +                <option name="charting.backgroundColor">#292C33</option>
    +                <!-- Set foreground color -->
    +                <option name="charting.foregroundColor">#EBF5FF</option>
    +                <!-- Set font color (axis labels, legends) -->
    +                <option name="charting.fontColor">#BFBFBF</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="refresh.display">none</option>
    +                <option name="height">280</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <title>File-system usage</title>
    +            <chart depends="$start_df_storage_search$">
    +                <search depends="$start_df_storage_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.Use_pct" $host$ dimension_mount="*" by host, dimension_mount span=1m
    +| timechart `nmon_span` latest(value) as storage_used_percent by dimension_mount</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsY.majorUnit">25</option>
    +                <option name="charting.axisY.maximumNumber">101</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">Percent</option>
    +                <option name="charting.axisY.maximumNumber">101</option>
    +                <!-- Set background color -->
    +                <option name="charting.backgroundColor">#292C33</option>
    +                <!-- Set foreground color -->
    +                <option name="charting.foregroundColor">#EBF5FF</option>
    +                <!-- Set font color (axis labels, legends) -->
    +                <option name="charting.fontColor">#BFBFBF</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">280</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$start_jfs_storage_search$">
    +                <search depends="$start_jfs_storage_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsfile" $host$ by host, dimension_mount span=1m
    +| timechart `nmon_span` limit=0 useother=f latest(value) As value by dimension_mount</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsY.majorUnit">25</option>
    +                <option name="charting.axisY.maximumNumber">101</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">Percent</option>
    +                <option name="charting.axisY.maximumNumber">101</option>
    +                <!-- Set background color -->
    +                <option name="charting.backgroundColor">#292C33</option>
    +                <!-- Set foreground color -->
    +                <option name="charting.foregroundColor">#EBF5FF</option>
    +                <!-- Set font color (axis labels, legends) -->
    +                <option name="charting.fontColor">#BFBFBF</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">280</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <title>Disks IOPS</title>
    +            <chart>
    +                <search>
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgxfer" OR metric_name="os.unix.nmon.storage.diskxfer") $host$ by host, metric_name, dimension_device span=1m
    +| stats sum(value) as value by _time, host, metric_name
    +| eval dgxfer_iops=case(match(metric_name, "dgxfer"), value), diskxfer_iops=case(match(metric_name, "diskxfer"), value)
    +| stats values(dgxfer_iops) as dgxfer_iops, values(diskxfer_iops) as diskxfer_iops by _time, host
    +| eval iops=if(isnum('dgxfer_iops'), 'dgxfer_iops', 'diskxfer_iops')
    +| timechart `nmon_span` avg(iops) as avg_iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">I/O per second</option>
    +                <!-- Set background color -->
    +                <option name="charting.backgroundColor">#292C33</option>
    +                <!-- Set foreground color -->
    +                <option name="charting.foregroundColor">#EBF5FF</option>
    +                <!-- Set font color (axis labels, legends) -->
    +                <option name="charting.fontColor">#BFBFBF</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="refresh.display">none</option>
    +                <option name="height">280</option>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_Summary.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_Summary.xml
    new file mode 100644
    index 0000000..d08b1b9
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_Summary.xml
    @@ -0,0 +1,2516 @@
    +<form stylesheet="ui_simple.css,hover.css,hide_timeindicator.css,panel_decoration.css,table_data_bar.css" script="active_button.js,autodiscover.js,table_data_bar.js" isVisible="true" version="1.1" theme="dark">
    +    <label>NMON Summary Light Analysis</label>
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +        </input>
    +
    +        <input id="frameID" type="dropdown" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <choice value="*">Any</choice>
    +            <default>*</default>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="dropdown" token="host" searchWhenChanged="true">
    +            <label>Host:</label>
    +            <search base="populate">
    +                <query>search frameID=$frameID$ host=$host-prefilter$ | stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <unset token="OStype_is_set"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="span" searchWhenChanged="true">
    +            <label>Span:</label>
    +            <default>`nmon_span`</default>
    +            <choice value="`nmon_span`">auto</choice>
    +            <choice value="span=1m">1 minute</choice>
    +            <choice value="span=2m">2 minutes</choice>
    +            <choice value="span=3m">3 minutes</choice>
    +            <choice value="span=4m">4 minutes</choice>
    +            <choice value="span=5m">5 minutes</choice>
    +            <choice value="span=10m">10 minutes</choice>
    +            <choice value="span=15m">15 minutes</choice>
    +            <choice value="span=30m">30 minutes</choice>
    +            <choice value="span=1h">1 hour</choice>
    +            <choice value="span=2h">2 hours</choice>
    +            <choice value="span=12h">12 hours</choice>
    +            <choice value="span=4h">4 hours</choice>
    +            <choice value="span=1d">1 day</choice>
    +            <choice value="span=2d">2 days</choice>
    +            <choice value="span=1w">7 days</choice>
    +            <choice value="span=1mon">1 month</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    base search for main dropdown populating
    +    -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- OStype -->
    +
    +    <search id="OSType_detection">
    +        <query>| mcatalog values(OStype) as OStype_values where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" host=$host$ | rename OStype_values as OStype | mvexpand OStype | head 1 | table OStype</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="'result.OStype'==&quot;Linux&quot;">
    +                <set token="is_Linux">true</set>
    +                <unset token="is_AIX"></unset>
    +                <unset token="is_Solaris"></unset>
    +            </condition>
    +            <condition match="'result.OStype'==&quot;AIX&quot;">
    +                <set token="is_AIX">true</set>
    +                <unset token="is_Linux"></unset>
    +                <unset token="is_Solaris"></unset>
    +            </condition>
    +            <condition match="'result.OStype'==&quot;Solaris&quot;">
    +                <set token="is_Solaris">true</set>
    +                <unset token="is_AIX"></unset>
    +                <unset token="is_Linux"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- CPU data source (CPU_ALL versus LPAR) -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.lpar.PhysicalCPU" host=$host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                <set token="is_not_LPAR">true</set>
    +                <unset token="is_LPAR"></unset>
    +                <set token="CPU_datasource">CPU_ALL usage</set>
    +                <set token="CPU_datasource_minilabel">CPU % usage</set>
    +            </condition>
    +            <condition>
    +                <set token="is_LPAR">true</set>
    +                <unset token="is_not_LPAR"></unset>
    +                <set token="CPU_datasource">LPAR usage</set>
    +                <set token="CPU_datasource_minilabel">partition vCPUs usage</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- TOP data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                <set token="show_null_top">true</set>
    +            </condition>
    +            <condition>
    +                <unset token="show_null_top"/>
    +                <set token="start_top_searches">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- UPTIME data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.system.uptime.load_average_1min" host=$host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_uptime_searches"></unset>
    +                    <set token="show_null_uptime">true</set>
    +            </condition>
    +            <condition>
    +                    <set token="start_uptime_searches">true</set>
    +                    <unset token="show_null_uptime"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- DG data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgxfer" host=$host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <set token="start_disk_stats_search">_time,*</set>
    +                    <unset token="start_dg_stats_search"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_dg_stats_search">_time,*</set>
    +                    <unset token="start_disk_stats_search"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- DF_STORAGE data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.Use_pct" host=$host$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <set token="start_jfs_storage_search">true</set>
    +                    <unset token="start_df_storage_search"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_df_storage_search">true</set>
    +                    <unset token="start_jfs_storage_search"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +
    +    <!-- Configuration Search uses nmon_inventory -->
    +
    +    <search id="configSearch" depends="$show_configuration$">
    +        <query>| inputlookup nmon_inventory
    +| rename hostname as host
    +| search host=$host$
    +| sort limit=0 host | eval OS_summary=upper(OStype)+" / "+OSversion
    +| fields host, OS_summary, cpu_cores, Processor</query>
    +        <earliest>0</earliest>
    +        <!-- Progress event has access to job properties only -->
    +        <progress>
    +            <condition match="'job.resultCount' == 0">
    +                <set token="show_null_config">True</set>
    +            </condition>
    +            <condition>
    +                <unset token="show_null_config"/>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <search id="MEMSearch" depends="$show_configuration$">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.memory.mem.memtotal" OR metric_name="os.unix.nmon.memory.mem.Real_total_MB" OR metric_name="os.unix.nmon.memory.mem.swaptotal" OR metric_name="os.unix.nmon.memory.mem.Virtual_total_MB") host=$host$ by host, metric_name span=1m
    +| eval memtotal=case(isnum(value) AND metric_name="os.unix.nmon.memory.mem.memtotal", value, isnum(value) AND metric_name="os.unix.nmon.memory.mem.Real_total_MB", value)
    +| eval swaptotal=case(isnum(value) AND metric_name="os.unix.nmon.memory.mem.swaptotal", value, isnum(value) AND metric_name="os.unix.nmon.memory.mem.Virtual_total_MB", value)
    +| stats latest(memtotal) as memtotal, latest(swaptotal) as swaptotal
    +| foreach * [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 0) ]</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- for non LPARs -->
    +
    +    <search id="CPUSearch_summary">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` host=$host$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| stats max(cpu_load_percent) AS max_usage, avg(cpu_load_percent) AS avg_usage, median(cpu_load_percent) AS median_usage
    +| foreach * [ eval &lt;&lt;FIELD&gt;&gt; = if('&lt;&lt;FIELD&gt;&gt;'>100, 100, round('&lt;&lt;FIELD&gt;&gt;', 2) ) ]</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="TOPSearch" depends="$show_processes$">
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, metric_name, dimension_Command
    +| appendcols [ | mstats latest(_value) as logical_cpus where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" host=GMD-LAPTOP by host ]
    +| appendcols [ | mstats latest(_value) as virtual_cpus where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.virtual_cpus" host=GMD-LAPTOP by host ]
    +| filldown logical_cpus, virtual_cpus
    +| stats values(pct_CPU) as pct_CPU, values(logical_cpus) as logical_cpus, values(virtual_cpus) as virtual_cpus by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100), smt_threads=(logical_cpus/virtual_cpus)
    +| eval usage_per_core=case(isnum(smt_threads) AND smt_threads&gt;="2", usage_per_core*1.2, isnum(smt_threads) AND smt_threads&gt;="4", usage_per_core*1.4, isnum(usage_per_core), usage_per_core)
    +| stats max(usage_per_core) as max_usage_per_core, avg(usage_per_core) as avg_usage_per_core by dimension_Command | rename dimension_Command as Command
    +| foreach *usage_per_core [ eval &lt;&lt;FIELD&gt;&gt;=round('&lt;&lt;FIELD&gt;&gt;', 3) ] | sort - max_usage_per_core</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader2">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +
    +                    <h4>The Nmon Summary interface has been designed for focused time ranges, very large time ranges may require time to be fully processed</h4>
    +                    <h4>For long time analysis, please consider using metric dedicated interfaces available from App home pages</h4>
    +
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- non LPARs -->
    +
    +    <row>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="CPUSearch_summary">
    +                    <query>gauge max_usage</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Max %CPU</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="CPUSearch_summary">
    +                    <query>gauge avg_usage</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Avg %CPU</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="CPUSearch_summary">
    +                    <query>gauge median_usage</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Median %CPU</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### Active Buttons #########################################  -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_configuration" data-alt-label="HIDE CONFIGURATION SUMMARY" data-token-value="fields *">SHOW CONFIGURATION SUMMARY</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_uptime_load_average" data-alt-label="HIDE UPTIME LOAD AVERAGE" data-token-value="fields *">SHOW UPTIME LOAD AVERAGE</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_configuration$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start host configuration</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_configuration$">
    +
    +        <panel rejects="$show_null_config$">
    +            <title>Operating System</title>
    +            <single>
    +                <search base="configSearch">
    +                    <query>fields OS_summary</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">Operating System Level</option>
    +            </single>
    +        </panel>
    +
    +        <panel rejects="$show_null_config$">
    +            <title>Processor Configuration</title>
    +            <single>
    +                <search base="configSearch">
    +                    <query>fields cpu_cores</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">Virtual Proc / Logical Cores</option>
    +            </single>
    +            <single>
    +                <search base="configSearch">
    +                    <query>fields Processor</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">Processor Type</option>
    +            </single>
    +        </panel>
    +
    +        <panel depends="$show_null_config$">
    +            <html>
    +                <p style="color:blue;margin-left:30px;font-size:14px;margin-top:50px">SYSTEM SUMMARY OVERVIEW Search returned no results, The nmon inventory data may not be available yet for this host, manually run the Nmon Inventory Generation report or wait for the auto update. (occurs every hour by default)</p>
    +            </html>
    +        </panel>
    +
    +        <panel>
    +            <title>Memory Configuration</title>
    +
    +            <single>
    +                <search base="MEMSearch">
    +                    <query>fields memtotal</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">Total Memory</option>
    +                <option name="unit">MB</option>
    +            </single>
    +
    +            <single>
    +                <search base="MEMSearch">
    +                    <query>fields swaptotal</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">Total Paging Space</option>
    +                <option name="unit">MB</option>
    +            </single>
    +
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_configuration$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End host configuration</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- nmon external UPTIME -->
    +
    +    <search id="baseSearch_loadaverage" depends="$start_uptime_searches$">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.system.uptime.load_average_1min OR metric_name=os.unix.nmon.system.uptime.load_average_5min OR metric_name=os.unix.nmon.system.uptime.load_average_15min host=$host$ by metric_name, host span=1m
    +| `extract_metrics`
    +| eval {metric}=value
    +| fillnull value=0 load_average_1min load_average_5min load_average_15min
    +| timechart $span$ avg(load_average_1min) as load_average_1min, avg(load_average_5min) as load_average_5min, avg(load_average_15min) as load_average_15min | fields _time,load_average_1min,load_average_5min,load_average_15min</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <sampleRatio>1</sampleRatio>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <row depends="$show_uptime_load_average$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start uptime load average</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_uptime_load_average$ $show_null_uptime$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - UPTIME DATA UNAVAILABLE: The uptime data (nmon external collection) is not available, collecting these data requires the TA-nmon 1.3.x minimum - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_uptime_load_average$" rejects="$show_null_uptime$">
    +        <panel>
    +            <title>SYSTEM LOAD AVERAGE (nmon external: UPTIME)</title>
    +            <single>
    +                <search base="baseSearch_loadaverage">
    +                    <query>fields _time, load_average_1min | where isnotnull(load_average_1min)</query>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="underLabel">load average 1min</option>
    +                <option name="useColors">1</option>
    +            </single>
    +            <single>
    +                <search base="baseSearch_loadaverage">
    +                    <query>fields _time, load_average_5min | where isnotnull(load_average_5min)</query>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="underLabel">load average 5min</option>
    +                <option name="useColors">1</option>
    +            </single>
    +            <single>
    +                <search base="baseSearch_loadaverage">
    +                    <query>fields _time, load_average_15min | where isnotnull(load_average_15min)</query>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="underLabel">load average 15min</option>
    +                <option name="useColors">1</option>
    +            </single>
    +            <single>
    +                <search depends="$start_uptime_searches$">
    +                    <query>eventtype=nmon:events type=UPTIME host=$host$
    +| eval uptime=if(uptime&lt;86400, round((uptime/3600), 2) . " hours", round((uptime/86400), 2) . " days" )
    +| fields uptime</query>
    +                    <earliest>-15m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="drilldown">all</option>
    +                <option name="underLabel">current server uptime</option>
    +            </single>
    +            <chart>
    +                <search base="baseSearch_loadaverage">
    +                    <query>fields _time,load_average_1min,load_average_5min,load_average_15min</query>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <option name="height">350</option>
    +            </chart>
    +            <table>
    +                <search base="baseSearch_loadaverage" depends="$start_uptime_searches$">
    +                    <query>stats latest(load_average_1min) as current_load_average_1min, avg(load_average_1min) as avg_load_average_1min, max(load_average_1min) as max_load_average_1min,
    +latest(load_average_5min) as current_load_average_5min, avg(load_average_5min) as avg_load_average_5min, max(load_average_5min) as max_load_average_5min,
    +latest(load_average_15min) as current_load_average_15min, avg(load_average_15min) as avg_load_average_15min, max(load_average_15min) as max_load_average_15min
    +| foreach * [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]
    +| eval "load average 1 min" =  "Current: " . current_load_average_1min . " Average: " . avg_load_average_1min . " Max: " . max_load_average_1min
    +| eval "load average 5 min" = "Current: " . current_load_average_5min . " Average: " . avg_load_average_5min . " Max: " . max_load_average_5min
    +| eval "load average 15 min" = "Current: " . current_load_average_15min . " Average: " . avg_load_average_15min . " Max: " . max_load_average_15min
    +| fields "load average *min" | transpose | eval order=case(column="load average 1 min", 1, column="load average 5 min", 2, column="load average 15 min", 3) | sort order | rename column as "By", "row 1" as "Load average" | fields By, "Load average"</query>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +            </table>
    +        </panel>
    +
    +    </row>
    +
    +    <row depends="$show_uptime_load_average$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End uptime load average</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>CPU Usage Statistics - $CPU_datasource_minilabel$</title>
    +
    +            <chart>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` host=$host$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart $span$ max(cpu_load_percent) AS "max cpu load %", avg(cpu_load_percent) AS "avg cpu load %"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">350</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$CPU_datasource_minilabel$</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +        </panel>
    +
    +        <panel id="disk">
    +            <title>I/O Operations per second</title>
    +
    +            <chart depends="$start_dg_stats_search$">
    +                <search depends="$start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgxfer" host=$host$ by host, dimension_device span=1m
    +| stats sum(value) as disk_total_iops by _time, host
    +| timechart $span$ max(disk_total_iops) As "max Total I/O", avg(disk_total_iops) As "avg Total I/O"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">350</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">I/O per second</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +            <chart depends="$start_disk_stats_search$">
    +                <search id="IOPStimechart" depends="$start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" host=$host$ by host, dimension_device span=1m
    +| stats sum(value) AS iops by _time, host
    +| timechart $span$ max(iops) As "max Total I/O", avg(iops) As "avg Total I/O"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">350</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">I/O per second</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### Active Buttons #########################################  -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_cpu" data-alt-label="HIDE EXTENDED CPU STATS" data-token-value="true">SHOW EXTENDED CPU STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_disks" data-alt-label="HIDE EXTENDED DISKS STATS" data-token-value="true">SHOW EXTENDED DISKS STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### CPU #########################################  -->
    +
    +    <row depends="$show_cpu$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended CPU stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_cpu$" rejects="$is_LPAR$">
    +        <panel>
    +            <chart>
    +                <title>% CPU stats over time per category</title>
    +                <search depends="$show_cpu$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT) (host=$host$) by metric_name, host span=1m
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value), Steal_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Steal_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent, values(Steal_percent) as Steal_percent by _time, host
    +| timechart $span$
    +avg(Idle_percent) AS "Idle %",
    +avg(Sys_percent) AS "Sys %",
    +avg(User_percent) AS "User %",
    +avg(Wait_percent) AS "Wait %",
    +avg(Steal_percent) AS "Steal %"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">%</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_cpu$" rejects="$is_LPAR$">
    +        <panel>
    +            <chart>
    +                <title>% CPU stats over time per core</title>
    +                <search depends="$show_cpu$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* (host=$host$) by metric_name host span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT, Steal_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT, values(Steal_PCT) as Steal_PCT by _time, host, cpu_core
    +| fillnull value=0 Sys_PCT,User_PCT,Wait_PCT,Steal_PCT
    +| search (cpu_core="*")
    +| eval cpu_PCT=(Sys_PCT+User_PCT+Wait_PCT+Steal_PCT)
    +| timechart `nmon_span` useother=f limit=0 avg(cpu_PCT) AS cpu_PCT by cpu_core</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">%</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <!-- This is for AIX LPARs -->
    +
    +    <row depends="$show_cpu$ $is_LPAR$ $is_AIX$">
    +        <panel>
    +            <chart>
    +                <title>AIX LPAR statistics</title>
    +                <search depends="$show_cpu$ $is_LPAR$ $is_AIX$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.VP_User_PCT" OR metric_name="os.unix.nmon.cpu.lpar.VP_Sys_PCT" OR metric_name="os.unix.nmon.cpu.lpar.VP_Wait_PCT" OR metric_name="os.unix.nmon.cpu.lpar.VP_Idle_PCT" OR metric_name="os.unix.nmon.cpu.lpar.PhysicalCPU" OR metric_name="os.unix.nmon.cpu.lpar.entitled" OR metric_name="os.unix.nmon.cpu.lpar.virtualCPUs") (host=$host$) by metric_name, OStype, host span=1m
    +| `def_lpar_load_cores`
    +| timechart $span$ max(lpar_load_cores) AS "max cpu load cores", avg(lpar_load_cores) AS "avg cpu load cores", max(entitled) as entitled, max(virtualCPUs) as virtualCPUs</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">Virtual CPUs</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_cpu$ $is_LPAR$ $is_AIX$">
    +        <panel>
    +            <chart>
    +                <title>AIX LPAR statistics per category</title>
    +                <search depends="$show_cpu$ $is_LPAR$ $is_AIX$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.VP_User_PCT" OR metric_name="os.unix.nmon.cpu.lpar.VP_Sys_PCT" OR metric_name="os.unix.nmon.cpu.lpar.VP_Wait_PCT" OR metric_name="os.unix.nmon.cpu.lpar.VP_Idle_PCT" OR metric_name="os.unix.nmon.cpu.lpar.entitled" OR metric_name="os.unix.nmon.cpu.lpar.virtualCPUs") (host=$host$) by metric_name, OStype, host span=1m
    +| `def_lpar_load_aix_cores_by_cat`
    +| timechart $span$ avg(VP_Idle_PCT) AS VP_Idle_PCT, avg(VP_Sys_PCT) AS VP_Sys_PCT, avg(VP_User_PCT) AS VP_User_PCT, avg(VP_Wait_PCT) AS VP_Wait_PCT</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked100</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_cpu$ $is_LPAR$ $is_AIX$">
    +        <panel>
    +            <chart rejects="$show_null_AIX_pooldata$">
    +                <title>AIX LPAR Pools statistics</title>
    +                <search depends="$show_cpu$ $is_LPAR$ $is_AIX$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.poolCPUs" OR metric_name="os.unix.nmon.cpu.lpar.Pool_id" OR metric_name="os.unix.nmon.cpu.lpar.PoolIdle") (host=$host$) by metric_name, OStype, host span=1m
    +| `def_lpar_pool_load_aix_cores`
    +| timechart $span$ max(lpar_pool_usage) As lpar_pool_usage max(poolCPUs) AS poolCPUs</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">Virtual CPUs</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <html depends="$show_null_AIX_pooldata$">
    +                <p style="color:blue;margin-left:30px;font-size:14px"><b>AIX LPAR Pools statistics:</b> Search returned no results, this partition might not be allowed to retrieve the pool statistics it belongs to.</p>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- This is for PowerLinux LPARs -->
    +
    +    <row depends="$show_cpu$ $is_LPAR$ $is_Linux$">
    +        <panel>
    +            <chart>
    +                <title>PowerLinux LPAR statistics</title>
    +                <search depends="$show_cpu$ $is_LPAR$ $is_Linux$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.PhysicalCPU" OR metric_name="os.unix.nmon.cpu.lpar.partition_active_processors" OR metric_name="os.unix.nmon.cpu.lpar.partition_entitled_capacity") (host=$host$) by metric_name, host span=1m
    +| `def_lpar_load_linux_cores`
    +| timechart $span$ max(lpar_load_cores) AS "max cpu load cores", avg(lpar_load_cores) AS "avg cpu load cores", max(partition_active_processors) as partition_active_processors, max(partition_entitled_capacity) as partition_entitled_capacity</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">Virtual CPUs</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_cpu$ $is_LPAR$ $is_Linux$">
    +        <panel>
    +            <chart>
    +                <title>PowerLinux LPAR Pools statistics</title>
    +                <search depends="$show_cpu$ $is_LPAR$ $is_Linux$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.smt_mode" OR metric_name="os.unix.nmon.cpu.lpar.pool_idle_time" OR metric_name="os.unix.nmon.cpu.lpar.pool_capacity") (host=$host$) by metric_name, host span=1m
    +| `def_lpar_pool_load_linux_cores`
    +| timechart $span$ max(lpar_pool_vp_usage) As lpar_pool_vp_usage max(pool_capacity) AS pool_capacity</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">Virtual CPUs</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <!-- This is for Solaris -->
    +
    +    <row depends="$show_cpu$ $is_Solaris$">
    +        <panel>
    +            <chart>
    +                <title>Solaris WML statistics per zone</title>
    +                <search depends="$show_cpu$ $is_Solaris$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.wlmprojectcpu" (host=$host$) by metric_name, host, dimension_device span=1m
    +| timechart $span$ limit=0 useother=f max(value) As value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% CPU</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_cpu$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended CPU stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### DISKS #########################################  -->
    +
    +    <!--  disks extended stats (DG*) -->
    +
    +    <row depends="$show_disks$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended Disks stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_disks$ $start_dg_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>Avg I/O per sec over time - click on the chart to get by device view</title>
    +                <search depends="$show_disks$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgxfer" host=$host$ by dimension_device span=1m
    +| stats sum(value) as disk_total_iops by _time
    +| timechart $span$ avg(disk_total_iops) As disk_total_iops | trendline sma5(disk_total_iops) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">I/O per sec</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgxfer" host=$host$ by dimension_device span=1m
    +| timechart useother=f limit=0 $span$ avg(value) As disk_total_iops by dimension_device&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>Avg read/write I/O per sec over time - click on the chart to get by device view</title>
    +                <search depends="$show_disks$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dg*" host=$host$ by metric_name, dimension_device span=1m
    +| `extract_metrics("dgxfer dgread dgwrite dgsize")`
    +| stats max(dgxfer) as disk_total_iops max(dgread) as disk_read_KB_per_sec max(dgwrite) as disk_write_KB_per_sec max(dgsize) as disk_block_size_KB by _time, dimension_device
    +| eval disk_read_iops=(disk_read_KB_per_sec/disk_block_size_KB), disk_write_iops=(disk_write_KB_per_sec/disk_block_size_KB)
    +| stats sum(disk_*) as "disk_*" by _time
    +| timechart $span$ avg(disk_read_iops) as disk_read_iops avg(disk_write_iops) as disk_write_iops</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">I/O per sec</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dg*" host=$host$ by metric_name, dimension_device span=1m
    +| `extract_metrics("dgxfer dgread dgwrite dgsize")`
    +| stats max(dgxfer) as disk_total_iops max(dgread) as disk_read_KB_per_sec max(dgwrite) as disk_write_KB_per_sec max(dgsize) as disk_block_size_KB by _time, dimension_device
    +| eval disk_read_iops=(disk_read_KB_per_sec/disk_block_size_KB), disk_write_iops=(disk_write_KB_per_sec/disk_block_size_KB)
    +| timechart useother=f limit=0 $span$ avg(disk_read_iops) as disk_read_iops avg(disk_write_iops) as disk_write_iops by dimension_device&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_disks$ $start_dg_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>Avg % busy time - click on the chart to get by device view</title>
    +                <search depends="$show_disks$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbusy" host=$host$ by host, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_busy_time_pct | trendline sma5(disk_busy_time_pct) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% of time busy</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbusy" host=$host$ by host, dimension_device span=1m
    +| timechart limit=0 useother=f $span$ avg(value) as disk_busy_time_pct by dimension_device&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>Avg data transfer size over time - click on the chart to get by device view</title>
    +                <search depends="$show_disks$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgsize" host=$host$ by host, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_block_size_KB | trendline sma5(disk_block_size_KB) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">KBytes per transfer</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgsize" host=$host$ by host, dimension_device span=1m
    +| timechart limit=0 useother=f $span$ avg(value) as disk_block_size_KB by dimension_device&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_disks$ $start_dg_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>Avg read/write data rate (KBytes/sec) - click on the chart to get by device view</title>
    +                <search depends="$show_disks$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgread" OR metric_name="os.unix.nmon.storage.dgwrite") host=$host$ by host, metric_name, dimension_device span=1m
    +| `extract_metrics("dgread dgwrite")`
    +| stats values(dgread) as disk_read_KB_per_sec, values(dgwrite) as disk_write_KB_per_sec by _time, host, dimension_device
    +| timechart $span$ avg(disk_read_KB_per_sec) as disk_read_KB_per_sec, avg(disk_write_KB_per_sec) as disk_write_KB_per_sec</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">KBytes/sec</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgread" OR metric_name="os.unix.nmon.storage.dgwrite") host=$host$ by metric_name, dimension_device span=1m
    +| `extract_metrics("dgread dgwrite")`
    +| stats values(dgread) as disk_read_KB_per_sec, values(dgwrite) as disk_write_KB_per_sec by _time, dimension_device
    +| timechart useother=f limit=0 $span$ avg(disk_read_KB_per_sec) as disk_read_KB_per_sec, avg(disk_write_KB_per_sec) as disk_write_KB_per_sec by dimension_device&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>Avg read/write service time (ms) - click on the chart to get by device view</title>
    +                <search depends="$show_disks$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreadserv" OR metric_name="os.unix.nmon.storage.dgwriteserv") host=$host$ by host, metric_name, dimension_device span=1m
    +| `extract_metrics("dgreadserv dgwriteserv")`
    +| stats values(dgreadserv) as disk_read_service_time_ms, values(dgwriteserv) as disk_write_service_time_ms by _time, host, dimension_device
    +| timechart $span$ avg(disk_read_service_time_ms) as disk_read_service_time_ms, avg(disk_write_service_time_ms) as disk_write_service_time_ms</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">Milliseconds (ms)</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreadserv" OR metric_name="os.unix.nmon.storage.dgwriteserv") host=$host$ by host, metric_name, dimension_device span=1m
    +| `extract_metrics("dgreadserv dgwriteserv")`
    +| stats values(dgreadserv) as disk_read_service_time_ms, values(dgwriteserv) as disk_write_service_time_ms by _time, host, dimension_device
    +| timechart useother=f limit=0 $span$ avg(disk_read_service_time_ms) as disk_read_service_time_ms, avg(disk_write_service_time_ms) as disk_write_service_time_ms by dimension_device&display.general.type=visualizations&display.page.search.tab=visualizations&display.visualizations.charting.chart=line
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <!--  disks standard stats (DISK*) -->
    +
    +    <row depends="$show_disks$ $start_disk_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>Avg I/O per sec over time</title>
    +                <search depends="$show_disks$ $start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" host=$host$ by host, dimension_device span=1m
    +| stats sum(value) as disk_total_iops by _time, host
    +| timechart $span$ avg(disk_total_iops) As disk_total_iops | trendline sma5(disk_total_iops) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">I/O per sec</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>Avg % time busy disk over time</title>
    +                <search depends="$show_disks$ $start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbusy" host=$host$ by host, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_busy_time_pct | trendline sma5(disk_busy_time_pct) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% of time busy</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_disks$ $start_disk_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>Avg data transfer size over time</title>
    +                <search depends="$show_disks$ $start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbsize" host=$host$ by host, dimension_device span=1m
    +| timechart $span$ avg(value) as disk_block_size_KB | trendline sma5(disk_block_size_KB) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">KBytes per transfer</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>Avg read/write data rate (KBytes/sec) over time</title>
    +                <search depends="$show_disks$ $start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.diskread" OR metric_name="os.unix.nmon.storage.diskwrite") host=$host$ by host, metric_name, dimension_device span=1m
    +| `extract_metrics("diskread diskwrite")`
    +| stats values(diskread) as disk_read_KB_per_sec, values(diskwrite) as disk_write_KB_per_sec by _time, host, dimension_device
    +| timechart $span$ avg(disk_read_KB_per_sec) as disk_read_KB_per_sec, avg(disk_write_KB_per_sec) as disk_write_KB_per_sec</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">KBytes/sec</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="height">500</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_disks$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended Disks stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="mem">
    +            <title>Memory Statistics</title>
    +
    +            <chart>
    +                <search id="MEMtimechart">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart $span$ dedup_splitvals=t avg(mem_used_effective_PCT) AS mem_used_PCT, avg(swap_used_effective_PCT) AS swap_used_PCT</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">350</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Percentage (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +
    +        <panel id="process">
    +            <title>Top 20 processes CPU Statistics</title>
    +
    +            <chart rejects="$show_null_top$">
    +                <search id="TOPtimechart" depends="$start_top_searches$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, metric_name, dimension_Command
    +| appendcols [ | mstats latest(_value) as logical_cpus where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" host=$host$ by host ]
    +| appendcols [ | mstats latest(_value) as virtual_cpus where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.virtual_cpus" host=$host$ by host ]
    +| filldown logical_cpus, virtual_cpus
    +| stats values(pct_CPU) as pct_CPU, values(logical_cpus) as logical_cpus, values(virtual_cpus) as virtual_cpus by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100), smt_threads=(logical_cpus/virtual_cpus)
    +| eval usage_per_core=case(isnum(smt_threads) AND smt_threads&gt;="2", usage_per_core*1.2, isnum(smt_threads) AND smt_threads&gt;="4", usage_per_core*1.4, isnum(usage_per_core), usage_per_core)
    +| timechart $span$ useother=f limit="20" max(usage_per_core) as "CPU Usage per core" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">350</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Logical Core</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +            <html depends="$show_null_top$">
    +                <p style="color:blue;margin-left:30px;font-size:14px">Search returned no results, TOP collection (processes activity) has not been activated or no processes were captured due to lack of activity</p>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### Active Buttons #########################################  -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_memory" data-alt-label="HIDE EXTENDED MEMORY STATS" data-token-value="true">SHOW EXTENDED MEMORY STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_processes" data-alt-label="HIDE EXTENDED PROCESSES STATS" data-token-value="true">SHOW EXTENDED PROCESSES STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### Memory #########################################  -->
    +
    +    <row depends="$show_memory$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended Memory stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <search id="linux_memory_stats" depends="$show_memory$ $is_Linux$">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| timechart $span$ dedup_splitvals=t avg(memtotal) AS mem_total_MB, avg(mem_used_effective) as mem_used_effective_MB, avg(buffers) as mem_buffers_MB, avg(cached) as mem_cached_MB, avg(memfree) as mem_free_MB,
    +avg(swapfree) as swap_free_MB, avg(swap_used_effective) as swap_used_effective_MB, avg(swapcached) as swap_cached_MB, avg(swaptotal) as swap_total_MB</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="AIX_mem_memory_stats" depends="$show_memory$ $is_AIX$">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| eval Real_used_MB=(Real_total_MB-Real_free_MB), Virtual_used_MB=(Virtual_total_MB-Virtual_free_MB)
    +| timechart $span$ avg(Real_total_MB) AS Real_total_MB, avg(Real_used_MB) AS Real_used_MB, avg(Virtual_total_MB) AS Virtual_total_MB, avg(Virtual_used_MB) AS Virtual_used_MB</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="AIX_memnew_memory_stats" depends="$show_memory$ $is_AIX$">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memnew.*" host=$host$ by OStype, host, metric_name span=1m
    +| rex field="metric_name" "os.unix.nmon.memory.memnew.(?&lt;metric&gt;.*)"
    +| eval {metric}=value
    +| stats avg(Free_PCT) AS Free_PCT avg(FScache_PCT) AS FScache_PCT avg(memused_PCT) AS memused_PCT, avg(Process_PCT) AS Process_PCT avg(System_PCT) AS System_PCT by _time, host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="Solaris_MEM_real" depends="$show_memory$ $is_Solaris$">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| timechart $span$
    +avg(mem_used_effective) AS mem_used_MB, avg(memfree) AS mem_free_MB, avg(memtotal) AS mem_total_MB</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="Solaris_MEM_swap" depends="$show_memory$ $is_Solaris$">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.*" host=$host$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB`
    +| timechart $span$
    +avg(swap_used_effective) AS swap_used_MB, avg(swapfree) AS swap_free_MB, avg(swaptotal) AS swap_total_MB</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <row depends="$show_memory$">
    +        <panel>
    +            <chart depends="$is_Linux$">
    +                <title>Memory usage (MB) by main metrics</title>
    +                <search base="linux_memory_stats">
    +                    <query>fields _time, *mem_free_MB*, *mem_cached_MB*, *mem_buffers_MB*, *mem_used_effective_MB*, *mem_total_MB*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.overlayFields">mem_total_MB</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.fieldColors">{"mem_total_MB": 0xe50000}</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$is_AIX$">
    +                <title>AIX % memory allocation by category</title>
    +                <search base="AIX_memnew_memory_stats">
    +                    <query>fields _time,Free_PCT,FScache_PCT,Process_PCT,System_PCT</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Percentage (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$is_Solaris$">
    +                <title>Solaris memory usage (MB)</title>
    +                <search base="Solaris_MEM_real">
    +                    <query>fields _time,mem_free_MB,mem_used_MB,mem_total_MB</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.chart.overlayFields">mem_total_MB</option>
    +                <option name="charting.fieldColors">{"mem_total_MB": 0xe50000}</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +
    +        <panel>
    +            <chart depends="$is_Linux$">
    +                <title>Swap effective used/cached/free/global (MB)</title>
    +                <search base="linux_memory_stats">
    +                    <query>fields _time, *swap_free_MB*, *swap_used_effective_MB*, *swap_cached_MB*, *swap_total_MB*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.overlayFields">swap_total_MB</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.fieldColors">{"swap_total_MB": 0xe50000}</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$is_AIX$">
    +                <title>AIX paging Space usage (MB)</title>
    +                <search base="AIX_mem_memory_stats">
    +                    <query>fields _time,Virtual_total_MB,Virtual_used_MB</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Virtual_total_MB</option>
    +                <option name="charting.chart.overlayFields">Virtual_total_MB</option>
    +                <option name="charting.fieldColors">{"Virtual_total_MB": 0xe50000}</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$is_Solaris$">
    +                <title>Solaris swap usage (MB)</title>
    +                <search base="Solaris_MEM_swap">
    +                    <query>fields _time,swap_free_MB,swap_used_MB,swap_total_MB</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.chart.overlayFields">swap_total_MB</option>
    +                <option name="charting.fieldColors">{"swap_total_MB": 0xe50000}</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_memory$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended Memory stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### Processes #########################################  -->
    +
    +    <row depends="$show_processes$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended processes stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_processes$">
    +        <panel>
    +
    +            <single>
    +                <search base="TOPSearch">
    +                    <query>head 1 | fields Command</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">TOP Process</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="unit">Command</option>
    +                <option name="unitPosition">before</option>
    +                <option name="refresh.display">none</option>
    +            </single>
    +
    +            <single>
    +                <search base="TOPSearch">
    +                    <query>head 1 | fields avg_usage_per_core</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">Average Conso for this Command</option>
    +                <option name="numberPrecision">0.000</option>
    +                <option name="unit">core conso</option>
    +                <option name="unitPosition">before</option>
    +                <option name="refresh.display">none</option>
    +            </single>
    +
    +            <single>
    +                <search base="TOPSearch">
    +                    <query>head 1 | fields max_usage_per_core</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="underLabel">Max Conso for this Command</option>
    +                <option name="numberPrecision">0.000</option>
    +                <option name="unit">core conso</option>
    +                <option name="unitPosition">before</option>
    +                <option name="refresh.display">none</option>
    +            </single>
    +
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_processes$">
    +
    +        <!-- Table stats of CPU processes usage -->
    +
    +        <panel>
    +            <table>
    +                <title>Table stats: CPU Usage in logical core per Command invocation</title>
    +                <search depends="$show_processes$ $start_top_searches$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, metric_name, dimension_Command
    +| appendcols [ | mstats latest(_value) as logical_cpus where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" host=GMD-LAPTOP by host ]
    +| appendcols [ | mstats latest(_value) as virtual_cpus where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.virtual_cpus" host=GMD-LAPTOP by host ]
    +| filldown logical_cpus, virtual_cpus
    +| stats values(pct_CPU) as pct_CPU, values(logical_cpus) as logical_cpus, values(virtual_cpus) as virtual_cpus by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100), smt_threads=(logical_cpus/virtual_cpus)
    +| eval usage_per_core=case(isnum(smt_threads) AND smt_threads&gt;="2", usage_per_core*1.2, isnum(smt_threads) AND smt_threads&gt;="4", usage_per_core*1.4, isnum(usage_per_core), usage_per_core)
    +| stats max(usage_per_core) as "max CPU usage per core", avg(usage_per_core) as "avg CPU usage per core", sparkline(max(usage_per_core)) As sparkline by dimension_Command | rename dimension_Command as Command
    +| foreach *CPU* [ eval &lt;&lt;FIELD&gt;&gt;=round('&lt;&lt;FIELD&gt;&gt;', 3) ]
    +| sort - "max CPU usage per core"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +        </panel>
    +
    +        <!-- Table stats of Memory processes usage -->
    +
    +        <panel>
    +            <table depends="$is_Linux$">
    +                <title>Table stats: Memory Usage per command invocation</title>
    +                <search depends="$is_Linux$ $show_processes$ $start_top_searches$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSet" host=$host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as ResSet by _time, host, metric_name, dimension_Command
    +| eval Used_Mem_MB=((ResSet)/1024)
    +| stats sum(Used_Mem_MB) As value by _time, dimension_Command
    +| stats max(value) as "max memory usage (MB)", avg(value) as "avg memory usage (MB)", sparkline(max(value)) as sparkline by dimension_Command
    +| foreach *MB* [ eval &lt;&lt;FIELD&gt;&gt;=round('&lt;&lt;FIELD&gt;&gt;', 0) ]
    +| sort - "max memory usage (MB)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +            <table depends="$is_AIX$">
    +                <title>Table stats: Memory Usage per command invocation</title>
    +                <search depends="$is_AIX$ $show_processes$ $start_top_searches$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.processes.top.ResText" OR metric_name="os.unix.nmon.processes.top.ResData") host=$host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, host, metric_name, dimension_Command
    +| rex field="metric_name" "os.unix.nmon.processes.top.(?&lt;metric&gt;.*)"
    +| eval {metric}=value
    +| stats values(ResText) as ResText, values(ResData) as ResData by _time, host, dimension_Command
    +| fillnull value=0 ResText ResData
    +| eval Used_Mem_MB=((ResData+ResText)/1024)
    +| stats sum(Used_Mem_MB) As value by _time, host, dimension_Command
    +| stats max(value) as max_Used_Mem_MB, avg(value) as avg_Used_Mem_MB, sparkline(max(value)) as sparkline by dimension_Command | eval max_Used_Mem_MB=round(max_Used_Mem_MB,2) | eval avg_Used_Mem_MB=round(avg_Used_Mem_MB,2)
    +| sort - "avg_Used_Mem_MB"
    +| rename max_Used_Mem_MB AS "max memory usage (MB)", avg_Used_Mem_MB AS "avg memory usage (MB)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +            <table depends="$is_Solaris$">
    +                <title>Table stats: Physical Memory Usage per command invocation</title>
    +                <search depends="$is_Solaris$ $show_processes$ $start_top_searches$">
    +                    <query>| mstats max(_value) as ResSize where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSize" host=$host$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, host, metric_name, dimension_Command
    +| eval Phys_Mem_MB=round(((ResSize)/1024),2)
    +| stats sum(Phys_Mem_MB) As value by _time, host, dimension_Command
    +| stats max(value) as "max memory usage (MB)", avg(value) as "avg memory usage (MB)", sparkline(max(value)) as sparkline by dimension_Command
    +| foreach *MB* [ eval &lt;&lt;FIELD&gt;&gt;=round('&lt;&lt;FIELD&gt;&gt;', 0) ]
    +| sort - "max memory usage (MB)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_processes$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended processes stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="network">
    +            <title>Inbound/Outbound network traffic</title>
    +            <chart>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.net host=$host$ (dimension_device!="*lo*") by metric_name, host, dimension_device span=1m
    +| where value&gt;0
    +| eval traffic_type=case(match(dimension_device, ".+read.+"), "Inbound", match(dimension_device, ".+write.+"), "Outbound")
    +| eval value=case(traffic_type="Outbound", "-" . value, traffic_type="Inbound", value)
    +| timechart $span$ avg(value) as value by traffic_type</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <sampleRatio>1</sampleRatio>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">KBps</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.fieldColors">{Inbound: 0xBDBD5E, Outbound: 0x5F7396}</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">350</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="fs_df_storage" depends="$start_df_storage_search$">
    +            <title>File System usage statistics (external DF_STORAGE collection)</title>
    +            <table id="tablebar">
    +                <search depends="$start_df_storage_search$">
    +                    <query>| mstats latest(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.*" host=$host$ by host, metric_name, dimension_mount
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)
    +| stats first(Available) as Available, first(Use_pct) as Use_pct, first(Used) as Used, first(blocks) as blocks by host, dimension_mount
    +| rename dimension_mount as mount
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free
    +| eval {metric}=value
    +| foreach storage, storage_free, storage_used [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;'/1024/1024, 2) ]
    +| foreach storage*percent [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]
    +| rename storage as "storage (GB)", storage_free as "storage free (GB)", storage_used as "storage used (GB)", storage_free_percent as "storage free (%)", storage_used_percent as "storage used (%)"
    +| eval UsedPct=if(isnum('storage used (%)'), 'storage used (%)', 0 )
    +| fields mount, "storage (GB)", "storage free (GB)", "storage used (GB)", "storage free (%)", "storage used (%)", UsedPct
    +| appendpipe [ stats sum("storage (GB)") as "storage (GB)", sum("storage free (GB)") as "storage free (GB)", sum("storage used (GB)") as "storage used (GB)" ]
    +| eval "storage free (%)" = if(isnull('storage free (%)'), (('storage free (GB)'/'storage (GB)')*100), 'storage free (%)'), "storage used (%)" = if(isnull('storage used (%)'), (('storage used (GB)'/'storage (GB)')*100), 'storage used (%)'), UsedPct = if(isnull(UsedPct), 'storage used (%)', UsedPct)
    +| fillnull value="*** TOTAL GB / AVERAGE % ****" mount
    +| foreach storage*%* UsedPct [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +        </panel>
    +        <panel id="fs_jfs" depends="$start_jfs_storage_search$">
    +            <title>File System Percent utilization (internal JFSFILE collection)</title>
    +            <table>
    +                <search depends="$start_jfs_storage_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsfile" host=$host$ by host, dimension_mount span=1m
    +| stats max(value) AS max_value, avg(value) AS avg_value, min(value) AS min_value, latest(value) AS UsedPct by dimension_mount
    +| sort limit=0 dimension_mount | rename dimension_mount AS "Mount point"
    +| eval value=round(value,2)
    +| fields "Mount point",max_value, avg_value, min_value, UsedPct | eval avg_value=round(avg_value,2)
    +| rename max_value AS "Max value in period (%)", avg_value AS "Average value in period (%)", min_value AS "Min value in Period (%)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### Active Buttons #########################################  -->
    +
    +    <row>
    +        <panel depends="$start_df_storage_search$">
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_df_storage_overtime" data-alt-label="HIDE FILE-SYSTEMS OVER TIME" data-token-value="true">SHOW FILE-SYSTEMS EVOLUTION OVER TIME</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel depends="$start_jfs_storage_search$">
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_jfs_storage_overtime" data-alt-label="HIDE FILE-SYSTEMS OVER TIME" data-token-value="true">SHOW FILE-SYSTEMS EVOLUTION OVER TIME</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### filesystem over time #########################################  -->
    +
    +    <row depends="$start_df_storage_search$ $show_df_storage_overtime$">
    +        <panel>
    +            <title>File systems utilization evolution over time</title>
    +
    +            <input type="text" token="df_storage_mount">
    +              <label>mount</label>
    +              <default>*</default>
    +            </input>
    +
    +            <input type="dropdown" token="df_storage_monitor">
    +                <label>Monitor:</label>
    +                <choice value="storage">storage (volume size)</choice>
    +                <choice value="storage_free">storage_free (volume free)</choice>
    +                <choice value="storage_used">storage_used (volume used)</choice>
    +                <choice value="storage_free_percent">storage_free_percent (%)</choice>
    +                <choice value="storage_used_percent">storage_used_percent (%)</choice>
    +                <default>storage_used_percent</default>
    +                <change>
    +                    <condition value="storage">
    +                        <unset token="form.df_storage_monitor_unit"></unset>
    +                        <set token="df_storage_show_unit">true</set>
    +                        <unset token="df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_free">
    +                        <unset token="form.df_storage_monitor_unit"></unset>
    +                        <set token="df_storage_show_unit">true</set>
    +                        <unset token="df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_used">
    +                        <unset token="form.df_storage_monitor_unit"></unset>
    +                        <set token="df_storage_show_unit">true</set>
    +                        <unset token="df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_free_percent">
    +                        <set token="df_storage_unit">%</set>
    +                        <unset token="df_storage_show_unit"></unset>
    +                        <set token="df_storage_monitor_max_chart">101</set>
    +                    </condition>
    +                    <condition value="storage_used_percent">
    +                        <set token="form.df_storage_monitor_unit">pct</set>
    +                        <set token="df_storage_monitor_max_chart">101</set>
    +                        <unset token="df_storage_show_unit"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="df_storage_monitor_unit" depends="$df_storage_show_unit$">
    +                <label>Unit:</label>
    +                <choice value="MB">MB</choice>
    +                <choice value="GB">GB</choice>
    +                <choice value="TB">TB</choice>
    +                <default>GB</default>
    +                <change>
    +                    <condition value="MB">
    +                        <set token="df_storage_unit_math">value</set>
    +                        <set token="df_storage_unit_legend">MB</set>
    +                    </condition>
    +                    <condition value="GB">
    +                        <set token="df_storage_unit_math">value/1024</set>
    +                        <set token="df_storage_unit_legend">GB</set>
    +                    </condition>
    +                    <condition value="TB">
    +                        <set token="df_storage_unit_math">value/1024/1204</set>
    +                        <set token="df_storage_unit_legend">TB</set>
    +                    </condition>
    +                    <condition value="pct">
    +                        <set token="df_storage_unit_math">value</set>
    +                        <set token="df_storage_unit_legend">pct</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart>
    +                <search depends="$show_df_storage_overtime$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.*" host=$host$ dimension_mount="$df_storage_mount$" by host, metric_name, dimension_mount span=1m
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free
    +| foreach storage, storage_free, storage_used [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;'/1024, 2) ]
    +| stats latest(storage*) as "storage*" by _time, dimension_mount, host
    +| eval value=$df_storage_monitor$
    +| eval value=$df_storage_unit_math$
    +| timechart $span$ latest(value) as $df_storage_monitor$ by dimension_mount</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">$df_storage_unit_legend$</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">$df_storage_monitor_max_chart$</option>
    +            </chart>
    +        </panel>
    +
    +    </row>
    +
    +    <row depends="$show_jfs_storage_overtime$ $show_jfs_storage_overtime$">
    +        <panel>
    +            <title>File systems utilization evolution over time</title>
    +
    +            <input type="text" token="fsfilter" searchWhenChanged="true">
    +                <label>Filter FileSystems by pattern:</label>
    +                <default>*</default>
    +            </input>
    +
    +            <chart>
    +                <search depends="$show_jfs_storage_overtime$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsfile" host=$host$ dimension_device="$fsfilter$" by dimension_device span=1m
    +| timechart $span$ limit=0 useother=f latest(value) As value by dimension_device</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% Used</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_WOF.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_WOF.xml
    new file mode 100644
    index 0000000..db6374f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_WOF.xml
    @@ -0,0 +1,2116 @@
    +<form script="metricator-for-nmon:active_button.js" stylesheet="metricator-for-nmon:ui_simple.css,metricator-for-nmon:panel_decoration.css,metricator-for-nmon:hover.css" isVisible="true" version="1.1" theme="dark">
    +    <label>NMON Performance - Wall Of Performance</label>
    +
    +    <fieldset submitButton="false">
    +
    +        <input type="time" searchWhenChanged="true" token="timerange">
    +            <label>Time range:</label>
    +            <default>
    +                <earliest>-4h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$
    +| stats count by host | dedup host | sort 0 host</query>
    +                <progress>
    +                    <condition match="'job.resultCount' == 0">
    +                        <set token="show_null_host">True</set>
    +                    </condition>
    +                    <condition>
    +                        <unset token="show_null_host"></unset>
    +                    </condition>
    +                </progress>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- OStype -->
    +
    +    <search id="OSType_detection">
    +        <query>| mcatalog values(OStype) as OStype_values where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" host=$host-prefilter$ $host_query$ by host
    +| rename OStype_values as OStype
    +| stats values(OStype) as OStype | mvexpand OStype | head 1 | table OStype</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="'result.OStype'==&quot;Linux&quot;">
    +                <set token="is_Linux">true</set>
    +                <unset token="is_AIX"></unset>
    +                <unset token="is_Solaris"></unset>
    +            </condition>
    +            <condition match="'result.OStype'==&quot;AIX&quot;">
    +                <set token="is_AIX">true</set>
    +                <unset token="is_Linux"></unset>
    +                <unset token="is_Solaris"></unset>
    +            </condition>
    +            <condition match="'result.OStype'==&quot;Solaris&quot;">
    +                <set token="is_Solaris">true</set>
    +                <unset token="is_AIX"></unset>
    +                <unset token="is_Linux"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- TOP data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                <set token="show_null_top">true</set>
    +            </condition>
    +            <condition>
    +                <unset token="show_null_top"/>
    +                <set token="start_top_searches">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- DG data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgxfer" host=$host-prefilter$ $host_query$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <set token="start_disk_stats_search">_time,*</set>
    +                    <unset token="start_dg_stats_search"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_dg_stats_search">_time,*</set>
    +                    <unset token="start_disk_stats_search"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_null_host$">
    +        <panel>
    +            <html>
    +                <p style="color:blue;margin-left:30px;font-size:14px">Searching for nmon performance data did not returned any result, please ensure at least one host is correctly configured to generate performance data. (search for eventtype=nmon:events)</p>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_config" data-alt-label="HIDE HOSTS CONFIGURATION" data-token-value="fields - _time">SHOW HOSTS CONFIGURATION</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_config$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start host configuration</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_config$">
    +        <panel>
    +            <table rejects="$show_null_config$">
    +                <title>NMON Inventory data:</title>
    +                <search depends="$show_config$">
    +                    <query>| inputlookup nmon_inventory
    +| rename hostname as host
    +| `mapping_frameID`
    +| search host=$host-prefilter$ $host_query$ $frameID$
    +| eval "Operating System"=case(OStype=="AIX", ("IBM AIX " + AIX_LEVEL), OStype=="Linux", Linux_distribution, OStype=="Solaris", if(isnotnull(Solaris_version), Solaris_version, Solaris_sunOS_version))
    +| fields host,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,"Operating System",nmon_version
    +| fillnull value="N/A"
    +| rename Physical_mem_MB AS "Physical memory (MB)", Virtual_mem_MB AS "Virtual memory (MB)"</query>
    +                    <earliest>0</earliest>
    +                <!-- Progress event has access to job properties only -->
    +                <progress>
    +                    <condition match="'job.resultCount' == 0">
    +                        <set token="show_null_config">True</set>
    +                    </condition>
    +                    <condition>
    +                        <unset token="show_null_config"/>
    +                    </condition>
    +                </progress>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="drilldown">row</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +            </table>
    +            <html depends="$show_null_config$">
    +                <p style="color:blue;margin-left:30px;font-size:14px">SYSTEM SUMMARY OVERVIEW Search returned no results, The nmon inventory data may not be available yet, manually run the Nmon Inventory Generation report or wait for the auto update. (occurs every hour by default)</p>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_config$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End host configuration</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>CPU statistics</title>
    +        </panel>
    +        <panel id="memory1">
    +            <title>Physical memory</title>
    +        </panel>
    +        <panel id="memory2">
    +            <title>Swap memory</title>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <single>
    +                <title>Average deployment CPU % usage</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` host=$host-prefilter$ $host_query$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart `nmon_span` avg(cpu_load_percent) AS cpu_load_percent | where isnotnull(cpu_load_percent)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">none</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="unit">%</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +        </panel>
    +        <panel>
    +            <single>
    +                <title>Average deployment physical memory % usage</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart `nmon_span` avg(mem_used_effective_PCT) AS mem_used_effective_PCT | where isnotnull(mem_used_effective_PCT)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">none</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="unit">%</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +        </panel>
    +        <panel>
    +            <single rejects="$show_swap_result$">
    +                <title>Average deployment swap memory % usage</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart `nmon_span` avg(swap_used_effective_PCT) AS swap_used_effective_PCT | where isnotnull(swap_used_effective_PCT)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_swap_result">True</set>
    +                        </condition>
    +                        <condition>
    +                            <unset token="show_swap_result"/>
    +                        </condition>
    +                    </progress>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">none</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="unit">%</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <html depends="$show_swap_result$">
    +                <p style="color:blue;margin-left:30px;font-size:14px;margin-top:50px">No swap memory available on these systems</p>
    +            </html>
    +
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_cpu" data-alt-label="HIDE EXTENDED CPU STATS" data-token-value="true">SHOW EXTENDED CPU STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_phymem" data-alt-label="HIDE EXTENDED MEMORY STATS" data-token-value="true">SHOW EXTENDED MEMORY STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_virtualmem" data-alt-label="HIDE EXTENDED SWAP STATS" data-token-value="true">SHOW EXTENDED SWAP STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### CPU #########################################  -->
    +
    +    <row depends="$show_cpu$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended CPU stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_cpu$">
    +        <panel>
    +            <chart>
    +                <title>Deployment global % CPU stats over time</title>
    +                <search depends="$show_cpu$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` host=$host-prefilter$ $host_query$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart `nmon_span` avg(cpu_load_percent) AS cpu_load_percent | trendline sma5(cpu_load_percent) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% CPU</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>Deployment per category % CPU stats over time</title>
    +                <search depends="$show_cpu$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` host=$host-prefilter$ $host_query$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent_by_category`
    +| timechart `nmon_span` avg(Sys_PCT) AS Sys_PCT, avg(User_PCT) AS User_PCT, avg(Wait_PCT) AS Wait_PCT, avg(Idle_PCT) AS Idle_PCT
    +| fields _time,Idle_PCT,Wait_PCT,User_PCT,Sys_PCT</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% CPU</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked100</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row depends="$show_cpu$">
    +        <panel>
    +            <chart>
    +                <title>By host global % CPU stats over time</title>
    +                <search depends="$show_cpu$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` host=$host-prefilter$ $host_query$ by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart `nmon_span` avg(cpu_load_percent) AS cpu_load_percent by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% CPU</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_cpu$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended CPU stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### Physical Memory #########################################  -->
    +
    +    <row depends="$show_phymem$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended physical memory stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Notes: because we perform an aggregation of the deployment, time will bucketed by minute -->
    +
    +    <row depends="$show_phymem$">
    +        <panel>
    +            <chart>
    +                <title>Deployment physical memory MB usage per category over time</title>
    +                <search depends="$show_phymem$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB_by_category`
    +| stats sum(cached) AS cached, sum(buffers) AS buffers, sum(memfree) AS memfree, sum(mem_used_effective) AS mem_used_effective, sum(memtotal) AS memtotal by _time
    +| timechart `nmon_span` avg(*) AS *</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">400</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.overlayFields">memtotal</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.fieldColors">{"memtotal": 0xe50000}</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>Deployment physical memory % usage over time</title>
    +                <search depends="$show_phymem$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart `nmon_span` avg(mem_used_effective_PCT) AS mem_used_effective_PCT | trendline sma5(mem_used_effective_PCT) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% mem</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked100</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row depends="$show_phymem$">
    +        <panel>
    +            <chart>
    +                <title>By host physical memory % usage over time</title>
    +                <search depends="$show_phymem$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart `nmon_span` avg(mem_used_effective_PCT) AS mem_used_effective_PCT by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% mem</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_phymem$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended physical memory stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### Virtual Memory #########################################  -->
    +
    +    <row depends="$show_virtualmem$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended vitual memory stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Notes: because we perform an aggregation of the deployment, time will bucketed by minute -->
    +
    +    <row depends="$show_virtualmem$">
    +        <panel>
    +            <chart>
    +                <title>Deployment swap memory MB usage per category over time</title>
    +                <search depends="$show_virtualmem$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `def_memory_volume_MB_by_category`
    +| stats sum(swap_used_effective) AS swap_used, sum(swaptotal) AS swaptotal, sum(swapfree) AS swapfree by _time
    +| timechart `nmon_span` avg(*) AS *</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">400</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.overlayFields">swaptotal</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.fieldColors">{"swaptotal": 0xe50000}</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>Deployment swap memory % usage over time</title>
    +                <search depends="$show_virtualmem$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart `nmon_span` avg(swap_used_effective_PCT) AS swap_used_effective_PCT
    +| trendline sma5(swap_used_effective_PCT) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% mem</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked100</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row depends="$show_virtualmem$">
    +        <panel>
    +            <chart>
    +                <title>By host swap memory % usage over time</title>
    +                <search depends="$show_virtualmem$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart `nmon_span` avg(swap_used_effective_PCT) AS swap_used_effective_PCT by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% mem</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_virtualmem$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended vitual memory stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="disk">
    +            <title>Disks activity</title>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <single rejects="$start_disk_stats_search$">
    +                <title>Average deployment I/O per sec</title>
    +                <search depends="$start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgxfer" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| stats sum(value) as disk_total_iops by _time, host
    +| timechart `nmon_span` avg(disk_total_iops) AS disk_total_iops | where isnotnull(disk_total_iops)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">none</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="unit">iops</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <single rejects="$start_dg_stats_search$">
    +                <title>Average deployment I/O per sec</title>
    +                <search depends="$start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| stats sum(value) as value by _time, host
    +| timechart `nmon_span` avg(value) AS value | where isnotnull(value)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">none</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="unit">iops</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +        </panel>
    +        <panel>
    +            <single rejects="$start_disk_stats_search$">
    +                <title>Average deployment % of time busy disks</title>
    +                <search depends="$start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbusy" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| timechart `nmon_span` avg(value) AS disk_busy_time_pct | where isnotnull(disk_busy_time_pct)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">none</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="unit">%</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <single rejects="$start_dg_stats_search$">
    +                <title>Average deployment % of time busy disks</title>
    +                <search depends="$start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbusy" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| timechart `nmon_span` avg(value) AS value | where isnotnull(value)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">none</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="unit">%</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +        </panel>
    +        <panel>
    +            <single rejects="$start_disk_stats_search$">
    +                <title>Average deployment disk data transfer size</title>
    +                <search depends="$start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgsize" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| timechart `nmon_span` avg(value) AS disk_block_size_KB | where isnotnull(disk_block_size_KB)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">none</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="unit">KBytes</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <single rejects="$start_dg_stats_search$">
    +                <title>Average deployment disk data transfer size</title>
    +                <search depends="$start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbsize" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| timechart `nmon_span` avg(value) AS value | where isnotnull(value)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">none</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="unit">KBytes</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_diskxfer" data-alt-label="HIDE EXTENDED DISKXFER STATS" data-token-value="true">SHOW EXTENDED DISKXFER STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_diskbusy" data-alt-label="HIDE EXTENDED DISKBUSY STATS" data-token-value="true">SHOW EXTENDED DISKBUSY STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_diskbsize" data-alt-label="HIDE EXTENDED DISKBSIZE STATS" data-token-value="true">SHOW EXTENDED DISKBSIZE STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### DISKXFER #########################################  -->
    +
    +    <row depends="$show_diskxfer$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended diskxfer stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_diskxfer$ $start_dg_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>Deployment global I/O per sec over time</title>
    +                <search depends="$show_diskxfer$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgxfer" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| stats sum(value) as disk_total_iops by _time, host
    +| timechart `nmon_span` avg(disk_total_iops) AS iops
    +| trendline sma5(iops) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">I/O per sec</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row depends="$show_diskxfer$ $start_dg_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>By host I/O per sec over time</title>
    +                <search depends="$show_diskxfer$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgxfer" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| stats sum(value) as disk_total_iops by _time, host
    +| timechart `nmon_span` avg(disk_total_iops) AS iops by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">I/O per sec</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_diskxfer$ $start_disk_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>Deployment global I/O per sec over time</title>
    +                <search depends="$show_diskxfer$ $start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| stats sum(value) AS iops by _time, host
    +| timechart `nmon_span` avg(value) AS iops
    +| trendline sma5(iops) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">I/O per sec</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row depends="$show_diskxfer$ $start_disk_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>By host I/O per sec over time</title>
    +                <search depends="$show_diskxfer$ $start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskxfer" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| stats sum(value) AS iops by _time, host
    +| timechart `nmon_span` avg(value) AS iops by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">I/O per sec</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_diskxfer$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended diskxfer stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### DISKBUSY #########################################  -->
    +
    +    <row depends="$show_diskbusy$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended diskbusy stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_diskbusy$ $start_dg_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>Deployment global % time busy disk over time</title>
    +                <search depends="$show_diskbusy$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbusy" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| timechart `nmon_span` avg(value) as disk_busy_time_pct
    +| trendline sma5(disk_busy_time_pct) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% time busy</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row depends="$show_diskbusy$ $start_dg_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>By host % time busy disk over time</title>
    +                <search depends="$show_diskbusy$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbusy" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| timechart `nmon_span` avg(value) as disk_busy_time_pct by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% time busy</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_diskbusy$ $start_disk_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>Deployment global % time busy disk over time</title>
    +                <search depends="$show_diskbusy$ $start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbusy" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| timechart `nmon_span` avg(value) as disk_busy_time_pct
    +| trendline sma5(disk_busy_time_pct) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% time busy</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row depends="$show_diskbusy$ $start_disk_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>By host % time busy disk over time</title>
    +                <search depends="$show_diskbusy$ $start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbusy" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| timechart `nmon_span` avg(value) as disk_busy_time_pct by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">% time busy</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_diskbusy$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended diskbusy stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### DISKBSIZE #########################################  -->
    +
    +    <row depends="$show_diskbsize$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended diskbsize stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_diskbsize$ $start_dg_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>Deployment global disk data transfer (KBytes per transfer) over time</title>
    +                <search depends="$show_diskbsize$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgsize" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| timechart `nmon_span` avg(value) AS disk_block_size_KB
    +| trendline sma5(disk_block_size_KB) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">KBytes</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row depends="$show_diskbsize$ $start_dg_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>By host disk data transfer (KBytes per transfer) over time</title>
    +                <search depends="$show_diskbsize$ $start_dg_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgsize" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| timechart `nmon_span` avg(value) AS disk_block_size_KB by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">KBytes</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_diskbsize$ $start_disk_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>Deployment global disk data transfer (KBytes per transfer) over time</title>
    +                <search depends="$show_diskbsize$ $start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbsize" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| timechart `nmon_span` avg(value) AS disk_block_size_KB
    +| trendline sma5(tranfer_rate) AS trend</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">KBytes</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row depends="$show_diskbsize$ $start_disk_stats_search$">
    +        <panel>
    +            <chart>
    +                <title>By host disk data transfer (KBytes per transfer) over time</title>
    +                <search depends="$show_diskbsize$ $start_disk_stats_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.diskbsize" host=$host-prefilter$ $host_query$ by host, dimension_device span=1m
    +| timechart `nmon_span` avg(value) AS disk_block_size_KB by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">KBytes</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_diskbsize$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended diskbsize stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### PROCESS AND NETWORK #########################################  -->
    +
    +    <row>
    +        <panel id="process1">
    +            <title>Processes CPU usage</title>
    +        </panel>
    +        <panel id="process2">
    +            <title>Processes Memory usage</title>
    +        </panel>
    +        <panel id="network">
    +            <title>Network traffic</title>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <single rejects="$show_null_top$">
    +                <title>Average deployment CPU usage main process</title>
    +                <search depends="$start_top_searches$">
    +                    <query>| mstats sum(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ by host, metric_name, dimension_Command span=1m
    +| stats max(value) as max_usage_per_core, avg(value) as avg_usage_per_core by dimension_Command | rename dimension_Command as Command
    +| foreach *usage_per_core [ eval &lt;&lt;FIELD&gt;&gt;=round('&lt;&lt;FIELD&gt;&gt;', 3) ] | sort - avg_usage_per_core | head 1 | fields Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">0</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <html depends="$show_null_top$">
    +                <p style="color:blue;margin-left:30px;font-size:14px">Search returned no results, TOP collection (processes activity) may have not been activated at nmon binary startup or no processes activity could be captured. (use the -t or -T option to activate the TOP collection)</p>
    +            </html>
    +        </panel>
    +        <panel>
    +            <single rejects="$show_null_top$">
    +                <title>Average deployment Memory usage main process</title>
    +                <search depends="$start_top_searches$">
    +                    <query>| mstats sum(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData host=$host-prefilter$ $host_query$ by OStype, host, metric_name, dimension_Command span=1m
    +| `def_all_os_top_memory`
    +| stats avg(mem_usage_mb) AS mem_usage_mb by dimension_Command | sort - mem_usage_mb</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">0</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <html depends="$show_null_top$">
    +                <p style="color:blue;margin-left:30px;font-size:14px">Search returned no results, TOP collection (processes activity) may have not been at nmon binary startup or no processes activity could be captured. (use the -t or -T option to activate the TOP collection)</p>
    +            </html>
    +        </panel>
    +        <panel>
    +            <single>
    +                <title>Deployment MBps network traffic (total)</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.net host=$host-prefilter$ $host_query$ (dimension_device!="*lo*") by metric_name, host, dimension_device span=1m
    +| where value&gt;0
    +| eval traffic_type=case(match(dimension_device, ".+read.+"), "Inbound", match(dimension_device, ".+write.+"), "Outbound")
    +| eval value=case(traffic_type="Outbound", value, traffic_type="Inbound", value)
    +| stats avg(value) as value by _time, traffic_type
    +| eval value=round((value/1000),3)
    +| chart latest(value) AS value by traffic_type | eval value=round(value, 3)
    +| fields value | transpose | eval value='row 1' + " / " + 'row 2' | fields value | where isnotnull(value)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="underLabel">IN / OUT  NETWORK TRAFFIC</option>
    +                <option name="colorBy">trend</option>
    +                <option name="colorMode">none</option>
    +                <option name="drilldown">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0x006d9c","0xf2aa0a","0xf58f39","0xd93f3c"]</option>
    +                <option name="rangeValues">[0,30,70,100]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="trendDisplayMode">percent</option>
    +                <option name="unit">MBps</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">0</option>
    +                <option name="useThousandSeparators">1</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_cpuprocess" data-alt-label="HIDE EXTENDED CPU PROCESSES STATS" data-token-value="true">SHOW EXTENDED CPU PROCESSES STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_memprocess" data-alt-label="HIDE EXTENDED MEM PROCESSES STATS" data-token-value="true">SHOW EXTENDED MEM PROCESSES STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <html>
    +                <div class="custom-sub-nav" style="text-align: center;">
    +                    <button class="button2_lowpadding glow" data-token-name="show_net" data-alt-label="HIDE EXTENDED NETWORK STATS" data-token-value="true">SHOW EXTENDED NETWORK STATS</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### TOP CPU #########################################  -->
    +
    +    <row depends="$show_cpuprocess$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended CPU processes stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_cpuprocess$">
    +        <panel>
    +            <chart>
    +                <title>Deployment TOP 10 CPU processes usage</title>
    +                <search depends="$show_cpuprocess$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| where (usage_per_core>0)
    +| stats sum(usage_per_core) as usage_per_core by _time, dimension_Command
    +| timechart `nmon_span` useother=f limit="10" max(usage_per_core) as "CPU Usage per core" by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">logical CPUs</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row depends="$show_cpuprocess$">
    +        <panel>
    +            <chart>
    +                <title>By host TOP 10 CPU processes usage</title>
    +                <search depends="$show_cpuprocess$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| where (usage_per_core>0)
    +| eval key=host . ":" . dimension_Command
    +| timechart `nmon_span` useother=f limit="10" max(usage_per_core) as "CPU Usage per core" by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">logical CPUs</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_cpuprocess$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended CPU processes stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### TOP Memory #########################################  -->
    +
    +    <row depends="$show_memprocess$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended processes memory stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_memprocess$">
    +        <panel>
    +            <chart>
    +                <title>Deployment TOP 10 Memory processes usage</title>
    +                <search depends="$show_memprocess$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData host=$host-prefilter$ $host_query$ by OStype, host, metric_name, dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, OStype, host, metric_name, dimension_Command
    +| `extract_metrics`
    +| eval {metric}=value
    +| stats values(ResSet) as ResSet, values(ResText) as ResText, values(ResData) as ResData, values(ResSize) as ResSize by _time, OStype, host, dimension_Command
    +| fillnull value=0 ResSet ResText ResData ResSize
    +| eval mem_usage_mb=case(match(OStype, "Linux"), ((ResSet)/1024), match(OStype, "AIX"), ((ResData+ResText)/1024), match(OStype, "Solaris"), (ResSize/1024) )
    +| timechart `nmon_span` limit=10 useother=f max(mem_usage_mb) AS mem_usage_mb by dimension_Command</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">MB</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row depends="$show_memprocess$">
    +        <panel>
    +            <chart>
    +                <title>By host TOP 10 Memory processes usage</title>
    +                <search depends="$show_memprocess$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData host=$host-prefilter$ $host_query$ by OStype, host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, OStype, host, metric_name, dimension_Command
    +| `extract_metrics`
    +| eval {metric}=value
    +| stats values(ResSet) as ResSet, values(ResText) as ResText, values(ResData) as ResData, values(ResSize) as ResSize by _time, OStype, host, dimension_Command
    +| fillnull value=0 ResSet ResText ResData ResSize
    +| eval mem_usage_mb=case(match(OStype, "Linux"), ((ResSet)/1024), match(OStype, "AIX"), ((ResData+ResText)/1024), match(OStype, "Solaris"), (ResSize/1024) )
    +| eval key=host . ":" . dimension_Command
    +| timechart `nmon_span` limit=10 useother=f max(mem_usage_mb) As mem_usage_mb by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">MB</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">0</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_memprocess$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended processes memory stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ######################################### Network #########################################  -->
    +
    +    <row depends="$show_net$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>Start extended networking stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_net$">
    +        <panel>
    +            <chart>
    +                <title>Deployment Inbound/Outbound network traffic</title>
    +                <search depends="$show_net$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.net host=$host-prefilter$ $host_query$ (dimension_device!="*lo*") by metric_name, host, dimension_device span=1m
    +| where value&gt;0
    +| eval traffic_type=case(match(dimension_device, ".+read.+"), "Inbound", match(dimension_device, ".+write.+"), "Outbound")
    +| eval value=case(traffic_type="Outbound", "-" . value, traffic_type="Inbound", value)
    +| timechart `nmon_span` avg(value) AS KBps by traffic_type</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">KBps</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.fieldColors">{Inbound: 0xBDBD5E, Outbound: 0x5F7396}</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row depends="$show_net$">
    +        <panel>
    +            <chart>
    +                <title>By host Inbound/Outbound network traffic</title>
    +                <search depends="$show_net$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.net host=$host-prefilter$ $host_query$ (dimension_device!="*lo*") by metric_name, host, dimension_device span=1m
    +| where value&gt;0
    +| eval traffic_type=case(match(dimension_device, ".+read.+"), "Inbound", match(dimension_device, ".+write.+"), "Outbound")
    +| eval value=case(traffic_type="Outbound", "-" . value, traffic_type="Inbound", value)
    +| eval key=host+":"+traffic_type
    +| timechart `nmon_span` useother=f limit=0 avg(value) AS KBps by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.text">Kbps</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_net$">
    +        <panel>
    +            <html>
    +                <div class="dashseparator">
    +                    <h1>End extended networking stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_baseline.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_baseline.xml
    new file mode 100644
    index 0000000..f35e67b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_baseline.xml
    @@ -0,0 +1,354 @@
    +<form stylesheet="standard.css,ui_simple.css,panel_decoration.css" script="autodiscover.js" isVisible="true" version="1.1" theme="dark">
    +    <label>NMON Baseline Analysis</label>
    +    <description>Analyse main system key metrics against the baseline to determine derivation anomalies</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>@d</earliest>
    +                <latest>+1d@d</latest>
    +            </default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +        </input>
    +
    +        <input type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>frameID Selection:</label>
    +            <search base="populate_servers">
    +                <query>stats count by frameID | fields frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <initialValue>*</initialValue>
    +            <valuePrefix>frameID="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +            <choice value="*">Any</choice>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="dropdown" token="host" searchWhenChanged="true">
    +            <label>hosts Selection:</label>
    +            <search base="populate_servers">
    +                <query>search $frameID$ $host-prefilter$ | stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    base search for main dropdown populating for Servers
    +    -->
    +
    +    <search id="populate_servers">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4>Objectives of the baseline: Using system key metrics with an historical analysis to determine expected system resources usage</h4>
    +                </div>
    +
    +                <div class="list">
    +                    <lu>
    +                        <li><b>Days of week analysis:</b> Evaluate the metric usage against days of week, eg: compare monday values against each available mondays stored within the baseline collection</li>
    +                        <li><b>Time span accuracy:</b> Each baseline data points represents the average value of each historical value points evaluated with a per 5 minutes accuracy at the lower level</li>
    +                        <li><b>Future charting:</b> Baseline macros are able to chart in the future if you choose adapted time ranges, by default the period starts at beginning of day and ends at midnight, allowing charting in the future</li>
    +                        <li><b>Reliability:</b> The baseline data gets better and more accurate over time, several months of data are required to get good results. The More stable your servers are (eg. Production servers), the more reliable will be the baseline data</li>
    +                        <li><b>Customizing baseline evaluation:</b> The evaluation of the baseline can easily be customized to exclude specific periods from the evaluation to improve baseline accuracy, such as bank holiday, identified Disaster Recovery Tests or Exercises, ask your Splunk admin</li>
    +                    </lu>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Settings</title>
    +            <input type="dropdown" token="baseline" searchWhenChanged="true">
    +                <label>Type of Baseline:</label>
    +                <default>full</default>
    +                <choice value="simple">Simple baseline</choice>
    +                <choice value="full">Full baseline (lower/predicted/upper)</choice>
    +            </input>
    +            <input type="dropdown" token="baselinemode" searchWhenChanged="true">
    +                <label>Charting the future:</label>
    +                <default>_future</default>
    +                <choice value="_future">True</choice>
    +                <choice value="">False</choice>
    +            </input>
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label>Stats mode:</label>
    +                <default>avg</default>
    +                <choice value="max">Max</choice>
    +                <choice value="avg">Avg</choice>
    +            </input>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>connect</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="cpu">
    +            <title>CPU Percentage Usage vs baseline</title>
    +            <input type="checkbox" token="cpu_scale" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="cpu_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="100">Ends scale at 100 %</choice>
    +                <initialValue>100</initialValue>
    +            </input>
    +            <chart>
    +                <search>
    +                    <query>| `nmon_cpu_pct_$baseline$_baseline$baselinemode$($host$,$statsmode$)`</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.axisTitleY.text">% CPUs</option>
    +                <option name="height">450</option>
    +                <option name="charting.fieldColors">{"predicted": 0x9d0eaf}</option>
    +                <option name="charting.chart.overlayFields">baseline_avg_cpu</option>
    +                <option name="charting.axisY.minimumNumber">$cpu_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$cpu_scaleend$</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=%7C%20%60nmon_cpu_pct_$baseline$_baseline$baselinemode$($host$,$statsmode$)%60&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart.overlayFields=baseline_avg_cpu</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="mem1">
    +            <title>Real Memory Percentage Usage vs baseline</title>
    +            <input type="checkbox" token="realmem_scale" searchWhenChanged="true">
    +                <label></label>
    +                <default>0</default>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="realmem_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <default>100</default>
    +                <choice value="100">Ends scale at 100 %</choice>
    +            </input>
    +            <chart>
    +                <search>
    +                    <query>| `nmon_real_mem_$baseline$_baseline$baselinemode$($host$,$statsmode$)`</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.axisTitleY.text">% Real Mem</option>
    +                <option name="height">450</option>
    +                <option name="charting.fieldColors">{"predicted": 0x9d0eaf}</option>
    +                <option name="charting.chart.overlayFields">baseline_avg_real_mem</option>
    +                <option name="charting.axisY.minimumNumber">$realmem_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$realmem_scaleend$</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=%7C%20%60nmon_real_mem_$baseline$_baseline$baselinemode$($host$,$statsmode$)%60&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart.overlayFields=baseline_avg_real_mem</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="mem2">
    +            <title>Virtual Memory Percentage Usage vs baseline</title>
    +            <input type="checkbox" token="virtualmem_scale" searchWhenChanged="true">
    +                <label></label>
    +                <default>0</default>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="virtualmem_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <default></default>
    +                <choice value="100">Ends scale at 100 %</choice>
    +            </input>
    +            <chart>
    +                <search>
    +                    <query>| `nmon_virtual_mem_$baseline$_baseline$baselinemode$($host$,$statsmode$)`</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.axisTitleY.text">% Virtual Mem</option>
    +                <option name="height">450</option>
    +                <option name="charting.fieldColors">{"predicted": 0x9d0eaf}</option>
    +                <option name="charting.chart.overlayFields">baseline_avg_virtual_mem</option>
    +                <option name="charting.axisY.minimumNumber">$virtualmem_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$virtualmem_scaleend$</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=%7C%20%60nmon_virtual_mem_$baseline$_baseline$baselinemode$($host$,$statsmode$)%60&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart.overlayFields=baseline_avg_virtual_mem</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="disk">
    +            <title>Number of I/O per sec vs baseline</title>
    +            <input type="checkbox" token="iopsmem_scale" searchWhenChanged="true">
    +                <label></label>
    +                <default>0</default>
    +                <choice value="0">Starts scale at 0 I/O per sec</choice>
    +            </input>
    +            <chart>
    +                <search>
    +                    <query>| `nmon_iops_$baseline$_baseline$baselinemode$($host$,$statsmode$)`</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.axisTitleY.text">Nbr I/O per sec</option>
    +                <option name="height">450</option>
    +                <option name="charting.fieldColors">{"predicted": 0x9d0eaf}</option>
    +                <option name="charting.chart.overlayFields">baseline_disk_iops</option>
    +                <option name="charting.axisY.minimumNumber">$iopsmem_scale$</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=%7C%20%60nmon_iops_$baseline$_baseline$baselinemode$($host$,$statsmode$)%60&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart.overlayFields=baseline_disk_iops</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_baseline_AIX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_baseline_AIX.xml
    new file mode 100644
    index 0000000..e26bcc1
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_baseline_AIX.xml
    @@ -0,0 +1,381 @@
    +<form stylesheet="standard.css,ui_simple.css,panel_decoration.css" script="autodiscover.js" isVisible="true" version="1.1" theme="dark">
    +    <label>NMON AIX Baseline Analysis</label>
    +    <description>Analyse main system key metrics against the baseline to determine derivation anomalies</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>@d</earliest>
    +                <latest>+1d@d</latest>
    +            </default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>AIX</default>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +        </input>
    +
    +        <input type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>frameID Selection:</label>
    +            <search base="populate_servers">
    +                <query>stats count by frameID | fields frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <initialValue>*</initialValue>
    +            <valuePrefix>frameID="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +            <choice value="*">Any</choice>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="dropdown" token="host" searchWhenChanged="true">
    +            <label>hosts Selection:</label>
    +            <search base="populate_servers">
    +                <query>search $frameID$ $host-prefilter$ | stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    base search for main dropdown populating for Servers
    +    -->
    +
    +    <search id="populate_servers">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4>Objectives of the baseline: Using system key metrics with an historical analysis to determine expected system resources usage</h4>
    +                </div>
    +
    +                <div class="list">
    +                    <lu>
    +                        <li><b>Days of week analysis:</b> Evaluate the metric usage against days of week, eg: compare monday values against each available mondays stored within the baseline collection</li>
    +                        <li><b>Time span accuracy:</b> Each baseline data points represents the average value of each historical value points evaluated with a per 5 minutes accuracy at the lower level</li>
    +                        <li><b>Future charting:</b> Baseline macros are able to chart in the future if you choose adapted time ranges, by default the period starts at beginning of day and ends at midnight, allowing charting in the future</li>
    +                        <li><b>Reliability:</b> The baseline data gets better and more accurate over time, several months of data are required to get good results. The More stable your servers are (eg. Production servers), the more reliable will be the baseline data</li>
    +                        <li><b>Customizing baseline evaluation:</b> The evaluation of the baseline can easily be customized to exclude specific periods from the evaluation to improve baseline accuracy, such as bank holiday, identified Disaster Recovery Tests or Exercises, ask your Splunk admin</li>
    +                    </lu>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Settings</title>
    +            <input type="dropdown" token="baseline" searchWhenChanged="true">
    +                <label>Type of Baseline:</label>
    +                <default>full</default>
    +                <choice value="simple">Simple baseline</choice>
    +                <choice value="full">Full baseline (lower/predicted/upper)</choice>
    +            </input>
    +            <input type="dropdown" token="baselinemode" searchWhenChanged="true">
    +                <label>Charting the future:</label>
    +                <default>_future</default>
    +                <choice value="_future">True</choice>
    +                <choice value="">False</choice>
    +            </input>
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label>Stats mode:</label>
    +                <default>avg</default>
    +                <choice value="max">Max</choice>
    +                <choice value="avg">Avg</choice>
    +            </input>            
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>connect</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="cpu1">
    +            <title>Virtual CPUs Usage vs baseline</title>
    +            <chart>
    +                <search>
    +                    <query>| `nmon_vp_usage_$baseline$_baseline$baselinemode$($host$,$statsmode$)`</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.axisTitleY.text">virtual CPUs</option>
    +                <option name="height">450</option>
    +                <option name="charting.fieldColors">{"baseline_avg_vp_usage": 0xF69D1F,"vp_usage": 0x259FF8,"entitled": 0x00e600,"virtualCPUs":0xE60000}</option>
    +                <option name="charting.chart.overlayFields">baseline_avg_vp_usage, entitled, virtualCPUs</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=%7C%20%60nmon_vp_usage_$baseline$_baseline$baselinemode$($host$,$statsmode$)%60&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart.overlayFields=baseline_avg_vp_usage&amp;display.visualizations.charting.chart.overlayFields=entitled&amp;display.visualizations.charting.chart.overlayFields=virtualCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="cpu2">
    +            <title>Shared Pool CPUs Usage vs baseline</title>
    +            <chart>
    +                <search>
    +                    <query>| `nmon_pool_usage_$baseline$_baseline$baselinemode$($host$,$statsmode$)`</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.axisTitleY.text">virtual CPUs</option>
    +                <option name="height">450</option>
    +                <option name="charting.fieldColors">{"baseline_avg_pool_usage": 0xF69D1F,"pool_usage": 0x259FF8,"poolCPUs":0xE60000}</option>
    +                <option name="charting.chart.overlayFields">baseline_avg_pool_usage, poolCPUs</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=%7C%20%60nmon_pool_usage_$baseline$_baseline$baselinemode$($host$,$statsmode$)%60&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart.overlayFields=baseline_avg_pool_usage&amp;display.visualizations.charting.chart.overlayFields=poolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="mem1">
    +            <title>Real Memory Percentage Usage vs baseline</title>
    +            <input type="checkbox" token="realmem_scale" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="realmem_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>100</initialValue>
    +                <choice value="100">Ends scale at 100 %</choice>
    +            </input>
    +            <chart>
    +                <search>
    +                    <query>| `nmon_real_mem_$baseline$_baseline$baselinemode$($host$,$statsmode$)`</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.axisTitleY.text">% Real Mem</option>
    +                <option name="height">450</option>
    +                <option name="charting.fieldColors">{"baseline_avg_real_mem": 0xF69D1F,"avg_real_mem": 0x259FF8}</option>
    +                <option name="charting.chart.overlayFields">baseline_avg_real_mem</option>
    +                <option name="charting.axisY.minimumNumber">$realmem_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$realmem_scaleend$</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=%7C%20%60nmon_real_mem_$baseline$_baseline$baselinemode$($host$,$statsmode$)%60&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart.overlayFields=baseline_avg_real_mem</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="mem2">
    +            <title>Virtual Memory Percentage Usage vs baseline</title>
    +            <input type="checkbox" token="virtualmem_scalestart" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="virtualmem_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="100">Ends scale at 100 %</choice>
    +            </input>
    +            <chart>
    +                <search>
    +                    <query>| `nmon_virtual_mem_$baseline$_baseline$baselinemode$($host$,$statsmode$)`</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.axisTitleY.text">% Virtual Mem</option>
    +                <option name="height">450</option>
    +                <option name="charting.fieldColors">{"baseline_avg_virtual_mem": 0xF69D1F,"avg_virtual_mem": 0x259FF8}</option>
    +                <option name="charting.chart.overlayFields">baseline_avg_virtual_mem</option>
    +                <option name="charting.axisY.minimumNumber">$virtualmem_scalestart$</option>
    +                <option name="charting.axisY.maximumNumber">$virtualmem_scaleend$</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=%7C%20%60nmon_virtual_mem_$baseline$_baseline$baselinemode$($host$,$statsmode$)%60&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart.overlayFields=baseline_avg_virtual_mem</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="disk">
    +            <title>Number of I/O per sec vs baseline</title>
    +            <input type="checkbox" token="iopsmem_scale" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0 I/O per sec</choice>
    +            </input>
    +            <chart>
    +                <search>
    +                    <query>| `nmon_iops_$baseline$_baseline$baselinemode$($host$,$statsmode$)`</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.axisTitleY.text">Nbr I/O per sec</option>
    +                <option name="height">450</option>
    +                <option name="charting.fieldColors">{"baseline_disk_iops": 0xF69D1F,"disk_iops": 0x259FF8}</option>
    +                <option name="charting.chart.overlayFields">baseline_disk_iops</option>
    +                <option name="charting.axisY.minimumNumber">$iopsmem_scale$</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=%7C%20%60nmon_iops_$baseline$_baseline$baselinemode$($host$,$statsmode$)%60&amp;display.page.search.tab=visualizations&amp;display.general.type=visualizations&amp;display.visualizations.charting.chart.overlayFields=baseline_disk_iops</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_compare.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_compare.xml
    new file mode 100644
    index 0000000..b2eb6d3
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_compare.xml
    @@ -0,0 +1,1345 @@
    +<form script="Nmon_compare.js" stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI Comparison - Advanced interface for comparative analysis</label>
    +    <description>The comparative analysis provides advanced insights for your server metrics between different time ranges</description>
    +
    +    <!--
    +    base search for main dropdown populating for Server A / B
    +    -->
    +
    +    <search id="populate_timerange1">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $osfilter1$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange1.earliest$</earliest>
    +        <latest>$timerange1.latest$</latest>
    +    </search>
    +
    +    <search id="populate_timerange2">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $osfilter2$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange2.earliest$</earliest>
    +        <latest>$timerange2.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Retrieve the OStype values for each Server A / B and define a token according to its values
    +    -->
    +
    +    <search id="ostype1_analysis">
    +        <query>| mcatalog values(OStype) as OStype_values where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" (host=$host1$) | rename OStype_values as OStype</query>
    +        <earliest>$timerange1.earliest$</earliest>
    +        <latest>$timerange1.latest$</latest>
    +        <progress>
    +            <condition>
    +                <set token="OStype1">$result.OStype$</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <search id="ostype2_analysis">
    +        <query>| mcatalog values(OStype) as OStype_values where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" (host=$host2$) | rename OStype_values as OStype</query>
    +        <earliest>$timerange2.earliest$</earliest>
    +        <latest>$timerange2.latest$</latest>
    +        <progress>
    +            <condition>
    +                <set token="OStype2">$result.OStype$</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!--
    +    Base search for the metric catalog populating, avoid extending raw metrics with non relevant calculated metrics
    +    -->
    +
    +    <search id="populate_metric">
    +        <query>| mcatalog values(metric_name) as metrics where `nmon_metrics_index` metric_name="os.unix.nmon.*" (host=$host1$ OR host=$host2$)
    +| rename metrics as metric_name
    +| mvexpand metric_name
    +| append [ | inputlookup nmon_metric_catalog | where (is_$OStype1$=="True" OR is_$OStype2$=="True") | fields metric_name ]
    +| rex field="metric_name" "os\.unix\.nmon\.(?&lt;metric_category&gt;\w*)\.(?&lt;nmon_section&gt;\w*)"
    +| sort 0 metric_name
    +| lookup nmon_metric_catalog metric_name
    +| eval metric_filter=if(isnull(metric_filter), ("metric_name=" . metric_name), metric_filter)
    +| eval metric_has_device=if(match(metric_name, "\.disk\w*|\.adapters|\.dg\w*|\.top\.|\.df_\w*|\.jfs\w*|\.network\.\w*"), "True", "False")
    +| eval metric_dimension_field=case(match(metric_name, "df_\w*|jfsfile|jfsinode"), "dimension_mount", match(metric_name, "\.top\.*"), "dimension_Command", metric_has_device=="True", "dimension_device")
    +| eval metric_volume_unit_choice=if(match(metric_name, "df_storage\.Used"), "True", "False")
    +| eval metric_rate_unit_choice=if(match(metric_name, "\.network\.net"), "True", "False")
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.\w*\.(?&lt;metric_shortname&gt;\w*)"
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.(?&lt;metric_shortname&gt;\w*)$"
    +| eval metric_calculation=if(isnotnull(metric_calculation), metric_calculation, "eval value=value")
    +| eval metric_type_of_calculation=if(isnotnull(metric_type_of_calculation), metric_type_of_calculation, "01 - raw metric")
    +| eval metric_data_field=if(isnotnull(metric_data_field), metric_data_field, "value")
    +| eval metric_by=if(isnotnull(metric_groupby), metric_groupby, metric_by) | eval metric_by=if(isnull(metric_by), "host", metric_by)
    +| eval metric_timechart_by=if(isnotnull(metric_timechart_by), metric_timechart_by, "host")
    +| eval metric_primary_statsmode=if(isnotnull(metric_primary_statsmode), metric_primary_statsmode, "avg")
    +        </query>
    +        <earliest>$timerange1.earliest$</earliest>
    +        <latest>$timerange1.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +    
    +    <!-- definition of metric related tokens -->
    +
    +    <search id="basesearch_metric_definition" base="populate_metric">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition>
    +                <set token="metric_filter">$result.metric_filter$</set>
    +                <set token="metric_calculation">$result.metric_calculation$</set>
    +                <set token="metric_type_of_calculation">$result.metric_type_of_calculation$</set>
    +                <set token="metric_has_device">$result.metric_has_device$</set>
    +                <set token="metric_dimension_field">$result.metric_dimension_field$</set>
    +                <set token="metric_shortname">$result.metric_shortname$</set>
    +                <set token="metric_data_field">$result.metric_data_field$</set>
    +                <set token="metric_primary_statsmode">$result.metric_primary_statsmode$</set>
    +                <set token="metric_by">$result.metric_by$</set>
    +                <set token="metric_timechart_by">$result.metric_timechart_by$</set>
    +                <set token="metric_volume_unit_choice">$result.metric_volume_unit_choice$</set>
    +                <set token="metric_rate_unit_choice">$result.metric_rate_unit_choice$</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- analyse if the metric has a device dimension -->
    +
    +    <search id="basesearch_metric_device" base="populate_metric">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition match="'result.metric_has_device'==&quot;True&quot;">
    +                <set token="show_device">True</set>
    +            </condition>
    +            <condition match="'result.metric_has_device'==&quot;False&quot;">
    +                <unset token="show_device"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- analyse if the metric has a volume unit choice option -->
    +
    +    <search id="basesearch_metric_volume_unit" base="populate_metric">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition match="'result.metric_volume_unit_choice'==&quot;True&quot;">
    +                <set token="show_unit">True</set>
    +            </condition>
    +            <condition match="'result.metric_volume_unit_choice'==&quot;False&quot;">
    +                <unset token="show_unit"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- analyse if the metric has a rate unit choice option -->
    +
    +    <search id="basesearch_metric_rate_unit" base="populate_metric">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition match="'result.metric_rate_unit_choice'==&quot;True&quot;">
    +                <set token="show_unit_rate">True</set>
    +            </condition>
    +            <condition match="'result.metric_rate_unit_choice'==&quot;False&quot;">
    +                <unset token="show_unit_rate"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <row>
    +
    +        <panel>
    +            <title>A - Select time period</title>
    +
    +            <input type="time" token="timerange1" searchWhenChanged="true">
    +                <label>Time Range:</label>
    +                <default>
    +                    <earliest>-24h</earliest>
    +                    <latest>now</latest>
    +                </default>
    +            </input>
    +            <input type="dropdown" token="TimeFilter" searchWhenChanged="true">
    +                <label>Time Filtering:</label>
    +                <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +                <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +                <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +                <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +                <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +                <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +                <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +                <default>No_Filter</default>
    +            </input>
    +            <input type="text" token="timerange1_name" searchWhenChanged="true">
    +                <label>Name for period:</label>
    +                <default>period_A</default>
    +            </input>
    +        </panel>
    +
    +        <panel>
    +            <title>B - Select time period</title>
    +
    +            <input type="time" token="timerange2" searchWhenChanged="true">
    +                <label>Time Range:</label>
    +                <default>
    +                    <earliest>-24h</earliest>
    +                    <latest>now</latest>
    +                </default>
    +            </input>
    +            <input type="dropdown" token="TimeFilter" searchWhenChanged="true">
    +                <label>Time Filtering:</label>
    +                <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +                <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +                <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +                <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +                <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +                <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +                <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +                <default>No_Filter</default>
    +            </input>
    +            <input type="text" token="timerange2_name" searchWhenChanged="true">
    +                <label>Name for period:</label>
    +                <default>period_B</default>
    +            </input>
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>A - Select the first server:</title>
    +
    +            <input type="dropdown" token="osfilter1" searchWhenChanged="true">
    +                <label>Filter OS Type:</label>
    +                <default>*</default>
    +                <choice value="*">Any OS</choice>
    +                <choice value="AIX">AIX</choice>
    +                <choice value="Linux">Linux</choice>
    +                <choice value="Solaris">Solaris</choice>
    +                <prefix>OStype="</prefix>
    +                <suffix>"</suffix>
    +            </input>
    +
    +            <input type="multiselect" token="frameID1" searchWhenChanged="true">
    +                <label>frameID Selection:</label>
    +                <search base="populate_timerange1">
    +                    <query>stats count by frameID | fields frameID | dedup frameID | sort 0 frameID</query>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>frameID="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <fieldForLabel>frameID</fieldForLabel>
    +                <fieldForValue>frameID</fieldForValue>
    +                <choice value="*">Any</choice>
    +            </input>
    +
    +            <input type="text" token="host-prefilter1" searchWhenChanged="true">
    +                <label>Optional: Filter hosts populating</label>
    +                <prefix>host="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +
    +            <input id="host1" type="dropdown" token="host1" searchWhenChanged="true">
    +                <label>hosts Selection:</label>
    +                <search base="populate_timerange1">
    +                    <query>search $frameID1$ $host-prefilter1$ | stats count by host | dedup host | sort 0 host</query>
    +                </search>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +            </input>
    +
    +            <input id="device1" type="multiselect" token="device1" searchWhenChanged="true" depends="$show_device$">
    +                <label>Dimensions:</label>
    +                <search>
    +                    <query>| mcatalog values($metric_dimension_field$) as $metric_dimension_field$_values where `nmon_metrics_index` $metric_filter$ $host-prefilter1$ host=$host1$ $osfilter1$
    +| rename $metric_dimension_field$_values as $metric_dimension_field$
    +| mvexpand $metric_dimension_field$ | dedup $metric_dimension_field$ | sort 0 $metric_dimension_field$</query>
    +                    <earliest>$timerange1.earliest$</earliest>
    +                    <latest>$timerange1.latest$</latest>
    +                </search>
    +                <choice value="*">Any</choice>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>$metric_dimension_field$=</valuePrefix>
    +                <delimiter> OR </delimiter>
    +                <fieldForLabel>$metric_dimension_field$</fieldForLabel>
    +                <fieldForValue>$metric_dimension_field$</fieldForValue>
    +            </input>
    +
    +        </panel>
    +
    +        <panel>
    +            <title>B - Select the second server to compare with:</title>
    +
    +            <input type="dropdown" token="osfilter2" searchWhenChanged="true">
    +                <label>Filter OS Type:</label>
    +                <default>*</default>
    +                <choice value="*">Any OS</choice>
    +                <choice value="AIX">AIX</choice>
    +                <choice value="Linux">Linux</choice>
    +                <choice value="Solaris">Solaris</choice>
    +                <prefix>OStype="</prefix>
    +                <suffix>"</suffix>
    +            </input>
    +
    +            <input type="multiselect" token="frameID2" searchWhenChanged="true">
    +                <label>frameID Selection:</label>
    +                <search base="populate_timerange2">
    +                    <query>stats count by frameID | fields frameID | dedup frameID | sort 0 frameID</query>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>frameID="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <fieldForLabel>frameID</fieldForLabel>
    +                <fieldForValue>frameID</fieldForValue>
    +                <choice value="*">Any</choice>
    +            </input>
    +
    +            <input type="text" token="host-prefilter2" searchWhenChanged="true">
    +                <label>Optional: Filter hosts populating</label>
    +                <prefix>host="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +
    +            <input id="host2" type="dropdown" token="host2" searchWhenChanged="true">
    +                <label>hosts Selection:</label>
    +                <search base="populate_timerange2">
    +                    <query>search $frameID2$ $host-prefilter2$ | stats count by host | dedup host | sort 0 host</query>
    +                </search>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +            </input>
    +
    +            <input id="device2" type="multiselect" token="device2" searchWhenChanged="true" depends="$show_device$">
    +                <label>Dimensions:</label>
    +                <search>
    +                    <query>| mcatalog values($metric_dimension_field$) as $metric_dimension_field$_values where `nmon_metrics_index` $metric_filter$ $host-prefilter2$ host=$host2$ $osfilter2$
    +| rename $metric_dimension_field$_values as $metric_dimension_field$
    +| mvexpand $metric_dimension_field$ | dedup $metric_dimension_field$ | sort 0 $metric_dimension_field$</query>
    +                    <earliest>$timerange2.earliest$</earliest>
    +                    <latest>$timerange2.latest$</latest>
    +                </search>
    +                <choice value="*">Any</choice>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>$metric_dimension_field$=</valuePrefix>
    +                <delimiter> OR </delimiter>
    +                <fieldForLabel>$metric_dimension_field$</fieldForLabel>
    +                <fieldForValue>$metric_dimension_field$</fieldForValue>
    +            </input>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row>
    +        <panel rejects="$host1$">
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select the server A in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel rejects="$host2$">
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select the server B in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_device$">
    +        <panel depends="$host1$" rejects="$device1$">
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select the device A in the device selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel depends="$host2$" rejects="$device2$">
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select the device B in the device selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$host1$ $host2$ $metric_name$ $show_device$">
    +        <panel>
    +            <html>
    +                <div class="blue_help_user">
    +                    <p>- - - - - - - - - - INFORMATION: the metric $metric_name$ has dimensions that can filtered out in the dimensions selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Metric selection - which metric do you want to compare ?</title>
    +
    +            <input token="metric_category" type="dropdown" searchWhenChanged="true">
    +                <label>METRIC CATEGORY:</label>
    +                <search base="populate_metric">
    +                    <query>stats count by metric_category | sort 0 metric_category</query>
    +                </search>
    +                <choice value="*">Any</choice>
    +                <default>*</default>
    +                <fieldForLabel>metric_category</fieldForLabel>
    +                <fieldForValue>metric_category</fieldForValue>
    +            </input>
    +
    +            <input token="nmon_section" type="dropdown" searchWhenChanged="true">
    +                <label>NMON SECTION:</label>
    +                <search base="populate_metric">
    +                    <query>search metric_category="$metric_category$" | stats count by nmon_section | sort 0 nmon_section</query>
    +                </search>
    +                <choice value="*">Any</choice>
    +                <default>*</default>
    +                <fieldForLabel>nmon_section</fieldForLabel>
    +                <fieldForValue>nmon_section</fieldForValue>
    +            </input>
    +
    +            <input token="metric_type_of_calculation_form" type="dropdown" searchWhenChanged="true">
    +                <label>TYPE OF METRIC CALCULATION:</label>
    +                <search base="populate_metric">
    +                    <query>search metric_category="$metric_category$" | stats count by metric_type_of_calculation | sort 0 metric_type_of_calculation</query>
    +                </search>
    +                <choice value="*">Any</choice>
    +                <default>*</default>
    +                <fieldForLabel>metric_type_of_calculation</fieldForLabel>
    +                <fieldForValue>metric_type_of_calculation</fieldForValue>
    +            </input>
    +
    +            <!-- the metric_name dropdown size will be increased using css -->
    +
    +            <input id="metric_name" token="metric_name" type="dropdown" searchWhenChanged="true">
    +                <label>PERFORMANCE METRIC:</label>
    +                <search base="populate_metric">
    +                    <query>search metric_category="$metric_category$" nmon_section="$nmon_section$" metric_type_of_calculation="$metric_type_of_calculation_form$" | table metric_name | sort 0 metric_name</query>
    +                </search>
    +                <fieldForLabel>metric_name</fieldForLabel>
    +                <fieldForValue>metric_name</fieldForValue>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_device$ $show_unit$">
    +        <panel>
    +
    +            <input type="dropdown" token="storage_unit">
    +                <label>Unit:</label>
    +                <choice value="MB">MB</choice>
    +                <choice value="GB">GB</choice>
    +                <choice value="TB">TB</choice>
    +                <default>GB</default>
    +                <change>
    +                    <condition value="MB">
    +                        <set token="metric_math">value</set>
    +                        <set token="storage_metric_unit">MB</set>
    +                    </condition>
    +                    <condition value="GB">
    +                        <set token="metric_math">value/1024</set>
    +                        <set token="storage_metric_unit">GB</set>
    +                    </condition>
    +                    <condition value="TB">
    +                        <set token="metric_math">value/1024/1204</set>
    +                        <set token="storage_metric_unit">TB</set>
    +                    </condition>
    +                    <condition value="pct">
    +                        <set token="metric_math">value</set>
    +                        <set token="storage_metric_unit">pct</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_device$ $show_unit_rate$">
    +        <panel>
    +
    +            <input type="dropdown" token="rate_unit">
    +                <label>Unit:</label>
    +                <choice value="KBps">KBps</choice>
    +                <choice value="MBps">MBps</choice>
    +                <choice value="GBps">GBps</choice>
    +                <default>KBps</default>
    +                <change>
    +                    <condition value="KBps">
    +                        <set token="metric_math">value</set>
    +                        <set token="rate_metric_unit">KBps</set>
    +                    </condition>
    +                    <condition value="MBps">
    +                        <set token="metric_math">value/1000</set>
    +                        <set token="rate_metric_unit">MBps</set>
    +                    </condition>
    +                    <condition value="GBps">
    +                        <set token="metric_math">value/1000/1000</set>
    +                        <set token="rate_metric_unit">GBps</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row depends="$host1$ $host2$" rejects="$metric_name$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select the performance metric to be compared in the metric selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!--
    +
    +    Base searches for KPIs single forms
    +
    +    -->
    +
    +    <search id="KPIs_server_A">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter1$ host=$host1$ $osfilter1$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$TimeFilter$`
    +| stats avg($metric_data_field$) as avg, median($metric_data_field$) as median, max($metric_data_field$) as max</query>
    +        <earliest>$timerange1.earliest$</earliest>
    +        <latest>$timerange1.latest$</latest>
    +    </search>
    +
    +    <search id="KPIs_server_B">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter2$ host=$host2$ $osfilter2$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$TimeFilter$`
    +| stats avg($metric_data_field$) as avg, median($metric_data_field$) as median, max($metric_data_field$) as max</query>
    +        <earliest>$timerange2.earliest$</earliest>
    +        <latest>$timerange2.latest$</latest>
    +    </search>
    +
    +    <search id="KPIs_server_A_device" depends="$show_device$">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter1$ host=$host1$ $osfilter1$ $device1$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$TimeFilter$`
    +| eval storage_metric_unit="$storage_metric_unit$", metric_volume_unit_choice="$metric_volume_unit_choice$"
    +| eval rate_metric_unit="$rate_metric_unit$", metric_rate_unit_choice="$metric_rate_unit_choice$"
    +| eval $metric_data_field$=case(metric_volume_unit_choice=="True" AND storage_metric_unit=="MB", $metric_data_field$, metric_volume_unit_choice=="True" AND storage_metric_unit=="GB", $metric_data_field$/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="TB", $metric_data_field$/1024/1024, metric_volume_unit_choice=="False", $metric_data_field$)
    +| eval $metric_data_field$=case(metric_rate_unit_choice=="True" AND rate_metric_unit=="KBps", $metric_data_field$, metric_rate_unit_choice=="True" AND rate_metric_unit=="MBps", $metric_data_field$/1000, metric_rate_unit_choice=="True" AND rate_metric_unit=="GBps", $metric_data_field$/1000/1000, metric_rate_unit_choice=="False", $metric_data_field$)
    +| stats avg($metric_data_field$) as avg, median($metric_data_field$) as median, max($metric_data_field$) as max</query>
    +        <earliest>$timerange1.earliest$</earliest>
    +        <latest>$timerange1.latest$</latest>
    +    </search>
    +
    +    <search id="KPIs_server_B_device" depends="$show_device$">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter2$ host=$host2$ $osfilter2$ $device2$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$TimeFilter$`
    +| eval storage_metric_unit="$storage_metric_unit$", metric_volume_unit_choice="$metric_volume_unit_choice$"
    +| eval rate_metric_unit="$rate_metric_unit$", metric_rate_unit_choice="$metric_rate_unit_choice$"
    +| eval $metric_data_field$=case(metric_volume_unit_choice=="True" AND storage_metric_unit=="MB", $metric_data_field$, metric_volume_unit_choice=="True" AND storage_metric_unit=="GB", $metric_data_field$/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="TB", $metric_data_field$/1024/1024, metric_volume_unit_choice=="False", $metric_data_field$)
    +| eval $metric_data_field$=case(metric_rate_unit_choice=="True" AND rate_metric_unit=="KBps", $metric_data_field$, metric_rate_unit_choice=="True" AND rate_metric_unit=="MBps", $metric_data_field$/1000, metric_rate_unit_choice=="True" AND rate_metric_unit=="GBps", $metric_data_field$/1000/1000, metric_rate_unit_choice=="False", $metric_data_field$)
    +| stats avg($metric_data_field$) as avg, median($metric_data_field$) as median, max($metric_data_field$) as max</query>
    +        <earliest>$timerange2.earliest$</earliest>
    +        <latest>$timerange2.latest$</latest>
    +    </search>
    +
    +    <!--
    +
    +    KPIs Server A / B
    +
    +    -->
    +
    +
    +    <row>
    +        <panel>
    +            <title>Server A - main KPIs results</title>
    +
    +            <html>
    +                <div style="font-size: 18px; margin: 10px 0; font-weight: bold; text-align: center; color: black;">
    +                    <p>Server A:
    +                        <span style="color: #aec6cf; font-size: 200%;">$host1$</span>
    +                    </p>
    +                </div>
    +            </html>
    +
    +            <single rejects="$show_device$">
    +                <search base="KPIs_server_A">
    +                    <query>fields avg</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Average $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single rejects="$show_device$">
    +                <search base="KPIs_server_A">
    +                    <query>fields median</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Median $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single rejects="$show_device$">
    +                <search base="KPIs_server_A">
    +                    <query>fields max</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Max $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single depends="$show_device$">
    +                <search base="KPIs_server_A_device">
    +                    <query>fields avg</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Average $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single depends="$show_device$">
    +                <search base="KPIs_server_A_device">
    +                    <query>fields median</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Median $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single depends="$show_device$">
    +                <search base="KPIs_server_A_device">
    +                    <query>fields max</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Max $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +        </panel>
    +
    +        <panel>
    +            <title>Server B - main KPIs results</title>
    +
    +            <html>
    +                <div style="font-size: 18px; margin: 10px 0; font-weight: bold; text-align: center; color: black;">
    +                    <p>Server B:
    +                        <span style="color: #aec6cf; font-size: 200%;">$host2$</span>
    +                    </p>
    +                </div>
    +            </html>
    +
    +            <single rejects="$show_device$">
    +                <search base="KPIs_server_B">
    +                    <query>fields avg</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Average $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single rejects="$show_device$">
    +                <search base="KPIs_server_B">
    +                    <query>fields median</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Median $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single rejects="$show_device$">
    +                <search base="KPIs_server_B">
    +                    <query>fields max</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Max $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single depends="$show_device$">
    +                <search base="KPIs_server_B_device">
    +                    <query>fields avg</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Average $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single depends="$show_device$">
    +                <search base="KPIs_server_B_device">
    +                    <query>fields median</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Median $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single depends="$show_device$">
    +                <search base="KPIs_server_B_device">
    +                    <query>fields max</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Max $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <!--
    +
    +    Charting parameters
    +
    +    -->
    +
    +
    +    <row depends="$chartactivate$">
    +        <panel>
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <!--
    +
    +    Combined charting Server A / B
    +
    +    -->
    +
    +    <row>
    +        <panel>
    +            <title>Combined Chart (Time line period 1)</title>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label>Statistic mode:</label>
    +                <default>avg</default>
    +                <choice value="max">Max</choice>
    +                <choice value="avg">Avg</choice>
    +                <choice value="min">Min</choice>
    +                <choice value="median">Median</choice>
    +                <choice value="mode">Mode</choice>
    +                <choice value="range">Range</choice>
    +            </input>
    +
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +
    +            <input type="dropdown" token="chart_settings" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="0">Show charting parameters</choice>
    +                <choice value="1">Hide charting parameters</choice>
    +                <default>1</default>
    +                <change>
    +                    <condition value="0">
    +                        <set token="chart_customize">True</set>
    +                    </condition>
    +                    <condition value="1">
    +                        <unset token="chart_customize"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="chart" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.chart.nullValueMode" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +
    +            <input type="dropdown" token="chart.stackingmode" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.legend.placement" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +
    +            <input type="checkbox" token="chart_min_scale" depends="$chart_customize$" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0</choice>
    +            </input>
    +
    +            <input type="checkbox" token="chart_max_scale" depends="$chart_customize$" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="101">Max scale at 100</choice>
    +            </input>
    +
    +            <chart rejects="$show_device$">
    +                <search rejects="$show_device$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter1$ host=$host1$ $osfilter1$ earliest="$timerange1.earliest$" latest="$timerange1.latest$" by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$TimeFilter$`
    +| bucket _time $span$
    +| chart limit=0 useother=f $statsmode$($metric_data_field$) As $timerange1_name$, $statsmode$(fake) As fake by _time, host | makecontinuous _time $span$
    +| fields _time,$timerange1_name$*
    +| appendcols
    +[ | mstats avg(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter2$ host=$host2$ $osfilter2$ earliest="$timerange2.earliest$" latest="$timerange2.latest$" by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$TimeFilter$`
    +| bucket _time $span$
    +| chart limit=0 useother=f $statsmode$($metric_data_field$) As $timerange2_name$, $statsmode$(fake) As fake by _time, host | makecontinuous _time $span$
    +| fields $timerange2_name$* ] | where isnotnull(_time)</query>
    +                    <earliest>$timerange1.earliest$</earliest>
    +                    <latest>$timerange1.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$metric_shortname$</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$chart_max_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +
    +            <chart depends="$show_device$">
    +                <search depends="$show_device$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter1$ host=$host1$ $osfilter1$ $device1$ earliest="$timerange1.earliest$" latest="$timerange1.latest$" by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$TimeFilter$`
    +| eval storage_metric_unit="$storage_metric_unit$", metric_volume_unit_choice="$metric_volume_unit_choice$"
    +| eval rate_metric_unit="$rate_metric_unit$", metric_rate_unit_choice="$metric_rate_unit_choice$"
    +| eval $metric_data_field$=case(metric_volume_unit_choice=="True" AND storage_metric_unit=="MB", $metric_data_field$, metric_volume_unit_choice=="True" AND storage_metric_unit=="GB", $metric_data_field$/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="TB", $metric_data_field$/1024/1024, metric_volume_unit_choice=="False", $metric_data_field$)
    +| eval $metric_data_field$=case(metric_rate_unit_choice=="True" AND rate_metric_unit=="KBps", $metric_data_field$, metric_rate_unit_choice=="True" AND rate_metric_unit=="MBps", $metric_data_field$/1000, metric_rate_unit_choice=="True" AND rate_metric_unit=="GBps", $metric_data_field$/1000/1000, metric_rate_unit_choice=="False", $metric_data_field$)
    +| bucket _time $span$
    +| chart limit=0 useother=f $statsmode$($metric_data_field$) As $timerange1_name$, $statsmode$(fake) As fake by _time, host | makecontinuous _time $span$
    +| fields _time,$timerange1_name$*
    +| appendcols
    +[ | mstats avg(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter2$ host=$host2$ $osfilter2$ $device2$ earliest="$timerange2.earliest$" latest="$timerange2.latest$" by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$TimeFilter$`
    +| eval storage_metric_unit="$storage_metric_unit$", metric_volume_unit_choice="$metric_volume_unit_choice$"
    +| eval rate_metric_unit="$rate_metric_unit$", metric_rate_unit_choice="$metric_rate_unit_choice$"
    +| eval $metric_data_field$=case(metric_volume_unit_choice=="True" AND storage_metric_unit=="MB", $metric_data_field$, metric_volume_unit_choice=="True" AND storage_metric_unit=="GB", $metric_data_field$/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="TB", $metric_data_field$/1024/1024, metric_volume_unit_choice=="False", $metric_data_field$)
    +| eval $metric_data_field$=case(metric_rate_unit_choice=="True" AND rate_metric_unit=="KBps", $metric_data_field$, metric_rate_unit_choice=="True" AND rate_metric_unit=="MBps", $metric_data_field$/1000, metric_rate_unit_choice=="True" AND rate_metric_unit=="GBps", $metric_data_field$/1000/1000, metric_rate_unit_choice=="False", $metric_data_field$)
    +| bucket _time $span$
    +| chart limit=0 useother=f $statsmode$($metric_data_field$) As $timerange2_name$, $statsmode$(fake) As fake by _time, host | makecontinuous _time $span$
    +| fields $timerange2_name$* ] | where isnotnull(_time)</query>
    +                    <earliest>$timerange1.earliest$</earliest>
    +                    <latest>$timerange1.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$metric_shortname$</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$chart_max_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <!--
    +
    +    Charting Server A / B
    +
    +    -->
    +
    +
    +    <row>
    +        <panel>
    +            <title>Chart server A</title>
    +
    +            <html>
    +                <div style="font-size: 18px; margin: 10px 0; font-weight: bold; text-align: center; color: black;">
    +                    <p>Server A:
    +                        <span style="color: #aec6cf; font-size: 200%;">$host1$</span>
    +                    </p>
    +                </div>
    +            </html>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label>Statistic mode:</label>
    +                <default>avg</default>
    +                <choice value="max">Max</choice>
    +                <choice value="avg">Avg</choice>
    +                <choice value="min">Min</choice>
    +                <choice value="median">Median</choice>
    +                <choice value="mode">Mode</choice>
    +                <choice value="range">Range</choice>
    +            </input>
    +
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +
    +            <input type="dropdown" token="chart_settings" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="0">Show charting parameters</choice>
    +                <choice value="1">Hide charting parameters</choice>
    +                <default>1</default>
    +                <change>
    +                    <condition value="0">
    +                        <set token="chart_customize">True</set>
    +                    </condition>
    +                    <condition value="1">
    +                        <unset token="chart_customize"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="chart" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.chart.nullValueMode" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +
    +            <input type="dropdown" token="chart.stackingmode" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.legend.placement" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +
    +            <input type="checkbox" token="chart_min_scale" depends="$chart_customize$" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0</choice>
    +            </input>
    +
    +            <input type="checkbox" token="chart_max_scale" depends="$chart_customize$" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="101">Max scale at 100</choice>
    +            </input>
    +
    +            <chart rejects="$show_device$">
    +                <search rejects="$show_device$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter1$ host=$host1$ $osfilter1$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$TimeFilter$`
    +| timechart $span$ limit=0 useother=f $statsmode$($metric_data_field$) As $timerange1_name$, $statsmode$(fake) As fake by host</query>
    +                    <earliest>$timerange1.earliest$</earliest>
    +                    <latest>$timerange1.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$metric_shortname$</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$chart_max_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +
    +            <chart depends="$show_device$">
    +                <search depends="$show_device$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter1$ host=$host1$ $osfilter1$ $device1$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$TimeFilter$`
    +| eval storage_metric_unit="$storage_metric_unit$", metric_volume_unit_choice="$metric_volume_unit_choice$"
    +| eval rate_metric_unit="$rate_metric_unit$", metric_rate_unit_choice="$metric_rate_unit_choice$"
    +| eval $metric_data_field$=case(metric_volume_unit_choice=="True" AND storage_metric_unit=="MB", $metric_data_field$, metric_volume_unit_choice=="True" AND storage_metric_unit=="GB", $metric_data_field$/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="TB", $metric_data_field$/1024/1024, metric_volume_unit_choice=="False", $metric_data_field$)
    +| eval $metric_data_field$=case(metric_rate_unit_choice=="True" AND rate_metric_unit=="KBps", $metric_data_field$, metric_rate_unit_choice=="True" AND rate_metric_unit=="MBps", $metric_data_field$/1000, metric_rate_unit_choice=="True" AND rate_metric_unit=="GBps", $metric_data_field$/1000/1000, metric_rate_unit_choice=="False", $metric_data_field$)
    +| timechart $span$ limit=0 useother=f $statsmode$($metric_data_field$) As $timerange1_name$, $statsmode$(fake) As fake by host</query>
    +                    <earliest>$timerange1.earliest$</earliest>
    +                    <latest>$timerange1.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$metric_shortname$</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$chart_max_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +
    +        </panel>
    +
    +        <panel>
    +            <title>Chart server B</title>
    +
    +            <html>
    +                <div style="font-size: 18px; margin: 10px 0; font-weight: bold; text-align: center; color: black;">
    +                    <p>Server B:
    +                        <span style="color: #aec6cf; font-size: 200%;">$host2$</span>
    +                    </p>
    +                </div>
    +            </html>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label>Statistic mode:</label>
    +                <default>avg</default>
    +                <choice value="max">Max</choice>
    +                <choice value="avg">Avg</choice>
    +                <choice value="min">Min</choice>
    +                <choice value="median">Median</choice>
    +                <choice value="mode">Mode</choice>
    +                <choice value="range">Range</choice>
    +            </input>
    +
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +
    +            <input type="dropdown" token="chart_settings" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="0">Show charting parameters</choice>
    +                <choice value="1">Hide charting parameters</choice>
    +                <default>1</default>
    +                <change>
    +                    <condition value="0">
    +                        <set token="chart_customize">True</set>
    +                    </condition>
    +                    <condition value="1">
    +                        <unset token="chart_customize"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="chart" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.chart.nullValueMode" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +
    +            <input type="dropdown" token="chart.stackingmode" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.legend.placement" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +
    +            <input type="checkbox" token="chart_min_scale" depends="$chart_customize$" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0</choice>
    +            </input>
    +
    +            <input type="checkbox" token="chart_max_scale" depends="$chart_customize$" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="101">Max scale at 100</choice>
    +            </input>
    +
    +            <chart rejects="$show_device$">
    +                <search rejects="$show_device$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter2$ host=$host2$ $osfilter2$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$TimeFilter$`
    +| timechart $span$ limit=0 useother=f $statsmode$($metric_data_field$) As $timerange2_name$, $statsmode$(fake) As fake by host</query>
    +                    <earliest>$timerange2.earliest$</earliest>
    +                    <latest>$timerange2.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$metric_shortname$</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$chart_max_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +
    +            <chart depends="$show_device$">
    +                <search depends="$show_device$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter2$ host=$host2$ $osfilter2$ $device2$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$TimeFilter$`
    +| eval storage_metric_unit="$storage_metric_unit$", metric_volume_unit_choice="$metric_volume_unit_choice$"
    +| eval rate_metric_unit="$rate_metric_unit$", metric_rate_unit_choice="$metric_rate_unit_choice$"
    +| eval $metric_data_field$=case(metric_volume_unit_choice=="True" AND storage_metric_unit=="MB", $metric_data_field$, metric_volume_unit_choice=="True" AND storage_metric_unit=="GB", $metric_data_field$/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="TB", $metric_data_field$/1024/1024, metric_volume_unit_choice=="False", $metric_data_field$)
    +| eval $metric_data_field$=case(metric_rate_unit_choice=="True" AND rate_metric_unit=="KBps", $metric_data_field$, metric_rate_unit_choice=="True" AND rate_metric_unit=="MBps", $metric_data_field$/1000, metric_rate_unit_choice=="True" AND rate_metric_unit=="GBps", $metric_data_field$/1000/1000, metric_rate_unit_choice=="False", $metric_data_field$)
    +| timechart $span$ limit=0 useother=f $statsmode$($metric_data_field$) As $timerange2_name$, $statsmode$(fake) As fake by host</query>
    +                    <earliest>$timerange2.earliest$</earliest>
    +                    <latest>$timerange2.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$metric_shortname$</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$chart_max_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_mexplorer.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_mexplorer.xml
    new file mode 100644
    index 0000000..0d8029d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_mexplorer.xml
    @@ -0,0 +1,1232 @@
    +<form stylesheet="ui_simple.css" script="modal.js" isVisible="true" version="1.1" theme="dark">
    +    <label>Metric Explorer - Universal interface for Nmon metrics exploration</label>
    +    <description>The Metric Explorer provides a simple and efficient human interface to analyse any available metrics</description>
    +
    +    <!--
    +    base search for main dropdown populating for Servers
    +    -->
    +
    +    <search id="populate_servers">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Retrieve the OStype values for each Server and define a token according to its values
    +    This token will be used to filter out added calculated metrics
    +    -->
    +
    +    <search id="ostype_analysis">
    +        <query>| mcatalog values(OStype) as OStype_values where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" ($host$)
    +| rename OStype_values as OStype
    +| mvexpand OStype
    +| eval OStype="is_" . OStype . "==\"True\""
    +| mvcombine OStype | nomv OStype | rex field=OStype mode=sed "s/\" /\" OR /g"</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition>
    +                <set token="OStype">$result.OStype$</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!--
    +    Base search for the metric catalog populating, avoid extending raw metrics with non relevant calculated metrics
    +    -->
    +
    +    <search id="populate_metric_mono">
    +        <query>| mcatalog values(metric_name) as metrics where `nmon_metrics_index` metric_name="os.unix.nmon.*" $osfilter$ ($host$)
    +| rename metrics as metric_name
    +| mvexpand metric_name
    +| append [ | inputlookup nmon_metric_catalog where ($OStype$) | fields metric_name ]
    +| rex field="metric_name" "os\.unix\.nmon\.(?&lt;metric_category&gt;\w*)\.(?&lt;nmon_section&gt;\w*)"
    +| sort 0 metric_name
    +| lookup nmon_metric_catalog metric_name
    +| eval metric_filter=if(isnull(metric_filter), ("metric_name=" . metric_name), metric_filter)
    +| eval metric_has_device=if(match(metric_name, "\.disk\w*|\.adapters|\.dg\w*|\.top\.|\.df_\w*|\.jfs\w*|\.network\.\w*"), "True", "False")
    +| eval metric_dimension_field=case(match(metric_name, "df_\w*|jfsfile|jfsinode"), "dimension_mount", match(metric_name, "\.top\.*"), "dimension_Command", metric_has_device=="True", "dimension_device")
    +| eval metric_volume_unit_choice=if(match(metric_name, "df_storage\.Used"), "True", "False")
    +| eval metric_rate_unit_choice=if(match(metric_name, "\.network\.net"), "True", "False")
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.\w*\.(?&lt;metric_shortname&gt;\w*)"
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.(?&lt;metric_shortname&gt;\w*)$"
    +| eval metric_calculation=if(isnotnull(metric_calculation), metric_calculation, "eval value=value")
    +| eval metric_type_of_calculation=if(isnotnull(metric_type_of_calculation), metric_type_of_calculation, "01 - raw metric")
    +| eval metric_data_field=if(isnotnull(metric_data_field), metric_data_field, "value")
    +| eval metric_by=if(isnotnull(metric_groupby), metric_groupby, metric_by) | eval metric_by=if(isnull(metric_by), "host", metric_by)
    +| eval metric_table_by=if(isnotnull(metric_table_by), metric_table_by, "host")
    +| eval metric_timechart_by=if(isnotnull(metric_timechart_by), metric_timechart_by, "host")
    +| eval metric_primary_statsmode=if(isnotnull(metric_primary_statsmode), metric_primary_statsmode, "avg")
    +| eval metric_charting_chart=if(isnotnull(metric_charting_chart), metric_charting_chart, "line")
    +| eval metric_charting_stackmode=if(isnotnull(metric_charting_stackmode), metric_charting_stackmode, "default")
    +        </query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Base search for the metric catalog populating, avoid extending raw metrics with non relevant calculated metrics
    +    -->
    +
    +    <search id="populate_metric_simple_mode">
    +        <query>| mcatalog values(metric_name) as metrics where `nmon_metrics_index` metric_name="os.unix.nmon.*" ($host$)
    +| rename metrics as metric_name
    +| mvexpand metric_name
    +| rex field="metric_name" "os\.unix\.nmon\.(?&lt;metric_category&gt;\w*)\.(?&lt;nmon_section&gt;\w*)"
    +| sort 0 metric_name</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- definition of metric related tokens -->
    +
    +    <search id="basesearch_metric_definition" base="populate_metric_mono">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition>
    +                <set token="metric_filter">$result.metric_filter$</set>
    +                <set token="metric_calculation">$result.metric_calculation$</set>
    +                <set token="metric_has_device">$result.metric_has_device$</set>
    +                <set token="metric_dimension_field">$result.metric_dimension_field$</set>
    +                <set token="metric_shortname">$result.metric_shortname$</set>
    +                <set token="metric_data_field">$result.metric_data_field$</set>
    +                <set token="metric_primary_statsmode">$result.metric_primary_statsmode$</set>
    +                <set token="metric_by">$result.metric_by$</set>
    +                <set token="metric_table_by">$result.metric_table_by$</set>
    +                <set token="metric_timechart_by">$result.metric_timechart_by$</set>
    +                <set token="metric_volume_unit_choice">$result.metric_volume_unit_choice$</set>
    +                <set token="metric_rate_unit_choice">$result.metric_rate_unit_choice$</set>
    +                <set token="form.chart">$result.metric_charting_chart$</set>
    +                <set token="form.chart.stackingmode">$result.metric_charting_stackmode$</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- analyse if the metric has a device dimension -->
    +
    +    <search id="basesearch_metric_device_mono" depends="$metric_mode_mono$">
    +        <query>| mcatalog values(_dims) as dimensions where `nmon_metrics_index` $metric_filter$ $host-prefilter$ $host$ $osfilter$
    +| mvexpand dimensions
    +| where (dimensions LIKE "dimension_%")</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <!-- Progress event has access to job properties only -->
    +        <progress>
    +            <condition match="'job.resultCount' == 0">
    +                <unset token="show_device"></unset>
    +            </condition>
    +            <condition>
    +                <set token="show_device">True</set>
    +                <set token="dimension">$result.dimensions$</set>
    +                <!-- If not unset here, the form using the metric_dimension_field will be set before the token
    +                is defined, and thus render an error
    +                -->
    +                <unset token="form.dimension_input_filter_mono_tk"></unset>
    +                <unset token="form.dimension_input_mono_tk"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <search id="basesearch_metric_device_multi" depends="$metric_mode_multi$">
    +        <query>| mcatalog values(_dims) as dimensions where `nmon_metrics_index` $metric_name_simple$ $host-prefilter$ $host$ $osfilter$
    +| mvexpand dimensions
    +| where (dimensions LIKE "dimension_%")</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <!-- Progress event has access to job properties only -->
    +        <progress>
    +            <condition match="'job.resultCount' == 0">
    +                <unset token="show_device"></unset>
    +            </condition>
    +            <condition>
    +                <set token="show_device">True</set>
    +                <set token="dimension_multi">$result.dimensions$</set>
    +                <!-- If not unset here, the form using the metric_dimension_field will be set before the token
    +                is defined, and thus render an error
    +                -->
    +                <unset token="form.dimension_input_filter_multi_tk"></unset>
    +                <unset token="form.dimension_input_multi_tk"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- analyse if the metric has a volume unit choice option -->
    +
    +    <search id="basesearch_metric_volume_unit" base="populate_metric_mono">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition match="'result.metric_volume_unit_choice'==&quot;True&quot;">
    +                <set token="show_unit">True</set>
    +            </condition>
    +            <condition match="'result.metric_volume_unit_choice'==&quot;False&quot;">
    +                <unset token="show_unit"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- analyse if the metric has a rate unit choice option -->
    +
    +    <search id="basesearch_metric_rate_unit" base="populate_metric_mono">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition match="'result.metric_rate_unit_choice'==&quot;True&quot;">
    +                <set token="show_unit_rate">True</set>
    +            </condition>
    +            <condition match="'result.metric_rate_unit_choice'==&quot;False&quot;">
    +                <unset token="show_unit_rate"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!--
    +    time range related selection
    +    -->
    +
    +    <row>
    +
    +        <panel>
    +            <title>Select time period</title>
    +
    +            <input type="time" token="timerange" searchWhenChanged="true">
    +                <label>Time Range:</label>
    +                <default>
    +                    <earliest>-24h</earliest>
    +                    <latest>now</latest>
    +                </default>
    +            </input>
    +            <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +                <label>Time Filtering:</label>
    +                <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +                <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +                <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +                <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +                <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +                <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +                <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +                <default>No_Filter</default>
    +            </input>
    +        </panel>
    +
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Select the server(s):</title>
    +
    +            <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +                <label>Filter OS Type:</label>
    +                <default>*</default>
    +                <choice value="*">Any OS</choice>
    +                <choice value="AIX">AIX</choice>
    +                <choice value="Linux">Linux</choice>
    +                <choice value="Solaris">Solaris</choice>
    +                <prefix>OStype="</prefix>
    +                <suffix>"</suffix>
    +            </input>
    +
    +            <input type="multiselect" token="frameID" searchWhenChanged="true">
    +                <label>frameID Selection:</label>
    +                <search base="populate_servers">
    +                    <query>stats count by frameID | fields frameID | dedup frameID | sort 0 frameID</query>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>frameID="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <fieldForLabel>frameID</fieldForLabel>
    +                <fieldForValue>frameID</fieldForValue>
    +                <choice value="*">ANY</choice>
    +            </input>
    +
    +            <input type="text" token="host-prefilter" searchWhenChanged="true">
    +                <label>Optional: Filter hosts populating</label>
    +                <prefix>host="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +
    +            <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +                <label>hosts Selection:</label>
    +                <search base="populate_servers">
    +                    <query>search $frameID$ $host-prefilter$ | stats count by host | dedup host | sort 0 host</query>
    +                </search>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +                <valuePrefix>host="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">ANY</choice>
    +                <change>
    +                    <condition>
    +                        <unset token="form.host_query_input"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +            <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +                <label>Hosts Selection:</label>
    +                <search base="populate_servers">
    +                    <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +                </search>
    +                <selectFirstChoice>true</selectFirstChoice>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +            </input>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row>
    +        <panel rejects="$host$">
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select one or more servers in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Metric selection - which metric do you want to explore ?</title>
    +
    +            <input token="metric_category" type="dropdown" searchWhenChanged="true">
    +                <label>METRIC CATEGORY:</label>
    +                <search base="populate_metric_mono">
    +                    <query>stats count by metric_category | sort 0 metric_category</query>
    +                </search>
    +                <choice value="*">ANY</choice>
    +                <default>*</default>
    +                <fieldForLabel>metric_category</fieldForLabel>
    +                <fieldForValue>metric_category</fieldForValue>
    +            </input>
    +
    +            <input token="nmon_section" type="dropdown" searchWhenChanged="true">
    +                <label>NMON SECTION:</label>
    +                <search base="populate_metric_mono">
    +                    <query>search metric_category="$metric_category$" | stats count by nmon_section | sort 0 nmon_section</query>
    +                </search>
    +                <choice value="*">ANY</choice>
    +                <default>*</default>
    +                <fieldForLabel>nmon_section</fieldForLabel>
    +                <fieldForValue>nmon_section</fieldForValue>
    +            </input>
    +
    +            <input token="metric_type_of_selection" type="dropdown" searchWhenChanged="true">
    +                <label>ASSISTANT METRICS MODE:</label>
    +                <default>mono_metrics</default>
    +                <choice value="mono_metrics">mono-metric with raw and calculated metrics</choice>
    +                <choice value="multi_metrics">multi-metrics with raw metrics</choice>
    +                <change>
    +                    <condition value="mono_metrics">
    +                        <set token="metric_mode_mono">true</set>
    +                        <unset token="metric_mode_multi"></unset>
    +                    </condition>
    +                    <condition value="multi_metrics">
    +                        <set token="metric_mode_multi">true</set>
    +                        <unset token="metric_mode_mono"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <!-- the metric_name dropdown size will be increased using css -->
    +
    +            <input token="metric_type_of_calculation" depends="$metric_mode_mono$" type="dropdown" searchWhenChanged="true">
    +                <label>TYPE OF METRIC CALCULATION:</label>
    +                <search base="populate_metric_mono">
    +                    <query>search metric_category="$metric_category$" | stats count by metric_type_of_calculation | sort 0 metric_type_of_calculation</query>
    +                </search>
    +                <choice value="*">ANY</choice>
    +                <default>*</default>
    +                <fieldForLabel>metric_type_of_calculation</fieldForLabel>
    +                <fieldForValue>metric_type_of_calculation</fieldForValue>
    +            </input>
    +
    +            <input id="metric_name" token="metric_name_simple" depends="$metric_mode_multi$" type="multiselect" searchWhenChanged="true">
    +                <label>PERFORMANCE METRIC:</label>
    +                <search base="populate_metric_simple_mode">
    +                    <query>search metric_category="$metric_category$" nmon_section="$nmon_section$" | table metric_name | sort 0 metric_name</query>
    +                </search>
    +                <valuePrefix>metric_name="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <fieldForLabel>metric_name</fieldForLabel>
    +                <fieldForValue>metric_name</fieldForValue>
    +            </input>
    +
    +            <input id="metric_name2" token="metric_name" depends="$metric_mode_mono$" type="dropdown" searchWhenChanged="true">
    +                <label>PERFORMANCE METRIC:</label>
    +                <search base="populate_metric_mono">
    +                    <query>search metric_category="$metric_category$" nmon_section="$nmon_section$" metric_type_of_calculation="$metric_type_of_calculation$" | table metric_name | sort 0 metric_name</query>
    +                </search>
    +                <fieldForLabel>metric_name</fieldForLabel>
    +                <fieldForValue>metric_name</fieldForValue>
    +            </input>
    +
    +            <html>
    +                <h4>
    +                    Quick help:
    +                    <div class="custom-modal">
    +                        <a data-modal-name="Help_modal_metric_assistant"> assistant mode</a>
    +                    </div>
    +                </h4>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal_metric_assistant" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="info"/>
    +                                    <h1>
    +                                        Quick help: metrics assistant mode
    +                                    </h1>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>The metric assistant mode dropdown provides 2 main options:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>mono-metrics mode with raw and calculated metrics</b></li>
    +                                            <li><b>multi-raw metrics mode:</b></li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <h1>mono-metrics mode:</h1>
    +
    +                                    <b>The mono-metrics mode provides both raw metrics and pre-calculated advanced metrics with a mono selection behaviour:</b>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li>raw metrics are metrics natively available and generated on the servers, example: Wait percentage usage of CPU</li>
    +                                            <li>extended metrics are calculated metrics which are the combination of raw metrics with the appropriated calculation, example: global percentage usage of CPU</li>
    +                                            <li>extended metrics are sourced from the lookup nmon_metric_catalog hosted in the application</li>
    +                                            <li>when a metric has a notion of rate or volume, a unit choice is provided</li>
    +                                            <li>when available, dimensions are automatically selectable and used for group by statements</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <h1>multi-raw metrics mode:</h1>
    +
    +
    +                                    <b>The multi-metrics mode provides both raw metrics with a multi selection behaviour:</b>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li>raw metrics can be selected in a multi-selected behaviour</li>
    +                                            <li>when available, dimensions are automatically selectable and used for group by statements</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row depends="$host$ $metric_mode_mono$" rejects="$metric_name$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select the performance metric to be explored in the metric selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$host$ $metric_mode_multi$" rejects="$metric_name_simple$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select the performance metric to be explored in the metric selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!--
    +
    +    Base searches for KPIs single forms
    +
    +    -->
    +
    +    <search id="KPIs" depends="$metric_mode_mono$">
    +        <query>| mstats $metric_primary_statsmode$(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter$ $host_query$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$timefilter$`
    +| stats avg($metric_data_field$) as avg, median($metric_data_field$) as median, max($metric_data_field$) as max</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="KPIs_device" depends="$metric_mode_mono$ $show_device$">
    +        <query>| mstats $metric_primary_statsmode$(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter$ $host_query$ $dimension_input_filter_mono_tk$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$timefilter$`
    +| eval storage_metric_unit="$storage_metric_unit$", metric_volume_unit_choice="$metric_volume_unit_choice$"
    +| eval rate_metric_unit="$rate_metric_unit$", metric_rate_unit_choice="$metric_rate_unit_choice$"
    +| eval $metric_data_field$=case(metric_volume_unit_choice=="True" AND storage_metric_unit=="MB", $metric_data_field$/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="GB", $metric_data_field$/1024/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="TB", $metric_data_field$/1024/1024/1024, metric_volume_unit_choice=="False", $metric_data_field$)
    +| eval $metric_data_field$=case(metric_rate_unit_choice=="True" AND rate_metric_unit=="KBps", $metric_data_field$, metric_rate_unit_choice=="True" AND rate_metric_unit=="MBps", $metric_data_field$/1000, metric_rate_unit_choice=="True" AND rate_metric_unit=="GBps", $metric_data_field$/1000/1000, metric_rate_unit_choice=="False", $metric_data_field$)
    +| stats avg($metric_data_field$) as avg, median($metric_data_field$) as median, max($metric_data_field$) as max</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +
    +    Dimensions definition
    +
    +    -->
    +
    +    <row depends="$show_device$">
    +        <panel>
    +
    +            <input type="multiselect" token="dimension_input_filter_mono_tk" searchWhenChanged="true" depends="$metric_mode_mono$">
    +                <label>FILTER BY DIMENSION:</label>
    +                <search depends="$metric_mode_mono$">
    +                    <query>| mcatalog values($metric_dimension_field$) as $metric_dimension_field$_values where `nmon_metrics_index` $metric_filter$ $host_query$
    +| rename $metric_dimension_field$_values as $metric_dimension_field$
    +| mvexpand $metric_dimension_field$ | dedup $metric_dimension_field$ | sort 0 $metric_dimension_field$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>$metric_dimension_field$=</valuePrefix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">ANY</choice>
    +                <fieldForLabel>$metric_dimension_field$</fieldForLabel>
    +                <fieldForValue>$metric_dimension_field$</fieldForValue>
    +            </input>
    +
    +            <input token="dimension_input_mono_tk" depends="$show_device$ $metric_mode_mono$" type="dropdown" searchWhenChanged="true">
    +                <label>GROUP BY DIMENSION:</label>
    +                <search base="basesearch_metric_device_mono">
    +                    <query></query>
    +                </search>
    +                <selectFirstChoice>true</selectFirstChoice>
    +                <fieldForLabel>dimensions</fieldForLabel>
    +                <fieldForValue>dimensions</fieldForValue>
    +            </input>
    +
    +            <input type="multiselect" token="dimension_input_filter_multi_tk" searchWhenChanged="true" depends="$metric_mode_multi$">
    +                <label>FILTER BY DIMENSION:</label>
    +                <search depends="$metric_mode_multi$">
    +                    <query>| mcatalog values($dimension_multi$) as $dimension_multi$_values where `nmon_metrics_index` $metric_name_simple$ $host_query$
    +| rename $dimension_multi$_values as $dimension_multi$
    +| mvexpand $dimension_multi$ | dedup $dimension_multi$ | sort 0 $dimension_multi$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>$dimension_multi$=</valuePrefix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">ANY</choice>
    +                <fieldForLabel>$dimension_multi$</fieldForLabel>
    +                <fieldForValue>$dimension_multi$</fieldForValue>
    +            </input>
    +
    +            <input token="dimension_input_multi_tk" depends="$metric_mode_multi$" type="dropdown" searchWhenChanged="true">
    +                <label>GROUP BY DIMENSION:</label>
    +                <search base="basesearch_metric_device_multi">
    +                    <query></query>
    +                </search>
    +                <selectFirstChoice>true</selectFirstChoice>
    +                <fieldForLabel>dimensions</fieldForLabel>
    +                <fieldForValue>dimensions</fieldForValue>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <!--
    +
    +    mono-metric modes
    +
    +    -->
    +
    +    <row depends="$metric_mode_mono$">
    +        <panel>
    +            <title>main KPIs results</title>
    +
    +            <html depends="$metric_name$">
    +                <div style="font-size: 18px; margin: 10px 0; font-weight: bold; text-align: center; color: black;">
    +                    <p>
    +                        <span style="color: #aec6cf; font-size: 200%;">$metric_name$</span>
    +                    </p>
    +                </div>
    +            </html>
    +
    +            <single rejects="$show_device$">
    +                <search base="KPIs">
    +                    <query>fields avg</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Average $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single rejects="$show_device$">
    +                <search base="KPIs">
    +                    <query>fields median</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Median $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single rejects="$show_device$">
    +                <search base="KPIs">
    +                    <query>fields max</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Max $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single depends="$show_device$">
    +                <search base="KPIs_device">
    +                    <query>fields avg</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Average $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single depends="$show_device$">
    +                <search base="KPIs_device">
    +                    <query>fields median</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Median $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <single depends="$show_device$">
    +                <search base="KPIs_device">
    +                    <query>fields max</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +                <option name="field">value</option>
    +                <option name="underLabel">Max $metric_shortname$</option>
    +                <option name="numberPrecision">0.00</option>
    +            </single>
    +
    +            <table rejects="$show_device$">
    +                <search rejects="$show_device$" depends="$metric_mode_mono$">
    +                    <query>| mstats $metric_primary_statsmode$(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter$ $host_query$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$timefilter$`
    +| chart min($metric_data_field$) As min_$metric_data_field$ avg($metric_data_field$) As avg_$metric_data_field$ median($metric_data_field$) As median_$metric_data_field$ max($metric_data_field$) As max_$metric_data_field$ sparkline(avg($metric_data_field$),) As sparkline by $metric_table_by$
    +| foreach *_$metric_data_field$ [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 3) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +
    +            <input type="dropdown" token="storage_unit" depends="$metric_mode_mono$ $show_device$ $show_unit$">
    +                <label>Unit:</label>
    +                <choice value="MB">MB</choice>
    +                <choice value="GB">GB</choice>
    +                <choice value="TB">TB</choice>
    +                <default>GB</default>
    +                <change>
    +                    <condition value="MB">
    +                        <set token="metric_math">value</set>
    +                        <set token="storage_metric_unit">MB</set>
    +                    </condition>
    +                    <condition value="GB">
    +                        <set token="metric_math">value/1024</set>
    +                        <set token="storage_metric_unit">GB</set>
    +                    </condition>
    +                    <condition value="TB">
    +                        <set token="metric_math">value/1024/1204</set>
    +                        <set token="storage_metric_unit">TB</set>
    +                    </condition>
    +                    <condition value="pct">
    +                        <set token="metric_math">value</set>
    +                        <set token="storage_metric_unit">pct</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="rate_unit" depends="$metric_mode_mono$ $show_device$ $show_unit_rate$">
    +                <label>Unit:</label>
    +                <choice value="KBps">KBps</choice>
    +                <choice value="MBps">MBps</choice>
    +                <choice value="GBps">GBps</choice>
    +                <default>KBps</default>
    +                <change>
    +                    <condition value="KBps">
    +                        <set token="metric_math">value</set>
    +                        <set token="rate_metric_unit">KBps</set>
    +                    </condition>
    +                    <condition value="MBps">
    +                        <set token="metric_math">value/1000</set>
    +                        <set token="rate_metric_unit">MBps</set>
    +                    </condition>
    +                    <condition value="GBps">
    +                        <set token="metric_math">value/1000/1000</set>
    +                        <set token="rate_metric_unit">GBps</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <table depends="$metric_mode_mono$ $show_device$">
    +                <search depends="$metric_mode_mono$ $show_device$">
    +                    <query>| mstats $metric_primary_statsmode$(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter$ $host_query$ $dimension_input_filter_mono_tk$ by host metric_name $dimension_input_mono_tk$ span=1m
    +| $metric_calculation$
    +| `$timefilter$`
    +| eval storage_metric_unit="$storage_metric_unit$", metric_volume_unit_choice="$metric_volume_unit_choice$"
    +| eval rate_metric_unit="$rate_metric_unit$", metric_rate_unit_choice="$metric_rate_unit_choice$"
    +| eval $metric_data_field$=case(metric_volume_unit_choice=="True" AND storage_metric_unit=="MB", $metric_data_field$/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="GB", $metric_data_field$/1024/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="TB", $metric_data_field$/1024/1024/1024, metric_volume_unit_choice=="False", $metric_data_field$)
    +| eval $metric_data_field$=case(metric_rate_unit_choice=="True" AND rate_metric_unit=="KBps", $metric_data_field$, metric_rate_unit_choice=="True" AND rate_metric_unit=="MBps", $metric_data_field$/1000, metric_rate_unit_choice=="True" AND rate_metric_unit=="GBps", $metric_data_field$/1000/1000, metric_rate_unit_choice=="False", $metric_data_field$)
    +| stats min($metric_data_field$) As min_$metric_data_field$ avg($metric_data_field$) As avg_$metric_data_field$ median($metric_data_field$) As median_$metric_data_field$ max($metric_data_field$) As max_$metric_data_field$ sparkline(avg($metric_data_field$),) As sparkline by host $dimension_input_mono_tk$
    +| foreach *_$metric_data_field$ [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 3) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <!--
    +
    +    multi-metric modes
    +
    +    -->
    +
    +    <row depends="$metric_mode_multi$">
    +        <panel>
    +
    +            <title>multi-metrics results</title>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true" depends="$show_device$">
    +                <label>Statistic mode:</label>
    +                <default>avg</default>
    +                <choice value="max">Max</choice>
    +                <choice value="avg">Avg</choice>
    +                <choice value="min">Min</choice>
    +                <choice value="median">Median</choice>
    +                <choice value="mode">Mode</choice>
    +                <choice value="range">Range</choice>
    +            </input>
    +
    +            <table depends="$metric_mode_multi$ $show_device$">
    +                <search depends="$metric_mode_multi$ $show_device$">
    +                    <query>| mstats $statsmode$(_value) as value where `nmon_metrics_index` $metric_name_simple$ $host-prefilter$ $host_query$ $dimension_input_filter_multi_tk$ by host metric_name $dimension_input_multi_tk$ span=1m
    +| `$timefilter$`
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.(?&lt;nmon_section&gt;\w*)\.(?&lt;metric_shortname&gt;\w*)"
    +| rex field="metric_name" "os\.unix\.nmon\.(?&lt;nmon_section&gt;\w*)\.(?&lt;metric_shortname&gt;\w*)$"
    +| eval key=nmon_section . ":" . metric_shortname . ":" . $dimension_input_multi_tk$
    +| stats min(value) As min_value avg(value) As avg_value median(value) As median_value max(value) As max_value sparkline(avg(value),) As sparkline by host, key
    +| foreach *_value [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 3) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +
    +            <table depends="$metric_mode_multi$" rejects="$show_device$">
    +                <search depends="$metric_mode_multi$" rejects="$show_device$">
    +                    <query>| mstats $statsmode$(_value) as value where `nmon_metrics_index` $metric_name_simple$ $host-prefilter$ $host_query$ by host metric_name span=1m
    +| `$timefilter$`
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.(?&lt;nmon_section&gt;\w*)\.(?&lt;metric_shortname&gt;\w*)"
    +| rex field="metric_name" "os\.unix\.nmon\.(?&lt;nmon_section&gt;\w*)\.(?&lt;metric_shortname&gt;\w*)$"
    +| eval key=nmon_section . ":" . metric_shortname
    +| chart limit=0 useother=f $statsmode$(value) As value sparkline(avg(value),) As sparkline by host, key
    +| foreach value* [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 3) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <!--
    +
    +    Charting parameters
    +
    +    -->
    +
    +    <row depends="$chartactivate$">
    +        <panel>
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <!--
    +
    +    Charting Servers
    +
    +    -->
    +
    +    <row>
    +        <panel>
    +            <title>Metrics rendering</title>
    +
    +            <!--
    +
    +            charting rendering settings
    +
    +            -->
    +
    +            <input type="dropdown" token="storage_unit" depends="$metric_mode_mono$ $show_device$ $show_unit$">
    +                <label>Unit:</label>
    +                <choice value="MB">MB</choice>
    +                <choice value="GB">GB</choice>
    +                <choice value="TB">TB</choice>
    +                <default>GB</default>
    +                <change>
    +                    <condition value="MB">
    +                        <set token="metric_math">value</set>
    +                        <set token="storage_metric_unit">MB</set>
    +                    </condition>
    +                    <condition value="GB">
    +                        <set token="metric_math">value/1024</set>
    +                        <set token="storage_metric_unit">GB</set>
    +                    </condition>
    +                    <condition value="TB">
    +                        <set token="metric_math">value/1024/1204</set>
    +                        <set token="storage_metric_unit">TB</set>
    +                    </condition>
    +                    <condition value="pct">
    +                        <set token="metric_math">value</set>
    +                        <set token="storage_metric_unit">pct</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="rate_unit" depends="$metric_mode_mono$ $show_device$ $show_unit_rate$">
    +                <label>Unit:</label>
    +                <choice value="KBps">KBps</choice>
    +                <choice value="MBps">MBps</choice>
    +                <choice value="GBps">GBps</choice>
    +                <default>KBps</default>
    +                <change>
    +                    <condition value="KBps">
    +                        <set token="metric_math">value</set>
    +                        <set token="rate_metric_unit">KBps</set>
    +                    </condition>
    +                    <condition value="MBps">
    +                        <set token="metric_math">value/1000</set>
    +                        <set token="rate_metric_unit">MBps</set>
    +                    </condition>
    +                    <condition value="GBps">
    +                        <set token="metric_math">value/1000/1000</set>
    +                        <set token="rate_metric_unit">GBps</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label>Statistic mode:</label>
    +                <default>avg</default>
    +                <choice value="max">Max</choice>
    +                <choice value="avg">Avg</choice>
    +                <choice value="min">Min</choice>
    +                <choice value="median">Median</choice>
    +                <choice value="mode">Mode</choice>
    +                <choice value="range">Range</choice>
    +            </input>
    +
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +
    +            <input type="dropdown" token="chart_settings" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="0">Show charting parameters</choice>
    +                <choice value="1">Hide charting parameters</choice>
    +                <default>1</default>
    +                <change>
    +                    <condition value="0">
    +                        <set token="chart_customize">True</set>
    +                    </condition>
    +                    <condition value="1">
    +                        <unset token="chart_customize"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="chart" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.chart.nullValueMode" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +
    +            <input type="dropdown" token="chart.stackingmode" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.legend.placement" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +
    +            <input type="checkbox" token="chart_min_scale" depends="$chart_customize$" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0</choice>
    +            </input>
    +
    +            <input type="checkbox" token="chart_max_scale" depends="$chart_customize$" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="101">Max scale at 100</choice>
    +            </input>
    +
    +            <!--
    +
    +            mono-metric mode
    +
    +            -->
    +
    +            <chart rejects="$show_device$" depends="$metric_mode_mono$">
    +                <search rejects="$show_device$" depends="$metric_mode_mono$">
    +                    <query>| mstats $metric_primary_statsmode$(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter$ $host_query$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$timefilter$`
    +| timechart $span$ limit=0 useother=f $statsmode$($metric_data_field$) As $metric_shortname$ by $metric_timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$metric_shortname$</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$chart_max_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +
    +            <chart depends="$metric_mode_mono$ $show_device$">
    +                <search depends="$metric_mode_mono$ $show_device$">
    +                    <query>| mstats $metric_primary_statsmode$(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter$ $host_query$ $dimension_input_filter_mono_tk$ by host metric_name $dimension_input_mono_tk$ span=1m
    +| $metric_calculation$
    +| `$timefilter$`
    +| eval storage_metric_unit="$storage_metric_unit$", metric_volume_unit_choice="$metric_volume_unit_choice$"
    +| eval rate_metric_unit="$rate_metric_unit$", metric_rate_unit_choice="$metric_rate_unit_choice$"
    +| eval $metric_data_field$=case(metric_volume_unit_choice=="True" AND storage_metric_unit=="MB", $metric_data_field$/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="GB", $metric_data_field$/1024/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="TB", $metric_data_field$/1024/1024/1024, metric_volume_unit_choice=="False", $metric_data_field$)
    +| eval $metric_data_field$=case(metric_rate_unit_choice=="True" AND rate_metric_unit=="KBps", $metric_data_field$, metric_rate_unit_choice=="True" AND rate_metric_unit=="MBps", $metric_data_field$/1000, metric_rate_unit_choice=="True" AND rate_metric_unit=="GBps", $metric_data_field$/1000/1000, metric_rate_unit_choice=="False", $metric_data_field$)
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.\w*\.(?&lt;metric_shortname&gt;\w*)"
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.(?&lt;metric_shortname&gt;\w*)$"
    +| eval key = host . ":" . metric_shortname . ":" . $dimension_input_mono_tk$
    +| timechart $span$ limit=0 useother=f $statsmode$($metric_data_field$) As $metric_shortname$ by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$metric_shortname$</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +
    +            <!--
    +
    +            multi-metric modes
    +
    +            -->
    +
    +            <chart depends="$metric_mode_multi$" rejects="$show_device$">
    +                <search depends="$metric_mode_multi$" rejects="$show_device$">
    +                    <query>| mstats $statsmode$(_value) as value where `nmon_metrics_index` $metric_name_simple$ $host-prefilter$ $host_query$ by host metric_name span=1m
    +| `$timefilter$`
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.\w*\.(?&lt;metric_shortname&gt;\w*)"
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.(?&lt;metric_shortname&gt;\w*)$"
    +| eval key = host . ":" . metric_shortname
    +| timechart $span$ limit=0 useother=f $statsmode$(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$chart_max_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +
    +            <chart depends="$metric_mode_multi$ $show_device$">
    +                <search depends="$metric_mode_multi$ $show_device$">
    +                    <query>| mstats $statsmode$(_value) as value where `nmon_metrics_index` $metric_name_simple$ $host-prefilter$ $host_query$ $dimension_input_filter_multi_tk$ by host metric_name $dimension_input_multi_tk$ span=1m
    +| `$timefilter$`
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.\w*\.(?&lt;metric_shortname&gt;\w*)"
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.(?&lt;metric_shortname&gt;\w*)$"
    +| eval key = host . ":" . metric_shortname . ":" . $dimension_input_multi_tk$
    +| timechart $span$ limit=0 useother=f $statsmode$(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$chart_max_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +            </chart>
    +
    +        </panel>
    +
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_predict.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_predict.xml
    new file mode 100644
    index 0000000..3d736c9
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Nmon_predict.xml
    @@ -0,0 +1,872 @@
    +<form script="Nmon_predict.js,modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>NMON Predictive interface, Predictive analysis using the forecasting predict command</label>
    +    <description></description>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/predict.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for predictive analysis</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/predict.png" alt="predict"/>
    +                                    <h1>Predictive analysis with the Splunk builtin predict command </h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The predictive analysis interface implements the builtin Splunk command "predict" to forecast time-series data of different main Nmon monitors such as CPU utilization.
    +                                    <br />
    +                                    By default, this interface will use last past 3 months of data to try predicting the next 3 months potential usage of th selected performance metric
    +                                    <br />
    +                                    Get more information of the predict command and its available options, see <a href="http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Predict" target="_blank">http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Predict</a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!--
    +    base search for main dropdown populating for Servers
    +    -->
    +
    +    <search id="populate_servers">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Retrieve the OStype values for each Server and define a token according to its values
    +    This token will be used to filter out added calculated metrics
    +    -->
    +
    +    <search id="ostype_analysis">
    +        <query>| mcatalog values(OStype) as OStype_values where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" ($host$)
    +| rename OStype_values as OStype
    +| mvexpand OStype
    +| eval OStype="is_" . OStype . "==\"True\""
    +| mvcombine OStype | nomv OStype | rex field=OStype mode=sed "s/\" /\" OR /g"</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition>
    +                <set token="OStype">$result.OStype$</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!--
    +    Base search for the metric catalog populating, avoid extending raw metrics with non relevant calculated metrics
    +    -->
    +
    +    <search id="populate_metric">
    +        <query>| mcatalog values(metric_name) as metrics where `nmon_metrics_index` metric_name="os.unix.nmon.*" ($host$)
    +| rename metrics as metric_name
    +| mvexpand metric_name
    +| append [ | inputlookup nmon_metric_catalog where ($OStype$) | fields metric_name ]
    +| rex field="metric_name" "os\.unix\.nmon\.(?&lt;metric_category&gt;\w*)\.(?&lt;nmon_section&gt;\w*)"
    +| sort 0 metric_name
    +| lookup nmon_metric_catalog metric_name
    +| eval metric_filter=if(isnull(metric_filter), ("metric_name=" . metric_name), metric_filter)
    +| eval metric_has_device=if(match(metric_name, "\.disk\w*|\.adapters|\.dg\w*|\.top\.|\.df_\w*|\.jfs\w*|\.network\.\w*"), "True", "False")
    +| eval metric_dimension_field=case(match(metric_name, "df_\w*|jfsfile|jfsinode"), "dimension_mount", match(metric_name, "\.top\.*"), "dimension_Command", metric_has_device=="True", "dimension_device")
    +| eval metric_volume_unit_choice=if(match(metric_name, "df_storage\.Used"), "True", "False")
    +| eval metric_rate_unit_choice=if(match(metric_name, "\.network\.net"), "True", "False")
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.\w*\.(?&lt;metric_shortname&gt;\w*)"
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.(?&lt;metric_shortname&gt;\w*)$"
    +| eval metric_calculation=if(isnotnull(metric_calculation), metric_calculation, "eval value=value")
    +| eval metric_type_of_calculation=if(isnotnull(metric_type_of_calculation), metric_type_of_calculation, "01 - raw metric")
    +| eval metric_data_field=if(isnotnull(metric_data_field), metric_data_field, "value")
    +| eval metric_by=if(isnotnull(metric_groupby), metric_groupby, metric_by) | eval metric_by=if(isnull(metric_by), "host", metric_by)
    +| eval metric_timechart_by=if(isnotnull(metric_timechart_by), metric_timechart_by, "host")
    +| eval metric_primary_statsmode=if(isnotnull(metric_primary_statsmode), metric_primary_statsmode, "avg")
    +| eval metric_charting_chart=if(isnotnull(metric_charting_chart), metric_charting_chart, "line")
    +| eval metric_charting_stackmode=if(isnotnull(metric_charting_stackmode), metric_charting_stackmode, "default")
    +        </query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- definition of metric related tokens -->
    +
    +    <search id="basesearch_metric_definition" base="populate_metric">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition>
    +                <set token="metric_filter">$result.metric_filter$</set>
    +                <set token="metric_calculation">$result.metric_calculation$</set>
    +                <set token="metric_has_device">$result.metric_has_device$</set>
    +                <set token="metric_dimension_field">$result.metric_dimension_field$</set>
    +                <set token="metric_shortname">$result.metric_shortname$</set>
    +                <set token="metric_data_field">$result.metric_data_field$</set>
    +                <set token="metric_primary_statsmode">$result.metric_primary_statsmode$</set>
    +                <set token="metric_by">$result.metric_by$</set>
    +                <set token="metric_timechart_by">$result.metric_timechart_by$</set>
    +                <set token="metric_volume_unit_choice">$result.metric_volume_unit_choice$</set>
    +                <set token="metric_rate_unit_choice">$result.metric_rate_unit_choice$</set>
    +                <set token="form.chart">$result.metric_charting_chart$</set>
    +                <set token="form.chart.stackingmode">$result.metric_charting_stackmode$</set>
    +
    +                <unset token="form.device"></unset>
    +
    +
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- analyse if the metric has a device dimension -->
    +
    +    <search id="basesearch_metric_device" base="populate_metric">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition match="'result.metric_has_device'==&quot;True&quot;">
    +                <set token="show_device">True</set>
    +            </condition>
    +            <condition match="'result.metric_has_device'==&quot;False&quot;">
    +                <unset token="show_device"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- analyse if the metric has a volume unit choice option -->
    +
    +    <search id="basesearch_metric_volume_unit" base="populate_metric">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition match="'result.metric_volume_unit_choice'==&quot;True&quot;">
    +                <set token="show_unit">True</set>
    +            </condition>
    +            <condition match="'result.metric_volume_unit_choice'==&quot;False&quot;">
    +                <unset token="show_unit"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- analyse if the metric has a rate unit choice option -->
    +
    +    <search id="basesearch_metric_rate_unit" base="populate_metric">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition match="'result.metric_rate_unit_choice'==&quot;True&quot;">
    +                <set token="show_unit_rate">True</set>
    +            </condition>
    +            <condition match="'result.metric_rate_unit_choice'==&quot;False&quot;">
    +                <unset token="show_unit_rate"></unset>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- ################################ -->
    +
    +    <row>
    +        <panel id="settings1">
    +            <title>Time range and server selection:</title>
    +
    +            <input type="time" token="timerange" searchWhenChanged="true">
    +                <label>Time Range:</label>
    +                <default>
    +                    <earliest>-30d</earliest>
    +                    <latest>now</latest>
    +                </default>
    +            </input>
    +
    +            <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +                <label>Time Filtering:</label>
    +                <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +                <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +                <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +                <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +                <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +                <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +                <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +                <default>No_Filter</default>
    +            </input>
    +
    +            <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +                <label>Filter OS Type:</label>
    +                <default>*</default>
    +                <prefix>OStype="</prefix>
    +                <suffix>"</suffix>
    +                <choice value="*">Any OS</choice>
    +                <choice value="AIX">AIX</choice>
    +                <choice value="Linux">Linux</choice>
    +                <choice value="Solaris">Solaris</choice>
    +            </input>
    +
    +            <input type="multiselect" token="frameID" searchWhenChanged="true">
    +                <label>frameID Selection:</label>
    +                <search base="populate_servers">
    +                    <query>stats count by frameID | fields frameID | dedup frameID | sort 0 frameID</query>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>frameID="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <fieldForLabel>frameID</fieldForLabel>
    +                <fieldForValue>frameID</fieldForValue>
    +                <choice value="*">Any</choice>
    +            </input>
    +
    +            <input type="text" token="host-prefilter" searchWhenChanged="true">
    +                <label>Optional: Filter hosts populating</label>
    +                <prefix>host="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +
    +            <input id="host" type="dropdown" token="host" searchWhenChanged="true">
    +                <label>hosts Selection:</label>
    +                <search base="populate_servers">
    +                    <query>search $frameID$ $host-prefilter$ | stats count by host | dedup host | sort 0 host</query>
    +                </search>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +                <prefix>host="</prefix>
    +                <suffix>"</suffix>
    +                <!-- Enforce unset of token when host choice is done -->
    +                <change>
    +                    <unset token="form.holdback_choice"></unset>
    +                    <unset token="form.futurespan_choice"></unset>
    +                </change>
    +            </input>
    +
    +            <input id="device" type="multiselect" token="device" searchWhenChanged="true" depends="$show_device$">
    +                <label>Dimensions:</label>
    +                <search>
    +                    <query>| mcatalog values($metric_dimension_field$) as $metric_dimension_field$_values where `nmon_metrics_index` $metric_filter$ $host-prefilter$ $host$ $osfilter$
    +| rename $metric_dimension_field$_values as $metric_dimension_field$
    +| mvexpand $metric_dimension_field$ | dedup $metric_dimension_field$ | sort 0 $metric_dimension_field$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>$metric_dimension_field$=</valuePrefix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">Any</choice>
    +                <fieldForLabel>$metric_dimension_field$</fieldForLabel>
    +                <fieldForValue>$metric_dimension_field$</fieldForValue>
    +            </input>
    +
    +            <!-- help boxes -->
    +
    +            <html depends="$host$" rejects="$OStype$">
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - Please wait while identifying the operating system... - - - - - - - - - - </p>
    +                </div>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row>
    +        <panel rejects="$host$">
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select one or more servers in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$host$ $metric_name$ $show_device$">
    +        <panel>
    +            <html>
    +                <div class="blue_help_user">
    +                    <p>- - - - - - - - - - INFORMATION: the metric $metric_name$ has dimensions that can filtered out in the dimensions selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings2">
    +            <title>Metric selection and parameters:</title>
    +
    +            <input token="metric_category" type="dropdown" searchWhenChanged="true">
    +                <label>METRIC CATEGORY:</label>
    +                <search base="populate_metric">
    +                    <query>stats count by metric_category | sort 0 metric_category</query>
    +                </search>
    +                <choice value="*">Any</choice>
    +                <default>*</default>
    +                <fieldForLabel>metric_category</fieldForLabel>
    +                <fieldForValue>metric_category</fieldForValue>
    +            </input>
    +
    +            <input token="nmon_section" type="dropdown" searchWhenChanged="true">
    +                <label>NMON SECTION:</label>
    +                <search base="populate_metric">
    +                    <query>search metric_category="$metric_category$" | stats count by nmon_section | sort 0 nmon_section</query>
    +                </search>
    +                <choice value="*">Any</choice>
    +                <default>*</default>
    +                <fieldForLabel>nmon_section</fieldForLabel>
    +                <fieldForValue>nmon_section</fieldForValue>
    +            </input>
    +
    +            <input token="metric_type_of_calculation" type="dropdown" searchWhenChanged="true">
    +                <label>TYPE OF METRIC CALCULATION:</label>
    +                <search base="populate_metric">
    +                    <query>search metric_category="$metric_category$" | stats count by metric_type_of_calculation | sort 0 metric_type_of_calculation</query>
    +                </search>
    +                <choice value="*">Any</choice>
    +                <default>*</default>
    +                <fieldForLabel>metric_type_of_calculation</fieldForLabel>
    +                <fieldForValue>metric_type_of_calculation</fieldForValue>
    +            </input>
    +
    +            <!-- the metric_name dropdown size will be increased using css -->
    +
    +            <input id="metric_name" token="metric_name" type="dropdown" searchWhenChanged="true">
    +                <label>PERFORMANCE METRIC:</label>
    +                <search base="populate_metric">
    +                    <query>search metric_category="$metric_category$" nmon_section="$nmon_section$" metric_type_of_calculation="$metric_type_of_calculation$" | table metric_name | sort 0 metric_name</query>
    +                </search>
    +                <fieldForLabel>metric_name</fieldForLabel>
    +                <fieldForValue>metric_name</fieldForValue>
    +
    +                <change>
    +                    <condition value="os.unix.nmon.storage.df_storage.Used">
    +                        <set token="storage_metric">true</set>
    +                        <unset token="show_processing_saturation_predicted"></unset>
    +                        <unset token="show_null_saturation_predicted"></unset>
    +                        <unset token="show_saturation_predicted"></unset>
    +                    </condition>
    +                    <condition>
    +                        <unset token="storage_metric"></unset>
    +                    </condition>
    +                </change>
    +
    +            </input>
    +
    +            <!-- help boxes -->
    +
    +            <html depends="$is_detected$" rejects="$metric_name$">
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please select a performance monitor in the selector above - - - - - - - - - - </p>
    +                </div>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_device$ $show_unit$">
    +        <panel>
    +
    +            <input type="dropdown" token="storage_unit">
    +                <label>Unit:</label>
    +                <choice value="MB">MB</choice>
    +                <choice value="GB">GB</choice>
    +                <choice value="TB">TB</choice>
    +                <default>GB</default>
    +                <change>
    +                    <condition value="MB">
    +                        <set token="metric_math">value</set>
    +                        <set token="storage_metric_unit">MB</set>
    +                    </condition>
    +                    <condition value="GB">
    +                        <set token="metric_math">value/1024</set>
    +                        <set token="storage_metric_unit">GB</set>
    +                    </condition>
    +                    <condition value="TB">
    +                        <set token="metric_math">value/1024/1204</set>
    +                        <set token="storage_metric_unit">TB</set>
    +                    </condition>
    +                    <condition value="pct">
    +                        <set token="metric_math">value</set>
    +                        <set token="storage_metric_unit">pct</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_device$ $show_unit_rate$">
    +        <panel>
    +
    +            <input type="dropdown" token="rate_unit">
    +                <label>Unit:</label>
    +                <choice value="KBps">KBps</choice>
    +                <choice value="MBps">MBps</choice>
    +                <choice value="GBps">GBps</choice>
    +                <default>KBps</default>
    +                <change>
    +                    <condition value="KBps">
    +                        <set token="metric_math">value</set>
    +                        <set token="rate_metric_unit">KBps</set>
    +                    </condition>
    +                    <condition value="MBps">
    +                        <set token="metric_math">value/1000</set>
    +                        <set token="rate_metric_unit">MBps</set>
    +                    </condition>
    +                    <condition value="GBps">
    +                        <set token="metric_math">value/1000/1000</set>
    +                        <set token="rate_metric_unit">GBps</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row depends="$host$" rejects="$metric_name$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select the performance metric to be explore in the metric selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="predict1">
    +            <title>Prediction parameters:</title>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label>Stats mode:</label>
    +                <default>perc95</default>
    +                <choice value="max">Max</choice>
    +                <choice value="avg">Avg</choice>
    +                <choice value="min">Min</choice>
    +                <choice value="perc95">Percentile 95</choice>
    +                <choice value="median">Median</choice>
    +                <choice value="mode">Mode</choice>
    +                <choice value="range">Range</choice>
    +            </input>
    +
    +            <input type="dropdown" token="algo">
    +                <label>Prediction algorithm:</label>
    +                <choice value="LL">LL (Local Level)</choice>
    +                <choice value="LLP">LLP (Seasonal local level)</choice>
    +                <choice value="LLP5">LLP5 (Combines LLT and LLP models)</choice>
    +                <choice value="LLT">LLT (Local level trend)</choice>
    +                <default>LLP5</default>
    +            </input>
    +
    +            <input type="text" token="interval">
    +                <prefix>span="</prefix>
    +                <suffix>"</suffix>
    +                <default>1d</default>
    +                <label>Time span value (ex: 1d for 1 day)</label>
    +            </input>
    +
    +            <input type="dropdown" token="holdback_choice">
    +                <label>Holdback:</label>
    +                <choice value="auto">auto (none)</choice>
    +                <choice value="custom">custom</choice>
    +                <default>auto</default>
    +                <change>
    +                    <condition value="auto">
    +                        <unset token="show_holdback"></unset>
    +                        <set token="holdback">holdback=0</set>
    +                    </condition>
    +                    <condition value="custom">
    +                        <set token="show_holdback">true</set>
    +                        <unset token="holdback"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +            <input type="text" token="holdback" depends="$show_holdback$">
    +                <prefix>holdback="</prefix>
    +                <suffix>"</suffix>
    +                <label>Nb of last points to ignore</label>
    +            </input>
    +
    +            <input type="dropdown" token="futurespan_choice">
    +                <label>Futurespan:</label>
    +                <choice value="auto">auto (90)</choice>
    +                <choice value="custom">custom</choice>
    +                <default>auto</default>
    +                <change>
    +                    <condition value="auto">
    +                        <unset token="show_futurespan"></unset>
    +                        <set token="futurespan">future_timespan=90</set>
    +                    </condition>
    +                    <condition value="custom">
    +                        <set token="show_futurespan">true</set>
    +                        <unset token="futurespan"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +            <input type="text" token="futurespan" depends="$show_futurespan$">
    +                <prefix>future_timespan="</prefix>
    +                <suffix>"</suffix>
    +                <label>Nb of time points in future</label>
    +            </input>
    +
    +            <input type="dropdown" token="upperlower_choice">
    +                <label>Upper/Lower:</label>
    +                <choice value="auto">auto (upper75=high lower75=low)</choice>
    +                <choice value="custom">custom</choice>
    +                <default>auto</default>
    +                <change>
    +                    <condition value="auto">
    +                        <unset token="show_upperlower"></unset>
    +                        <set token="upperlower">upper75=high lower75=low</set>
    +                    </condition>
    +                    <condition value="custom">
    +                        <set token="show_upperlower">true</set>
    +                        <unset token="upperlower"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +            <input type="text" token="upperlower" depends="$show_upperlower$">
    +                <default></default>
    +                <label>Enter upper and lower settings:</label>
    +            </input>
    +
    +            <html depends="$show_holdback$" rejects="$holdback$">
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please enter the number of data points from the end that are not to be used, and press Enter - - - - - - - - - - </p>
    +                </div>
    +            </html>
    +
    +            <html depends="$show_futurespan$" rejects="$futurespan$">
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please enter the number of data points to be predicted, depending on the interval value this will influence the future prediction (for example with 1d as the interval, 90 means predicting for next 90 days), and press Enter - - - - - - - - - - </p>
    +                </div>
    +            </html>
    +
    +            <html depends="$show_upperlower$" rejects="$upperlower$">
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please enter lower and upper settings under the form  "upperXX=high lowerXX=high" and press Enter - - - - - - - - - - </p>
    +                </div>
    +            </html>
    +
    +        </panel>
    +    </row>
    +
    +    <search id="predicted_storage_saturation" depends="$storage_metric$">
    +        <query>| mstats $metric_primary_statsmode$(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.storage.df_storage.Used OR metric_name=os.unix.nmon.storage.df_storage.Available $host-prefilter$ $host$ $osfilter$ $device$ by metric_name, host span=1m
    +| eval storage_used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), storage=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value)
    +| stats latest(storage_used) as storage_used, latest(storage) as storage by _time, host
    +| `$timefilter$`
    +| eval storage_metric_unit="$storage_metric_unit$", metric_volume_unit_choice="$metric_volume_unit_choice$"
    +| eval storage_used=case(storage_metric_unit=="MB", storage_used, storage_metric_unit=="GB", storage_used/1024, storage_metric_unit=="TB", storage_used/1024/1024)
    +| eval storage=case(storage_metric_unit=="MB", storage, storage_metric_unit=="GB", storage/1024, storage_metric_unit=="TB", storage/1024/1024)
    +| timechart $interval$ $statsmode$(storage_used) AS storage_used latest(storage) as storage
    +| predict storage_used As predict algorithm=$algo$ $holdback$ $futurespan$ $upperlower$
    +| filldown storage
    +| eval now=now()
    +| where (predict&gt;=storage AND _time>now) | sort 0 _time | head 1
    +| stats count, min(_time) as predicted_saturation, latest(predict) as predict, latest(storage) as storage
    +| eval predicted_saturation=strftime(predicted_saturation, "%d %b %Y"), storage_needs=(predict-storage), storage_margin_90pct=(storage*0.1), storage_margin_80pct=(storage*0.2)
    +| eval storage_needs_90pct=round((storage_needs+storage_margin_90pct), 2), storage_needs_80pct=round((storage_needs+storage_margin_80pct), 2)
    +| eval prediction_saturation_found=if(predict>storage, "true", "false")</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +                <set token="storage_prediction_is_processing">true</set>
    +                <unset token="storage_prediction_will_be_satured"></unset>
    +                <unset token="storage_prediction_has_no_prediction"></unset>
    +        </progress>
    +        <finalized>
    +            <condition match="'result.prediction_saturation_found'==&quot;false&quot;">
    +                <set token="storage_prediction_has_no_prediction">true</set>
    +                <unset token="storage_prediction_is_processing"></unset>
    +                <unset token="storage_prediction_will_be_satured"></unset>
    +            </condition>
    +            <condition match="'result.prediction_saturation_found'==&quot;true&quot;">
    +                <set token="storage_prediction_will_be_satured">true</set>
    +                <unset token="storage_prediction_is_processing"></unset>
    +                <unset token="storage_prediction_has_no_prediction"></unset>
    +                <set token="predicted_saturation">$result.predicted_saturation$</set>
    +                <set token="storage_needs_80pct">$result.storage_needs_80pct$</set>
    +                <set token="storage_needs_90pct">$result.storage_needs_90pct$</set>
    +            </condition>
    +        </finalized>
    +
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <title>Metrics rendering</title>
    +
    +            <html depends="$metric_name$">
    +                <div style="font-size: 18px; margin: 10px 0; font-weight: bold; text-align: center; color: black;">
    +                    <p>
    +                        <span style="color: #aec6cf; font-size: 200%;">$metric_name$</span>
    +                    </p>
    +                </div>
    +            </html>
    +
    +            <html depends="$storage_metric$ $storage_prediction_is_processing$">
    +                <div style="font-size: 18px; margin: 10px 0; font-weight: bold; text-align: center; color: black;">
    +                    <h2>Please wait while processing the file-system saturation predictive analysis...</h2>
    +                </div>
    +            </html>
    +
    +            <html depends="$storage_metric$ $storage_prediction_has_no_prediction$" rejects="$storage_prediction_is_processing$">
    +                <div style="font-size: 18px; margin: 10px 0; font-weight: bold; text-align: center; color: black;">
    +                    <p>PREDICTIVE ANALYSIS: no saturation prediction could be detected for file-system: <span style="color: #aec6cf; font-size: 200%;">$device$</span></p>
    +                </div>
    +            </html>
    +
    +            <html depends="$storage_metric$ $storage_prediction_will_be_satured$" rejects="$storage_prediction_is_processing$">
    +                <div style="font-size: 18px; margin: 10px 0; font-weight: bold; text-align: center; color: black;">
    +                    <p>PREDICTIVE ANALYSIS: starting date of
    +                        <span style="color: #ff6961; font-size: 200%;">$predicted_saturation$</span>
    +                        the file-system:
    +                        <span style="color: #aec6cf; font-size: 200%;">$device$</span>
    +                        might be saturated
    +                        <br /><br />
    +                        <lu>
    +                            <li>Approx. <span style="color: #aec6cf; font-size: 150%;">$storage_needs_90pct$ $storage_metric_unit$</span> of supplementary storage would be needed to keep the storage at 90% of used space</li>
    +                            <br />
    +                            <li>Approx. <span style="color: #aec6cf; font-size: 150%;">$storage_needs_80pct$ $storage_metric_unit$</span> of supplementary storage would be needed to keep the storage at 80% of used space</li>
    +                        </lu>
    +                    </p>
    +                </div>
    +            </html>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label>Statistic mode:</label>
    +                <default>avg</default>
    +                <choice value="max">Max</choice>
    +                <choice value="avg">Avg</choice>
    +                <choice value="min">Min</choice>
    +                <choice value="median">Median</choice>
    +                <choice value="mode">Mode</choice>
    +                <choice value="range">Range</choice>
    +            </input>
    +
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +
    +            <input type="dropdown" token="chart_settings" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="0">Show charting parameters</choice>
    +                <choice value="1">Hide charting parameters</choice>
    +                <default>1</default>
    +                <change>
    +                    <condition value="0">
    +                        <set token="chart_customize">True</set>
    +                    </condition>
    +                    <condition value="1">
    +                        <unset token="chart_customize"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="chart" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.chart.nullValueMode" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.legend.placement" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +
    +            <input type="checkbox" token="chart_min_scale" depends="$chart_customize$" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0</choice>
    +            </input>
    +
    +            <input type="checkbox" token="chart_max_scale" depends="$chart_customize$" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="101">Max scale at 100</choice>
    +            </input>
    +
    +            <chart rejects="$show_device$">
    +                <title></title>
    +                <search rejects="$show_device$">
    +                    <query>| mstats $metric_primary_statsmode$(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter$ $host$ $osfilter$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$timefilter$`
    +| timechart $interval$ $statsmode$($metric_data_field$) As $metric_shortname$
    +| predict $metric_shortname$ As predict algorithm=$algo$ $holdback$ $futurespan$ $upperlower$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$metric_shortname$</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$chart_max_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.fieldColors">{"predict": 0x9d0eaf}</option>
    +            </chart>
    +
    +            <chart depends="$show_device$" rejects="$storage_metric$">
    +                <title></title>
    +                <search depends="$show_device$" rejects="$storage_metric$">
    +                    <query>| mstats $metric_primary_statsmode$(_value) as value where `nmon_metrics_index` $metric_filter$ $host-prefilter$ $host$ $osfilter$ $device$ by $metric_by$ span=1m
    +| $metric_calculation$
    +| `$timefilter$`
    +| eval storage_metric_unit="$storage_metric_unit$", metric_volume_unit_choice="$metric_volume_unit_choice$"
    +| eval rate_metric_unit="$rate_metric_unit$", metric_rate_unit_choice="$metric_rate_unit_choice$"
    +| eval $metric_data_field$=case(metric_volume_unit_choice=="True" AND storage_metric_unit=="MB", $metric_data_field$, metric_volume_unit_choice=="True" AND storage_metric_unit=="GB", $metric_data_field$/1024, metric_volume_unit_choice=="True" AND storage_metric_unit=="TB", $metric_data_field$/1024/1024, metric_volume_unit_choice=="False", $metric_data_field$)
    +| eval $metric_data_field$=case(metric_rate_unit_choice=="True" AND rate_metric_unit=="KBps", $metric_data_field$, metric_rate_unit_choice=="True" AND rate_metric_unit=="MBps", $metric_data_field$/1000, metric_rate_unit_choice=="True" AND rate_metric_unit=="GBps", $metric_data_field$/1000/1000, metric_rate_unit_choice=="False", $metric_data_field$)
    +| timechart $interval$ $statsmode$($metric_data_field$) AS $metric_shortname$
    +| predict $metric_shortname$ As predict algorithm=$algo$ $holdback$ $futurespan$ $upperlower$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$metric_shortname$</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$chart_max_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.fieldColors">{"predict": 0x9d0eaf}</option>
    +            </chart>
    +
    +            <chart depends="$show_device$ $storage_metric$">
    +                <title></title>
    +                <search depends="$show_device$ $storage_metric$">
    +                    <query>| mstats $metric_primary_statsmode$(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.storage.df_storage.Used OR metric_name=os.unix.nmon.storage.df_storage.Available $host-prefilter$ $host$ $osfilter$ $device$ by metric_name, host span=1m
    +| eval storage_used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), storage=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value)
    +| stats latest(storage_used) as storage_used, latest(storage) as storage by _time, host
    +| `$timefilter$`
    +| eval storage_metric_unit="$storage_metric_unit$", metric_volume_unit_choice="$metric_volume_unit_choice$"
    +| eval storage_used=case(storage_metric_unit=="MB", storage_used, storage_metric_unit=="GB", storage_used/1024, storage_metric_unit=="TB", storage_used/1024/1024)
    +| eval storage=case(storage_metric_unit=="MB", storage, storage_metric_unit=="GB", storage/1024, storage_metric_unit=="TB", storage/1024/1024)
    +| timechart $interval$ $statsmode$(storage_used) AS storage_used latest(storage) as storage
    +| predict storage_used As predict algorithm=$algo$ $holdback$ $futurespan$ $upperlower$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$metric_shortname$</option>
    +                <option name="charting.axisY.minimumNumber">$chart_min_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$chart_max_scale$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.fieldColors">{"storage": 0xFF0000, "predict": 0x9d0eaf}</option>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Overview.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Overview.xml
    new file mode 100644
    index 0000000..70e0f04
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Overview.xml
    @@ -0,0 +1,687 @@
    +<form script="autodiscover.js,panel_resize.js,active_button.js" stylesheet="Home.css,ui_simple.css,hover.css,hide_timeindicator.css" hideEdit="false" isVisible="true" version="1.1" theme="dark">
    +    <label>Overview</label>
    +    <description>Enterprise edition - version build 2.0.0</description>
    +    <fieldset submitButton="false"></fieldset>
    +
    +    <!-- Take the tour ! -->
    +    <row >
    +        <panel>
    +            <html>
    +                <div class = "splunk-view" data-require = "app/metricator-for-nmon/components/scc_takethetour/scc_takethetour"
    +					data-options = '{
    +						"user_slides":"scc-takethetour-slides",
    +						"width":"60",
    +						"title":"Metricator for Nmon: Take the tour !",
    +						"close_btn_label":"Close",
    +						"no_more_label":"Do not show this again",
    +						"cookie_name_suffix":"metricator-for-nmon-v1.0",
    +						"hide_container":false,
    +						"show_credits":true
    +					}'>
    +                </div>
    +                <ul id="scc-takethetour-slides" class="hide">
    +
    +                    <li>
    +
    +                        <h1>WELCOME IN THE METRICATOR APPLICATION FOR SPLUNK ENTERPRISE</h1>
    +
    +                        <h2>The super fast, rich and definitive monitoring and performance application suite for Unix and Linux.</h2>
    +
    +                        <div style="text-align: left;">
    +                            <a href="http://www.octamis.com" target="_blank">
    +                                <img src="../../static/app/metricator-for-nmon/Octamis/Octamis_Logo_v3_no_bg.png" alt="Octamis"/>
    +                            </a>
    +                        </div>
    +
    +                        <b>Contact us at: </b>
    +                        <a target="_top" href="mailto:sales@octamis.com?subject=Nmon%20Performance%20for%20Splunk">sales@octamis.com</a>
    +                        <br />
    +                        <b>Share your testimonial: </b>
    +                        <a target="_top" href="mailto:nmon@octamis.com?subject=Nmon%20Performance%20for%20Splunk">nmon@octamis.com</a>
    +                        <br />
    +                        <b>We are looking for talent, <a target="_blank" href="https://www.octamis.com/careers/">find a job opportunity at Octamis</a>
    +                        </b>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/main.png" alt="main.png"/>
    +                        </div>
    +
    +                    </li>
    +
    +                    <li>
    +
    +                        <h1>Metrics on steroids with Splunk 7 metric store</h1>
    +
    +                        <h2>Native metrics implementation</h2>
    +
    +                        <p>
    +                            The Metricator application fully implements Splunk time series metrics ingested within the metric store indexes.
    +                            <br />
    +                            We make good usage of it, and bring you one of the most performer user experience on Splunk Enterprise.
    +                            <br />
    +                            Access easily any metric available, use high performance mstats and mcatalog commands and retrieve results in seconds.
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/metrics_showcase.png" alt="metrics_showcase.png"/>
    +                        </div>
    +
    +                    </li>
    +
    +                    <li>
    +
    +                        <h1>The most advanced and dynamic dashboards and user interfaces for the highest quality of user experience</h1>
    +
    +                        <h2>We've got you covered. Find replies to your questions and get back in control with your systems</h2>
    +
    +                        <p>
    +                            Use our advanced dashboards to easily perform the best performance analysis.
    +                            <br />
    +                            More than simple dashboards, we provide rich, powerful and well designed user interfaces.
    +                            <br />
    +                            Dashboards and user interfaces are easily accessible from the application home page, we have a dashboard for all use cases.
    +                        </p>
    +
    +                        <div style="text-align: center; max-width: 1250x;">
    +                            <img src="../../static/app/metricator-for-nmon/take_the_tour/advanced_dashboards.png" alt="advanced_dashboards.png"/>
    +                        </div>
    +
    +                    </li>
    +
    +                    <li>
    +                        <h1>Certified Technical Addon, low footprint and highly configurable</h1>
    +
    +                        <h2>Our Technical Addons are heavily tested, qualified and certified against numbers of architectures and Operating Systems, this includes:</h2>
    +
    +                        <p>
    +                            - IBM AIX 7.1 / 7.2<br />
    +                            - PowerLinux Linux (RHEL/Ubuntu/SLES...)<br />
    +                            - X86 (RHEL/Ubuntu/SLES...)<br />
    +                            - Oracle Solaris 11 on X86 and SPARC<br />
    +            </p>
    +
    +                        The Technical Addons are as well compatible with ARM platforms, IBM zLinux!
    +
    +            <div style="text-align: center; max-width: 1250x;">
    +                <img src="../../static/app/metricator-for-nmon/take_the_tour/OS_logos.png" alt="OS_logos.png"/>
    +            </div>
    +
    +        </li>
    +
    +        <li>
    +            <h1>Builtin costs of ownership analytic and metrics volume optimizations</h1>
    +
    +            <h2>Get the insight vision of every cost related to your deployment</h2>
    +
    +            <p>
    +                            - The DCO dashboard provides you builtin analytic features against application costs, daily average volume and metric metadatas, and even more<br />
    +                            - The Add-on dashboard provides automatic reporting your servers deployment, which versions are deployed on which servers<br />
    +                            - Don't pay for a zero ! The Technical Addons have been slighty optimized to remove any useless data from the metrics generation, you only pay for what is useful<br />
    +    </p>
    +
    +    <div style="text-align: center; max-width: 1250x;">
    +        <img src="../../static/app/metricator-for-nmon/take_the_tour/tco.png" alt="tco.png"/>
    +    </div>
    +
    +</li>
    +
    +<li>
    +    <h1>Threshold management, frameID mapping and thresholds templating</h1>
    +
    +    <h2>The alerting features implements a multi-layer thresholds system based on:</h2>
    +
    +    <p>
    +                            - The frameID that allows logically grouping server assets<br />
    +                            - FrameID mapping is achieved either at the raw level with different options (static definition, pre-ation scripts) or at search time with the KVstore management interface for frameID mapping<br />
    +                            - Alerting thresholds values can be defined using macros default, on a per frameID template basis or on a per server basis using the KVstore collection management interfaces<br />
    +</p>
    +
    +<div style="text-align: center; max-width: 1250x;">
    +<img src="../../static/app/metricator-for-nmon/take_the_tour/thresholds.png" alt="thresholds.png"/>
    +</div>
    +
    +</li>
    +
    +</ul>
    +</html>
    +</panel>
    +</row>
    +
    +<row>
    +<panel>
    +<single>
    +<search>
    +<query>| `alerting_cpu_usage` | stats count</query>
    +<earliest>-60m</earliest>
    +<latest>now</latest>
    +<refresh>150s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="refresh.display">none</option>
    +<option name="underLabel">cpu percentage saturation</option>
    +<option name="unit">cpu active alerts</option>
    +<option name="colorBy">value</option>
    +<option name="colorMode">block</option>
    +<option name="numberPrecision">0</option>
    +<option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +<option name="rangeValues">[0]</option>
    +<option name="showSparkline">1</option>
    +<option name="showTrendIndicator">1</option>
    +<option name="trellis.enabled">0</option>
    +<option name="trellis.scales.shared">1</option>
    +<option name="trellis.size">medium</option>
    +<option name="trendColorInterpretation">standard</option>
    +<option name="trendDisplayMode">absolute</option>
    +<option name="unitPosition">after</option>
    +<option name="useColors">1</option>
    +<option name="useThousandSeparators">1</option>
    +<drilldown target="search">
    +<link>search?q=| `alerting_cpu_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +</drilldown>
    +</single>
    +<single>
    +<search>
    +<query>| `alerting_realmemory_usage` | stats count</query>
    +<earliest>-60m</earliest>
    +<latest>now</latest>
    +<refresh>160s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="refresh.display">none</option>
    +<option name="underLabel">physical memory percentage saturation</option>
    +<option name="unit">physical memory active alerts</option>
    +<option name="colorBy">value</option>
    +<option name="colorMode">block</option>
    +<option name="numberPrecision">0</option>
    +<option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +<option name="rangeValues">[0]</option>
    +<option name="showSparkline">1</option>
    +<option name="showTrendIndicator">1</option>
    +<option name="trellis.enabled">0</option>
    +<option name="trellis.scales.shared">1</option>
    +<option name="trellis.size">medium</option>
    +<option name="trendColorInterpretation">standard</option>
    +<option name="trendDisplayMode">absolute</option>
    +<option name="unitPosition">after</option>
    +<option name="useColors">1</option>
    +<option name="useThousandSeparators">1</option>
    +<drilldown target="search">
    +<link>search?q=| `alerting_realmemory_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +</drilldown>
    +</single>
    +<single>
    +<search>
    +<query>| `alerting_virtualmemory_usage` | stats count</query>
    +<earliest>-60m</earliest>
    +<latest>now</latest>
    +<refresh>170s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="refresh.display">none</option>
    +<option name="underLabel">virtual memory saturation</option>
    +<option name="unit">virtual memory active alerts</option>
    +<option name="colorBy">value</option>
    +<option name="colorMode">block</option>
    +<option name="numberPrecision">0</option>
    +<option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +<option name="rangeValues">[0]</option>
    +<option name="showSparkline">1</option>
    +<option name="showTrendIndicator">1</option>
    +<option name="trellis.enabled">0</option>
    +<option name="trellis.scales.shared">1</option>
    +<option name="trellis.size">medium</option>
    +<option name="trendColorInterpretation">standard</option>
    +<option name="trendDisplayMode">absolute</option>
    +<option name="unitPosition">after</option>
    +<option name="useColors">1</option>
    +<option name="useThousandSeparators">1</option>
    +<drilldown target="search">
    +<link>search?q=| `alerting_virtualmemory_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +</drilldown>
    +</single>
    +<single>
    +<search>
    +<query>| `alerting_filesystem_usage` | stats count</query>
    +<earliest>-60m</earliest>
    +<latest>now</latest>
    +<refresh>180s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="refresh.display">none</option>
    +<option name="underLabel">file-systems under usage saturation</option>
    +<option name="unit">file systems active alerts</option>
    +<option name="colorBy">value</option>
    +<option name="colorMode">block</option>
    +<option name="numberPrecision">0</option>
    +<option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +<option name="rangeValues">[0]</option>
    +<option name="showSparkline">1</option>
    +<option name="showTrendIndicator">1</option>
    +<option name="trellis.enabled">0</option>
    +<option name="trellis.scales.shared">1</option>
    +<option name="trellis.size">medium</option>
    +<option name="trendColorInterpretation">standard</option>
    +<option name="trendDisplayMode">absolute</option>
    +<option name="unitPosition">after</option>
    +<option name="useColors">1</option>
    +<option name="useThousandSeparators">1</option>
    +<drilldown target="search">
    +<link>search?q=| `alerting_filesystem_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +</drilldown>
    +</single>
    +</panel>
    +</row>
    +<row>
    +<panel>
    +<single>
    +<search ref="Hosts with data within last 7 days">
    +<refresh>600s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="colorBy">value</option>
    +<option name="colorMode">none</option>
    +<option name="drilldown">all</option>
    +<option name="numberPrecision">0</option>
    +<option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +<option name="rangeValues">[18]</option>
    +<option name="refresh.display">progressbar</option>
    +<option name="showSparkline">1</option>
    +<option name="showTrendIndicator">1</option>
    +<option name="trellis.enabled">0</option>
    +<option name="trellis.scales.shared">1</option>
    +<option name="trellis.size">medium</option>
    +<option name="trendColorInterpretation">standard</option>
    +<option name="trendDisplayMode">absolute</option>
    +<option name="underLabel">IN THE LAST 7 DAYS</option>
    +<option name="unit">Host(s) with activity</option>
    +<option name="unitPosition">after</option>
    +<option name="useColors">1</option>
    +<option name="useThousandSeparators">1</option>
    +<drilldown target="search">
    +<link>search?q=%7C%20tstats%20dc(host)%20as%20dcount%20where%20%60nmon_index%60%20sourcetype%3Dnmon_data%20by%20_time%20span%3D1d&amp;earliest=-7d%40h&amp;latest=now&amp;display.general.type=visualizations&amp;display.page.search.tab=visualizations&amp;display.visualizations.type=singlevalue</link>
    +</drilldown>
    +</single>
    +<single>
    +<search>
    +<query>| mstats latest(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.logical_cpus by host span=1m
    +| stats max(value) as value by _time, host
    +| stats sum(value) as value by _time
    +| timechart max(value) as core_compute</query>
    +<earliest>-4h@m</earliest>
    +<latest>-1m@m</latest>
    +<refresh>30s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="colorBy">value</option>
    +<option name="colorMode">none</option>
    +<option name="drilldown">all</option>
    +<option name="numberPrecision">0</option>
    +<option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +<option name="rangeValues">[18]</option>
    +<option name="refresh.display">progressbar</option>
    +<option name="showSparkline">1</option>
    +<option name="showTrendIndicator">1</option>
    +<option name="trellis.enabled">0</option>
    +<option name="trellis.scales.shared">1</option>
    +<option name="trellis.size">medium</option>
    +<option name="trendColorInterpretation">standard</option>
    +<option name="trendDisplayMode">absolute</option>
    +<option name="underLabel">CPU COMPUTE AVAILABLE</option>
    +<option name="unit">processing cores</option>
    +<option name="unitPosition">after</option>
    +<option name="useColors">1</option>
    +<option name="useThousandSeparators">1</option>
    +<drilldown target="search">
    +<link>search?q=| mstats latest(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.logical_cpus by host span=1m
    +| stats max(value) as value by _time, host
    +| stats sum(value) as value by _time
    +| timechart max(value) as core_compute&amp;earliest=-4h@m&amp;latest=-1m@m&amp;display.general.type=visualizations&amp;display.page.search.tab=visualizations&amp;display.visualizations.type=singlevalue</link>
    +</drilldown>
    +</single>
    +<single>
    +<search>
    +<query>| mstats latest(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.memtotal" OR metric_name="os.unix.nmon.memory.mem.Real_total_MB" by host metric_name span=1m
    +| `extract_metrics`
    +| eval {metric}=value
    +| eval mem_total=case(isnum(memtotal), round(memtotal, 0), isnum(Real_total_MB), round(Real_total_MB, 0))
    +| stats max(mem_total) as mem_total by _time, host
    +| stats sum(mem_total) as mem_total by _time
    +| timechart max(mem_total) as mem_total
    +| eval mem_total=round(mem_total/1024, 2)</query>
    +<earliest>-4h@m</earliest>
    +<latest>-1m@m</latest>
    +<refresh>30s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="colorBy">value</option>
    +<option name="colorMode">none</option>
    +<option name="drilldown">all</option>
    +<option name="numberPrecision">0</option>
    +<option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +<option name="rangeValues">[18]</option>
    +<option name="refresh.display">progressbar</option>
    +<option name="showSparkline">1</option>
    +<option name="showTrendIndicator">1</option>
    +<option name="trellis.enabled">0</option>
    +<option name="trellis.scales.shared">1</option>
    +<option name="trellis.size">medium</option>
    +<option name="trendColorInterpretation">standard</option>
    +<option name="trendDisplayMode">absolute</option>
    +<option name="underLabel">TOTAL AMOUNT (GB) OF PHYSICAL MEMORY AVAILABLE</option>
    +<option name="unit">GB</option>
    +<option name="unitPosition">after</option>
    +<option name="useColors">1</option>
    +<option name="useThousandSeparators">1</option>
    +<drilldown target="search">
    +<link>search?q=| mstats latest(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.mem.memtotal" OR metric_name="os.unix.nmon.memory.mem.Real_total_MB" by host metric_name span=1m
    +| `extract_metrics`
    +| eval {metric}=value
    +| eval mem_total=case(isnum(memtotal), round(memtotal, 0), isnum(Real_total_MB), round(Real_total_MB, 0))
    +| stats max(mem_total) as mem_total by _time, host
    +| stats sum(mem_total) as mem_total by _time
    +| timechart max(mem_total) as mem_total
    +| eval mem_total=round(mem_total/1024, 2)&amp;earliest=-4h@m&amp;latest=-1m@m&amp;display.general.type=visualizations&amp;display.page.search.tab=visualizations&amp;display.visualizations.type=singlevalue</link>
    +</drilldown>
    +</single>
    +<single>
    +<search>
    +<query>| tstats latest("Uptime.uptime") AS uptime_seconds from datamodel=metricator-nmon-config.Uptime where (nodename = Uptime) (Uptime.uptime = "*") by host
    +| where uptime_seconds&lt;=3600
    +| stats count</query>
    +<earliest>-4h@m</earliest>
    +<latest>now</latest>
    +<refresh>30s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="colorBy">value</option>
    +<option name="colorMode">none</option>
    +<option name="drilldown">all</option>
    +<option name="numberPrecision">0</option>
    +<option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +<option name="rangeValues">[18]</option>
    +<option name="refresh.display">progressbar</option>
    +<option name="showSparkline">1</option>
    +<option name="showTrendIndicator">1</option>
    +<option name="trellis.enabled">0</option>
    +<option name="trellis.scales.shared">1</option>
    +<option name="trellis.size">medium</option>
    +<option name="trendColorInterpretation">standard</option>
    +<option name="trendDisplayMode">absolute</option>
    +<option name="underLabel">IN THE LAST 60 MINUTES</option>
    +<option name="unit">Host(s) with recent reboot</option>
    +<option name="unitPosition">after</option>
    +<option name="useColors">1</option>
    +<option name="useThousandSeparators">1</option>
    +<drilldown>
    +<link target="_blank">/app/metricator-for-nmon/report?s=UPTIME - servers recent reboot (last 60 minutes)</link>
    +</drilldown>
    +</single>
    +<single>
    +<search>
    +<query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.pct_CPU by dimension_Command span=1m
    +| timechart `nmon_span` dc(dimension_Command) as dcount
    +| where dcount&gt;0</query>
    +<earliest>-4h@m</earliest>
    +<latest>-1m@m</latest>
    +<refresh>30s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="colorBy">value</option>
    +<option name="colorMode">none</option>
    +<option name="drilldown">all</option>
    +<option name="numberPrecision">0</option>
    +<option name="rangeColors">["0x3F6FDE","0x3F6FDE"]</option>
    +<option name="rangeValues">[18]</option>
    +<option name="refresh.display">progressbar</option>
    +<option name="showSparkline">1</option>
    +<option name="showTrendIndicator">1</option>
    +<option name="trellis.enabled">0</option>
    +<option name="trellis.scales.shared">1</option>
    +<option name="trellis.size">medium</option>
    +<option name="trendColorInterpretation">standard</option>
    +<option name="trendDisplayMode">absolute</option>
    +<option name="underLabel">CAPTURED IN THE LAST 60 MINUTES</option>
    +<option name="unit">Commands invocation</option>
    +<option name="unitPosition">after</option>
    +<option name="useColors">1</option>
    +<option name="useThousandSeparators">1</option>
    +<drilldown>
    +<link target="_blank">/app/metricator-for-nmon/Dashboard_Bubblechart_top_processes?form.host=*&amp;form.timerange.earliest=-60m@m&amp;form.timerange.latest=now</link>
    +</drilldown>
    +</single>
    +</panel>
    +</row>
    +<row>
    +<panel>
    +<title>TOP deployment pressure overview - active drilldown</title>
    +
    +<input type="link" token="linkinput">
    +<label></label>
    +<choice value="chart1">Last hour TOP 30 servers under CPU pressure</choice>
    +<choice value="chart2">Last hour TOP 30 servers under CPU I/O Wait pressure</choice>
    +<choice value="chart3">Last hour TOP 30 servers under IOPS pressure</choice>
    +<choice value="chart4">Last hour TOP 30 servers under Memory pressure</choice>
    +<choice value="chart5">Last hour TOP 30 processes CPU consumers</choice>
    +<choice value="chart6">Last hour TOP 30 processes Memory consumers</choice>
    +<default>chart1</default>
    +<change>
    +<condition value="chart1">
    +<set token="chart1">true</set>
    +<unset token="chart2"></unset>
    +<unset token="chart3"></unset>
    +<unset token="chart4"></unset>
    +<unset token="chart5"></unset>
    +<unset token="chart6"></unset>
    +</condition>
    +<condition value="chart2">
    +<set token="chart2">true</set>
    +<unset token="chart1"></unset>
    +<unset token="chart3"></unset>
    +<unset token="chart4"></unset>
    +<unset token="chart5"></unset>
    +<unset token="chart6"></unset>
    +</condition>
    +<condition value="chart3">
    +<set token="chart3">true</set>
    +<unset token="chart1"></unset>
    +<unset token="chart2"></unset>
    +<unset token="chart4"></unset>
    +<unset token="chart5"></unset>
    +<unset token="chart6"></unset>
    +</condition>
    +<condition value="chart4">
    +<set token="chart4">true</set>
    +<unset token="chart1"></unset>
    +<unset token="chart2"></unset>
    +<unset token="chart3"></unset>
    +<unset token="chart5"></unset>
    +<unset token="chart6"></unset>
    +</condition>
    +<condition value="chart5">
    +<set token="chart5">true</set>
    +<unset token="chart1"></unset>
    +<unset token="chart2"></unset>
    +<unset token="chart3"></unset>
    +<unset token="chart4"></unset>
    +<unset token="chart6"></unset>
    +</condition>
    +<condition value="chart6">
    +<set token="chart6">true</set>
    +<unset token="chart1"></unset>
    +<unset token="chart2"></unset>
    +<unset token="chart3"></unset>
    +<unset token="chart4"></unset>
    +<unset token="chart5"></unset>
    +</condition>
    +</change>
    +</input>
    +<chart depends="$chart1$">
    +<search depends="$chart1$">
    +<query>| mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters`
    +[ | mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` earliest=-60m latest=now by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| stats avg(cpu_load_percent) as cpu_load_percent by host
    +| sort 30 - cpu_load_percent
    +| table host ] by metric_name, OStype, host span=1m
    +| `def_all_os_cpu_load_percent`
    +| timechart `nmon_span` limit=0 useother=f avg(cpu_load_percent) as cpu_load_percent by host</query>
    +<earliest>-4h@m</earliest>
    +<latest>now</latest>
    +<refresh>30s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="charting.axisTitleX.visibility">collapsed</option>
    +<option name="charting.axisTitleY.text">% cpu</option>
    +<option name="charting.chart">line</option>
    +<option name="charting.drilldown">all</option>
    +<option name="charting.legend.placement">bottom</option>
    +<option name="height">450</option>
    +<option name="refresh.display">none</option>
    +<drilldown>
    +<link target="_blank">/app/metricator-for-nmon/Nmon_Summary?form.host=$click.name2$&amp;form.timerange.earliest=-4h&amp;form.timerange.latest=now</link>
    +</drilldown>
    +</chart>
    +<chart depends="$chart2$">
    +<search depends="$chart2$">
    +<query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT
    +[ | mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT earliest=-60m latest=now by metric_name, OStype, host span=1m
    +| stats avg(value) as cpu_iowait_percent by host
    +| sort 30 - cpu_iowait_percent
    +| table host ] by metric_name, OStype, host span=1m
    +| timechart `nmon_span` limit=0 useother=f avg(value) as cpu_iowait_percent by host
    +| fillnull value=0</query>
    +<earliest>-4h@m</earliest>
    +<latest>now</latest>
    +<refresh>30s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="charting.axisTitleX.visibility">collapsed</option>
    +<option name="charting.axisTitleY.text">% cpu I/O wait</option>
    +<option name="charting.chart">line</option>
    +<option name="charting.drilldown">all</option>
    +<option name="charting.legend.placement">bottom</option>
    +<option name="height">450</option>
    +<option name="refresh.display">none</option>
    +<drilldown>
    +<link target="_blank">/app/metricator-for-nmon/Nmon_Summary?form.host=$click.name2$&amp;form.timerange.earliest=-4h&amp;form.timerange.latest=now</link>
    +</drilldown>
    +</chart>
    +<chart depends="$chart3$">
    +<search depends="$chart3$">
    +<query>| mstats sum(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgxfer" OR metric_name="os.unix.nmon.storage.diskxfer")
    +[ | mstats sum(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgxfer" OR metric_name="os.unix.nmon.storage.diskxfer") earliest=-60m latest=now by host, metric_name span=1m
    +| eval dgxfer_iops=case(match(metric_name, "dgxfer"), value), diskxfer_iops=case(match(metric_name, "diskxfer"), value)
    +| stats values(dgxfer_iops) as dgxfer_iops, values(diskxfer_iops) as diskxfer_iops by _time, host
    +| eval iops=if(isnum('dgxfer_iops'), 'dgxfer_iops', 'diskxfer_iops')
    +| stats avg(iops) as avg_iops by host
    +| sort 30 - avg_iops
    +|  table host ] by host, metric_name span=1m
    +| eval dgxfer_iops=case(match(metric_name, "dgxfer"), value), diskxfer_iops=case(match(metric_name, "diskxfer"), value)
    +| stats values(dgxfer_iops) as dgxfer_iops, values(diskxfer_iops) as diskxfer_iops by _time, host
    +| eval iops=if(isnum('dgxfer_iops'), 'dgxfer_iops', 'diskxfer_iops')
    +| timechart useother=f limit=0 `nmon_span` avg(iops) as avg_iops by host</query>
    +<earliest>-4h@m</earliest>
    +<latest>now</latest>
    +<refresh>30s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="charting.axisTitleX.visibility">collapsed</option>
    +<option name="charting.axisTitleY.text">disk IOPS</option>
    +<option name="charting.chart">line</option>
    +<option name="charting.drilldown">all</option>
    +<option name="charting.legend.placement">bottom</option>
    +<option name="height">450</option>
    +<option name="refresh.display">none</option>
    +<drilldown>
    +<link target="_blank">/app/metricator-for-nmon/Nmon_Summary?form.host=$click.name2$&amp;form.timerange.earliest=-4h&amp;form.timerange.latest=now</link>
    +</drilldown>
    +</chart>
    +<chart depends="$chart4$">
    +<search depends="$chart4$">
    +<query>| mstats avg(_value) as value where `nmon_metrics_index` `def_phys_memory_all_os_metric_filters`
    +[ | mstats avg(_value) as value where `nmon_metrics_index` `def_phys_memory_all_os_metric_filters` earliest=-60m latest=now by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| stats avg(mem_used_effective_PCT) AS mem_used_percent by host
    +| sort 30 - mem_used_percent
    +| table host ] by OStype, host, metric_name span=1m
    +| `def_memory_load_percent`
    +| timechart `nmon_span` limit=0 useother=f avg(mem_used_effective_PCT) AS mem_used_PCT by host</query>
    +<earliest>-4h@m</earliest>
    +<latest>now</latest>
    +<refresh>30s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="charting.axisTitleX.visibility">collapsed</option>
    +<option name="charting.axisTitleY.text">% memory</option>
    +<option name="charting.chart">line</option>
    +<option name="charting.drilldown">all</option>
    +<option name="charting.legend.placement">bottom</option>
    +<option name="height">450</option>
    +<option name="refresh.display">none</option>
    +<drilldown>
    +<link target="_blank">/app/metricator-for-nmon/Nmon_Summary?form.host=$click.name2$&amp;form.timerange.earliest=-4h&amp;form.timerange.latest=now</link>
    +</drilldown>
    +</chart>
    +<chart depends="$chart5$">
    +<search depends="$chart5$">
    +<query>| mstats sum(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU"
    +[ | mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" earliest=-60m latest=now by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| eval usage_per_core=(value/100)
    +|  stats avg(usage_per_core) as usage_per_core by dimension_Command
    +| sort 30 - usage_per_core
    +| table dimension_Command ] by host, metric_name, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| eval usage_per_core=(value/100)
    +| timechart `nmon_span` limit=0 useother=f avg(usage_per_core) as usage_per_core by dimension_Command</query>
    +<earliest>-4h@m</earliest>
    +<latest>now</latest>
    +<refresh>30s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="charting.axisTitleX.visibility">collapsed</option>
    +<option name="charting.axisTitleY.text">cpu cores</option>
    +<option name="charting.chart">column</option>
    +<option name="charting.chart.stackMode">stacked</option>
    +<option name="charting.drilldown">all</option>
    +<option name="charting.legend.placement">bottom</option>
    +<option name="height">450</option>
    +<option name="refresh.display">none</option>
    +<drilldown>
    +<link target="_blank">/app/metricator-for-nmon/Overview_drilldown_TOP?form.host=*&amp;form.Command=$click.name2$&amp;form.top_linkinput=top_chart1&amp;form.timerange.earliest=-4h&amp;form.timerange.latest=now</link>
    +</drilldown>
    +</chart>
    +<chart depends="$chart6$">
    +<search depends="$chart6$">
    +<query>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData OR metric_name=os.unix.nmon.processes.top.ResSize
    +[ | mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData OR metric_name=os.unix.nmon.processes.top.ResSize earliest=-60m latest=now by metric_name, OStype, host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, metric_name, OStype, host, dimension_Command
    +| `def_all_os_top_memory`
    +| stats sum(mem_usage_mb) As mem_usage_mb by _time, host, dimension_Command
    +| stats avg(mem_usage_mb) as mem_usage_mb by dimension_Command
    +| sort 30 - mem_usage_mb
    +| table dimension_Command ] by metric_name, OStype, host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, metric_name, OStype, host, dimension_Command
    +| `def_all_os_top_memory`
    +| stats sum(mem_usage_mb) As mem_usage_mb by _time, host, dimension_Command
    +| timechart useother=f limit=0 `nmon_span` sum(mem_usage_mb) as mem_usage_mb by dimension_Command</query>
    +<earliest>-4h@m</earliest>
    +<latest>now</latest>
    +<refresh>30s</refresh>
    +<refreshType>delay</refreshType>
    +</search>
    +<option name="charting.axisTitleX.visibility">collapsed</option>
    +<option name="charting.axisTitleY.text">memory MB</option>
    +<option name="charting.chart">column</option>
    +<option name="charting.chart.stackMode">stacked</option>
    +<option name="charting.drilldown">all</option>
    +<option name="charting.legend.placement">bottom</option>
    +<option name="height">450</option>
    +<option name="refresh.display">none</option>
    +<drilldown>
    +<link target="_blank">/app/metricator-for-nmon/Overview_drilldown_TOP?form.host=*&amp;form.Command=$click.name2$&amp;form.top_linkinput=top_chart2&amp;form.timerange.earliest=-4h&amp;form.timerange.latest=now</link>
    +</drilldown>
    +</chart>
    +</panel>
    +</row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/Overview_drilldown_TOP.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/Overview_drilldown_TOP.xml
    new file mode 100644
    index 0000000..5ef3b28
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/Overview_drilldown_TOP.xml
    @@ -0,0 +1,596 @@
    +<form script="togglepanel.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="false" version="1.1" theme="dark">
    +    <label>Drilldown TOP processes consumers</label>
    +    <description></description>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.*" by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="populate_command">
    +        <query>| mcatalog values(dimension_Command) as commands where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.*" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host
    +| rename commands as dimension_Command
    +| stats count by dimension_Command</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <row>
    +        <panel id="selection_togglepanel_true">
    +
    +        <title>Selection filtering</title>
    +
    +            <input type="time" token="timerange" searchWhenChanged="true">
    +                <label>Time Range:</label>
    +                <default>
    +                    <earliest>-24h</earliest>
    +                    <latest>now</latest>
    +                </default>
    +                <change>
    +                    <unset token="form.refresh"></unset>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +                <label>Time Filtering:</label>
    +                <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +                <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +                <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +                <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +                <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +                <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +                <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +                <default>No_Filter</default>
    +            </input>
    +
    +            <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +                <label>Frame IDs:</label>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate">
    +                    <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +                </search>
    +                <valuePrefix>frameID=</valuePrefix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">Any</choice>
    +                <initialValue>*</initialValue>
    +                <fieldForLabel>frameID</fieldForLabel>
    +                <fieldForValue>frameID</fieldForValue>
    +            </input>
    +
    +            <input type="text" token="host-prefilter" searchWhenChanged="true">
    +                <label>Optional: Filter hosts populating</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +                <label>Hosts Selection:</label>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate">
    +                    <query>search $frameID$ host=$host-prefilter$
    +        | stats count by host | dedup host | sort 0 host</query>
    +                </search>
    +                <valuePrefix>host="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">ALL Hosts</choice>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +                <change>
    +                    <condition>
    +                        <unset token="form.host_query_input"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +            <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +                <label>Hosts Selection:</label>
    +                <search base="populate">
    +                    <query>search $host$ $frameID$
    +        | stats values(host) as host
    +        | format | fields - host | rename search as host</query>
    +                </search>
    +                <selectFirstChoice>true</selectFirstChoice>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +            </input>
    +
    +            <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +                <label>Select a stats mode:</label>
    +                <default>max</default>
    +                <choice value="max">Max</choice>
    +                <choice value="avg">Avg</choice>
    +                <choice value="min">Min</choice>
    +                <choice value="median">Median</choice>
    +                <choice value="mode">Mode</choice>
    +                <choice value="range">Range</choice>
    +            </input>
    +
    +            <input type="dropdown" token="refresh" searchWhenChanged="true">
    +                <label>Auto-refresh:</label>
    +                <fieldForLabel>label</fieldForLabel>
    +                <fieldForValue>value</fieldForValue>
    +                <selectFirstChoice>true</selectFirstChoice>
    +                <search>
    +                    <query>| `def_auto_refresh`</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +            </input>
    +
    +            <input type="text" token="Command" searchWhenChanged="true">
    +                <label>Optional: Filter by Command</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="text" token="PID" searchWhenChanged="true">
    +                <label>Optional: Filter by PIDs</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="multiselect" token="Command_multiselect" searchWhenChanged="true">
    +                <label>Command(s):</label>
    +                <search base="populate_command">
    +                    <query>sort 0 dimension_Command</query>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>dimension_Command="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">Any</choice>
    +                <fieldForLabel>dimension_Command</fieldForLabel>
    +                <fieldForValue>dimension_Command</fieldForValue>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>TOP 100 servers by CPU process consumers: bubblechart</title>
    +            <html>
    +                <div id="bubbleSearch1"
    +                     class="splunk-manager"
    +                     data-require="splunkjs/mvc/searchmanager"
    +                     data-options='{
    +                    "search": {
    +								"type": "token_safe",
    +                    		"value": "| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.pct_CPU host=$$host-prefilter$$ $$host_query$$ (dimension_Command=$$Command$$) (dimension_PID=$$PID$$) by host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| stats avg(usage_per_core) as usage_per_core by host | eval usage_per_core=round(usage_per_core, 3) | sort 100 - usage_per_core"
    +						  },
    +          			  "earliest_time": {
    +            				"type": "token_safe",
    +            				"value": "$$timerange.earliest$$"
    +          				},
    +          				"latest_time": {
    +            				"type": "token_safe",
    +            				"value": "$$timerange.latest$$"
    +          				},
    +                    "auto_cancel": 90,
    +                    "preview": true
    +                 }'>
    +                </div>
    +                <div id="bubbleChart1"
    +                     class="splunk-view"
    +                     data-require="app/metricator-for-nmon/components/bubblechart/bubblechart"
    +                     data-options='{
    +                    "managerid": "bubbleSearch1",
    +                    "nameField": "host",
    +                    "categoryField": "host",
    +                    "valueField": "usage_per_core",
    +                    "height": 600
    +                 }'>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <title>TOP 100 servers by Memory process consumer: bubblechart</title>
    +            <html>
    +                <div id="bubbleSearch2"
    +                     class="splunk-manager"
    +                     data-require="splunkjs/mvc/searchmanager"
    +                     data-options='{
    +                    "search": {
    +								"type": "token_safe",
    +                    		"value": "| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData OR metric_name=os.unix.nmon.processes.top.ResSize host=$$host-prefilter$$ $$host_query$$ (dimension_Command=$$Command$$) (dimension_PID=$$PID$$) by OStype, metric_name, host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, metric_name, OStype, host, dimension_Command
    +| `def_all_os_top_memory`
    +| stats avg(mem_usage_mb) as mem_usage_mb by host | eval mem_usage_mb=round(mem_usage_mb, 3) | sort 100 - mem_usage_mb"
    +						  },
    +          			  "earliest_time": {
    +            				"type": "token_safe",
    +            				"value": "$$timerange.earliest$$"
    +          				},
    +          				"latest_time": {
    +            				"type": "token_safe",
    +            				"value": "$$timerange.latest$$"
    +          				},
    +                    "auto_cancel": 90,
    +                    "preview": true
    +                 }'>
    +                </div>
    +                <div id="bubbleChart2"
    +                     class="splunk-view"
    +                     data-require="app/metricator-for-nmon/components/bubblechart/bubblechart"
    +                     data-options='{
    +                    "managerid": "bubbleSearch2",
    +                    "nameField": "host",
    +                    "categoryField": "host",
    +                    "valueField": "mem_usage_mb",
    +                    "height": 600
    +                 }'>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Active drilldown: click on a command invocation to get detailed PIDs statistics of that command (may be truncated with large number of PIDs)</title>
    +
    +            <input type="text" token="limit" searchWhenChanged="true">
    +                <label>Max series:</label>
    +                <default>50</default>
    +                <prefix>limit=</prefix>
    +            </input>
    +
    +            <input type="dropdown" token="timechart_by" searchWhenChanged="true">
    +                <label>group by statement:</label>
    +                <default>key</default>
    +                <choice value="key">host:Command</choice>
    +                <choice value="dimension_Command">Command</choice>
    +            </input>
    +
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +
    +            <input type="dropdown" token="chart_settings" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="0">Show charting parameters</choice>
    +                <choice value="1">Hide charting parameters</choice>
    +                <default>1</default>
    +                <change>
    +                    <condition value="0">
    +                        <set token="chart_customize">True</set>
    +                    </condition>
    +                    <condition value="1">
    +                        <unset token="chart_customize"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="chart" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>column</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.chart.nullValueMode" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +
    +            <input type="dropdown" token="chart.stackingmode" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>stacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.legend.placement" depends="$chart_customize$" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +
    +            <input type="link" token="top_linkinput">
    +                <label></label>
    +                <choice value="top_chart1">CPU Usage per logical core</choice>
    +                <choice value="top_chart2">Memory Usage per command invocation</choice>
    +                <choice value="uarg">UARG: commands arguments</choice>
    +                <default>top_chart1</default>
    +                <change>
    +                    <condition value="top_chart1">
    +                        <set token="top_chart1">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart2">
    +                        <set token="top_chart2">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="uarg">
    +                        <set token="uarg">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$top_chart1$">
    +                <title></title>
    +                <search depends="$top_chart1$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(usage_per_core) as "CPU Usage per core" by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Logical Core</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as pct_CPU where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| eval usage_per_core=(pct_CPU/100)
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(usage_per_core) as "CPU Usage per core" by key | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart2$">
    +                <title></title>
    +                <search depends="$top_chart2$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData OR metric_name=os.unix.nmon.processes.top.ResSize host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by OStype, metric_name, host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, metric_name, OStype, host, dimension_Command
    +| `def_all_os_top_memory`
    +| stats sum(mem_usage_mb) As mem_usage_mb by _time, host, dimension_Command
    +| eval key=host . ":" . dimension_Command
    +| timechart useother=f limit=0 `nmon_span` sum(mem_usage_mb) as mem_usage_mb by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData OR metric_name=os.unix.nmon.processes.top.ResSize host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by OStype, metric_name, host, dimension_Command, dimension_PID span=1m
    +| `def_all_os_top_memory`
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(mem_usage_mb) as mem_usage_mb by key | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <input type="text" token="Command" depends="$uarg$" searchWhenChanged="true">
    +                <label>Optional: Filter by Command</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="text" token="PID" depends="$uarg$" searchWhenChanged="true">
    +                <label>Optional: Filter by PIDs</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="multiselect" token="Command_multiselect" depends="$uarg$" searchWhenChanged="true">
    +                <label>Command(s):</label>
    +                <search base="populate_command">
    +                    <query>sort 0 dimension_Command</query>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>dimension_Command="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">Any</choice>
    +                <fieldForLabel>dimension_Command</fieldForLabel>
    +                <fieldForValue>dimension_Command</fieldForValue>
    +            </input>
    +
    +            <event depends="$uarg$">
    +                <title></title>
    +                <search depends="$uarg$">
    +                    <query>eventtype=nmon:events type=UARG host=$host-prefilter$ $host_query$ ($frameID$) (dimension_Command=$Command$) (dimension_PID=$PID$)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="count">10</option>
    +                <option name="list.drilldown">full</option>
    +                <option name="list.wrap">1</option>
    +                <option name="maxLines">0</option>
    +                <option name="raw.drilldown">full</option>
    +                <option name="rowNumbers">0</option>
    +                <option name="table.drilldown">1</option>
    +                <option name="table.wrap">1</option>
    +                <option name="type">list</option>
    +                <option name="refresh.display">none</option>
    +                <fields>[]</fields>
    +            </event>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <search id="uarg_definition">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition>
    +                <set token="metric_filter">$result.metric_filter$</set>
    +                <set token="metric_calculation">$result.metric_calculation$</set>
    +                <set token="metric_has_device">$result.metric_has_device$</set>
    +                <set token="metric_dimension_field">$result.metric_dimension_field$</set>
    +                <set token="metric_shortname">$result.metric_shortname$</set>
    +                <set token="metric_data_field">$result.metric_data_field$</set>
    +                <set token="metric_primary_statsmode">$result.metric_primary_statsmode$</set>
    +                <set token="metric_by">$result.metric_by$</set>
    +                <set token="metric_timechart_by">$result.metric_timechart_by$</set>
    +                <set token="metric_volume_unit_choice">$result.metric_volume_unit_choice$</set>
    +                <set token="metric_rate_unit_choice">$result.metric_rate_unit_choice$</set>
    +                <set token="form.chart">$result.metric_charting_chart$</set>
    +                <set token="form.chart.stackingmode">$result.metric_charting_stackmode$</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Table stats: CPU Usage per logical core</title>
    +                <search>
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| stats $statsmode$(usage_per_core) as "CPU Usage per Logical Cores", sparkline($statsmode$(usage_per_core)) As sparkline by host, dimension_Command
    +| rename dimension_Command as Command
    +| eval "CPU Usage per Logical Cores"=round('CPU Usage per Logical Cores', 3)
    +| sort - "CPU Usage per Logical Cores"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="CPU Usage per Logical Cores">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table stats: Memory Usage per command invocation</title>
    +                <search>
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.processes.top.ResSet OR metric_name=os.unix.nmon.processes.top.ResText OR metric_name=os.unix.nmon.processes.top.ResData OR metric_name=os.unix.nmon.processes.top.ResSize host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by OStype, metric_name, host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, metric_name, OStype, host, dimension_Command
    +| `def_all_os_top_memory`
    +| stats $statsmode$(mem_usage_mb) as "Used Memory per Command (MB)", sparkline($statsmode$(mem_usage_mb)) as sparkline by host, dimension_Command
    +| rename dimension_Command as Command
    +| eval "Used Memory per Command (MB)"=round('Used Memory per Command (MB)', 3)
    +| sort - "Used Memory per Command (MB)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="Used Memory per Command (MB)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/README b/deployment-apps/metricator-for-nmon/default/data/ui/views/README
    new file mode 100644
    index 0000000..6cf74f0
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/README
    @@ -0,0 +1 @@
    +Add all the views that your app needs in this directory
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Alert_Center.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Alert_Center.xml
    new file mode 100644
    index 0000000..0649aee
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Alert_Center.xml
    @@ -0,0 +1,1340 @@
    +<form stylesheet="safecenter.css" script="autodiscover.js" isVisible="true" version="1.1" theme="dark">
    +    <label>ALERT CENTER</label>
    +    <description>NMON Triggered Alerts Analysis</description>
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div style="text-align: center;">
    +                    <img src="../../static/app/metricator-for-nmon/icons/color_theme/warning.png" alt="warning"/>
    +                    <h1>ALERT CENTER: Triggered Alerts</h1>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +          <title>Active Alerts</title>
    +
    +            <single>
    +                <search>
    +                    <query>| `alerting_cpu_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>150s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">cpu percentage saturation</option>
    +                <option name="unit">cpu active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_cpu_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_realmemory_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>160s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">physical memory percentage saturation</option>
    +                <option name="unit">physical memory active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_realmemory_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_virtualmemory_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>170s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">virtual memory saturation</option>
    +                <option name="unit">virtual memory active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_virtualmemory_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            <single>
    +                <search>
    +                    <query>| `alerting_filesystem_usage` | stats count</query>
    +                    <earliest>-60m</earliest>
    +                    <latest>now</latest>
    +                    <refresh>180s</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="refresh.display">none</option>
    +                <option name="underLabel">file-systems under usage saturation</option>
    +                <option name="unit">file systems active alerts</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">block</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x006d9c","0xf2aa0a"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trellis.enabled">0</option>
    +                <option name="trellis.scales.shared">1</option>
    +                <option name="trellis.size">medium</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="unitPosition">after</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_filesystem_usage`&amp;earliest=-60m%40m&amp;latest=now</link>
    +                </drilldown>
    +            </single>
    +            
    +        </panel>
    +    </row>
    +
    +    <!-- Main search for form populating -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" by host
    +| `mapping_frameID`
    +| stats count by frameID, host</query>
    +        <earliest>-24h</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <title>Search:</title>
    +
    +            <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +                <label>Frame IDs:</label>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate">
    +                    <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +                </search>
    +                <valuePrefix>frameID=</valuePrefix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">Any</choice>
    +                <initialValue>*</initialValue>
    +                <fieldForLabel>frameID</fieldForLabel>
    +                <fieldForValue>frameID</fieldForValue>
    +            </input>
    +
    +            <input type="text" token="host-prefilter" searchWhenChanged="true">
    +                <label>Optional: Filter hosts populating</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +                <label>Hosts Selection:</label>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate">
    +                    <query>search $frameID$ host=$host-prefilter$ | stats count by host | dedup host | sort 0 host</query>
    +                </search>
    +                <valuePrefix>host="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">ALL Hosts</choice>
    +                <initialValue>*</initialValue>
    +                <fieldForLabel>host</fieldForLabel>
    +                <fieldForValue>host</fieldForValue>
    +            </input>
    +
    +            <input type="dropdown" token="refresh" searchWhenChanged="true">
    +                <label>Auto-refresh:</label>
    +                <choice value="30s">30 sec</choice>
    +                <choice value="60s">1 min</choice>
    +                <choice value="300s">5 min</choice>
    +                <choice value="0">none</choice>
    +                <default>0</default>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- Search Base for post processing -->
    +
    +    <search id="CPU_Global" ref="ALERT CENTER - CPU issues">
    +      <refresh>$refresh$</refresh>
    +      <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="RealMem_Global" ref="ALERT CENTER - Real Memory issues">
    +      <refresh>$refresh$</refresh>
    +      <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="VirtualMem_Global" ref="ALERT CENTER - Virtual Memory issues">
    +      <refresh>$refresh$</refresh>
    +      <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="FileSystem_Global" ref="ALERT CENTER - FS issues">
    +      <refresh>$refresh$</refresh>
    +      <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- -->
    +
    +    <search id="tagcloud_cpu">
    +        <query>| `alerting_cpu_usage` | search $frameID$ host=$host-prefilter$ $host$ | top limit=10 host</query>
    +        <earliest>-24h</earliest>
    +        <latest>now</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <html id="cpu">
    +                <div class="safecenter">
    +                    <h1>CPU</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="panela2_setWidth_48">
    +            <title>Summary:</title>
    +            <single>
    +                <search base="CPU_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats dc(host) AS dcount</query>
    +                </search>
    +                <option name="underLabel">HOSTS WITH CPU ALERTS (last 24h)</option>
    +                <option name="field">count</option>
    +                <option name="drilldown">all</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0xf58f39"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_cpu_usage`</link>
    +                </drilldown>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <single>
    +                <search base="CPU_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats count AS count</query>
    +                </search>
    +                <option name="underLabel">NUMBER OF TOTAL CPU ALERTS (last 24h)</option>
    +                <option name="field">count</option>
    +                <option name="drilldown">all</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0xf58f39"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_cpu_usage`</link>
    +                </drilldown>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <html rejects="$show_null_alert_cpu$" depends="$frameID$ $host$">
    +                <h2>TagCloud: TOP 10 hosts in Alerts</h2>
    +                <div id="tagcloud1"
    +                     class="splunk-view"
    +                     data-require="app/metricator-for-nmon/components/tagcloud/tagcloud"
    +                     data-options='{
    +            "minFontSize": 14,
    +            "maxFontSize": 55,
    +            "managerid": "tagcloud_cpu",
    +            "valueField": "count",
    +            "labelField": "host"
    +            }'>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel id="panela3_setWidth_48">
    +            <title>Last 24 hours summary</title>
    +            <input type="link" token="cpu_linkinput">
    +                <label></label>
    +                <choice value="cpu_chart1">Chart over time (top 10)</choice>
    +                <choice value="cpu_chart2">Events</choice>
    +                <choice value="cpu_chart3">TOP chart count</choice>
    +                <choice value="cpu_chart4">TOP Stats count</choice>
    +                <choice value="cpu_chart5">TOP chart value</choice>
    +                <choice value="cpu_chart6">TOP Stats value</choice>
    +                <default>cpu_chart1</default>
    +                <change>
    +                    <condition value="cpu_chart1">
    +                        <set token="cpu_chart1">true</set>
    +                        <unset token="cpu_chart2"></unset>
    +                        <unset token="cpu_chart3"></unset>
    +                        <unset token="cpu_chart4"></unset>
    +                        <unset token="cpu_chart5"></unset>
    +                        <unset token="cpu_chart6"></unset>
    +                    </condition>
    +                    <condition value="cpu_chart2">
    +                        <set token="cpu_chart2">true</set>
    +                        <unset token="cpu_chart1"></unset>
    +                        <unset token="cpu_chart3"></unset>
    +                        <unset token="cpu_chart4"></unset>
    +                        <unset token="cpu_chart5"></unset>
    +                        <unset token="cpu_chart6"></unset>
    +                    </condition>
    +                    <condition value="cpu_chart3">
    +                        <set token="cpu_chart3">true</set>
    +                        <unset token="cpu_chart1"></unset>
    +                        <unset token="cpu_chart2"></unset>
    +                        <unset token="cpu_chart4"></unset>
    +                        <unset token="cpu_chart5"></unset>
    +                        <unset token="cpu_chart6"></unset>
    +                    </condition>
    +                    <condition value="cpu_chart4">
    +                        <set token="cpu_chart4">true</set>
    +                        <unset token="cpu_chart1"></unset>
    +                        <unset token="cpu_chart2"></unset>
    +                        <unset token="cpu_chart3"></unset>
    +                        <unset token="cpu_chart5"></unset>
    +                        <unset token="cpu_chart6"></unset>
    +                    </condition>
    +                    <condition value="cpu_chart5">
    +                        <set token="cpu_chart5">true</set>
    +                        <unset token="cpu_chart1"></unset>
    +                        <unset token="cpu_chart2"></unset>
    +                        <unset token="cpu_chart3"></unset>
    +                        <unset token="cpu_chart4"></unset>
    +                        <unset token="cpu_chart6"></unset>
    +                    </condition>
    +                    <condition value="cpu_chart6">
    +                        <set token="cpu_chart6">true</set>
    +                        <unset token="cpu_chart1"></unset>
    +                        <unset token="cpu_chart2"></unset>
    +                        <unset token="cpu_chart3"></unset>
    +                        <unset token="cpu_chart4"></unset>
    +                        <unset token="cpu_chart5"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +            <chart depends="$cpu_chart1$" rejects="$show_null_alert_cpu$">
    +                <title></title>
    +                <search base="CPU_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | timechart useother=t limit=10 count by host</query>
    +                    <!-- Progress event has access to job properties only -->
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_null_alert_cpu">True</set>
    +                        </condition>
    +                        <condition>
    +                            <unset token="show_null_alert_cpu"/>
    +                        </condition>
    +                    </progress>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">Alerts count by host</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <table depends="$cpu_chart2$" rejects="$show_null_alert_cpu$">
    +                <title></title>
    +                <search base="CPU_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +            <chart depends="$cpu_chart3$" rejects="$show_null_alert_cpu$">
    +                <title></title>
    +                <search base="CPU_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | top host</query>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <table depends="$cpu_chart4$" rejects="$show_null_alert_cpu$">
    +                <title></title>
    +                <search base="CPU_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | top host</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +            <chart depends="$cpu_chart5$" rejects="$show_null_alert_cpu$">
    +                <title></title>
    +                <search base="CPU_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats max(latest_cpu_load_percent) AS latest_cpu_load_percent by host | sort - latest_cpu_load_percent</query>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <table depends="$cpu_chart6$" rejects="$show_null_alert_cpu$">
    +                <title></title>
    +                <search base="CPU_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats max(latest_cpu_load_percent) AS latest_cpu_load_percent by host | sort - latest_cpu_load_percent</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +            </table>
    +            <html depends="$show_null_alert_cpu$ $frameID$ $host$">
    +                <br />
    +                <p style="color:#157EFB;margin-left:30px;font-size:14px;font-style:italic;">No hosts with CPU alerts were reported over last 24 hours</p>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <search id="tagcloud_realmem">
    +        <query>| `alerting_realmemory_usage` | search $frameID$ host=$host-prefilter$ $host$ | top limit=10 host</query>
    +        <earliest>-24h</earliest>
    +        <latest>now</latest>
    +    </search>
    +    <row>
    +        <panel>
    +            <html id="mem">
    +                <div class="safecenter">
    +                    <h1>MEM</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="panelb2_setWidth_48">
    +            <title>Summary:</title>
    +            <single>
    +                <search base="RealMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats dc(host) AS dcount</query>
    +                </search>
    +                <option name="underLabel">HOSTS WITH REAL MEMORY ALERTS (last 24h)</option>
    +                <option name="field">count</option>
    +                <option name="drilldown">all</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0xf58f39"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_realmemory_usage`</link>
    +                </drilldown>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <single>
    +                <search base="RealMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats count AS count</query>
    +                </search>
    +                 <option name="underLabel">NUMBER OF TOTAL REAL MEMORY ALERTS (last 24h)</option>
    +                <option name="field">count</option>
    +                <option name="drilldown">all</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0xf58f39"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_realmemory_usage`</link>
    +                </drilldown>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <html rejects="$show_null_alert_realmem$" depends="$frameID$ $host$">
    +                <h2>TagCloud: TOP 10 hosts in Alerts</h2>
    +                <div id="tagcloud2"
    +                     class="splunk-view"
    +                     data-require="app/metricator-for-nmon/components/tagcloud/tagcloud"
    +                     data-options='{
    +            "minFontSize": 14,
    +            "maxFontSize": 55,
    +            "managerid": "tagcloud_realmem",
    +            "valueField": "count",
    +            "labelField": "host"
    +            }'>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel id="panelb3_setWidth_48">
    +            <title>Last 24 hours summary</title>
    +
    +            <input type="link" token="mem_linkinput">
    +                <label></label>
    +                <choice value="mem_chart1">Chart over time (top 10)</choice>
    +                <choice value="mem_chart2">Events</choice>
    +                <choice value="mem_chart3">TOP chart count</choice>
    +                <choice value="mem_chart4">TOP Stats count</choice>
    +                <choice value="mem_chart5">TOP chart value</choice>
    +                <choice value="mem_chart6">TOP Stats value</choice>
    +                <default>mem_chart1</default>
    +                <change>
    +                    <condition value="mem_chart1">
    +                        <set token="mem_chart1">true</set>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                        <unset token="mem_chart6"></unset>
    +                    </condition>
    +                    <condition value="mem_chart2">
    +                        <set token="mem_chart2">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                        <unset token="mem_chart6"></unset>
    +                    </condition>
    +                    <condition value="mem_chart3">
    +                        <set token="mem_chart3">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                        <unset token="mem_chart6"></unset>
    +                    </condition>
    +                    <condition value="mem_chart4">
    +                        <set token="mem_chart4">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                        <unset token="mem_chart6"></unset>
    +                    </condition>
    +                    <condition value="mem_chart5">
    +                        <set token="mem_chart5">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart6"></unset>
    +                    </condition>
    +                    <condition value="mem_chart6">
    +                        <set token="mem_chart6">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                        <unset token="mem_chart5"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$mem_chart1$" rejects="$show_null_alert_realmem$">
    +                <title></title>
    +                <search base="RealMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | timechart useother=t limit=10 count by host</query>
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_null_alert_realmem">True</set>
    +                        </condition>
    +                        <condition>
    +                            <unset token="show_null_alert_realmem"/>
    +                        </condition>
    +                    </progress>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">Alerts count by host</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <table depends="$mem_chart2$" rejects="$show_null_alert_realmem$">
    +                <title></title>
    +                <search base="RealMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +            <chart depends="$mem_chart3$" rejects="$show_null_alert_realmem$">
    +                <title></title>
    +                <search base="RealMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | top host</query>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <table depends="$mem_chart4$" rejects="$show_null_alert_realmem$">
    +                <title></title>
    +                <search base="RealMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | top host</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +            <chart depends="$mem_chart5$" rejects="$show_null_alert_realmem$">
    +                <title></title>
    +                <search base="RealMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats max(latest_mem_used_effective_PCT) AS latest_mem_used_effective_PCT by host | sort - latest_mem_used_effective_PCT</query>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <table depends="$mem_chart6$" rejects="$show_null_alert_realmem$">
    +                <title></title>
    +                <search base="RealMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats max(latest_mem_used_effective_PCT) AS latest_mem_used_effective_PCT by host | sort - latest_mem_used_effective_PCT</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +            <html depends="$show_null_alert_realmem$ $frameID$ $host$">
    +                <br />
    +                <p style="color:#157EFB;margin-left:30px;font-size:14px;font-style:italic;">No hosts with real memory alerts were reported over last 24 hours</p>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <search id="tagcloud_virtualmem">
    +        <query>| `alerting_virtualmemory_usage` | search $frameID$ host=$host-prefilter$ $host$ | top limit=10 host</query>
    +        <earliest>-24h</earliest>
    +        <latest>now</latest>
    +    </search>
    +    <row>
    +        <panel>
    +            <html id="swap">
    +                <div class="safecenter">
    +                    <h1>SWAP</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="panelc2_setWidth_48">
    +            <title>Summary:</title>
    +            <single>
    +                <search base="VirtualMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats dc(host) AS dcount</query>
    +                </search>
    +                  <option name="underLabel">HOSTS WITH VIRTUAL MEMORY ALERTS (last 24h)</option>
    +                <option name="field">count</option>
    +                <option name="drilldown">all</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0xf58f39"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_virtualmemory_usage`</link>
    +                </drilldown>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <single>
    +                <search base="VirtualMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats count AS count</query>
    +                </search>
    +                <option name="underLabel">NUMBER OF TOTAL VIRTUAL MEMORY ALERTS (last 24h)</option>
    +                <option name="field">count</option>
    +                <option name="drilldown">all</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0xf58f39"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_virtualmemory_usage`</link>
    +                </drilldown>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <html rejects="$show_null_alert_virtualmem$" depends="$frameID$ $host$">
    +                <h2>TagCloud: TOP 10 hosts in Alerts</h2>
    +                <div id="tagcloud3"
    +                     class="splunk-view"
    +                     data-require="app/metricator-for-nmon/components/tagcloud/tagcloud"
    +                     data-options='{
    +            "minFontSize": 14,
    +            "maxFontSize": 55,
    +            "managerid": "tagcloud_virtualmem",
    +            "valueField": "count",
    +            "labelField": "host"
    +            }'>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel id="panelc3_setWidth_48">
    +            <title>Last 24 hours summary</title>
    +            <input type="link" token="swap_linkinput">
    +                <label></label>
    +                <choice value="swap_chart1">Chart over time (top 10)</choice>
    +                <choice value="swap_chart2">Events</choice>
    +                <choice value="swap_chart3">TOP chart count</choice>
    +                <choice value="swap_chart4">TOP Stats count</choice>
    +                <choice value="swap_chart5">TOP chart value</choice>
    +                <choice value="swap_chart6">TOP Stats value</choice>
    +                <default>swap_chart1</default>
    +                <change>
    +                    <condition value="swap_chart1">
    +                        <set token="swap_chart1">true</set>
    +                        <unset token="swap_chart2"></unset>
    +                        <unset token="swap_chart3"></unset>
    +                        <unset token="swap_chart4"></unset>
    +                        <unset token="swap_chart5"></unset>
    +                        <unset token="swap_chart6"></unset>
    +                    </condition>
    +                    <condition value="swap_chart2">
    +                        <set token="swap_chart2">true</set>
    +                        <unset token="swap_chart1"></unset>
    +                        <unset token="swap_chart3"></unset>
    +                        <unset token="swap_chart4"></unset>
    +                        <unset token="swap_chart5"></unset>
    +                        <unset token="swap_chart6"></unset>
    +                    </condition>
    +                    <condition value="swap_chart3">
    +                        <set token="swap_chart3">true</set>
    +                        <unset token="swap_chart1"></unset>
    +                        <unset token="swap_chart2"></unset>
    +                        <unset token="swap_chart4"></unset>
    +                        <unset token="swap_chart5"></unset>
    +                        <unset token="swap_chart6"></unset>
    +                    </condition>
    +                    <condition value="swap_chart4">
    +                        <set token="swap_chart4">true</set>
    +                        <unset token="swap_chart1"></unset>
    +                        <unset token="swap_chart2"></unset>
    +                        <unset token="swap_chart3"></unset>
    +                        <unset token="swap_chart5"></unset>
    +                        <unset token="swap_chart6"></unset>
    +                    </condition>
    +                    <condition value="swap_chart5">
    +                        <set token="swap_chart5">true</set>
    +                        <unset token="swap_chart1"></unset>
    +                        <unset token="swap_chart2"></unset>
    +                        <unset token="swap_chart3"></unset>
    +                        <unset token="swap_chart4"></unset>
    +                        <unset token="swap_chart6"></unset>
    +                    </condition>
    +                    <condition value="swap_chart6">
    +                        <set token="swap_chart6">true</set>
    +                        <unset token="swap_chart1"></unset>
    +                        <unset token="swap_chart2"></unset>
    +                        <unset token="swap_chart3"></unset>
    +                        <unset token="swap_chart4"></unset>
    +                        <unset token="swap_chart5"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +            <chart depends="$swap_chart1$" rejects="$show_null_alert_virtualmem$">
    +                <title></title>
    +                <search base="VirtualMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | timechart useother=t limit=10 count by host</query>
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_null_alert_virtualmem">True</set>
    +                        </condition>
    +                        <condition>
    +                            <unset token="show_null_alert_virtualmem"/>
    +                        </condition>
    +                    </progress>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">Alerts count by host</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <table depends="$swap_chart2$" rejects="$show_null_alert_virtualmem$">
    +                <title></title>
    +                <search base="VirtualMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +            <chart depends="$swap_chart3$" rejects="$show_null_alert_virtualmem$">
    +                <title></title>
    +                <search base="VirtualMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | top host</query>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <table depends="$swap_chart4$" rejects="$show_null_alert_virtualmem$">
    +                <title></title>
    +                <search base="VirtualMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | top host</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +            <chart depends="$swap_chart5$" rejects="$show_null_alert_virtualmem$">
    +                <title></title>
    +                <search base="VirtualMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats max(latest_swap_used_effective_PCT) AS latest_swap_used_effective_PCT by host | sort - latest_swap_used_effective_PCT</query>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <table depends="$swap_chart6$" rejects="$show_null_alert_virtualmem$">
    +                <title></title>
    +                <search base="VirtualMem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats max(latest_swap_used_effective_PCT) AS latest_swap_used_effective_PCT by host | sort - latest_swap_used_effective_PCT</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +            <html depends="$show_null_alert_virtualmem$ $frameID$ $host$">
    +                <br />
    +                <p style="color:#157EFB;margin-left:30px;font-size:14px;font-style:italic;">No hosts with virtual memory alerts were reported over last 24 hours</p>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <search id="tagcloud_filesystem">
    +        <query>| `alerting_filesystem_usage` | search $frameID$ host=$host-prefilter$ $host$ | top limit=10 host</query>
    +        <earliest>-24h</earliest>
    +        <latest>now</latest>
    +    </search>
    +    <row>
    +        <panel>
    +            <html id="filesystem">
    +                <div class="safecenter">
    +                    <h1>FILE-SYSTEMS</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel id="paneld2_setWidth_48">
    +            <title>Summary:</title>
    +            <single>
    +                <search base="FileSystem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats dc(host) AS dcount</query>
    +                </search>
    +                <option name="underLabel">HOSTS WITH FILESYSTEM SATURATION ALERTS (last 24h)</option>
    +                <option name="field">count</option>
    +                <option name="drilldown">all</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0xf58f39"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_filesystem_usage`</link>
    +                </drilldown>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <single>
    +                <search base="FileSystem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats count AS count</query>
    +                </search>
    +                <option name="underLabel">NUMBER OF TOTAL FILESYSTEM SATURATION ALERTS (last 24h)</option>
    +                <option name="field">count</option>
    +                <option name="drilldown">all</option>
    +                <option name="colorBy">value</option>
    +                <option name="colorMode">none</option>
    +                <option name="numberPrecision">0</option>
    +                <option name="rangeColors">["0x65a637","0xf58f39"]</option>
    +                <option name="rangeValues">[0]</option>
    +                <option name="showSparkline">1</option>
    +                <option name="showTrendIndicator">1</option>
    +                <option name="trendColorInterpretation">standard</option>
    +                <option name="trendDisplayMode">absolute</option>
    +                <option name="useColors">1</option>
    +                <option name="useThousandSeparators">1</option>
    +                <drilldown target="search">
    +                    <link>search?q=| `alerting_filesystem_usage`</link>
    +                </drilldown>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +            <html rejects="$show_null_alert_fs$" depends="$frameID$ $host$">
    +                <h2>TagCloud: TOP 10 hosts in Alerts</h2>
    +                <div id="tagcloud4"
    +                     class="splunk-view"
    +                     data-require="app/metricator-for-nmon/components/tagcloud/tagcloud"
    +                     data-options='{
    +            "minFontSize": 14,
    +            "maxFontSize": 55,
    +            "managerid": "tagcloud_filesystem",
    +            "valueField": "count",
    +            "labelField": "host"
    +            }'>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel id="paneld3_setWidth_48">
    +            <title>Last 24 hours summary</title>
    +            <input type="link" token="fs_linkinput">
    +                <label></label>
    +                <choice value="fs_chart1">Chart over time (top 10)</choice>
    +                <choice value="fs_chart2">Events</choice>
    +                <choice value="fs_chart3">TOP chart count</choice>
    +                <choice value="fs_chart4">TOP Stats count</choice>
    +                <choice value="fs_chart5">TOP chart value</choice>
    +                <choice value="fs_chart6">TOP Stats value</choice>
    +                <default>fs_chart1</default>
    +                <change>
    +                    <condition value="fs_chart1">
    +                        <set token="fs_chart1">true</set>
    +                        <unset token="fs_chart2"></unset>
    +                        <unset token="fs_chart3"></unset>
    +                        <unset token="fs_chart4"></unset>
    +                        <unset token="fs_chart5"></unset>
    +                        <unset token="fs_chart6"></unset>
    +                    </condition>
    +                    <condition value="fs_chart2">
    +                        <set token="fs_chart2">true</set>
    +                        <unset token="fs_chart1"></unset>
    +                        <unset token="fs_chart3"></unset>
    +                        <unset token="fs_chart4"></unset>
    +                        <unset token="fs_chart5"></unset>
    +                        <unset token="fs_chart6"></unset>
    +                    </condition>
    +                    <condition value="fs_chart3">
    +                        <set token="fs_chart3">true</set>
    +                        <unset token="fs_chart1"></unset>
    +                        <unset token="fs_chart2"></unset>
    +                        <unset token="fs_chart4"></unset>
    +                        <unset token="fs_chart5"></unset>
    +                        <unset token="fs_chart6"></unset>
    +                    </condition>
    +                    <condition value="fs_chart4">
    +                        <set token="fs_chart4">true</set>
    +                        <unset token="fs_chart1"></unset>
    +                        <unset token="fs_chart2"></unset>
    +                        <unset token="fs_chart3"></unset>
    +                        <unset token="fs_chart5"></unset>
    +                        <unset token="fs_chart6"></unset>
    +                    </condition>
    +                    <condition value="fs_chart5">
    +                        <set token="fs_chart5">true</set>
    +                        <unset token="fs_chart1"></unset>
    +                        <unset token="fs_chart2"></unset>
    +                        <unset token="fs_chart3"></unset>
    +                        <unset token="fs_chart4"></unset>
    +                        <unset token="fs_chart6"></unset>
    +                    </condition>
    +                    <condition value="fs_chart6">
    +                        <set token="fs_chart6">true</set>
    +                        <unset token="fs_chart1"></unset>
    +                        <unset token="fs_chart2"></unset>
    +                        <unset token="fs_chart3"></unset>
    +                        <unset token="fs_chart4"></unset>
    +                        <unset token="fs_chart5"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +            <chart depends="$fs_chart1$" rejects="$show_null_alert_fs$">
    +                <title></title>
    +                <search base="FileSystem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | timechart useother=t limit=40 count by host</query>
    +                    <progress>
    +                        <condition match="'job.resultCount' == 0">
    +                            <set token="show_null_alert_fs">True</set>
    +                        </condition>
    +                        <condition>
    +                            <unset token="show_null_alert_fs"/>
    +                        </condition>
    +                    </progress>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">Alerts count by host</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">column</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">top</option>
    +                <option name="height">400</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <table depends="$fs_chart2$" rejects="$show_null_alert_fs$">
    +                <title></title>
    +                <search base="FileSystem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +            <chart depends="$fs_chart3$" rejects="$show_null_alert_fs$">
    +                <title></title>
    +                <search base="FileSystem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | top host</query>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <table depends="$fs_chart4$" rejects="$show_null_alert_fs$">
    +                <title></title>
    +                <search base="FileSystem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | top host</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +            <chart depends="$fs_chart5$" rejects="$show_null_alert_fs$">
    +                <title></title>
    +                <search base="FileSystem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats max(latest_storage_used_percent) AS latest_storage_used_percent by host | sort - latest_storage_used_percent</query>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <table depends="$fs_chart6$" rejects="$show_null_alert_fs$">
    +                <title></title>
    +                <search base="FileSystem_Global">
    +                    <query>search $frameID$ host=$host-prefilter$ $host$ | stats max(latest_storage_used_percent) AS latest_storage_used_percent by host,mount | sort - latest_storage_used_percent</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="count">10</option>
    +                <option name="drilldown">cell</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +            <html depends="$show_null_alert_fs$ $frameID$ $host$">
    +                <br />
    +                <p style="color:#157EFB;margin-left:30px;font-size:14px;font-style:italic;">No hosts with file systems alerts were reported over last 24 hours</p>
    +            </html>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG.xml
    new file mode 100644
    index 0000000..528a76a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG.xml
    @@ -0,0 +1,91 @@
    +<form stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI CONFIG, Full Host Configuration viewer</label>
    +    <description>Extraction of AAA and BBB* configuration sections from Nmon raw data</description>
    +    <fieldset autoRun="false" submitButton="false">
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>TimeRange:</label>
    +            <default>
    +                <earliest>-48h</earliest>
    +                <latest>now</latest>
    +            </default>
    +        </input>
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Type of OS:</label>
    +            <default></default>
    +            <choice value="">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <change>
    +                <condition>
    +                    <unset token="form.host"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <prefix>host="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +            <change>
    +                <condition>
    +                    <unset token="form.host"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +        <input id="host" type="dropdown" token="host" searchWhenChanged="true">
    +            <label>Host Selection:</label>
    +            <prefix>host="</prefix>
    +            <suffix>"</suffix>
    +            <search>
    +                <query>| tstats count where `nmon_index` $host-prefilter$ $osfilter$ by host | dedup host | sort host</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +    </fieldset>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <input type="text" token="customsearch">
    +                <label>Search for a pattern (Will be highlighted):</label>
    +                <default/>
    +                <suffix>*</suffix>
    +            </input>
    +            <event>
    +                <title>Host Configuration Elements (AAA and BBB sections extracted from NMON) - Last event of selected Period</title>
    +                <search>
    +                    <query>eventtype=nmon:config $host$ | head 1 | search $customsearch$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                </search>
    +                <option name="count">10</option>
    +                <option name="list.drilldown">full</option>
    +                <option name="list.wrap">1</option>
    +                <option name="maxLines">0</option>
    +                <option name="raw.drilldown">full</option>
    +                <option name="rowNumbers">0</option>
    +                <option name="table.drilldown">1</option>
    +                <option name="table.wrap">1</option>
    +                <option name="type">list</option>
    +                <fields>[]</fields>
    +            </event>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG_simple_inventory.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG_simple_inventory.xml
    new file mode 100644
    index 0000000..c59ab46
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG_simple_inventory.xml
    @@ -0,0 +1,430 @@
    +<form stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI CONFIG, Inventory Data for All OS</label>
    +    <description>User Interface for Inventory Data Summary (All Operating Systems)</description>
    +    <fieldset autoRun="true" submitButton="false">
    +    </fieldset>
    +    <search id="Global">
    +        <query>| inputlookup nmon_inventory</query>
    +    </search>
    +    <row>
    +        <html>
    +            <div style="text-align: center;">
    +                <img src="../../static/app/metricator-for-nmon/icons/dark_theme/inventory.png" alt="Inventory"/>
    +            </div>
    +            <div class="custom">
    +                <h1>Inventory Summary</h1>
    +            </div>
    +        </html>
    +    </row>
    +    <row>
    +        <single>
    +            <search base="Global">
    +                <query>stats dc(hostname) As count</query>
    +            </search>
    +            <option name="unit">Hosts known</option>
    +            <option name="underLabel">ANY OS</option>
    +            <option name="drilldown">all</option>
    +            <drilldown target="search">
    +                <link>search?q=| inputlookup nmon_inventory
    +| eval "Operating System"=case(OStype=="AIX", ("IBM AIX " %2B AIX_LEVEL), OStype=="Linux", Linux_distribution, OStype=="Solaris", if(isnotnull(Solaris_version), Solaris_version, Solaris_sunOS_version))
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,"Operating System",nmon_version
    +| fillnull value="N/A"
    +| rename Physical_mem_MB AS "Physical memory (MB)", Virtual_mem_MB AS "Virtual memory (MB)"</link>
    +            </drilldown>
    +        </single>
    +    </row>
    +    <row>
    +        <panel>
    +            <single>
    +                <search base="Global">
    +                    <query>search OStype="AIX" | stats dc(hostname) As count</query>
    +                </search>
    +                <option name="unit">Hosts</option>
    +                <option name="underLabel">AIX</option>
    +                <option name="drilldown">all</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype=AIX
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </single>
    +            <html>
    +                <div class="customlink">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/link.png"/>
    +                    <a href="UI_Nmon_CONFIG_simple_inventory_AIX" target="_blank">
    +                        <h3>Link: Access to AIX dedicated Inventory</h3>
    +                    </a>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <single>
    +                <search base="Global">
    +                    <query>search OStype="Linux" | stats dc(hostname) As count</query>
    +                </search>
    +                <option name="unit">Hosts</option>
    +                <option name="underLabel">LINUX</option>
    +                <option name="drilldown">all</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux"
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </single>
    +            <html>
    +                <div class="customlink">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/link.png"/>
    +                    <a href="UI_Nmon_CONFIG_simple_inventory_LINUX" target="_blank">
    +                        <h3>Link: Access to Linux dedicated Inventory</h3>
    +                    </a>
    +                </div>
    +            </html>
    +        </panel>
    +        <panel>
    +            <single>
    +                <search base="Global">
    +                    <query>search OStype="Solaris" | stats dc(hostname) As count</query>
    +                </search>
    +                <option name="unit">Hosts</option>
    +                <option name="underLabel">SOLARIS</option>
    +                <option name="drilldown">all</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype=Solaris
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </single>
    +            <html>
    +                <div class="customlink">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/link.png"/>
    +                    <a href="UI_Nmon_CONFIG_simple_inventory_SOLARIS" target="_blank">
    +                        <h3>Link: Access to Solaris dedicated Inventory</h3>
    +                    </a>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <chart>
    +            <title>Operating System</title>
    +            <search base="Global">
    +                <query>stats count by OStype</query>
    +            </search>
    +            <option name="charting.axisTitleX.visibility">visible</option>
    +            <option name="charting.axisTitleY.visibility">visible</option>
    +            <option name="charting.axisX.scale">linear</option>
    +            <option name="charting.axisY.scale">linear</option>
    +            <option name="charting.chart">pie</option>
    +            <option name="charting.chart.nullValueMode">gaps</option>
    +            <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +            <option name="charting.chart.stackMode">default</option>
    +            <option name="charting.chart.style">minimal</option>
    +            <option name="charting.drilldown">all</option>
    +            <option name="height">300</option>
    +            <option name="charting.layout.splitSeries">0</option>
    +            <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +            <option name="charting.legend.placement">right</option>
    +            <drilldown target="search">
    +                <link>search?q=| inputlookup nmon_inventory | search OStype="$click.value$"
    +| eval "Operating System"=case(OStype=="AIX", ("IBM AIX " %2B AIX_LEVEL), OStype=="Linux", Linux_distribution, OStype=="Solaris", if(isnotnull(Solaris_version), Solaris_version, Solaris_sunOS_version))
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,"Operating System",nmon_version
    +| fillnull value="N/A"
    +| rename Physical_mem_MB AS "Physical memory (MB)", Virtual_mem_MB AS "Virtual memory (MB)"</link>
    +            </drilldown>
    +        </chart>
    +        <table>
    +            <title>Table Stats</title>
    +            <search base="Global">
    +                <query>top limit=0 OStype | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +            </search>
    +            <option name="drilldown">row</option>
    +            <drilldown target="search">
    +                <link>search?q=| inputlookup nmon_inventory | search OStype="$click.value$"
    +| eval "Operating System"=case(OStype=="AIX", ("IBM AIX " %2B AIX_LEVEL), OStype=="Linux", Linux_distribution, OStype=="Solaris", if(isnotnull(Solaris_version), Solaris_version, Solaris_sunOS_version))
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,"Operating System",nmon_version
    +| fillnull value="N/A"
    +| rename Physical_mem_MB AS "Physical memory (MB)", Virtual_mem_MB AS "Virtual memory (MB)"</link>
    +            </drilldown>
    +        </table>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>AIX Version</title>
    +                <search base="Global">
    +                    <query>search OStype="AIX" | stats count by AIX_LEVEL</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_LEVEL="$click.value$"
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>Linux Distribution</title>
    +                <search base="Global">
    +                    <query>search OStype="Linux" | stats count by Linux_distribution</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" Linux_distribution="$click.value$"
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>Solaris Version</title>
    +                <search base="Global">
    +                    <query>search OStype="Solaris" | stats count by Solaris_version</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" Solaris_version="$click.value$"
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Processor</title>
    +                <search base="Global">
    +                    <query>search OStype="AIX" | stats count by Processor</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" Processor="$click.value$"
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>Processor</title>
    +                <search base="Global">
    +                    <query>search OStype="Linux" | stats count by Processor</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" Processor="$click.value$"
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>Processor</title>
    +                <search base="Global">
    +                    <query>search OStype="Solaris" | stats count by Processor</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" Processor="$click.value$"
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>CPU cores Capacity</title>
    +                <search base="Global">
    +                    <query>search OStype="AIX" | stats count by AIX_logicalcores</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_logicalcores="$click.value$"
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>CPU cores Capacity</title>
    +                <search base="Global">
    +                    <query>search OStype="Linux" | stats count by cpu_cores</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" cpu_cores="$click.value$"
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <chart>
    +                <title>CPU cores Capacity</title>
    +                <search base="Global">
    +                    <query>search OStype="Solaris" | stats count by cpu_cores</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" cpu_cores="$click.value$"
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>Full OS Information</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Full AIX Configuration</title>
    +                <search base="Global">
    +                    <query>search OStype="AIX" | fields hostname,AIX_Machine_SerialNumber,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Physical_mem_MB,Virtual_mem_MB,Processor,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_LEVEL,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs
    +| rename "AIX_*" AS *</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Full Linux Configuration</title>
    +                <search base="Global">
    +                        <query>search OStype="Linux" | fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Full Solaris Configuration</title>
    +                <search base="Global">
    +                    <query>search OStype="Solaris" | fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Physical_mem_MB,Virtual_mem_MB,Processor,Solaris_processor_clockspeed,nmon_version</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG_simple_inventory_AIX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG_simple_inventory_AIX.xml
    new file mode 100644
    index 0000000..c98803a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG_simple_inventory_AIX.xml
    @@ -0,0 +1,531 @@
    +<form stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI CONFIG, Inventory for AIX OS</label>
    +    <description>User Interface for Inventory Data of AIX systems</description>
    +
    +    <search id="Global">
    +        <query>| inputlookup nmon_inventory | search OStype="AIX" $hostname$ $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$</query>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div style="text-align: center;">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/inventory.png" alt="Inventory"/>
    +                </div>
    +                <div class="custom">
    +                    <h1>AIX Inventory Summary</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <input type="text" token="hostname" searchWhenChanged="true">
    +                <label>Hostnames:</label>
    +                <prefix>hostname="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="AIX_LEVEL" searchWhenChanged="true">
    +                <label>AIX Versions:</label>
    +                <prefix>AIX_LEVEL="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="Processor" searchWhenChanged="true">
    +                <label>Processor Type:</label>
    +                <prefix>Processor="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="AIX_processor_mode" searchWhenChanged="true">
    +                <label>Processor Mode:</label>
    +                <prefix>AIX_processor_mode="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="AIX_processor_clockspeed" searchWhenChanged="true">
    +                <label>Processor Speed:</label>
    +                <prefix>AIX_processor_clockspeed="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="AIX_cpu_type" searchWhenChanged="true">
    +                <label>CPU Type:</label>
    +                <prefix>AIX_cpu_type="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="AIX_kernel_type" searchWhenChanged="true">
    +                <label>Kernel Type:</label>
    +                <prefix>AIX_kernel_type="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="AIX_plateform_firmware_level" searchWhenChanged="true">
    +                <label>Platform Firmware Level:</label>
    +                <prefix>AIX_plateform_firmware_level="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="AIX_virtualcpus" searchWhenChanged="true">
    +                <label>CPU Virtual capacity:</label>
    +                <prefix>AIX_virtualcpus="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="AIX_logicalcores" searchWhenChanged="true">
    +                <label>CPU cores capacity:</label>
    +                <prefix>AIX_logicalcores="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="nmon_version" searchWhenChanged="true">
    +                <label>Nmon Versions:</label>
    +                <prefix>nmon_version="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <html>
    +                <div style="text-align: left;">
    +                    <b>Optional Filters:</b> To filter results, enter a pattern and press Enter, use * as wilcard character or absolute patterns
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <single>
    +                <search base="Global">
    +                    <query>stats dc(hostname) As count</query>
    +                </search>
    +                <option name="unit">Hosts known</option>
    +                <option name="underLabel">AIX</option>
    +                <option name="drilldown">none</option>
    +            </single>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>AIX Version</title>
    +                <search base="Global">
    +                    <query>stats count by AIX_LEVEL</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_LEVEL="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 AIX_LEVEL | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_LEVEL="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Processor Type</title>
    +                <search base="Global">
    +                    <query>stats count by Processor</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" Processor="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 Processor | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" Processor="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Processor Mode</title>
    +                <search base="Global">
    +                    <query>stats count by AIX_processor_mode</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_processor_mode="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 AIX_processor_mode | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_processor_mode="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Processor Clock Speed</title>
    +                <search base="Global">
    +                    <query>stats count by AIX_processor_clockspeed</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_processor_clockspeed="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 AIX_processor_clockspeed | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_processor_clockspeed="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>CPU Type</title>
    +                <search base="Global">
    +                    <query>stats count by AIX_cpu_type</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_cpu_type="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 AIX_cpu_type | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_cpu_type="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Kernel Type</title>
    +                <search base="Global">
    +                    <query>stats count by AIX_kernel_type</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_kernel_type="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 AIX_kernel_type | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_kernel_type="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Plateform Firmware Level</title>
    +                <search base="Global">
    +                    <query>stats count by AIX_plateform_firmware_level</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_plateform_firmware_level="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 AIX_plateform_firmware_level | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_plateform_firmware_level="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>CPU Virtual (VP) Capacity</title>
    +                <search base="Global">
    +                    <query>stats count by AIX_virtualcpus</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_virtualcpus="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 AIX_virtualcpus | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_virtualcpus="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>CPU cores Capacity</title>
    +                <search base="Global">
    +                    <query>stats count by AIX_logicalcores</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_logicalcores="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 AIX_logicalcores | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" AIX_logicalcores="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Nmon version</title>
    +                <search base="Global">
    +                    <query>stats count by nmon_version</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" nmon_version="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 nmon_version | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="AIX" nmon_version="$click.value$" $AIX_LEVEL$ $Processor$ $AIX_processor_mode$ $AIX_processor_clockspeed$ $AIX_cpu_type$ $AIX_kernel_type$ $AIX_plateform_firmware_level$ $AIX_virtualcpus$ $AIX_logicalcores$ $nmon_version$
    +| fields hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>fields hostname,AIX_Machine_SerialNumber,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Physical_mem_MB,Virtual_mem_MB,Processor,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_LEVEL,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs
    +| rename "AIX_*" AS *</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG_simple_inventory_LINUX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG_simple_inventory_LINUX.xml
    new file mode 100644
    index 0000000..366f968
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG_simple_inventory_LINUX.xml
    @@ -0,0 +1,347 @@
    +<form stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI CONFIG, Inventory for Linux OS</label>
    +    <description>User Interface for inventory data of Linux systems</description>
    +
    +    <search id="Global">
    +        <query>| inputlookup nmon_inventory | search OStype=Linux $hostname$ $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$</query>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div style="text-align: center;">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/inventory.png" alt="Inventory"/>
    +                </div>
    +                <div class="custom">
    +                    <h1>Linux Inventory Summary</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <input type="text" token="hostname" searchWhenChanged="true">
    +                <label>Hostnames:</label>
    +                <prefix>hostname="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="Linux_vendor" searchWhenChanged="true">
    +                <label>Linux Vendor:</label>
    +                <prefix>Linux_vendor="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="Linux_distribution" searchWhenChanged="true">
    +                <label>Linux Distributions:</label>
    +                <prefix>Linux_distribution="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="Processor" searchWhenChanged="true">
    +                <label>Processor Type:</label>
    +                <prefix>Processor="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="cpu_cores" searchWhenChanged="true">
    +                <label>CPU cores capacity:</label>
    +                <prefix>cpu_cores="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="Linux_kernelversion" searchWhenChanged="true">
    +                <label>Kernel versions:</label>
    +                <prefix>Linux_kernelversion="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="nmon_version" searchWhenChanged="true">
    +                <label>Nmon Versions:</label>
    +                <prefix>nmon_version="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <html>
    +                <div style="text-align: left;">
    +                    <b>Optional Filters:</b> To filter results, enter a pattern and press Enter, use * as wilcard character or absolute patterns
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <single>
    +                <search base="Global">
    +                    <query>stats count</query>
    +                </search>
    +                <option name="unit">Hosts known</option>
    +                <option name="underLabel">Linux</option>
    +                <option name="drilldown">none</option>
    +            </single>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Linux Vendor (requires lsb_release)</title>
    +                <search base="Global">
    +                    <query>stats count by Linux_vendor</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" Linux_vendor="$click.value$" $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 Linux_vendor | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" Linux_vendor="$click.value$" $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Linux Distribution (lsb_release or /etc/release)</title>
    +                <search base="Global">
    +                    <query>stats count by Linux_distribution</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" Linux_distribution="$click.value$" $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 Linux_distribution | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" Linux_distribution="$click.value$" $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Processor</title>
    +                <search base="Global">
    +                    <query>stats count by Processor</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" Processor="$click.value$" $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 Processor | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" Processor="$click.value$" $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>CPUs cores Capacity</title>
    +                <search base="Global">
    +                    <query>stats count by cpu_cores</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" cpu_cores="$click.value$" $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 cpu_cores | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" cpu_cores="$click.value$" $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Linux Kernel</title>
    +                <search base="Global">
    +                    <query>stats count by Linux_kernelversion</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" Linux_kernelversion="$click.value$" $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 Linux_kernelversion | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" Linux_kernelversion="$click.value$" $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Nmon version</title>
    +                <search base="Global">
    +                    <query>stats count by nmon_version</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" nmon_version="$click.value$" $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 nmon_version | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Linux" nmon_version="$click.value$" $Linux_vendor$ $Linux_distribution$ $Processor$ $cpu_cores$ $Linux_kernelversion$ $nmon_version$
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_seconds,uptime_duration,system_startup_date</query>
    +                </search>
    +                <option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG_simple_inventory_SOLARIS.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG_simple_inventory_SOLARIS.xml
    new file mode 100644
    index 0000000..9e1b402
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CONFIG_simple_inventory_SOLARIS.xml
    @@ -0,0 +1,341 @@
    +<form stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI CONFIG, Inventory for Solaris OS</label>
    +    <description>User Interface for inventory data of Solaris systems</description>
    +
    +    <search id="Global">
    +        <query>| inputlookup nmon_inventory | search OStype=Solaris $hostname$ $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$</query>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div style="text-align: center;">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/inventory.png" alt="Inventory"/>
    +                </div>
    +                <div class="custom">
    +                    <h1>Solaris Inventory Summary</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <input type="text" token="hostname" searchWhenChanged="true">
    +                <label>Hostnames:</label>
    +                <prefix>hostname="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="Solaris_version" searchWhenChanged="true">
    +                <label>Solaris Versions:</label>
    +                <prefix>Solaris_version="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="Solaris_sunOS_version" searchWhenChanged="true">
    +                <label>SunOS Versions:</label>
    +                <prefix>Solaris_sunOS_version="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="cpu_cores" searchWhenChanged="true">
    +                <label>CPU cores capacity:</label>
    +                <prefix>cpu_cores="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="Processor" searchWhenChanged="true">
    +                <label>Processor Type:</label>
    +                <prefix>Processor="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="Solaris_processor_clockspeed" searchWhenChanged="true">
    +                <label>Processor Clockspeed:</label>
    +                <prefix>Solaris_processor_clockspeed="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <input type="text" token="nmon_version" searchWhenChanged="true">
    +                <label>Nmon Versions:</label>
    +                <prefix>nmon_version="</prefix>
    +                <suffix>"</suffix>
    +                <default>*</default>
    +            </input>
    +            <html>
    +                <div style="text-align: left;">
    +                    <b>Optional Filters:</b> To filter results, enter a pattern and press Enter, you use * as wilcard character or absolute patterns
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <single>
    +                <search base="Global">
    +                    <query>stats count</query>
    +                </search>
    +                <option name="unit">Solaris Hosts known</option>
    +            </single>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Solaris version</title>
    +                <search base="Global">
    +                    <query>stats count by Solaris_version</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" Solaris_version="$click.value$" $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 Solaris_version | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" Solaris_version="$click.value$" $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Solaris (sunOS) version</title>
    +                <search base="Global">
    +                    <query>stats count by Solaris_sunOS_version</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" Solaris_sunOS_version="$click.value$" $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 Solaris_sunOS_version | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" Solaris_sunOS_version="$click.value$" $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>CPUs cores Capacity</title>
    +                <search base="Global">
    +                    <query>stats count by cpu_cores</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" cpu_cores="$click.value$" $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 cpu_cores | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" cpu_cores="$click.value$" $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Processor</title>
    +                <search base="Global">
    +                    <query>stats count by Processor</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" Processor="$click.value$" $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>search $hostname$ $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$ | top limit=0 Processor | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" Processor="$click.value$" $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Processor ClockSpeed</title>
    +                <search base="Global">
    +                    <query>stats count by Solaris_processor_clockspeed</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" Solaris_processor_clockspeed="$click.value$" $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 Solaris_processor_clockspeed | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" Solaris_processor_clockspeed="$click.value$" $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <chart>
    +                <title>Nmon version</title>
    +                <search base="Global">
    +                    <query>stats count by nmon_version</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">pie</option>
    +                <option name="charting.chart.nullValueMode">gaps</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">minimal</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="height">300</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">right</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" nmon_version="$click.value$" $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>top limit=0 nmon_version | eval percent=round(percent,2) | rename count As "Number of Hosts" | strcat percent "%" percent | rename percent As "Percent (%)"</query>
    +                </search>
    +                <option name="drilldown">row</option>
    +                <drilldown target="search">
    +                    <link>search?q=| inputlookup nmon_inventory | search OStype="Solaris" nmon_version="$click.value$" $Solaris_version$ $Solaris_sunOS_version$ $cpu_cores$ $Processor$ $Solaris_processor_clockspeed$ $nmon_version$
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,nmon_version</link>
    +                </drilldown>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="Global">
    +                    <query>fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Physical_mem_MB,Virtual_mem_MB,Processor,Solaris_processor_clockspeed,nmon_version</query>
    +                </search><option name="drilldown">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CPU_ALL.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CPU_ALL.xml
    new file mode 100644
    index 0000000..d8ad40d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CPU_ALL.xml
    @@ -0,0 +1,654 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI CPU_ALL - CPU Percentage usage advanced analysis</label>
    +    <description>User Interface for the CPU_ALL monitor, Processor Percentage utilization statistics</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate_input" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="none">Single Series</choice>
    +            <choice value="avg">Average by Time interval</choice>
    +            <choice value="median">Median by Time interval</choice>
    +            <choice value="max">Max by Time interval</choice>
    +            <default>none</default>
    +            <change>
    +                <condition value="none">
    +                    <set token="aggregate">fields *</set>
    +                </condition>
    +                <condition value="avg">
    +                    <set token="aggregate">stats avg(*) as &quot;*&quot; by _time | eval host=&quot;aggreg_host&quot;</set>
    +                </condition>
    +                <condition value="median">
    +                    <set token="aggregate">stats median(*) as &quot;*&quot; by _time | eval host=&quot;aggreg_host&quot;</set>
    +                </condition>
    +                <condition value="max">
    +                    <set token="aggregate">stats max(*) as &quot;*&quot; by _time | eval host=&quot;aggreg_host&quot;</set>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>avg</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Main search for form populating -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.logical_cpus" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for CPU statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                                    <h1>
    +                                        CPU global percentage statistics
    +                                        <br />
    +                                        (metric_name=os.unix.nmon.cpu.cpu_all.*)
    +                                    </h1>
    +
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    <i>The CPU_ALL monitor represents average metrics for all available logical CPUs to the system.</i>
    +                                    <br />
    +                                    <i>These metrics are common to every supported operating systems.</i>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>raw metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Sys_PCT:</b> % of CPU time spent in kernel mode</li>
    +                                            <li><b>User_PCT:</b> % of CPU time spent in user mode</li>
    +                                            <li><b>Wait_PCT:</b> % of CPU time spent in waiting for resources</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Steal_PCT:</b> % of time a virtual CPU waits for a real CPU while the hypervisor is servicing another virtual processor</li>
    +                                            <li><b>Idle_PCT:</b> % of CPU time free, meaning not having task to do</li>
    +                                            <li><b>CPUs:</b> Number of CPUs cores available to the system</li>
    +                                        </lu>
    +                                        <br />
    +                                    </div>
    +
    +                                    <h1>calculated metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>cpu_load_percent:</b> % of CPU usage for all available cores (Sys_PCT+User_PCT+Wait_PCT+Steal_PCT)</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.cpu.cpu_all.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_cpu_load_percent%60" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_CPU_ALL_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" class="tryitbtnxl">CPU Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="gaugestats">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT) host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Steal_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Steal_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent, values(Steal_percent) as Steal_percent by _time, host
    +| fillnull value=0 Sys_percent,User_percent,Wait_percent,Steal_percent
    +| eval cpu_load_percent=(Sys_percent+User_percent+Wait_percent+Steal_percent)
    +| stats max(cpu_load_percent) AS max, avg(cpu_load_percent) AS avg, median(cpu_load_percent) AS median | foreach * [ eval &lt;&lt;FIELD&gt;&gt; = if('&lt;&lt;FIELD&gt;&gt;'>100, 100, round('&lt;&lt;FIELD&gt;&gt;', 2) ) ]</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- ################################ -->
    +
    +    <row>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval max=round(max,2) | gauge max</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Max %CPU</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval avg=round(avg,2) | gauge avg</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Avg %CPU</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval median=round(median,2) | gauge median</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Median %CPU</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <table>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT) host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value), Steal_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Steal_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent, values(Steal_percent) as Steal_percent by _time, host
    +| fillnull value=0 Sys_percent,User_percent,Wait_percent,Steal_percent
    +| eval cpu_load_percent=(Sys_percent+User_percent+Wait_percent+Steal_percent)
    +| $aggregate$
    +| stats $statsmode$(cpu_load_percent) as cpu_load_percent, $statsmode$(Sys_percent) as Sys_percent, $statsmode$(User_percent) as User_percent, $statsmode$(Wait_percent) as Wait_percent, $statsmode$(Steal_percent) as Steal_percent, $statsmode$(Idle_percent) as Idle_percent, sparkline(avg(cpu_load_percent),) As sparkline by host
    +| foreach *_percent [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 3) ]
    +| rename *_percent AS "* (%)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="User (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Sys (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Wait (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Steal (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="cpu (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="cpumode" searchWhenChanged="true">
    +                <label>Show CPU load by:</label>
    +                <default>fields _time,host,CPU.cpu_PCT</default>
    +                <choice value="fields _time,host,CPU.cpu_PCT">Global CPU Percent Utilization</choice>
    +                <choice value="fields _time,host,CPU.Idle_PCT,CPU.Sys_PCT,CPU.User_PCT,CPU.Wait_PCT,CPU.Steal_PCT">MultiSeries: Sys,User,Wait,Steal,Idle</choice>
    +                <change>
    +                    <condition value="fields _time,host,CPU.Idle_PCT,CPU.Sys_PCT,CPU.User_PCT,CPU.Wait_PCT,CPU.Steal_PCT">
    +                        <set token="form.chart">area</set>
    +                        <set token="form.charting.chart.nullValueMode">connect</set>
    +                        <set token="form.chart.stackingmode">stacked</set>
    +                        <set token="cpu_by_category">_time, *</set>
    +                        <unset token="cpu_global"></unset>
    +                        <unset token="form.cpu_scaleend"></unset>
    +                    </condition>
    +                    <condition value="fields _time,host,CPU.cpu_PCT">
    +                        <set token="form.chart">line</set>
    +                        <set token="form.charting.chart.nullValueMode">gaps</set>
    +                        <set token="form.chart.stackingmode">default</set>
    +                        <set token="cpu_global">_time, *</set>
    +                        <unset token="cpu_by_category"></unset>
    +                        <set token="form.cpu_scaleend">100</set>
    +                    </condition>
    +                </change>
    +            </input>
    +            <input type="checkbox" token="cpumode_cat" searchWhenChanged="true" depends="$cpu_by_category$">
    +              <label>Categories:</label>
    +              <choice value="Sys_percent*">Sys_percent</choice>
    +              <choice value="User_percent*">User_percent</choice>
    +              <choice value="Wait_percent*">Wait_percent</choice>
    +              <choice value="Steal_percent*">Steal_percent</choice>
    +              <choice value="Idle_percent*">Idle_percent</choice>
    +              <default>Idle_percent*,Wait_percent*,User_percent*,Sys_percent*,Steal_percent*</default>
    +              <delimiter>,</delimiter>
    +            </input>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>CPU percentage usage statistics</title>
    +            <input type="checkbox" token="cpu_scale" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="cpu_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="100">Ends scale at 100 %</choice>
    +                <initialValue>100</initialValue>
    +            </input>
    +            <chart rejects="$cpu_by_category$">
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT) host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Steal_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Steal_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent, values(Steal_percent) as Steal_percent by _time, host
    +| fillnull value=0 Sys_percent,User_percent,Wait_percent,Steal_percent
    +| eval cpu_load_percent=(Sys_percent+User_percent+Wait_percent+Steal_percent)
    +| $aggregate$
    +| timechart $span$ useother=f limit=0 $statsmode$(cpu_load_percent) AS cpu_load_percent by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPUs</option>
    +                <option name="charting.axisY.minimumNumber">$cpu_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$cpu_scaleend$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT) host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Steal_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Steal_PCT", value)
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Idle_percent) as Idle_percent, values(Steal_percent) as Steal_percent by _time, host
    +| fillnull value=0 Sys_percent,User_percent,Wait_percent,Steal_percent
    +| eval cpu_load_percent=(Sys_percent+User_percent+Wait_percent+Steal_percent)
    +| $aggregate$
    +| timechart $span$ useother=f limit=0 $statsmode$(cpu_load_percent) AS cpu_load_percent by host</link>
    +                </drilldown>
    +            </chart>
    +            <chart depends="$cpu_by_category$">
    +                <search depends="$cpu_by_category$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT) host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value), Steal_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Steal_PCT", value)
    +| $aggregate$
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Steal_percent) as Steal_percent, values(Idle_percent) as Idle_percent by _time, host
    +| timechart $span$ useother=f limit=0 $statsmode$(Idle_percent) AS Idle_percent,
    +$statsmode$(Sys_percent) AS Sys_percent,
    +$statsmode$(User_percent) AS User_percent,
    +$statsmode$(Wait_percent) AS Wait_percent,
    +$statsmode$(Steal_percent) AS Steal_percent by host
    +| fields _time, $cpumode_cat$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPUs</option>
    +                <option name="charting.axisY.minimumNumber">$cpu_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$cpu_scaleend$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT) host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Idle_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Idle_PCT", value), Steal_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Steal_PCT", value)
    +| $aggregate$
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Steal_percent) as Steal_percent, values(Idle_percent) as Idle_percent by _time, host
    +| timechart $span$ useother=f limit=0 $statsmode$(Idle_percent) AS Idle_percent,
    +$statsmode$(Sys_percent) AS Sys_percent,
    +$statsmode$(User_percent) AS User_percent,
    +$statsmode$(Wait_percent) AS Wait_percent,
    +$statsmode$(Steal_percent) AS Steal_percent by host
    +| fields _time, $cpumode_cat$</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CPUnn.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CPUnn.xml
    new file mode 100644
    index 0000000..d872fb9
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_CPUnn.xml
    @@ -0,0 +1,677 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI CPUnn - CPU Percentage usage per core advanced analysis</label>
    +    <description>User Interface for the CPUnn monitor, Processor Percentage utilization statistics per logical core</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input type="multiselect" token="cpu_core" searchWhenChanged="true">
    +            <label>Core Selection:</label>
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$ $host$
    +| stats count by cpu_core | dedup cpu_core | sort 0 cpu_core</query>
    +            </search>
    +            <valuePrefix>cpu_core="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL cores</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>cpu_core</fieldForLabel>
    +            <fieldForValue>cpu_core</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate_input" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="none">Single Series</choice>
    +            <choice value="avg">Average by Time interval</choice>
    +            <choice value="median">Median by Time interval</choice>
    +            <choice value="max">Max by Time interval</choice>
    +            <default>none</default>
    +            <change>
    +                <condition value="none">
    +                    <set token="aggregate">fields *</set>
    +                </condition>
    +                <condition value="avg">
    +                    <set token="aggregate">stats avg(*) as &quot;*&quot; by _time, cpu_core | eval host=&quot;aggreg_host&quot;</set>
    +                </condition>
    +                <condition value="median">
    +                    <set token="aggregate">stats median(*) as &quot;*&quot; by _time, cpu_core | eval host=&quot;aggreg_host&quot;</set>
    +                </condition>
    +                <condition value="max">
    +                    <set token="aggregate">stats max(*) as &quot;*&quot; by _time, cpu_core | eval host=&quot;aggreg_host&quot;</set>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>avg</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) as metrics values(OStype) as OStype where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpunn.*" $osfilter$ by host
    +| rename metrics as metric_name
    +| rex field="metric_name" "os\.unix\.nmon\.\w*\.\w*\.(?&lt;cpu_core&gt;\w*)\.(?&lt;metric&gt;\w*)"
    +| `mapping_frameID`
    +| stats count by frameID, host, cpu_core | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for CPU statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                                    <h1>
    +                                        CPU percentage statistics per logical processor
    +                                        <br />
    +                                        (metric_name=os.unix.nmon.cpu.cpunn.*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div>
    +                                    <i>The CPUnn monitor represents average metrics on a per logical CPU level available to the system.</i>
    +                                    <br />
    +                                    <i>These metrics are common to every supported operating systems.</i>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>raw metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>os.unix.nmon.cpu.cpunn.*.Sys_PCT:</b> % of CPU time spent in kernel mode</li>
    +                                            <li><b>os.unix.nmon.cpu.cpunn.*.User_PCT:</b> % of CPU time spent in user mode</li>
    +                                            <li><b>os.unix.nmon.cpu.cpunn.*.Wait_PCT:</b> % of CPU time spent in waiting for resources</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>os.unix.nmon.cpu.cpunn.*.Steal_PCT:</b> % of time a virtual CPU waits for a real CPU while the hypervisor is servicing another virtual processor</li>
    +                                        </lu>
    +                                        <lu>
    +                                            <li><b>os.unix.nmon.cpu.cpunn.*.Idle_PCT:</b> % of CPU time free, meaning not having task to do</li>
    +                                        </lu>
    +                                        <br />
    +                                    </div>
    +
    +                                    <h1>calculated metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>cpu_load_percent:</b> % of CPU usage for all available cores (Sys_PCT+User_PCT+Wait_PCT+Steal_PCT)</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <h1>metric dimensions:</h1>
    +
    +                                    <div>
    +                                        <i>The CPUnn monitor owns a dimension which is the name of the cpu core, it is part of the metric_name as the 6th segment: <b>os.unix.nmon.cpu.cpunn.&lt;CPU_core&gt;.*</b>
    +                                        </i>
    +                                        <br />
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.cpu.cpunn.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60extract_metrics_cpu_all(&quot;Sys_PCT%2C%20User_PCT%2C%20Wait_PCT%2C%20Idle_PCT%2C%20Steal_PCT&quot;)%60%0A%7C%20stats%20values(Sys_PCT)%20as%20Sys_PCT%2C%20values(User_PCT)%20as%20User_PCT%2C%20values(Steal_PCT)%20as%20Steal_PCT%2C%20values(Wait_PCT)%20as%20Wait_PCT%2C%20values(Idle_PCT)%20as%20Idle_PCT%20by%20_time%2C%20host%2C%20cpu_core%0A%7C%20fillnull%20value%3D0%20Sys_PCT%20User_PCT%20Wait_PCT%20Steal_PCT%0A%7C%20eval%20cpu_load_percent%3D(Sys_PCT%2BUser_PCT%2BWait_PCT%2BSteal_PCT)" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_CPU_ALL_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" class="tryitbtnxl">CPU Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <search id="gaugestats">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT, Steal_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT, values(Steal_PCT) as Steal_PCT by _time, host, cpu_core
    +| `$timefilter$`
    +| fillnull value=0 Sys_PCT,User_PCT,Wait_PCT,Steal_PCT
    +| eval cpu_load_percent=(Sys_PCT+User_PCT+Wait_PCT+Steal_PCT)
    +| stats avg(cpu_load_percent) as cpu_load_percent by _time, host
    +| stats avg(cpu_load_percent) as cpu_load_percent by _time
    +| stats max(cpu_load_percent) AS max, avg(cpu_load_percent) AS avg, median(cpu_load_percent) AS median</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- ################################ -->
    +
    +    <row>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval max=round(max,2) | gauge max</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Max %CPU</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval avg=round(avg,2) | gauge avg</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Avg %CPU</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval median=round(median,2) | gauge median</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Median %CPU</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT, Steal_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT, values(Steal_PCT) as Steal_PCT by _time, host, cpu_core
    +| `$timefilter$`
    +| fillnull value=0 Sys_PCT,User_PCT,Wait_PCT,Steal_PCT
    +| eval cpu_load_percent=(Sys_PCT+User_PCT+Wait_PCT+Steal_PCT)
    +| $aggregate$
    +| stats avg(cpu_load_percent) as cpu_load_percent, avg(Sys_PCT) as Sys_PCT, avg(User_PCT) as User_PCT, avg(Wait_PCT) as Wait_PCT, avg(Steal_PCT) as Steal_PCT by host, cpu_core
    +| foreach cpu_load_percent Sys_PCT User_PCT Wait_PCT Steal_PCT [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 3) ]
    +| rename cpu_load_percent as "cpu (%)", Sys_PCT as "Sys (%)", User_PCT as "User (%)", Wait_PCT as "Wait (%)", Steal_PCT as "Steal (%)"
    +                    </query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="User (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Sys (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Wait (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Steal (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="cpu (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="cpumode" searchWhenChanged="true">
    +                <label>Show CPU load by:</label>
    +                <default>global_cpu</default>
    +                <choice value="global_cpu">Global CPU Percent Utilization</choice>
    +                <choice value="multi_cpu">MultiSeries: Sys,User,Wait,Steal,Idle</choice>
    +                <change>
    +                    <condition value="global_cpu">
    +                        <set token="form.chart">line</set>
    +                        <set token="form.charting.chart.nullValueMode">gaps</set>
    +                        <set token="form.chart.stackingmode">default</set>
    +                        <set token="show_by_cpu_global">True</set>
    +                        <unset token="show_by_cpu_category"></unset>
    +                    </condition>
    +                    <condition value="multi_cpu">
    +                        <set token="form.chart">area</set>
    +                        <set token="form.charting.chart.nullValueMode">connect</set>
    +                        <set token="form.chart.stackingmode">stacked</set>
    +                        <set token="show_by_cpu_category">True</set>
    +                        <unset token="show_by_cpu_global"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +            <input type="checkbox" token="cpumode_cat" searchWhenChanged="true" depends="$cpu_by_category$">
    +              <label>Categories:</label>
    +              <choice value="Sys_PCT*">Sys_PCT</choice>
    +              <choice value="User_PCT*">User_PCT</choice>
    +              <choice value="Wait_PCT*">Wait_PCT</choice>
    +              <choice value="Steal_PCT*">Steal_PCT</choice>
    +              <choice value="Idle_PCT*">Idle_PCT</choice>
    +              <default>Idle_PCT*,Wait_PCT*,User_PCT*,Sys_PCT*,Steal_PCT*</default>
    +              <delimiter>,</delimiter>
    +            </input>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>CPU Logical Core statistics</title>
    +            <input type="checkbox" token="cpu_scale" searchWhenChanged="true">
    +                <label></label>
    +                <initialValue>0</initialValue>
    +                <choice value="0">Starts scale at 0 %</choice>
    +            </input>
    +            <input type="checkbox" token="cpu_scaleend" searchWhenChanged="true">
    +                <label></label>
    +                <choice value="100">Ends scale at 100 %</choice>
    +                <initialValue>100</initialValue>
    +            </input>
    +            <chart depends="$show_by_cpu_global$">
    +                <search depends="$show_by_cpu_global$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT, Steal_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT, values(Steal_PCT) as Steal_PCT by _time, host, cpu_core
    +| fillnull value=0 Sys_PCT,User_PCT,Wait_PCT,Steal_PCT
    +| `$timefilter$`
    +| search ($cpu_core$)
    +| eval cpu_PCT=(Sys_PCT+User_PCT+Wait_PCT+Steal_PCT)
    +| $aggregate$
    +| eval key=host . ":" . cpu_core
    +| timechart $span$ useother=f limit=0 avg(cpu_PCT) AS cpu_PCT by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPUs</option>
    +                <option name="charting.axisY.minimumNumber">$cpu_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$cpu_scaleend$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT, Steal_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT, values(Steal_PCT) as Steal_PCT by _time, host, cpu_core
    +| fillnull value=0 Sys_PCT,User_PCT,Wait_PCT,Steal_PCT
    +| `$timefilter$`
    +| search ($cpu_core$)
    +| eval cpu_PCT=(Sys_PCT+User_PCT+Wait_PCT+Steal_PCT)
    +| $aggregate$
    +| eval key=host . ":" . cpu_core
    +| timechart $span$ useother=f limit=0 avg(cpu_PCT) AS cpu_PCT by key
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +            <chart depends="$show_by_cpu_category$">
    +                <search depends="$show_by_cpu_category$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT, Steal_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT, values(Steal_PCT) as Steal_PCT by _time, host, cpu_core | fillnull value=0
    +| `$timefilter$`
    +| search ($cpu_core$)
    +| eval Idle_PCT=100-(Sys_PCT+User_PCT+Wait_PCT+Steal_PCT)
    +| $aggregate$
    +| timechart $span$ useother=f limit=0 avg(Idle_PCT) as "Idle_PCT", avg(Wait_PCT) as Wait_PCT, avg(User_PCT) as User_PCT, avg(Sys_PCT) as Sys_PCT, avg(Steal_PCT) as Steal_PCT by host
    +| fields _time,$cpumode_cat$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% CPUs</option>
    +                <option name="charting.axisY.minimumNumber">$cpu_scale$</option>
    +                <option name="charting.axisY.maximumNumber">$cpu_scaleend$</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpunn.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `extract_metrics_cpu_all("Sys_PCT, User_PCT, Wait_PCT, Steal_PCT")`
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT, values(Steal_PCT) as Steal_PCT by _time, host, cpu_core | fillnull value=0
    +| `$timefilter$`
    +| search ($cpu_core$)
    +| eval Idle_PCT=100-(Sys_PCT+User_PCT+Wait_PCT+Steal_PCT)
    +| $aggregate$
    +| timechart $span$ useother=f limit=0 avg(Idle_PCT) as "Idle_PCT", avg(Wait_PCT) as Wait_PCT, avg(User_PCT) as User_PCT, avg(Sys_PCT) as Sys_PCT, avg(Steal_PCT) as Steal_PCT by host
    +| fields _time,$cpumode_cat$
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_DG.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_DG.xml
    new file mode 100644
    index 0000000..009dd13
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_DG.xml
    @@ -0,0 +1,1017 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI DG, Disks extended statistics</label>
    +    <description>User Interface for the disks extended performance monitors</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input id="device" type="multiselect" token="device" searchWhenChanged="true">
    +            <label>Disks Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ $host$
    +| stats count by dimension_device | dedup dimension_device | sort 0 dimension_device</query>
    +            </search>
    +            <valuePrefix>dimension_device="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <initialValue>*</initialValue>
    +            <choice value="*">ALL Devices</choice>
    +            <fieldForLabel>dimension_device</fieldForLabel>
    +            <fieldForValue>dimension_device</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>avg</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row depends="$host$" rejects="$device$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please select associated devices to be analysed in the device selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4>
    +                        <a data-modal-name="Help_modal">Help, information and related links for disks statistics</a>
    +                    </h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
    +                                    <span aria-hidden="true"/>
    +                                </button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/drive.png" alt="drive"/>
    +                                    <h1>Disks extended statistics (os.unix.nmon.storage.dg*)</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>disk_backlog_time_ms:</b> Disk Group Backlog time (ms) - DGBACKLOG </li>
    +                                            <li><b>disk_busy_time_pct:</b> Disk Group Busy (% of time) - DGBUSY </li>
    +                                            <li><b>disk_block_size_KB:</b> Disk Group Block Size KB - DGSIZE</li>
    +                                            <li><b>disk_in_flight_io:</b> Disk Group in flight IO (I/O per sec) - DGINFLIGHT</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +
    +                                            <li><b>disk_read_KB_per_sec:</b> Disk Group Read KB/s - DGREAD </li>
    +                                            <li><b>disk_read_sec:</b> Disk Group read/s - DGREADS </li>
    +                                            <li><b>disk_read_service_time_ms:</b> Disk Group read service time (SUM ms) - DGREADSERV </li>
    +                                            <li><b>disk_read_iops:</b> Disk Group Read Transfers/s (DGREAD divided by DGSIZE) </li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +
    +                                            <li><b>disk_write_KB_per_sec:</b> Disk Group Write KB/s - DGWRITE </li>
    +                                            <li><b>disk_write_service_time_ms:</b> Disk Group write service time (SUM ms) - DGWRITESERV </li>
    +                                            <li><b>disk_write_iops:</b> Disk Group Write Transfers/s (DGWRITE divided by DGSIZE) </li>
    +                                            <li><b>disk_write_sec:</b> Disk Group write/s - DGWRITES</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>disk_merge_write_sec:</b> Disk Group merged write/s - DGWRITEMERGE </li>
    +                                            <li><b>disk_merge_read_sec:</b> Disk Group merged read/s - DGREADMERGE</li>
    +                                            <li><b>disk_total_iops:</b> Disk Group Transfers/s - DGXFER </li>
    +                                            <li><b>disk_time_spent_for_io_ms:</b> Disk Group time spent for IO (ms) - DGIOTIME </li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Help:</h1>From the Nmon FAQ: <a target="_blank" href="http://nmon.sourceforge.net/pmwiki.php?n=Site.NmonFAQ" >http://nmon.sourceforge.net/pmwiki.php?n=Site.NmonFAQ</a>
    +
    +                                </div>
    +
    +                                <br />
    +
    +                                <div class="list">
    +                                    <lu>
    +                                        <li><b>DGBUSY</b> highlights which disks are slowing you down</li>
    +                                        <li><b>DGREAD</b> and <b>DGWRITE</b> highlights how much data you are shifting</li>
    +                                    </lu>
    +                                </div>
    +
    +                                <div class="list">
    +                                    <lu>
    +                                        <li><b>DGXFER</b> highlight is you are approaching the Disk seek limits and adapter operation limits</li>
    +                                        <li><b>DGSIZE</b> highlights if your application is doing silly small boxes</li>
    +                                    </lu>
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_device)%20as%20dimension_device%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.dg*%20host%3D*" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.dg*%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.dg*%20host%3D*%20dimension_device%3D*%20by%20host%2C%20metric_name%2C%20dimension_device%20span%3D1m%0A%7C%20%60extract_metrics(&quot;dgbacklog%20dgbusy%20dginflight%20dgiotime%20dgread%20dgreadmerge%20dgreads%20dgreadserv%20dgsize%20dgwrite%20dgwritemerge%20dgwrites%20dgwriteserv%20dgxfer&quot;)%60%0A%7C%20stats%20values(dg*)%20as%20&quot;dg*&quot;%20by%20_time%2C%20host%2C%20dimension_device%0A%7C%20eval%20dgxfer_read%3D(dgread%2Fdgsize)%2C%20dgxfer_write%3D(dgwrite%2Fdgsize)%0A%7C%20stats%20avg(dg*)%20as%20&quot;dg*&quot;%20by%20_time%2C%20host%2C%20dimension_device%0A%7C%20foreach%20dg*%20%5B%20eval%20&lt;&lt;FIELD&gt;&gt;%20%3D%20round(%27&lt;&lt;FIELD&gt;&gt;%27%2C%202)%20%5D" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_DISK_DG_spl" class="tryitbtnxl">HOWTO »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.disk*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.storage.disk* »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dg*" $osfilter$ by host, dimension_device
    +| `mapping_frameID` | stats count by frameID, host, dimension_device | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <title>Statistics:</title>
    +            <table>
    +                <search id="tablestats">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dg*" host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| `extract_metrics("dgbacklog dgbusy dginflight dgiotime dgread dgreadmerge dgreads dgreadserv dgsize dgwrite dgwritemerge dgwrites dgwriteserv dgxfer")`
    +| stats values(dg*) as "dg*" by _time, host, dimension_device
    +| eval dgxfer_read=(dgread/dgsize), dgxfer_write=(dgwrite/dgsize)
    +| stats $statsmode$(dg*) as "dg*" by host, dimension_device
    +| foreach dg* [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="dgbacklog">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgbusy">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dginflight">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgiotime">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgread">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgreadmerge">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgreads">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgreadserv">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgsize">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgwrite">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgwritemerge">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgwrites">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgwriteserv">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgxfer">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgxfer_read">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dgxfer_write">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Over time charting:</title>
    +
    +            <input type="link" token="disk_dg_linkinput">
    +                <label></label>
    +                <choice value="disk_dg_chart1">DG, I/O Operations per second (DGXFER/DGREAD-DGWRITE by DGSIZE)</choice>
    +                <choice value="disk_dg_chart2">DG, % time busy (DGBUSY)</choice>
    +                <choice value="disk_dg_chart3">DG, read/write KB (DGREAD/DGWRITE)</choice>
    +                <choice value="disk_dg_chart4">DG, block size KB (DGSIZE)</choice>
    +                <choice value="disk_dg_chart5">DG, read/write service time ms (DGREADSERV/DGWRITESERV)</choice>
    +                <choice value="disk_dg_chart6">DG, read/write per sec (DGREADS/DGWRITES)</choice>
    +                <choice value="disk_dg_chart7">DG, merge read/write per sec (DGREADMERGE/DGWRITEMERGE)</choice>
    +                <choice value="disk_dg_chart8">DG, time spent (ms) for I/O (DGIOTIME)</choice>
    +                <choice value="disk_dg_chart9">DG, back log time (ms) (DGBACKLOG)</choice>
    +                <choice value="disk_dg_chart10">DG, In flight I/O (DGINFLIGHT)</choice>
    +                <default>disk_dg_chart1</default>
    +                <change>
    +                    <condition value="disk_dg_chart1">
    +                        <set token="disk_dg_chart1">true</set>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart2">
    +                        <set token="disk_dg_chart2">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart3">
    +                        <set token="disk_dg_chart3">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart4">
    +                        <set token="disk_dg_chart4">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart5">
    +                        <set token="disk_dg_chart5">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart6">
    +                        <set token="disk_dg_chart6">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart7">
    +                        <set token="disk_dg_chart7">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart8">
    +                        <set token="disk_dg_chart8">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart9">
    +                        <set token="disk_dg_chart9">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart10"></unset>
    +                    </condition>
    +                    <condition value="disk_dg_chart10">
    +                        <set token="disk_dg_chart10">true</set>
    +                        <unset token="disk_dg_chart1"></unset>
    +                        <unset token="disk_dg_chart2"></unset>
    +                        <unset token="disk_dg_chart3"></unset>
    +                        <unset token="disk_dg_chart4"></unset>
    +                        <unset token="disk_dg_chart5"></unset>
    +                        <unset token="disk_dg_chart6"></unset>
    +                        <unset token="disk_dg_chart7"></unset>
    +                        <unset token="disk_dg_chart8"></unset>
    +                        <unset token="disk_dg_chart9"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$disk_dg_chart1$">
    +                <title></title>
    +                <search depends="$disk_dg_chart1$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dg*" host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| `extract_metrics("dgxfer dgread dgwrite dgsize")`
    +| stats max(dgxfer) as disk_total_iops max(dgread) as disk_read_KB_per_sec max(dgwrite) as disk_write_KB_per_sec max(dgsize) as disk_block_size_KB by _time, host, dimension_device
    +| eval disk_read_iops=(disk_read_KB_per_sec/disk_block_size_KB), disk_write_iops=(disk_write_KB_per_sec/disk_block_size_KB)
    +| stats sum(disk_*) as "disk_*" by _time, host
    +| timechart $span$ $statsmode$(disk_total_iops) as disk_total_iops, $statsmode$(disk_read_iops) as disk_read_iops $statsmode$(disk_write_iops) as disk_write_iops by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Transfers/s (IOPS)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dg*" host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| `extract_metrics("dgxfer dgread dgwrite dgsize")`
    +| stats max(dgxfer) as disk_total_iops max(dgread) as disk_read_KB_per_sec max(dgwrite) as disk_write_KB_per_sec max(dgsize) as disk_block_size_KB by _time, host, dimension_device
    +| eval disk_read_iops=(disk_read_KB_per_sec/disk_block_size_KB), disk_write_iops=(disk_write_KB_per_sec/disk_block_size_KB)
    +| stats sum(disk_*) as "disk_*" by _time, host
    +| timechart $span$ $statsmode$(disk_total_iops) as disk_total_iops, $statsmode$(disk_read_iops) as disk_read_iops $statsmode$(disk_write_iops) as disk_write_iops by host
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart2$">
    +                <title></title>
    +                <search depends="$disk_dg_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbusy" host=$host-prefilter$ $host_query$ $device$ by host, dimension_device span=1m
    +| `$timefilter$`
    +| timechart $span$ $statsmode$(value) as disk_busy_time_pct by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Pct busy (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbusy" host=$host-prefilter$ $host_query$ $device$ by host, dimension_device span=1m
    +| `$timefilter$`
    +| timechart $span$ $statsmode$(value) as disk_busy_time_pct by host
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart3$">
    +                <title></title>
    +                <search depends="$disk_dg_chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgread" OR metric_name="os.unix.nmon.storage.dgwrite") host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| `extract_metrics("dgread dgwrite")`
    +| stats values(dgread) as disk_read_KB_per_sec, values(dgwrite) as disk_write_KB_per_sec by _time, host, dimension_device
    +| timechart $span$ $statsmode$(disk_read_KB_per_sec) as disk_read_KB_per_sec, $statsmode$(disk_write_KB_per_sec) as disk_write_KB_per_sec by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">KB/s</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgread" OR metric_name="os.unix.nmon.storage.dgwrite") host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| `extract_metrics("dgread dgwrite")`
    +| stats values(dgread) as disk_read_KB_per_sec, values(dgwrite) as disk_write_KB_per_sec by _time, host, dimension_device
    +| timechart $span$ $statsmode$(disk_read_KB_per_sec) as disk_read_KB_per_sec, $statsmode$(disk_write_KB_per_sec) as disk_write_KB_per_sec by host
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart4$">
    +                <title></title>
    +                <search depends="$disk_dg_chart4$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgsize" host=$host-prefilter$ $host_query$ $device$ by host, dimension_device span=1m
    +| `$timefilter$`
    +| timechart $span$ $statsmode$(value) as disk_block_size_KB by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Kilobytes (KB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgsize" host=$host-prefilter$ $host_query$ $device$ by host, dimension_device span=1m
    +| `$timefilter$`
    +| timechart $span$ $statsmode$(value) as disk_block_size_KB by host
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart5$">
    +                <title></title>
    +                <search depends="$disk_dg_chart5$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreadserv" OR metric_name="os.unix.nmon.storage.dgwriteserv") host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| `extract_metrics("dgreadserv dgwriteserv")`
    +| stats values(dgreadserv) as disk_read_service_time_ms, values(dgwriteserv) as disk_write_service_time_ms by _time, host, dimension_device
    +| timechart $span$ $statsmode$(disk_read_service_time_ms) as disk_read_service_time_ms, $statsmode$(disk_write_service_time_ms) as disk_write_service_time_ms by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Milliseconds (ms)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreadserv" OR metric_name="os.unix.nmon.storage.dgwriteserv") host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| `extract_metrics("dgreadserv dgwriteserv")`
    +| stats values(dgreadserv) as disk_read_service_time_ms, values(dgwriteserv) as disk_write_service_time_ms by _time, host, dimension_device
    +| timechart $span$ $statsmode$(disk_read_service_time_ms) as disk_read_service_time_ms, $statsmode$(disk_write_service_time_ms) as disk_write_service_time_ms by host
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart6$">
    +                <title></title>
    +                <search depends="$disk_dg_chart6$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreads" OR metric_name="os.unix.nmon.storage.dgwrites") host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| `extract_metrics("dgreads dgwrites")`
    +| timechart $span$ $statsmode$(dgreads) as disk_read_sec, $statsmode$(dgwrites) as disk_write_sec by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">read/write per sec</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreads" OR metric_name="os.unix.nmon.storage.dgwrites") host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| `extract_metrics("dgreads dgwrites")`
    +| timechart $span$ $statsmode$(dgreads) as disk_read_sec, $statsmode$(dgwrites) as disk_write_sec by host
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart7$">
    +                <title></title>
    +                <search depends="$disk_dg_chart7$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreadmerge" OR metric_name="os.unix.nmon.storage.dgwritemerge") host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| `extract_metrics("dgreadmerge dgwritemerge")`
    +| timechart $span$ $statsmode$(dgreadmerge) as disk_merge_read_sec, $statsmode$(dgwritemerge) as disk_merge_write_sec by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">read/write per sec</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.dgreadmerge" OR metric_name="os.unix.nmon.storage.dgwritemerge") host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| `extract_metrics("dgreadmerge dgwritemerge")`
    +| timechart $span$ $statsmode$(dgreadmerge) as disk_merge_read_sec, $statsmode$(dgwritemerge) as disk_merge_write_sec by host
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart8$">
    +                <title></title>
    +                <search depends="$disk_dg_chart8$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgiotime" host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| timechart $span$ $statsmode$(value) as disk_time_spent_for_io_ms by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Milliseconds (ms)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgiotime" host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| timechart $span$ $statsmode$(value) as disk_time_spent_for_io_ms by host
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart9$">
    +                <title></title>
    +                <search depends="$disk_dg_chart9$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbacklog" host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| timechart $span$ $statsmode$(value) as disk_backlog_time_ms by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Milliseconds (ms)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dgbacklog" host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| timechart $span$ $statsmode$(value) as disk_backlog_time_ms by host
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$disk_dg_chart10$">
    +                <title></title>
    +                <search depends="$disk_dg_chart10$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dginflight" host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| timechart $span$ $statsmode$(value) as disk_in_flight_io by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Tranfers/sec (IOPS)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?earliest=$timerange.earliest$&latest=$timerange.latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.dginflight" host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| timechart $span$ $statsmode$(value) as disk_in_flight_io by host
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_DISK.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_DISK.xml
    new file mode 100644
    index 0000000..6f94863
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_DISK.xml
    @@ -0,0 +1,522 @@
    +<form stylesheet="ui_simple.css,panel_decoration.css" script="modal.js" isVisible="true" version="1.1" theme="dark">
    +    <label>UI DISK, global user interface for disk* metrics</label>
    +    <description>Storage disk metrics on a per host/logical device basis</description>
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input id="device" type="multiselect" token="device" searchWhenChanged="true">
    +            <label>Disks Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ $host$
    +| stats count by dimension_device | dedup dimension_device | sort 0 dimension_device</query>
    +            </search>
    +            <valuePrefix>dimension_device="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <initialValue>*</initialValue>
    +            <choice value="*">ALL Devices</choice>
    +            <fieldForLabel>dimension_device</fieldForLabel>
    +            <fieldForValue>dimension_device</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="fields *">Single Series</choice>
    +            <choice value="stats avg(value) as value by _time, host | eval dimension_device=&quot;aggreg_device&quot;, frameID=&quot;aggreg_frameID&quot;">Average by Time interval, host</choice>
    +            <choice value="stats avg(value) as value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_device&quot;, frameID=&quot;aggreg_frameID&quot;, host=&quot;aggreg_frameID&quot;">Average by Time interval</choice>
    +            <choice value="stats max(value) as value by _time, host | eval dimension_device=&quot;aggregate&quot;, frameID=&quot;aggreg_frameID&quot;">Max by Time interval, host</choice>
    +            <choice value="stats max(value) as value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_device&quot;, frameID=&quot;aggreg_frameID&quot;, host=&quot;aggreg_frameID&quot;">Max by Time interval</choice>
    +            <choice value="stats sum(value) as value by _time, host | eval dimension_device=&quot;aggregate&quot;, frameID=&quot;aggreg_frameID&quot;">Sum by Time interval, host</choice>
    +            <choice value="stats sum(value) as value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_device&quot;, frameID=&quot;aggreg_frameID&quot;, host=&quot;aggreg_frameID&quot;">Sum by Time interval</choice>
    +            <default>fields *</default>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <row>
    +        <panel>
    +            <input id="metric_name" type="dropdown" token="metric_name" searchWhenChanged="true">
    +                <label>Metric:</label>
    +                <default></default>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate_metric">
    +                    <query>fields metric_name | sort 0 metric_name</query>
    +                </search>
    +                <fieldForLabel>metric_name</fieldForLabel>
    +                <fieldForValue>metric_name</fieldForValue>
    +                <change>
    +                    <condition value="os.unix.nmon.storage.diskbsize">
    +                        <set token="metric_title">Average data transfer size (block size) for read/write operations</set>
    +                        <set token="metric_desc">Average data transfer size (block size) for read/write operations</set>
    +                        <set token="metric_is_set">True</set>
    +                    </condition>
    +                    <condition value="os.unix.nmon.storage.diskbusy">
    +                        <set token="metric_title">Percentage of time a physical disk was active (iostat % tm_act)</set>
    +                        <set token="metric_desc">Percentage of time a physical disk was active (iostat % tm_act)</set>
    +                        <set token="metric_is_set">True</set>
    +                    </condition>
    +                    <condition value="os.unix.nmon.storage.diskread">
    +                        <set token="metric_title">Disk Read Data Rate</set>
    +                        <set token="metric_desc">Disk Read Data Rate</set>
    +                        <set token="metric_is_set">True</set>
    +                    </condition>
    +                    <condition value="os.unix.nmon.storage.diskwrite">
    +                        <set token="metric_title">Disk Write Data Rate</set>
    +                        <set token="metric_desc">Disk Write Data Rate</set>
    +                        <set token="metric_is_set">True</set>
    +                    </condition>
    +                    <condition value="os.unix.nmon.storage.diskxfer">
    +                        <set token="metric_title">Disk I/O Operations per second (IOPS, iostat tps)</set>
    +                        <set token="metric_desc">Disk I/O Operations per second (IOPS, iostat tps)</set>
    +                        <set token="metric_is_set">True</set>
    +                    </condition>
    +                    <condition value="os.unix.nmon.storage.disksvctm">
    +                        <set token="metric_title">(ms) Average service time per disk</set>
    +                        <set token="metric_desc">(ms) Average service time per disk</set>
    +                        <set token="metric_is_set">True</set>
    +                    </condition>
    +                    <condition value="os.unix.nmon.storage.diskwaittm">
    +                        <set token="metric_title">(ms) Average wait time per disk</set>
    +                        <set token="metric_desc">(ms) Average wait time per disk</set>
    +                        <set token="metric_is_set">True</set>
    +                    </condition>
    +                    <condition>
    +                        <unset token="metric_title"></unset>
    +                        <unset token="metric_desc"></unset>
    +                        <unset token="metric_is_set"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row depends="$host$ $device$" rejects="$metric_is_set$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please select the metric in the metric selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$host$" rejects="$device$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please select associated devices to be analysed in the device selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ################################ -->
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for disks statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/drive.png" alt="drive"/>
    +                                    <h1>disk metrics $metric_title$
    +                                        <br />$metric_name$</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Metrics &amp; dimensions:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>dimension_device:</b> logical device name</li>
    +                                            <li><b>value:</b> value for this metric</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Help:</h1>From the Nmon FAQ: <a target="_blank" href="http://nmon.sourceforge.net/pmwiki.php?n=Site.NmonFAQ" >http://nmon.sourceforge.net/pmwiki.php?n=Site.NmonFAQ</a>
    +
    +                                </div>
    +
    +                                <br />
    +
    +                                <div class="list">
    +                                    <lu>
    +                                        <li><b>DISKGBUSY</b> highlights which disks are slowing you down</li>
    +                                        <li><b>DISKGREAD</b> and <b>DISKGWRITE</b> highlights how much data you are shifting</li>
    +                                    </lu>
    +                                </div>
    +
    +                                <div class="list">
    +                                    <lu>
    +                                        <li><b>DISKGXFER</b> highlight is you are approaching the Disk seek limits and adapter operation limits</li>
    +                                        <li><b>DISKGSIZE</b> highlights if your application is doing silly small boxes</li>
    +                                    </lu>
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_device)%20as%20dimension_device%20where%20%60nmon_metrics_index%60%20metric_name%3D$metric_name$%20host%3D*%20by%20host" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3D$metric_name$%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">mstats raw query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_DISK_spl" class="tryitbtnxl">HOWTO Interface for disks»
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=DISKS%20STATISTICS" class="tryitbtnxl">Disks Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.diskbusy%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.storage.diskbusy »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.diskxfer%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.storage.diskxfer »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.diskread%20OR%20metric_name%3Dos.unix.nmon.storage.diskwrite%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.storage.diskread/write »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate_metric">
    +        <query>| mcatalog values(metric_name) as metrics where `nmon_metrics_index` metric_name="os.unix.nmon.storage.disk*" $osfilter$
    +| rename metrics as metric_name
    +| mvexpand metric_name | fields metric_name | sort 0 metric_name</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.storage.disk*" $osfilter$ by host, dimension_device
    +| `mapping_frameID`
    +| stats count by frameID, host, dimension_device | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <title>$metric_title$</title>
    +                <search id="tablestats" depends="$metric_is_set$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=$metric_name$ host=$host-prefilter$ $host_query$ $device$ by dimension_device host span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| stats max(value) as max_value, avg(value) as avg_value, min(value) as min_value, sparkline($statsmode$(value)) As sparkline by host, dimension_device
    +| sort limit=0 host
    +| foreach *_value [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]
    +| fields host,dimension_device,max_value, avg_value, min_value,sparkline | eval avg_value=round(avg_value,2)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="disk">
    +            <title>Disks statistics</title>
    +            <chart>
    +                <search id="timechart" depends="$metric_is_set$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=$metric_name$ host=$host-prefilter$ $host_query$ $device$ by dimension_device host span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| eval key=host . ":" . dimension_device
    +| timechart $span$ limit=0 useother=f $statsmode$(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KBytes per transfer</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_FC.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_FC.xml
    new file mode 100644
    index 0000000..8b90cf7
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_FC.xml
    @@ -0,0 +1,504 @@
    +<form script="modal.js" stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI FC, Fiber Channel Adapters Read/Write KB/s transfer, In/Out I/O transfer</label>
    +    <description>User Interface for the FC monitor</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input id="device" type="multiselect" token="device" searchWhenChanged="true">
    +            <label>Disks Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ $host$
    +| stats count by dimension_device | dedup dimension_device | sort 0 dimension_device</query>
    +            </search>
    +            <valuePrefix>dimension_device="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <initialValue>*</initialValue>
    +            <choice value="*">ALL Devices</choice>
    +            <fieldForLabel>dimension_device</fieldForLabel>
    +            <fieldForValue>dimension_device</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="fields *">Single Series</choice>
    +            <choice value="stats dedup_splitvals=t avg(value) AS value by _time, host, dimension_device | eval dimension_device=&quot;aggreg_dimension_device&quot; | eval frameID=&quot;aggreg_frameID&quot;">Average by Time interval, host</choice>
    +            <choice value="stats dedup_splitvals=t avg(value) AS value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_dimension_device&quot; | eval frameID=&quot;aggreg_frameID&quot;">Average by Time interval</choice>
    +            <choice value="stats dedup_splitvals=t max(value) AS value by _time, host, dimension_device | eval dimension_device=&quot;aggregate&quot; | eval frameID=&quot;aggreg_frameID&quot;">Max by Time interval, host</choice>
    +            <choice value="stats dedup_splitvals=t max(value) AS value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_dimension_device&quot; | eval frameID=&quot;aggreg_frameID&quot;">Max by Time interval</choice>
    +            <choice value="stats dedup_splitvals=t sum(value) AS value by _time, host, dimension_device | eval dimension_device=&quot;aggregate&quot; | eval frameID=&quot;aggreg_frameID&quot;">Sum by Time interval, host</choice>
    +            <choice value="stats dedup_splitvals=t sum(value) AS value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_dimension_device&quot; | eval frameID=&quot;aggreg_frameID&quot;">Sum by Time interval</choice>
    +            <default>fields *</default>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +        <input type="checkbox" token="charting" searchWhenChanged="true">
    +            <label>Charting:</label>
    +            <default>fields *</default>
    +            <choice value="fields *">On</choice>
    +        </input>
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row depends="$host$" rejects="$device$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please select associated devices to be analysed in the device selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for fiber channel adapters statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/network.png" alt="NET"/>
    +                                    <h1>Fiber channel adapters statistics
    +                                        <br />(os.unix.nmon.adapters.fc*)</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Metrics &amp; dimensions:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>dimension_device:</b> Name of the fiber interface</li>
    +                                            <li><b>value:</b> Data rate in KBytes/sec or Total I/O operations (tps) depending on the associated device</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_device)%20as%20dimension_device%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.adapters.fc*%20host%3D*" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.adapters.fc*%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_Nmon_FC" class="tryitbtnxl">Fiber Channel interface »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_device)%20as%20dimension_device%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.adapters.ioadapt%20host%3D*" class="tryitbtnxl">os.unix.nmon.adapters.ioadapt »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.adapters.fc*" by host, dimension_device
    +| `mapping_frameID`
    +| stats count by frameID, host, dimension_device | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Read/Write Operations Table Stats (KB/s)</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.fcread OR metric_name=os.unix.nmon.adapters.fcwrite host=$host-prefilter$ $host_query$ $device$ by host, dimension_device span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| stats max(value) As max_value, avg(value) As avg_value, min(value) As min_value, sparkline(max(value)) As sparkline by host, dimension_device
    +| foreach *_value [ eval &lt;&lt;FIELD&gt;&gt;=round(&lt;&lt;FIELD&gt;&gt;, 0) ]
    +| sort limit=0 host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Total I/O Operations Table Stats (tps)</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.fcxfer* $host$ $device$ by host, dimension_device span=1m
    +| `$timefilter$`
    +| $frameID_query$
    +| $aggregate$
    +| stats max(value) As max_value, avg(value) As avg_value, min(value) As min_value, sparkline(max(value)) As sparkline by host, dimension_device
    +| foreach *_value [ eval &lt;&lt;FIELD&gt;&gt;=round(&lt;&lt;FIELD&gt;&gt;, 0) ]
    +| sort limit=0 host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row depends="$charting$">
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>area</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>stacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row depends="$charting$">
    +        <panel>
    +
    +            <input type="link" token="chart_linkinput">
    +                <label></label>
    +                <choice value="link_chart1">Read / Write transfer rate (KB/sec)</choice>
    +                <choice value="link_chart2">In/Out I/O transfer</choice>
    +                <default>link_chart1</default>
    +                <change>
    +                    <condition value="link_chart1">
    +                        <set token="link_chart1">true</set>
    +                        <unset token="link_chart2"></unset>
    +                    </condition>
    +                    <condition value="link_chart2">
    +                        <set token="link_chart2">true</set>
    +                        <unset token="link_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$link_chart1$">
    +                <title></title>
    +                <search depends="$link_chart1$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.fcread OR metric_name=os.unix.nmon.adapters.fcwrite $host$ $device$ by host, dimension_device span=1m
    +| `$timefilter$`
    +| $frameID_query$
    +| $aggregate$
    +| eval key = host . ":" . dimension_device
    +| timechart $span$ limit=0 useother=f $statsmode$(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Kbytes/sec</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +            <chart depends="$link_chart2$">
    +                <title></title>
    +                <search depends="$link_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.fcxfer* $host$ $device$ by host, dimension_device span=1m
    +| `$timefilter$`
    +| $frameID_query$
    +| $aggregate$
    +| eval key = host . ":" . dimension_device
    +| timechart $span$ limit=0 useother=f $statsmode$(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">I/O per Second</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_FILE.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_FILE.xml
    new file mode 100644
    index 0000000..ebed3ad
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_FILE.xml
    @@ -0,0 +1,467 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI FILE, Kernel file statistics: per-second frequency of selected file and the TTY statistics</label>
    +    <description>User Interface for the FILE monitor</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="tablestats">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.file.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, host, value
    +| chart useother=f limit=0 avg(value) as value by host, metric
    +| foreach * [ eval &lt;&lt;FIELD&gt;&gt; = if('&lt;&lt;FIELD&gt;&gt;'>0, round('&lt;&lt;FIELD&gt;&gt;', 2), '&lt;&lt;FIELD&gt;&gt;' ) ]</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for FILE statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="process"/>
    +                                    <h1>Kernel file statistics: per-second frequency of selected file and the TTY statistics (FILE)</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main metrics/fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Readch:</b> The amount of bytes read per second through the read system call over the monitoring interval</li>
    +                                            <li><b>Writech:</b> The amount of bytes written per second through the write system call over the monitoring interval</li>
    +                                            <li><b>Rawin:</b> The amount of raw bytes read per second from TTYs over the monitoring interval</li>
    +                                            <li><b>Ttyout:</b> The amount of bytes written to TTYs per second over the monitoring interval</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Igets:</b> The number of calls per second to the inode lookup routines over the monitoring interval</li>
    +                                            <li><b>Namei:</b> The number of calls per second to the path name lookup routines over the monitoring interval</li>
    +                                            <li><b>Dirblk:</b> The number of directory blocks scanned per second by the directory search routine over the monitoring interval</li>
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon:performance:cpu%20type%3DFILE" class="tryitbtnxl">Explore RAW DATA »
    +                                    </a>
    +
    +                                    <a target="_blank" href="pivot?model=%2FservicesNS%2Fnobody%2Fnmon%2Fdatamodel%2Fmodel%2FNMON_Data_FILE" class="tryitbtnxl">PIVOT Data model »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=PROCESSES%20STATISTICS" class="tryitbtnxl">Processes Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.file.*" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <title>FILE - Kernel Statistics Table Stats</title>
    +                <search base="tablestats">
    +                    <query>fields host,readch,writech,spk_readch,spk_writech</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="spk_readch">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="sparkline" field="spk_writech">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="readch">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="writech">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>FILE - Kernel Statistics Table Stats</title>
    +                <search base="tablestats">
    +                    <query>fields host,iget,namei,dirblk,tty* by host</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="iget">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="namei">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="dirblk">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="ttycanch">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="ttyoutch">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="ttyrawch">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Kernel file statistics</title>
    +
    +            <input type="link" token="linkinput">
    +                <label></label>
    +                <choice value="chart1">FILE - Read/Write system calls</choice>
    +                <choice value="chart2">FILE - Other statistics</choice>
    +                <default>chart1</default>
    +                <change>
    +                    <condition value="chart1">
    +                        <set token="chart1">true</set>
    +                        <unset token="chart2"></unset>
    +                    </condition>
    +                    <condition value="chart2">
    +                        <set token="chart2">true</set>
    +                        <unset token="chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$chart1$">
    +                <title></title>
    +                <search depends="$chart1$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.file.readch OR metric_name=os.unix.nmon.kernel.file.writech host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval key = host . ":" . metric
    +| timechart $span$ useother=f limit=0 $statsmode$(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rate/Sec</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart2$">
    +                <title></title>
    +                <search depends="$chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.file.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval key = host . ":" . metric
    +| timechart $span$ useother=f limit=0 $statsmode$(value) As value by key
    +| fields _time, *iget*, *namei*, *dirblk*, *ttycanch*, *ttyoutch*, *ttyrawch*</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rate/Sec</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_IOADAPT.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_IOADAPT.xml
    new file mode 100644
    index 0000000..6ab3489
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_IOADAPT.xml
    @@ -0,0 +1,498 @@
    +<form script="modal.js" stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI IOADAPT, Adapters Read/Write / Total Operations</label>
    +    <description>User Interface for the IOADAPT monitor</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input id="device" type="multiselect" token="device" searchWhenChanged="true">
    +            <label>Disks Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ $host$
    +| stats count by dimension_device | dedup dimension_device | sort 0 dimension_device</query>
    +            </search>
    +            <valuePrefix>dimension_device="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <initialValue>*</initialValue>
    +            <choice value="*">ALL Devices</choice>
    +            <fieldForLabel>dimension_device</fieldForLabel>
    +            <fieldForValue>dimension_device</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="fields *">Single Series</choice>
    +            <choice value="stats dedup_splitvals=t avg(value) AS value by _time, host, dimension_device | eval dimension_device=&quot;aggreg_dimension_device&quot; | eval frameID=&quot;aggreg_frameID&quot;">Average by Time interval, host</choice>
    +            <choice value="stats dedup_splitvals=t avg(value) AS value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_dimension_device&quot; | eval frameID=&quot;aggreg_frameID&quot;">Average by Time interval</choice>
    +            <choice value="stats dedup_splitvals=t max(value) AS value by _time, host, dimension_device | eval dimension_device=&quot;aggregate&quot; | eval frameID=&quot;aggreg_frameID&quot;">Max by Time interval, host</choice>
    +            <choice value="stats dedup_splitvals=t max(value) AS value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_dimension_device&quot; | eval frameID=&quot;aggreg_frameID&quot;">Max by Time interval</choice>
    +            <choice value="stats dedup_splitvals=t sum(value) AS value by _time, host, dimension_device | eval dimension_device=&quot;aggregate&quot; | eval frameID=&quot;aggreg_frameID&quot;">Sum by Time interval, host</choice>
    +            <choice value="stats dedup_splitvals=t sum(value) AS value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_dimension_device&quot; | eval frameID=&quot;aggreg_frameID&quot;">Sum by Time interval</choice>
    +            <default>fields *</default>
    +        </input>
    +        
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +        
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +    
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row depends="$host$" rejects="$device$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please select associated devices to be analysed in the device selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for fiber channel adapters statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/network.png" alt="NET"/>
    +                                    <h1>Adapters Read/Write / Total Operations
    +                                        <br />(os.unix.nmon.adapters.ioadapt)</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Metrics &amp; dimensions:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>dimension_device:</b> Name of the fiber interface (including read/write distinction for traffic, and/or the metric type)</li>
    +                                            <li><b>value:</b> Data rate in KBytes/sec or Total I/O operations (tps) depending on the associated device</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_device)%20as%20dimension_device%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.adapters.ioadapt%20host%3D*" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.adapters.ioadapt%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_Nmon_FC" class="tryitbtnxl">Fiber Channel interface »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.adapters.fc*%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">os.unix.nmon.adapters.fc* »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.adapters.ioadapt" by host, dimension_device
    +| `mapping_frameID`
    +| stats count by frameID, host, dimension_device | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="tablestats">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.ioadapt host=$host-prefilter$ $host_query$ $device$ by host, dimension_device span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| stats max(value) As max_value, avg(value) As avg_value, min(value) As min_value, sparkline(max(value)) As sparkline by host, dimension_device
    +| foreach *_value [ eval &lt;&lt;FIELD&gt;&gt;=round(&lt;&lt;FIELD&gt;&gt;, 0) ]
    +| sort limit=0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Read/Write Operations Table Stats (KB/s)</title>
    +                <search base="tablestats">
    +                    <query>| where ( dimension_device LIKE "%KB/s%")</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Total I/O Operations Table Stats (tps)</title>
    +                <search base="tablestats">
    +                    <query>| where ( dimension_device LIKE "%tps%")</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>area</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>stacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Adapters statistics</title>
    +
    +            <input type="link" token="chart_linkinput">
    +                <label></label>
    +                <choice value="link_chart1">Data Rate (Kbytes/sec)</choice>
    +                <choice value="link_chart2">Total I/O Operations (tps)</choice>
    +                <default>link_chart1</default>
    +                <change>
    +                    <condition value="link_chart1">
    +                        <set token="link_chart1">true</set>
    +                        <unset token="link_chart2"></unset>
    +                    </condition>
    +                    <condition value="link_chart2">
    +                        <set token="link_chart2">true</set>
    +                        <unset token="link_chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$link_chart1$">
    +                <title></title>
    +                <search depends="$link_chart1$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.ioadapt host=$host-prefilter$ $host_query$ $device$ dimension_device=*KB* by host, dimension_device span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| stats $statsmode$(value) As value by _time,host,dimension_device
    +| eval key=host . ":" . dimension_device
    +| timechart $span$ limit=0 useother=f $statsmode$(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Kbytes/sec</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +            <chart depends="$link_chart2$">
    +                <title></title>
    +                <search depends="$link_chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.adapters.ioadapt host=$host-prefilter$ $host_query$ $device$ dimension_device=*tps* by host, dimension_device span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| eval key=host . ":" . dimension_device
    +| timechart $span$ limit=0 useother=f $statsmode$(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">I/O per Second</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LOAD_AVG.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LOAD_AVG.xml
    new file mode 100644
    index 0000000..06e0bd8
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LOAD_AVG.xml
    @@ -0,0 +1,487 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI UPTIME Load average</label>
    +    <description>User Interface for the UPTIME load average external monitor statistics</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>avg</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Main search for form populating -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name=os.unix.nmon.system.uptime.load_average_1min OR metric_name=os.unix.nmon.system.uptime.load_average_5min OR metric_name=os.unix.nmon.system.uptime.load_average_15min $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                                    <h1>
    +                                        UPTIME load average statistics
    +                                        <br />
    +                                        (metric_name=os.unix.nmon.system.uptime.*)
    +                                    </h1>
    +
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    <i>The external UPTIME metric collection records the uptime command results with the system load averages for the past 1, 5, and 15 minutes.</i>
    +                                    <br />
    +                                    <i>These metrics are common to every supported operating systems.</i>
    +                                    <br />
    +                                    <b>uptime command man page:</b>
    +                                    <br />
    +                                    System load averages is the average number of processes that are either in a runnable or uninterruptable state.  A process in a runnable state is either using the CPU or waiting to use the  CPU.   A
    +                                    <br />
    +                                    process  in uninterruptable state is waiting for some I/O access, eg waiting for disk.  The averages are taken over the three time intervals.  Load averages are not normalized for the number of CPUs
    +                                    <br />
    +                                    in a system, so a load average of 1 means a single CPU system is loaded all the time while on a 4 CPU system it means it was idle 75% of the time.
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.system.uptime.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.system.uptime.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" class="tryitbtnxl">CPU Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUPTIME" class="tryitbtnxl">UPTIME events »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="baseSearch_loadaverage">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.system.uptime.load_average_1min OR metric_name=os.unix.nmon.system.uptime.load_average_5min OR metric_name=os.unix.nmon.system.uptime.load_average_15min host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| eval load_average_1min=case(metric_name=="os.unix.nmon.system.uptime.load_average_1min", value), load_average_5min=case(metric_name=="os.unix.nmon.system.uptime.load_average_5min", value), load_average_15min=case(metric_name=="os.unix.nmon.system.uptime.load_average_15min", value)
    +| `extract_metrics`
    +| eval {metric}=value
    +| fillnull value=0 load_average_1min load_average_5min load_average_15min
    +| timechart $span$ $statsmode$(load_average_1min) as load_average_1min, $statsmode$(load_average_5min) as load_average_5min, $statsmode$(load_average_15min) as load_average_15min</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- ################################ -->
    +
    +    <row>
    +        <panel>
    +            <single>
    +                <search base="baseSearch_loadaverage">
    +                    <query>fields _time, load_average_1min | where isnotnull(load_average_1min)</query>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="underLabel">load average 1min</option>
    +                <option name="useColors">1</option>
    +            </single>
    +            <single>
    +                <search base="baseSearch_loadaverage">
    +                    <query>fields _time, load_average_5min | where isnotnull(load_average_5min)</query>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="underLabel">load average 5min</option>
    +                <option name="useColors">1</option>
    +            </single>
    +            <single>
    +                <search base="baseSearch_loadaverage">
    +                    <query>fields _time, load_average_15min | where isnotnull(load_average_15min)</query>
    +                </search>
    +                <option name="colorBy">trend</option>
    +                <option name="drilldown">all</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="trendColorInterpretation">inverse</option>
    +                <option name="underLabel">load average 15min</option>
    +                <option name="useColors">1</option>
    +            </single>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <table>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.system.uptime.load_average_1min OR metric_name=os.unix.nmon.system.uptime.load_average_5min OR metric_name=os.unix.nmon.system.uptime.load_average_15min host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval {metric}=value
    +| fillnull value=0 load_average_1min load_average_5min load_average_15min
    +| stats latest(load_average_1min) as current_load_average_1min, avg(load_average_1min) as avg_load_average_1min, max(load_average_1min) as max_load_average_1min,
    +latest(load_average_5min) as current_load_average_5min, avg(load_average_5min) as avg_load_average_5min, max(load_average_5min) as max_load_average_5min,
    +latest(load_average_15min) as current_load_average_15min, avg(load_average_15min) as avg_load_average_15min, max(load_average_15min) as max_load_average_15min,
    +sparkline(avg(load_average_5min),) As sparkline by host
    +| foreach *load* [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]
    +| eval "load average 1 min" =  "Current: " . current_load_average_1min . " Average: " . avg_load_average_1min . " Max: " . max_load_average_1min
    +| eval "load average 5 min" = "Current: " . current_load_average_5min . " Average: " . avg_load_average_5min . " Max: " . max_load_average_5min
    +| eval "load average 15 min" = "Current: " . current_load_average_15min . " Average: " . avg_load_average_15min . " Max: " . max_load_average_15min
    +| lookup nmon_inventory hostname as host OUTPUT cpu_logicalcores
    +| fields host, cpu_logicalcores, "load average 1 min", "load average 5 min", "load average 15 min", sparkline</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="User (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Sys (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Wait (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="cpu (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>UPTIME load average over time</title>
    +
    +            <input type="checkbox" token="series_selection" searchWhenChanged="true">
    +              <label>Categories:</label>
    +              <choice value="load_average_1min*">load_average_1min</choice>
    +              <choice value="load_average_5min*">load_average_5min</choice>
    +              <choice value="load_average_15min*">load_average_15min</choice>
    +              <choice value="cpu_logicalcores*">cpu_logicalcores</choice>
    +              <default>load_average_1min*,load_average_5min*,load_average_15min*</default>
    +              <delimiter>,</delimiter>
    +            </input>
    +
    +            <chart>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.system.uptime.load_average_1min OR metric_name=os.unix.nmon.system.uptime.load_average_5min OR metric_name=os.unix.nmon.system.uptime.load_average_15min host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval {metric}=value
    +| fillnull value=0 load_average_1min load_average_5min load_average_15min
    +| lookup nmon_inventory hostname as host OUTPUT cpu_logicalcores
    +| timechart $span$ useother=f limit=0 $statsmode$(load_average_1min) as load_average_1min, $statsmode$(load_average_5min) as load_average_5min, $statsmode$(load_average_15min) as load_average_15min, latest(cpu_logicalcores) as cpu_logicalcores by host
    +| fields _time, $series_selection$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">load average</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.system.uptime.load_average_1min OR metric_name=os.unix.nmon.system.uptime.load_average_5min OR metric_name=os.unix.nmon.system.uptime.load_average_15min host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval {metric}=value
    +| fillnull value=0 load_average_1min load_average_5min load_average_15min
    +| lookup nmon_inventory hostname as host OUTPUT cpu_logicalcores
    +| timechart $span$ useother=f limit=0 $statsmode$(load_average_1min) as load_average_1min, $statsmode$(load_average_5min) as load_average_5min, $statsmode$(load_average_15min) as load_average_15min, latest(cpu_logicalcores) as cpu_logicalcores by host
    +| fields _time, $series_selection$</link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LPAR_AIX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LPAR_AIX.xml
    new file mode 100644
    index 0000000..616ca53
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LPAR_AIX.xml
    @@ -0,0 +1,550 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI LPAR, Micro-Partitions Virtual CPU Usage (AIX)</label>
    +    <description>User Interface for the LPAR monitor and IBM Micro-Partitions CPU usage statistics</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="fields *">Single Series</choice>
    +            <choice value="stats avg(*) AS &quot;*&quot;, avg(entitled) As entitled, avg(virtual_cpus) AS virtual_cpus by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Average by Time interval</choice>
    +            <choice value="stats avg(*) AS &quot;*&quot;, avg(entitled) As entitled, avg(virtual_cpus) AS virtual_cpus by _time,frameID | eval host='frameID'">Average by Time interval,frameID</choice>
    +            <choice value="stats max(*) AS &quot;*&quot;, max(entitled) As entitled, max(virtual_cpus) AS virtual_cpus by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Max by Time interval</choice>
    +            <choice value="stats max(*) AS &quot;*&quot;, max(entitled) As entitled, max(virtual_cpus) AS virtual_cpus by _time,frameID | eval host='frameID'">Max by Time interval,frameID</choice>
    +            <choice value="stats sum(*) AS &quot;*&quot;, sum(entitled) As entitled, sum(virtual_cpus) AS virtual_cpus by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Sum by Time interval</choice>
    +            <choice value="stats sum(*) AS &quot;*&quot;, sum(entitled) As entitled, sum(virtual_cpus) AS virtual_cpus by _time,frameID | eval host='frameID'">Sum by Time interval,frameID</choice>
    +            <default>fields *</default>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="indicator" searchWhenChanged="true">
    +            <label>Show CPU load by:</label>
    +            <default>`def_lpar_load_vp_aix_cores`</default>
    +            <choice value="`def_lpar_load_vp_aix_cores`">Usage vs VirtualCPUs</choice>
    +            <choice value="`def_lpar_load_vp_aix_percent`">Usage vs VirtualCPUs % Usage</choice>
    +            <choice value="`def_lpar_load_ec_aix_cores`">Usage vs Entitled</choice>
    +            <choice value="`def_lpar_load_ec_aix_percent`">Usage vs Entitled % usage</choice>
    +            <change>
    +                <condition value="`def_lpar_load_vp_aix_cores`">
    +                    <set token="unity_label">Virtual CPUs (nbr)</set>
    +                    <set token="unity_minilabel">Cores</set>
    +                    <set token="metric_datafield">lpar_load_cores</set>
    +                    <set token="show_additional_monitors">true</set>
    +                </condition>
    +                <condition value="`def_lpar_load_vp_aix_percent`">
    +                    <set token="unity_label">Percentage of capacity (%)</set>
    +                    <set token="unity_minilabel">%</set>
    +                    <set token="metric_datafield">lpar_load_percent</set>
    +                    <unset token="show_additional_monitors"></unset>
    +                    <unset token="form.timechart_selection"></unset>
    +                </condition>
    +                <condition value="`def_lpar_load_ec_aix_cores`">
    +                    <set token="unity_label">Virtual CPUs (nbr)</set>
    +                    <set token="unity_minilabel">Cores</set>
    +                    <set token="metric_datafield">lpar_load_cores</set>
    +                    <set token="show_additional_monitors">true</set>
    +                </condition>
    +                <condition value="`def_lpar_load_ec_aix_percent`">
    +                    <set token="unity_label">Percentage of capacity (%)</set>
    +                    <set token="unity_minilabel">%</set>
    +                    <set token="metric_datafield">lpar_load_percent</set>
    +                    <unset token="show_additional_monitors"></unset>
    +                    <unset token="form.timechart_selection"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.lpar.*" by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- used to smartly generate the dynamic timechart query -->
    +
    +    <search id="timechart_query_generator">
    +        <query>| makeresults
    +| eval metric_datafield="$metric_datafield$", timechart_selection="$timechart_selection$", statsmode="$statsmode$"
    +| eval timechart_query=case(
    +timechart_selection=="none", statsmode . "(" . metric_datafield . ") as " . metric_datafield,
    +timechart_selection=="entitled", statsmode . "(" . metric_datafield . ") as " . metric_datafield . " " . statsmode . "(" . "entitled" . ") as entitled",
    +timechart_selection=="virtualCPUs", statsmode . "(" . metric_datafield . ") as " . metric_datafield . " " . statsmode . "(" . "virtualCPUs" . ") as virtualCPUs",
    +timechart_selection=="entitled,virtualCPUs", statsmode . "(" . metric_datafield . ") as " . metric_datafield . " " . statsmode . "(" . "entitled" . ") as entitled " . statsmode . "(" . "virtualCPUs" . ") as virtualCPUs" )
    +| fields timechart_query
    +        </query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition>
    +                <set token="timechart_query">$result.timechart_query$</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- Global Search -->
    +
    +    <search id="Global">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_lpar_AIX_metric_filters` host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| $indicator$
    +| `mapping_frameID`
    +| $aggregate$
    +| sort limit=0 _time
    +| where $metric_datafield$&gt;0
    +| stats min($metric_datafield$) As min_$metric_datafield$, avg($metric_datafield$) As avg_$metric_datafield$, max($metric_datafield$) As max_$metric_datafield$, max(entitled) As entitled, max(virtualCPUs) As virtualCPUs, sparkline($statsmode$($metric_datafield$)) As sparkline by frameID,host
    +| sort limit=0 frameID | eval avg_$metric_datafield$=round(avg_$metric_datafield$,3)</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for LPAR statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                                    <h1>CPU global percentage statistics for IBM AIX partitions
    +                                    <br />
    +                                    (metric_name=os.unix.nmon.cpu.lpar.*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div>
    +                                    <i>The LPAR monitor contains IBM Power partitions specific CPU statistics.</i>
    +                                    <br />
    +                                    <i>These metrics are available only for IBM Pseries and partitions running AIX or PowerLinux.</i>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>raw metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>entitled:</b> Entitled capacity of the partition</li>
    +                                            <li><b>virtualCPUs:</b> Number of virtual processors in the LPAR definition</li>
    +                                            <li><b>VP_Idle_PCT/EC_Idle_PCT:</b> % of CPU time free, meaning not having task to do</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>VP_Sys_PCT/EC_Sys_PCT:</b> % of CPU time spent in kernel mode</li>
    +                                            <li><b>VP_User_PCT/EC_User_PCT:</b> % of CPU time spent in user mode</li>
    +                                            <li><b>VP_Wait_PCT/VP_Wait_PCT:</b> % of CPU time spent in waiting for resources</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <h1>calculated metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>lpar_load_cores:</b> partition CPU cores usage versus VP/EC</li>
    +                                            <li><b>lpar_load_percent:</b> partition CPU percentage usage versus VP/EC</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.cpu.lpar.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_load_vp_aix_cores%60" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_LPAR_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_Summary" class="tryitbtnxl">NMON SUMMARY Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_ANALYSER_AIX" class="tryitbtnxl">NMON ANALYSER Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" class="tryitbtnxl">CPU Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +
    +    <row>
    +        <panel>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats max(max_$metric_datafield$) AS max</query>
    +                </search>
    +                <option name="underLabel">Maximum Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">$unity_minilabel$</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats avg(avg_$metric_datafield$) AS avg | eval avg=round(avg,3)</query>
    +                </search>
    +                <option name="underLabel">Average Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">$unity_minilabel$</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats min(min_$metric_datafield$) AS min</query>
    +                </search>
    +                <option name="underLabel">Minimal Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">$unity_minilabel$</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <table>
    +                <search base="Global">
    +                    <query>foreach max_$metric_datafield$,avg_$metric_datafield$,min_$metric_datafield$ [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 3) ] | fields frameID,host,max_$metric_datafield$,avg_$metric_datafield$,min_$metric_datafield$,entitled,virtualCPUs,sparkline</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <drilldown target="search">
    +                    <link>search?earliest=$timerange.earliest$&amp;latest=$timerange.latest$&amp;q=| mstats avg(_value) as value where `nmon_metrics_index` `def_lpar_AIX_metric_filters` host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| $indicator$
    +| `mapping_frameID`
    +| $aggregate$
    +| sort limit=0 _time
    +| where $metric_datafield$&gt;0
    +| stats min($metric_datafield$) As min_$metric_datafield$, avg($metric_datafield$) As avg_$metric_datafield$, max($metric_datafield$) As max_$metric_datafield$, max(entitled) As entitled, max(virtualCPUs) As virtualCPUs, sparkline($statsmode$($metric_datafield$)) As sparkline by frameID,host
    +| sort limit=0 frameID | eval avg_$metric_datafield$=round(avg_$metric_datafield$,3)</link>
    +                </drilldown>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>Micro-Partitions Virtual CPUs statistics</title>
    +
    +            <input type="dropdown" token="timechart_selection" depends="$show_additional_monitors$" searchWhenChanged="true">
    +                <label>LPAR additional Series:</label>
    +                <default>none</default>
    +                <choice value="none">none</choice>
    +                <choice value="entitled">Entitled</choice>
    +                <choice value="virtualCPUs">VirtualCPUs</choice>
    +                <choice value="entitled,virtualCPUs">Entitled And VirtualCPUs</choice>
    +            </input>
    +
    +            <chart>
    +                <search id="timechart">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_lpar_AIX_metric_filters` host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| $indicator$
    +| `mapping_frameID`
    +| $aggregate$
    +| timechart $span$ useother=f limit=0 $timechart_query$ by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$unity_minilabel$</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.entitled  OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs6 host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| $indicator$
    +| `mapping_frameID`
    +| $aggregate$
    +| timechart $span$ useother=f limit=0 $timechart_query$ by host</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LPAR_AIX_poolconso.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LPAR_AIX_poolconso.xml
    new file mode 100644
    index 0000000..f87797f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LPAR_AIX_poolconso.xml
    @@ -0,0 +1,520 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI LPAR Pool, Pool Virtual CPU Usage (AIX)</label>
    +    <description>User Interface for the LPAR monitor and IBM PSeries Pools usage statistics</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +                <unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="device" type="multiselect" token="PoolID" searchWhenChanged="true">
    +            <label>Pool IDs: (0 for DefaultPool)</label>
    +            <search base="populate">
    +                <query>stats count by PoolID | dedup PoolID | sort 0 PoolID</query>
    +            </search>
    +            <valuePrefix>PoolID="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>PoolID</fieldForLabel>
    +            <fieldForValue>PoolID</fieldForValue>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="fields *">Single Series</choice>
    +            <choice value="stats avg(poolCPUs) AS poolCPUs, avg(lpar_pool_usage) AS lpar_pool_usage by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Average by Time interval</choice>
    +            <choice value="stats avg(poolCPUs) AS poolCPUs, avg(lpar_pool_usage) AS lpar_pool_usage by _time, frameID | eval host='frameID'">Average by Time interval,frameID</choice>
    +            <choice value="stats max(poolCPUs) AS poolCPUs, max(lpar_pool_usage) AS lpar_pool_usage by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Max by Time interval</choice>
    +            <choice value="stats max(poolCPUs) AS poolCPUs, max(lpar_pool_usage) AS lpar_pool_usage by _time, frameID | eval host='frameID'">Max by Time interval,frameID</choice>
    +            <choice value="stats sum(poolCPUs) AS poolCPUs, sum(lpar_pool_usage) AS lpar_pool_usage by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Sum by Time interval</choice>
    +            <choice value="stats sum(poolCPUs) AS poolCPUs, sum(lpar_pool_usage) AS lpar_pool_usage by _time, frameID | eval host='frameID'">Sum by Time interval,frameID</choice>
    +            <default>fields *</default>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="monitor" searchWhenChanged="true">
    +            <label>Show CPU load by:</label>
    +            <default>`def_lpar_pool_load_aix_cores`</default>
    +            <choice value="`def_lpar_pool_load_aix_cores`">VP Usage</choice>
    +            <choice value="`def_lpar_pool_load_aix_percent` | rename lpar_pool_usage_percent as lpar_pool_usage">VP Usage (% usage of capacity)</choice>
    +            <change>
    +                <condition value="`def_lpar_pool_load_aix_cores`">
    +                    <set token="unity_label">Virtual CPUs (nbr)</set>
    +                    <set token="unity_minilabel">Cores</set>
    +                    <set token="show_poolcpus_choice">true</set>
    +                </condition>
    +                <condition value="`def_lpar_pool_load_aix_percent` | rename lpar_pool_usage_percent as lpar_pool_usage">
    +                    <set token="unity_label">Percentage of capacity (%)</set>
    +                    <set token="unity_minilabel">%</set>
    +                    <unset token="show_poolcpus_choice"></unset>
    +                    <set token="form.show_poolcpus_input">false</set>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.lpar.PoolIdle" by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host
    +| lookup nmon_inventory hostname as host OUTPUT AIX_PoolID as PoolID
    +| fillnull value="0" PoolID</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Global Search -->
    +
    +    <search id="Global">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.poolCPUs" OR metric_name="os.unix.nmon.cpu.lpar.Pool_id" OR metric_name="os.unix.nmon.cpu.lpar.PoolIdle") host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| $monitor$
    +| `$timefilter$`
    +| `mapping_frameID`
    +| lookup nmon_inventory hostname as host OUTPUT AIX_PoolID as PoolID
    +| fillnull value="0" PoolID
    +| search $PoolID$
    +| $aggregate$
    +| sort limit=0 _time
    +| stats min(lpar_pool_usage) As min_usage, avg(lpar_pool_usage) As avg_usage, max(lpar_pool_usage) As max_usage, latest(poolCPUs) AS poolCPUs, sparkline($statsmode$(lpar_pool_usage)) As sparkline by frameID, host
    +| sort limit=0 frameID | eval avg_usage=round(avg_usage,3)
    +| lookup nmon_inventory hostname as host OUTPUT AIX_PoolID as PoolID
    +| fillnull value="0" PoolID</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for LPAR statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                                    <h1>CPU global percentage statistics for IBM PSeries Pools
    +                                    <br />
    +                                    (metric_name=os.unix.nmon.cpu.lpar.*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    <i>The LPAR monitor contains IBM Power partitions specific CPU statistics.</i>
    +                                    <br />
    +                                    <i>These metrics are available only for IBM Pseries and partitions running AIX or PowerLinux.</i>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main metrics/fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>max/avg/min_usage:</b> Virtual CPU / Percentage CPU usage of the Pool the partition belongs to</li>
    +                                            <li><b>Pool ID:</b> POOL Identifier that the lpar belongs to (the DefaultPool will always have a 0 ID)</li>
    +                                            <li><b>CPUs in Pool:</b> Number of Virtual Processor affected to the Pool the lpar belongs to</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.cpu.lpar.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_pool_load_aix_cores%60" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_LPAR_partitions_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_Summary" class="tryitbtnxl">NMON SUMMARY Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_ANALYSER_AIX" class="tryitbtnxl">NMON ANALYSER Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" class="tryitbtnxl">CPU Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.pools.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.pools.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats max(max_usage) AS max</query>
    +                </search>
    +                <option name="underLabel">Maximum Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">$unity_minilabel$</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats avg(avg_usage) AS avg | eval avg=round(avg,3)</query>
    +                </search>
    +                <option name="underLabel">Average Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">$unity_minilabel$</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats min(min_usage) AS min</query>
    +                </search>
    +                <option name="underLabel">Minimal Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">$unity_minilabel$</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <table>
    +                <search base="Global">
    +                    <query>foreach max_usage,avg_usage,min_usage [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 3) ] | fields host,frameID,PoolID,poolCPUs,max_usage,avg_usage,min_usage,sparkline</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>Shared Pool CPU statistics</title>
    +
    +            <input type="dropdown" token="show_poolcpus_input" searchWhenChanged="true" depends="$show_poolcpus_choice$">
    +                <label>Show number of CPUs in Pool:</label>
    +                <default>false</default>
    +                <choice value="false">false</choice>
    +                <choice value="true">true</choice>
    +                <change>
    +                    <condition value="true">
    +                        <set token="show_poolcpus">max(poolCPUs) AS poolCPUs</set>
    +                    </condition>
    +                    <condition value="false">
    +                        <set token="show_poolcpus"></set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart>
    +                <search id="timechart">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.poolCPUs" OR metric_name="os.unix.nmon.cpu.lpar.Pool_id" OR metric_name="os.unix.nmon.cpu.lpar.PoolIdle") host=$host-prefilter$ $host_query$ by metric_name, OStype, host span=1m
    +| $monitor$
    +| `$timefilter$`
    +| `mapping_frameID`
    +| lookup nmon_inventory hostname as host OUTPUT AIX_PoolID as PoolID
    +| fillnull value="0" PoolID
    +| search $PoolID$
    +| $aggregate$
    +| timechart useother=f limit=0 $span$ $statsmode$(lpar_pool_usage) as lpar_pool_usage $show_poolcpus$ by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$unity_label$</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LPAR_LINUX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LPAR_LINUX.xml
    new file mode 100644
    index 0000000..4ad5716
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LPAR_LINUX.xml
    @@ -0,0 +1,516 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI LPAR, Micro-Partitions Physical CPU Usage (PowerLinux)</label>
    +    <description>User Interface for the LPAR monitor and IBM Micro-Partitions CPU usage statistics</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +		    <change>
    +		        <unset token="form.refresh"></unset>
    +		    </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="fields *">Single Series</choice>
    +            <choice value="stats avg(*) AS &quot;*&quot;, avg(partition_entitled_capacity) As partition_entitled_capacity, avg(partition_active_processors) AS partition_active_processors by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Average by Time interval</choice>
    +            <choice value="stats avg(*) AS &quot;*&quot;, avg(partition_entitled_capacity) As partition_entitled_capacity, avg(partition_active_processors) AS partition_active_processors by _time,frameID | eval host='frameID'">Average by Time interval,frameID</choice>
    +            <choice value="stats max(*) AS &quot;*&quot;, max(partition_entitled_capacity) As partition_entitled_capacity, max(partition_active_processors) AS partition_active_processors by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Max by Time interval</choice>
    +            <choice value="stats max(*) AS &quot;*&quot;, max(partition_entitled_capacity) As partition_entitled_capacity, max(partition_active_processors) AS partition_active_processors by _time,frameID | eval host='frameID'">Max by Time interval,frameID</choice>
    +            <choice value="stats sum(*) AS &quot;*&quot;, sum(partition_entitled_capacity) As partition_entitled_capacity, sum(partition_active_processors) AS partition_active_processors by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Sum by Time interval</choice>
    +            <choice value="stats sum(*) AS &quot;*&quot;, sum(partition_entitled_capacity) As partition_entitled_capacity, sum(partition_active_processors) AS partition_active_processors by _time,frameID | eval host='frameID'">Sum by Time interval,frameID</choice>
    +            <default>fields *</default>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="indicator" searchWhenChanged="true">
    +            <label>Show CPU load by:</label>
    +            <default>`def_lpar_load_linux_cores`</default>
    +            <choice value="`def_lpar_load_linux_cores`">Usage in cores</choice>
    +            <choice value="`def_lpar_load_linux_percent`">Usage in percentage</choice>
    +            <change>
    +                <condition value="`def_lpar_load_linux_cores`">
    +                    <set token="unity_label">Virtual CPUs (nbr)</set>
    +                    <set token="unity_minilabel">Cores</set>
    +                    <set token="metric_datafield">lpar_load_cores</set>
    +                    <set token="show_additional_monitors">true</set>
    +                </condition>
    +                <condition value="`def_lpar_load_linux_percent`">
    +                    <set token="unity_label">Percentage of capacity (%)</set>
    +                    <set token="unity_minilabel">%</set>
    +                    <set token="metric_datafield">lpar_load_percent</set>
    +                    <unset token="show_additional_monitors"></unset>
    +                    <unset token="form.timechart_selection"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.lpar.*" OStype="Linux" by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- used to smartly generate the dynamic timechart query -->
    +
    +    <search id="timechart_query_generator">
    +        <query>| makeresults
    +| eval metric_datafield="$metric_datafield$", timechart_selection="$timechart_selection$", statsmode="$statsmode$"
    +| eval timechart_query=case(
    +timechart_selection=="none", statsmode . "(" . metric_datafield . ") as " . metric_datafield,
    +timechart_selection=="partition_entitled_capacity", statsmode . "(" . metric_datafield . ") as " . metric_datafield . " " . statsmode . "(" . "partition_entitled_capacity" . ") as partition_entitled_capacity",
    +timechart_selection=="partition_active_processors", statsmode . "(" . metric_datafield . ") as " . metric_datafield . " " . statsmode . "(" . "partition_active_processors" . ") as partition_active_processors",
    +timechart_selection=="partition_entitled_capacity,partition_active_processors", statsmode . "(" . metric_datafield . ") as " . metric_datafield . " " . statsmode . "(" . "partition_entitled_capacity" . ") as partition_entitled_capacity " . statsmode . "(" . "partition_active_processors" . ") as partition_active_processors" )
    +| fields timechart_query
    +        </query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition>
    +                <set token="timechart_query">$result.timechart_query$</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- Global Search -->
    +
    +    <search id="Global">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.PhysicalCPU" OR metric_name="os.unix.nmon.cpu.lpar.partition_active_processors" OR metric_name="os.unix.nmon.cpu.lpar.partition_entitled_capacity") host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| $indicator$
    +| `mapping_frameID`
    +| $aggregate$
    +| sort limit=0 _time
    +| where $metric_datafield$&gt;0
    +| stats min($metric_datafield$) As min_$metric_datafield$, avg($metric_datafield$) As avg_$metric_datafield$, max($metric_datafield$) As max_$metric_datafield$, max(partition_entitled_capacity) As partition_entitled_capacity, max(partition_active_processors) As partition_active_processors, sparkline($statsmode$($metric_datafield$)) As sparkline by frameID,host
    +| sort limit=0 frameID | eval avg_$metric_datafield$=round(avg_$metric_datafield$,3)</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for LPAR statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                                    <h1>CPU global percentage statistics for IBM Power Linux partitions</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    <i>The LPAR monitor contains IBM Power partitions specific CPU statistics.</i>
    +                                    <br />
    +                                    <i>These metrics are available only for IBM Pseries and partitions running AIX or PowerLinux.</i>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>raw metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>max/avg/min_usage:</b> CPU physical usage (in cores / percentage of capacity)</li>
    +                                            <li><b>partition_entitled_capacity:</b> Entitled capacity of the partition</li>
    +                                            <li><b>partition_active_processors:</b> Number of virtual processors in the LPAR definition</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.cpu.lpar.*&quot;%20host%3D&quot;*&quot;%20OStype%3D&quot;Linux&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20OStype%3D&quot;Linux&quot;%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20OStype%3D&quot;Linux&quot;%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_load_linux_cores%60" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_Summary" class="tryitbtnxl">NMON SUMMARY Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_ANALYSER_LINUX" class="tryitbtnxl">NMON ANALYSER Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" class="tryitbtnxl">CPU Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats max(max_$metric_datafield$) AS max</query>
    +                </search>
    +                <option name="underLabel">Maximum Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">$unity_minilabel$</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats avg(avg_$metric_datafield$) AS avg | eval avg=round(avg,3)</query>
    +                </search>
    +                <option name="underLabel">Average Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">$unity_minilabel$</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats min(min_$metric_datafield$) AS min</query>
    +                </search>
    +                <option name="underLabel">Minimal Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">$unity_minilabel$</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <table>
    +                <search base="Global">
    +                    <query>foreach max_$metric_datafield$,avg_$metric_datafield$,min_$metric_datafield$ [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 3) ] | fields frameID,host,max_$metric_datafield$,avg_$metric_datafield$,min_$metric_datafield$,partition_entitled_capacity,partition_active_processors,sparkline</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <drilldown target="search">
    +                    <link>search?earliest=$timerange.earliest$&amp;latest=$timerange.latest$&amp;q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.PhysicalCPU" OR metric_name="os.unix.nmon.cpu.lpar.partition_active_processors" OR metric_name="os.unix.nmon.cpu.lpar.partition_entitled_capacity") host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| $indicator$
    +| `mapping_frameID`
    +| $aggregate$
    +| sort limit=0 _time
    +| where $metric_datafield$&gt;0
    +| stats min($metric_datafield$) As min_$metric_datafield$, avg($metric_datafield$) As avg_$metric_datafield$, max($metric_datafield$) As max_$metric_datafield$, max(partition_entitled_capacity) As partition_entitled_capacity, max(partition_active_processors) As partition_active_processors, sparkline($statsmode$($metric_datafield$)) As sparkline by frameID,host
    +| sort limit=0 frameID | eval avg_$metric_datafield$=round(avg_$metric_datafield$,3)</link>
    +                </drilldown>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="timechart_selection" depends="$show_additional_monitors$" searchWhenChanged="true">
    +                <label>LPAR additional Series:</label>
    +                <default>none</default>
    +                <choice value="none">none</choice>
    +                <choice value="partition_entitled_capacity">partition_entitled_capacity</choice>
    +                <choice value="partition_active_processors">partition_active_processors</choice>
    +                <choice value="partition_entitled_capacity,partition_active_processors">partition_entitled_capacity And partition_active_processors</choice>
    +            </input>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>Micro-Partitions Physical CPUs statistics</title>
    +            <chart>
    +                <search id="timechart">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.PhysicalCPU" OR metric_name="os.unix.nmon.cpu.lpar.partition_active_processors" OR metric_name="os.unix.nmon.cpu.lpar.partition_entitled_capacity") host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| $indicator$
    +| `mapping_frameID`
    +| $aggregate$
    +| timechart $span$ useother=f limit=0 $timechart_query$ by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$unity_label$</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>search?earliest=$earliest$&amp;latest=$latest$&amp;q=| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.PhysicalCPU" OR metric_name="os.unix.nmon.cpu.lpar.partition_active_processors" OR metric_name="os.unix.nmon.cpu.lpar.partition_entitled_capacity") host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| $indicator$
    +| `mapping_frameID`
    +| $aggregate$
    +| timechart $span$ useother=f limit=0 $timechart_query$ by host</link>
    +                </drilldown>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LPAR_LINUX_poolconso.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LPAR_LINUX_poolconso.xml
    new file mode 100644
    index 0000000..5c23481
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_LPAR_LINUX_poolconso.xml
    @@ -0,0 +1,449 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI LPAR Pool, Pool Physical CPU Usage (PowerLinux)</label>
    +    <description>User Interface for the LPAR monitor and IBM PSeries Pools usage statistics</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +		    <change>
    +		        <unset token="form.refresh"></unset>
    +		    </change>
    +        </input>
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="fields *">Single Series</choice>
    +            <choice value="stats avg(*) AS &quot;*&quot; by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Average by Time interval</choice>
    +            <choice value="stats avg(*) AS &quot;*&quot; by _time,frameID | eval host='frameID'">Average by Time interval,frameID</choice>
    +            <choice value="stats max(*) AS &quot;*&quot; by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Max by Time interval</choice>
    +            <choice value="stats max(*) AS &quot;*&quot; by _time,frameID | eval host='frameID'">Max by Time interval,frameID</choice>
    +            <choice value="stats sum(*) AS &quot;*&quot; by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Sum by Time interval</choice>
    +            <choice value="stats sum(*) AS &quot;*&quot; by _time,frameID | eval host='frameID'">Sum by Time interval,frameID</choice>
    +            <default>fields *</default>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.lpar.pool_idle_time" by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Global Search -->
    +
    +    <search id="Global">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.smt_mode" OR metric_name="os.unix.nmon.cpu.lpar.pool_idle_time" OR metric_name="os.unix.nmon.cpu.lpar.pool_capacity") host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| `def_lpar_pool_load_linux_cores`
    +| `mapping_frameID`
    +| $aggregate$
    +| sort limit=0 _time
    +| stats min(lpar_pool_vp_usage) As "min_lpar_pool_vp_usage", avg(lpar_pool_vp_usage) As "avg_lpar_pool_vp_usage", max(lpar_pool_vp_usage) As "max_lpar_pool_vp_usage", latest(smt_mode) AS smt_mode, latest(pool_capacity) as pool_capacity, sparkline($statsmode$(lpar_pool_vp_usage)) As sparkline by frameID, host
    +| sort limit=0 frameID | eval avg_lpar_pool_vp_usage=round(avg_lpar_pool_vp_usage,3)</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for LPAR statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                                    <h1>CPU global percentage statistics for IBM Power Linux partitions</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    <i>The LPAR monitor contains IBM Power partitions specific CPU statistics.</i>
    +                                    <br />
    +                                    <i>These metrics are available only for IBM Pseries and partitions running AIX or PowerLinux.</i>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main metrics/fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>max/avg/min_usage:</b> Virtual CPU / Percentage CPU usage of the Pool the partition belongs to</li>
    +                                            <li><b>CPUs in Pool:</b> Number of Virtual Processor affected to the Pool the lpar belongs to</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.cpu.lpar.*&quot;%20host%3D&quot;*&quot;%20Ostype%3DLinux" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20Ostype%3DLinux%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20Ostype%3DLinux%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_pool_load_linux_cores%60" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_Summary" class="tryitbtnxl">NMON SUMMARY Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_ANALYSER_LINUX" class="tryitbtnxl">NMON ANALYSER Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" class="tryitbtnxl">CPU Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats max(max_lpar_pool_vp_usage) AS max</query>
    +                </search>
    +                <option name="underLabel">Maximum Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">$unity_minilabel$</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats avg(avg_lpar_pool_vp_usage) AS avg | eval avg=round(avg,3)</query>
    +                </search>
    +                <option name="underLabel">Average Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">$unity_minilabel$</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats min(min_lpar_pool_vp_usage) AS min</query>
    +                </search>
    +                <option name="underLabel">Minimal Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">$unity_minilabel$</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <table>
    +                <title>Shared Pool CPU statistics</title>
    +                <search base="Global">
    +                    <query>foreach max_* avg_* min_* [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 3) ]</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="addindicator" searchWhenChanged="true">
    +                <label>Pool additional Series:</label>
    +                <default>none</default>
    +                <choice value="">none</choice>
    +                <choice value="latest(pool_capacity) AS pool_capacity">pool_capacity: Nbr of cores in Pool</choice>
    +            </input>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>Shared Pool CPU statistics</title>
    +            <chart>
    +                <search id="timechart">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.lpar.smt_mode" OR metric_name="os.unix.nmon.cpu.lpar.pool_idle_time" OR metric_name="os.unix.nmon.cpu.lpar.pool_capacity") host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `def_lpar_pool_load_linux_cores`
    +| `$timefilter$`
    +| $aggregate$
    +| timechart `nmon_span` useother=f limit=0 max(lpar_pool_vp_usage) AS lpar_pool_vp_usage max(pool_capacity) AS pool_capacity by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">$unity_label$</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEMNEW_AIX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEMNEW_AIX.xml
    new file mode 100644
    index 0000000..b5896df
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEMNEW_AIX.xml
    @@ -0,0 +1,396 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI MEMNEW, AIX Memory Allocation Analysis</label>
    +    <description>User Interface for the MEMNEW monitor</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +		    <change>
    +		        <unset token="form.refresh"></unset>
    +		    </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memnew.*" Ostype=AIX by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for Memory statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/memory.png" alt="memory"/>
    +                                    <h1>AIX Memory Allocation
    +                                        <br />(os.unix.nmon.memory.memnew.*)</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main metrics/fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Process:</b> Percentage of real memory that is used by process segments</li>
    +                                            <li><b>System:</b> Percentage of real memory that is used by system segments</li>
    +                                            <li><b>Free:</b> Percentage of real memory that is free</li>
    +                                            <li><b>FScache:</b> Percentage of real memory that is used for File System Cache</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memnew.*%20host%3D*%20(OStype%3DAIX)%20" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memnew.*%20host%3D*%20(OStype%3DAIX)%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memnew.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60extract_metrics(&quot;Free_PCT%20FScache_PCT%20memused_PCT%20Process_PCT%20System_PCT&quot;)%60%0A%7C%20stats%20values(Free_PCT)%20as%20Free_PCT%2C%20values(FScache_PCT)%20as%20FScache_PCT%2C%20values(Process_PCT)%20as%20Process_PCT%2C%20values(System_PCT)%20as%20System_PCT%20by%20_time%2C%20host%0A%7C%20eval%20memused_PCT%3D(FScache_PCT%2BProcess_PCT%2BSystem_PCT)" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_MEM_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.itemfilter=MEMORY%20STATISTICS" class="tryitbtnxl">Memory Data Dictionary »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_Nmon_TOP_AIX" class="tryitbtnxl">TOP interface »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.memory.mem.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memuse.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.memory.memuse.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.lpar.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Table Stats</title>
    +            <table>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memnew.*" host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| `extract_metrics("Free_PCT FScache_PCT memused_PCT Process_PCT System_PCT")`
    +| stats values(Free_PCT) as Free_PCT, values(FScache_PCT) as FScache_PCT, values(Process_PCT) as Process_PCT, values(System_PCT) as System_PCT by _time, host
    +| fillnull value=0 FScache_PCT, Process_PCT, System_PCT
    +| eval memused_PCT=(FScache_PCT+Process_PCT+System_PCT)
    +| stats avg(Free_PCT) AS Free_PCT avg(FScache_PCT) AS FScache_PCT avg(memused_PCT) AS memused_PCT avg(Process_PCT) AS Process_PCT avg(System_PCT) AS System_PCT by host
    +| foreach *_PCT [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]
    +| fields host,memused_PCT,Free_PCT,FScache_PCT,Process_PCT,System_PCT</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="Total Mem Used (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="FScache (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Process (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="System PCT(%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="User (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>area</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>stacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="memory">
    +            <title>Memory Allocation statistics</title>
    +            <chart>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memnew.*" host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| `extract_metrics("Free_PCT FScache_PCT memused_PCT Process_PCT System_PCT")`
    +| stats values(Free_PCT) as Free_PCT, values(FScache_PCT) as FScache_PCT, values(Process_PCT) as Process_PCT, values(System_PCT) as System_PCT by _time, host
    +| timechart $span$ avg(Free_PCT) AS Free_PCT avg(FScache_PCT) AS FScache_PCT avg(Process_PCT) AS Process_PCT avg(System_PCT) AS System_PCT by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Percentage (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEMUSE_AIX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEMUSE_AIX.xml
    new file mode 100644
    index 0000000..a9c387e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEMUSE_AIX.xml
    @@ -0,0 +1,394 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI MEMUSE, AIX vmtune Statistics</label>
    +    <description>User Interface for the MEMUSE monitor</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +		    <change>
    +		        <unset token="form.refresh"></unset>
    +		    </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memuse.*" OStype=AIX by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for Memory statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/memory.png" alt="memory"/>
    +                                    <h1>AIX vmtune Statistics
    +                                        <br />(os.unix.nmon.memory.memuse.*)</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main metrics/fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>maxclient:</b> Maximum number of client frames</li>
    +                                            <li><b>maxperm:</b> The minperm and maxperm values for page steals</li>
    +                                            <li><b>minperm:</b> The minperm and maxperm values for page steals</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>numclient:</b> Number of client frames</li>
    +                                            <li><b>numperm:</b> Number of frames that are used for files (in 4-KB pages)</li>
    +                                        </lu>
    +                                        <br />
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memuse.*%20host%3D*%20(OStype%3DAIX)%20" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memuse.*%20host%3D*%20(OStype%3DAIX)%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memuse.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60extract_metrics(&quot;PCTmaxclient%20PCTmaxperm%20PCTminperm%20PCTnumclient%20PCTnumperm&quot;)%60%0A%7C%20stats%20values(PCTmaxclient)%20as%20PCTmaxclient%2C%20values(PCTmaxperm)%20as%20PCTmaxperm%2C%20values(PCTminperm)%20as%20PCTminperm%2C%20values(PCTnumclient)%20as%20PCTnumclient%2C%20values(PCTnumperm)%20as%20PCTnumperm%20by%20_time%2C%20host" class="tryitbtnxl">mstats volume pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_MEM_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.itemfilter=MEMORY%20STATISTICS" class="tryitbtnxl">Memory Data Dictionary »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_Nmon_TOP_AIX" class="tryitbtnxl">TOP interface »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.memory.mem.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memnew.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.memory.memnew.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.lpar.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Table Stats</title>
    +            <table>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memuse.*" host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| `extract_metrics("PCTmaxclient PCTmaxperm PCTminperm PCTnumclient PCTnumperm")`
    +| stats values(PCTmaxclient) as PCTmaxclient, values(PCTmaxperm) as PCTmaxperm, values(PCTminperm) as PCTminperm, values(PCTnumclient) as PCTnumclient, values(PCTnumperm) as PCTnumperm by _time, host
    +| stats $statsmode$(PCTmaxclient) AS PCTmaxclient $statsmode$(PCTmaxperm) AS PCTmaxperm $statsmode$(PCTminperm) AS PCTminperm $statsmode$(PCTnumclient) AS PCTnumclient $statsmode$(PCTnumperm) AS PCTnumperm by host
    +| sort host | fields host, PCTmaxclient, PCTmaxperm, PCTminperm, PCTnumclient, PCTnumperm</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="PCTmaxclient">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="PCTmaxperm">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="PCTminperm">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="PCTnumclient">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="PCTnumperm">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>stacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="memory">
    +            <title>Vmtune Memory statistics</title>
    +            <chart>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memuse.*" host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| `extract_metrics("PCTmaxclient PCTmaxperm PCTminperm PCTnumclient PCTnumperm")`
    +| stats values(PCTmaxclient) as PCTmaxclient, values(PCTmaxperm) as PCTmaxperm, values(PCTminperm) as PCTminperm, values(PCTnumclient) as PCTnumclient, values(PCTnumperm) as PCTnumperm by _time, host
    +| timechart $span$ useother=f limit=0 $statsmode$(PCTmaxclient) AS PCTmaxclient $statsmode$(PCTmaxperm) AS PCTmaxperm $statsmode$(PCTminperm) AS PCTminperm $statsmode$(PCTnumclient) AS PCTnumclient $statsmode$(PCTnumperm) AS PCTnumperm by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="charting.axisTitleY.text">Percentage (%)</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEMUSE_SOLARIS.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEMUSE_SOLARIS.xml
    new file mode 100644
    index 0000000..cbf2e5f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEMUSE_SOLARIS.xml
    @@ -0,0 +1,521 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css,hover.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI MEMUSE, Various Solaris Memory Statistics</label>
    +    <description>User Interface for MEMUSE monitor</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +		    <change>
    +		        <unset token="form.refresh"></unset>
    +		    </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.memory.memuse.*" OStype=Solaris by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for memory statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <h1>Solaris Memory statistics
    +                                        <br />(os.unix.nmon.memory.memuse.*)</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <i>Effective fields: Effective statistics will deduce buffers and cached memory, This amount of memory can be freed by the kernel if it is required by the system or programs.</i>
    +                                    <br />
    +                                    <i>Available units: All fields (but total fields) are available in volume (Megabytes) or in percentage.</i>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>PCTrcache:</b> Cache hit ratio, Same as 'sar -b'</li>
    +                                            <li><b>PCTwcache:</b>	Cache hit ratio, Same as 'sar -b'</li>
    +                                            <li><b>lread:</b> (sec) accesses of system buffers, Same as 'sar -b'</li>
    +                                            <li><b>lwrite:</b> (sec) accesses of system buffers, Same as 'sar -b'</li>
    +                                            <li><b>pread:</b> (sec) transfers using raw (physical) device mechanism, Same as 'sar -b'</li>
    +                                            <li><b>pwrite:</b> (sec) transfers using raw (physical) device mechanism, Same as 'sar -b'</li>
    +                                            <li><b>bread:</b> (sec) transfer of data between system buffers and disk or other block device, Same as 'sar -b'</li>
    +                                            <li><b>bwrite:</b> (sec) transfer of data between system buffers and disk or other block device, Same as 'sar -b'</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="bootstrap_title">
    +
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memuse.*%20OStype%3DSolaris%20host%3D*" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memuse.*%20OStype%3DSolaris%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memuse.*%20OStype%3DSolaris%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60extract_metrics%60%20%7C%20where%20NOT%20match(metric%2C%20&quot;NA&quot;)%0A%7C%20%7C%20eval%20%7Bmetric%7D%3Dvalue%20%5D%0A%7C%20stats%20values(PCTrcache)%20AS%20PCTrcache%20values(PCTwcache)%20AS%20PCTwcache%20values(lread)%20AS%20lread%20values(lwrite)%20AS%20lwrite%2C%20values(pread)%20AS%20pread%20values(pwrite)%20AS%20pwrite%20values(bread)%20AS%20bread%20values(bwrite)%20AS%20bwrite%20by%20_time" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_MEM_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_baseline?form.osfilter=Linux" class="tryitbtnxl">Baseline Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?form.osfilter=Linux" class="tryitbtnxl">TOP Dashboard »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20OStype%3DSolaris%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.memory.mem.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20OStype%3DSolaris%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20OStype%3DSolaris%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20OStype%3DSolaris%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Table Stats</title>
    +            <table>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.memuse.* host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| `extract_metrics` | where NOT match(metric, "NA")
    +| eval {metric}=value
    +| stats values(PCTrcache) AS PCTrcache values(PCTwcache) AS PCTwcache values(lread) AS lread values(lwrite) AS lwrite, values(pread) AS pread values(pwrite) AS pwrite values(bread) AS bread values(bwrite) AS bwrite by _time, host
    +| stats $statsmode$(PCTrcache) AS PCTrcache $statsmode$(PCTwcache) AS PCTwcache $statsmode$(lread) AS lread $statsmode$(lwrite) AS lwrite, $statsmode$(pread) AS pread $statsmode$(pwrite) AS pwrite $statsmode$(bread) AS bread $statsmode$(bwrite) AS bwrite by host
    +| foreach PCTrcache PCTwcache lread lwrite pread pwrite bread bwrite [ eval "&lt;&lt;FIELD&gt;&gt;" = round('&lt;&lt;FIELD&gt;&gt;', 2) ]
    +| sort host
    +| fields host, PCT*,*</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="PCTrcache">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="PCTwcache">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="bread">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="bwrite">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="lread">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +
    +                <format type="color" field="lwrite">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="pread">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="pwrite">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <search id="global_timechart">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.memuse.* host=$host-prefilter$ $host_query$ by metric_name, host span=1m
    +| `$timefilter$`
    +| `extract_metrics` | where NOT match(metric, "NA")
    +| eval key = host . ":" . metric
    +| timechart $span$ limit=0 useother=f avg(value) by key</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <row>
    +        <panel id="memory">
    +            <title>Memory statistics</title>
    +
    +            <input type="link" token="mem_linkinput">
    +                <label></label>
    +                <choice value="mem_chart1">MEMUSE, Cache Hit Ratio (%)</choice>
    +                <choice value="mem_chart2">MEMUSE, System Buffer Accesses</choice>
    +                <choice value="mem_chart3">MEMUSE, Transfers using raw (physical) device mechanism</choice>
    +                <choice value="mem_chart4">MEMUSE, Transfer of data between system buffers and disk or other block device</choice>
    +                <default>mem_chart1</default>
    +                <change>
    +                    <condition value="mem_chart1">
    +                        <set token="mem_chart1">true</set>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                    </condition>
    +                    <condition value="mem_chart2">
    +                        <set token="mem_chart2">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                    </condition>
    +                    <condition value="mem_chart3">
    +                        <set token="mem_chart3">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart4"></unset>
    +                    </condition>
    +                    <condition value="mem_chart4">
    +                        <set token="mem_chart4">true</set>
    +                        <unset token="mem_chart1"></unset>
    +                        <unset token="mem_chart2"></unset>
    +                        <unset token="mem_chart3"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$mem_chart1$">
    +                <title></title>
    +                <search base="global_timechart">
    +                    <query>fields _time, *PCTrcache, *PCTwcache</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Percentage (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$mem_chart2$">
    +                <title></title>
    +                <search base="global_timechart">
    +                    <query>fields _time, *lread, *lwrite</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Volume per second</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$mem_chart3$">
    +                <title></title>
    +                <search base="global_timechart">
    +                    <query>fields _time, *pread, *pwrite</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Volume per second</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$mem_chart4$">
    +                <title></title>
    +                <search base="global_timechart">
    +                    <query>fields _time, *bread, *bwrite</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Volume per second</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEM_AIX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEM_AIX.xml
    new file mode 100644
    index 0000000..ac75a15
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEM_AIX.xml
    @@ -0,0 +1,607 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI MEM/MEMNEW, AIX Free Memory and Paging space activity</label>
    +    <description>User Interface for the MEM monitor</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +		    <change>
    +		        <unset token="form.refresh"></unset>
    +		    </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>AIX</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +        <input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +            <label>Hosts Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ host=$host-prefilter$
    +| stats count by host | dedup host | sort 0 host</query>
    +            </search>
    +            <valuePrefix>host="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL Hosts</choice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +            <change>
    +                <condition>
    +                    <unset token="form.host_query_input"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +        <input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +            <label>Hosts Selection:</label>
    +            <search base="populate">
    +                <query>search $host$ $frameID$
    +| stats values(host) as host
    +| format | fields - host | rename search as host</query>
    +            </search>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <fieldForLabel>host</fieldForLabel>
    +            <fieldForValue>host</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` `def_memory_AIX_metric_filters` $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="Global">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_AIX_metric_filters` host=$host-prefilter$ $host_query$ by host, metric_name span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval {metric}=value
    +| stats values(Real_total_MB) as Real_total_MB, values(System_PCT) as System_PCT, values(Process_PCT) as Process_PCT, values(Virtual_total_MB) as Virtual_total_MB, values(Virtual_free_MB) as Virtual_free_MB by _time, host
    +| eval Real_used_PCT = round(System_PCT+Process_PCT,2)
    +| eval Real_used_MB = round((Real_total_MB/100)*(System_PCT+Process_PCT),2)
    +| eval Virtual_used_PCT = round((((Virtual_total_MB-Virtual_free_MB)/Virtual_total_MB)*100),2)
    +| eval Virtual_used_MB = round((Virtual_total_MB-Virtual_free_MB),2)
    +| stats $statsmode$(*) as "*" by host
    +| foreach *_MB [eval &lt;&lt;FIELD&gt;&gt;=round(&lt;&lt;FIELD&gt;&gt;, 0)]
    +| foreach *_PCT [eval &lt;&lt;FIELD&gt;&gt;=round(&lt;&lt;FIELD&gt;&gt;, 2)]</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="gaugestats">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_AIX_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `$timefilter$`
    +| `def_memory_load_percent`
    +| stats max(mem_used_effective_PCT) AS max_mem, avg(mem_used_effective_PCT) AS avg_mem, max(swap_used_effective_PCT) AS max_swap, avg(swap_used_effective_PCT) AS avg_swap</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for Memory statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/memory.png" alt="memory"/>
    +                                    <h1>AIX Free Memory and Paging space activity
    +                                        <br />(os.unix.nmon.memory.mem.*)</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main metrics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Real_free_MB / Real_free_PCT:</b> (MB / %) Physical memory free</li>
    +                                            <li><b>Real_total_MB:</b> (MB) Total physical memory available</li>
    +                                            <li><b>Real_used_MB / Real_used_PCT:</b> (MB / %) Physical memory used</li>
    +                                        </lu>
    +                                    </div>
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Virtual_free_MB / Virtual_free_PCT:</b> (MB / %) Free paging space</li>
    +                                            <li><b>Virtual_total_MB:</b> (MB) Total paging space</li>
    +                                            <li><b>Virtual_used_MB / Virtual_used_PCT:</b> (MB / %) Used paging space</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <br />
    +                                    <p>Notes: Due to the way AIX manages memory, calculation is made with both MEM and MEMNEW metrics against process and system categories.</p>
    +                                    
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20OR%20metric_name%3Dos.unix.nmon.memory.memnew.*%20host%3D*%20(OStype%3DAIX)%20" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20OR%20metric_name%3Dos.unix.nmon.memory.memnew.*%20host%3D*%20(OStype%3DAIX)%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20OR%20metric_name%3Dos.unix.nmon.memory.memnew.*%20(host%3D*)%20(OStype%3DAIX)%20(host%3D*)%20by%20OStype%20host%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_volume_MB%60" class="tryitbtnxl">mstats volume pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20OR%20metric_name%3Dos.unix.nmon.memory.memnew.*%20(host%3D*)%20(OStype%3DAIX)%20(host%3D*)%20by%20OStype%20host%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent_all_metrics%60" class="tryitbtnxl">mstats percentage pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_MEM_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?form.osfilter=AIX%3Dtrue&amp;form.itemfilter=MEMORY%20STATISTICS" class="tryitbtnxl">Memory Data Dictionary »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_Nmon_TOP_AIX" class="tryitbtnxl">TOP interface »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memnew.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.memory.memnew.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memuse.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.memory.memuse.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.lpar.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20OStype%3DAIX%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval max_mem=round(max_mem,2) | gauge max_mem</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Max %Mem</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval avg_mem=round(avg_mem,2) | gauge avg_mem</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Avg %Mem</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval max_swap=round(max_swap,2) | fillnull value="0" max_swap | gauge max_swap</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Max %Swap</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval avg_swap=round(avg_swap,2) | fillnull value="0" avg_swap | gauge avg_swap</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Avg %Swap</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <title>MEM - Real Memory Table Stats</title>
    +                <search base="Global">
    +                    <query>fields frameID,host,*Real*MB,*Real*PCT*</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="Real_used_MB">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Real_Free_PCT">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Real_used_PCT">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +
    +        <panel>
    +            <table>
    +                <title>MEM - Paging Space Table Stats</title>
    +                <search base="Global">
    +                    <query>fields frameID,host,*Virtual*PCT,*Virtual*MB*</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="Virtual_used_MB">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Virtual_Free_PCT">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Virtual_used_PCT">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="memmode" searchWhenChanged="true">
    +                <label>Show Mem load by:</label>
    +                <default>fields _time,*MB*</default>
    +                <choice value="fields _time,*MB*">Activity in Data Volume (MB)</choice>
    +                <choice value="fields _time,*Real_used_PCT*,*Virtual_used_PCT*">Usage in percentage (%)</choice>
    +                <choice value="fields _time,*Real_Free_PCT*,*Virtual_free_PCT*">Free in percentage (%)</choice>
    +            </input>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="memory">
    +            <title>Memory statistics</title>
    +
    +            <input type="link" token="linkinput">
    +                <label></label>
    +                <choice value="chart1">Real Memory</choice>
    +                <choice value="chart2">Paging Space</choice>
    +                <default>chart1</default>
    +                <change>
    +                    <condition value="chart1">
    +                        <set token="chart1">true</set>
    +                        <unset token="chart2"></unset>
    +                    </condition>
    +                    <condition value="chart2">
    +                        <set token="chart2">true</set>
    +                        <unset token="chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +            
    +            <chart depends="$chart1$">
    +                <title></title>
    +                <search depends="$chart1$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_AIX_metric_filters` host=$host-prefilter$ $host_query$ by host, metric_name span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval {metric}=value
    +| stats values(Real_total_MB) as Real_total_MB, values(System_PCT) as System_PCT, values(Process_PCT) as Process_PCT by _time, host
    +| eval Real_used_PCT = round(System_PCT+Process_PCT,2), Real_Free_PCT = round(100-(System_PCT+Process_PCT),2), Real_used_MB = round((Real_total_MB/100)*(System_PCT+Process_PCT),2)
    +| timechart $span$ useother=f limit=0
    +$statsmode$(Real_Free_PCT) AS Real_Free_PCT $statsmode$(Real_total_MB) AS Real_total_MB $statsmode$(Real_used_MB) AS Real_used_MB
    +$statsmode$(Real_used_PCT) AS Real_used_PCT by host | $memmode$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Real Memory</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart2$">
    +                <title></title>
    +                <search depends="$chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_AIX_metric_filters` host=$host-prefilter$ $host_query$ by host, metric_name span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval {metric}=value
    +| stats values(Virtual_free_PCT) as Virtual_free_PCT, values(Virtual_total_MB) as Virtual_total_MB, values(Virtual_free_MB) as Virtual_free_MB by _time, host
    +| eval Virtual_used_PCT = round((((Virtual_total_MB-Virtual_free_MB)/Virtual_total_MB)*100),2)
    +| eval Virtual_used_MB = round((Virtual_total_MB-Virtual_free_MB),2)
    +| timechart $span$ useother=f limit=0
    +$statsmode$(Virtual_free_PCT) AS Virtual_free_PCT $statsmode$(Virtual_total_MB) AS Virtual_total_MB $statsmode$(Virtual_used_MB) AS Virtual_used_MB
    +$statsmode$(Virtual_used_PCT) AS Virtual_used_PCT by host | $memmode$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">Paging Space</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEM_LINUX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEM_LINUX.xml
    new file mode 100644
    index 0000000..4c06816
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEM_LINUX.xml
    @@ -0,0 +1,807 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css,hover.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI MEM, Linux Memory and Swap Usage</label>
    +    <description>User Interface for the MEM monitor</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +		    <change>
    +		        <unset token="form.refresh"></unset>
    +		    </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>Linux</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="Linux">Linux</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>avg</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for memory statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/OS/colors/linux_72px.png" alt="Linux"/>
    +                                    <h1>Linux Memory statistics</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <i>Effective fields: Effective statistics will deduce buffers and cached memory, This amount of memory can be freed by the kernel if it is required by the system or programs.</i>
    +                                    <br />
    +                                    <i>Available units: All fields (but total fields) are available in volume (Megabytes) or in percentage.</i>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Physical memory statistics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>memused:</b> Total amount of physical RAM used</li>
    +                                            <li><b>memfree:</b> Total amount of physical RAM left unused by the system</li>
    +                                            <li><b>memtotal:</b> Total amount of physical RAM</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>buffers:</b> The amount of physical RAM, used for file buffers</li>
    +                                            <li><b>cached:</b> The amount of physical RAM, used as cache memory</li>
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>active:</b> The total amount of buffer or page cache memory, that is in active use. This is memory that has been recently used and is usually not reclaimed for other purposes</li>
    +                                            <li><b>inactive:</b> The total amount of buffer or page cache memory, that are free and available. This is memory that has not been recently used and can be reclaimed for other purposes</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <br />
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>mem_used_effective:</b> Total amount of physical RAM used, less buffers and cached</li>
    +                                            <li><b>mem_free_effective:</b> Total amount of physical RAM left unused by the system, less buffers and cached</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <h1>Swap memory statistics:</h1>
    +
    +                                    <div class="list" style="display: inline-block">
    +                                        <lu>
    +                                            <li><b>swapfree:</b> The total amount of swap free</li>
    +                                            <li><b>swapused:</b> The total amount of swap used</li>
    +                                            <li><b>swaptotal:</b> The total amount of swap available</li>
    +                                            <li><b>swapcached:</b> The amount of swap, used as cache memory</li>
    +                                        </lu>
    +                                    </div>
    +
    +
    +                                    <div class="list" style="display: inline-block">
    +                                        <lu>
    +                                            <li><b>swap_used_effective:</b> The total amount of swap used, less swap cached</li>
    +                                            <li><b>swap_free_effective:</b> The total amount of swap free, less swap cached</li>
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="bootstrap_title">
    +
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.memory.mem.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20(host%3D*)%20(OStype%3DLinux)%20(host%3D*)%20by%20host%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_volume_MB%60" class="tryitbtnxl">mstats volume pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20(host%3D*)%20(OStype%3DLinux)%20(host%3D*)%20by%20host%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent_all_metrics%60" class="tryitbtnxl">mstats percentage pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_MEM_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?form.osfilter=Linux%3Dtrue" class="tryitbtnxl">Linux Data Dictionary »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_baseline?form.osfilter=Linux" class="tryitbtnxl">Baseline Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?form.osfilter=Linux" class="tryitbtnxl">TOP Dashboard »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` `def_memory_linux_metric_filters` $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="gaugestats">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `$timefilter$`
    +| `def_memory_load_percent`
    +| stats max(mem_used_effective_PCT) AS max_mem, avg(mem_used_effective_PCT) AS avg_mem, max(swap_used_effective_PCT) AS max_swap, avg(swap_used_effective_PCT) AS avg_swap</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="chartstats_byhost_percentage">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `$timefilter$`
    +| `def_memory_load_percent_all_metrics`
    +| timechart $span$ useother=f limit=0 $statsmode$(buffers) as buffers, $statsmode$(cached) as cached, $statsmode$(mem_used_effective) as mem_used_effective by host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="chartstats_byhost_volume">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `$timefilter$`
    +| `def_memory_volume_MB`
    +| timechart $span$ useother=f limit=0 $statsmode$(active) AS active, $statsmode$(buffers) as buffers, $statsmode$(cached) as cached,
    +$statsmode$(inactive) as inactive, $statsmode$(mem_used_effective) as mem_used_effective, $statsmode$(memtotal) as memtotal,
    +$statsmode$(swap_used_effective) as swap_used_effective, $statsmode$(swap_used_effective) as swap_used_effective, $statsmode$(swapcached) as swap_cached_MB, $statsmode$(swaptotal) as swaptotal by host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="chartstats_bydeployment_percentage">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `$timefilter$`
    +| `def_memory_load_percent_all_metrics`
    +| timechart $span$ $statsmode$(*) AS *</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="chartstats_bydeployment_volume">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `$timefilter$`
    +| `def_memory_volume_MB`
    +| timechart $span$ $statsmode$(*) AS *</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- ################################ -->
    +
    +    <row>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval max_mem=round(max_mem,2) | gauge max_mem</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Max %Mem</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval avg_mem=round(avg_mem,2) | gauge avg_mem</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Avg %Mem</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval max_swap=round(max_swap,2) | fillnull value="0" max_swap | gauge max_swap</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Max %Swap</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval avg_swap=round(avg_swap,2) | fillnull value="0" avg_swap | gauge avg_swap</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Avg %Swap</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="memory1">
    +            <title>Memory table stats</title>
    +            <input type="dropdown" token="memmode" searchWhenChanged="true">
    +                <label></label>
    +                <default>percentage</default>
    +                <choice value="percentage">Usage in percentage (%)</choice>
    +                <choice value="volume">Activity in Data Volume (MB)</choice>
    +                <change>
    +                    <condition value="percentage">
    +                        <set token="show_memory_percentage">True</set>
    +                        <unset token="show_memory_volume"></unset>
    +                    </condition>
    +                    <condition value="volume">
    +                        <set token="show_memory_volume">True</set>
    +                        <unset token="show_memory_percentage"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <table depends="$show_memory_percentage$">
    +                <title></title>
    +                <search depends="$show_memory_percentage$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` host=$host-prefilter$ $host_query$ by host, metric_name span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval {metric}=value
    +| stats values(memtotal) as memtotal, values(buffers) as buffers, values(active) as active, values(inactive) as inactive, values(cached) as cached, values(memfree) as memfree,
    +values(swapcached) as swapcached, values(swaptotal) as swaptotal, values(swapfree) as swapfree by _time, host
    +| fillnull value=0 memtotal, buffers, active, inactive, cached, memfree, swapcached, swaptotal, swapfree
    +| eval mem_used_effective=case(isnotnull(cached), round((((((memtotal-(buffers+cached))-memfree))/memtotal)*100),2), isnotnull(memtotal), round((((memtotal-memfree)/memtotal)*100),2))
    +| eval mem_free_effective = case(isnotnull(cached), round((((memfree+(buffers+cached))/memtotal)*100),2), isnotnull(memtotal), round(((memfree/memtotal)*100),2))
    +| eval swap_used_effective=case(isnotnull(swapcached), round((((((swaptotal-swapfree)-swapcached))/swaptotal)*100),2), isnotnull(swaptotal), round((((swaptotal-swapfree)/swaptotal)*100),2))
    +| eval swap_free_effective=case(isnotnull(swapcached), round((((swapfree+swapcached)/swaptotal)*100),2), isnotnull(swapfree), round(((swapfree/swaptotal)*100),2))
    +| eval swapcached = case(isnotnull(swapcached), round(((swapcached/swaptotal)*100),2))
    +| eval cached = case(isnotnull(cached), round(((cached/memtotal)*100),2)), buffers = case(isnotnull(buffers), round(((buffers/memtotal)*100),2)),
    +active = case(isnotnull(active), round(((active/memtotal)*100),2)), inactive = case(isnotnull(inactive), round(((inactive/memtotal)*100),2))
    +| fields - memtotal, memfree, memtotal, swaptotal, swapfree
    +| stats $statsmode$(*) as "*" by host
    +| rename "*_PCT" as "*"
    +| fields host, "mem*total*", "mem*used*", "mem*free*", active, inactive, buffers, cached, "swap*total*", "swap*used*", "swap*free*", *
    +| rename "mem*" AS "mem* (%)", "swap*" AS "swap* (%)", active as "active (%)", inactive as "inactive (%)", buffers as "buffers (%)", cached as "cached (%)"
    +| foreach "*%*" [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 2) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="mem_used_effective (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="swap_used_effective (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +            <table depends="$show_memory_volume$">
    +                <title></title>
    +                <search depends="$show_memory_volume$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_linux_metric_filters` host=$host-prefilter$ $host_query$ by host, metric_name span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval {metric}=value
    +| stats values(memtotal) as memtotal, values(buffers) as buffers, values(active) as active, values(inactive) as inactive, values(cached) as cached, values(memfree) as memfree,
    +values(swapcached) as swapcached, values(swaptotal) as swaptotal, values(swapfree) as swapfree by _time, host
    +| fillnull value=0 memtotal, buffers, active, inactive, cached, memfree, swapcached, swaptotal, swapfree
    +| eval mem_used_effective = case(isnotnull(cached), ((memtotal-(buffers+cached))-memfree), isnotnull(memtotal), memtotal-memfree)
    +| eval swap_used_effective = case(isnotnull(swapcached), ((swaptotal-swapfree)-swapcached), isnotnull(swaptotal), (swaptotal-swapfree))
    +| stats $statsmode$(*) as "*" by host
    +| fields host, "mem*total*", "mem*used*", "mem*free*", active, inactive, buffers, cached, "swap*total*", "swap*used*", "swap*free*", *
    +| rename "mem*" AS "mem* (MB)", "swap*" AS "swap* (MB)", active as "active (MB)", inactive as "inactive (MB)", buffers as "buffers (MB)", cached as "cached (MB)"
    +| foreach "*MB*" [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 0) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="mem_used_effective (MB)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="swap_used_effective (MB)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="memory2">
    +            <title>Memory charts</title>
    +
    +            <input type="link" token="linkinput">
    +                <label></label>
    +                <choice value="chart1">Deployment: Free/Buffers/Cached memory (MB)</choice>
    +                <choice value="chart2">Deployment: Effective memory/swap used (%)</choice>
    +                <choice value="chart3">By host: Effective memory Used/Total available (MB)</choice>
    +                <choice value="chart4">By host: Used/Cached/Buffers memory (%)</choice>
    +                <choice value="chart5">By host: Used/Cached/Buffers/Total memory (MB)</choice>
    +                <choice value="chart6">By host: Swap Cached/Used/Total available (MB)</choice>
    +                <default>chart1</default>
    +                <change>
    +                    <condition value="chart1">
    +                        <set token="chart1">true</set>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart2">
    +                        <set token="chart2">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart3">
    +                        <set token="chart3">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart4">
    +                        <set token="chart4">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart5">
    +                        <set token="chart5">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart6">
    +                        <set token="chart6">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$chart1$">
    +                <title></title>
    +                <search base="chartstats_bydeployment_volume">
    +                    <query>fields _time, memfree, cached, buffers, mem_used_effective, memtotal</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.overlayFields">mem_total_MB</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.fieldColors">{"mem_total_MB": 0xe50000}</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart2$">
    +                <title></title>
    +                <search base="chartstats_bydeployment_percentage">
    +                    <query>fields _time, mem_used_effective, swap_used_effective</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">percentage (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart3$">
    +                <title></title>
    +                <search base="chartstats_byhost_volume">
    +                    <query>fields _time, *mem_used_effective*, *memtotal*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart4$">
    +                <title></title>
    +                <search base="chartstats_byhost_percentage">
    +                    <query>fields _time, mem_used*, cached*, buffers*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">percentage (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart5$">
    +                <title></title>
    +                <search base="chartstats_byhost_volume">
    +                    <query>fields _time, mem_used*, cached*, buffers*, memtotal*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart6$">
    +                <title></title>
    +                <search base="chartstats_byhost_volume">
    +                    <query>fields _time, swap_used*, swap_cached*, swaptotal*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEM_SOLARIS.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEM_SOLARIS.xml
    new file mode 100644
    index 0000000..ccfbaca
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_MEM_SOLARIS.xml
    @@ -0,0 +1,799 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css,hover.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI MEM, Solaris Memory and Swap Usage</label>
    +    <description>User Interface the MEM monitor</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +		    <change>
    +		        <unset token="form.refresh"></unset>
    +		    </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>Solaris</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for memory statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <h1>Solaris Memory statistics
    +                                        <br />(os.unix.nmon.memory.mem.*)</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <i>Effective fields: Effective statistics will deduce buffers and cached memory, This amount of memory can be freed by the kernel if it is required by the system or programs.</i>
    +                                    <br />
    +                                    <i>Available units: All fields (but total fields) are available in volume (Megabytes) or in percentage.</i>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Physical memory statistics:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>memused:</b> Total amount of physical RAM used</li>
    +                                            <li><b>memfree:</b> Total amount of physical RAM left unused by the system</li>
    +                                            <li><b>memtotal:</b> Total amount of physical RAM</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <br />
    +
    +                                    <h1>Swap memory statistics:</h1>
    +
    +                                    <div class="list" style="display: inline-block">
    +                                        <lu>
    +                                            <li><b>swapfree:</b> The total amount of swap free</li>
    +                                            <li><b>swapused:</b> The total amount of swap used</li>
    +                                            <li><b>swaptotal:</b> The total amount of swap available</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="bootstrap_title">
    +
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.memory.mem.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20(host%3D*)%20(OStype%3DLinux)%20(host%3D*)%20by%20OStype%20host%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_volume_MB%60" class="tryitbtnxl">mstats volume pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.mem.*%20(host%3D*)%20(OStype%3DLinux)%20(host%3D*)%20by%20OStype%20host%2C%20metric_name%20span%3D1m%0A%7C%20%60def_memory_load_percent_all_metrics%60" class="tryitbtnxl">mstats percentage pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_MEM_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_baseline?form.osfilter=Linux" class="tryitbtnxl">Baseline Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?form.osfilter=Linux" class="tryitbtnxl">TOP Dashboard »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.memory.memuse.*%20OStype%3DSolaris%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.memory.memuse.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20OStype%3DSolaris%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20OStype%3DSolaris%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20OStype%3DSolaris%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` `def_memory_all_os_metric_filters` $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="gaugestats">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `$timefilter$`
    +| `def_memory_load_percent`
    +| stats max(mem_used_effective_PCT) AS max_mem, avg(mem_used_effective_PCT) AS avg_mem, max(swap_used_effective_PCT) AS max_swap, avg(swap_used_effective_PCT) AS avg_swap</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="chartstats_byhost_percentage">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `$timefilter$`
    +| `def_memory_load_percent_all_metrics`
    +| timechart $span$ useother=f limit=0 $statsmode$(buffers) as buffers, $statsmode$(cached) as cached, $statsmode$(mem_used_effective) as mem_used_effective by host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="chartstats_byhost_volume">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `$timefilter$`
    +| `def_memory_volume_MB`
    +| timechart $span$ useother=f limit=0 $statsmode$(active) AS active, $statsmode$(buffers) as buffers, $statsmode$(cached) as cached,
    +$statsmode$(inactive) as inactive, $statsmode$(mem_used_effective) as mem_used_effective, $statsmode$(memtotal) as memtotal,
    +$statsmode$(swap_used_effective) as swap_used_effective, $statsmode$(swap_used_effective) as swap_used_effective, $statsmode$(swapcached) as swap_cached_MB, $statsmode$(swaptotal) as swaptotal by host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="chartstats_bydeployment_percentage">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `$timefilter$`
    +| `def_memory_load_percent_all_metrics`
    +| timechart $span$ $statsmode$(*) AS *</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="chartstats_bydeployment_volume">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by OStype, host, metric_name span=1m
    +| `$timefilter$`
    +| `def_memory_volume_MB`
    +| timechart $span$ $statsmode$(*) AS *</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval max_mem=round(max_mem,2) | gauge max_mem</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Max %Mem</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval avg_mem=round(avg_mem,2) | gauge avg_mem</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Avg %Mem</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval max_swap=round(max_swap,2) | fillnull value="0" max_swap | gauge max_swap</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Max %Swap</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +        <panel>
    +            <viz type="horseshoe_meter_app.horseshoe_meter">
    +                <search base="gaugestats">
    +                    <query>eval avg_swap=round(avg_swap,2) | fillnull value="0" avg_swap | gauge avg_swap</query>
    +                </search>
    +                <option name="horseshoe_meter_app.horseshoe_meter.backgroundColor">#212527</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.dialColor">#d0d5d9</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeColor">#b44441</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxRangeThreshold">85</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.maxValue">100</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeColor">#fbcd2f</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.midRangeThreshold">55</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minRangeColor">#3fc77a</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.minValue">0</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.thresholdStyle">percentage</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.useRangemap">false</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.valueColor">#779ecb</option>
    +                <option name="horseshoe_meter_app.horseshoe_meter.caption">Avg %Swap</option>
    +                <option name="height">180</option>
    +                <option name="refresh.display">preview</option>
    +            </viz>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="memory1">
    +            <title>Memory table stats</title>
    +            <input type="dropdown" token="memmode" searchWhenChanged="true">
    +                <label></label>
    +                <default>percentage</default>
    +                <choice value="percentage">Usage in percentage (%)</choice>
    +                <choice value="volume">Activity in Data Volume (MB)</choice>
    +                <change>
    +                    <condition value="percentage">
    +                        <set token="show_memory_percentage">True</set>
    +                        <unset token="show_memory_volume"></unset>
    +                    </condition>
    +                    <condition value="volume">
    +                        <set token="show_memory_volume">True</set>
    +                        <unset token="show_memory_percentage"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <table depends="$show_memory_percentage$">
    +                <title></title>
    +                <search depends="$show_memory_percentage$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by host, metric_name span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval {metric}=value
    +| stats values(memtotal) as memtotal, values(memfree) as memfree, values(swaptotal) as swaptotal, values(swapfree) as swapfree by _time, host
    +| eval mem_used_effective= round((((memtotal-memfree)/memtotal)*100),2)
    +| eval mem_free_effective = round(((memfree/memtotal)*100),2)
    +| eval swap_used_effective = round((((swaptotal-swapfree)/swaptotal)*100),2)
    +| eval swap_free_effective = round(((swapfree/swaptotal)*100),2)
    +| fields - memtotal, memfree, memtotal, swaptotal, swapfree
    +| stats $statsmode$(*) as "*" by host
    +| rename "*_PCT" as "*"
    +| fields host, "mem*total*", "mem*used*", "mem*free*", "swap*total*", "swap*used*", "swap*free*", *
    +| rename "mem*" AS "mem* (%)", "swap*" AS "swap* (%)"
    +| foreach "*%*" [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 2) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="mem_used_effective (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="swap_used_effective (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +            <table depends="$show_memory_volume$">
    +                <title></title>
    +                <search depends="$show_memory_volume$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` host=$host-prefilter$ $host_query$ by host, metric_name span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval {metric}=value
    +| stats values(memtotal) as memtotal, values(memfree) as memfree, values(swaptotal) as swaptotal, values(swapfree) as swapfree by _time, host
    +| eval mem_used_effective = (memtotal-memfree)
    +| eval swap_used_effective = (swaptotal-swapfree)
    +| stats $statsmode$(*) as "*" by host
    +| fields host, "mem*total*", "mem*used*", "mem*free*", "swap*total*", "swap*used*", "swap*free*", *
    +| rename "mem*" AS "mem* (MB)", "swap*" AS "swap* (MB)"
    +| foreach "*MB*" [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 0) ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="mem_used_effective (MB)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="swap_used_effective (MB)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="memory2">
    +            <title>Memory charts</title>
    +
    +            <input type="link" token="linkinput">
    +                <label></label>
    +                <choice value="chart1">Deployment: Free/Used/Total memory (MB)</choice>
    +                <choice value="chart2">Deployment: Effective memory/swap used (%)</choice>
    +                <choice value="chart3">By host: Effective memory Used/Total available (MB)</choice>
    +                <choice value="chart4">By host: Used memory (%)</choice>
    +                <choice value="chart5">By host: Used/Total memory (MB)</choice>
    +                <choice value="chart6">By host: Swap Used/Total available (MB)</choice>
    +                <default>chart1</default>
    +                <change>
    +                    <condition value="chart1">
    +                        <set token="chart1">true</set>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart2">
    +                        <set token="chart2">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart3">
    +                        <set token="chart3">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart4">
    +                        <set token="chart4">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart5">
    +                        <set token="chart5">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart6">
    +                        <set token="chart6">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$chart1$">
    +                <title></title>
    +                <search base="chartstats_bydeployment_volume">
    +                    <query>fields _time, memfree, mem_used_effective, memtotal</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">area</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">stacked</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart.bubbleMaximumSize">50</option>
    +                <option name="charting.chart.bubbleMinimumSize">10</option>
    +                <option name="charting.chart.bubbleSizeBy">area</option>
    +                <option name="charting.chart.overlayFields">mem_total_MB</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.fieldColors">{"mem_total_MB": 0xe50000}</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart2$">
    +                <title></title>
    +                <search base="chartstats_bydeployment_percentage">
    +                    <query>fields _time, mem_used_effective, swap_used_effective</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">percentage (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart3$">
    +                <title></title>
    +                <search base="chartstats_byhost_volume">
    +                    <query>fields _time, *mem_used_effective*, *memtotal*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart4$">
    +                <title></title>
    +                <search base="chartstats_byhost_percentage">
    +                    <query>fields _time, mem_used*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">percentage (%)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart5$">
    +                <title></title>
    +                <search base="chartstats_byhost_volume">
    +                    <query>fields _time, mem_used*, memtotal*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart6$">
    +                <title></title>
    +                <search base="chartstats_byhost_volume">
    +                    <query>fields _time, swap_used*, swaptotal*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">line</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">default</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">volume (MB)</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_NET.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_NET.xml
    new file mode 100644
    index 0000000..e588163
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_NET.xml
    @@ -0,0 +1,505 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI NET, global user interface for network metrics</label>
    +    <description>User Interface for the network statistics</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +		    <change>
    +		        <unset token="form.refresh"></unset>
    +		    </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input id="device" type="multiselect" token="device" searchWhenChanged="true">
    +            <label>Disks Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ $host$
    +| stats count by dimension_device | dedup dimension_device | sort 0 dimension_device</query>
    +            </search>
    +            <valuePrefix>dimension_device="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <initialValue>*</initialValue>
    +            <choice value="*">ALL Devices</choice>
    +            <fieldForLabel>dimension_device</fieldForLabel>
    +            <fieldForValue>dimension_device</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="fields *">Single Series</choice>
    +            <choice value="rex mode=sed field=&quot;dimension_device&quot; &quot;s/^\w*\-//&quot; | stats dedup_splitvals=t avg(value) AS value by _time, host,dimension_device">Avg by Time interval,host,flow</choice>
    +            <choice value="stats dedup_splitvals=t avg(value) AS value by _time, host | eval dimension_device=&quot;aggreg_dimension_device&quot;">Avg by Time interval,host</choice>
    +            <choice value="rex mode=sed field=&quot;dimension_device&quot; &quot;s/^\w*\-//&quot; | stats dedup_splitvals=t avg(value) AS value by _time, dimension_device | eval host=&quot;aggreg_host&quot;">Avg by Time interval,flow</choice>
    +            <choice value="stats dedup_splitvals=t avg(value) AS value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_dimension_device&quot;">Avg by Time interval</choice>
    +            <choice value="rex mode=sed field=&quot;dimension_device&quot; &quot;s/^\w*\-//&quot; | stats dedup_splitvals=t max(value) AS value by _time, host,dimension_device">Max by Time interval,host,flow</choice>
    +            <choice value="stats dedup_splitvals=t max(value) AS value by _time, host | eval dimension_device=&quot;aggregate&quot;">Max by Time interval,host</choice>
    +            <choice value="rex mode=sed field=&quot;dimension_device&quot; &quot;s/^\w*\-//&quot; | stats dedup_splitvals=t max(value) AS value by _time, dimension_device | eval host=&quot;aggreg_host&quot;">Max by Time interval,flow</choice>
    +            <choice value="stats dedup_splitvals=t max(value) AS value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_dimension_device&quot;">Max by Time interval</choice>
    +            <choice value="rex mode=sed field=&quot;dimension_device&quot; &quot;s/^\w*\-//&quot; | stats dedup_splitvals=t sum(value) AS value by _time, host,dimension_device">Sum by Time interval,host,flow</choice>
    +            <choice value="stats dedup_splitvals=t sum(value) AS value by _time, host | eval dimension_device=&quot;aggregate&quot;">Sum by Time interval,host</choice>
    +            <choice value="rex mode=sed field=&quot;dimension_device&quot; &quot;s/^\w*\-//&quot; | stats dedup_splitvals=t sum(value) AS value by _time, dimension_device | eval host=&quot;aggreg_host&quot;">Sum by Time interval,flow</choice>
    +            <choice value="stats dedup_splitvals=t sum(value) AS value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_dimension_device&quot;">Sum by Time interval</choice>
    +            <default>fields *</default>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="dataconvert" depends="$metric_has_rate$" searchWhenChanged="true">
    +            <label>Data Conversion:</label>
    +            <default>eval value=round((value),2)</default>
    +            <choice value="eval value=round((value/1000),2) | rex mode=sed field=dimension_device &quot;s/KB/MB/&quot;">MBps</choice>
    +            <choice value="eval value=round((value/1000/1000),2) | rex mode=sed field=dimension_device &quot;s/KB/GB/&quot;">GBps</choice>
    +            <choice value="eval value=round((value),2)">KBps</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <row>
    +        <panel>
    +            <input id="metric_name" type="dropdown" token="metric_name" searchWhenChanged="true">
    +                <label>Metric:</label>
    +                <default>os.unix.nmon.network.net</default>
    +                <initialValue>os.unix.nmon.network.net</initialValue>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate_metric">
    +                    <query>fields metric_name | sort 0 metric_name</query>
    +                </search>
    +                <fieldForLabel>metric_name</fieldForLabel>
    +                <fieldForValue>metric_name</fieldForValue>
    +                <change>
    +                    <condition value="os.unix.nmon.network.net">
    +                        <set token="metric_title">Network Inbound / Outbound Traffic</set>
    +                        <set token="metric_desc">Traffic in KBytes/sec</set>
    +                        <set token="metric_has_rate">True</set>
    +                        <set token="metric_is_set">True</set>
    +                        <set token="metric_label">network traffic</set>
    +                    </condition>
    +                    <condition value="os.unix.nmon.network.neterror">
    +                        <set token="metric_title">Number of errors per Network Interface</set>
    +                        <set token="metric_desc">Number of errors</set>
    +                        <unset token="metric_has_rate"></unset>
    +                        <set token="metric_is_set">True</set>
    +                        <set token="metric_label">nb of network errors</set>
    +                    </condition>
    +                    <condition value="os.unix.nmon.network.netpacket">
    +                        <set token="metric_title">Number of read/write packets per Network Interface</set>
    +                        <set token="metric_desc">Number of network packets</set>
    +                        <unset token="metric_has_rate"></unset>
    +                        <set token="metric_is_set">True</set>
    +                        <set token="metric_label">nb of network packets</set>
    +                    </condition>
    +                    <condition>
    +                        <set token="metric_title">$metric_name$</set>
    +                        <set token="metric_desc">value for this metric</set>
    +                        <set token="metric_is_set">True</set>
    +                        <unset token="metric_has_rate"></unset>
    +                        <set token="metric_label">$metric_name$</set>
    +                    </condition>
    +                </change>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row depends="$host$ $device$" rejects="$metric_is_set$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please select the metric in the metric selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row depends="$host$" rejects="$device$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please select associated devices to be analysed in the device selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for Network statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/network.png" alt="NET"/>
    +                                    <h1>$metric_title$
    +                                        <br />($metric_name$)</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Metrics &amp; dimensions:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>device:</b> Name of the network interface</li>
    +                                            <li><b>value:</b> $metric_desc$</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_device)%20as%20dimension_device%20where%20%60nmon_metrics_index%60%20metric_name%3D$metric_name$%20host%3D*%20by%20host" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3D$metric_name$%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">mstats raw query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_NET_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=NETWORK*" class="tryitbtnxl">Networking Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.net%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">os.unix.nmon.network.net »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.netpacket%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">os.unix.nmon.network.netpacket »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.neterror%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">os.unix.nmon.network.neterror »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name=$metric_name$ $osfilter$ by host, dimension_device
    +| `mapping_frameID`
    +| stats count by frameID, host, dimension_device | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate_metric">
    +        <query>| mcatalog values(metric_name) as metrics where `nmon_metrics_index` metric_name="os.unix.nmon.network.net*"
    +| rename metrics as metric_name
    +| mvexpand metric_name | fields metric_name | sort 0 metric_name</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <title>$metric_title$</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=$metric_name$ host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| $dataconvert$
    +| stats max(value) AS max_value, avg(value) AS avg_value, min(value) AS min_value, sparkline($statsmode$(value)) As sparkline by host, dimension_device
    +| sort limit=0 host
    +| eval value=round(value,2)
    +| fields host,dimension_device,max_value, avg_value, min_value,sparkline | eval avg_value=round(avg_value,2)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="network">
    +            <title>Network statistics</title>
    +            <chart>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=$metric_name$ host=$host-prefilter$ $host_query$ $device$ by host, metric_name, dimension_device span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| $dataconvert$
    +| eval key = host . ":" . dimension_device
    +| timechart $span$ limit=0 useother=f $statsmode$(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">$metric_label$</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_NFS.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_NFS.xml
    new file mode 100644
    index 0000000..f31024e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_NFS.xml
    @@ -0,0 +1,888 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI NFS, Network FileSystem Server / Client statistics</label>
    +    <description>User Interface for the NFS monitor</description>
    +
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +		    <change>
    +		        <unset token="form.refresh"></unset>
    +		    </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for NFS statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/network.png" alt="NET"/>
    +                                    <h1>Network File System statistics
    +                                    <br />
    +                                    (metric_name=os.unix.nmon.network.nfs*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Metrics links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.nfssvrv4*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">NFS SRV V4 »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.nfscliv4*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">NFS CLI V4 »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.nfssvrv3*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">NFS SRV V3 »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.nfscliv3*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">NFS CLI V3 »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.nfssvrv2*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">NFS SRV V2 »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.nfscliv2*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">NFS CLI V2 »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.net%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">os.unix.nmon.network.net »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.netpacket%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">os.unix.nmon.network.netpacket »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.neterror%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">os.unix.nmon.network.neterror »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.network.nfs*" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    NFS server / client: only show the panels if we have data
    +    -->
    +
    +    <!-- NFS v2 data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.network.nfs*v2.*" host=$host-prefilter$ $host_query$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_nfsv2_searches"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_nfsv2_searches">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- NFS v3 data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.network.nfs*v3.*" host=$host-prefilter$ $host_query$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_nfsv3_searches"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_nfsv3_searches">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <!-- NFS v4 data availability -->
    +
    +    <search>
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.network.nfs*v4.*" host=$host-prefilter$ $host_query$ | stats count | where count&gt;0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <progress>
    +            <condition match="$job.resultCount$ == 0">
    +                    <unset token="start_nfsv4_searches"></unset>
    +            </condition>
    +            <condition>
    +                    <set token="start_nfsv4_searches">true</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div class="custom">
    +                    <h1>Table Stats</h1>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$start_nfsv2_searches$">
    +        <panel>
    +            <table>
    +                <title>NFS Server V2</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv2.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics` | chart useother=f limit=0 avg(value) as value by host, metric
    +| foreach * [ eval &lt;&lt;FIELD&gt;&gt; = if(isnum('&lt;&lt;FIELD&gt;&gt;'), round('&lt;&lt;FIELD&gt;&gt;', 2), '&lt;&lt;FIELD&gt;&gt;') ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="spk">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>NFS Client V2</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv2.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics` | chart useother=f limit=0 avg(value) as value by host, metric
    +| foreach * [ eval &lt;&lt;FIELD&gt;&gt; = if(isnum('&lt;&lt;FIELD&gt;&gt;'), round('&lt;&lt;FIELD&gt;&gt;', 2), '&lt;&lt;FIELD&gt;&gt;') ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="spk">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row depends="$start_nfsv3_searches$">
    +        <panel>
    +            <table>
    +                <title>NFS Server V3</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv3.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics` | chart useother=f limit=0 avg(value) as value by host, metric
    +| foreach * [ eval &lt;&lt;FIELD&gt;&gt; = if(isnum('&lt;&lt;FIELD&gt;&gt;'), round('&lt;&lt;FIELD&gt;&gt;', 2), '&lt;&lt;FIELD&gt;&gt;') ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="spk">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>NFS Client V3</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv3.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics` | chart useother=f limit=0 avg(value) as value by host, metric
    +| foreach * [ eval &lt;&lt;FIELD&gt;&gt; = if(isnum('&lt;&lt;FIELD&gt;&gt;'), round('&lt;&lt;FIELD&gt;&gt;', 2), '&lt;&lt;FIELD&gt;&gt;') ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="spk">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row depends="$start_nfsv4_searches$">
    +        <panel>
    +            <table>
    +                <title>NFS Server V4</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv4.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics` | chart useother=f limit=0 avg(value) as value by host, metric
    +| foreach * [ eval &lt;&lt;FIELD&gt;&gt; = if(isnum('&lt;&lt;FIELD&gt;&gt;'), round('&lt;&lt;FIELD&gt;&gt;', 2), '&lt;&lt;FIELD&gt;&gt;') ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="spk">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>NFS Client V4</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv4.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics` | chart useother=f limit=0 avg(value) as value by host, metric
    +| foreach * [ eval &lt;&lt;FIELD&gt;&gt; = if(isnum('&lt;&lt;FIELD&gt;&gt;'), round('&lt;&lt;FIELD&gt;&gt;', 2), '&lt;&lt;FIELD&gt;&gt;') ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="spk">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <!-- NFS v2 -->
    +
    +    <row depends="$start_nfsv2_searches$">
    +        <panel>
    +
    +            <input type="link" token="nfsv2_linkinput">
    +                <label></label>
    +                <choice value="nfssvrv2">NFS Server v2</choice>
    +                <choice value="nfscliv2">NFS Client v2</choice>
    +                <default>nfssvrv2</default>
    +                <change>
    +                    <condition value="nfssvrv2">
    +                        <set token="show_nfssvrv2">true</set>
    +                        <unset token="show_nfscliv2"></unset>
    +                    </condition>
    +                    <condition value="nfscliv2">
    +                        <set token="show_nfscliv2">true</set>
    +                        <unset token="show_nfssvrv2"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$show_nfssvrv2$">
    +                <title></title>
    +                <search depends="$start_nfsv2_searches$ $show_nfssvrv2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv2.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">nb operations</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv2.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$show_nfscliv2$">
    +                <title></title>
    +                <search depends="$start_nfsv2_searches$ $show_nfscliv2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv2.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">nb operations</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv2.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- NFS v3 -->
    +
    +    <row depends="$start_nfsv3_searches$">
    +        <panel>
    +
    +            <input type="link" token="nfsv3_linkinput">
    +                <label></label>
    +                <choice value="nfssvrv3">NFS Server v3</choice>
    +                <choice value="nfscliv3">NFS Client v3</choice>
    +                <default>nfssvrv3</default>
    +                <change>
    +                    <condition value="nfssvrv3">
    +                        <set token="show_nfssvrv3">true</set>
    +                        <unset token="show_nfscliv3"></unset>
    +                    </condition>
    +                    <condition value="nfscliv3">
    +                        <set token="show_nfscliv3">true</set>
    +                        <unset token="show_nfssvrv3"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$show_nfssvrv3$">
    +                <title></title>
    +                <search depends="$start_nfsv3_searches$ $show_nfssvrv3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv3.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">nb operations</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv3.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$show_nfscliv3$">
    +                <title></title>
    +                <search depends="$start_nfsv3_searches$ $show_nfscliv3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv3.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">nb operations</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv3.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- NFS v4 -->
    +
    +    <row depends="$start_nfsv4_searches$">
    +        <panel>
    +
    +            <input type="link" token="nfsv4_linkinput">
    +                <label></label>
    +                <choice value="nfssvrv4">NFS Server v4</choice>
    +                <choice value="nfscliv4">NFS Client v4</choice>
    +                <default>nfssvrv4</default>
    +                <change>
    +                    <condition value="nfssvrv4">
    +                        <set token="show_nfssvrv4">true</set>
    +                        <unset token="show_nfscliv4"></unset>
    +                    </condition>
    +                    <condition value="nfscliv4">
    +                        <set token="show_nfscliv4">true</set>
    +                        <unset token="show_nfssvrv4"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$show_nfssvrv4$">
    +                <title></title>
    +                <search depends="$start_nfsv4_searches$ $show_nfssvrv4$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv4.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">nb operations</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfssvrv4.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$show_nfscliv4$">
    +                <title></title>
    +                <search depends="$start_nfsv4_searches$ $show_nfscliv4$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv4.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">nb operations</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                        search?earliest=$earliest$&latest=$latest$&q=| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.network.nfscliv4.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, metric, value
    +| timechart $span$ limit=0 useother=f avg(value) by metric
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_PAGE_AIX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_PAGE_AIX.xml
    new file mode 100644
    index 0000000..20fe2c7
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_PAGE_AIX.xml
    @@ -0,0 +1,497 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI PAGE, Paging Statistics (AIX)</label>
    +    <description>User Interface for the PAGE monitor</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +		    <change>
    +		        <unset token="form.refresh"></unset>
    +		    </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.page.*" by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for PAGE statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="CPU"/>
    +                                    <h1>AIX Paging Statistics (PAGE)</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>faults:</b> Total nbr of page faults taken per second over the monitoring interval. This includes page faults that do not cause paging activity</li>
    +                                            <li><b>pgspin:</b> The nbr of 4 K pages read from paging space per second over the monitoring interval</li>
    +                                            <li><b>pgsout:</b> The nbr of 4 K pages written to paging space per second over the monitoring interval</li>
    +                                            <li><b>pgin:</b> The nbr of 4 K pages read per second over the monitoring interval. This includes paging activity associated with reading from file systems. Subtract PgspIn from this value to get the number of 4K pages read from file systems per second over the monitoring interval</li>
    +                                            <li><b>pgout:</b> The nbr of 4 K pages written per second over the monitoring interval. This includes paging activity associated with writing to file systems. Subtract PgspOut from this value to get the number of 4K pages written to file systems per second over the monitoring interval</li>
    +                                        </lu>
    +                                    </div>
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>scans:</b> Nbr of page scans by clock</li>
    +                                            <li><b>reclaims:</b> Nbr of pages reclaims</li>
    +                                            <li><b>fsin:</b> Sum of pgsin / pgin per time interval</li>
    +                                            <li><b>fsout:</b> Sum of pgsout / pgout per time interval</li>
    +                                            <li><b>scanfree_ratio:</b> Scan Free Ratio, Pages scans by reclaims per time interval (scans/reclaims)</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.kernel.page.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.kernel.page.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=PROCESSES%20STATISTICS" class="tryitbtnxl">Processes Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <search id="tableStats">
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.page.*" host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics("faults pgin pgout pgsin pgsout reclaims scans cycles")`
    +| stats values(pgin) as pgin, values(pgout) as pgout, values(pgsin) as pgsin, values(pgsout) as pgsout, values(reclaims) as reclaims, values(scans) as scans, values(cycles) as cycles by _time host
    +| fillnull value=0 faults pgin pgout pgsin pgsout reclaims scans cycles
    +| eval scanfree_ratio=round((scans/reclaims),3), fsin=(pgin+pgsin), fsout=(pgout+pgsout)
    +| fillnull value="0" faults, pgin, pgout, pgsin, pgsout, reclaims, scans, cycles, fsin, fsout, scanfree_ratio
    +| stats
    +$statsmode$(faults) AS faults $statsmode$(pgin) AS pgin $statsmode$(pgout) AS pgout $statsmode$(pgsin) AS pgsin
    +$statsmode$(pgsout) AS pgsout $statsmode$(reclaims) AS reclaims $statsmode$(scans) AS scans
    +$statsmode$(cycles) AS cycles $statsmode$(fsin) AS fsin $statsmode$(fsout) AS fsout $statsmode$(scanfree_ratio) AS scanfree_ratio by host
    +| fields host, faults, pgin, pgout, pgsin, pgsout, reclaims, scans, cycles, fsin, fsout, scanfree_ratio
    +| fillnull value="0" faults, pgin, pgout, pgsin, pgsout, reclaims, scans, cycles, fsin, fsout, scanfree_ratio</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <search id="timeStats">
    +        <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.page.*" host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics("faults pgin pgout pgsin pgsout reclaims scans cycles")`
    +| stats values(pgin) as pgin, values(pgout) as pgout, values(pgsin) as pgsin, values(pgsout) as pgsout, values(reclaims) as reclaims, values(scans) as scans, values(cycles) as cycles by _time host
    +| fillnull value=0 faults pgin pgout pgsin pgsout reclaims scans cycles
    +| eval scanfree_ratio=round((scans/reclaims),3), fsin=(pgin+pgsin), fsout=(pgout+pgsout)
    +| fillnull value="0" faults, pgin, pgout, pgsin, pgsout, reclaims, scans, cycles, fsin, fsout, scanfree_ratio
    +| timechart $span$ useother=f limit=0
    +$statsmode$(faults) AS faults $statsmode$(pgin) AS pgin $statsmode$(pgout) AS pgout $statsmode$(pgsin) AS pgsin
    +$statsmode$(pgsout) AS pgsout $statsmode$(reclaims) AS reclaims $statsmode$(scans) AS scans
    +$statsmode$(cycles) AS cycles $statsmode$(fsin) AS fsin $statsmode$(fsout) AS fsout $statsmode$(scanfree_ratio) AS scanfree_ratio by host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Global Table Stats</title>
    +                <search base="tableStats">
    +                    <query>fields host,faults,pgin,pgout,pgsin,pgsout,reclaims,scans,cyles</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +
    +                <format type="color" field="faults">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="pgin">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="pgout">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="pgsin">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="pgsout">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="reclaims">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="scans">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="cyles">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +        <panel>
    +            <table>
    +                <title>Fs In/Out and Scan Free Ratio Table Stats</title>
    +                <search base="tableStats">
    +                    <query>fields host,fsin,fsout,scanfree_ratio</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="fsin">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="fsout">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="scanfree_ratio">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Paging statistics</title>
    +
    +            <input type="link" token="linkinput">
    +                <label></label>
    +                <choice value="chart1">Pages In / Pages Out (pgsin / pgsout, pgin / pgout)</choice>
    +                <choice value="chart2">Fs In / Fs Out (sum of pgin/pgsin and pgout/pgsout per interval)</choice>
    +                <choice value="chart3">Scan Free Ratio (Pages scans by reclaims per interval)</choice>
    +                <default>chart1</default>
    +                <change>
    +                    <condition value="chart1">
    +                        <set token="chart1">true</set>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                    </condition>
    +                    <condition value="chart2">
    +                        <set token="chart2">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart3"></unset>
    +                    </condition>
    +                    <condition value="chart3">
    +                        <set token="chart3">true</set>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$chart1$">
    +                <title></title>
    +                <search base="timeStats">
    +                    <query>fields _time,pgsin*,pgsout*,pgin*,pgout*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart2$">
    +                <title></title>
    +                <search base="timeStats">
    +                    <query>fields _time,fsin*,fsout*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart3$">
    +                <title></title>
    +                <search base="timeStats">
    +                    <query>fields _time,scanfree_ratio*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_POOLS.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_POOLS.xml
    new file mode 100644
    index 0000000..f9ff952
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_POOLS.xml
    @@ -0,0 +1,496 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI POOLS, IBM Pseries POOLS statistics</label>
    +    <description>User Interface for the POOLS monitor and IBM PSeries Pools usage statistics</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +		    <change>
    +		        <unset token="form.refresh"></unset>
    +		    </change>
    +        </input>
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="device" type="multiselect" token="device" searchWhenChanged="true">
    +            <label>Pool IDs: (0 for DefaultPool)</label>
    +            <search base="populate">
    +                <query>stats count by PoolID | dedup PoolID | sort 0 PoolID</query>
    +            </search>
    +            <valuePrefix>PoolID="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>PoolID</fieldForLabel>
    +            <fieldForValue>PoolID</fieldForValue>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="aggregate" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="fields *">Single Series</choice>
    +            <choice value="stats avg(*) AS * by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Average by Time interval</choice>
    +            <choice value="stats avg(*) AS * by _time, frameID | eval host='frameID'">Average by Time interval,frameID</choice>
    +            <choice value="stats max(*) AS * by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Max by Time interval</choice>
    +            <choice value="stats max(*) AS * by _time, frameID | eval host='frameID'">Max by Time interval,frameID</choice>
    +            <choice value="stats sum(*) AS * by _time | eval frameID=&quot;aggreg_frameID&quot; | eval host=&quot;aggreg_host&quot;">Sum by Time interval</choice>
    +            <choice value="stats sum(*) AS * by _time, frameID | eval host='frameID'">Sum by Time interval,frameID</choice>
    +            <default>fields *</default>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="monitor" searchWhenChanged="true">
    +            <label>Show CPU load by:</label>
    +            <default>pool_busy_time</default>
    +            <choice value="pool_busy_time">pool_busy_time</choice>
    +            <choice value="shcpu_busy_time">shcpu_busy_time</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.pools.*" by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host
    +| lookup nmon_inventory hostname as host OUTPUT AIX_PoolID as PoolID
    +| fillnull value="0" PoolID</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Global Search -->
    +
    +    <search id="Global">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.pools.max_pool_capacity" OR metric_name="os.unix.nmon.cpu.pools.entitled_pool_capacity" OR metric_name="os.unix.nmon.cpu.pools.$monitor$") host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `extract_metrics("max_pool_capacity entitled_pool_capacity $monitor$")`
    +| stats values(max_pool_capacity) as max_pool_capacity, values(entitled_pool_capacity) as entitled_pool_capacity, values($monitor$) as $monitor$ by _time, host
    +| `$timefilter$`
    +| `mapping_frameID`
    +| lookup nmon_inventory hostname as host OUTPUT AIX_PoolID as PoolID
    +| fillnull value="0" PoolID
    +| search $device$
    +| $aggregate$
    +| sort limit=0 _time
    +| stats min($monitor$) As min_usage, avg($monitor$) As avg_usage, max($monitor$) As max_usage, latest(max_pool_capacity) AS max_pool_capacity, latest(entitled_pool_capacity) AS entitled_pool_capacity, sparkline($statsmode$($monitor$)) As sparkline by frameID, host
    +| sort limit=0 frameID | eval avg_usage=round(avg_usage,3)
    +| lookup nmon_inventory hostname as host OUTPUT AIX_PoolID as PoolID
    +| fillnull value="0" PoolID</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for POOLS statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                                    <h1>CPU global percentage statistics for IBM PSeries Pools</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    <i>The POOLS monitor contains IBM Power partitions specific CPU statistics.</i>
    +                                    <br />
    +                                    <i>These metrics are available only for IBM Pseries and partitions running AIX.</i>
    +
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main metrics/fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>max/avg/min_usage:</b> Virtual CPU statistics of the Pool the partition belongs to</li>
    +                                            <li><b>Pool ID:</b> POOL Identifier that the lpar belongs to (the DefaultPool will always have a 0 ID)</li>
    +                                            <li><b>max_pool_capacity:</b> Max Number of Virtual Processor affected to the Pool the lpar belongs to</li>
    +                                            <li><b>entitled_pool_capacity:</b> Entitled (minimal guarantee) Number of Virtual Processor affected to the Pool the lpar belongs to</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.cpu.lpar.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m%0A%7C%20%60def_lpar_pool_load_aix_cores%60" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_LPAR_partitions_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_Summary" class="tryitbtnxl">NMON SUMMARY Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Nmon_ANALYSER_AIX" class="tryitbtnxl">NMON ANALYSER Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=CPU%20USAGE%20STATISTICS" class="tryitbtnxl">CPU Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.lpar.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats max(max_usage) AS max</query>
    +                </search>
    +                <option name="underLabel">Maximum Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">cores</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats avg(avg_usage) AS avg | eval avg=round(avg,2)</query>
    +                </search>
    +                <option name="underLabel">Average Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">cores</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <single>
    +                <search base="Global">
    +                    <query>stats min(min_usage) AS min</query>
    +                </search>
    +                <option name="underLabel">Minimal Load</option>
    +                <option name="unitPosition">after</option>
    +                <option name="unit">cores</option>
    +                <option name="numberPrecision">0.00</option>
    +                <option name="refresh.display">preview</option>
    +            </single>
    +
    +            <table>
    +                <search base="Global">
    +                    <query>foreach max_usage,avg_usage,min_usage [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 2) ]
    +| fields frameID, host, min_usage, avg_usage, max_usage, Pool_id, entitled_pool_capacity, max_pool_capacity, sparkline</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_usage">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="cpu">
    +            <title>Shared Pool CPU statistics</title>
    +
    +            <input type="dropdown" token="addindicator" searchWhenChanged="true">
    +                <label>Pool additional Series:</label>
    +                <default>none</default>
    +                <choice value="">none</choice>
    +                <choice value="max(max_pool_capacity) AS max_pool_capacity">max_pool_capacity</choice>
    +                <choice value="max(entitled_pool_capacity) AS entitled_pool_capacity">entitled_pool_capacity</choice>
    +                <choice value="max(entitled_pool_capacity) AS entitled_pool_capacity, max(max_pool_capacity) AS max_pool_capacity">max_pool_capacity / entitled_pool_capacity</choice>
    +            </input>
    +
    +            <chart>
    +                <search id="timechart">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.cpu.pools.max_pool_capacity" OR metric_name="os.unix.nmon.cpu.pools.entitled_pool_capacity" OR metric_name="os.unix.nmon.cpu.pools.$monitor$") host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `extract_metrics("max_pool_capacity entitled_pool_capacity $monitor$")`
    +| stats values(max_pool_capacity) as max_pool_capacity, values(entitled_pool_capacity) as entitled_pool_capacity, values($monitor$) as $monitor$ by _time, host
    +| `$timefilter$`
    +| `mapping_frameID`
    +| lookup nmon_inventory hostname as host OUTPUT AIX_PoolID as PoolID
    +| fillnull value="0" PoolID
    +| search $device$
    +| $aggregate$
    +| timechart $span$ useother=f limit=0 $statsmode$($monitor$) as $monitor$ $addindicator$ by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">cores</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_PROC.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_PROC.xml
    new file mode 100644
    index 0000000..5cb60fb
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_PROC.xml
    @@ -0,0 +1,554 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI PROC, Kernel Internal Statistics</label>
    +    <description>User Interface for the PROC monitor</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.proc.*" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for PROC statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="CPU"/>
    +                                    <h1>
    +                                        Kernel Internal Statistics
    +                                        <br />
    +                                        (metric_name=os.unix.nmon.kernel.proc.*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>runqueue:</b> Average number of threads that are ready to run but are waiting for an available processor</li>
    +                                            <li><b>swapin:</b> Number of processes in swap queue per second in the interval</li>
    +                                            <li><b>pswitch:</b> Number of processor switches per second in the interval</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>syscall:</b> Number of system calls per second in the interval</li>
    +                                            <li><b>exec:</b> Number of execs per second in the interval</li>
    +                                            <li><b>fork:</b> Number of forks per second in the interval</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.kernel.proc.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.kernel.proc.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <search id="baseSearch">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.proc.Runnable OR metric_name=os.unix.nmon.kernel.proc.Swap-in OR metric_name=os.unix.nmon.kernel.proc.pswitch OR metric_name=os.unix.nmon.kernel.proc.syscall OR metric_name=os.unix.nmon.kernel.proc.fork OR metric_name=os.unix.nmon.kernel.proc.exec host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, frameID, host, metric, value
    +| eval {metric}=value
    +| fillnull value="0" Runnable Swap-in pswitch syscall fork exec
    +| stats
    +$statsmode$(Runnable) As "RunQueue", sparkline($statsmode$(Runnable)) As "spk_RunQueue",
    +$statsmode$(Swap-in) As "Swap-in", sparkline($statsmode$(Swap-in)) As "spk_Swap-in",
    +$statsmode$(pswitch) As "pswitch/sec", sparkline($statsmode$(pswitch)) As "spk_pswitch/sec",
    +$statsmode$(syscall) As "syscall/sec", sparkline($statsmode$(syscall)) As "spk_syscall/sec",
    +$statsmode$(fork) As "fork/sec", sparkline($statsmode$(fork)) As "spk_fork/sec",
    +$statsmode$(exec) As "exec/sec", sparkline($statsmode$(exec)) As "spk_exec/sec" by host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Kernel Threads in run queue and to be paged - Table Stats</title>
    +                <search base="baseSearch">
    +                    <query>fields frameID,host,"RunQueue","Swap-in","spk_RunQueue","spk_Swap-in"</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="spk_RunQueue">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="sparkline" field="spk_Swap-in">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="RunQueue">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="Swap_in">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Context switches, System / Fork / Exec calls - Table Stats</title>
    +                <search base="baseSearch">
    +                    <query>fields frameID,host,"pswitch/sec","syscall/sec","fork/sec","exec/sec","spk_pswitch/sec","spk_syscall/sec","spk_fork/sec","spk_exec/sec"</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="spk_pswitch/sec">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="sparkline" field="spk_syscall/sec">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="sparkline" field="spk_fork/sec">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="sparkline" field="spk_exec/sec">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="pswitch/sec">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="syscall/sec">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="fork/sec">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="exec/sec">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Kernel internal statistics</title>
    +
    +            <input type="link" token="linkinput">
    +                <label></label>
    +                <choice value="chart1">Kernel Threads in run queue and to be paged (RunQueue, Swap-In)</choice>
    +                <choice value="chart2">Context switches and system calls (pswitch, syscall)</choice>
    +                <choice value="chart3">Fork and Exec system calls (fork, exec)</choice>
    +                <default>chart1</default>
    +                <change>
    +                    <condition value="chart1">
    +                        <set token="chart1">true</set>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                    </condition>
    +                    <condition value="chart2">
    +                        <set token="chart2">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart3"></unset>
    +                    </condition>
    +                    <condition value="chart3">
    +                        <set token="chart3">true</set>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart1"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +            
    +            <chart depends="$chart1$">
    +                <title></title>
    +                <search depends="$chart1$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.proc.Runnable OR metric_name=os.unix.nmon.kernel.proc.Swap-in host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, host, metric, value
    +| eval {metric}=value
    +| fillnull value="0" Runnable Swap-in
    +| timechart $span$ useother=f limit=0
    +$statsmode$(Runnable) AS Runnable $statsmode$(Swap-in) AS Swap-in by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rates per Second</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart2$">
    +                <title></title>
    +                <search depends="$chart2$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.proc.pswitch OR metric_name=os.unix.nmon.kernel.proc.syscall host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, host, metric, value
    +| eval {metric}=value
    +| fillnull value="0" pswitch syscall
    +| timechart $span$ useother=f limit=0
    +$statsmode$(pswitch) AS pswitch $statsmode$(syscall) AS syscall by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rates per Second</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart3$">
    +                <title></title>
    +                <search depends="$chart3$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.proc.fork OR metric_name=os.unix.nmon.kernel.proc.exec host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, host, metric, value
    +| eval {metric}=value
    +| fillnull value="0" fork exec
    +| timechart $span$ useother=f limit=0
    +$statsmode$(fork) AS fork $statsmode$(exec) AS exec by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Rates per Second</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_PROCSOL_SOLARIS.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_PROCSOL_SOLARIS.xml
    new file mode 100644
    index 0000000..d8a5e54
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_PROCSOL_SOLARIS.xml
    @@ -0,0 +1,455 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI PROCSOL, Percentage of Time Processes have spent in (Solaris)</label>
    +    <description>User Interface for the Solaris PROCSOL monitor</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>TimeRange:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.kernel.procsol.*" by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="BaseSearch">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.procsol.USR OR metric_name=os.unix.nmon.kernel.procsol.SYS OR metric_name=os.unix.nmon.kernel.procsol.TRP OR metric_name=os.unix.nmon.kernel.procsol.TFL OR metric_name=os.unix.nmon.kernel.procsol.DFL OR metric_name=os.unix.nmon.kernel.procsol.LAT host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, host, metric, value
    +| eval {metric}=value
    +| fillnull value="0" USR SYS TRP TFL DFL LAT
    +| stats
    +$statsmode$(USR) As "USR (%time in User Mode)", sparkline($statsmode$(USR)) As "spk_USR",
    +$statsmode$(SYS) As "SYS (%time in System Mode)", sparkline($statsmode$(SYS)) As "spk_SYS",
    +$statsmode$(TRP) As "TRP (%time Processing system traps)", sparkline($statsmode$(TRP)) As "spk_TRP",
    +$statsmode$(TFL) As "TFL (%time Processing text page faults)", sparkline($statsmode$(TFL)) As "spk_TFL",
    +$statsmode$(DFL) As "DFL (%time Processing data page faults)", sparkline($statsmode$(DFL)) As "spk_DFL",
    +$statsmode$(LAT) As "LAT (%time Waiting for CPU)", sparkline($statsmode$(LAT)) As "spk_LAT" by host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for PROCSOL statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="CPU"/>
    +                                    <h1>
    +                                        Percentage of Time Processes have spent in
    +                                        <br />
    +                                        (metric_name=os.unix.nmon.kernel.procsol.*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>USR (%):</b> The percentage of time all processes have spent in user mode (estimation since terminated processes are not accounted)</li>
    +                                            <li><b>SYS (%):</b> The percentage of time all processes have spent in system mode (estimation since terminated processes are not accounted)</li>
    +                                            <li><b>TRP (%):</b> The percentage of time all processes have spent in processing system traps (estimation since terminated processes are not accounted)</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>TFL (%):</b> The percentage of time all processes have spent processing text page faults (estimation since terminated processes are not accounted)</li>
    +                                            <li><b>DFL (%):</b> The percentage of time all processes have spent processing data page faults (estimation since terminated processes are not accounted)</li>
    +                                            <li><b>LAT (%):</b> The percentage of time all processes have spent waiting for CPU (estimation since terminated processes are not accounted)</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.kernel.procsol.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.kernel.procsol.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search base="BaseSearch">
    +                    <query>fields host, "USR (%time in User Mode)", "spk_USR","SYS (%time in System Mode)", "spk_SYS","TRP (%time Processing system traps)","spk_TRP"</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="sparkline" field="spk_USR">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="sparkline" field="spk_SYS">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="sparkline" field="spk_TRP">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="USR (%time in User Mode)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="SYS (%time in System Mode)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="TRP (%time Processing system traps)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <table>
    +                <title/>
    +                <search base="BaseSearch">
    +                    <query>fields, host, "TFL (%time Processing text page faults)", "spk_TFL", "DFL (%time Processing data page faults)", "spk_DFL", "LAT (%time Waiting for CPU)", "spk_LAT"</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="spk_TFL">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="sparkline" field="spk_DFL">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="sparkline" field="spk_LAT">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="TFL (%time Processing text page faults)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="DFL (%time Processing data page faults)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="LAT (%time Waiting for CPU)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Processes statistics</title>
    +            <chart>
    +                <title>Chart - Percentage of Time All processes have spent in: (estimation since terminated processes are not accounted)</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.kernel.procsol.USR OR metric_name=os.unix.nmon.kernel.procsol.SYS OR metric_name=os.unix.nmon.kernel.procsol.TRP OR metric_name=os.unix.nmon.kernel.procsol.TFL OR metric_name=os.unix.nmon.kernel.procsol.DFL OR metric_name=os.unix.nmon.kernel.procsol.LAT host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| fields _time, host, metric, value
    +| eval {metric}=value
    +| fillnull value="0" USR SYS TRP TFL DFL LAT
    +| timechart $span$ useother=f limit=0
    +$statsmode$(USR) As "USR (%time in User Mode)", $statsmode$(SYS) As "SYS (%time in System Mode)", $statsmode$(TRP) As "TRP (%time Processing system traps)",
    +$statsmode$(TFL) As "TFL (%time Processing text page faults)", $statsmode$(DFL) As "DFL (%time Processing data page faults)",
    +$statsmode$(LAT) As "LAT (%time Waiting for CPU)" by host</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">% Of Time</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisY2.enabled">false</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_SEA.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_SEA.xml
    new file mode 100644
    index 0000000..41c5083
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_SEA.xml
    @@ -0,0 +1,466 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI SEA, Ethernet (Shared and Physical) Adapters Traffic Analysis</label>
    +    <description>User Interface for the SEA monitor (IBM PSeries Vios)</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="monitor" searchWhenChanged="true">
    +            <label>Monitor:</label>
    +            <default>os.unix.nmon.adapters.sea</default>
    +            <choice value="os.unix.nmon.adapters.sea">SEA - Shared Ethernet Adapter Traffic</choice>
    +            <choice value="os.unix.nmon.adapters.seachphy">SEACHPHY - Physical Adapter Traffic</choice>
    +            <choice value="os.unix.nmon.adapters.seapacket">SEAPACKET - Number of read/write packets</choice>
    +            <change>
    +                <condition value="os.unix.nmon.adapters.sea">
    +                    <set token="metric_has_rate">True</set>
    +                    <set token="metric_label">Network traffic</set>
    +                </condition>
    +                <condition value="os.unix.nmon.adapters.seachphy">
    +                    <set token="metric_has_rate">True</set>
    +                    <set token="metric_label">Network traffic</set>
    +                </condition>
    +                <condition value="os.unix.nmon.adapters.seapacket">
    +                    <unset token="metric_has_rate"></unset>
    +                    <set token="metric_label">Network packets</set>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input id="device" type="multiselect" token="device" searchWhenChanged="true">
    +            <label>Interfaces Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ $host$
    +| stats count by dimension_device | dedup dimension_device | sort 0 dimension_device</query>
    +            </search>
    +            <valuePrefix>dimension_device="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <initialValue>*</initialValue>
    +            <choice value="*">ALL Devices</choice>
    +            <fieldForLabel>dimension_device</fieldForLabel>
    +            <fieldForValue>dimension_device</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="fields *">Single Series</choice>
    +            <choice value="stats dedup_splitvals=t avg(value) AS value by _time, host, dimension_device | eval dimension_device=&quot;aggreg_dimension_device&quot; | eval frameID=&quot;aggreg_frameID&quot;">Average by Time interval, host</choice>
    +            <choice value="stats dedup_splitvals=t avg(value) AS value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_dimension_device&quot; | eval frameID=&quot;aggreg_frameID&quot;">Average by Time interval</choice>
    +            <choice value="stats dedup_splitvals=t max(value) AS value by _time, host, dimension_device | eval dimension_device=&quot;aggregate&quot; | eval frameID=&quot;aggreg_frameID&quot;">Max by Time interval, host</choice>
    +            <choice value="stats dedup_splitvals=t max(value) AS value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_dimension_device&quot; | eval frameID=&quot;aggreg_frameID&quot;">Max by Time interval</choice>
    +            <choice value="stats dedup_splitvals=t sum(value) AS value by _time, host, dimension_device | eval dimension_device=&quot;aggregate&quot; | eval frameID=&quot;aggreg_frameID&quot;">Sum by Time interval, host</choice>
    +            <choice value="stats dedup_splitvals=t sum(value) AS value by _time | eval host=&quot;aggreg_host&quot; | eval dimension_device=&quot;aggreg_dimension_device&quot; | eval frameID=&quot;aggreg_frameID&quot;">Sum by Time interval</choice>
    +            <default>fields *</default>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="dataconvert" searchWhenChanged="true" depends="$metric_has_rate$">
    +            <label>Data Conversion:</label>
    +            <default>eval value=round((value),2)</default>
    +            <choice value="eval value=round((value/1000),2) | rex mode=sed field=dimension_device &quot;s/KB/MB/&quot;">MBps</choice>
    +            <choice value="eval value=round((value/1000/1000),2) | rex mode=sed field=dimension_device &quot;s/KB/GB/&quot;">GBps</choice>
    +            <choice value="eval value=round((value),2)">KBps</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$ $show_no_hosts_found$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_no_hosts_found$" rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>
    +                    Oops! We're sorry but we could't find any server...
    +                    <br />
    +                    Consider adjusting the search time range or your selection.
    +                    </p>
    +                </div>
    +                <div style="text-align: left;">
    +                    <p>
    +                    <br />
    +                    ADDITIONAL INFORMATION:
    +                    <br />
    +                    The Shared Ethernet adapter (SEA) VIOS collection for AIX requires the "-O" option at nmon startup time.
    +                    <br />
    +                    This option can be configured either on a per deployment basis in your local/nmon.conf or on a per server basis in /etc/nmon.conf.
    +                    </p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row depends="$host$" rejects="$device$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please select associated devices to be analysed in the device selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for Network statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/network.png" alt="NET"/>
    +                                    <h1>Ethernet (Shared and Physical) Adapters Traffic Analysis
    +                                        <br />(os.unix.nmon.adapters.sea*)</h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Metrics &amp; dimensions:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>dimension_device:</b> Name of the network interface</li>
    +                                            <li><b>value:</b> Various (depending on selected device)</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_device)%20as%20dimension_device%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.adapters.sea*%20host%3D*" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.adapters.sea*%20host%3D*%20by%20metric_name%2C%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_device)%20as%20dimension_device%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.net%20host%3D*" class="tryitbtnxl">os.unix.nmon.network.net »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_device)%20as%20dimension_device%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.neterror%20host%3D*" class="tryitbtnxl">os.unix.nmon.network.neterror »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_device)%20as%20dimension_device%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.network.netpacket%20host%3D*" class="tryitbtnxl">os.unix.nmon.network.netpacket »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name=$monitor$ by host, dimension_device
    +| `mapping_frameID`
    +| stats count by frameID, host, dimension_device | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <done>
    +            <condition match="'job.resultCount' == 0">
    +                <set token="show_no_hosts_found">true</set>
    +            </condition>
    +            <condition>
    +                <unset token="show_no_hosts_found"></unset>
    +            </condition>
    +        </done>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <search id="tablestats">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=$monitor$ host=$host-prefilter$ $host_query$ $device$ by host, dimension_device span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| $dataconvert$
    +| stats max(value) AS max_value, avg(value) AS avg_value, min(value) AS min_value, sparkline($statsmode$(value)) As sparkline by host, dimension_device
    +| sort limit=0 host
    +| eval value=round(value,2)
    +| fields host,dimension_device,max_value,avg_value,min_value,sparkline | eval avg_value=round(avg_value,2)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="network">
    +            <title>Shared Ethernet Adapters statistics</title>
    +            <chart>
    +                <search id="timechart">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=$monitor$ host=$host-prefilter$ $host_query$ $device$ by host, dimension_device span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| $dataconvert$
    +| eval key = host . ":" . dimension_device
    +| timechart $span$ limit=0 useother=f $statsmode$(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">$metric_label$</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_STORAGE.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_STORAGE.xml
    new file mode 100644
    index 0000000..df60f06
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_STORAGE.xml
    @@ -0,0 +1,789 @@
    +<form stylesheet="ui_simple.css,panel_decoration.css,table_data_bar.css" script="table_data_bar.js,modal.js" isVisible="true" version="1.1" theme="dark">
    +    <label>UI STORAGE, utilization statistics of file systems</label>
    +    <description>User Interface for file systems related statistics (DF_STORAGE, DF_INODES)</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>*</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input type="dropdown" token="datasource" searchWhenChanged="true">
    +            <label>Metric collection:</label>
    +            <default>DF_STORAGE</default>
    +            <choice value="DF_STORAGE">DF_STORAGE (volume usage statistics)</choice>
    +            <choice value="JFSFILE">JFSFILE (volume pct only usage statistics)</choice>
    +            <choice value="DF_INODES">DF_INODES (volume inodes usage statistics)</choice>
    +            <change>
    +                <condition value="DF_STORAGE">
    +                        <set token="metric_name">os.unix.nmon.storage.df_storage</set>
    +                        <set token="start_df_storage_search">true</set>
    +                        <unset token="start_jfsfile_storage_search"></unset>
    +                        <unset token="start_df_inodes_search"></unset>
    +                </condition>
    +                <condition value="JFSFILE">
    +                        <set token="metric_name">os.unix.nmon.storage.jfsfile</set>
    +                        <set token="start_jfsfile_storage_search">true</set>
    +                        <unset token="start_df_storage_search"></unset>
    +                        <unset token="start_df_inodes_search"></unset>
    +                </condition>
    +                <condition value="DF_INODES">
    +                        <set token="metric_name">os.unix.nmon.storage.df_inodes</set>
    +                        <set token="start_df_inodes_search">true</set>
    +                        <unset token="start_df_storage_search"></unset>
    +                        <unset token="start_jfsfile_storage_search"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="multiselect" token="mount" searchWhenChanged="true">
    +            <label>mount Selection:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ $host$
    +| stats count by dimension_mount | dedup dimension_mount | sort 0 dimension_mount</query>
    +            </search>
    +            <valuePrefix>dimension_mount="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <initialValue>*</initialValue>
    +            <choice value="*">ALL</choice>
    +            <fieldForLabel>dimension_mount</fieldForLabel>
    +            <fieldForValue>dimension_mount</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="fsfilter" searchWhenChanged="true">
    +            <label>Filter FileSystems by pattern:</label>
    +            <default>*</default>
    +            <prefix>dimension_mount="</prefix>
    +            <suffix>"</suffix>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Help the user -->
    +
    +    <row depends="$host$" rejects="$mount$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p> - - - - - - - - - - ACTION REQUIRED: please select associated devices to be analysed in the device selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- ################################ -->
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for file systems statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/drive.png" alt="drive"/>
    +                                    <h1>STORAGE - File systems utilisation statistics (os.unix.nmon.storage.df_storage*/df_storage*/jfsfile)</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <h1>DF_STORAGE - raw metrics and dimensions:</h1>
    +
    +                                    External collection which runs the Unix "df -k" command in POSIX mode and is available for all operating systems, the following fields and statistics are available:
    +
    +                                    <br />
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>dimension_filesystem:</b> logical name of the device associated with the file system</li>
    +                                            <li><b>dimension_mount:</b> mount point of the file system</li>
    +                                            <li><b>blocks:</b> size of the file system in KB</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Used:</b> volume used the file system in KB</li>
    +                                            <li><b>Use_pct:</b> volume used on the file system in percentage</li>
    +                                            <li><b>Available:</b> volume free on the file system in KB</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <h1>DF_INODES - raw metrics and dimensions:</h1>
    +
    +                                    External collection which runs the Unix "df -i" command in POSIX mode and is available for all operating systems, the following fields and statistics are available:
    +
    +                                    <br />
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>dimension_filesystem:</b> logical name of the device associated with the file system</li>
    +                                            <li><b>dimension_mount:</b> mount point of the file system</li>
    +                                            <li><b>Inodes:</b> number of inodes of the file system (Linux only)</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>IFree:</b> number of free inodes on the file system in KB (Linux only)</li>
    +                                            <li><b>IUsed:</b> number of used inodes the file system in KB</li>
    +                                            <li><b>IUse_pct:</b> inodes used on the file system in percentage</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <h1>JFSFILE - raw metrics and dimensions:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>dimension_mount:</b> mount point of the file system</li>
    +                                            <li><b>value:</b> number of inodes of the file system (Linux only)</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <br />
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_mount)%20as%20dimension_mount%20values(dimension_filesystem)%20as%20dimension_filesystem%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.df_storage*%20host%3D*" class="tryitbtnxl">mcatalog df_storage »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.df_storage*%20host%3D*%20by%20metric_name%2C%20host%20dimension_mount%20span%3D1m" class="tryitbtnxl">mstats df_storage raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_mount)%20as%20dimension_mount%20values(dimension_filesystem)%20as%20dimension_filesystem%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.df_inodes*%20host%3D*" class="tryitbtnxl">mcatalog df_inodes »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.df_inodes*%20host%3D*%20by%20metric_name%2C%20host%20dimension_mount%20span%3D1m" class="tryitbtnxl">mstats df_inodes raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_mount)%20as%20dimension_mount%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.jfsfile%20host%3D*" class="tryitbtnxl">mcatalog jfsfile »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.storage.jfsfile%20host%3D*%20by%20metric_name%2C%20host%20dimension_mount%20span%3D1m" class="tryitbtnxl">mstats jfsfile raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_DISK_spl" class="tryitbtnxl">HOWTO Interface for disks»
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=FILESYSTEMS%20STATISTICS" class="tryitbtnxl">filesystems Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name=$metric_name$* $osfilter$ by host, dimension_mount
    +| `mapping_frameID`
    +| stats count by frameID, host, dimension_mount | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <input type="dropdown" token="table_count">
    +                <label>Nb table lines:</label>
    +                <choice value="10">10</choice>
    +                <choice value="50">50</choice>
    +                <choice value="100">100</choice>
    +                <default>10</default>
    +            </input>
    +
    +            <input type="dropdown" token="df_storage_monitor_unit" depends="$start_df_storage_search$">
    +                <label>Unit:</label>
    +                <choice value="MB">MB</choice>
    +                <choice value="GB">GB</choice>
    +                <choice value="TB">TB</choice>
    +                <default>GB</default>
    +                <change>
    +                    <condition value="MB">
    +                        <set token="df_storage_unit_math">/1024</set>
    +                        <set token="df_storage_unit_legend">MB</set>
    +                    </condition>
    +                    <condition value="GB">
    +                        <set token="df_storage_unit_math">/1024/1024</set>
    +                        <set token="df_storage_unit_legend">GB</set>
    +                    </condition>
    +                    <condition value="TB">
    +                        <set token="df_storage_unit_math">/1024/1024/1024</set>
    +                        <set token="df_storage_unit_legend">TB</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="df_storage_monitor_add_global_stats" depends="$start_df_storage_search$">
    +                <label>Append global stats:</label>
    +                <choice value="true">true</choice>
    +                <choice value="false">false</choice>
    +                <default>true</default>
    +                <change>
    +                    <condition value="true">
    +                        <set token="df_storage_monitor_add_global_stats_tk">where like(mount, &quot;%&quot;)</set>
    +                    </condition>
    +                    <condition value="false">
    +                        <set token="df_storage_monitor_add_global_stats_tk">where NOT like(mount, &quot;*** TOTAL GB / AVERAGE % ****&quot;)</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <table id="tablebar" depends="$start_df_storage_search$">
    +                <title>Latest known values within the period for the following file systems:</title>
    +                <search depends="$start_df_storage_search$">
    +                    <query>| mstats latest(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.storage.df_storage.Available OR metric_name=os.unix.nmon.storage.df_storage.Use_pct OR metric_name=os.unix.nmon.storage.df_storage.Used OR metric_name=os.unix.nmon.storage.df_storage.blocks host=$host-prefilter$ $host_query$ $mount$ $fsfilter$ by host, metric_name, dimension_mount
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)
    +| stats last(Available) as Available, last(Use_pct) as Use_pct, last(Used) as Used, last(blocks) as blocks by host, dimension_mount
    +| rename dimension_mount as mount
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free
    +| foreach storage, storage_free, storage_used [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;'$df_storage_unit_math$, 2) ]
    +| foreach storage*percent [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ]
    +| rename storage as "storage ($df_storage_unit_legend$)", storage_free as "storage free ($df_storage_unit_legend$)", storage_used as "storage used ($df_storage_unit_legend$)", storage_free_percent as "storage free (%)", storage_used_percent as "storage used (%)"
    +| eval UsedPct=if(isnum('storage used (%)'), 'storage used (%)', 0 )
    +| fields host, mount, "storage ($df_storage_unit_legend$)", "storage free ($df_storage_unit_legend$)", "storage used ($df_storage_unit_legend$)", "storage free (%)", "storage used (%)", UsedPct
    +| appendpipe [ stats sum("storage ($df_storage_unit_legend$)") as "storage ($df_storage_unit_legend$)", sum("storage free ($df_storage_unit_legend$)") as "storage free ($df_storage_unit_legend$)", sum("storage used ($df_storage_unit_legend$)") as "storage used ($df_storage_unit_legend$)" ]
    +| eval "storage free (%)" = if(isnull('storage free (%)'), (('storage free ($df_storage_unit_legend$)'/'storage ($df_storage_unit_legend$)')*100), 'storage free (%)'), "storage used (%)" = if(isnull('storage used (%)'), (('storage used ($df_storage_unit_legend$)'/'storage ($df_storage_unit_legend$)')*100), 'storage used (%)'), UsedPct = if(isnull(UsedPct), 'storage used (%)', UsedPct)
    +| fillnull value="*** TOTAL $df_storage_unit_legend$ / AVERAGE % ****" mount
    +| foreach storage*%* UsedPct [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;', 2) ] | $df_storage_monitor_add_global_stats_tk$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">$table_count$</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="storage used (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +            <table id="tablebar1" depends="$start_jfsfile_storage_search$">
    +                <title></title>
    +                <search depends="$start_jfsfile_storage_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsfile" host=$host-prefilter$ $host_query$ $mount$ $fsfilter$ by host, dimension_mount span=1m
    +| stats max(value) AS max_value, avg(value) AS avg_value, min(value) AS min_value, latest(value) AS UsedPct by host, dimension_mount
    +| sort limit=0 dimension_mount | rename dimension_mount AS "Mount point"
    +| eval value=round(value,2)
    +| fields host, "Mount point", max_value, avg_value, min_value, UsedPct | eval avg_value=round(avg_value,2)
    +| rename max_value AS "Max value in period (%)", avg_value AS "Average value in period (%)", min_value AS "Min value in Period (%)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">$table_count$</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="max_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +            <table id="tablebar2" depends="$start_df_inodes_search$">
    +                <title>Latest known values within the period for the following file systems:</title>
    +                <search depends="$start_df_inodes_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.storage.df_inodes.IFree OR metric_name=os.unix.nmon.storage.df_inodes.IUse_pct OR metric_name=os.unix.nmon.storage.df_inodes.IUsed OR metric_name=os.unix.nmon.storage.df_inodes.Inodes host=$host-prefilter$ $host_query$ $mount$ $fsfilter$ by host, metric_name, dimension_mount span=1m
    +| `extract_metrics("Inodes IFree IUse_pct IUsed IUse_pct")`
    +| stats values(Inodes) as Inodes values(IFree) as IFree, values(IUsed) as IUsed, values(IUse_pct) as IUse_pct by _time, host, dimension_mount
    +| fillnull value=0 IUse_pct
    +| stats latest(Inodes) as "storage_inodes (Inodes)" latest(IFree) as "storage_free_inodes (IFree)", latest(IUsed) as "storage_used_inodes (Used)", latest(IUse_pct) as "storage_used_inodes_percent (IUse_pct)" by host, dimension_mount
    +| eval UsedPct=if(isnum('storage_used_inodes_percent (IUse_pct)'), 'storage_used_inodes_percent (IUse_pct)', 0 )</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">$table_count$</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <format type="color" field="storage inodes used (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row depends="$start_df_storage_search$">
    +        <panel>
    +            <title>File systems utilization evolution over time</title>
    +
    +            <input type="dropdown" token="chart_df_storage_monitor">
    +                <label>Monitor:</label>
    +                <choice value="storage">storage (volume size)</choice>
    +                <choice value="storage_free">storage_free (volume free)</choice>
    +                <choice value="storage_used">storage_used (volume used)</choice>
    +                <choice value="storage_free_percent">storage_free_percent (%)</choice>
    +                <choice value="storage_used_percent">storage_used_percent (%)</choice>
    +                <default>storage_used_percent</default>
    +                <change>
    +                    <condition value="storage">
    +                        <set token="chart_df_storage_metric_name">metric_name=os.unix.nmon.storage.df_storage.blocks</set>
    +                        <unset token="form.chart_df_storage_monitor_unit"></unset>
    +                        <set token="chart_df_storage_show_unit">true</set>
    +                        <unset token="chart_df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_free">
    +                        <set token="chart_df_storage_metric_name">metric_name=os.unix.nmon.storage.df_storage.Available</set>
    +                        <unset token="form.chart_df_storage_monitor_unit"></unset>
    +                        <set token="chart_df_storage_show_unit">true</set>
    +                        <unset token="chart_df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_used">
    +                        <set token="chart_df_storage_metric_name">metric_name=os.unix.nmon.storage.df_storage.Used</set>
    +                        <unset token="form.chart_df_storage_monitor_unit"></unset>
    +                        <set token="chart_df_storage_show_unit">true</set>
    +                        <unset token="chart_df_storage_monitor_max_chart"></unset>
    +                    </condition>
    +                    <condition value="storage_free_percent">
    +                        <set token="chart_df_storage_metric_name">metric_name=os.unix.nmon.storage.df_storage.Use_pct</set>
    +                        <set token="chart_df_storage_unit">%</set>
    +                        <unset token="chart_df_storage_show_unit"></unset>
    +                        <set token="chart_df_storage_monitor_max_chart">101</set>
    +                        <set token="chart_df_storage_unit_legend">pct</set>
    +                    </condition>
    +                    <condition value="storage_used_percent">
    +                        <set token="chart_df_storage_metric_name">metric_name=os.unix.nmon.storage.df_storage.Use_pct</set>
    +                        <set token="form.chart_df_storage_monitor_unit">pct</set>
    +                        <set token="chart_df_storage_monitor_max_chart">101</set>
    +                        <unset token="chart_df_storage_show_unit"></unset>
    +                        <set token="chart_df_storage_unit_legend">pct</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" token="chart_df_storage_monitor_unit" depends="$chart_df_storage_show_unit$">
    +                <label>Unit:</label>
    +                <choice value="MB">MB</choice>
    +                <choice value="GB">GB</choice>
    +                <choice value="TB">TB</choice>
    +                <default>GB</default>
    +                <change>
    +                    <condition value="MB">
    +                        <set token="chart_df_storage_unit_math">value</set>
    +                        <set token="chart_df_storage_unit_legend">MB</set>
    +                    </condition>
    +                    <condition value="GB">
    +                        <set token="chart_df_storage_unit_math">value/1024</set>
    +                        <set token="chart_df_storage_unit_legend">GB</set>
    +                    </condition>
    +                    <condition value="TB">
    +                        <set token="chart_df_storage_unit_math">value/1024/1204</set>
    +                        <set token="chart_df_storage_unit_legend">TB</set>
    +                    </condition>
    +                    <condition value="pct">
    +                        <set token="chart_df_storage_unit_math">value</set>
    +                        <set token="chart_df_storage_unit_legend">pct</set>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="multiselect" token="mount" searchWhenChanged="true">
    +                <label>mount Selection:</label>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate">
    +                    <query>search $frameID$ $host$
    +    | stats count by dimension_mount | dedup dimension_mount | sort 0 dimension_mount</query>
    +                </search>
    +                <valuePrefix>dimension_mount="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <initialValue>*</initialValue>
    +                <choice value="*">ALL</choice>
    +                <fieldForLabel>dimension_mount</fieldForLabel>
    +                <fieldForValue>dimension_mount</fieldForValue>
    +            </input>
    +
    +            <input type="text" token="fsfilter" searchWhenChanged="true">
    +                <label>Filter FileSystems by pattern:</label>
    +                <default>*</default>
    +                <prefix>dimension_mount="</prefix>
    +                <suffix>"</suffix>
    +            </input>
    +
    +            <chart>
    +                <search depends="$start_df_storage_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` $chart_df_storage_metric_name$ host=$host-prefilter$ $host_query$ $mount$ $fsfilter$ by host, metric_name, dimension_mount span=1m
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free
    +| foreach storage, storage_free, storage_used [ eval &lt;&lt;FIELD&gt;&gt; = round('&lt;&lt;FIELD&gt;&gt;'/1024, 2) ]
    +| stats latest(storage*) as "storage*" by _time, dimension_mount, host
    +| eval value=$chart_df_storage_monitor$
    +| eval value=$chart_df_storage_unit_math$
    +| eval key = host . ":" . dimension_mount
    +| timechart $span$ latest(value) as $chart_df_storage_monitor$ by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
    +                <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
    +                <option name="charting.axisTitleX.visibility">collapsed</option>
    +                <option name="charting.axisTitleY.text">$chart_df_storage_unit_legend$</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisTitleY2.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.axisY2.enabled">0</option>
    +                <option name="charting.axisY2.scale">inherit</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.showDataLabels">none</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">none</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">bottom</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">$df_storage_monitor_max_chart$</option>
    +            </chart>
    +        </panel>
    +
    +    </row>
    +
    +    <row depends="$start_jfsfile_storage_search$">
    +        <panel>
    +            <title>File systems utilization evolution over time</title>
    +
    +            <input type="multiselect" token="mount" searchWhenChanged="true">
    +                <label>mount Selection:</label>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate">
    +                    <query>search $frameID$ $host$
    +    | stats count by dimension_mount | dedup dimension_mount | sort 0 dimension_mount</query>
    +                </search>
    +                <valuePrefix>dimension_mount="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <initialValue>*</initialValue>
    +                <choice value="*">ALL</choice>
    +                <fieldForLabel>dimension_mount</fieldForLabel>
    +                <fieldForValue>dimension_mount</fieldForValue>
    +            </input>
    +
    +            <input type="text" token="fsfilter" searchWhenChanged="true">
    +                <label>Filter FileSystems by pattern:</label>
    +                <default>*</default>
    +                <prefix>dimension_mount="</prefix>
    +                <suffix>"</suffix>
    +            </input>
    +
    +            <chart>
    +                <search depends="$start_jfsfile_storage_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.jfsfile" host=$host-prefilter$ $host_query$ $mount$ $fsfilter$ by host, dimension_mount span=1m
    +| eval key = host . ":" . dimension_mount
    +| timechart $span$ limit=0 useother=f latest(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% Used</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +
    +    <row depends="$start_df_inodes_search$">
    +        <panel>
    +            <title>File systems utilization evolution over time</title>
    +
    +            <input type="multiselect" token="mount" searchWhenChanged="true">
    +                <label>mount Selection:</label>
    +                <!-- Populating Data Model Search -->
    +                <search base="populate">
    +                    <query>search $frameID$ $host$
    +    | stats count by dimension_mount | dedup dimension_mount | sort 0 dimension_mount</query>
    +                </search>
    +                <valuePrefix>dimension_mount="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <initialValue>*</initialValue>
    +                <choice value="*">ALL</choice>
    +                <fieldForLabel>dimension_mount</fieldForLabel>
    +                <fieldForValue>dimension_mount</fieldForValue>
    +            </input>
    +
    +            <input type="text" token="fsfilter" searchWhenChanged="true">
    +                <label>Filter FileSystems by pattern:</label>
    +                <default>*</default>
    +                <prefix>dimension_mount="</prefix>
    +                <suffix>"</suffix>
    +            </input>
    +
    +            <chart>
    +                <search depends="$start_df_inodes_search$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_inodes.IUse_pct" host=$host-prefilter$ $host_query$ $mount$ $fsfilter$ by host, dimension_mount span=1m
    +| eval key = host . ":" . dimension_mount
    +| timechart $span$ limit=0 useother=f latest(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">connect</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">500</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisTitleY.text">% Used</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisY.maximumNumber">100</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_TOP_AIX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_TOP_AIX.xml
    new file mode 100644
    index 0000000..13166db
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_TOP_AIX.xml
    @@ -0,0 +1,875 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI TOP, AIX Processes System Resources statistics</label>
    +    <description>User Interface for the TOP monitor on AIX Systems</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>AIX</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate_input" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="none">Single Series</choice>
    +            <choice value="sum">Sum by Time interval</choice>
    +            <choice value="avg">Average by Time interval</choice>
    +            <choice value="median">Median by Time interval</choice>
    +            <choice value="max">Max by Time interval</choice>
    +            <default>none</default>
    +            <change>
    +                <condition value="none">
    +                    <set token="aggregate">fields *</set>
    +                    <set token="form.timechart_by">key</set>
    +                    <set token="form.table_by">host,dimension_Command</set>
    +                </condition>
    +                <condition value="sum">
    +                    <set token="aggregate">stats sum(*) as &quot;*&quot; by _time, dimension_Command | eval host=&quot;aggreg_host&quot;</set>
    +                    <set token="form.timechart_by">dimension_Command</set>
    +                    <set token="form.table_by">dimension_Command</set>
    +                </condition>
    +                <condition value="avg">
    +                    <set token="aggregate">stats avg(*) as &quot;*&quot; by _time, dimension_Command | eval host=&quot;aggreg_host&quot;</set>
    +                    <set token="form.timechart_by">dimension_Command</set>
    +                    <set token="form.table_by">dimension_Command</set>
    +                </condition>
    +                <condition value="median">
    +                    <set token="aggregate">stats median(*) as &quot;*&quot; by _time, dimension_Command | eval host=&quot;aggreg_host&quot;</set>
    +                    <set token="form.timechart_by">dimension_Command</set>
    +                    <set token="form.table_by">dimension_Command</set>
    +                </condition>
    +                <condition value="max">
    +                    <set token="aggregate">stats max(*) as &quot;*&quot; by _time, dimension_Command | eval host=&quot;aggreg_host&quot;</set>
    +                    <set token="form.timechart_by">dimension_Command</set>
    +                    <set token="form.table_by">dimension_Command</set>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.*" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="populate_command">
    +        <query>| mcatalog values(dimension_Command) as commands where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.*" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host
    +| rename commands as dimension_Command
    +| stats count by dimension_Command</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for TOP statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="CPU"/>
    +                                    <h1>Processes statistics (metric_name=os.unix.nmon.processes.top.*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div>
    +                                    The TOP monitor captures processes statistics for system resources metrics such as CPU, memory and more.
    +                                    <br />
    +                                    This section is available in any supported operating systems, but some metrics are specifics for some systems.
    +                                    <br />
    +                                    The <b>UARG monitor</b> is associated with the TOP monitor as it will capture the full list of processes arguments.
    +                                    <br />
    +                                    Processes statistics are generated at the PID level for a given "Command" invocation, as such, calculation will aggregate statistics of all PIDs for that given Command.
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>raw metrics and dimensions:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>dimension_Command:</b> The name of the global command that generated the process</li>
    +                                            <li><b>dimension_PID:</b> The PID number of the process</li>
    +                                            <li><b>pct_CPU:</b> (%) average amount of CPU used by this process</li>
    +                                            <li><b>pct_Usr:</b> (%) average amount of user-mode CPU used by this process</li>
    +                                            <li><b>pct_Sys:</b> (%) average amount of kernel-mode CPU used by this process</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Size:</b> The size of the pages in kilobytes.</li>
    +                                            <li><b>ResSet:</b> The sum of real-memory data used by the process</li>
    +                                            <li><b>ResText:</b> The real-memory text size of the process.</li>
    +                                            <li><b>ResData:</b> The real-memory data size of the process.</li>
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.processes.top.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20dimension_Command%3D*%20dimension_PID%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20sum(_value)%20as%20pct_CPU%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.pct_CPU%20host%3D*%20dimension_Command%3D*%20by%20dimension_Command%20span%3D1m%0A%7C%20eval%20usage_per_core%3D(pct_CPU%2F100)%0A%7C%20timechart%20%60nmon_span%60%20useother%3Df%20limit%3D50%20max(usage_per_core)%20as%20usage_per_core%20by%20dimension_Command" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_TOP_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=PROCESSES%20STATISTICS" class="tryitbtnxl">Processes Data Dictionary »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?form.osfilter=Linux" class="tryitbtnxl">Bubblechart dashboard »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +        <title>Processes filtering:</title>
    +
    +            <input type="text" token="Command" searchWhenChanged="true">
    +                <label>Optional: Filter by Command</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="text" token="PID" searchWhenChanged="true">
    +                <label>Optional: Filter by PIDs</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="multiselect" token="Command_multiselect" searchWhenChanged="true">
    +                <label>Command(s):</label>
    +                <search base="populate_command">
    +                    <query>sort 0 dimension_Command</query>
    +                </search>
    +                <iniialValue>*</iniialValue>
    +                <valuePrefix>dimension_Command="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">Any</choice>
    +                <fieldForLabel>dimension_Command</fieldForLabel>
    +                <fieldForValue>dimension_Command</fieldForValue>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>area</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>zero</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>stacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Active drilldown: click on a command invocation to get detailed PIDs statistics of that command (may be truncated with large number of PIDs)</title>
    +
    +            <input type="text" token="valuefilter" searchWhenChanged="true" depends="$top_chart1$">
    +                <label>Filter values:</label>
    +                <default>usage_per_core>0</default>
    +            </input>
    +
    +            <input type="text" token="limit" searchWhenChanged="true">
    +                <label>Max series:</label>
    +                <default>50</default>
    +                <prefix>limit=</prefix>
    +            </input>
    +
    +            <input type="dropdown" token="timechart_by" searchWhenChanged="true">
    +                <label>group by statement:</label>
    +                <default>key</default>
    +                <choice value="key">host:Command</choice>
    +                <choice value="dimension_Command">Command</choice>
    +            </input>
    +
    +            <input type="link" token="top_linkinput">
    +                <label></label>
    +                <choice value="top_chart1">CPU Usage per logical core</choice>
    +                <choice value="top_chart2">Memory Usage per command invocation</choice>
    +                <choice value="top_chart3">Read / Write System Calls</choice>
    +                <choice value="top_chart4">Paging, Sum of page faults</choice>
    +                <choice value="top_chart5">Threads per Command invocation</choice>
    +                <choice value="uarg">UARG: commands arguments</choice>
    +                <default>top_chart1</default>
    +                <change>
    +                    <condition value="top_chart1">
    +                        <set token="top_chart1">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart2">
    +                        <set token="top_chart2">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart3">
    +                        <set token="top_chart3">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart4">
    +                        <set token="top_chart4">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart5">
    +                        <set token="top_chart5">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="uarg">
    +                        <set token="uarg">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$top_chart1$">
    +                <title></title>
    +                <search depends="$top_chart1$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| lookup nmon_inventory hostname as host OUTPUT AIX_logicalcores as logical_cpus, AIX_virtualcpus as virtual_cpus
    +| eval usage_per_core=(pct_CPU/100), smt_threads=(logical_cpus/virtual_cpus)
    +| eval usage_per_core=case(isnum(smt_threads) AND smt_threads&gt;="2", usage_per_core*1.2, isnum(smt_threads) AND smt_threads&gt;="4", usage_per_core*1.4, isnum(usage_per_core), usage_per_core)
    +| fields _time, host,dimension_Command,usage_per_core
    +| $aggregate$
    +| where ($valuefilter$)
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(usage_per_core) as "CPU Usage per core" by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Logical Core</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as pct_CPU where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| eval usage_per_core=(pct_CPU/100)
    +| lookup nmon_inventory hostname as host OUTPUT AIX_logicalcores as logical_cpus, AIX_virtualcpus as virtual_cpus
    +| eval usage_per_core=(pct_CPU/100), smt_threads=(logical_cpus/virtual_cpus)
    +| eval usage_per_core=case(isnum(smt_threads) AND smt_threads&gt;="2", usage_per_core*1.2, isnum(smt_threads) AND smt_threads&gt;="4", usage_per_core*1.4, isnum(usage_per_core), usage_per_core)
    +| fields _time, host,dimension_Command,usage_per_core
    +| $aggregate$
    +| where ($valuefilter$)
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(usage_per_core) as "CPU Usage per core" by key | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart2$">
    +                <title></title>
    +                <search depends="$top_chart2$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSet" OR metric_name="os.unix.nmon.processes.top.ResData" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| eval Used_Mem_MB=((value)/1024)
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(Used_Mem_MB) as "memory usage (MB)" by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSet" OR metric_name="os.unix.nmon.processes.top.ResData" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| eval Used_Mem_MB=((value)/1024)
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(Used_Mem_MB) as "memory usage (MB)" by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart3$">
    +                <title></title>
    +                <search depends="$top_chart3$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.CharIO" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":"
    +| timechart $span$ $limit$ useother=f $statsmode$(value) as "CharIO" by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.CharIO" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by dimension_Command dimension_PID span=1m
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(value) as "CharIO" by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart4$">
    +                <title></title>
    +                <search depends="$top_chart4$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Paging" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(value) as Paging by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/sec</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Paging" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(value) as Paging by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*
    +| fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart5$">
    +                <title></title>
    +                <search depends="$top_chart5$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Threads" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(value) as Threads by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/sec</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Threads" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(value) as Threads by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <input type="text" token="Command" depends="$uarg$" searchWhenChanged="true">
    +                <label>Optional: Filter by Command</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="text" token="PID" depends="$uarg$" searchWhenChanged="true">
    +                <label>Optional: Filter by PIDs</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="multiselect" token="Command_multiselect" depends="$uarg$" searchWhenChanged="true">
    +                <label>Command(s):</label>
    +                <search base="populate_command">
    +                    <query>sort 0 dimension_Command</query>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>COMM="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">Any</choice>
    +                <fieldForLabel>dimension_Command</fieldForLabel>
    +                <fieldForValue>dimension_Command</fieldForValue>
    +            </input>
    +
    +            <event depends="$uarg$">
    +                <title></title>
    +                <search depends="$uarg$">
    +                    <query>eventtype=nmon:events type=UARG host=$host-prefilter$ $host_query$ ($frameID$) (COMM=$Command$) (PID=$PID$)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="count">10</option>
    +                <option name="list.drilldown">full</option>
    +                <option name="list.wrap">1</option>
    +                <option name="maxLines">0</option>
    +                <option name="raw.drilldown">full</option>
    +                <option name="rowNumbers">0</option>
    +                <option name="table.drilldown">1</option>
    +                <option name="table.wrap">1</option>
    +                <option name="type">list</option>
    +                <option name="refresh.display">none</option>
    +                <fields>[]</fields>
    +            </event>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <search id="uarg_definition">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition>
    +                <set token="metric_filter">$result.metric_filter$</set>
    +                <set token="metric_calculation">$result.metric_calculation$</set>
    +                <set token="metric_has_device">$result.metric_has_device$</set>
    +                <set token="metric_dimension_field">$result.metric_dimension_field$</set>
    +                <set token="metric_shortname">$result.metric_shortname$</set>
    +                <set token="metric_data_field">$result.metric_data_field$</set>
    +                <set token="metric_primary_statsmode">$result.metric_primary_statsmode$</set>
    +                <set token="metric_by">$result.metric_by$</set>
    +                <set token="metric_timechart_by">$result.metric_timechart_by$</set>
    +                <set token="metric_volume_unit_choice">$result.metric_volume_unit_choice$</set>
    +                <set token="metric_rate_unit_choice">$result.metric_rate_unit_choice$</set>
    +                <set token="form.chart">$result.metric_charting_chart$</set>
    +                <set token="form.chart.stackingmode">$result.metric_charting_stackmode$</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +
    +    <row>
    +        <panel>
    +            <input type="dropdown" token="table_by" searchWhenChanged="true">
    +                <label>group by statement:</label>
    +                <default>host,dimension_Command</default>
    +                <choice value="host,dimension_Command">host:Command</choice>
    +                <choice value="dimension_Command">Command</choice>
    +            </input>
    +            <table>
    +                <title>Table stats: CPU Usage per logical core</title>
    +                <search>
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| $aggregate$
    +| eval usage_per_core=(pct_CPU/100)
    +| stats $statsmode$(usage_per_core) as "CPU Usage per Logical Cores", sparkline($statsmode$(usage_per_core)) As sparkline by $table_by$
    +| rename dimension_Command as Command
    +| eval "CPU Usage per Logical Cores"=round('CPU Usage per Logical Cores', 3)
    +| sort - "CPU Usage per Logical Cores"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="CPU Usage per Logical Cores">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +        <panel>
    +            <input type="dropdown" token="table_by" searchWhenChanged="true">
    +                <label>group by statement:</label>
    +                <default>host,dimension_Command</default>
    +                <choice value="host,dimension_Command">host:Command</choice>
    +                <choice value="dimension_Command">Command</choice>
    +            </input>
    +            <table>
    +                <title>Table stats: Memory Usage per command invocation</title>
    +                <search>
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSet" OR metric_name="os.unix.nmon.processes.top.ResData" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| eval Used_Mem_MB=((value)/1024)
    +| stats sum(Used_Mem_MB) As Used_Mem_MB by _time, host, dimension_Command
    +| $aggregate$
    +| stats $statsmode$(Used_Mem_MB) as "Used Memory per Command (MB)", sparkline($statsmode$(Used_Mem_MB)) as sparkline by $table_by$
    +| rename dimension_Command as Command
    +| eval "Used Memory per Command (MB)"=round('Used Memory per Command (MB)', 3)
    +| sort - "Used Memory per Command (MB)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="Used Memory per Command (MB)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_TOP_LINUX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_TOP_LINUX.xml
    new file mode 100644
    index 0000000..eb06b3a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_TOP_LINUX.xml
    @@ -0,0 +1,1051 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI TOP, Linux Processes System Resources statistics</label>
    +    <description>User Interface for the TOP monitor on Linux Systems</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>Linux</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="">Any OS</choice>
    +            <choice value="Linux">Linux</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate_input" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="none">Single Series</choice>
    +            <choice value="sum">Sum by Time interval</choice>
    +            <choice value="avg">Average by Time interval</choice>
    +            <choice value="median">Median by Time interval</choice>
    +            <choice value="max">Max by Time interval</choice>
    +            <default>none</default>
    +            <change>
    +                <condition value="none">
    +                    <set token="aggregate">fields *</set>
    +                    <set token="form.timechart_by">key</set>
    +                    <set token="form.table_by">host,dimension_Command</set>
    +                </condition>
    +                <condition value="sum">
    +                    <set token="aggregate">stats sum(*) as &quot;*&quot; by _time, dimension_Command | eval host=&quot;aggreg_host&quot;</set>
    +                    <set token="form.timechart_by">dimension_Command</set>
    +                    <set token="form.table_by">dimension_Command</set>
    +                </condition>
    +                <condition value="avg">
    +                    <set token="aggregate">stats avg(*) as &quot;*&quot; by _time, dimension_Command | eval host=&quot;aggreg_host&quot;</set>
    +                    <set token="form.timechart_by">dimension_Command</set>
    +                    <set token="form.table_by">dimension_Command</set>
    +                </condition>
    +                <condition value="median">
    +                    <set token="aggregate">stats median(*) as &quot;*&quot; by _time, dimension_Command | eval host=&quot;aggreg_host&quot;</set>
    +                    <set token="form.timechart_by">dimension_Command</set>
    +                    <set token="form.table_by">dimension_Command</set>
    +                </condition>
    +                <condition value="max">
    +                    <set token="aggregate">stats max(*) as &quot;*&quot; by _time, dimension_Command | eval host=&quot;aggreg_host&quot;</set>
    +                    <set token="form.timechart_by">dimension_Command</set>
    +                    <set token="form.table_by">dimension_Command</set>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.*" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="populate_command">
    +        <query>| mcatalog values(dimension_Command) as commands where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.*" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host
    +| rename commands as dimension_Command
    +| stats count by dimension_Command</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for TOP statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="CPU"/>
    +                                    <h1>Processes statistics (metric_name=os.unix.nmon.processes.top.*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div>
    +                                    The TOP monitor captures processes statistics for system resources metrics such as CPU, memory and more.
    +                                    <br />
    +                                    This section is available in any supported operating systems, but some metrics are specifics for some systems.
    +                                    <br />
    +                                    The <b>UARG monitor</b> is associated with the TOP monitor as it will capture the full list of processes arguments.
    +                                    <br />
    +                                    Processes statistics are generated at the PID level for a given "Command" invocation, as such, calculation will aggregate statistics of all PIDs for that given Command.
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>raw metrics and dimensions:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>dimension_Command:</b> The name of the global command that generated the process</li>
    +                                            <li><b>dimension_PID:</b> The PID number of the process</li>
    +                                            <li><b>pct_CPU:</b> (%) average amount of CPU used by this process</li>
    +                                            <li><b>pct_Usr:</b> (%) average amount of user-mode CPU used by this process</li>
    +                                            <li><b>pct_Sys:</b> (%) average amount of kernel-mode CPU used by this process</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Size:</b> The size of the pages in kilobytes.</li>
    +                                            <li><b>ResSet:</b> The sum of real-memory data used by the process</li>
    +                                            <li><b>ResText:</b> The real-memory text size of the process.</li>
    +                                            <li><b>ResData:</b> The real-memory data size of the process.</li>
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.processes.top.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20dimension_Command%3D*%20dimension_PID%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20sum(_value)%20as%20pct_CPU%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.pct_CPU%20host%3D*%20dimension_Command%3D*%20by%20dimension_Command%20span%3D1m%0A%7C%20eval%20usage_per_core%3D(pct_CPU%2F100)%0A%7C%20timechart%20%60nmon_span%60%20useother%3Df%20limit%3D50%20max(usage_per_core)%20as%20usage_per_core%20by%20dimension_Command" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_TOP_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=PROCESSES%20STATISTICS" class="tryitbtnxl">Processes Data Dictionary »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?form.osfilter=Linux" class="tryitbtnxl">Bubblechart dashboard »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +        <title>Processes filtering:</title>
    +
    +            <input type="text" token="Command" searchWhenChanged="true">
    +                <label>Optional: Filter by Command</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="text" token="PID" searchWhenChanged="true">
    +                <label>Optional: Filter by PIDs</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="multiselect" token="Command_multiselect" searchWhenChanged="true">
    +                <label>Command(s):</label>
    +                <search base="populate_command">
    +                    <query>sort 0 dimension_Command</query>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>dimension_Command="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">Any</choice>
    +                <fieldForLabel>dimension_Command</fieldForLabel>
    +                <fieldForValue>dimension_Command</fieldForValue>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>area</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>zero</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>stacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Active drilldown: click on a command invocation to get detailed PIDs statistics of that command (may be truncated with large number of PIDs)</title>
    +
    +            <input type="text" token="valuefilter" searchWhenChanged="true" depends="$top_chart1$">
    +                <label>Filter values:</label>
    +                <default>usage_per_core>0</default>
    +            </input>
    +
    +            <input type="text" token="limit" searchWhenChanged="true">
    +                <label>Max series:</label>
    +                <default>50</default>
    +                <prefix>limit=</prefix>
    +            </input>
    +
    +            <input type="dropdown" token="timechart_by" searchWhenChanged="true">
    +                <label>group by statement:</label>
    +                <default>key</default>
    +                <choice value="key">host:Command</choice>
    +                <choice value="dimension_Command">Command</choice>
    +            </input>
    +
    +            <input type="link" token="top_linkinput">
    +                <label></label>
    +                <choice value="top_chart1">CPU Usage per logical core</choice>
    +                <choice value="top_chart2">Memory Usage per command invocation</choice>
    +                <choice value="top_chart3">Virtual Memory Usage per command invocation</choice>
    +                <choice value="top_chart4">MinorFault per Command invocation</choice>
    +                <choice value="top_chart5">MajorFault per Command invocation</choice>
    +                <choice value="top_chart6">Shared library pages per Command invocation</choice>
    +                <choice value="top_chart7">Number of Threads per Command invocation</choice>
    +                <choice value="top_chart8">IOwaitTime per Command invocation</choice>
    +                <choice value="uarg">UARG: commands arguments</choice>
    +                <default>top_chart1</default>
    +                <change>
    +                    <condition value="top_chart1">
    +                        <set token="top_chart1">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="top_chart7"></unset>
    +                        <unset token="top_chart8"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart2">
    +                        <set token="top_chart2">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="top_chart7"></unset>
    +                        <unset token="top_chart8"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart3">
    +                        <set token="top_chart3">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="top_chart7"></unset>
    +                        <unset token="top_chart8"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart4">
    +                        <set token="top_chart4">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="top_chart7"></unset>
    +                        <unset token="top_chart8"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart5">
    +                        <set token="top_chart5">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="top_chart7"></unset>
    +                        <unset token="top_chart8"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart6">
    +                        <set token="top_chart6">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart7"></unset>
    +                        <unset token="top_chart8"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart7">
    +                        <set token="top_chart7">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="top_chart8"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart8">
    +                        <set token="top_chart8">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="top_chart7"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="uarg">
    +                        <set token="uarg">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="top_chart7"></unset>
    +                        <unset token="top_chart8"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$top_chart1$">
    +                <title></title>
    +                <search depends="$top_chart1$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| $aggregate$
    +| where ($valuefilter$)
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(usage_per_core) as "CPU Usage per core" by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Logical Core</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as pct_CPU where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| eval usage_per_core=(pct_CPU/100)
    +| $aggregate$
    +| where ($valuefilter$)
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(usage_per_core) as "CPU Usage per core" by key | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart2$">
    +                <title></title>
    +                <search depends="$top_chart2$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSet" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| eval Used_Mem_MB=((value)/1024)
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(Used_Mem_MB) as "memory usage (MB)" by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSet" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| eval Used_Mem_MB=((value)/1024)
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(Used_Mem_MB) as "memory usage (MB)" by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart3$">
    +                <title></title>
    +                <search depends="$top_chart3$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Size" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| eval Virtual_Mem_MB=((value)/1024)
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":"
    +| timechart $span$ $limit$ useother=f $statsmode$(Virtual_Mem_MB) as "Virtual_Mem usage (MB)" by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Size" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| eval Virtual_Mem_MB=((value)/1024)
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(Virtual_Mem_MB) as "Virtual_Mem usage (MB)" by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart4$">
    +                <title></title>
    +                <search depends="$top_chart4$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.MinorFault" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(value) as MinorFault by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/sec</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.MinorFault" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(value) as MinorFault by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*
    +| fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart5$">
    +                <title></title>
    +                <search depends="$top_chart5$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.MajorFault" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(value) as MajorFault by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/sec</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.MajorFault" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(value) as MajorFault by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart6$">
    +                <title></title>
    +                <search depends="$top_chart6$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ShdLib" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as ShdLib by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/sec</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ShdLib" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ useother=f limit=0 avg(value) as ShdLib by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart7$">
    +                <title></title>
    +                <search depends="$top_chart7$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Threads" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as Threads by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Nb threads</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Threads" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ useother=f limit=0 avg(value) as Threads by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart8$">
    +                <title></title>
    +                <search depends="$top_chart8$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.IOwaitTime" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command span=1m
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as IOwaitTime by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">I/O wait time</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.IOwaitTime" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ useother=f limit=0 avg(value) as IOwaitTime by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <input type="text" token="Command" depends="$uarg$" searchWhenChanged="true">
    +                <label>Optional: Filter by Command</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="text" token="PID" depends="$uarg$" searchWhenChanged="true">
    +                <label>Optional: Filter by PIDs</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="multiselect" token="Command_multiselect" depends="$uarg$" searchWhenChanged="true">
    +                <label>Command(s):</label>
    +                <search base="populate_command">
    +                    <query>sort 0 dimension_Command</query>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>ProgName="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">Any</choice>
    +                <fieldForLabel>dimension_Command</fieldForLabel>
    +                <fieldForValue>dimension_Command</fieldForValue>
    +            </input>
    +
    +            <event depends="$uarg$">
    +                <title></title>
    +                <search depends="$uarg$">
    +                    <query>eventtype=nmon:events type=UARG host=$host-prefilter$ $host_query$ ($frameID$) (ProgName=$Command$) (PID=$PID$)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="count">10</option>
    +                <option name="list.drilldown">full</option>
    +                <option name="list.wrap">1</option>
    +                <option name="maxLines">0</option>
    +                <option name="raw.drilldown">full</option>
    +                <option name="rowNumbers">0</option>
    +                <option name="table.drilldown">1</option>
    +                <option name="table.wrap">1</option>
    +                <option name="type">list</option>
    +                <option name="refresh.display">none</option>
    +                <fields>[]</fields>
    +            </event>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <search id="uarg_definition">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition>
    +                <set token="metric_filter">$result.metric_filter$</set>
    +                <set token="metric_calculation">$result.metric_calculation$</set>
    +                <set token="metric_has_device">$result.metric_has_device$</set>
    +                <set token="metric_dimension_field">$result.metric_dimension_field$</set>
    +                <set token="metric_shortname">$result.metric_shortname$</set>
    +                <set token="metric_data_field">$result.metric_data_field$</set>
    +                <set token="metric_primary_statsmode">$result.metric_primary_statsmode$</set>
    +                <set token="metric_by">$result.metric_by$</set>
    +                <set token="metric_timechart_by">$result.metric_timechart_by$</set>
    +                <set token="metric_volume_unit_choice">$result.metric_volume_unit_choice$</set>
    +                <set token="metric_rate_unit_choice">$result.metric_rate_unit_choice$</set>
    +                <set token="form.chart">$result.metric_charting_chart$</set>
    +                <set token="form.chart.stackingmode">$result.metric_charting_stackmode$</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +
    +    <row>
    +        <panel>
    +            <input type="dropdown" token="table_by" searchWhenChanged="true">
    +                <label>group by statement:</label>
    +                <default>host,dimension_Command</default>
    +                <choice value="host,dimension_Command">host:Command</choice>
    +                <choice value="dimension_Command">Command</choice>
    +            </input>
    +            <table>
    +                <title>Table stats: CPU Usage per logical core</title>
    +                <search>
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| $aggregate$
    +| eval usage_per_core=(pct_CPU/100)
    +| stats $statsmode$(usage_per_core) as "CPU Usage per Logical Cores", sparkline($statsmode$(usage_per_core)) As sparkline by $table_by$
    +| rename dimension_Command as Command
    +| eval "CPU Usage per Logical Cores"=round('CPU Usage per Logical Cores', 3)
    +| sort - "CPU Usage per Logical Cores"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="CPU Usage per Logical Cores">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +        <panel>
    +            <input type="dropdown" token="table_by" searchWhenChanged="true">
    +                <label>group by statement:</label>
    +                <default>host,dimension_Command</default>
    +                <choice value="host,dimension_Command">host:Command</choice>
    +                <choice value="dimension_Command">Command</choice>
    +            </input>
    +            <table>
    +                <title>Table stats: Memory Usage per command invocation</title>
    +                <search>
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSet" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| eval Used_Mem_MB=((value)/1024)
    +| stats sum(Used_Mem_MB) As Used_Mem_MB by _time, host, dimension_Command
    +| $aggregate$
    +| stats $statsmode$(Used_Mem_MB) as "Used Memory per Command (MB)", sparkline($statsmode$(Used_Mem_MB)) as sparkline by $table_by$
    +| rename dimension_Command as Command
    +| eval "Used Memory per Command (MB)"=round('Used Memory per Command (MB)', 3)
    +| sort - "Used Memory per Command (MB)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="Used Memory per Command (MB)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_TOP_SOLARIS.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_TOP_SOLARIS.xml
    new file mode 100644
    index 0000000..fd5e81c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_TOP_SOLARIS.xml
    @@ -0,0 +1,928 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI TOP, Solaris Processes System Resources statistics</label>
    +    <description>User Interface for the TOP monitor on Solaris Systems</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>Solaris</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="">Any OS</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate_input" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="none">Single Series</choice>
    +            <choice value="sum">Sum by Time interval</choice>
    +            <choice value="avg">Average by Time interval</choice>
    +            <choice value="median">Median by Time interval</choice>
    +            <choice value="max">Max by Time interval</choice>
    +            <default>none</default>
    +            <change>
    +                <condition value="none">
    +                    <set token="aggregate">fields *</set>
    +                    <set token="form.timechart_by">key</set>
    +                    <set token="form.table_by">host,dimension_Command</set>
    +                </condition>
    +                <condition value="sum">
    +                    <set token="aggregate">stats sum(*) as &quot;*&quot; by _time, dimension_Command | eval host=&quot;aggreg_host&quot;</set>
    +                    <set token="form.timechart_by">dimension_Command</set>
    +                    <set token="form.table_by">dimension_Command</set>
    +                </condition>
    +                <condition value="avg">
    +                    <set token="aggregate">stats avg(*) as &quot;*&quot; by _time, dimension_Command | eval host=&quot;aggreg_host&quot;</set>
    +                    <set token="form.timechart_by">dimension_Command</set>
    +                    <set token="form.table_by">dimension_Command</set>
    +                </condition>
    +                <condition value="median">
    +                    <set token="aggregate">stats median(*) as &quot;*&quot; by _time, dimension_Command | eval host=&quot;aggreg_host&quot;</set>
    +                    <set token="form.timechart_by">dimension_Command</set>
    +                    <set token="form.table_by">dimension_Command</set>
    +                </condition>
    +                <condition value="max">
    +                    <set token="aggregate">stats max(*) as &quot;*&quot; by _time, dimension_Command | eval host=&quot;aggreg_host&quot;</set>
    +                    <set token="form.timechart_by">dimension_Command</set>
    +                    <set token="form.table_by">dimension_Command</set>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.*" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <search id="populate_command">
    +        <query>| mcatalog values(dimension_Command) as commands where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.*" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host
    +| rename commands as dimension_Command
    +| stats count by dimension_Command</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for TOP statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="CPU"/>
    +                                    <h1>Processes statistics (metric_name=os.unix.nmon.processes.top.*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div>
    +                                    The TOP monitor captures processes statistics for system resources metrics such as CPU, memory and more.
    +                                    <br />
    +                                    This section is available in any supported operating systems, but some metrics are specifics for some systems.
    +                                    <br />
    +                                    The <b>UARG monitor</b> is associated with the TOP monitor as it will capture the full list of processes arguments.
    +                                    <br />
    +                                    Processes statistics are generated at the PID level for a given "Command" invocation, as such, calculation will aggregate statistics of all PIDs for that given Command.
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>raw metrics and dimensions:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>dimension_Command:</b> The name of the global command that generated the process</li>
    +                                            <li><b>dimension_PID:</b> The PID number of the process</li>
    +                                            <li><b>pct_CPU:</b> (%) average amount of CPU used by this process</li>
    +                                            <li><b>pct_Usr:</b> (%) average amount of user-mode CPU used by this process</li>
    +                                            <li><b>pct_Sys:</b> (%) average amount of kernel-mode CPU used by this process</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>Size:</b> (KB) total virtual memory size of this process Same as 'prstat.SIZE'</li>
    +                                            <li><b>ResSize:</b> (KB) Resident set size of the process Same as 'prstat.RSS'</li>
    +                                            <li><b>Threads:</b> Number of LWPs of this process Same as 'prstat.NLWP'</li>
    +                                            <li><b>CharIO:</b> (bytes/s) count of bytes/sec being passed via the read and write system calls</li>
    +                                            <li><b>LAT:</b> (%) of time the process has spent waiting for CPU Same as 'prstat -v.LAT'</li>
    +                                            <br />
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20metric_name%3D&quot;os.unix.nmon.processes.top.*&quot;%20host%3D&quot;*&quot;" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20dimension_Command%3D*%20dimension_PID%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20sum(_value)%20as%20pct_CPU%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.pct_CPU%20host%3D*%20dimension_Command%3D*%20by%20dimension_Command%20span%3D1m%0A%7C%20eval%20usage_per_core%3D(pct_CPU%2F100)%0A%7C%20timechart%20%60nmon_span%60%20useother%3Df%20limit%3D50%20max(usage_per_core)%20as%20usage_per_core%20by%20dimension_Command" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_TOP_spl" class="tryitbtnxl">HOWTO Interface »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=PROCESSES%20STATISTICS" class="tryitbtnxl">Processes Data Dictionary »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?form.osfilter=Linux" class="tryitbtnxl">Bubblechart dashboard »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +        <title>Processes filtering:</title>
    +
    +            <input type="text" token="Command" searchWhenChanged="true">
    +                <label>Optional: Filter by Command</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="text" token="PID" searchWhenChanged="true">
    +                <label>Optional: Filter by PIDs</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="multiselect" token="Command_multiselect" searchWhenChanged="true">
    +                <label>Command(s):</label>
    +                <search base="populate_command">
    +                    <query>sort 0 dimension_Command</query>
    +                </search>
    +                <default>*</default>
    +                <valuePrefix>dimension_Command="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">Any</choice>
    +                <fieldForLabel>dimension_Command</fieldForLabel>
    +                <fieldForValue>dimension_Command</fieldForValue>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>area</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>zero</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>stacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Active drilldown: click on a command invocation to get detailed PIDs statistics of that command (may be truncated with large number of PIDs)</title>
    +
    +            <input type="text" token="valuefilter" searchWhenChanged="true" depends="$top_chart1$">
    +                <label>Filter values:</label>
    +                <default>usage_per_core>0</default>
    +            </input>
    +
    +            <input type="text" token="limit" searchWhenChanged="true">
    +                <label>Max series:</label>
    +                <default>50</default>
    +                <prefix>limit=</prefix>
    +            </input>
    +
    +            <input type="dropdown" token="timechart_by" searchWhenChanged="true">
    +                <label>group by statement:</label>
    +                <default>key</default>
    +                <choice value="key">host:Command</choice>
    +                <choice value="dimension_Command">Command</choice>
    +            </input>
    +
    +            <input type="link" token="top_linkinput">
    +                <label></label>
    +                <choice value="top_chart1">CPU Usage per logical core</choice>
    +                <choice value="top_chart2">Physical Memory (RSS) Usage per command invocation</choice>
    +                <choice value="top_chart3">Virtual Memory (SIZE) Usage per command invocation</choice>
    +                <choice value="top_chart4">Paging, Sum of page faults</choice>
    +                <choice value="top_chart5">Threads per Command invocation</choice>
    +                <choice value="top_chart6">CharIO per Command invocation</choice>
    +                <choice value="uarg">UARG: commands arguments</choice>
    +                <default>top_chart1</default>
    +                <change>
    +                    <condition value="top_chart1">
    +                        <set token="top_chart1">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart2">
    +                        <set token="top_chart2">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart3">
    +                        <set token="top_chart3">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart4">
    +                        <set token="top_chart4">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart5">
    +                        <set token="top_chart5">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart6"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="top_chart6">
    +                        <set token="top_chart6">true</set>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="uarg"></unset>
    +                    </condition>
    +                    <condition value="uarg">
    +                        <set token="uarg">true</set>
    +                        <unset token="top_chart1"></unset>
    +                        <unset token="top_chart2"></unset>
    +                        <unset token="top_chart3"></unset>
    +                        <unset token="top_chart4"></unset>
    +                        <unset token="top_chart5"></unset>
    +                        <unset token="top_chart6"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$top_chart1$">
    +                <title></title>
    +                <search depends="$top_chart1$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| eval usage_per_core=(pct_CPU/100)
    +| $aggregate$
    +| where ($valuefilter$)
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(usage_per_core) as "CPU Usage per core" by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Logical Core</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as pct_CPU where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| eval usage_per_core=(pct_CPU/100)
    +| $aggregate$
    +| where ($valuefilter$)
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(usage_per_core) as "CPU Usage per core" by key | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart2$">
    +                <title></title>
    +                <search depends="$top_chart2$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSize" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| eval Used_Mem_MB=((value)/1024)
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(Used_Mem_MB) as "memory usage (MB)" by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSize" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| eval Used_Mem_MB=((value)/1024)
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(Used_Mem_MB) as "memory usage (MB)" by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart3$">
    +                <title></title>
    +                <search depends="$top_chart3$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Size" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| eval Virtual_Mem_MB=((value)/1024)
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":"
    +| timechart $span$ $limit$ useother=f $statsmode$(Virtual_Mem_MB) as "Virtual_Mem usage (MB)" by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Megabytes (MB)</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Size" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by dimension_Command dimension_PID span=1m
    +| eval Virtual_Mem_MB=((value)/1024)
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(Virtual_Mem_MB) as "Virtual_Mem usage (MB)" by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart4$">
    +                <title></title>
    +                <search depends="$top_chart4$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Paging" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(value) as Paging by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/sec</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Paging" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(value) as Paging by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*
    +| fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart5$">
    +                <title></title>
    +                <search depends="$top_chart5$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Threads" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ $limit$ useother=f $statsmode$(value) as Threads by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/sec</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.Threads" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ limit=0 useother=f $statsmode$(value) as Threads by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <chart depends="$top_chart6$">
    +                <title></title>
    +                <search depends="$top_chart6$">
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.CharIO" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| stats sum(value) as value by _time, host, dimension_Command
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command
    +| timechart $span$ useother=f limit="50" avg(value) as CharIO by $timechart_by$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/sec</option>
    +                <option name="refresh.display">none</option>
    +                <drilldown target="search">
    +                    <link>
    +                        <![CDATA[
    +                            search?&earliest=$earliest$&latest=$latest$&q=| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.CharIO" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host dimension_Command dimension_PID span=1m
    +| $aggregate$
    +| eval key=host . ":" . dimension_Command . ":" . dimension_PID
    +| timechart $span$ useother=f limit=0 avg(value) as CharIO by $timechart_by$ | rename "aggreg:*" AS "*" | fields _time,$click.name2$*&display.page.search.tab=visualizations&display.general.type=visualizations&display.visualizations.charting.chart=column&display.visualizations.charting.chart.stackMode=stacked
    +                        ]]>
    +                    </link>
    +                </drilldown>
    +            </chart>
    +
    +            <input type="text" token="Command" depends="$uarg$" searchWhenChanged="true">
    +                <label>Optional: Filter by Command</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="text" token="PID" depends="$uarg$" searchWhenChanged="true">
    +                <label>Optional: Filter by PIDs</label>
    +                <default>*</default>
    +            </input>
    +
    +            <input type="multiselect" token="Command_multiselect" depends="$uarg$" searchWhenChanged="true">
    +                <label>Command(s):</label>
    +                <search base="populate_command">
    +                    <query>sort 0 dimension_Command</query>
    +                </search>
    +                <initialValue>*</initialValue>
    +                <valuePrefix>dimension_Command="</valuePrefix>
    +                <valueSuffix>"</valueSuffix>
    +                <delimiter> OR </delimiter>
    +                <choice value="*">Any</choice>
    +                <fieldForLabel>dimension_Command</fieldForLabel>
    +                <fieldForValue>dimension_Command</fieldForValue>
    +            </input>
    +
    +            <event depends="$uarg$">
    +                <title></title>
    +                <search depends="$uarg$">
    +                    <query>eventtype=nmon:events type=UARG host=$host-prefilter$ $host_query$ (COMM=$Command$) (PID=$PID$)</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="count">10</option>
    +                <option name="list.drilldown">full</option>
    +                <option name="list.wrap">1</option>
    +                <option name="maxLines">0</option>
    +                <option name="raw.drilldown">full</option>
    +                <option name="rowNumbers">0</option>
    +                <option name="table.drilldown">1</option>
    +                <option name="table.wrap">1</option>
    +                <option name="type">list</option>
    +                <option name="refresh.display">none</option>
    +                <fields>[]</fields>
    +            </event>
    +
    +        </panel>
    +
    +    </row>
    +
    +    <search id="uarg_definition">
    +        <query>search metric_name=$metric_name$</query>
    +        <progress>
    +            <condition>
    +                <set token="metric_filter">$result.metric_filter$</set>
    +                <set token="metric_calculation">$result.metric_calculation$</set>
    +                <set token="metric_has_device">$result.metric_has_device$</set>
    +                <set token="metric_dimension_field">$result.metric_dimension_field$</set>
    +                <set token="metric_shortname">$result.metric_shortname$</set>
    +                <set token="metric_data_field">$result.metric_data_field$</set>
    +                <set token="metric_primary_statsmode">$result.metric_primary_statsmode$</set>
    +                <set token="metric_by">$result.metric_by$</set>
    +                <set token="metric_timechart_by">$result.metric_timechart_by$</set>
    +                <set token="metric_volume_unit_choice">$result.metric_volume_unit_choice$</set>
    +                <set token="metric_rate_unit_choice">$result.metric_rate_unit_choice$</set>
    +                <set token="form.chart">$result.metric_charting_chart$</set>
    +                <set token="form.chart.stackingmode">$result.metric_charting_stackmode$</set>
    +            </condition>
    +        </progress>
    +    </search>
    +
    +
    +    <row>
    +        <panel>
    +            <input type="dropdown" token="table_by" searchWhenChanged="true">
    +                <label>group by statement:</label>
    +                <default>host,dimension_Command</default>
    +                <choice value="host,dimension_Command">host:Command</choice>
    +                <choice value="dimension_Command">Command</choice>
    +            </input>
    +            <table>
    +                <title>Table stats: CPU Usage per logical core</title>
    +                <search>
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.pct_CPU" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) as pct_CPU by _time, host, dimension_Command
    +| $aggregate$
    +| eval usage_per_core=(pct_CPU/100)
    +| stats $statsmode$(usage_per_core) as "CPU Usage per Logical Cores", sparkline($statsmode$(usage_per_core)) As sparkline by $table_by$
    +| rename dimension_Command as Command
    +| eval "CPU Usage per Logical Cores"=round('CPU Usage per Logical Cores', 3)
    +| sort - "CPU Usage per Logical Cores"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="CPU Usage per Logical Cores">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +        <panel>
    +            <input type="dropdown" token="table_by" searchWhenChanged="true">
    +                <label>group by statement:</label>
    +                <default>host,dimension_Command</default>
    +                <choice value="host,dimension_Command">host:Command</choice>
    +                <choice value="dimension_Command">Command</choice>
    +            </input>
    +            <table>
    +                <title>Table stats: Memory Usage per command invocation</title>
    +                <search>
    +                    <query>| mstats max(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.processes.top.ResSize" host=$host-prefilter$ $host_query$ (dimension_Command=$Command$) (dimension_PID=$PID$) by host, dimension_Command, dimension_PID span=1m
    +| stats sum(value) As value by _time, host, dimension_Command
    +| eval Used_Mem_MB=((value)/1024)
    +| $aggregate$
    +| stats $statsmode$(Used_Mem_MB) as "Used Memory per Command (MB)", sparkline($statsmode$(Used_Mem_MB)) as sparkline by $table_by$
    +| rename dimension_Command as Command
    +| eval "Used Memory per Command (MB)"=round('Used Memory per Command (MB)', 3)
    +| sort - "Used Memory per Command (MB)"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="Used Memory per Command (MB)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_UARG_AIX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_UARG_AIX.xml
    new file mode 100644
    index 0000000..fd69d19
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_UARG_AIX.xml
    @@ -0,0 +1,298 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI UARG, Search Commands Arguments</label>
    +    <description>User Interface for the UARG monitor on AIX systems</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>TimeRange:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>AIX</default>
    +            <choice value="*">Any OS</choice>
    +            <choice value="AIX">AIX</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="text" token="PID" searchWhenChanged="true">
    +            <label>Optional: Filter PIDs</label>
    +            <prefix>PID="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="text" token="COMM" searchWhenChanged="true">
    +            <label>Optional: Filter Command name</label>
    +            <prefix>COMM="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="text" token="USER" searchWhenChanged="true">
    +            <label>Optional: Filter user</label>
    +            <prefix>USER="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="text" token="GROUP" searchWhenChanged="true">
    +            <label>Optional: Filter group</label>
    +            <prefix>GROUP="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="text" token="FullCommand" searchWhenChanged="true">
    +            <label>Optional: Filter FullCommand</label>
    +            <prefix>FullCommand="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for UARG data</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="CPU"/>
    +                                    <h1>Processes full arguments (UARG)</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The UARG monitor captures the full argument line of processes on a per PID level, it is highly related to the TOP monitor which contains performance metrics for theses processes.
    +                                    <br />
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>PID:</b> The PID number of the process</li>
    +                                            <li><b>PPID:</b> The father's PID number for that process</li>
    +                                            <li><b>COMM:</b> The name of the main command invocation. (equivalent to Command in TOP data)</li>
    +                                            <li><b>FullCommand:</b> List of arguments that were associated with this PID</li>
    +                                            <li><b>USER:</b> Name of the Unix user that owns the process</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon:performance:process%20type%3DUARG%20OStype%3DAIX" class="tryitbtnxl">Explore RAW DATA »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_TOP_spl" class="tryitbtnxl">HOWTO Interface for TOP »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=PROCESSES%20STATISTICS" class="tryitbtnxl">Processes Data Dictionary »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?form.osfilter=AIX" class="tryitbtnxl">Bubblechart dashboard »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| tstats count where `nmon_events_index` type=UARG OStype=$osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Commands arguments</title>
    +            <input type="text" token="customsearch">
    +                <label>Search for a pattern (Will be highlighted):</label>
    +                <default/>
    +                <suffix>*</suffix>
    +            </input>
    +            <event>
    +                <title>Events:</title>
    +                <search>
    +                    <query>eventtype=nmon:events type=UARG $frameID$ host=$host-prefilter$ $host_query$ $PID$ $COMM$ $USER$ $GROUP$ $FullCommand$ | search $customsearch$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="count">10</option>
    +                <option name="list.drilldown">full</option>
    +                <option name="list.wrap">1</option>
    +                <option name="maxLines">0</option>
    +                <option name="raw.drilldown">full</option>
    +                <option name="rowNumbers">0</option>
    +                <option name="table.drilldown">1</option>
    +                <option name="table.wrap">1</option>
    +                <option name="type">list</option>
    +                <option name="refresh.display">none</option>
    +                <fields>[]</fields>
    +            </event>
    +            <table>
    +                <title>Table:</title>
    +                <search>
    +                    <query>eventtype=nmon:events type=UARG $frameID$ host=$host-prefilter$ $host_query$ $PID$ $COMM$ $USER$ $GROUP$ $FullCommand$ | table _time,host,PID,PPID,COMM,THCOUNT,USER,GROUP,FullCommand</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_UARG_LINUX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_UARG_LINUX.xml
    new file mode 100644
    index 0000000..d10d57b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_UARG_LINUX.xml
    @@ -0,0 +1,283 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI UARG, Search Commands Arguments</label>
    +    <description>User Interface for the UARG data on Linux systems</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>TimeRange:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>Linux</default>
    +            <choice value="*">Any OS</choice>
    +            <choice value="Linux">Linux</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="text" token="ProgName" searchWhenChanged="true">
    +            <label>Optional: Filter Command name</label>
    +            <prefix>ProgName="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="text" token="PID" searchWhenChanged="true">
    +            <label>Optional: Filter PIDs</label>
    +            <prefix>PID="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="text" token="FullCommand" searchWhenChanged="true">
    +            <label>Optional: Filter FullCommand</label>
    +            <prefix>FullCommand="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for UARG data</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="CPU"/>
    +                                    <h1>Processes full arguments (UARG)</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The UARG monitor captures the full argument line of processes on a per PID level, it is highly related to the TOP monitor which contains performance metrics for theses processes.
    +                                    <br />
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>PID:</b> The PID number of the process</li>
    +                                            <li><b>ProgName:</b> The name of the main command invocation. (equivalent to Command in TOP data)</li>
    +                                            <li><b>FullCommand:</b> List of arguments that were associated with this PID</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon:performance:process%20type%3DUARG%20OStype%3DLinux" class="tryitbtnxl">Explore RAW DATA »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_TOP_spl" class="tryitbtnxl">HOWTO Interface for TOP »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=PROCESSES%20STATISTICS" class="tryitbtnxl">Processes Data Dictionary »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?form.osfilter=Linux" class="tryitbtnxl">Bubblechart dashboard »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| tstats count where `nmon_events_index` type=UARG OStype=$osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Commands arguments</title>
    +            <input type="text" token="customsearch">
    +                <label>Search for a pattern (Will be highlighted):</label>
    +                <default/>
    +                <suffix>*</suffix>
    +            </input>
    +            <event>
    +                <title>Events:</title>
    +                <search>
    +                    <query>eventtype=nmon:events type=UARG $frameID$ host=$host-prefilter$ $host_query$ $ProgName$ $PID$ $FullCommand$ | search $customsearch$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="count">10</option>
    +                <option name="list.drilldown">full</option>
    +                <option name="list.wrap">1</option>
    +                <option name="maxLines">0</option>
    +                <option name="raw.drilldown">full</option>
    +                <option name="rowNumbers">0</option>
    +                <option name="table.drilldown">1</option>
    +                <option name="table.wrap">1</option>
    +                <option name="type">list</option>
    +                <option name="refresh.display">none</option>
    +                <fields>[]</fields>
    +            </event>
    +            <table>
    +                <title>Table:</title>
    +                <search>
    +                    <query>eventtype=nmon:events type=UARG $frameID$ host=$host-prefilter$ $host_query$ $ProgName$ $PID$ $FullCommand$ | table _time,host,PID,ProgName,FullCommand</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_UARG_SOLARIS.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_UARG_SOLARIS.xml
    new file mode 100644
    index 0000000..277f912
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_UARG_SOLARIS.xml
    @@ -0,0 +1,298 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI UARG, Search Commands Arguments</label>
    +    <description>User Interface for the UARG monitor on Solaris systems</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>TimeRange:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>Solaris</default>
    +            <choice value="*">Any OS</choice>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="text" token="PID" searchWhenChanged="true">
    +            <label>Optional: Filter PIDs</label>
    +            <prefix>PID="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="text" token="COMM" searchWhenChanged="true">
    +            <label>Optional: Filter Command name</label>
    +            <prefix>COMM="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="text" token="USER" searchWhenChanged="true">
    +            <label>Optional: Filter user</label>
    +            <prefix>USER="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="text" token="GROUP" searchWhenChanged="true">
    +            <label>Optional: Filter group</label>
    +            <prefix>GROUP="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="text" token="FullCommand" searchWhenChanged="true">
    +            <label>Optional: Filter FullCommand</label>
    +            <prefix>FullCommand="</prefix>
    +            <suffix>"</suffix>
    +            <default>*</default>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>s
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for UARG data</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="CPU"/>
    +                                    <h1>Processes full arguments (UARG)</h1>
    +                                </div>
    +
    +                                <div>
    +                                    <br />
    +                                    The UARG monitor captures the full argument line of processes on a per PID level, it is highly related to the TOP monitor which contains performance metrics for theses processes.
    +                                    <br />
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>PID:</b> The PID number of the process</li>
    +                                            <li><b>PPID:</b> The father's PID number for that process</li>
    +                                            <li><b>COMM:</b> The name of the main command invocation. (equivalent to Command in TOP data)</li>
    +                                            <li><b>FullCommand:</b> List of arguments that were associated with this PID</li>
    +                                            <li><b>USER:</b> Name of the Unix user that owns the process</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon:performance:process%20type%3DUARG%20OStype%3DSolaris" class="tryitbtnxl">Explore RAW DATA »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Howto_TOP_spl" class="tryitbtnxl">HOWTO Interface for TOP »
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=PROCESSES%20STATISTICS" class="tryitbtnxl">Processes Data Dictionary »
    +                                    </a>
    +
    +                                    <a target="_blank" href="Dashboard_Bubblechart_top_processes?form.osfilter=Solaris" class="tryitbtnxl">Bubblechart dashboard »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| tstats count where `nmon_events_index` type=UARG OStype=$osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Commands arguments</title>
    +            <input type="text" token="customsearch">
    +                <label>Search for a pattern (Will be highlighted):</label>
    +                <default/>
    +                <suffix>*</suffix>
    +            </input>
    +            <event>
    +                <title>Events:</title>
    +                <search>
    +                    <query>eventtype=nmon:events type=UARG $frameID$ host=$host-prefilter$ $host_query$ $PID$ $COMM$ $USER$ $GROUP$ $FullCommand$ | search $customsearch$</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="count">10</option>
    +                <option name="list.drilldown">full</option>
    +                <option name="list.wrap">1</option>
    +                <option name="maxLines">0</option>
    +                <option name="raw.drilldown">full</option>
    +                <option name="rowNumbers">0</option>
    +                <option name="table.drilldown">1</option>
    +                <option name="table.wrap">1</option>
    +                <option name="type">list</option>
    +                <option name="refresh.display">none</option>
    +                <fields>[]</fields>
    +            </event>
    +            <table>
    +                <title>Table:</title>
    +                <search>
    +                    <query>eventtype=nmon:events type=UARG $frameID$ host=$host-prefilter$ $host_query$ $PID$ $COMM$ $USER$ $GROUP$ $FullCommand$ | table _time,host,PID,PPID,COMM,THCOUNT,USER,GROUP,FullCommand</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +            </table>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_VM_LINUX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_VM_LINUX.xml
    new file mode 100644
    index 0000000..b27fed9
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_VM_LINUX.xml
    @@ -0,0 +1,834 @@
    +<form script="active_button.js,modal.js" stylesheet="ui_simple.css,panel_decoration.css,hover.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI VM, Linux Virtual Memory Statistics</label>
    +    <description>User Interface for the VM monitor on Linux Systems</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>Linux</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="Linux">Linux</choice>
    +            <choice value="*">ANY</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>        
    +        
    +    </fieldset>
    +
    +        <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.memory.vm.*" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <search id="Global">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval key = host . ":" . metric
    +| timechart `nmon_span` limit=0 useother=f avg(value) as value by key
    +| fillnull value=0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +
    +        <panel>
    +            <html>
    +                <div class="mainbutton_container_nomargin">
    +                    <div class="mainbutton">
    +                        <div class="custom-sub-nav" style="text-align: center;">
    +                            <button class="button2_lowpadding glow" data-token-name="show_def" data-alt-label="Hide fields and metric definition for VM statistics" data-token-value="true">Show fields and metric definition for VM statistics</button>
    +                        </div>
    +                    </div>
    +                </div>
    +            </html>
    +        </panel>
    +
    +        <panel>
    +            <html>
    +                <div class="mainbutton_container_nomargin">
    +                    <div class="mainbutton custom-modal">
    +                        <button class="button2_lowpadding glow" data-modal-name="Help_modal">Help, information and related links for VM statistics</button>
    +                    </div>
    +                </div>
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/process.png" alt="CPU"/>
    +                                    <h1>
    +                                        Linux Virtual Memory Statistics
    +                                        <br />
    +                                        (metric_name=os.unix.nmon.memory.vm.*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20OStype%3DLinux%20metric_name%3Dos.unix.nmon.memory.vm.*%20host%3D*" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20OStype%3DLinux%20metric_name%3Dos.unix.nmon.memory.vm.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=KERNEL%20STATISTICS&amp;form.osfilter=Linux%3Dtrue" class="tryitbtnxl">Kernel Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row depends="$show_def$">
    +        <panel>
    +            <input type="text" token="def_search" searchWhenChanged="true">
    +                <label>free search:</label>
    +                <default>*</default>
    +            </input>
    +            <table>
    +                <title></title>
    +                <search depends="$show_def$">
    +                    <query>| inputlookup static_dictionary_VM_Linux | fields perf_item,nmon_section,formula*,long*,unity | sort "formula (or field name if not evaluated)"
    +| search long_description="*$def_search$*"</query>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">100</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| chart limit=0 useother=f avg(value) over host by metric
    +| foreach * [ eval &lt;&lt;FIELD&gt;&gt; = if(isnum('&lt;&lt;FIELD&gt;&gt;'), round('&lt;&lt;FIELD&gt;&gt;', 2), '&lt;&lt;FIELD&gt;&gt;') ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Virtual Memory statistics</title>
    +            <input type="link" token="linkinput">
    +                <label></label>
    +                <choice value="chart1">Pages dirty, under writeback or unstable</choice>
    +                <choice value="chart2">Pages allocated to page tables, mapped by files or allocated by the kernel slab allocator</choice>
    +                <choice value="chart3">Pageins and pageouts (since last boot)</choice>
    +                <choice value="chart4">swapins and swapouts (since last boot)</choice>
    +                <choice value="chart5">Page allocations per zone (since last boot)</choice>
    +                <choice value="chart6">Page frees, activations and deactivations (since last boot)</choice>
    +                <choice value="chart7">Minor and major page faults (since last boot)</choice>
    +                <choice value="chart8">Page refills (per zone, since last boot)</choice>
    +                <choice value="chart9">Page steals (per zone, since last boot)</choice>
    +                <choice value="chart10">Pages scanned by kswapd daemon (per zone, since last boot)</choice>
    +                <choice value="chart11">Pages reclaimed directly (per zone, since last boot)</choice>
    +                <choice value="chart12">Miscellaneous statistics</choice>
    +                <default>chart1</default>
    +                <change>
    +                    <condition value="chart1">
    +                        <set token="chart1">true</set>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                        <unset token="chart7"></unset>
    +                        <unset token="chart8"></unset>
    +                        <unset token="chart9"></unset>
    +                        <unset token="chart10"></unset>
    +                        <unset token="chart11"></unset>
    +                        <unset token="chart12"></unset>
    +                    </condition>
    +                    <condition value="chart2">
    +                        <set token="chart2">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                        <unset token="chart7"></unset>
    +                        <unset token="chart8"></unset>
    +                        <unset token="chart9"></unset>
    +                        <unset token="chart10"></unset>
    +                        <unset token="chart11"></unset>
    +                        <unset token="chart12"></unset>
    +                    </condition>
    +                    <condition value="chart3">
    +                        <set token="chart3">true</set>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                        <unset token="chart7"></unset>
    +                        <unset token="chart8"></unset>
    +                        <unset token="chart9"></unset>
    +                        <unset token="chart10"></unset>
    +                        <unset token="chart11"></unset>
    +                        <unset token="chart12"></unset>
    +                    </condition>
    +                    <condition value="chart4">
    +                        <set token="chart4">true</set>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                        <unset token="chart7"></unset>
    +                        <unset token="chart8"></unset>
    +                        <unset token="chart9"></unset>
    +                        <unset token="chart10"></unset>
    +                        <unset token="chart11"></unset>
    +                        <unset token="chart12"></unset>
    +                    </condition>
    +                    <condition value="chart5">
    +                        <set token="chart5">true</set>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart6"></unset>
    +                        <unset token="chart7"></unset>
    +                        <unset token="chart8"></unset>
    +                        <unset token="chart9"></unset>
    +                        <unset token="chart10"></unset>
    +                        <unset token="chart11"></unset>
    +                        <unset token="chart12"></unset>
    +                    </condition>
    +                    <condition value="chart6">
    +                        <set token="chart6">true</set>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart7"></unset>
    +                        <unset token="chart8"></unset>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart9"></unset>
    +                        <unset token="chart10"></unset>
    +                        <unset token="chart11"></unset>
    +                        <unset token="chart12"></unset>
    +                    </condition>
    +                    <condition value="chart7">
    +                        <set token="chart7">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                        <unset token="chart8"></unset>
    +                        <unset token="chart9"></unset>
    +                        <unset token="chart10"></unset>
    +                        <unset token="chart11"></unset>
    +                        <unset token="chart12"></unset>
    +                    </condition>
    +                    <condition value="chart8">
    +                        <set token="chart8">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                        <unset token="chart7"></unset>
    +                        <unset token="chart9"></unset>
    +                        <unset token="chart10"></unset>
    +                        <unset token="chart11"></unset>
    +                        <unset token="chart12"></unset>
    +                    </condition>
    +                    <condition value="chart9">
    +                        <set token="chart9">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                        <unset token="chart7"></unset>
    +                        <unset token="chart8"></unset>
    +                        <unset token="chart10"></unset>
    +                        <unset token="chart11"></unset>
    +                        <unset token="chart12"></unset>
    +                    </condition>
    +                    <condition value="chart10">
    +                        <set token="chart10">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                        <unset token="chart7"></unset>
    +                        <unset token="chart8"></unset>
    +                        <unset token="chart9"></unset>
    +                        <unset token="chart11"></unset>
    +                        <unset token="chart12"></unset>
    +                    </condition>
    +                    <condition value="chart11">
    +                        <set token="chart11">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                        <unset token="chart7"></unset>
    +                        <unset token="chart8"></unset>
    +                        <unset token="chart9"></unset>
    +                        <unset token="chart10"></unset>
    +                        <unset token="chart12"></unset>
    +                    </condition>
    +                    <condition value="chart12">
    +                        <set token="chart12">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                        <unset token="chart7"></unset>
    +                        <unset token="chart8"></unset>
    +                        <unset token="chart9"></unset>
    +                        <unset token="chart10"></unset>
    +                        <unset token="chart11"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$chart1$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*nr_dirty*,*nr_writeback*,*nr_unstable*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart2$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*nr_page_table_pages*,*nr_mapped*,*nr_slab*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart3$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pgpgin*,*pgpgout*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart4$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pswpin*,*pswpout*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart5$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pgalloc_high*,*pgalloc_normal*,*pgalloc_dma32*,*pgalloc_dma*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart6$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pgfree*,*pgactivate*,*pgdeactivate*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart7$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pgfault*,*pgmajfault*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart8$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pgrefill_high*,*pgrefill_normal*,*pgrefill_dma32*,*pgrefill_dma*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart9$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pgsteal_high*,*pgsteal_normal*,*pgsteal_dma32*,*pgsteal_dma*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart10$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pgscan_kswapd_high*,*pgscan_kswapd_normal*,*pgscan_kswapd_dma32*,*pgscan_kswapd_dma*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart11$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pgscan_direct_high*,*pgscan_direct_normal*,*pgscan_direct_dma32*,*pgscan_direct_dma*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart12$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pginodesteal*,*slabs_scanned*,*kswapd_steal*,*kswapd_inodesteal*,*pageoutrun*,*allocstall*,*pgrotated*,*nr_bounce*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Number of Pages</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_VM_SOLARIS.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_VM_SOLARIS.xml
    new file mode 100644
    index 0000000..45209d6
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_VM_SOLARIS.xml
    @@ -0,0 +1,559 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI VM, Solaris Virtual Memory Statistics (Solaris)</label>
    +    <description>User Interface for the VM monitor on Solaris Systems</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="osfilter" searchWhenChanged="true">
    +            <label>Filter OS Type:</label>
    +            <default>Solaris</default>
    +            <prefix>OStype="</prefix>
    +            <suffix>"</suffix>
    +            <choice value="Solaris">Solaris</choice>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Select a stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +        <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.memory.vm.*" $osfilter$ by host
    +| `mapping_frameID`
    +| stats count by frameID, host | sort 0 host</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <search id="Global">
    +        <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| eval key = host . ":" . metric
    +| timechart `nmon_span` limit=0 useother=f avg(value) as value by key
    +| fillnull value=0</query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +        <refresh>$refresh$</refresh>
    +        <refreshType>delay</refreshType>
    +    </search>
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for VM statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/network.png" alt="NET"/>
    +                                    <h1>
    +                                        Solaris Virtual Memory Statistics
    +                                        <br />
    +                                        (metric_name=os.unix.nmon.memory.vm.*)
    +                                    </h1>
    +                                </div>
    +
    +                                <div style="text-align: left;">
    +
    +                                    <h1>Main metrics/fields:</h1>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>minfaults:</b> (pages/s) minor faults, Same as 'vmstat.mf'</li>
    +                                            <li><b>majfaults:</b> (pages/s) major faults</li>
    +                                            <li><b>pgin:</b> (pages/s) pagein</li>
    +                                            <li><b>pgout:</b> (pages/s) pageins</li>
    +                                            <li><b>scans:</b> (pages/s) pages examined by pageout daemon, Same as 'vmstat.sr'</li>
    +                                            <li><b>reclaims:</b> (pages/s) pages freed by daemon or auto, Same as 'vmstat.re'</li>
    +                                        </lu>
    +                                    </div>
    +
    +                                    <div class="list">
    +                                        <lu>
    +                                            <li><b>pgpgin:</b> (KB/s) pages paged in, Same as 'vmstat.pi'</li>
    +                                            <li><b>pgpgout:</b>	(KB/s) pages paged out, Same as 'vmstat.po'</li>
    +                                            <li><b>pswpin:</b> (KB/s) pages swapped in and out, Same as 'vmstat.si'</li>
    +                                            <li><b>pswpout:</b>	(KB/s) pages swapped in and out, Same as 'vmstat.so'</li>
    +                                            <li><b>pgfree:</b> (KB/s) pages freed by daemon or auto, Same as 'vmstat.fr'</li>
    +                                        </lu>
    +                                        <br />
    +                                    </div>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20where%20%60nmon_metrics_index%60%20OStype%3DSolaris%20metric_name%3Dos.unix.nmon.memory.vm.*%20host%3D*" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20OStype%3DSolaris%20metric_name%3Dos.unix.nmon.memory.vm.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="UI_data_dictionary?&amp;form.itemfilter=KERNEL%20STATISTICS&amp;form.osfilter=Solaris%3Dtrue" class="tryitbtnxl">Kernel Data Dictionary »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <title>Table Stats</title>
    +                <search>
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.vm.* host=$host-prefilter$ $host_query$ by metric_name host span=1m
    +| `$timefilter$`
    +| `extract_metrics`
    +| chart limit=0 useother=f avg(value) over host by metric
    +| foreach * [ eval &lt;&lt;FIELD&gt;&gt; = if(isnum('&lt;&lt;FIELD&gt;&gt;'), round('&lt;&lt;FIELD&gt;&gt;', 2), '&lt;&lt;FIELD&gt;&gt;') ]</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +            </table>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="process">
    +            <title>Virtual Memory statistics</title>
    +
    +            <input type="link" token="linkinput">
    +                <label></label>
    +                <choice value="chart1">(pages/s) Minor faults and major faults</choice>
    +                <choice value="chart2">(pages/s) Pages IN and OUT</choice>
    +                <choice value="chart3">(pages/s) Pages examined and freed by pageout daemon</choice>
    +                <choice value="chart4">(KB/s) Pages paged IN and OUT</choice>
    +                <choice value="chart5">(KB/s) Pages swapped IN and OUT</choice>
    +                <choice value="chart6">(KB/s) Pages freed by daemon or auto</choice>
    +                <default>chart1</default>
    +                <change>
    +                    <condition value="chart1">
    +                        <set token="chart1">true</set>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart2">
    +                        <set token="chart2">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart3">
    +                        <set token="chart3">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart4">
    +                        <set token="chart4">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart5"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart5">
    +                        <set token="chart5">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart6"></unset>
    +                    </condition>
    +                    <condition value="chart6">
    +                        <set token="chart6">true</set>
    +                        <unset token="chart1"></unset>
    +                        <unset token="chart2"></unset>
    +                        <unset token="chart3"></unset>
    +                        <unset token="chart4"></unset>
    +                        <unset token="chart5"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <chart depends="$chart1$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*minfaults*,*majfaults*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/second</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart2$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pgin*,*pgout*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/second</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart3$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*scans*,*reclaims*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/second</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart4$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pgpgin*,*pgpgout*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">Pages/second</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart5$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pswpin*,*pswpout*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KB/Sec</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +            <chart depends="$chart6$">
    +                <title></title>
    +                <search base="Global">
    +                    <query>fields _time,*pgfree*</query>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">KB/Sec</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_WLM_AIX.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_WLM_AIX.xml
    new file mode 100644
    index 0000000..02904fc
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_WLM_AIX.xml
    @@ -0,0 +1,460 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI WLM, AIX Workload Manager</label>
    +    <description>User Interface for WLM on AIX systems</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="monitor" searchWhenChanged="true">
    +            <label>Monitor:</label>
    +            <choice value="os.unix.nmon.processes.wlmcpu">WLMCPU</choice>
    +            <choice value="os.unix.nmon.processes.wlmmem">WLMMEM</choice>
    +            <choice value="os.unix.nmon.processes.wlmbio">WLMBIO</choice>
    +            <default>WLMCPU</default>
    +            <change>
    +                <condition value="os.unix.nmon.processes.wlmcpu">
    +                    <set token="label">CPU percent (%)</set>
    +                </condition>
    +                <condition value="os.unix.nmon.processes.wlmmem">
    +                    <set token="label">Memory percent (%)</set>
    +                </condition>
    +                <condition value="os.unix.nmon.processes.wlmbio">
    +                    <set token="label">Block IO percent (%)</set>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input id="device" type="multiselect" token="device" searchWhenChanged="true">
    +            <label>Workload:</label>
    +            <search base="populate">
    +                <query>search $frameID$ $host$
    +| stats count by dimension_device | dedup dimension_device | sort 0 dimension_device</query>
    +            </search>
    +            <valuePrefix>dimension_device="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>dimension_device</fieldForLabel>
    +            <fieldForValue>dimension_device</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="fields *">Single Series</choice>
    +            <choice value="stats dedup_splitvals=t avg(value) AS value by _time, dimension_device | eval host=&quot;aggreg_host&quot;">Average by Time interval, Workload</choice>
    +            <choice value="stats dedup_splitvals=t sum(value) AS value by _time, dimension_device | eval host=&quot;aggreg_host&quot;">Sum by Time interval, Workdload</choice>
    +            <default>fields *</default>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="checkbox" token="charting" searchWhenChanged="true">
    +            <label>Charting:</label>
    +            <default>fields *</default>
    +            <choice value="fields *">On</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4>
    +                        <a data-modal-name="Help_modal">Help, information and related links for AIX WLM statistics</a>
    +                    </h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
    +                                    <span aria-hidden="true"/>
    +                                </button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/logos/manufactors/IBM_logo_72px.png" alt="IBM"/>
    +                                    <h1>AIX Workload Manager statistics
    +                                        <br />
    +                                        (os.unix.nmon.processes.wlm*)</h1>
    +                                </div>
    +
    +                                <h1>Description:</h1>
    +
    +                                <div class="list">
    +                                    <b>WLM Monitors:</b>
    +                                    <br/>
    +
    +                                    <lu>
    +                                        <li>WLMCPU, CPU percent for Workload classes</li>
    +                                        <li>WLMMEM, Memory percent for Workload classes</li>
    +                                        <li>WLMBIO, Block IO percent for Workload classes</li>
    +                                    </lu>
    +
    +                                    <br/>
    +
    +                                    <b>Fields:</b>
    +                                    <br />
    +
    +                                    <lu>
    +                                        <li>device: Name of the Workload class</li>
    +                                        <li>value: Value of the metric for this Workload class</li>
    +                                    </lu>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_device)%20as%20dimension_device%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.wlm*%20OStype%3DAIX%20host%3D*" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.wlm*%20OStype%3DAIX%20host%3D*%20dimension_device%3D*%20by%20metric_name%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.wlm*%20OStype%3DAIX%20host%3D*%20dimension_device%3D*%20by%20metric_name%20host%20dimension_device%20span%3D1m%0A%7C%20%60def_wlm_aix_percent%60" class="tryitbtnxl">mstats pre-built query »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.lpar.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.lpar.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="$monitor$" OStype="AIX" by host, dimension_device
    +| `mapping_frameID`
    +| stats count by frameID, host, dimension_device | sort 0 host
    +        </query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +            <table>
    +                <search id="tablestats">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=$monitor$ host=$host-prefilter$ $host_query$ $device$ by host dimension_device span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| stats max(value) AS max_value, avg(value) AS avg_value, min(value) AS min_value, sparkline($statsmode$(value)) As sparkline by  host, dimension_device
    +| sort limit=0 host
    +| eval value=round(value,2)
    +| fields host,dimension_device,max_value, avg_value, min_value,sparkline
    +| rename dimension_device AS "Workload"
    +| foreach "*_value" [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 2) ] | sort - avg_value | rename "*_value" AS "* $label$"</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max CPU percent (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg CPU percent (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min CPU percent (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="max Memory percent (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg Memory percent (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min Memory percent (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="max Block IO percent (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg Block IO percent (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min Block IO percent (%)">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +        </panel>
    +    </row>
    +    <row depends="$charting$">
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +    <row depends="$charting$">
    +        <panel id="cpu">
    +            <title>WorkLoad Manager $label$ statistics</title>
    +            <chart>
    +                <search id="timechart">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=$monitor$ host=$host-prefilter$ $host_query$ $device$ by host dimension_device span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| eval key = host . ":" . dimension_device
    +| timechart $span$ useother=f limit=0 avg(value) as cpu_pct by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">$label$</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_WLM_SOLARIS.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_WLM_SOLARIS.xml
    new file mode 100644
    index 0000000..9a91ccc
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_Nmon_WLM_SOLARIS.xml
    @@ -0,0 +1,589 @@
    +<form script="modal.js" stylesheet="ui_simple.css,panel_decoration.css" isVisible="true" version="1.1" theme="dark">
    +    <label>UI WLM, Solaris Project, Zone, Task and User CPU and MEM % Statistics</label>
    +    <description>User Interface for WLM monitors on Solaris Systems</description>
    +
    +    <fieldset autoRun="false" submitButton="false">
    +
    +        <input type="time" token="timerange" searchWhenChanged="true">
    +            <label>Time Range:</label>
    +            <default>
    +                <earliest>-24h</earliest>
    +                <latest>now</latest>
    +            </default>
    +            <change>
    +				<unset token="form.refresh"></unset>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="timefilter" searchWhenChanged="true">
    +            <label>Time Filtering:</label>
    +            <choice value="No_Filter">No Filter (24/24, 7/7)</choice>
    +            <choice value="Day_BusinessDays_8h-19h">Day Business (08h-19h)</choice>
    +            <choice value="Day_WeekEnd_8h-19h">Day WE (08h-19h)</choice>
    +            <choice value="Day_AllDays_8h-19h">Day Week (08h-19h)</choice>
    +            <choice value="Night_BusinessDays_19h-8h">Night Business (19h-08h)</choice>
    +            <choice value="Night_WeekEnd_19h-8h">Night WE (19h-08h)</choice>
    +            <choice value="Night_AllDays_19h-8h">Night All Days (19h-08h)</choice>
    +            <default>No_Filter</default>
    +        </input>
    +
    +        <input type="dropdown" token="type_monitor" searchWhenChanged="true">
    +            <label>Type:</label>
    +            <choice value="CPU">CPU</choice>
    +            <choice value="MEM">MEM</choice>
    +            <default>CPU</default>
    +            <change>
    +                <condition value="CPU">
    +                    <set token="type_monitor_cpu">True</set>
    +                    <unset token="type_monitor_mem"></unset>
    +                </condition>
    +                <condition value="MEM">
    +                    <set token="type_monitor_mem">True</set>
    +                    <unset token="type_monitor_cpu"></unset>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="monitor_cpu" depends="$type_monitor_cpu$" searchWhenChanged="true">
    +            <label>Monitor:</label>
    +            <choice value="os.unix.nmon.processes.wlmprojectcpu">WLMPROJECTCPU - CPU % for this Project</choice>
    +            <choice value="os.unix.nmon.processes.wlmzonecpu">WLMZONECPU - CPU % for this Zone</choice>
    +            <choice value="os.unix.nmon.processes.wlmtaskcpu">WLMTASKCPU - CPU % for this Task</choice>
    +            <choice value="os.unix.nmon.processes.wlmusercpu">WLMUSERCPU - CPU % for this user</choice>
    +            <default>os.unix.nmon.processes.wlmzonecpu</default>
    +            <change>
    +                <condition value="os.unix.nmon.processes.wlmprojectcpu">
    +                    <set token="dimension_label">Project</set>
    +                    <set token="label">CPU % for this Project</set>
    +                </condition>
    +                <condition value="os.unix.nmon.processes.wlmzonecpu">
    +                    <set token="dimension_label">Zone</set>
    +                    <set token="label">CPU % for this Zone</set>
    +                </condition>
    +                <condition value="os.unix.nmon.processes.wlmtaskcpu">
    +                    <set token="dimension_label">Task</set>
    +                    <set token="label">CPU % for this Task</set>
    +                </condition>
    +                <condition value="os.unix.nmon.processes.wlmusercpu">
    +                    <set token="dimension_label">User</set>
    +                    <set token="label">CPU % for this user</set>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input type="dropdown" token="monitor_mem" depends="$type_monitor_mem$" searchWhenChanged="true">
    +            <label>Monitor:</label>
    +            <choice value="os.unix.nmon.processes.wlmprojectmem">WLMPROJECTMEM - MEM % for this Project</choice>
    +            <choice value="os.unix.nmon.processes.wlmzonemem">WLMZONEMEM - MEM % for this Zone</choice>
    +            <choice value="os.unix.nmon.processes.wlmtaskmem">WLMTASKMEM - MEM % for this Task</choice>
    +            <choice value="os.unix.nmon.processes.wlmusermem">WLMUSERMEM - MEM % for this user</choice>
    +            <default>os.unix.nmon.processes.wlmzonemem</default>
    +            <change>
    +                <condition value="os.unix.nmon.processes.wlmprojectmem">
    +                    <set token="dimension_label">Project</set>
    +                    <set token="label">MEM % for this Project</set>
    +                </condition>
    +                <condition value="os.unix.nmon.processes.wlmzonemem">
    +                    <set token="dimension_label">Zone</set>
    +                    <set token="label">MEM % for this Zone</set>
    +                </condition>
    +                <condition value="os.unix.nmon.processes.wlmtaskmem">
    +                    <set token="dimension_label">Task</set>
    +                    <set token="label">MEM % for this Task</set>
    +                </condition>
    +                <condition value="os.unix.nmon.processes.wlmusermem">
    +                    <set token="dimension_label">User</set>
    +                    <set token="label">MEM % for this user</set>
    +                </condition>
    +            </change>
    +        </input>
    +
    +        <input id="frameID" type="multiselect" token="frameID" searchWhenChanged="true">
    +            <label>Frame IDs:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>stats count by frameID | dedup frameID | sort 0 frameID</query>
    +            </search>
    +            <valuePrefix>frameID=</valuePrefix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">Any</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>frameID</fieldForLabel>
    +            <fieldForValue>frameID</fieldForValue>
    +        </input>
    +
    +        <input type="text" token="host-prefilter" searchWhenChanged="true">
    +            <label>Optional: Filter hosts populating</label>
    +            <default>*</default>
    +        </input>
    +
    +		<input id="host" type="multiselect" token="host" searchWhenChanged="true">
    +		    <label>Hosts Selection:</label>
    +		    <!-- Populating Data Model Search -->
    +		    <search base="populate">
    +		        <query>search $frameID$ host=$host-prefilter$
    +	| stats count by host | dedup host | sort 0 host</query>
    +		    </search>
    +		    <valuePrefix>host="</valuePrefix>
    +		    <valueSuffix>"</valueSuffix>
    +		    <delimiter> OR </delimiter>
    +		    <choice value="*">ALL Hosts</choice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		    <change>
    +		        <condition>
    +		            <unset token="form.host_query_input"></unset>
    +		        </condition>
    +		    </change>
    +		</input>
    +
    +		<!-- hidden form that handles the advanced definition of hosts selection -->
    +
    +		<input id="host_query_input" type="dropdown" token="host_query" searchWhenChanged="true" depends="$hidden_form$">
    +		    <label>Hosts Selection:</label>
    +		    <search base="populate">
    +		        <query>search $host$ $frameID$
    +	| stats values(host) as host
    +	| format | fields - host | rename search as host</query>
    +		    </search>
    +		    <selectFirstChoice>true</selectFirstChoice>
    +		    <fieldForLabel>host</fieldForLabel>
    +		    <fieldForValue>host</fieldForValue>
    +		</input>
    +
    +        <input id="device" type="multiselect" token="device" searchWhenChanged="true">
    +            <label>Project / Zone / Task / User:</label>
    +            <!-- Populating Data Model Search -->
    +            <search base="populate">
    +                <query>search $frameID$ $host$
    +| stats count by dimension_device | dedup dimension_device | sort 0 dimension_device</query>
    +            </search>
    +            <valuePrefix>dimension_device="</valuePrefix>
    +            <valueSuffix>"</valueSuffix>
    +            <delimiter> OR </delimiter>
    +            <choice value="*">ALL</choice>
    +            <initialValue>*</initialValue>
    +            <fieldForLabel>dimension_device</fieldForLabel>
    +            <fieldForValue>dimension_device</fieldForValue>
    +        </input>
    +
    +        <input type="dropdown" token="aggregate" searchWhenChanged="true">
    +            <label>Aggregate:</label>
    +            <choice value="fields *">Single Series</choice>
    +            <choice value="stats dedup_splitvals=t avg(value) AS value by _time, dimension_device | eval host=&quot;aggreg_host&quot;">Average by Time interval, Project/Zone/Task</choice>
    +            <choice value="stats dedup_splitvals=t sum(value) AS value by _time, dimension_device | eval host=&quot;aggreg_host&quot;">Sum by Time interval, Project/Zone/Task</choice>
    +            <default>fields *</default>
    +        </input>
    +
    +        <input type="dropdown" token="statsmode" searchWhenChanged="true">
    +            <label>Stats mode:</label>
    +            <default>max</default>
    +            <choice value="max">Max</choice>
    +            <choice value="avg">Avg</choice>
    +            <choice value="min">Min</choice>
    +            <choice value="median">Median</choice>
    +            <choice value="mode">Mode</choice>
    +            <choice value="range">Range</choice>
    +        </input>
    +
    +        <input type="dropdown" token="refresh" searchWhenChanged="true">
    +            <label>Auto-refresh:</label>
    +            <fieldForLabel>label</fieldForLabel>
    +            <fieldForValue>value</fieldForValue>
    +            <selectFirstChoice>true</selectFirstChoice>
    +            <search>
    +                <query>| `def_auto_refresh`</query>
    +                <earliest>$timerange.earliest$</earliest>
    +                <latest>$timerange.latest$</latest>
    +            </search>
    +        </input>
    +
    +    </fieldset>
    +
    +    <!--
    +    Dynamic configuration
    +    The following searches are being used to define various tokens using event handlers
    +    -->
    +
    +    <!-- Help the user -->
    +
    +    <row rejects="$host$">
    +        <panel>
    +            <html>
    +                <div class="red_help_user">
    +                    <p>- - - - - - - - - - ACTION REQUIRED: please select your server name(s) in the host selector above - - - - - - - - - -</p>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Information panel -->
    +
    +    <row>
    +        <panel>
    +            <html>
    +
    +                <div class="imgheader custom-modal">
    +                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/info.png" alt="Info"/>
    +                    <h4><a data-modal-name="Help_modal">Help, information and related links for Solaris WLM statistics</a></h4>
    +                </div>
    +
    +                <!-- Modal -->
    +                <div class="modal custom-modal-60 fade" id="Help_modal" tabindex="-1" role="dialog" aria-labelledby="Help_modal_Label">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"></span></button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title" id="Help_modal_Label">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <img src="../../static/app/metricator-for-nmon/icons/dark_theme/cpu.png" alt="CPU"/>
    +                                    <h1>Solaris WLM CPU statistics
    +                                    <br />
    +                                    (os.unix.nmon.processes.wlm*)
    +                                    </h1>
    +                                </div>
    +
    +                                <h1>Description:</h1>
    +
    +                                <div class="list">
    +
    +                                    <b>CPU% for this project or zone or task or user:</b>
    +                                    <br />
    +
    +                                    This value is approximative since processes that terminated during the previous laps can not be accounted
    +                                    <br />
    +                                    Same as 'prstat -J.CPU' (or -Z or -T or -a)
    +                                    <br />
    +                                    As the Number of logical CPUs is known, the % CPU can also be reported in logical CPUs units.
    +                                    <br />
    +                                    (Choose Report CPU usage in Logical CPUs)
    +                                    <br />
    +
    +                                </div>
    +
    +                                <div class="list">
    +                                    <b>MEM% for this project or zone or task or user.</b>
    +                                    <br />
    +                                    Same as 'prstat -J.MEMORY' (or -Z or -T or -a)
    +                                    <br />
    +                                </div>
    +
    +                                <div class="list">
    +                                    <b>WLM CPUs Monitors:</b>
    +                                    <br />
    +
    +                                    <lu>
    +                                        <li>WLMPROJECTCPU, project name</li>
    +                                        <li>WLMZONECPU, zone name</li>
    +                                        <li>WLMTASKCPU, task id</li>
    +                                        <li>WLMUSERCPU, username</li>
    +                                    </lu>
    +
    +                                    <br />
    +
    +                                </div>
    +
    +                                <div class="list">
    +
    +                                    <b>WLM MEM Monitors:</b>
    +                                    <br />
    +
    +                                    <lu>
    +                                        <li>WLMPROJECTMEM, project name</li>
    +                                        <li>WLMZONEMEM, zone name</li>
    +                                        <li>WLMTASKMEM, task id</li>
    +                                        <li>WLMUSERMEM, username</li>
    +                                    </lu>
    +
    +                                    <br />
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mcatalog%20values(metric_name)%20as%20metrics%20values(dimension_device)%20as%20dimension_device%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.wlm*%20OStype%3DSolaris%20host%3D*" class="tryitbtnxl">mcatalog »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.wlm*%20OStype%3DSolaris%20host%3D*%20dimension_device%3D*%20by%20metric_name%20host%20dimension_device%20span%3D1m" class="tryitbtnxl">mstats raw query»
    +                                    </a>
    +
    +                                    <a target="_blank" href="Dashboard_WLM_Solaris" class="tryitbtnxl">BubbleChart Dashboard »
    +                                    </a>
    +
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related metrics:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;" class="cat_title">
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpu_all.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpu_all.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.cpu.cpunn.*%20host%3D*%20by%20metric_name%2C%20host%20span%3D1m" class="tryitbtnxl">os.unix.nmon.cpu.cpunn.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=%7C%20mstats%20avg(_value)%20as%20value%20where%20%60nmon_metrics_index%60%20metric_name%3Dos.unix.nmon.processes.top.*%20host%3D*%20by%20metric_name%2C%20host%2C%20dimension_Command%20span%3D1m" class="tryitbtnxl">os.unix.nmon.processes.top.* »
    +                                    </a>
    +
    +                                    <a target="_blank" href="search?q=search%20eventtype%3Dnmon%3Aevents%20type%3DUARG" class="tryitbtnxl">UARG events »
    +                                    </a>
    +
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <!-- Base Searches for PostProcessing -->
    +
    +    <search id="populate">
    +        <query>| mcatalog values(metric_name) where `nmon_metrics_index` metric_name="os.unix.nmon.processes.wlm*" OStype="Solaris" by host, dimension_device
    +| `mapping_frameID`
    +| stats count by frameID, host, dimension_device | sort 0 host
    +        </query>
    +        <earliest>$timerange.earliest$</earliest>
    +        <latest>$timerange.latest$</latest>
    +    </search>
    +
    +    <row>
    +        <panel>
    +
    +            <table depends="$type_monitor_cpu$">
    +                <search depends="$type_monitor_cpu$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=$monitor_cpu$ host=$host-prefilter$ $host_query$ $device$ by host dimension_device span=1m
    +| `$timefilter$`
    +| stats max(value) AS max_value, avg(value) AS avg_value, min(value) AS min_value, sparkline($statsmode$(value)) As sparkline by  host, dimension_device
    +| sort limit=0 host
    +| eval value=round(value,2)
    +| fields host,dimension_device,max_value, avg_value, min_value,sparkline
    +| rename dimension_device AS $dimension_label$
    +| foreach "*_value" [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 2) ] | sort - avg_value</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +            <table depends="$type_monitor_mem$">
    +                <search depends="$type_monitor_mem$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=$monitor_mem$ host=$host-prefilter$ $host_query$ $device$ by host dimension_device span=1m
    +| `$timefilter$`
    +| stats max(value) AS max_value, avg(value) AS avg_value, min(value) AS min_value, sparkline($statsmode$(value)) As sparkline by  host, dimension_device
    +| sort limit=0 host
    +| eval value=round(value,2)
    +| fields host,dimension_device,max_value, avg_value, min_value,sparkline
    +| rename dimension_device AS $dimension_label$
    +| foreach "*_value" [ eval "&lt;&lt;FIELD&gt;&gt;"=round('&lt;&lt;FIELD&gt;&gt;', 2) ] | sort - avg_value</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">cell</option>
    +                <option name="count">10</option>
    +                <option name="refresh.display">none</option>
    +                <option name="percentagesRow">false</option>
    +                <!-- Set sparkline options here; make sure that field matches field name of the search results -->
    +                <format type="sparkline" field="sparkline">
    +                    <option name="lineColor">#5379af</option>
    +                    <option name="fillColor">#CCDDFF</option>
    +                    <option name="lineWidth">1</option>
    +                    <option name="height">25</option>
    +                </format>
    +                <format type="color" field="max_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="avg_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +                <format type="color" field="min_value">
    +                    <colorPalette type="minMidMax" maxColor="#31A35F" minColor="#353535"></colorPalette>
    +                    <scale type="minMidMax"></scale>
    +                </format>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel id="settings">
    +            <title>Charting parameters</title>
    +            <input type="dropdown" token="chart" searchWhenChanged="true">
    +                <label>Select a type of chart:</label>
    +                <default>line</default>
    +                <choice value="area">Area</choice>
    +                <choice value="line">Line</choice>
    +                <choice value="column">Column</choice>
    +                <choice value="bar">Bar</choice>
    +            </input>
    +            <input type="dropdown" token="charting.chart.nullValueMode" searchWhenChanged="true">
    +                <label>Missing Data:</label>
    +                <default>gaps</default>
    +                <choice value="gaps">Gaps</choice>
    +                <choice value="connect">Connect</choice>
    +                <choice value="zero">Zero</choice>
    +            </input>
    +            <input type="dropdown" token="chart.stackingmode" searchWhenChanged="true">
    +                <label>Select a stacking mode:</label>
    +                <default>unstacked</default>
    +                <choice value="stacked">stacked (lines excluded)</choice>
    +                <choice value="stacked100">100% stacked (lines excluded)</choice>
    +                <choice value="unstacked">unstacked</choice>
    +            </input>
    +            <input type="dropdown" token="charting.legend.placement" searchWhenChanged="true">
    +                <label>Legend placement:</label>
    +                <default>bottom</default>
    +                <choice value="bottom">Bottom</choice>
    +                <choice value="top">Top</choice>
    +                <choice value="left">left</choice>
    +                <choice value="right">right</choice>
    +                <choice value="none">none</choice>
    +            </input>
    +            <input type="dropdown" token="span" searchWhenChanged="true">
    +                <label>Span:</label>
    +                <default>`nmon_span`</default>
    +                <choice value="`nmon_span`">auto</choice>
    +                <choice value="span=1m">1 minute</choice>
    +                <choice value="span=2m">2 minutes</choice>
    +                <choice value="span=3m">3 minutes</choice>
    +                <choice value="span=4m">4 minutes</choice>
    +                <choice value="span=5m">5 minutes</choice>
    +                <choice value="span=10m">10 minutes</choice>
    +                <choice value="span=15m">15 minutes</choice>
    +                <choice value="span=30m">30 minutes</choice>
    +                <choice value="span=1h">1 hour</choice>
    +                <choice value="span=2h">2 hours</choice>
    +                <choice value="span=12h">12 hours</choice>
    +                <choice value="span=4h">4 hours</choice>
    +                <choice value="span=1d">1 day</choice>
    +                <choice value="span=2d">2 days</choice>
    +                <choice value="span=1w">7 days</choice>
    +                <choice value="span=1mon">1 month</choice>
    +            </input>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>WorkLoad Manager CPU/MEM statistics</title>
    +
    +            <chart depends="$type_monitor_cpu$">
    +                <search depends="$type_monitor_cpu$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=$monitor_cpu$ Ostype=Solaris host=$host-prefilter$ $host_query$ $device$ by host dimension_device span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| eval key=host . ":" . dimension_device
    +| timechart $span$ limit=0 useother=f $statsmode$(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">CPU Usage (% or Logical CPUs)</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +            <chart depends="$type_monitor_mem$">
    +                <search depends="$type_monitor_mem$">
    +                    <query>| mstats avg(_value) as value where `nmon_metrics_index` metric_name=$monitor_mem$ Ostype=Solaris host=$host-prefilter$ $host_query$ $device$ by host dimension_device span=1m
    +| `$timefilter$`
    +| $aggregate$
    +| eval key=host . ":" . dimension_device
    +| timechart $span$ limit=0 useother=f $statsmode$(value) As value by key</query>
    +                    <earliest>$timerange.earliest$</earliest>
    +                    <latest>$timerange.latest$</latest>
    +                    <refresh>$refresh$</refresh>
    +                    <refreshType>delay</refreshType>
    +                </search>
    +                <option name="charting.axisTitleX.visibility">visible</option>
    +                <option name="charting.axisTitleY.visibility">visible</option>
    +                <option name="charting.axisX.scale">linear</option>
    +                <option name="charting.axisY.scale">linear</option>
    +                <option name="charting.chart">$chart$</option>
    +                <option name="charting.chart.nullValueMode">$charting.chart.nullValueMode$</option>
    +                <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
    +                <option name="charting.chart.stackMode">$chart.stackingmode$</option>
    +                <option name="charting.chart.style">shiny</option>
    +                <option name="charting.drilldown">all</option>
    +                <option name="charting.layout.splitSeries">0</option>
    +                <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
    +                <option name="charting.legend.placement">$charting.legend.placement$</option>
    +                <option name="height">680</option>
    +                <option name="charting.axisTitleX.text">Time</option>
    +                <option name="charting.axisY.minimumNumber">0</option>
    +                <option name="charting.axisTitleY.text">CPU Usage (% or Logical CPUs)</option>
    +                <option name="refresh.display">none</option>
    +            </chart>
    +
    +        </panel>
    +    </row>
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_data_dictionary.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_data_dictionary.xml
    new file mode 100644
    index 0000000..f2fdd45
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/UI_data_dictionary.xml
    @@ -0,0 +1,147 @@
    +<form script="autodiscover.js" stylesheet="ui_simple.css" isVisible="true" version="1.1" theme="dark">
    +
    +    <label>mcatalog data dictionary - discover and explore performance metrics</label>
    +    <description>Explore available raw metrics with the dendogram visualization</description>
    +
    +    <row>
    +        <html>
    +            <div style="text-align: center;">
    +                <img src="../../static/app/metricator-for-nmon/icons/dark_theme/dictionary.png" alt="Dictionary"/>
    +            </div>
    +            <div class="custom">
    +                <h1>Data dictionary</h1>
    +            </div>
    +        </html>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <title>Filtering options:</title>
    +
    +            <input type="dropdown" token="show_OStype_tk" searchWhenChanged="true">
    +                <label>Filter by Operating System:</label>
    +                <choice value="false">false</choice>
    +                <choice value="true">true</choice>
    +                <default>false</default>
    +                <change>
    +                    <condition value="true">
    +                        <set token="show_OStype">true</set>
    +                    </condition>
    +                    <condition value="true">
    +                        <unset token="show_OStype"></unset>
    +                    </condition>
    +                </change>
    +            </input>
    +
    +            <input type="dropdown" depends="$show_OStype$" token="osfilter" searchWhenChanged="true">
    +                <label>Is relevant for:</label>
    +                <choice value="*">Any</choice>
    +                <choice value="AIX">AIX</choice>
    +                <choice value="Linux">Linux</choice>
    +                <choice value="Solaris">Solaris</choice>
    +                <default>*</default>
    +            </input>
    +
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +
    +            <table>
    +                <title>Brief Data Table: click on a row to show the detail of metrics available</title>
    +                <search>
    +                    <query>| `def_mcatalog_dictionary($osfilter$)`
    +|  eval main_type="raw_metrics"
    +|  stats dc(metric) as "number of metrics" by main_type, metric_category</query>
    +                    <earliest>-24h</earliest>
    +                    <latest>now</latest>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">50</option>
    +                <drilldown>
    +                    <set token="drilldown_itemfilter">"$row.metric_category$"</set>
    +                    <set token="form.filtered_metric_category">"$row.metric_category$"</set>
    +                    <set token="show_filtered_metric_category">true</set>
    +                </drilldown>
    +            </table>
    +
    +            <table depends="$drilldown_itemfilter$">
    +                <title>Details:</title>
    +                <search>
    +                    <query>| `def_mcatalog_dictionary($osfilter$)` | where (metric_category == $drilldown_itemfilter$ ) | fields - count | sort 0 metric_category, nmon_section, metric</query>
    +                    <earliest>-24h</earliest>
    +                    <latest>now</latest>
    +                </search>
    +                <option name="wrap">true</option>
    +                <option name="rowNumbers">false</option>
    +                <option name="dataOverlayMode">none</option>
    +                <option name="drilldown">row</option>
    +                <option name="count">50</option>
    +            </table>
    +
    +        </panel>
    +    </row>
    +
    +    <!-- See https://splunkbase.splunk.com/app/2717-->
    +    <!-- All components are integrated within the App core -->
    +
    +    <row>
    +        <panel>
    +            <title>mcatalog dictionary</title>
    +
    +            <input type="dropdown" token="mcatalog_macro" searchWhenChanged="true">
    +                <label>Show metric dimensions:</label>
    +                <choice value="def_mcatalog_dictionary">false</choice>
    +                <choice value="def_mcatalog_dictionary_with_dimensions">true</choice>
    +                <default>def_mcatalog_dictionary</default>
    +            </input>
    +
    +            <input type="dropdown" depends="$show_filtered_metric_category$" token="filtered_metric_category" searchWhenChanged="true">
    +                <label>Filtered metric_category:</label>
    +                <choice value="*">Any</choice>
    +                <default>*</default>
    +            </input>
    +
    +            <html>
    +                <h4>Click on nodes to hide or develop associated items:</h4>
    +
    +                <br />
    +                <i>Dendgram built using Custom viz Dendogram visualization, https://splunkbase.splunk.com/app/2717</i>
    +                <br />
    +
    +                <div id="dendrogram_search" class="splunk-manager" data-require="splunkjs/mvc/searchmanager" data-options='{
    +          "search": {
    +            "type": "token_safe",
    +            "value": "| `$$mcatalog_macro$$($$osfilter$$)` | search (metric_category=$$filtered_metric_category$$ )"
    +          },
    +          "preview": true,
    +          "earliest_time": {
    +            "type": "token_safe",
    +            "value": "-24h"
    +          },
    +          "latest_time": {
    +            "type": "token_safe",
    +            "value": "now"
    +          }
    +        }'>
    +                </div>
    +                <div id="dendrogram" style="width:100%; overflow-x:scroll; border:dotted 1px black;" class="splunk-view" data-require="app/metricator-for-nmon/components/dendrogram/dendrogram" data-options='{
    +          "managerid": "dendrogram_search",
    +          "root_label": "Nmon Splunk App",
    +          "height": 3500,
    +          "width": 1700,
    +          "initial_open_level": 6,
    +          "has_size": true,
    +          "margin_left": 200,
    +          "margin_right": 200
    +        }'>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +</form>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/configuration.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/configuration.xml
    new file mode 100644
    index 0000000..6fa4966
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/configuration.xml
    @@ -0,0 +1,20 @@
    +<?xml version="1.0"?>
    +<!--
    +  ~ Copyright 2021 Splunk Inc.
    +  ~
    +  ~ Licensed 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.
    +  ~
    +-->
    +<view template="metricator-for-nmon:/templates/base.html" type="html" isDashboard="False">
    +	<label>Configuration</label>
    +</view>
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_alerting_threshold_filesystem_v2.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_alerting_threshold_filesystem_v2.xml
    new file mode 100644
    index 0000000..e2dee88
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_alerting_threshold_filesystem_v2.xml
    @@ -0,0 +1,329 @@
    +<dashboard version="1.1" theme="dark" stylesheet="manage_alerting_threshold_filesystem_v2.css,table_data_bar.css" script="manage_alerting_threshold_filesystem_v2.js,manage_alerting_threshold_filesystem_table_bar.js" hideEdit="true">
    +    <label>Configuration and management of per server file-system alerting threshold</label>
    +    <row>
    +        <panel>
    +            <html>
    +                <style>
    +                    .parent-top-single {
    +                        display: grid;
    +                        grid-template-columns: repeat(3, 1fr);
    +                        grid-template-rows: 1fr;
    +                        grid-column-gap: 0px;
    +                        grid-row-gap: 0px;
    +                    }
    +                </style>
    +
    +                <!-- modal windows -->
    +
    +                <!-- Help Modal -->
    +                <div class="modal custom-modal-60 fade" id="modal_help" tabindex="-1" role="dialog">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
    +                                    <span aria-hidden="true"></span>
    +                                </button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: center;">
    +                                    <h1>ALERTING THRESHOLD MANAGEMENT</h1>
    +                                </div>
    +                                <div>
    +                                    <h3>The alerting threshold management interface allows you to configure Nmon alerting features for:</h3>
    +                                    <ul>
    +                                        <li>CPU usage monitoring for continuous configurable peaks in seconds</li>
    +                                        <li>Physical memory usage monitoring for continuous configurable peaks in seconds</li>
    +                                        <li>Virtual memory usage monitoring for continuous configurable peaks in seconds</li>
    +                                    </ul>
    +
    +                                    <h3>By default, the alerting reports run for all servers with the following parameters:</h3>
    +                                    <ul>
    +                                        <li>
    +                                            <span style="color: indianred">90 %</span> of usage for CPU and Physical memory usage</li>
    +                                        <li>
    +                                            <span style="color: indianred">40 %</span> of usage for Virtual memory usage</li>
    +                                        <li>
    +                                            <span style="color: indianred">5 minutes (300 seconds)</span> of continuous peak</li>
    +                                    </ul>
    +
    +                                    <h3>Alerting reports use KVstore alerting collections to allow a per server configuration:</h3>
    +                                    <div class="list">
    +                                        <h4>CPU usage:</h4>
    +                                        <lu>
    +                                            <li>alert_cpu_max_percent</li>
    +                                            <li>alert_cpu_min_seconds</li>
    +                                        </lu>
    +                                    </div>
    +                                    <div class="list">
    +                                        <h4>Physical memory usage:</h4>
    +                                        <lu>
    +                                            <li>alert_physical_memory_max_percent</li>
    +                                            <li>alert_physical_memory_min_time_seconds</li>
    +                                        </lu>
    +                                    </div>
    +                                    <div class="list">
    +                                        <h4>Virtual memory usage:</h4>
    +                                        <lu>
    +                                            <li>alert_virtual_memory_max_percent</li>
    +                                            <li>alert_virtual_memory_min_time_seconds</li>
    +                                        </lu>
    +                                    </div>
    +                                    <h3>When a server is matched within the <span style="color: indianred">nmon_alerting_threshold</span> KVstore lookup, the server thresholds settings will override default alerting parameters.</h3>
    +                                    <h3>Per server alerting entries have the <span style="color: indianred">highest</span> priority against any other settings.</h3>
    +                                    <h3>Lookup access:</h3>
    +                                    <pre>| inputlookup nmon_alerting_threshold_filesystem</pre>
    +                                </div>
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Error or failure during the operation -->
    +                <div class="modal fade" id="modal_generic_error" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: indianred;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Oops!</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <h1>Sorry but it looks like an error occurred while attempting to perform this operation.</h1>
    +                                <h2>You might not have the permission to do so, or an unexpected failure was encountered.</h2>
    +                                <b>The server returned the following error message:</b>
    +                                <div class="modal-error-message">
    +                                    <p>error return message</p>
    +                                </div>
    +                            </div>
    +                        </div>
    +
    +                        <div class="modal-footer">
    +                            <button type="submit" class="btn btn-default pull-right" data-dismiss="modal">
    +                                <span class="glyphicon glyphicon-remove"></span> Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- successful operation -->
    +                <div class="modal fade" id="modal_generic_success" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: #77dd77;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Success</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div class="modal-success-message">
    +                                    <h2>The operation was achieved successfully.</h2>
    +                                </div>
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="submit" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Ok</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- add entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_add_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Add entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +                                    <h2>
    +                                        You can manually add a new entity to the frameID mapping collection, fill the required information and click on submit to add this new entity:
    +                                    </h2>
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_add_frameid">
    +                                            <label>set frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_serialnum">
    +                                            <label>set serialnum:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_host">
    +                                            <label>set host:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_mount">
    +                                            <label>set mount:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_fs_max_percent">
    +                                            <label>set alert_fs_max_percent:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_fs_min_time_seconds">
    +                                            <label>set alert_fs_min_time_seconds:</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_new_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Submit</button>
    +                                <button id="btn_cancel_new_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- update entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_update_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Update or delete entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +
    +                                    <h2>
    +                                        Update the entity information in the following inputs and click on the update button. If you wish to delete this entity from the collection, click on delete.
    +                                    </h2>
    +
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_update_frameid">
    +                                            <label>update frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_serialnum">
    +                                            <label>update serialnum:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_host">
    +                                            <label>update host:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_mount">
    +                                            <label>update mount:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_fs_max_percent">
    +                                            <label>alert_fs_max_percent:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_fs_min_time_seconds">
    +                                            <label>alert_fs_min_time_seconds:</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_delete_entity" style="margin-right: 10px;" class="btn btn-danger pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Delete this entity</button>
    +                                <button id="btn_submit_update_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Update this entity</button>
    +                                <button id="btn_cancel_update_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- end modals -->
    +
    +                <div class="parent-top-single">
    +                    <div id="element_unset_exclusions">
    +                    </div>
    +                    <div id="element_nb_hosts">
    +                    </div>
    +                    <div id="element_nb_mount">
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +                    <button id="btn_help" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span> Help &amp; information</button>
    +                    <button id="btn_add_new_template" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span>Add a new server threshold</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +
    +                    <div>
    +                        <h2>Filters:</h2>
    +                    </div>
    +
    +                    <div class="fieldset">
    +
    +                        <div class="input input-text" id="input_inventory_search_frameid">
    +                            <label>Search frameID:</label>
    +                        </div>
    +                        <div class="input input-text" id="input_inventory_search_serialnum">
    +                            <label>Search serialnum:</label>
    +                        </div>
    +                        <div class="input input-text" id="input_inventory_search_host">
    +                            <label>Search host:</label>
    +                        </div>
    +                        <div class="input input-text" id="input_inventory_search_mount">
    +                            <label>Search mount point:</label>
    +                        </div>
    +                        <div class="input input-text" id="input_inventory_search_filesystem">
    +                            <label>Search filesystem:</label>
    +                        </div>
    +
    +                    </div>
    +
    +                    <div style="margin-left: 20px;">
    +                        <div class="input input-linklist" id="inputLink">
    +                            <label></label>
    +                        </div>
    +                    </div>
    +
    +                    <div id="tableParent1" style="display: none;">
    +                        <h2>You can search any existing server using the optional fields, fill the filters and press enter.
    +                        </h2>
    +                        <h3>
    +                            <b>alert max value is in percentage and min time is in seconds</b>, mount point is <b>case insensitive and accepts wildcards</b> to match multiple mount points at once
    +                        </h3>
    +                        <h3 style="color: dodgerblue;">To create a new rule for a given machine and file-system, click on the corresponding row to open the helper screen.</h3>
    +                        <div id="element_table_show_lookup_inventory">
    +                        </div>
    +                    </div>
    +
    +                    <div id="tableParent2" style="display: none;">
    +                        <h2>Threshold table - currently configured alerting thresholds per server</h2>
    +                        <h3 style="color: dodgerblue;">To update or delete an existing rule, click on the corresponding row to open the helper screen.</h3>
    +                        <div id="element_table_show_lookup_content">
    +                        </div>
    +                    </div>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +</dashboard>
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_alerting_threshold_v2.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_alerting_threshold_v2.xml
    new file mode 100644
    index 0000000..9200516
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_alerting_threshold_v2.xml
    @@ -0,0 +1,338 @@
    +<dashboard version="1.1" theme="dark" stylesheet="manage_alerting_threshold_v2.css,table_data_bar.css" script="manage_alerting_threshold_v2.js,manage_alerting_threshold_table_bar.js" hideEdit="true">
    +    <label>Configuration and management of per server alerting threshold</label>
    +    <description>Use this interface to configure cpu, physical and virtual memory threshold for alerting</description>
    +    <row>
    +        <panel>
    +            <html>
    +                <style>
    +                    .parent-top-single {
    +                        display: grid;
    +                        grid-template-columns: repeat(2, 1fr);
    +                        grid-template-rows: 1fr;
    +                        grid-column-gap: 0px;
    +                        grid-row-gap: 0px;
    +                    }
    +                </style>
    +
    +                <!-- modal windows -->
    +
    +                <!-- Help Modal -->
    +                <div class="modal custom-modal-60 fade" id="modal_help" tabindex="-1" role="dialog">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
    +                                    <span aria-hidden="true"></span>
    +                                </button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: center;">
    +                                    <h1>ALERTING THRESHOLD MANAGEMENT</h1>
    +                                </div>
    +                                <div>
    +                                    <h3>The alerting threshold management interface allows you to configure Nmon alerting features for:</h3>
    +                                    <ul>
    +                                        <li>CPU usage monitoring for continuous configurable peaks in seconds</li>
    +                                        <li>Physical memory usage monitoring for continuous configurable peaks in seconds</li>
    +                                        <li>Virtual memory usage monitoring for continuous configurable peaks in seconds</li>
    +                                    </ul>
    +                                    <h3>By default, the alerting reports run for all servers with the following parameters:</h3>
    +                                    <ul>
    +                                        <li>
    +                                            <span style="color: indianred">90 %</span> of usage for CPU and Physical memory usage</li>
    +                                        <li>
    +                                            <span style="color: indianred">40 %</span> of usage for Virtual memory usage</li>
    +                                        <li>
    +                                            <span style="color: indianred">5 minutes (300 seconds)</span> of continuous peak</li>
    +                                    </ul>
    +                                    <h3>Alerting reports use KVstore alerting collections to allow a per server configuration:</h3>
    +                                    <div class="list">
    +                                        <h4>CPU usage:</h4>
    +                                        <ul>
    +                                            <li>alert_cpu_max_percent</li>
    +                                            <li>alert_cpu_min_seconds</li>
    +                                        </ul>
    +                                    </div>
    +                                    <div class="list">
    +                                        <h4>Physical memory usage:</h4>
    +                                        <ul>
    +                                            <li>alert_physical_memory_max_percent</li>
    +                                            <li>alert_physical_memory_min_time_seconds</li>
    +                                        </ul>
    +                                    </div>
    +                                    <div class="list">
    +                                        <h4>Virtual memory usage:</h4>
    +                                        <ul>
    +                                            <li>alert_virtual_memory_max_percent</li>
    +                                            <li>alert_virtual_memory_min_time_seconds</li>
    +                                        </ul>
    +                                    </div>
    +                                    <h3>When a server is matched within the <span style="color: indianred">nmon_alerting_threshold</span> KVstore lookup, the server thresholds settings will override default alerting parameters.</h3>
    +                                    <h3>Per server alerting entries have the <span style="color: indianred">highest</span> priority against any other settings.</h3>
    +                                    <h3>Lookup access:</h3>
    +                                    <pre>| inputlookup nmon_alerting_threshold</pre>
    +                                </div>
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Error or failure during the operation -->
    +                <div class="modal fade" id="modal_generic_error" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: indianred;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Oops!</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <h1>Sorry but it looks like an error occurred while attempting to perform this operation.</h1>
    +                                <h2>You might not have the permission to do so, or an unexpected failure was encountered.</h2>
    +                                <b>The server returned the following error message:</b>
    +                                <div class="modal-error-message">
    +                                    <p>error return message</p>
    +                                </div>
    +                            </div>
    +                        </div>
    +
    +                        <div class="modal-footer">
    +                            <button type="submit" class="btn btn-default pull-right" data-dismiss="modal">
    +                                <span class="glyphicon glyphicon-remove"></span> Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- successful operation -->
    +                <div class="modal fade" id="modal_generic_success" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: #77dd77;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Success</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div class="modal-success-message">
    +                                    <h2>The operation was achieved successfully.</h2>
    +                                </div>
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="submit" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Ok</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- add entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_add_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Add entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +                                    <h2>
    +                                        You can manually add a new entity to the frameID mapping collection, fill the required information and click on submit to add this new entity:
    +                                    </h2>
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_add_frameid">
    +                                            <label>set frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_serialnum">
    +                                            <label>set serialnum:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_host">
    +                                            <label>set host:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_cpu_max_percent">
    +                                            <label>cpu max %:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_cpu_min_time_seconds">
    +                                            <label>cpu min time (sec):</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_physical_memory_max_percent">
    +                                            <label>physical memory max %:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_physical_memory_min_time_seconds">
    +                                            <label>physical memory min time (sec):</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_virtual_memory_max_percent">
    +                                            <label>virtual memory max %:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_virtual_memory_min_time_seconds">
    +                                            <label>virtual memory min time (sec):</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_new_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Submit</button>
    +                                <button id="btn_cancel_new_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- update entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_update_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Update or delete entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +
    +                                    <h2>
    +                                        Update the entity information in the following inputs and click on the update button. If you wish to delete this entity from the collection, click on delete.
    +                                    </h2>
    +
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_update_frameid">
    +                                            <label>update frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_serialnum">
    +                                            <label>update serialnum:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_host">
    +                                            <label>update host:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_cpu_max_percent">
    +                                            <label>cpu max %:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_cpu_min_time_seconds">
    +                                            <label>cpu min time (sec):</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_physical_memory_max_percent">
    +                                            <label>physical memory max %:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_physical_memory_min_time_seconds">
    +                                            <label>physical memory min time (sec):</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_virtual_memory_max_percent">
    +                                            <label>virtual memory max %:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_virtual_memory_min_time_seconds">
    +                                            <label>virtual memory min time (sec):</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_delete_entity" style="margin-right: 10px;" class="btn btn-danger pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Delete this entity</button>
    +                                <button id="btn_submit_update_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Update this entity</button>
    +                                <button id="btn_cancel_update_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- end modals -->
    +
    +                <div class="parent-top-single">
    +                    <div id="element_unset_exclusions">
    +                    </div>
    +                    <div id="element_nb_hosts">
    +                    </div>
    +                </div>
    +
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +                    <button id="btn_help" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span> Help &amp; information</button>
    +                    <button id="btn_add_new_template" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span>Add a new server threshold</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +
    +                    <div>
    +                        <h2>Filters:</h2>
    +                    </div>
    +
    +                    <div class="fieldset">
    +
    +                        <div class="input input-text" id="input_inventory_search_frameid">
    +                            <label>Search frameID:</label>
    +                        </div>
    +                        <div class="input input-text" id="input_inventory_search_serialnum">
    +                            <label>Search serialnum:</label>
    +                        </div>
    +                        <div class="input input-text" id="input_inventory_search_host">
    +                            <label>Search host:</label>
    +                        </div>
    +
    +                    </div>
    +
    +                    <div style="margin-left: 20px;">
    +                        <div class="input input-linklist" id="inputLink">
    +                            <label></label>
    +                        </div>
    +                    </div>
    +
    +                    <div id="tableParent1" style="display: none;">
    +                        <h2>You can search any existing server using the optional fields, fill the filters and press enter.
    +                        </h2>
    +                        <h3>
    +                            <b>alert max value is in percentage and min time is in seconds</b>, mount point is <b>case insensitive and accepts wildcards</b> to match multiple mount points at once
    +                        </h3>
    +                        <h3 style="color: dodgerblue;">To create a new rule for a given machine and file-system, click on the corresponding row to open the helper screen.</h3>
    +                        <div id="element_table_show_lookup_inventory">
    +                        </div>
    +                    </div>
    +
    +                    <div id="tableParent2" style="display: none;">
    +                        <h2>Threshold table - currently configured alerting thresholds per server</h2>
    +                        <h3 style="color: dodgerblue;">To update or delete an existing rule, click on the corresponding row to open the helper screen.</h3>
    +                        <div id="element_table_show_lookup_content">
    +                        </div>
    +                    </div>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +</dashboard>
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_file_systems_exclusion_v2.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_file_systems_exclusion_v2.xml
    new file mode 100644
    index 0000000..1041e1a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_file_systems_exclusion_v2.xml
    @@ -0,0 +1,289 @@
    +<dashboard version="1.1" theme="dark" stylesheet="manage_file_systems_exclusion_v2.css" script="manage_file_systems_exclusion_v2.js" hideEdit="true">
    +    <label>Configuration and management of per server file system exclusion</label>
    +    <description>Use this interface to automatically exclude specific file systems from file system usage alerting</description>
    +    <row>
    +        <panel>
    +            <html>
    +                <style>
    +                    .parent-top-single {
    +                        display: grid;
    +                        grid-template-columns: repeat(3, 1fr);
    +                        grid-template-rows: 1fr;
    +                        grid-column-gap: 0px;
    +                        grid-row-gap: 0px;
    +                    }
    +                </style>
    +
    +                <!-- modal windows -->
    +
    +                <!-- Help Modal -->
    +                <div class="modal custom-modal-60 fade" id="modal_help" tabindex="-1" role="dialog">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
    +                                    <span aria-hidden="true"></span>
    +                                </button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: center;">
    +                                    <h1>ALERTING PER SERVER FILE-SYSTEM EXCLUSION</h1>
    +                                </div>
    +                                <div>
    +                                    <h3>The alerting per server file-system exclusion management interface allows you to configure Nmon alerting features for:</h3>
    +                                    <ul>
    +                                        <li>exclusion of file-systems from alerting on a per server and per file-system basis</li>
    +                                    </ul>
    +                                    <div class="list">
    +                                        <h4>file-systems exclusion:</h4>
    +                                        <ul>
    +                                            <li>mount: mount point of the Unix file-system</li>
    +                                            <li>exclude: (true/false) explicit exclusion (default)</li>
    +                                        </ul>
    +                                    </div>
    +                                    <h3>When a server is matched within the <span style="color: indianred">nmon_alerting_filesystem_per_server_exclusion</span> KVstore lookup, the file-system will automatically be excluded.</h3>
    +                                    <h3>You can use <span style="color: indianred">wildcards to match multiple file-systems at once, and case is insensitive</span>.
    +                                    </h3>
    +                                    <h3>Lookup access:</h3>
    +                                    <pre>| inputlookup nmon_alerting_filesystem_per_server_exclusion</pre>
    +                                </div>
    +                            </div>
    +                        </div>
    +                        <div class="modal-footer">
    +                            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Error or failure during the operation -->
    +                <div class="modal fade" id="modal_generic_error" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: indianred;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Oops!</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <h1>Sorry but it looks like an error occurred while attempting to perform this operation.</h1>
    +                                <h2>You might not have the permission to do so, or an unexpected failure was encountered.</h2>
    +                                <b>The server returned the following error message:</b>
    +                                <div class="modal-error-message">
    +                                    <p>error return message</p>
    +                                </div>
    +                            </div>
    +                        </div>
    +
    +                        <div class="modal-footer">
    +                            <button type="submit" class="btn btn-default pull-right" data-dismiss="modal">
    +                                <span class="glyphicon glyphicon-remove"></span> Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- successful operation -->
    +                <div class="modal fade" id="modal_generic_success" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: #77dd77;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Success</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div class="modal-success-message">
    +                                    <h2>The operation was achieved successfully.</h2>
    +                                </div>
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="submit" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Ok</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- add entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_add_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Add entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +                                    <h2>
    +                                        Please enter the new mount point to be excluded.
    +                                    </h2>
    +                                    <h3>
    +                                        You can use wildcards to match multiple file-systems at once, and case is insensitive:
    +                                    </h3>
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_add_frameid">
    +                                            <label>set frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_serialnum">
    +                                            <label>set serialnum:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_host">
    +                                            <label>set host:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_mount">
    +                                            <label>set mount:</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_new_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Submit</button>
    +                                <button id="btn_cancel_new_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- update entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_update_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Update or delete entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +
    +                                    <h2>
    +                                        Update the entity information in the following inputs and click on the update button. If you wish to delete this entity from the collection, click on delete.
    +                                    </h2>
    +
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_update_frameid">
    +                                            <label>update frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_serialnum">
    +                                            <label>update serialnum:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_host">
    +                                            <label>update host:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_mount">
    +                                            <label>update mount:</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_delete_entity" style="margin-right: 10px;" class="btn btn-danger pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Delete this entity</button>
    +                                <button id="btn_submit_update_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Update this entity</button>
    +                                <button id="btn_cancel_update_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- end modals -->
    +
    +                <div class="parent-top-single">
    +                    <div id="element_unset_exclusions">
    +                    </div>
    +                    <div id="element_nb_frameID">
    +                    </div>
    +                    <div id="element_nb_mount">
    +                    </div>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +                    <button id="btn_help" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span> Help &amp; information</button>
    +                    <button id="btn_add_new_template" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span>Add a new exclusion</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +
    +                    <div>
    +                        <h2>Filters:</h2>
    +                    </div>
    +
    +                    <div class="fieldset">
    +
    +                        <div class="input input-text" id="input_inventory_search_frameid">
    +                            <label>Search frameID:</label>
    +                        </div>
    +                        <div class="input input-text" id="input_inventory_search_serialnum">
    +                            <label>Search serialnum:</label>
    +                        </div>
    +                        <div class="input input-text" id="input_inventory_search_host">
    +                            <label>Search host:</label>
    +                        </div>
    +                        <div class="input input-text" id="input_inventory_search_mount">
    +                            <label>Search mount point:</label>
    +                        </div>
    +                        <div class="input input-text" id="input_inventory_search_filesystem">
    +                            <label>Search filesystem:</label>
    +                        </div>
    +
    +                    </div>
    +
    +                    <div style="margin-left: 20px;">
    +                        <div class="input input-linklist" id="inputLink">
    +                            <label></label>
    +                        </div>
    +                    </div>
    +
    +                    <div id="tableParent1" style="display: none;">
    +                        <h2>This table shows the servers currently in the inventory, to add a new exclusion for that machine, click on the corresponding row:
    +                        </h2>
    +                        <div id="element_table_show_lookup_inventory">
    +                        </div>
    +                    </div>
    +
    +                    <div id="tableParent2" style="display: none;">
    +                        <h2>This table shows exclusions currently configured, click on any row to update or delete this entry.</h2>
    +                        <h3>You can add a new exclusion entry, mount point is case insensitive and accepts wildcards to match multiple mount points at once</h3>
    +                        <div id="element_table_show_lookup_content">
    +                        </div>
    +                    </div>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +</dashboard>
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_file_systems_global_exclusion_v2.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_file_systems_global_exclusion_v2.xml
    new file mode 100644
    index 0000000..8a94334
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_file_systems_global_exclusion_v2.xml
    @@ -0,0 +1,246 @@
    +<dashboard version="1.1" theme="dark" stylesheet="manage_file_systems_global_exclusion_v2.css" script="manage_file_systems_global_exclusion_v2.js" hideEdit="true">
    +    <label>Configuration and management of global file system exclusion</label>
    +    <description>Use this interface to automatically exclude specific file systems for all server usage alerting</description>
    +    <row>
    +        <panel>
    +            <html>
    +                <style>
    +                    .parent-top-single {
    +                        display: grid;
    +                        grid-template-columns: repeat(2, 1fr);
    +                        grid-template-rows: 1fr;
    +                        grid-column-gap: 0px;
    +                        grid-row-gap: 0px;
    +                    }
    +                </style>
    +
    +                <!-- modal windows -->
    +
    +                <!-- Help Modal -->
    +                <div class="modal custom-modal-60 fade" id="modal_help" tabindex="-1" role="dialog">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
    +                                    <span aria-hidden="true"></span>
    +                                </button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: center;">
    +                                    <h1>ALERTING FILE-SYSTEM GLOBAL EXCLUSION</h1>
    +                                </div>
    +                                <div>
    +                                    <h3>The alerting file-system global exclusion management interface allows you to configure Nmon alerting features for:</h3>
    +                                    <ul>
    +                                        <li>global exclusion of file-systems from alerting</li>
    +                                    </ul>
    +                                    <div class="list">
    +                                        <h4>file-systems exclusion:</h4>
    +                                        <ul>
    +                                            <li>mount: mount point of the Unix file-system</li>
    +                                            <li>exclude: (true/false) explicit exclusion (default)</li>
    +                                        </ul>
    +                                    </div>
    +                                    <h3>Global entries will be applied<span style="color: indianred"> for all servers.</span>
    +                                    </h3>
    +                                    <h3>You can use <span style="color: indianred">wildcards to match multiple file-systems at once, and case is insensitive</span>.
    +                                    </h3>
    +                                    <h3>Lookup access:</h3>
    +                                    <pre>| inputlookup nmon_alerting_filesystem_global_exclusion</pre>
    +                                </div>
    +                            </div>
    +                        </div>
    +                        <div class="modal-footer">
    +                            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Error or failure during the operation -->
    +                <div class="modal fade" id="modal_generic_error" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: indianred;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Oops!</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <h1>Sorry but it looks like an error occurred while attempting to perform this operation.</h1>
    +                                <h2>You might not have the permission to do so, or an unexpected failure was encountered.</h2>
    +                                <b>The server returned the following error message:</b>
    +                                <div class="modal-error-message">
    +                                    <p>error return message</p>
    +                                </div>
    +                            </div>
    +                        </div>
    +
    +                        <div class="modal-footer">
    +                            <button type="submit" class="btn btn-default pull-right" data-dismiss="modal">
    +                                <span class="glyphicon glyphicon-remove"></span> Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- successful operation -->
    +                <div class="modal fade" id="modal_generic_success" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: #77dd77;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Success</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div class="modal-success-message">
    +                                    <h2>The operation was achieved successfully.</h2>
    +                                </div>
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="submit" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Ok</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- add entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_add_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Add entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +                                    <h2>
    +                                        Please enter the new mount point to be excluded.
    +                                    </h2>
    +                                    <h3>
    +                                        You can use wildcards to match multiple file-systems at once, and case is insensitive:
    +                                    </h3>
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_add_mount" style="width: 300px;">
    +                                            <label>mount:</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_new_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Submit</button>
    +                                <button id="btn_cancel_new_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- update entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_update_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Update or delete entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +
    +                                    <h2>
    +                                        Update the entity information in the following inputs and click on the update button. If you wish to delete this entity from the collection, click on delete.
    +                                    </h2>
    +
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_update_mount" style="width: 300px;">
    +                                            <label>update mount:</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_delete_entity" style="margin-right: 10px;" class="btn btn-danger pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Delete this entity</button>
    +                                <button id="btn_submit_update_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Update this entity</button>
    +                                <button id="btn_cancel_update_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- end modals -->
    +
    +                <div class="parent-top-single">
    +                    <div id="element_unset_exclusions">
    +                    </div>
    +                    <div id="element_nb_mount">
    +                    </div>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +                    <button id="btn_help" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span> Help &amp; information</button>
    +                    <button id="btn_add_new_template" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span>Add a new exclusion</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +
    +                    <div id="tableParent1">
    +
    +                        <h2>The exclusion table shows exclusions currently configured. To search for an entry, fill the filters and press enter. To pre-fill for addition, modification and deletion, click on any row of the table
    +                        </h2>
    +                        <h3>You can add a new exclusion entry, mount point is case insensitive and accepts wildcards to match multiple mount points at once
    +                        </h3>
    +                        <h3>CAUTION: any global exclusion will be applied to all servers!
    +                        </h3>
    +
    +                        <div class="fieldset">
    +                            <div class="input input-text" id="input_search_mount">
    +                                <label>Search mount:</label>
    +                            </div>
    +                        </div>
    +
    +                        <div id="element_table_show_lookup_content">
    +                        </div>
    +                    </div>
    +
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +</dashboard>
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_file_systems_template_exclusion_v2.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_file_systems_template_exclusion_v2.xml
    new file mode 100644
    index 0000000..577ef9c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_file_systems_template_exclusion_v2.xml
    @@ -0,0 +1,259 @@
    +<dashboard version="1.1" theme="dark" stylesheet="manage_file_systems_template_exclusion_v2.css" script="manage_file_systems_template_exclusion_v2.js" hideEdit="true">
    +    <label>Configuration and management of template file system exclusion</label>
    +    <description>Use this interface to automatically exclude specific file systems for all servers matching the frameID entries</description>
    +    <row>
    +        <panel>
    +            <html>
    +                <style>
    +                    .parent-top-single {
    +                        display: grid;
    +                        grid-template-columns: repeat(3, 1fr);
    +                        grid-template-rows: 1fr;
    +                        grid-column-gap: 0px;
    +                        grid-row-gap: 0px;
    +                    }
    +                </style>
    +
    +                <!-- modal windows -->
    +
    +                <!-- Help Modal -->
    +                <div class="modal custom-modal-60 fade" id="modal_help" tabindex="-1" role="dialog">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
    +                                    <span aria-hidden="true"></span>
    +                                </button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: center;">
    +                                    <h1>ALERTING FILE-SYSTEM TEMPLATE EXCLUSION</h1>
    +                                </div>
    +                                <div>
    +                                    <h3>The alerting file-system template exclusion management interface allows you to configure Nmon alerting features for:</h3>
    +                                    <ul>
    +                                        <li>template exclusion of file-systems from alerting</li>
    +                                    </ul>
    +                                    <div class="list">
    +                                        <h4>file-systems exclusion:</h4>
    +                                        <br />
    +                                        <ul>
    +                                            <li>frameID: value of the frameID</li>
    +                                            <li>mount: mount point of the Unix file-system</li>
    +                                            <li>exclude: (true/false) explicit exclusion (default)</li>
    +                                        </ul>
    +                                    </div>
    +                                    <h3>Template entries will be applied<span style="color: indianred"> for all servers matching the frameID.</span>
    +                                    </h3>
    +                                    <h3>You can use <span style="color: indianred">wildcards to match multiple file-systems at once, and case is insensitive</span>.
    +                                    </h3>
    +                                    <h3>Lookup access:</h3>
    +                                    <pre>| inputlookup nmon_alerting_filesystem_template_exclusion</pre>
    +                                </div>
    +                            </div>
    +                        </div>
    +                        <div class="modal-footer">
    +                            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Error or failure during the operation -->
    +                <div class="modal fade" id="modal_generic_error" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: indianred;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Oops!</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <h1>Sorry but it looks like an error occurred while attempting to perform this operation.</h1>
    +                                <h2>You might not have the permission to do so, or an unexpected failure was encountered.</h2>
    +                                <b>The server returned the following error message:</b>
    +                                <div class="modal-error-message">
    +                                    <p>error return message</p>
    +                                </div>
    +                            </div>
    +                        </div>
    +
    +                        <div class="modal-footer">
    +                            <button type="submit" class="btn btn-default pull-right" data-dismiss="modal">
    +                                <span class="glyphicon glyphicon-remove"></span> Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- successful operation -->
    +                <div class="modal fade" id="modal_generic_success" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: #77dd77;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Success</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div class="modal-success-message">
    +                                    <h2>The operation was achieved successfully.</h2>
    +                                </div>
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="submit" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Ok</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- add entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_add_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Add entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +                                    <h2>
    +                                        Please enter the new mount point to be excluded.
    +                                    </h2>
    +                                    <h3>
    +                                        You can use wildcards to match multiple file-systems at once, and case is insensitive:
    +                                    </h3>
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_add_frameid">
    +                                            <label>frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_mount" style="width: 300px;">
    +                                            <label>mount:</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_new_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Submit</button>
    +                                <button id="btn_cancel_new_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- update entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_update_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Update or delete entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +
    +                                    <h2>
    +                                        Update the entity information in the following inputs and click on the update button. If you wish to delete this entity from the collection, click on delete.
    +                                    </h2>
    +
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_update_frameid">
    +                                            <label>update frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_mount" style="width: 300px;">
    +                                            <label>update mount:</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_delete_entity" style="margin-right: 10px;" class="btn btn-danger pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Delete this entity</button>
    +                                <button id="btn_submit_update_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Update this entity</button>
    +                                <button id="btn_cancel_update_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- end modals -->
    +
    +                <div class="parent-top-single">
    +                    <div id="element_unset_exclusions">
    +                    </div>
    +                    <div id="element_nb_frameID">
    +                    </div>
    +                    <div id="element_nb_mount">
    +                    </div>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +                    <button id="btn_help" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span> Help &amp; information</button>
    +                    <button id="btn_add_new_template" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span>Add a new exclusion</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +
    +                    <div id="tableParent1">
    +
    +                        <h2>The exclusion table shows exclusions currently configured. To search for an entry, fill the filters and press enter. To pre-fill for addition, modification and deletion, click on any row of the table
    +                        </h2>
    +                        <h3>You can add a new exclusion entry, mount point is case insensitive and accepts wildcards to match multiple mount points at once
    +                        </h3>
    +                        <h3>CAUTION: any exclusion will be applied to all servers matching the frameID!
    +                        </h3>
    +
    +                        <div class="fieldset">
    +                            <div class="input input-text" id="input_search_frameid">
    +                                <label>Search frameID:</label>
    +                            </div>
    +                            <div class="input input-text" id="input_search_mount">
    +                                <label>Search mount:</label>
    +                            </div>
    +                        </div>
    +
    +                        <div id="element_table_show_lookup_content">
    +                        </div>
    +                    </div>
    +
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +</dashboard>
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_frameid_mapping_v2.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_frameid_mapping_v2.xml
    new file mode 100644
    index 0000000..8c1c745
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_frameid_mapping_v2.xml
    @@ -0,0 +1,312 @@
    +<dashboard version="1.1" theme="dark" stylesheet="manage_frameid_mapping_v2.css" script="manage_frameid_mapping_v2.js" hideEdit="true">
    +    <label>frameID mapping management interface</label>
    +    <row>
    +        <panel>
    +            <html>
    +                <style>
    +                    .parent-top-single {
    +                        display: grid;
    +                        grid-template-columns: repeat(3, 1fr);
    +                        grid-template-rows: 1fr;
    +                        grid-column-gap: 0px;
    +                        grid-row-gap: 0px;
    +                    }
    +                </style>
    +
    +                <!-- modal windows -->
    +
    +                <!-- Help Modal -->
    +                <div class="modal custom-modal-60 fade" id="modal_help" tabindex="-1" role="dialog">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
    +                                    <span aria-hidden="true"></span>
    +                                </button>
    +
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +
    +                            <div class="modal-body">
    +
    +                                <div style="text-align: center;">
    +                                    <h1>FRAMEID MAPPING MANAGEMENT</h1>
    +                                </div>
    +
    +                                <div>
    +
    +                                    <h3>The frameID mapping management interface allows to configure frameID mapping on a per server basis:</h3>
    +                                    <lu>
    +                                        <li>logically link a server with a frame identifier</li>
    +                                        <li>to be used as a search filters to filter out groups of server depending in your needs</li>
    +                                        <li>to be used for analytic purposes to perform advanced calculations and aggregations</li>
    +                                    </lu>
    +                                    <br />
    +
    +                                    <br />
    +                                    <div style="text-align: center;">
    +                                        <img src="../../static/app/metricator-for-nmon/diagrams/frameID_mapping.png" alt="frameID_mapping.png"></img>
    +                                    </div>
    +                                    <br />
    +                                </div>
    +
    +                                <div style="text-align:left;">
    +                                    <h1>Related links:</h1>
    +                                </div>
    +
    +                                <div style="text-align: center;">
    +                                    <a target="_blank" href="search?q=%7C%20inputlookup%20nmon_frameID_mapping%0A%7C%20fields%20frameID%2Cserialnum%2Chost%2C*" style="margin: 10px;" class="btn btn-outline-secondary">nmon_frameID_mapping collection »
    +                                    </a>
    +                                    <a target="_blank" href="Manage_alerting_threshold" style="margin: 10px;" class="btn btn-outline-secondary">per server alerting threshold »
    +                                    </a>
    +                                    <a target="_blank" href="Manage_alerting_threshold_filesystem" style="margin: 10px;" class="btn btn-outline-secondary">per server file-systems alerting threshold »
    +                                    </a>
    +                                    <a target="_blank" href="Manage_file_systems_global_exclusion" style="margin: 10px;" class="btn btn-outline-secondary">global file-system alerting exclusion »
    +                                    </a>
    +                                    <a target="_blank" href="Manage_file_systems_exclusion" style="margin: 10px;" class="btn btn-outline-secondary">per server file-system alerting exclusion »
    +                                    </a>
    +                                </div>
    +                            </div>
    +                        </div>
    +                        <div class="modal-footer">
    +                            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Error or failure during the operation -->
    +                <div class="modal fade" id="modal_generic_error" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: indianred;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Oops!</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <h1>Sorry but it looks like an error occurred while attempting to perform this operation.</h1>
    +                                <h2>You might not have the permission to do so, or an unexpected failure was encountered.</h2>
    +                                <b>The server returned the following error message:</b>
    +                                <div class="modal-error-message">
    +                                    <p>error return message</p>
    +                                </div>
    +                            </div>
    +                        </div>
    +
    +                        <div class="modal-footer">
    +                            <button type="submit" class="btn btn-default pull-right" data-dismiss="modal">
    +                                <span class="glyphicon glyphicon-remove"></span> Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- successful operation -->
    +                <div class="modal fade" id="modal_generic_success" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: #77dd77;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Success</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div class="modal-success-message">
    +                                    <h2>The operation was achieved successfully.</h2>
    +                                </div>
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="submit" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Ok</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- add entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_add_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Add entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +
    +                                    <h2>
    +                                        You can manually add a new entity to the frameID mapping collection, fill the required information and click on submit to add this new entity:
    +                                    </h2>
    +
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_add_frameid">
    +                                            <label>set frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_serialnum">
    +                                            <label>set serialnum:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_host">
    +                                            <label>set host:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_host_description">
    +                                            <label>set host desc:</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_new_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Submit</button>
    +                                <button id="btn_cancel_new_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- update entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_update_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Update or delete entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +
    +                                    <h2>
    +                                        Update the entity information in the following inputs and click on the update button. If you wish to delete this entity from the collection, click on delete.
    +                                    </h2>
    +
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_modify_frameid">
    +                                            <label>set frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_modify_serialnum">
    +                                            <label>set serialnum:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_modify_host">
    +                                            <label>set host:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_modify_host_description">
    +                                            <label>set host desc:</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_delete_entity" style="margin-right: 10px;" class="btn btn-danger pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Delete this entity</button>
    +                                <button id="btn_submit_update_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Update this entity</button>
    +                                <button id="btn_cancel_update_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- end modals -->
    +
    +                <div class="parent-top-single">
    +                    <div id="element_unset_frameID">
    +                    </div>
    +                    <div id="element_delta_frameID">
    +                    </div>
    +                    <div id="element_duplicated_hosts">
    +                    </div>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +                    <button id="btn_help" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span> Help &amp; information</button>
    +                    <button id="btn_add_new_mapping" style="margin-left: 10px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span> Add new entry</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +                    <div style="margin-left: 20px;">
    +                        <div class="input input-linklist" id="inputLink">
    +                            <label></label>
    +                        </div>
    +                    </div>
    +
    +                    <div id="tableParent1" style="display: none;">
    +
    +                        <h2>frameID KVstore collection current content:
    +                        </h2>
    +                        <h3>
    +                        The table shows frameID mapping entries currently configured. To search for an entry, fill the filters and press enter. To modify or delete an entity, click on the corresponding row in the table:
    +                        </h3>
    +                        <div>
    +                            <div class="fieldset">
    +                                <div class="input input-text" id="input_search_keyid">
    +                                    <label>search key:</label>
    +                                </div>
    +                                <div class="input input-text" id="input_search_frameid">
    +                                    <label>search frameID:</label>
    +                                </div>
    +                                <div class="input input-text" id="input_search_serialnum">
    +                                    <label>search serialnum:</label>
    +                                </div>
    +                                <div class="input input-text" id="input_search_host">
    +                                    <label>search host:</label>
    +                                </div>
    +                                <div class="input input-text" id="input_search_host_description">
    +                                    <label>search host desc:</label>
    +                                </div>
    +                            </div>
    +                        </div>
    +                        <div id="element_table_show_lookup_content">
    +                        </div>
    +                    </div>
    +
    +                    <div id="tableParent2" style="display: none;">
    +
    +                        <h2>frameID missing hosts:
    +                        </h2>
    +                        <h3>
    +                        Missing frameIDs - The following host(s) have missing entries in the collection, please run the report "Generate NMON frameID mapping lookup table" or manually add the relevant entry (click on the row to pre-fill fields for addition and open the addition screen automatically)
    +                        </h3>
    +                        <div id="element_table_missing_content">
    +                        </div>
    +                    </div>
    +
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +</dashboard>
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_template_alerting_threshold_filesystem_v2.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_template_alerting_threshold_filesystem_v2.xml
    new file mode 100644
    index 0000000..e66aa4f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_template_alerting_threshold_filesystem_v2.xml
    @@ -0,0 +1,313 @@
    +<dashboard version="1.1" theme="dark" stylesheet="manage_template_alerting_threshold_filesystem_v2.css" script="manage_template_alerting_threshold_filesystem_v2.js" hideEdit="true">
    +    <label>Configuration of template alerting threshold for file-systems</label>
    +    <row>
    +        <panel>
    +            <html>
    +                <style>
    +                    .parent-top-single {
    +                        display: grid;
    +                        grid-template-columns: repeat(2, 1fr);
    +                        grid-template-rows: 1fr;
    +                        grid-column-gap: 0px;
    +                        grid-row-gap: 0px;
    +                    }
    +                </style>
    +
    +                <!-- modal windows -->
    +
    +                <!-- Help Modal -->
    +                <div class="modal custom-modal-60 fade" id="modal_help" tabindex="-1" role="dialog">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
    +                                    <span aria-hidden="true"></span>
    +                                </button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: center">
    +                                    <h1>ALERTING THRESHOLD MANAGEMENT</h1>
    +                                </div>
    +                                <div>
    +                                    <h3>
    +                                        Use the alerting threshold management interfaces
    +                                        to configure Nmon alerting features:
    +                                    </h3>
    +                                    <br />
    +                                    <div style="text-align: center">
    +                                        <img src="../../static/app/metricator-for-nmon/diagrams/threshold_management.png" alt="threshold_management.png" />
    +                                    </div>
    +                                    <br />
    +                                    <b>Thresholds are applied the following way:</b>
    +                                    <ul>
    +                                        <li>
    +                                            If a server has per server thresholds
    +                                            configured, these values have the highest
    +                                            priority
    +                                        </li>
    +                                        <li>
    +                                            If a template threshold matches a server
    +                                            (against its frameID), values are applied after
    +                                            per server thresholds
    +                                        </li>
    +                                        <li>
    +                                            If none of those have matches, default macro
    +                                            threshold values will be applied
    +                                        </li>
    +                                    </ul>
    +                                    <br />
    +                                    <h3>Lookup access:</h3>
    +                                    <pre>| inputlookup nmon_alerting_threshold_template_filesystem</pre>
    +                                </div>
    +                            </div>
    +                        </div>
    +                        <div class="modal-footer">
    +                            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Error or failure during the operation -->
    +                <div class="modal fade" id="modal_generic_error" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: indianred;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Oops!</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <h1>Sorry but it looks like an error occurred while attempting to perform this operation.</h1>
    +                                <h2>You might not have the permission to do so, or an unexpected failure was encountered.</h2>
    +                                <b>The server returned the following error message:</b>
    +                                <div class="modal-error-message">
    +                                    <p>error return message</p>
    +                                </div>
    +                            </div>
    +                        </div>
    +
    +                        <div class="modal-footer">
    +                            <button type="submit" class="btn btn-default pull-right" data-dismiss="modal">
    +                                <span class="glyphicon glyphicon-remove"></span> Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- successful operation -->
    +                <div class="modal fade" id="modal_generic_success" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: #77dd77;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Success</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div class="modal-success-message">
    +                                    <h2>The operation was achieved successfully.</h2>
    +                                </div>
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="submit" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Ok</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- add entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_add_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Add entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +                                    <h2>
    +                                        You can manually add a new entity to the frameID mapping collection, fill the required information and click on submit to add this new entity:
    +                                    </h2>
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_add_frameid">
    +                                            <label>Enter the frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_mount">
    +                                            <label>mount:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_fs_max_percent">
    +                                            <label>alert_fs_max_percent:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_fs_min_time_seconds">
    +                                            <label>alert_fs_min_time_seconds:</label>
    +                                        </div>
    +                                        <div class="input input-dropdown" id="input_add_alert_fs_is_shared">
    +                                            <label style="margin-right: 20px">this file-system is shared:</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_new_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Submit</button>
    +                                <button id="btn_cancel_new_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- update entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_update_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Update or delete entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +
    +                                    <h2>
    +                                        Update the entity information in the following inputs and click on the update button. If you wish to delete this entity from the collection, click on delete.
    +                                    </h2>
    +
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_update_frameid">
    +                                            <label>update frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_mount">
    +                                            <label>update mount:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_fs_max_percent">
    +                                            <label>alert_fs_max_percent:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_fs_min_time_seconds">
    +                                            <label>alert_fs_min_time_seconds:</label>
    +                                        </div>
    +                                        <div class="input input-dropdown" id="input_update_alert_fs_is_shared">
    +                                            <label style="margin-right: 20px">this file-system is shared:</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_delete_entity" style="margin-right: 10px;" class="btn btn-danger pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Delete this entity</button>
    +                                <button id="btn_submit_update_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Update this entity</button>
    +                                <button id="btn_cancel_update_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- end modals -->
    +
    +                <div class="parent-top-single">
    +                    <div id="element_unset_exclusions">
    +                    </div>
    +                    <div id="element_nb_hosts">
    +                    </div>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +                    <button id="btn_help" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span> Help &amp; information</button>
    +                    <button id="btn_add_new_template" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span>Add a new template</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +                    <div style="margin-left: 20px;">
    +                        <div class="input input-linklist" id="inputLink">
    +                            <label></label>
    +                        </div>
    +                    </div>
    +
    +                    <div id="tableParent1" style="display: none;">
    +
    +                        <h2>Use template alerting threshold management to apply threshold against frameID. Thresholds will be applied to all matching servers unless servers have per server thresholds configured. (see help link at the bottom of this page)
    +                        </h2>
    +                        <h3>
    +                        The threshold table shows template thresholds currently configured.To pref-fill for modification and deletion, click on any row of the table
    +                        </h3>
    +
    +                        <div class="fieldset">
    +                            <div class="input input-text" id="input_search_frameid">
    +                                <label>Search frameID:</label>
    +                            </div>
    +                            <div class="input input-text" id="input_search_mount">
    +                                <label>Search mount:</label>
    +                            </div>
    +                        </div>
    +
    +                        <div id="element_table_show_lookup_content">
    +                        </div>
    +                    </div>
    +
    +                    <div id="tableParent2" style="display: none;">
    +
    +                        <h2>frameID KVstore collection current content:</h2>
    +                        <h3>The table shows frameID mapping entries currently configured. To search for an entry, fill the filters and press enter</h3>
    +                        <div>
    +                            <div class="fieldset">
    +                                <div class="input input-text" id="input_frameID_search_frameid">
    +                                    <label>Search frameID:</label>
    +                                </div>
    +
    +                                <div class="input input-text" id="input_frameID_search_serialnum">
    +                                    <label>Search serialnum:</label>
    +                                </div>
    +
    +                                <div class="input input-text" id="input_frameID_search_host">
    +                                    <label>Search host:</label>
    +                                </div>
    +
    +                                <div class="input input-text" id="input_frameID_search_host_description">
    +                                    <label>Search host_description:</label>
    +                                </div>
    +
    +                            </div>
    +                        </div>
    +                        <div id="element_table_show_frameID_lookup_content">
    +                        </div>
    +                    </div>
    +
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +</dashboard>
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_template_alerting_threshold_v2.xml b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_template_alerting_threshold_v2.xml
    new file mode 100644
    index 0000000..89072cf
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/data/ui/views/manage_template_alerting_threshold_v2.xml
    @@ -0,0 +1,305 @@
    +<dashboard version="1.1" theme="dark" stylesheet="manage_template_alerting_threshold_v2.css,,table_data_bar.css" script="manage_template_alerting_threshold_v2.js,manage_template_alerting_threshold_table_bar.js" hideEdit="true">
    +    <label>Configuration and management of template alerting threshold</label>
    +    <row>
    +        <panel>
    +            <html>
    +                <style>
    +                    .parent-top-single {
    +                        display: grid;
    +                        grid-template-columns: repeat(2, 1fr);
    +                        grid-template-rows: 1fr;
    +                        grid-column-gap: 0px;
    +                        grid-row-gap: 0px;
    +                    }
    +                </style>
    +
    +                <!-- modal windows -->
    +
    +                <!-- Help Modal -->
    +                <div class="modal custom-modal-60 fade" id="modal_help" tabindex="-1" role="dialog">
    +                    <div class="modal-dialog" role="document">
    +                        <div class="modal-content">
    +                            <div class="modal-header">
    +                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
    +                                    <span aria-hidden="true"></span>
    +                                </button>
    +                                <div style="text-align: left;">
    +                                    <h4 class="modal-title">Integrated Navigation:</h4>
    +                                </div>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div style="text-align: center;">
    +                                    <h1>ALERTING THRESHOLD MANAGEMENT</h1>
    +                                </div>
    +                                <div>
    +                                    <h3>Use the alerting threshold management interfaces to configure Nmon alerting features:</h3>
    +                                    <div style="text-align: center;">
    +                                        <img src="../../static/app/metricator-for-nmon/diagrams/threshold_management.png" alt="threshold_management.png"></img>
    +                                    </div>
    +                                    <b>Thresholds are applied the following way:</b>
    +                                    <lu>
    +                                        <li>If a server has per server thresholds configured, these values have the highest priority</li>
    +                                        <li>If a template threshold matches a server (against its frameID), values are applied after per server thresholds</li>
    +                                        <li>If none of those have matches, default macro threshold values will be applied</li>
    +                                    </lu>
    +                                    <h3>Lookup access:</h3>
    +                                    <pre>| inputlookup nmon_alerting_threshold_template</pre>
    +                                </div>
    +                            </div>
    +                        </div>
    +                        <div class="modal-footer">
    +                            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- Error or failure during the operation -->
    +                <div class="modal fade" id="modal_generic_error" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: indianred;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Oops!</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <h1>Sorry but it looks like an error occurred while attempting to perform this operation.</h1>
    +                                <h2>You might not have the permission to do so, or an unexpected failure was encountered.</h2>
    +                                <b>The server returned the following error message:</b>
    +                                <div class="modal-error-message">
    +                                    <p>error return message</p>
    +                                </div>
    +                            </div>
    +                        </div>
    +
    +                        <div class="modal-footer">
    +                            <button type="submit" class="btn btn-default pull-right" data-dismiss="modal">
    +                                <span class="glyphicon glyphicon-remove"></span> Close</button>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- successful operation -->
    +                <div class="modal fade" id="modal_generic_success" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: #77dd77;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Success</h1>
    +                            </div>
    +                            <div class="modal-body">
    +                                <div class="modal-success-message">
    +                                    <h2>The operation was achieved successfully.</h2>
    +                                </div>
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button type="submit" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Ok</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- add entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_add_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Add entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +                                    <h2>
    +                                        You can manually add a new entity to the frameID mapping collection, fill the required information and click on submit to add this new entity:
    +                                    </h2>
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_add_frameid">
    +                                            <label>Enter the frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_cpu_max_percent">
    +                                            <label>cpu max %:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_cpu_min_time_seconds">
    +                                            <label>cpu min time (sec):</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_physical_memory_max_percent">
    +                                            <label>physical memory max %:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_physical_memory_min_time_seconds">
    +                                            <label>physical memory min time (sec):</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_virtual_memory_max_percent">
    +                                            <label>virtual memory max %:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_add_alert_virtual_memory_min_time_seconds">
    +                                            <label>virtual memory min time (sec):</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +                            </div>
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_new_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Submit</button>
    +                                <button id="btn_cancel_new_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- update entity -->
    +                <div class="modal custom-modal-80 fade" id="modal_update_entity" role="dialog">
    +                    <div class="modal-dialog">
    +
    +                        <!-- Modal content-->
    +                        <div class="modal-content">
    +                            <div class="modal-header modal-header-danger">
    +                                <button type="button" class="close" data-dismiss="modal"></button>
    +                                <h1 style="color: dodgerblue;">
    +                                    <span class="glyphicon glyphicon-lock"></span>Update or delete entity:</h1>
    +                            </div>
    +                            <div class="modal-body">
    +
    +                                <div>
    +
    +                                    <h2>
    +                                        Update the entity information in the following inputs and click on the update button. If you wish to delete this entity from the collection, click on delete.
    +                                    </h2>
    +
    +                                    <div class="fieldset">
    +                                        <div class="input input-text" id="input_update_frameid">
    +                                            <label>update frameID:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_cpu_max_percent">
    +                                            <label>cpu max %:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_cpu_min_time_seconds">
    +                                            <label>cpu min time (sec):</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_physical_memory_max_percent">
    +                                            <label>physical memory max %:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_physical_memory_min_time_seconds">
    +                                            <label>physical memory min time (sec):</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_virtual_memory_max_percent">
    +                                            <label>virtual memory max %:</label>
    +                                        </div>
    +                                        <div class="input input-text" id="input_update_alert_virtual_memory_min_time_seconds">
    +                                            <label>virtual memory min time (sec):</label>
    +                                        </div>
    +                                    </div>
    +                                </div>
    +
    +                            </div>
    +
    +                            <div class="modal-footer">
    +                                <button id="btn_submit_delete_entity" style="margin-right: 10px;" class="btn btn-danger pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Delete this entity</button>
    +                                <button id="btn_submit_update_entity" style="margin-right: 10px;" class="btn btn-primary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Update this entity</button>
    +                                <button id="btn_cancel_update_entity" style="margin-right: 10px;" class="btn btn-secondary pull-right" data-dismiss="modal">
    +                                    <span class="glyphicon glyphicon-remove"></span> Cancel</button>
    +                            </div>
    +
    +                        </div>
    +                    </div>
    +                </div>
    +
    +                <!-- end modals -->
    +
    +                <div class="parent-top-single">
    +                    <div id="element_unset_exclusions">
    +                    </div>
    +                    <div id="element_nb_hosts">
    +                    </div>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +                    <button id="btn_help" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span> Help &amp; information</button>
    +                    <button id="btn_add_new_template" style="margin-left: 20px; margin-right: 10px;" class="btn btn-primary pull-left" data-dismiss="modal">
    +                        <span class="glyphicon glyphicon-remove"></span>Add a new template</button>
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +    <row>
    +        <panel>
    +            <html>
    +                <div>
    +                    <div style="margin-left: 20px;">
    +                        <div class="input input-linklist" id="inputLink">
    +                            <label></label>
    +                        </div>
    +                    </div>
    +
    +                    <div id="tableParent1" style="display: none;">
    +
    +                        <h2>Use template alerting threshold management to apply threshold against frameID. Thresholds will be applied to all matching servers unless servers have per server thresholds configured. (see help link at the bottom of this page)
    +                        </h2>
    +                        <h3>
    +                        The threshold table shows template thresholds currently configured.To pref-fill for modification and deletion, click on any row of the table
    +                        </h3>
    +
    +                        <div class="fieldset">
    +                            <div class="input input-text" id="input_search_frameid">
    +                                <label>Search frameID:</label>
    +                            </div>
    +                        </div>
    +
    +                        <div id="element_table_show_lookup_content">
    +                        </div>
    +                    </div>
    +
    +                    <div id="tableParent2" style="display: none;">
    +
    +                        <h2>frameID KVstore collection current content:</h2>
    +                        <h3>The table shows frameID mapping entries currently configured. To search for an entry, fill the filters and press enter</h3>
    +                        <div>
    +                            <div class="fieldset">
    +                                <div class="input input-text" id="input_frameID_search_frameid">
    +                                    <label>Search frameID:</label>
    +                                </div>
    +
    +                                <div class="input input-text" id="input_frameID_search_serialnum">
    +                                    <label>Search serialnum:</label>
    +                                </div>
    +
    +                                <div class="input input-text" id="input_frameID_search_host">
    +                                    <label>Search host:</label>
    +                                </div>
    +
    +                                <div class="input input-text" id="input_frameID_search_host_description">
    +                                    <label>Search host_description:</label>
    +                                </div>
    +
    +                            </div>
    +                        </div>
    +                        <div id="element_table_show_frameID_lookup_content">
    +                        </div>
    +                    </div>
    +
    +                </div>
    +            </html>
    +        </panel>
    +    </row>
    +
    +</dashboard>
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/default/datamodels.conf b/deployment-apps/metricator-for-nmon/default/datamodels.conf
    new file mode 100644
    index 0000000..4bf30f6
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/datamodels.conf
    @@ -0,0 +1,15 @@
    +# datamodels.conf
    +
    +# data models pre-set default acceleration over the last 30 days
    +
    +# Adapt those values according to your needs
    +
    +[metricator-nmon-config]
    +acceleration = 0
    +acceleration.cron_schedule = */5 * * * *
    +acceleration.earliest_time = -1mon
    +
    +[metricator-nmon-processing]
    +acceleration = 0
    +acceleration.cron_schedule = 4-59/5 * * * *
    +acceleration.earliest_time = -1mon
    diff --git a/deployment-apps/metricator-for-nmon/default/eventtypes.conf b/deployment-apps/metricator-for-nmon/default/eventtypes.conf
    new file mode 100644
    index 0000000..7a3d5b5
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/eventtypes.conf
    @@ -0,0 +1,47 @@
    +# eventtypes.conf
    +
    +##### Customization ####
    +# In case of index name customization or spliting data into multiple indexes, you should
    +# copy the eventtypes.conf to local/eventtypes.conf to adapt eventtypes definition to your needs
    +########################
    +
    +####################
    +# All data         #
    +####################
    +
    +[nmon]
    +search = (index=os-unix-nmon-events* OR index=os-unix-nmon-internal* OR index=os-unix-nmon-config*)
    +
    +####################
    +# Performance data #
    +####################
    +
    +[nmon:events]
    +search = index=os-unix-nmon-events* sourcetype=nmon_data
    +
    +#####################
    +# Others type of data
    +#####################
    +
    +[nmon:config]
    +search = index=os-unix-nmon-config* sourcetype=nmon_config
    +
    +[nmon:collect]
    +search = index=os-unix-nmon-internal* sourcetype=nmon_collect
    +
    +[nmon:processing]
    +search = index=os-unix-nmon-internal* sourcetype=nmon_processing
    +
    +[nmon:clean]
    +search = index=os-unix-nmon-internal* sourcetype=nmon_clean
    +
    +###################
    +# CIM normalization
    +###################
    +
    +# CIM - Uptime stdout (nmon external)
    +[uptime]
    +search = index=os-unix-nmon-events* sourcetype=nmon_data type=UPTIME
    +
    +[inventory]
    +search = index=os-unix-nmon-config* sourcetype=nmon_config
    diff --git a/deployment-apps/metricator-for-nmon/default/macros.conf b/deployment-apps/metricator-for-nmon/default/macros.conf
    new file mode 100644
    index 0000000..3ca18de
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/macros.conf
    @@ -0,0 +1,1625 @@
    +# macros.conf
    +
    +##############
    +# NMON index #
    +##############
    +
    +##### Customization ####
    +# The default model implements a dual index notion:
    +# "nmon_events": for all regular events (index type: Events)
    +# "nmon_metrics": for all metrics indexed as native metrics (index type: Metrics)
    +# You can easily have your own indexes naming convention and/or have more than the 2 defaults indexes (ex. split between Production and non Production)
    +# To achieve this, simply create your local/macros.conf and customize the indexes definition up to your needs
    +########################
    +
    +# This should match all indexes, events and metrics
    +[nmon_index]
    +definition = index="os-unix-nmon-*"
    +iseval = 0
    +
    +# This should match all indexes, events and metrics
    +[nmon_idx]
    +definition = idx="os-unix-nmon-*"
    +iseval = 0
    +
    +# metrics indexes, the definition should match all nmon events indexes
    +[nmon_events_index]
    +definition = index="os-unix-nmon-events*"
    +iseval = 0
    +
    +# metrics indexes, the definition should match all metrics indexes
    +[nmon_metrics_index]
    +definition = index="os-unix-nmon-metrics*"
    +iseval = 0
    +
    +########################################
    +# auto-refresh
    +########################################
    +
    +# This macro is used to define the options available for auto-refresh in dashboards, their order, the default selection and behaviour when looking at past data.
    +# You can transparently customize the macro to match your needs and requirements, if for example you prefer to have no auto refresh by default, or a different value than the one provided by default
    +# If you need to so, create a local copy of the macro bellow and modify it up to your needs.
    +
    +# - The "none" should not be removed, but its default priority can be changed
    +# - the evaluation will ensure that if the user is looking at past period, the auto-refresh is deactivated automatically as it would be point less
    +# - The final order is sorted by priority, from the biggest to the lowest value
    +
    +[def_auto_refresh]
    +definition = makeresults | eval label="30 sec", value="30s", priority=5\
    +| append [ | makeresults | eval label="1 min", value="60s", priority=4 ]\
    +| append [ | makeresults | eval label="5 min", value="300s", priority=3 ]\
    +| append [ | makeresults | eval label="none", value="0", priority=0 ]\
    +| addinfo | fields - _time\
    +| eval now=now(), delta_now=(now - info_max_time), is_past_search=if((delta_now >= 300),"true","false"), priority=if(((label == "none") AND (is_past_search == "true")),100,priority)\
    +| sort 0 - priority\
    +| fields label,value,priority
    +iseval = 0
    +
    +########################################
    +# metric filters macros
    +########################################
    +
    +# Using wildcards have performance hits within metric filters
    +# as much as possible we avoid this
    +
    +# CPU filters for all OS
    +[def_cpu_all_os_metric_filters]
    +definition = metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT\
    +OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT\
    +OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT\
    +OR metric_name=os.unix.nmon.cpu.cpu_all.Idle_PCT\
    +OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.entitled\
    +OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs
    +iseval = 0
    +
    +# memory filters for Linux OS
    +[def_memory_linux_metric_filters]
    +definition = metric_name=os.unix.nmon.memory.mem.memtotal\
    +OR metric_name=os.unix.nmon.memory.mem.active\
    +OR metric_name=os.unix.nmon.memory.mem.inactive\
    +OR metric_name=os.unix.nmon.memory.mem.buffers\
    +OR metric_name=os.unix.nmon.memory.mem.cached\
    +OR metric_name=os.unix.nmon.memory.mem.memfree\
    +OR metric_name=os.unix.nmon.memory.mem.swapcached\
    +OR metric_name=os.unix.nmon.memory.mem.swaptotal\
    +OR metric_name=os.unix.nmon.memory.mem.swapfree
    +iseval = 0
    +
    +# memory filters for AIX OS
    +[def_memory_AIX_metric_filters]
    +definition = metric_name=os.unix.nmon.memory.memnew.System_PCT\
    +OR metric_name=os.unix.nmon.memory.memnew.Process_PCT\
    +OR metric_name=os.unix.nmon.memory.mem.Real_total_MB\
    +OR metric_name=os.unix.nmon.memory.mem.Virtual_free_MB\
    +OR metric_name=os.unix.nmon.memory.mem.Virtual_free_PCT\
    +OR metric_name=os.unix.nmon.memory.mem.Virtual_total_MB
    +iseval = 0
    +
    +# physical memory filters for All OS
    +[def_phys_memory_all_os_metric_filters]
    +definition = metric_name=os.unix.nmon.memory.mem.memtotal\
    +OR metric_name=os.unix.nmon.memory.mem.active\
    +OR metric_name=os.unix.nmon.memory.mem.inactive\
    +OR metric_name=os.unix.nmon.memory.mem.buffers\
    +OR metric_name=os.unix.nmon.memory.mem.cached\
    +OR metric_name=os.unix.nmon.memory.mem.memfree\
    +OR metric_name=os.unix.nmon.memory.memnew.System_PCT\
    +OR metric_name=os.unix.nmon.memory.memnew.Process_PCT\
    +OR metric_name=os.unix.nmon.memory.mem.Real_total_MB
    +iseval = 0
    +
    +# physical and virtual memory filters for All OS
    +[def_memory_all_os_metric_filters]
    +definition = metric_name=os.unix.nmon.memory.mem.memtotal\
    +OR metric_name=os.unix.nmon.memory.mem.active\
    +OR metric_name=os.unix.nmon.memory.mem.inactive\
    +OR metric_name=os.unix.nmon.memory.mem.buffers\
    +OR metric_name=os.unix.nmon.memory.mem.cached\
    +OR metric_name=os.unix.nmon.memory.mem.memfree\
    +OR metric_name=os.unix.nmon.memory.memnew.System_PCT\
    +OR metric_name=os.unix.nmon.memory.memnew.Process_PCT\
    +OR metric_name=os.unix.nmon.memory.memnew.FScache_PCT\
    +OR metric_name=os.unix.nmon.memory.mem.Real_total_MB\
    +OR metric_name=os.unix.nmon.memory.mem.swapcached\
    +OR metric_name=os.unix.nmon.memory.mem.swaptotal\
    +OR metric_name=os.unix.nmon.memory.mem.swapfree\
    +OR metric_name=os.unix.nmon.memory.mem.Virtual_total_MB\
    +OR metric_name=os.unix.nmon.memory.mem.Virtual_free_MB
    +iseval = 0
    +
    +# lpar filters for AIX OS
    +[def_lpar_AIX_metric_filters]
    +definition = metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.EC_Sys_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.EC_User_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.EC_Wait_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.EC_Idle_PCT\
    +OR metric_name=os.unix.nmon.cpu.lpar.entitled\
    +OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs
    +iseval = 0
    +
    +########################################
    +# metric definitions macros
    +########################################
    +
    +# Generic metrics extraction
    +[extract_metrics]
    +definition = rex field="metric_name" ".(?<metric>[\w|\-|\_]*)$"
    +iseval = 0
    +
    +# Generic metrics extraction with the fields list in argument
    +[extract_metrics(1)]
    +args = fields_list
    +definition = `extract_metrics`\
    +| foreach $fields_list$ [ eval "<<FIELD>>" = case(metric="<<FIELD>>", value) ]
    +iseval = 0
    +
    +# Extract metrics for cpu_all
    +[extract_metrics_cpu_all(1)]
    +args = fields_list
    +definition = rex field="metric_name" "os\.unix\.nmon\.\w*\.\w*\.(?<cpu_core>\w*)\.(?<metric>\w*)"\
    +| foreach $fields_list$ [ eval "<<FIELD>>" = case(metric="<<FIELD>>", value) ]
    +iseval = 0
    +
    +# Extract metrics for dimensions and create a key field per metric / dimension
    +[extract_metrics_by_key]
    +definition = rex field=metric_name ".(?<metric>[\w|\-|\_]*)$"\
    +| eval key = metric . ":" . dimension_device
    +iseval = 0
    +
    +# All these macros are used to reduce searches complexity in various dashboards
    +# the macros are expected to be used after the mstats command
    +
    +# define the standard cpu load in percent
    +[def_cpu_load_percent]
    +definition = eval Sys_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Sys_PCT", value), User_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.User_PCT", value), Wait_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Wait_PCT", value), Steal_percent=case(metric_name=="os.unix.nmon.cpu.cpu_all.Steal_PCT", value)\
    +| stats values(Sys_percent) as Sys_percent, values(User_percent) as User_percent, values(Wait_percent) as Wait_percent, values(Steal_percent) as Steal_percent by _time, host\
    +| fillnull value=0 Sys_percent,User_percent,Wait_percent,Steal_percent\
    +| eval cpu_load_percent=(Sys_percent+User_percent+Wait_percent+Steal_percent)\
    +| fields _time, host, cpu_load_percent
    +iseval = 0
    +
    +# define the lpar (AIX or Linux) VP load in percent
    +[def_lpar_load_percent]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(VP_User_PCT) as VP_User_PCT, values(VP_Sys_PCT) as VP_Sys_PCT, values(VP_Wait_PCT) as VP_Wait_PCT, values(VP_Idle_PCT) as VP_Idle_PCT, values(PhysicalCPU) as PhysicalCPU, values(virtualCPUs) as virtualCPUs values(partition_active_processors) as partition_active_processors by _time, OStype, host\
    +| fillnull value=0 VP_User_PCT,VP_Sys_PCT,VP_Wait_PCT,VP_Idle_PCT,PhysicalCPU,partition_active_processors\
    +| eval lpar_load_percent = case(OStype=="AIX", round((VP_User_PCT+VP_Sys_PCT+VP_Wait_PCT+VP_Idle_PCT),2), OStype=="Linux", round((PhysicalCPU/partition_active_processors*100),2))\
    +| fields _time, host, lpar_load_percent
    +iseval = 0
    +
    +# define the merged cpu_all / lpar load in percent
    +[def_all_os_cpu_load_percent]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT, values(Steal_PCT) as Steal_PCT, values(VP_User_PCT) as VP_User_PCT, values(VP_Sys_PCT) as VP_Sys_PCT, values(VP_Wait_PCT) as VP_Wait_PCT, values(VP_Idle_PCT) as VP_Idle_PCT, values(PhysicalCPU) as PhysicalCPU, values(virtualCPUs) as virtualCPUs values(partition_active_processors) as partition_active_processors by _time, OStype, host\
    +| fillnull value=0 Sys_PCT,User_PCT,Wait_PCT,Steal_PCT,VP_User_PCT,VP_Sys_PCT,VP_Wait_PCT,VP_Idle_PCT,PhysicalCPU,partition_active_processors\
    +| eval cpu_all_load_percent=(Sys_PCT+User_PCT+Wait_PCT+Steal_PCT), lpar_load_percent = case(OStype=="AIX", round((VP_User_PCT+VP_Sys_PCT+VP_Wait_PCT+VP_Idle_PCT),2), OStype=="Linux", round((PhysicalCPU/partition_active_processors*100),2))\
    +| eventstats count(eval(lpar_load_percent>0)) as count_lpar by host\
    +| eval cpu_load_percent=if(count_lpar>0, lpar_load_percent, cpu_all_load_percent)\
    +| fields _time, host, cpu_load_percent
    +iseval = 0
    +
    +# define the merged cpu_all / lpar load in percent by category
    +[def_all_os_cpu_load_percent_by_category]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT, values(Idle_PCT) as Idle_PCT, values(Steal_PCT) as Steal_PCT, values(VP_User_PCT) as VP_User_PCT, values(VP_Sys_PCT) as VP_Sys_PCT, values(VP_Wait_PCT) as VP_Wait_PCT, values(VP_Idle_PCT) as VP_Idle_PCT by _time, host\
    +| eventstats count(eval(VP_Sys_PCT>0)) as count_lpar by host\
    +| fillnull value=0 Sys_PCT User_PCT Wait_PCT Steal_PCT VP_User_PCT VP_Sys_PCT VP_Wait_PCT VP_Idle_PCT\
    +| eval Sys_PCT=if(OStype=="AIX" AND count_lpar>0, VP_Sys_PCT, Sys_PCT),\
    +User_PCT=if(OStype=="AIX" AND count_lpar>0, VP_Sys_PCT, Sys_PCT),\
    +Wair_PCT=if(OStype=="AIX" AND count_lpar>0, VP_Wait_PCT, Wait_PCT),\
    +Idle_PCT=if(OStype=="AIX" AND count_lpar>0, VP_Idle_PCT, Idle_PCT)
    +iseval = 0
    +
    +# define the cpu_all load in percent by category
    +[def_cpu_all_cpu_load_percent_by_category]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(Sys_PCT) as Sys_PCT, values(User_PCT) as User_PCT, values(Wait_PCT) as Wait_PCT, values(Idle_PCT) as Idle_PCT by _time, host
    +iseval = 0
    +
    +# define the lpar (AIX or Linux) VP load in cores
    +[def_lpar_load_cores]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(VP_User_PCT) as VP_User_PCT, values(VP_Sys_PCT) as VP_Sys_PCT, values(VP_Wait_PCT) as VP_Wait_PCT, values(VP_Idle_PCT) as VP_Idle_PCT, values(PhysicalCPU) as PhysicalCPU, values(entitled) as entitled, values(virtualCPUs) as virtualCPUs by _time, OStype, host\
    +| fillnull value=0 VP_User_PCT VP_Sys_PCT VP_Wait_PCT VP_Idle_PCT PhysicalCPU entitled virtualCPUs\
    +| eval lpar_load_cores=case(OStype=="AIX", round(((VP_User_PCT+VP_Sys_PCT+VP_Wait_PCT+VP_Idle_PCT)*virtualCPUs/100),3), OStype=="Linux", round(PhysicalCPU,3))
    +iseval = 0
    +
    +# define the lpar (Linux) VP load in cores
    +[def_lpar_load_linux_cores]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(PhysicalCPU) as lpar_load_cores, values(partition_active_processors) as partition_active_processors, values(partition_entitled_capacity) as partition_entitled_capacity by _time, host
    +iseval = 0
    +
    +# define the lpar (Linux) VP load in percent
    +[def_lpar_load_linux_percent]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(PhysicalCPU) as PhysicalCPU, values(partition_active_processors) as partition_active_processors, values(partition_entitled_capacity) as partition_entitled_capacity by _time, host\
    +| fillnull value=0 PhysicalCPU partition_active_processors\
    +| eval lpar_load_percent = round((PhysicalCPU/partition_active_processors*100),2)
    +iseval = 0
    +
    +############
    +# AIX only #
    +############
    +
    +# define the lpar (AIX) VP load in cores
    +[def_lpar_load_vp_aix_cores]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(VP_User_PCT) as VP_User_PCT, values(VP_Sys_PCT) as VP_Sys_PCT, values(VP_Wait_PCT) as VP_Wait_PCT, values(VP_Idle_PCT) as VP_Idle_PCT, values(entitled) as entitled, values(virtualCPUs) as virtualCPUs by _time, host\
    +| fillnull value=0 VP_User_PCT VP_Sys_PCT VP_Wait_PCT VP_Idle_PCT entitled virtualCPUs\
    +| eval lpar_load_cores=round(((VP_User_PCT+VP_Sys_PCT+VP_Wait_PCT+VP_Idle_PCT)*virtualCPUs/100),3)
    +iseval = 0
    +
    +# define the lpar (AIX) VP load in percent
    +[def_lpar_load_vp_aix_percent]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(VP_User_PCT) as VP_User_PCT, values(VP_Sys_PCT) as VP_Sys_PCT, values(VP_Wait_PCT) as VP_Wait_PCT, values(VP_Idle_PCT) as VP_Idle_PCT by _time, host\
    +| fillnull value=0 VP_User_PCT VP_Sys_PCT VP_Wait_PCT VP_Idle_PCT\
    +| eval lpar_load_percent = round((VP_User_PCT+VP_Sys_PCT+VP_Wait_PCT+VP_Idle_PCT),2)\
    +| fields _time, host, lpar_load_percent
    +iseval = 0
    +
    +# define the lpar (AIX) EC load in cores
    +[def_lpar_load_ec_aix_cores]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(EC_User_PCT) as EC_User_PCT, values(EC_Sys_PCT) as EC_Sys_PCT, values(EC_Wait_PCT) as EC_Wait_PCT, values(EC_Idle_PCT) as EC_Idle_PCT, values(entitled) as entitled, values(virtualCPUs) as virtualCPUs by _time, host\
    +| fillnull value=0 EC_User_PCT EC_Sys_PCT EC_Wait_PCT EC_Idle_PCT virtualCPUs entitled\
    +| eval lpar_load_cores=round(((EC_User_PCT+EC_Sys_PCT+EC_Wait_PCT+EC_Idle_PCT)*virtualCPUs/100),3)
    +iseval = 0
    +
    +# define the lpar (AIX) EC load in percent
    +[def_lpar_load_ec_aix_percent]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(EC_User_PCT) as EC_User_PCT, values(EC_Sys_PCT) as EC_Sys_PCT, values(EC_Wait_PCT) as EC_Wait_PCT, values(EC_Idle_PCT) as EC_Idle_PCT by _time, host\
    +| fillnull value=0 EC_User_PCT EC_Sys_PCT EC_Wait_PCT EC_Idle_PCT virtualCPUs entitled\
    +| eval lpar_load_percent = round((EC_User_PCT+EC_Sys_PCT+EC_Wait_PCT+EC_Idle_PCT),2)\
    +| fields _time, host, lpar_load_percent
    +iseval = 0
    +
    +# define the lpar (AIX) VP load in cores with entitlement and VirtualCPUs
    +[def_lpar_load_aix_cores_by_cat]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(VP_User_PCT) as VP_User_PCT, values(VP_Sys_PCT) as VP_Sys_PCT, values(VP_Wait_PCT) as VP_Wait_PCT, values(VP_Idle_PCT) as VP_Idle_PCT, values(entitled) as entitled, values(virtualCPUs) as virtualCPUs by _time, OStype, host
    +iseval = 0
    +
    +# define the lpar (AIX) Pool VP load in cores
    +[def_lpar_pool_load_aix_cores]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(poolCPUs) as poolCPUs, values(Pool_id) as Pool_id, values(PoolIdle) as PoolIdle by _time, host\
    +| fillnull value=0 poolCPUs PoolIdle\
    +| eval lpar_pool_usage = round((poolCPUs-PoolIdle),3)
    +iseval = 0
    +
    +# define the lpar (AIX) Pool VP load in percentage of capacity
    +[def_lpar_pool_load_aix_percent]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(poolCPUs) as poolCPUs, values(Pool_id) as Pool_id, values(PoolIdle) as PoolIdle by _time, host\
    +| fillnull value=0 poolCPUs PoolIdle\
    +| eval lpar_pool_usage_percent = round(((poolCPUs-PoolIdle)*100/poolCPUs),2)
    +iseval = 0
    +
    +# define the WLM (AIX) statistics
    +[def_wlm_aix_percent]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(wlmcpu) as wlmcpu, values(wlmmem) as wlmmem, values(wlmbio) as wlmbio by _time, host, dimension_device
    +iseval = 0
    +
    +############
    +# Linux only
    +############
    +
    +# define the lpar (Linux) Pool VP load in cores
    +[def_lpar_pool_load_linux_cores]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(smt_mode) as smt_mode, values(pool_idle_time) as pool_idle_time, values(pool_capacity) as pool_capacity by _time, host\
    +| eval lpar_pool_vp_usage = case(pool_idle_time>"0.1" AND pool_idle_time<(pool_capacity/100), round((((pool_capacity/100)-pool_idle_time)/smt_mode),3))
    +iseval = 0
    +
    +# table stats report of percentage memory
    +[def_memory_percentage_linux_report]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(memtotal) as memtotal, values(buffers) as buffers, values(active) as active, values(inactive) as inactive, values(cached) as cached, values(memfree) as memfree,\
    +values(swapcached) as swapcached, values(swaptotal) as swaptotal, values(swapfree) as swapfree by _time, host\
    +| fillnull value=0 memtotal buffers active inactive cached memfree swapcached swaptotal swapfree\
    +| eval mem_used_effective=case(isnotnull(cached), round((((((memtotal-(buffers+cached))-memfree))/memtotal)*100),2), isnotnull(memtotal), round((((memtotal-memfree)/memtotal)*100),2))\
    +| eval mem_free_effective = case(isnotnull(cached), round((((memfree+(buffers+cached))/memtotal)*100),2), isnotnull(memtotal), round(((memfree/memtotal)*100),2))\
    +| eval swap_used_effective=case(isnotnull(swapcached), round((((((swaptotal-swapfree)-swapcached))/swaptotal)*100),2), isnotnull(swaptotal), round((((swaptotal-swapfree)/swaptotal)*100),2))\
    +| eval swap_free_effective=case(isnotnull(swapcached), round((((swapfree+swapcached)/swaptotal)*100),2), isnotnull(swapfree), round(((swapfree/swaptotal)*100),2))\
    +| eval swapcached = case(isnotnull(swapcached), round(((swapcached/swaptotal)*100),2))\
    +| eval cached = case(isnotnull(cached), round(((cached/memtotal)*100),2)), buffers = case(isnotnull(buffers), round(((buffers/memtotal)*100),2)),\
    +active = case(isnotnull(active), round(((active/memtotal)*100),2)), inactive = case(isnotnull(inactive), round(((inactive/memtotal)*100),2))\
    +| fields - memtotal, memfree, memtotal, swaptotal, swapfree\
    +| stats avg(*) as "*" by host\
    +| rename "*_PCT" as "*"\
    +| fields host, "mem*total*", "mem*used*", "mem*free*", active, inactive, buffers, cached, "swap*total*", "swap*used*", "swap*free*", *\
    +| rename "mem*" AS "mem* (%)", "swap*" AS "swap* (%)", active as "active (%)", inactive as "inactive (%)", buffers as "buffers (%)", cached as "cached (%)"\
    +| foreach "*%*" [ eval "<<FIELD>>"=round('<<FIELD>>', 2) ]
    +iseval = 0
    +
    +# table stats report of volume memory
    +[def_memory_volume_linux_report]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(memtotal) as memtotal, values(buffers) as buffers, values(active) as active, values(inactive) as inactive, values(cached) as cached, values(memfree) as memfree,\
    +values(swapcached) as swapcached, values(swaptotal) as swaptotal, values(swapfree) as swapfree by _time, host\
    +| fillnull value=0 memtotal buffers active inactive cached memfree swapcached swaptotal swapfree\
    +| eval mem_used_effective = case(isnotnull(cached), ((memtotal-(buffers+cached))-memfree), isnotnull(memtotal), memtotal-memfree)\
    +| eval swap_used_effective = case(isnotnull(swapcached), ((swaptotal-swapfree)-swapcached), isnotnull(swaptotal), (swaptotal-swapfree))\
    +| stats avg(*) as "*" by host\
    +| fields host, "mem*total*", "mem*used*", "mem*free*", active, inactive, buffers, cached, "swap*total*", "swap*used*", "swap*free*", *\
    +| rename "mem*" AS "mem* (MB)", "swap*" AS "swap* (MB)", active as "active (MB)", inactive as "inactive (MB)", buffers as "buffers (MB)", cached as "cached (MB)"\
    +| foreach "*MB*" [ eval "<<FIELD>>"=round('<<FIELD>>', 0) ]
    +iseval = 0
    +
    +########
    +# Others
    +########
    +
    +# define the lpar (All OS) Pool VP load in cores
    +[def_all_os_lpar_pool_load_cores]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(poolCPUs) as poolCPUs, values(PoolIdle) as PoolIdle, values(pool_idle_time) as pool_idle_time, values(pool_capacity) as pool_capacity, values(smt_mode) as smt_mode, values(Pool_id) as Pool_id by _time, OStype, host\
    +| fillnull value=0 poolCPUs PoolIdle pool_idle_time pool_capacity smt_mode Pool_id\
    +| eval lpar_pool_vp_usage = case(OStype=="AIX", round((poolCPUs-PoolIdle),3), OStype="Linux", case(pool_idle_time>"0.1" AND pool_idle_time<(pool_capacity/100), round((((pool_capacity/100)-pool_idle_time)/smt_mode),3)) )
    +iseval = 0
    +
    +# define the lpar (All OS) Pool VP load in percentage of capacity
    +[def_all_os_lpar_pool_load_percent]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(poolCPUs) as poolCPUs, values(PoolIdle) as PoolIdle, values(pool_idle_time) as pool_idle_time, values(pool_capacity) as pool_capacity, values(smt_mode) as smt_mode, values(Pool_id) as Pool_id by _time, OStype, host\
    +| fillnull value=0 poolCPUs PoolIdle pool_idle_time pool_capacity smt_mode Pool_id\
    +| eval lpar_pool_vp_usage_PCT = case(OStype=="AIX", round(((poolCPUs-PoolIdle)*100/poolCPUs),2), OStype="Linux", case(pool_idle_time>"0.1" AND pool_idle_time<(pool_capacity/100), round((((pool_capacity/100)-pool_idle_time)/smt_mode)/(pool_capacity/100)*100,2)) )
    +iseval = 0
    +
    +# define the lpar load and pool load (All OS) in VP
    +[def_all_os_lpar_load_and_pool_load_cores]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(VP_User_PCT) as VP_User_PCT, values(VP_Sys_PCT) as VP_Sys_PCT, values(VP_Wait_PCT) as VP_Wait_PCT, values(VP_Idle_PCT) as VP_Idle_PCT, values(PhysicalCPU) as PhysicalCPU, values(entitled) as entitled, values(virtualCPUs) as virtualCPUs, values(poolCPUs) as poolCPUs, values(PoolIdle) as PoolIdle, values(pool_idle_time) as pool_idle_time, values(pool_capacity) as pool_capacity, values(smt_mode) as smt_mode, values(Pool_id) as Pool_id by _time, OStype, host\
    +| fillnull value=0 VP_User_PCT VP_Sys_PCT VP_Wait_PCT VP_Idle_PCT PhysicalCPU entitled virtualCPUs poolCPUs PoolIdle pool_idle_time pool_capacity smt_mode Pool_id\
    +| eval lpar_load_cores=case(OStype=="AIX", round(((VP_User_PCT+VP_Sys_PCT+VP_Wait_PCT+VP_Idle_PCT)*virtualCPUs/100),3), OStype=="Linux", round(PhysicalCPU,3))\
    +| eval lpar_pool_vp_usage = case(OStype=="AIX", round((poolCPUs-PoolIdle),3), OStype="Linux", case(pool_idle_time>"0.1" AND pool_idle_time<(pool_capacity/100), round((((pool_capacity/100)-pool_idle_time)/smt_mode),3)) )\
    +| fields _time, host, lpar_load_cores, lpar_pool_vp_usage
    +iseval = 0
    +
    +# define for all OS memory and swap usage in percent
    +[def_memory_load_percent]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(System_PCT) as System_PCT, values(Process_PCT) as Process_PCT, values(memtotal) as memtotal, values(buffers) as buffers, values(cached) as cached, values(memfree) as memfree,\
    +values(Virtual_total_MB) as Virtual_total_MB, values(Virtual_free_MB) as Virtual_free_MB, values(swapcached) as swapcached, values(swaptotal) as swaptotal, values(swapfree) as swapfree by _time, OStype, host\
    +| fillnull value=0 System_PCT Process_PCT memtotal buffers cached memfree Virtual_total_MB Virtual_free_MB swapcached swaptotal swapfree\
    +| eval mem_used_effective_PCT=case(OStype == "AIX",round((System_PCT+Process_PCT),2), OStype=="Linux", round((((((memtotal-(buffers+cached))-memfree))/memtotal)*100),2), OStype=="Solaris", round((((memtotal-memfree)/memtotal)*100),2))\
    +| eval swap_used_effective_PCT=case(OStype=="AIX", round((((Virtual_total_MB-Virtual_free_MB)/Virtual_total_MB)*100),2), OStype=="Linux", round((((((swaptotal-swapfree)-swapcached))/swaptotal)*100),2), OStype=="Solaris", round((((swaptotal-swapfree)/swaptotal)*100),2))\
    +| fields _time, host, mem_used_effective_PCT, swap_used_effective_PCT
    +iseval = 0
    +
    +# define for Linux OS memory and swap usage in percent
    +[def_memory_load_percent_linux]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(memtotal) as memtotal, values(buffers) as buffers, values(cached) as cached, values(memfree) as memfree,\
    +values(swapcached) as swapcached, values(swaptotal) as swaptotal, values(swapfree) as swapfree by _time, host\
    +| fillnull value=0 memtotal buffers cached memfree swapcached swaptotal swapfree\
    +| eval mem_used_effective_PCT=round((((((memtotal-(buffers+cached))-memfree))/memtotal)*100),2)\
    +| eval swap_used_effective_PCT=round((((((swaptotal-swapfree)-swapcached))/swaptotal)*100),2)\
    +| fields _time, host, mem_used_effective_PCT, swap_used_effective_PCT
    +iseval = 0
    +
    +# define for all OS memory and swap usage in percent
    +[def_memory_load_percent_all_metrics]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(System_PCT) as System_PCT, values(Process_PCT) as Process_PCT, values(memtotal) as memtotal, values(buffers) as buffers, values(active) as active, values(inactive) as inactive, values(cached) as cached, values(memfree) as memfree,\
    +values(Virtual_total_MB) as Virtual_total_MB, values(Virtual_free_MB) as Virtual_free_MB, values(swapcached) as swapcached, values(swaptotal) as swaptotal, values(swapfree) as swapfree by _time, OStype, host\
    +| fillnull value=0 System_PCT Process_PCT memtotal buffers active inactive cached memfree Virtual_total_MB Virtual_free_MB swapcached swaptotal swapfree\
    +| eval mem_used_effective=case(OStype == "AIX",round((System_PCT+Process_PCT),2), OStype=="Linux", round((((((memtotal-(buffers+cached))-memfree))/memtotal)*100),2), OStype=="Solaris", round((((memtotal-memfree)/memtotal)*100),2))\
    +| eval mem_free_effective = case((OStype == "AIX"),round((100-(System_PCT+Process_PCT)),2), OStype=="Linux", round((((memfree+(buffers+cached))/memtotal)*100),2), OStype=="Solaris", round(((memfree/memtotal)*100),2))\
    +| eval swap_used_effective=case(OStype=="AIX", round((((Virtual_total_MB-Virtual_free_MB)/Virtual_total_MB)*100),2), OStype=="Linux", round((((((swaptotal-swapfree)-swapcached))/swaptotal)*100),2), OStype=="Solaris", round((((swaptotal-swapfree)/swaptotal)*100),2))\
    +| eval swap_free_effective=case(OStype=="AIX", Virtual_free_PCT, OStype=="Linux", round((((swapfree+swapcached)/swaptotal)*100),2), OStype=="Solaris", round(((swapfree/swaptotal)*100),2))\
    +| eval swapcached = case(OStype=="Linux", round(((swapcached/swaptotal)*100),2))\
    +| eval cached = case(OStype=="Linux", round(((cached/memtotal)*100),2)), buffers = case(OStype=="Linux", round(((buffers/memtotal)*100),2)),\
    +active = case(OStype=="Linux", round(((active/memtotal)*100),2)), inactive = case(OStype=="Linux", round(((inactive/memtotal)*100),2))\
    +| fields - memtotal, memfree, memtotal, swaptotal, swapfree
    +iseval = 0
    +
    +# define for all OS memory and swap usage in volume (MB)
    +[def_memory_volume_MB]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(Real_total_MB) as Real_total_MB, values(System_PCT) as System_PCT, values(Process_PCT) as Process_PCT, values(memtotal) as memtotal, values(buffers) as buffers, values(active) as active, values(inactive) as inactive, values(cached) as cached, values(memfree) as memfree,\
    +values(Virtual_total_MB) as Virtual_total_MB, values(Virtual_free_MB) as Virtual_free_MB, values(swapcached) as swapcached, values(swaptotal) as swaptotal, values(swapfree) as swapfree by _time, OStype, host\
    +| fillnull value=0 Real_total_MB System_PCT Process_PCT memtotal buffers active inactive cached memfree Virtual_total_MB Virtual_free_MB swapcached swaptotal swapfree\
    +| eval mem_used_effective = case(OStype=="AIX", (Real_total_MB/100)*(System_PCT+Process_PCT), OStype=="Linux", ((memtotal-(buffers+cached))-memfree), OStype=="Solaris", memtotal-memfree)\
    +| eval swap_used_effective = case(OStype=="AIX", (Virtual_total_MB-Virtual_free_MB), OStype=="Linux", ((swaptotal-swapfree)-swapcached), OStype=="Solaris", (swaptotal-swapfree))
    +iseval = 0
    +
    +# define for all OS memory by category in volume (MB)
    +[def_memory_volume_MB_by_category]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(Real_total_MB) as Real_total_MB, values(System_PCT) as System_PCT, values(Process_PCT) as Process_PCT, values(FScache_PCT) as FScache_PCT, values(memtotal) as memtotal, values(buffers) as buffers, values(cached) as cached, values(memfree) as memfree,\
    +values(Virtual_total_MB) as Virtual_total_MB, values(Virtual_free_MB) as Virtual_free_MB, values(swapcached) as swapcached, values(swaptotal) as swaptotal, values(swapfree) as swapfree by _time, OStype, host\
    +| fillnull value=0 Real_total_MB System_PCT Process_PCT memtotal buffers cached memfree Virtual_total_MB Virtual_free_MB swapcached swaptotal swapfree\
    +| eval mem_used_effective = case(OStype=="AIX", (Real_total_MB/100)*(System_PCT+Process_PCT), OStype=="Linux", ((memtotal-(buffers+cached))-memfree), OStype=="Solaris", memtotal-memfree)\
    +| eval swap_used_effective = case(OStype=="AIX", (Virtual_total_MB-Virtual_free_MB), OStype=="Linux", ((swaptotal-swapfree)-swapcached), OStype=="Solaris", (swaptotal-swapfree))\
    +| eval memtotal=if(OStype=="AIX", Real_total_MB, memtotal), cached=if(OStype=="AIX", (Real_total_MB/100)*FScache_PCT, cached), memfree=if(OStype=="AIX", memtotal-((Real_total_MB/100)*(System_PCT+Process_PCT+FScache_PCT)), memfree)
    +iseval = 0
    +
    +# define for all OS memory usage per process (TOP)
    +[def_all_os_top_memory]
    +definition = `extract_metrics`\
    +| eval {metric}=value\
    +| stats values(ResSet) as ResSet, values(ResText) as ResText, values(ResData) as ResData, values(ResSize) as ResSize by _time, OStype, host, dimension_Command\
    +| fillnull value=0 ResSet ResText ResData ResSize\
    +| eval mem_usage_mb=case(match(OStype, "Linux"), ((ResSet)/1024), match(OStype, "AIX"), ((ResData+ResText)/1024), match(OStype, "Solaris"), (ResSize/1024) )
    +iseval = 0
    +
    +# define for disk read xfer against diskbsize
    +[def_disk_read_xfer]
    +definition = `extract_metrics`\
    +| eval disk_read=case(match(metric_name, "diskread"), value), disk_size=case(match(metric_name, "diskbsize"), value)\
    +| stats values(disk_read) as disk_read values(disk_size) as disk_size by _time, dimension_device, host\
    +| eval disk_read_iops=(disk_read/disk_size)\
    +| stats sum(disk_read_iops) as disk_read_iops by _time, host
    +iseval = 0
    +
    +# define for disk read xfer against diskbsize by device
    +[def_disk_read_xfer_by_device]
    +definition = `extract_metrics`\
    +| eval disk_read=case(match(metric_name, "diskread"), value), disk_size=case(match(metric_name, "diskbsize"), value)\
    +| stats values(disk_read) as disk_read values(disk_size) as disk_size by _time, dimension_device, host\
    +| eval disk_read_iops=(disk_read/disk_size)\
    +| stats sum(disk_read_iops) as disk_read_iops by _time, host, dimension_device
    +iseval = 0
    +
    +# define for disk write xfer against diskbsize
    +[def_disk_write_xfer]
    +definition = `extract_metrics`\
    +| eval disk_write=case(match(metric_name, "diskwrite"), value), disk_size=case(match(metric_name, "diskbsize"), value)\
    +| stats values(disk_write) as disk_write values(disk_size) as disk_size by _time, dimension_device, host\
    +| eval disk_write_iops=(disk_write/disk_size)\
    +| stats sum(disk_write_iops) as disk_write_iops by _time, host
    +iseval = 0
    +
    +# define for disk write xfer against diskbsize by device
    +[def_disk_write_xfer_by_device]
    +definition = `extract_metrics`\
    +| eval disk_write=case(match(metric_name, "diskwrite"), value), disk_size=case(match(metric_name, "diskbsize"), value)\
    +| stats values(disk_write) as disk_write values(disk_size) as disk_size by _time, dimension_device, host\
    +| eval disk_write_iops=(disk_write/disk_size)\
    +| stats sum(disk_write_iops) as disk_write_iops by _time, host, dimension_device
    +iseval = 0
    +
    +# define for dg read xfer against dgsize
    +[def_dg_read_xfer]
    +definition = `extract_metrics("dgread dgsize")`\
    +| stats max(dgread) as disk_read_KB_per_sec max(dgsize) as disk_block_size_KB by _time, dimension_device, host\
    +| eval disk_read_iops=(disk_read_KB_per_sec/disk_block_size_KB)\
    +| stats sum(disk_read_iops) as disk_read_iops by _time, host
    +iseval = 0
    +
    +# define for dg read xfer against dgsize by device
    +[def_dg_read_xfer_by_device]
    +definition = `extract_metrics("dgread dgsize")`\
    +| stats max(dgread) as disk_read_KB_per_sec max(dgsize) as disk_block_size_KB by _time, dimension_device, host\
    +| eval disk_read_iops=(disk_read_KB_per_sec/disk_block_size_KB)\
    +| stats sum(disk_read_iops) as disk_read_iops by _time, host, dimension_device
    +iseval = 0
    +
    +# define for dg write xfer against dgsize
    +[def_dg_write_xfer]
    +definition = `extract_metrics("dgwrite dgsize")`\
    +| stats max(dgwrite) as disk_write_KB_per_sec max(dgsize) as disk_block_size_KB by _time, dimension_device, host\
    +| eval disk_write_iops=(disk_write_KB_per_sec/disk_block_size_KB)\
    +| stats sum(disk_write_iops) as disk_write_iops by _time, host
    +iseval = 0
    +
    +# define for dg write xfer against dgsize by device
    +[def_dg_write_xfer_by_device]
    +definition = `extract_metrics("dgwrite dgsize")`\
    +| stats max(dgwrite) as disk_write_KB_per_sec max(dgsize) as disk_block_size_KB by _time, dimension_device, host\
    +| eval disk_write_iops=(disk_write_KB_per_sec/disk_block_size_KB)\
    +| stats sum(disk_write_iops) as disk_write_iops by _time, host, dimension_device
    +iseval = 0
    +
    +#########################################
    +# frameID mapping
    +#########################################
    +
    +[mapping_frameID]
    +definition = lookup nmon_frameID_mapping host as host OUTPUT frameID\
    +| eval frameID=if(isnull(frameID), host, frameID)
    +iseval = 0
    +
    +#########################################
    +# mcatalog
    +#########################################
    +
    +# used by the data dictionary explorer UI
    +[def_mcatalog_full]
    +definition = mcatalog values(_dims) where `nmon_metrics_index` metric_name="os.unix.nmon.*" by metric_name\
    +| fields metric_name | sort 0 metric_name\
    +| append [ | inputlookup nmon_metric_catalog | fields metric_name ]\
    +| rex field="metric_name" "os\.unix\.nmon\.(?<metric_category>\w*)\.(?<nmon_section>\w*)"\
    +| sort 0 metric_name\
    +| rex field="metric_name" "\.(?<metric>\w*)$"\
    +| fields metric_category,nmon_section,metric\
    +| search [ | mcatalog values(_dims) where `nmon_metrics_index` metric_name="os.unix.nmon.*" by metric_name\
    +| fields metric_name | sort 0 metric_name\
    +| rex field="metric_name" "os\.unix\.nmon\.(?<metric_category>\w*)\.(?<nmon_section>\w*)"\
    +| stats count by nmon_section | fields - count | fields nmon_section ]
    +iseval = 0
    +
    +# mcatalog dictionary without dimensions
    +[def_mcatalog_dictionary(1)]
    +args = osfilter
    +definition = mcatalog values(sourcetype) as sourcetype_values where `nmon_metrics_index` metric_name=os.unix.nmon.* host=* OStype=$osfilter$ by OStype, metric_name\
    +| rename sourcetype_values as sourcetype\
    +| `extract_metrics`\
    +| rex field=metric_name "os\.unix\.nmon\.(?<metric_category>[^\.]*)\.(?<nmon_section>[^\.]*)"\
    +| stats count by metric_category, nmon_section, metric
    +iseval = 0
    +
    +# mcatalog dictionary with dimensions
    +[def_mcatalog_dictionary_with_dimensions(1)]
    +args = osfilter
    +definition = mcatalog values(sourcetype) as sourcetype_values values(_dims) as dimensions where `nmon_metrics_index` metric_name=os.unix.nmon.* host=* OStype=$osfilter$ by OStype, metric_name\
    +| rename sourcetype_values as sourcetype\
    +| rex field="metric_name" ".(?<metric>[\w|\-|\_]*)$"\
    +| rex field=metric_name "os\.unix\.nmon\.(?<metric_category>[^\.]*)\.(?<nmon_section>[^\.]*)"\
    +| mvexpand dimensions\
    +| where (((dimensions == "OStype") OR (dimensions == "serialnum")) OR like(dimensions,"dimension_%"))\
    +| stats count by metric_category, nmon_section, metric, dimensions\
    +| eval dimensions=if(match(dimensions, "dimension_.*"), dimensions, "none")\
    +| dedup metric_category, nmon_section, metric, dimensions\
    +| eval dimensions=if(match(dimensions, "dimension_.*"), dimensions, ""), count=if(match(dimensions, "dimension_.*"), count,1)
    +iseval = 0
    +
    +# mcatalog inventory output enriched with nmon inventory data
    +[def_mcatalog_mapped_nmon_inventory]
    +definition = mcatalog values(serialnum) as serials values(OStype) as OStype_values where `nmon_metrics_index` metric_name="os.unix.nmon.*" by host\
    +| rename serials as serialnum, OStype_values as OStype\
    +| `mapping_frameID`\
    +| lookup nmon_inventory hostname as host OUTPUT OSversion, cpu_cores, Physical_mem_MB, Virtual_mem_MB, uptime_duration, system_startup_date, reporting_date\
    +| eval OS_summary=upper(OStype)+" / "+OSversion\
    +| fields frameID, serialnum, host, OS_summary, cpu_cores, Physical_mem_MB, Virtual_mem_MB, uptime_duration, system_startup_date, reporting_date
    +iseval = 0
    +
    +# mcatalog inventory mapped with main KPIs
    +[def_mcatalog_mapped_nmon_inventory_with_main_kpis]
    +definition = `def_mcatalog_mapped_nmon_inventory`\
    +| fields frameID,serialnum,host,OS_summary,cpu_cores,Physical_mem_MB,Virtual_mem_MB\
    +| rename Physical_mem_MB as "physical mem (MB)", Virtual_mem_MB as "virtual mem (MB)"\
    +| sort 0 host\
    +| appendcols\
    +[ | mstats avg(_value) as value where `nmon_metrics_index` `def_cpu_all_os_metric_filters` by metric_name, OStype, host span=1m\
    +| `def_all_os_cpu_load_percent`\
    +| stats avg(cpu_load_percent) AS avg_cpu_usage, sparkline(avg(cpu_load_percent),5m) As cpu_sparkline by host\
    +| sort 0 host ]\
    +| appendcols\
    +[ | mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.mem.Real_total_MB\
    +OR metric_name=os.unix.nmon.memory.mem.Real_free_MB\
    +OR metric_name=os.unix.nmon.memory.mem.memtotal\
    +OR metric_name=os.unix.nmon.memory.mem.buffers\
    +OR metric_name=os.unix.nmon.memory.mem.cached\
    +OR metric_name=os.unix.nmon.memory.mem.memfree\
    +OR metric_name=os.unix.nmon.memory.mem.Virtual_total_MB\
    +OR metric_name=os.unix.nmon.memory.mem.Virtual_free_MB\
    +OR metric_name=os.unix.nmon.memory.mem.swapcached\
    +OR metric_name=os.unix.nmon.memory.mem.swaptotal\
    +OR metric_name=os.unix.nmon.memory.mem.swapfree by host, metric_name span=1m\
    +| `def_memory_load_percent`\
    +| stats avg(mem_used_effective_PCT) AS avg_physical_mem_usage, sparkline(avg(mem_used_effective_PCT),5m) As sparkline_physical_mem,\
    +avg(swap_used_effective_PCT) AS avg_virtual_mem_usage, sparkline(avg(swap_used_effective_PCT),5m) As sparkline_virtual_mem by host\
    +| sort 0 host ]\
    +| eval avg_cpu_usage=case(isnum(avg_cpu_usage), round(avg_cpu_usage, 2) . " %"),\
    +avg_physical_mem_usage=case(isnum(avg_physical_mem_usage), round(avg_physical_mem_usage, 2) . " %"),\
    +avg_virtual_mem_usage=if(isnum(avg_virtual_mem_usage), round(avg_virtual_mem_usage, 2) . " %", "no virtual memory")\
    +| `mapping_frameID`
    +iseval =0
    +
    +#########################################
    +# df_storage specific
    +#########################################
    +
    +# used by the configuration interface to provide server inventory
    +[def_filesystem_inventory]
    +definition = mstats latest(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.storage.df_storage.Available OR metric_name=os.unix.nmon.storage.df_storage.Use_pct OR metric_name=os.unix.nmon.storage.df_storage.Used OR metric_name=os.unix.nmon.storage.df_storage.blocks by serialnum, host, metric_name, dimension_mount, dimension_filesystem\
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)\
    +| stats last(Available) as Available, last(Use_pct) as Use_pct, last(Used) as Used, last(blocks) as blocks by serialnum, host, dimension_mount, dimension_filesystem\
    +| rename dimension_mount as mount, dimension_filesystem as filesystem\
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)\
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free\
    +| foreach storage, storage_free, storage_used [ eval <<FIELD>> = round('<<FIELD>>'/1024/1024, 2) ]\
    +| foreach storage*percent [ eval <<FIELD>> = round('<<FIELD>>', 2) ]\
    +| rename storage as "storage (GB)", storage_free as "storage free (GB)", storage_used as "storage used (GB)", storage_free_percent as "storage free (%)", storage_used_percent as "storage used (%)"\
    +| eval UsedPct=if(isnum('storage used (%)'), 'storage used (%)', 0 )\
    +| `mapping_frameID`\
    +| fields frameID, serialnum, host, mount, filesystem, "storage (GB)", "storage free (GB)", "storage used (GB)", "storage free (%)", "storage used (%)", UsedPct | rename UsedPct as current_used_percent\
    +| foreach storage*%* current_used_percent [ eval <<FIELD>> = round('<<FIELD>>', 2) ] | where like(mount, "%")
    +iseval = 0
    +
    +#########################################
    +#	LPAR Specific definitions
    +#########################################
    +
    +[lpar_define_conso]
    +definition = eval lpar_ecconso=round(((EC_User_PCT+EC_Sys_PCT+EC_Wait_PCT+EC_Idle_PCT)*entitled/100),2)\
    +| eval lpar_ec_pct_conso=round((((EC_User_PCT+EC_Sys_PCT+EC_Wait_PCT+EC_Idle_PCT)*entitled)/virtualCPUs),2)\
    +| eval lpar_vpconso=round(((VP_User_PCT+VP_Sys_PCT+VP_Wait_PCT+VP_Idle_PCT)*virtualCPUs/100),2)\
    +| eval lpar_vp_pct_conso=round((VP_User_PCT+VP_Sys_PCT+VP_Wait_PCT+VP_Idle_PCT),2)\
    +| eval pool_conso=round((poolCPUs-PoolIdle),2)\
    +| eval pool_pct_conso=round(((poolCPUs-PoolIdle)*poolCPUs/100),2)
    +iseval = 0
    +
    +#########################################
    +#	Custom Span Macro Definition
    +#########################################
    +
    +#################
    +# CUSTOMIZATION:
    +#################
    +
    +
    +# If you want to set a minimal span feature that better fits your data, such as 5mn between 2 measures for example, please:
    +# - Copy the 2 customspan macros to your local/macros.conf
    +# - Edit the line:
    +
    +#  | eval span=if(spanrestricted <= 20, "20s", span)\
    +
    +# And replace with: (example with 5 minutes span, time unit is in seconds)
    +
    +#  | eval span=if(spanrestricted <= (5*60), "5m", span)\
    +
    +[nmon_span]
    +definition = [ | stats count | addinfo\
    +| eval earliest=if(info_min_time == "0.000", info_search_time,info_min_time)\
    +| eval latest=if(info_max_time == "+Infinity", info_search_time,info_max_time)\
    +| eval searchStartTIme=strftime(earliest,"%a %d %B %Y %H:%M")\
    +| eval searchEndTime=strftime(latest,"%a %d %B %Y %H:%M")\
    +| eval Difference = (latest - earliest)\
    +| eval span=case(\
    +info_min_time == "0.000", "2m",\
    +Difference > (3000*24*60*60),"4d",\
    +Difference > (2000*24*60*60),"3d",\
    +Difference > (1000*24*60*60),"2d",\
    +Difference > (500*24*60*60),"1d",\
    +Difference > (333*24*60*60),"12h",\
    +Difference > (166*24*60*60),"8h",\
    +Difference > (83*24*60*60),"4h",\
    +Difference > (41*24*60*60),"2h",\
    +Difference > (916*60*60),"1h",\
    +Difference > (833*60*60),"55m",\
    +Difference > (750*60*60),"50m",\
    +Difference > (666*60*60),"45m",\
    +Difference > (583*60*60),"40m",\
    +Difference > (500*60*60),"35m",\
    +Difference > (416*60*60),"30m",\
    +Difference > (333*60*60),"25m",\
    +Difference > (250*60*60),"20m",\
    +Difference > (166*60*60),"15m",\
    +Difference > (83*60*60),"10m",\
    +Difference > (66*60*60),"5m",\
    +Difference > (50*60*60),"4m",\
    +Difference > (33*60*60),"3m",\
    +Difference > (16*60*60),"2m",\
    +Difference > (8*60*60),"1m",\
    +Difference <= (8*60*60),"1m"\
    +)\
    +| eval spanrestricted=case(\
    +info_min_time == "0.000", 2*60,\
    +Difference > (916*60*60),60*60,\
    +Difference > (833*60*60),55*60,\
    +Difference > (750*60*60),50*60,\
    +Difference > (666*60*60),45*60,\
    +Difference > (583*60*60),40*60,\
    +Difference > (500*60*60),35*60,\
    +Difference > (416*60*60),30*60,\
    +Difference > (333*60*60),25*60,\
    +Difference > (250*60*60),20*60,\
    +Difference > (166*60*60),15*60,\
    +Difference > (83*60*60),10*60,\
    +Difference > (66*60*60),5*60,\
    +Difference > (50*60*60),4*60,\
    +Difference > (33*60*60),180,\
    +Difference > (16*60*60),120,\
    +Difference > (8*60*60),60,\
    +Difference <= (8*60*60),60\
    +)\
    +| eval span=case(spanrestricted < interval, interval, spanrestricted >= interval, span, isnull(interval), span)\
    +| eval span=if(spanrestricted <= 60, "1m", span)\
    +| return span ]
    +iseval = 0
    +
    +# Baseline macro, uses a minimal span of 5m to match the Baseline span
    +
    +[baseline_span]
    +definition = [ | stats count | addinfo\
    +| eval earliest=if(info_min_time == "0.000", info_search_time,info_min_time)\
    +| eval latest=if(info_max_time == "+Infinity", info_search_time,info_max_time)\
    +| eval searchStartTIme=strftime(earliest,"%a %d %B %Y %H:%M")\
    +| eval searchEndTime=strftime(latest,"%a %d %B %Y %H:%M")\
    +| eval Difference = (latest - earliest)\
    +| eval span=case(\
    +info_min_time == "0.000", "2m",\
    +Difference > (3000*24*60*60),"4d",\
    +Difference > (2000*24*60*60),"3d",\
    +Difference > (1000*24*60*60),"2d",\
    +Difference > (500*24*60*60),"1d",\
    +Difference > (333*24*60*60),"12h",\
    +Difference > (166*24*60*60),"8h",\
    +Difference > (83*24*60*60),"4h",\
    +Difference > (41*24*60*60),"2h",\
    +Difference > (916*60*60),"1h",\
    +Difference > (833*60*60),"55m",\
    +Difference > (750*60*60),"50m",\
    +Difference > (666*60*60),"45m",\
    +Difference > (583*60*60),"40m",\
    +Difference > (500*60*60),"35m",\
    +Difference > (416*60*60),"30m",\
    +Difference > (333*60*60),"25m",\
    +Difference > (250*60*60),"20m",\
    +Difference > (166*60*60),"15m",\
    +Difference > (83*60*60),"10m",\
    +Difference > (8*60*60),"5m",\
    +Difference <= (8*60*60),"5m"\
    +)\
    +| eval spanrestricted=case(\
    +info_min_time == "0.000", 2*60,\
    +Difference > (916*60*60),60*60,\
    +Difference > (833*60*60),55*60,\
    +Difference > (750*60*60),50*60,\
    +Difference > (666*60*60),45*60,\
    +Difference > (583*60*60),40*60,\
    +Difference > (500*60*60),35*60,\
    +Difference > (416*60*60),30*60,\
    +Difference > (333*60*60),25*60,\
    +Difference > (250*60*60),20*60,\
    +Difference > (166*60*60),15*60,\
    +Difference > (83*60*60),10*60,\
    +Difference > (8*60*60),5*60,\
    +Difference <= (8*60*60),5*60\
    +)\
    +| eval span=case(spanrestricted < interval, interval, spanrestricted >= interval, span, isnull(interval), span)\
    +| eval span=if(spanrestricted <= 60, "5m", span)\
    +| return span ]
    +iseval = 0
    +
    +###############################################
    +#	Macro used in Compare interface
    +###############################################
    +
    +[eval_compare]
    +definition = eval Evolution_usage=((usage_period2-usage_period1)/usage_period1)*100 | eval Evolution_usage=round(Evolution_usage,3)\
    +| eval Delta_usage=round((usage_period2-usage_period1),3)\
    +| eval Evolution_pct_usage=case(isnotnull(pct_usage_period1), ((pct_usage_period2-pct_usage_period1)/pct_usage_period1)*100 ) | eval Evolution_pct_usage=round(Evolution_pct_usage,3)\
    +| eval Delta_pct_usage=round((pct_usage_period2-pct_usage_period1),3)\
    +| fields host,usage_period1,usage_period2,Delta_usage,Evolution_usage,*\
    +| rename Evolution_usage As "Evolution_usage (%)"\
    +| rename Evolution_pct_usage As "Evolution_pct_usage (%)"\
    +| eval range=case(\
    +usage_period1==usage_period2, 0, usage_period1<usage_period2, 2, usage_period1>usage_period2, 4,\
    +pct_usage_period1==pct_usage_period2, 0, pct_usage_period1<pct_usage_period2, 2, pct_usage_period1>pct_usage_period2, 4)\
    +| rangemap field=range equal=0-1 increase=2-3 decrease=4-5 default=no\
    +| eval usage_period1=round(usage_period1,3)\
    +| eval usage_period2=round(usage_period2,3)
    +iseval = 0
    +
    +###################################
    +# 	Index Statistics
    +###################################
    +
    +[indexes_datestats]
    +definition = rest /services/data/indexes\
    +| table currentDBSizeMB minTime maxTime totalEventCount splunk_server title\
    +| rename title as index | search `nmon_index`\
    +| eval firstTime=round(strptime('minTime', "%Y-%m-%dT%H:%M:%S%z"),0)\
    +| eval lastTime=round(strptime('maxTime', "%Y-%m-%dT%H:%M:%S%z"),0)\
    +| stats min(firstTime) as firstTime, max(lastTime) as lastTime\
    +| eval "First Event"=strftime(firstTime,"%d/%m/%y-%H:%M")\
    +| eval "Last Event"=strftime(lastTime,"%d/%m/%y-%H:%M")
    +iseval = 0
    +
    +#####################
    +# NMON CONFIG SECTION
    +#####################
    +
    +# Rex common to all OS
    +
    +[nmon_config_common_rex]
    +definition = rex "(?i),version,(?P<nmon_version>.+)"\
    +| rex "(?i),command,(?P<nmon_command>.+)"\
    +| rex "(?i),OS,(?P<OS>[^,]+)"\
    +| rex "AAA,cpus,(?P<cpu_cores_position1>\d+)"\
    +| rex "AAA,cpus,\d+,(?P<cpu_cores_position2>\d+)"
    +iseval = 0
    +
    +# AIX Specific
    +
    +[nmon_config_AIX_rex]
    +definition = rex "AAA,AIX,(?P<AIX_LEVEL>.+)"\
    +| rex "BBB.+,[0-9].+,lparstat.+,\"Online\sVirtual\sCPUs\s+\:\s(?P<AIX_virtualcpus>\d+)\""\
    +| rex "BBB.+,[0-9].+,online\sMemory,(?P<AIX_memory_MB>\d+)"\
    +| rex "BBB.+,[0-9].+,lsconf,\"\s+Total\sPaging\sSpace:\s(?P<AIX_pagingspace_MB>\d+)"\
    +| rex "BBB.+,[0-9].+,lsconf,\"Processor\sImplementation\sMode:\s(?P<AIX_processor_mode>.+\w)\""\
    +| rex "BBB.+,[0-9].+,lsconf,\"Processor\sClock\sSpeed:\s(?P<AIX_processor_clockspeed>.+\w)\""\
    +| rex "BBB.+,[0-9].+,lsconf,\"CPU\sType:\s(?P<AIX_cpu_type>.+\w)\""\
    +| rex "BBB.+,[0-9].+,lsconf,\"Kernel\sType:\s(?P<AIX_kernel_type>.+\w)\""\
    +| rex "BBB.+,[0-9].+,lsconf,\"Platform\sFirmware\slevel:\s(?P<AIX_plateform_firmware_level>.+\w)\""\
    +| rex "BBB.+,[0-9].+,lsconf,\"Machine\sSerial\sNumber:\s(?P<AIX_Machine_SerialNumber>.+)\""\
    +| rex "AAA,SerialNumber,(?P<AIX_alt_Machine_SerialNumber>\w+)"\
    +| eval AIX_Machine_SerialNumber=if(isnotnull(AIX_Machine_SerialNumber), AIX_Machine_SerialNumber, AIX_alt_Machine_SerialNumber)\
    +| rex "BBB.+,[0-9].+,lparstat.+,\"Shared\sPool\sID\s+\:\s(?P<AIX_PoolID>.+)\""\
    +| eval AIX_PoolID=if(AIX_PoolID=="-","N/A" ,AIX_PoolID)\
    +| rex "BBB.+,[0-9].+,lparstat.+,\"Maximum\sPhysical\sCPUs\sin\ssystem\s+\:\s(?P<AIX_system_installed_CPUs>.+)\""\
    +| rex "BBB.+,[0-9].+,lparstat.+,\"Active\sPhysical\sCPUs\sin\ssystem\s+\:\s(?P<AIX_system_active_CPUs>.+)\""\
    +| rex "BBB.+,[0-9].+,lparstat.+,\"Active\sCPUs\sin\sPool\s+\:\s(?P<AIX_PoolCPUs>.+)\""\
    +| eval AIX_PoolCPUs=if(AIX_PoolCPUs=="-","N/A" ,AIX_PoolCPUs)\
    +| rex "BBB.+,[0-9].+,lparstat.+,\"Entitled\sCapacity\s+\:\s(?P<AIX_entitled>.+)\""\
    +| rex "BBB.+,[0-9].+,lsconf,\"Processor\sType:\s(?P<AIX_processor>.+\w)\""\
    +| strcat AIX_virtualcpus " / " cpu_cores_position2 cpu_cores_combo\
    +| eval AIX_logicalcores=if(isnotnull(cpu_cores_position2), cpu_cores_position2, cpu_cores_position1)
    +iseval = 0
    +
    +# Linux specific
    +
    +[nmon_config_Linux_rex]
    +definition = rex "AAA,OS,Linux,(?P<Linux_LEVEL>.+)"\
    +| rex "BBB.+,[0-9].+cpuinfo,.+model\sname.+:\s+(?P<Linux_processor>.+)\""\
    +| rex "BBB.+,[0-9].+,.+etc+.release,\"(?P<Linux_distribution>.+)\""\
    +| rex "BBB.+,[0-9].+,lsb\_release,\"Release:\s+(?P<Linux_version>.+)\""\
    +| rex "BBB.+,[0-9].+,.proc.meminfo,\"MemTotal:\s+(?P<Linux_memory_kB>\d+)" | eval Linux_memory_MB=round(Linux_memory_kB/1024,0)\
    +| rex "BBB.+,[0-9].+,.proc.meminfo,\"SwapTotal:\s+(?P<Linux_swap_kB>\d+)" | eval Linux_swap_MB=round(Linux_swap_kB/1024,0)\
    +| rex "AAA,OS,Linux,(?P<Linux_kernelversion>\d+.\d+).+,#"\
    +| rex "AAA,OS,Linux,(?P<Linux_kernel>.+),#"\
    +| rex "AAA,OS,Linux,(?P<Linux_fullkernel>.+)"
    +iseval = 0
    +
    +# Solaris specific
    +
    +[nmon_config_Solaris_rex]
    +definition = rex "AAA,OS,Solaris,(?P<Solaris_LEVEL>.+)"\
    +| rex "AAA,OS,Solaris,.+,(?P<Solaris_kernel>.+),.+,.+"\
    +| rex "AAA,OS,Solaris,(?P<Solaris_sunOS_version>.+),.+,.+,.+"\
    +| rex "BBB.+,[0-9].+,.+etc+.release,\"\s+(?P<Solaris_version>.+)\""\
    +| rex "BBB.+,[0-9].+psrinfo\s\-pv,\"\s+(?P<Solaris_processor>.+\w)\""\
    +| rex "BBB.+,[0-9].+psrinfo\s\-pv,.+clock\s(?P<Solaris_processor_clockspeed>.+)\)\""
    +iseval = 0
    +
    +###################################
    +# 	Final macros used for inventory data retrieve
    +###################################
    +
    +[nmon_config]
    +definition = `nmon_index` sourcetype=nmon_config\
    +| rex "(?i),host,(?P<hostname>.+)"\
    +| `nmon_config_common_rex`\
    +| `nmon_config_AIX_rex`\
    +| `nmon_config_Linux_rex`\
    +| `nmon_config_Solaris_rex`\
    +| eval OStype=case(OS == "Linux", "Linux", OS == "Solaris", "Solaris", isnotnull(AIX_LEVEL), "AIX")\
    +| eval OS_Level=case(isnotnull(AIX_LEVEL), AIX_LEVEL, isnotnull(Solaris_version), Solaris_version, isnotnull(Linux_distribution), Linux_distribution)\
    +| eval cpu_cores=if(isnotnull(AIX_virtualcpus), cpu_cores_combo, cpu_cores_position1)\
    +| eval Processor=case(isnotnull(AIX_processor), AIX_processor, isnotnull(Solaris_processor), Solaris_processor, isnotnull(Linux_processor), Linux_processor)
    +iseval = 0
    +
    +# Used in addition with the command: `nmon_index` sourcetype=nmon_config | rex "(?i),host,(?<hostname>.+)" | search $hostname$" in Nmon_Summary
    +# to optimize time treatment
    +
    +[nmon_config_rex]
    +definition = `nmon_config_common_rex`\
    +| `nmon_config_AIX_rex`\
    +| `nmon_config_Linux_rex`\
    +| `nmon_config_Solaris_rex`\
    +| eval OStype=case(OS == "Linux", "Linux", OS == "Solaris", "Solaris", isnotnull(AIX_LEVEL), "AIX")\
    +| eval OS_Level=case(isnotnull(AIX_LEVEL), AIX_LEVEL, isnotnull(Solaris_version), Solaris_version, isnotnull(Linux_distribution), Linux_distribution)\
    +| eval cpu_cores=if(isnotnull(AIX_virtualcpus), cpu_cores_combo, cpu_cores_position1)\
    +| eval Processor=case(isnotnull(AIX_processor), AIX_processor, isnotnull(Solaris_processor), Solaris_processor, isnotnull(Linux_processor), Linux_processor)
    +iseval = 0
    +
    +# Called by User Interfaces to filter OS list based on type of OS
    +
    +[nmon_inventory]
    +definition = | inputlookup nmon_inventory
    +iseval = 0
    +
    +# This macro will be called by the scheduled report responsible for the update of the configuration KVstore lookup
    +# On some large system at scale, the lengh of the code seemed to be an issue in Splunk Web
    +
    +[nmon_inventory_update]
    +definition = tstats latest("Nmon_Config.OStype") as OStype\
    +latest("Nmon_Config.AIX_Machine_SerialNumber") AS AIX_Machine_SerialNumber\
    +latest("Nmon_Config.AIX_virtualcpus") AS AIX_virtualcpus\
    +latest("Nmon_Config.AIX_logicalcores") AS AIX_logicalcores\
    +latest("Nmon_Config.AIX_entitled") AS AIX_entitled\
    +latest("Nmon_Config.AIX_LEVEL") AS AIX_LEVEL\
    +latest("Nmon_Config.AIX_processor_mode") AS AIX_processor_mode\
    +latest("Nmon_Config.AIX_processor_clockspeed") AS AIX_processor_clockspeed\
    +latest("Nmon_Config.AIX_cpu_type") AS AIX_cpu_type\
    +latest("Nmon_Config.AIX_kernel_type") AS AIX_kernel_type\
    +latest("Nmon_Config.AIX_plateform_firmware_level") AS AIX_plateform_firmware_level\
    +latest("Nmon_Config.AIX_PoolID") AS AIX_PoolID\
    +latest("Nmon_Config.AIX_system_installed_CPUs") AS AIX_system_installed_CPUs\
    +latest("Nmon_Config.AIX_system_active_CPUs") AS AIX_system_active_CPUs\
    +latest("Nmon_Config.AIX_PoolCPUs") AS AIX_PoolCPUs\
    +latest("Nmon_Config.AIX_memory_MB") AS AIX_memory_MB\
    +latest("Nmon_Config.AIX_pagingspace_MB") AS AIX_pagingspace_MB\
    +latest("Nmon_Config.Linux_memory_MB") AS Linux_memory_MB\
    +latest("Nmon_Config.Linux_swap_MB") AS Linux_swap_MB\
    +latest("Nmon_Config.Linux_distribution") AS Linux_distribution\
    +latest("Nmon_Config.Linux_vendor") AS Linux_vendor\
    +latest("Nmon_Config.Linux_kernelversion") AS Linux_kernelversion\
    +latest("Nmon_Config.Solaris_version") AS Solaris_version\
    +latest("Nmon_Config.Solaris_sunOS_version") AS Solaris_sunOS_version\
    +latest("Nmon_Config.Solaris_processor_clockspeed") AS Solaris_processor_clockspeed\
    +latest("Nmon_Config.Solaris_physical_memory_MB") AS Solaris_physical_memory_MB\
    +latest("Nmon_Config.Processor") AS Processor\
    +latest("Nmon_Config.cpu_cores") AS cpu_cores\
    +latest("Nmon_Config.nmon_version") AS nmon_version\
    +latest("Nmon_Config.uptime") AS uptime_seconds\
    +latest("Nmon_Config.event_epoch") AS last_report\
    +from datamodel=metricator-nmon-config where (nodename = Nmon_Config) (sourcetype=nmon_config) by host prestats=true\
    +| tstats latest("Uptime.uptime") AS external_uptime latest(Uptime.event_epoch) as external_last_report from datamodel=metricator-nmon-config.Uptime where (nodename = Uptime) (Uptime.uptime = "*") by host append=true prestats=true\
    +| stats dedup_splitvals=t\
    +latest("Nmon_Config.OStype") as OStype\
    +latest("Nmon_Config.AIX_Machine_SerialNumber") AS AIX_Machine_SerialNumber\
    +latest("Nmon_Config.AIX_virtualcpus") AS AIX_virtualcpus\
    +latest("Nmon_Config.AIX_logicalcores") AS AIX_logicalcores\
    +latest("Nmon_Config.AIX_entitled") AS AIX_entitled\
    +latest("Nmon_Config.AIX_LEVEL") AS AIX_LEVEL\
    +latest("Nmon_Config.AIX_processor_mode") AS AIX_processor_mode\
    +latest("Nmon_Config.AIX_processor_clockspeed") AS AIX_processor_clockspeed\
    +latest("Nmon_Config.AIX_cpu_type") AS AIX_cpu_type\
    +latest("Nmon_Config.AIX_kernel_type") AS AIX_kernel_type\
    +latest("Nmon_Config.AIX_plateform_firmware_level") AS AIX_plateform_firmware_level\
    +latest("Nmon_Config.AIX_PoolID") AS AIX_PoolID\
    +latest("Nmon_Config.AIX_system_installed_CPUs") AS AIX_system_installed_CPUs\
    +latest("Nmon_Config.AIX_system_active_CPUs") AS AIX_system_active_CPUs\
    +latest("Nmon_Config.AIX_PoolCPUs") AS AIX_PoolCPUs\
    +latest("Nmon_Config.AIX_memory_MB") AS AIX_memory_MB\
    +latest("Nmon_Config.AIX_pagingspace_MB") AS AIX_pagingspace_MB\
    +latest("Nmon_Config.Linux_memory_MB") AS Linux_memory_MB\
    +latest("Nmon_Config.Linux_swap_MB") AS Linux_swap_MB\
    +latest("Nmon_Config.Linux_distribution") AS Linux_distribution\
    +latest("Nmon_Config.Linux_vendor") AS Linux_vendor\
    +latest("Nmon_Config.Linux_kernelversion") AS Linux_kernelversion\
    +latest("Nmon_Config.Solaris_version") AS Solaris_version\
    +latest("Nmon_Config.Solaris_sunOS_version") AS Solaris_sunOS_version\
    +latest("Nmon_Config.Solaris_processor_clockspeed") AS Solaris_processor_clockspeed\
    +latest("Nmon_Config.Solaris_physical_memory_MB") AS Solaris_physical_memory_MB\
    +latest("Nmon_Config.Processor") AS Processor\
    +latest("Nmon_Config.cpu_cores") AS cpu_cores\
    +latest("Nmon_Config.nmon_version") AS nmon_version\
    +latest("Nmon_Config.uptime") AS uptime_seconds\
    +latest("Uptime.uptime") AS external_uptime_seconds\
    +latest("Nmon_Config.event_epoch") AS last_report, latest(Uptime.event_epoch) as external_last_report by host\
    +| sort limit=0 host\
    +| rename host AS hostname\
    +| eval now=now()\
    +| eval uptime_seconds=if(isnotnull(external_uptime_seconds), external_uptime_seconds, uptime_seconds)\
    +| eval last_report=if(isnotnull(external_last_report), external_last_report, last_report)\
    +| fields - external_uptime_seconds\
    +| eval uptime_seconds=(uptime_seconds+(now-last_report))\
    +| eval uptime_duration=tostring(uptime_seconds, "duration")\
    +| fields - external_last_report\
    +| eval reporting_date=strftime(last_report, "%m/%d/%Y %H:%M")\
    +| eval system_startup_date=strftime((now()-uptime_seconds), "%m/%d/%Y %H:%M")\
    +| eval cpu_logicalcores=if(isnum(AIX_logicalcores), AIX_logicalcores, cpu_cores)\
    +| rex field=Linux_distribution mode=sed "s/Q$//g"\
    +| fields hostname, OStype, AIX_Machine_SerialNumber, AIX_virtualcpus, AIX_logicalcores, AIX_entitled, AIX_LEVEL,\
    +AIX_processor_mode, AIX_processor_clockspeed, AIX_cpu_type, AIX_kernel_type, AIX_plateform_firmware_level, AIX_PoolID,\
    +AIX_system_installed_CPUs, AIX_system_active_CPUs, AIX_PoolCPUs, AIX_memory_MB, AIX_pagingspace_MB, Linux_memory_MB, Linux_swap_MB, Linux_distribution,\
    +Linux_vendor, Linux_kernelversion, Solaris_version, Solaris_sunOS_version, Solaris_processor_clockspeed, Solaris_physical_memory_MB, Processor, cpu_cores, cpu_logicalcores, nmon_version, uptime_seconds, uptime_duration, system_startup_date, reporting_date\
    +| eval OSversion=case(OStype=="Linux", Linux_distribution, OStype=="AIX", AIX_LEVEL, OStype=="Solaris", if(isnotnull(Solaris_version), Solaris_version, Solaris_sunOS_version))\
    +| eval Physical_mem_MB=case(OStype=="Linux", Linux_memory_MB, OStype=="AIX", AIX_memory_MB, OStype=="Solaris", Solaris_physical_memory_MB)\
    +| eval Virtual_mem_MB=case(OStype=="Linux", Linux_swap_MB, OStype=="AIX", AIX_pagingspace_MB, OStype=="Solaris", "NA")\
    +| fillnull value="NA"
    +iseval = 0
    +
    +###################################
    +# 	Custom Span definition for Application Statistics Django View
    +###################################
    +
    +[internal_table_stats_span]
    +definition = [ search index=_internal | head 1 | addinfo\
    +| eval earliest=if(info_min_time == "0.000", info_search_time,info_min_time)\
    +| eval latest=if(info_max_time == "+Infinity", info_search_time,info_max_time)\
    +| eval searchStartTIme=strftime(earliest,"%a %d %B %Y %H:%M")\
    +| eval searchEndTime=strftime(latest,"%a %d %B %Y %H:%M")\
    +| eval Difference = (latest - earliest)\
    +| eval span=case(\
    +Difference > (12*31*24*60*60),"1y",\
    +Difference > (31*24*60*60),"1m",\
    +Difference > (24*60*60),"1d",\
    +Difference <= (24*60*60),"1h"\
    +)\
    +| return span ]
    +iseval = 0
    +
    +#####################
    +#	FILTER TIME		#
    +#####################
    +
    +[No_Filter]
    +definition = eval time_filtering="false"
    +iseval = 0
    +
    +[Day_BusinessDays_8h-19h]
    +definition = eval local_time=strftime(_time, "%H:%M"), date_wday=lower(strftime(_time, "%A")) | search (local_time>="08:00" AND local_time<="19:00") AND (date_wday!="sunday" date_wday!="saturday")
    +iseval = 0
    +
    +[Day_WeekEnd_8h-19h]
    +definition = eval local_time=strftime(_time, "%H:%M"), date_wday=lower(strftime(_time, "%A")) | search (local_time>="08:00" AND local_time<="19:00") AND (date_wday="sunday" OR date_wday="saturday")
    +iseval = 0
    +
    +[Day_AllDays_8h-19h]
    +definition = eval local_time=strftime(_time, "%H:%M"), date_wday=lower(strftime(_time, "%A")) | search (local_time>="08:00" AND local_time<="19:00")
    +iseval = 0
    +
    +[Night_BusinessDays_19h-8h]
    +definition = eval local_time=strftime(_time, "%H:%M"), date_wday=lower(strftime(_time, "%A")) | search (local_time>="19:00" AND local_time<="23:59") OR (local_time>="00:00" AND local_time<="08:00") AND (date_wday!="sunday" date_wday!="saturday")
    +iseval = 0
    +
    +[Night_WeekEnd_19h-8h]
    +definition = eval local_time=strftime(_time, "%H:%M"), date_wday=lower(strftime(_time, "%A")) | search (local_time>="19:00" AND local_time<="23:59") OR (local_time>="00:00" AND local_time<="08:00") AND (date_wday="sunday" OR date_wday="saturday")
    +iseval = 0
    +
    +[Night_AllDays_19h-8h]
    +definition = eval local_time=strftime(_time, "%H:%M"), date_wday=lower(strftime(_time, "%A")) | search (local_time>="19:00" AND local_time<="23:59") OR (local_time>="00:00" AND local_time<="08:00")
    +iseval = 0
    +
    +####################################################
    +# NMON PROCESSING SECTION
    +####################################################
    +
    +[nmon_processing]
    +definition = `nmon_index` sourcetype=nmon_processing
    +iseval = 0
    +
    +[nmon_processing_stats]
    +definition = `nmon_processing`\
    +| eval size_KB=round((size_in_bytes/1000),2)\
    +| eval size_MB=round((size_in_bytes/1000/1000),2)\
    +| stats\
    +min(nbr_lines) As min_nbr_lines, avg(nbr_lines) As avg_nbr_lines, max(nbr_lines) As max_nbr_lines, sum(nbr_lines) As sum_nbr_lines,\
    +min(size_KB) As min_size_KB, avg(size_KB) As avg_size_KB, max(size_KB) As max_size_KB, sum(size_KB) As sum_size_KB,\
    +min(size_MB) As min_size_MB, avg(size_MB) As avg_size_MB, max(size_MB) As max_size_MB, sum(size_MB) As sum_size_MB,\
    +min(elapsed_in_seconds) As min_elapsed_in_seconds, avg(elapsed_in_seconds) As avg_elapsed_in_seconds, max(elapsed_in_seconds) As max_elapsed_in_seconds, sum(elapsed_in_seconds) As sum_elapsed_in_seconds\
    +| eval sum_nbr_lines_in_millions=round((sum_nbr_lines/1000/1000),2)\
    +| eval sum_size_GB=round((sum_size_KB/1000/1000),2)\
    +| eval sum_elapsed=tostring(sum_elapsed_in_seconds,"duration")\
    +| eval avg_nbr_lines=round(avg_nbr_lines,0)\
    +| eval avg_size_MB=round(avg_size_MB,2)\
    +| eval avg_elapsed_in_seconds=round(avg_elapsed_in_seconds,2)
    +iseval = 0
    +
    +[nmon_processing_stats_by_time]
    +definition = `nmon_processing`\
    +| eval size_KB=round((size_in_bytes/1000),2)\
    +| eval size_MB=round((size_in_bytes/1000/1000),2)\
    +| stats\
    +min(nbr_lines) As min_nbr_lines, avg(nbr_lines) As avg_nbr_lines, max(nbr_lines) As max_nbr_lines, sum(nbr_lines) As sum_nbr_lines,\
    +min(size_KB) As min_size_KB, avg(size_KB) As avg_size_KB, max(size_KB) As max_size_KB, sum(size_KB) As sum_size_KB,\
    +min(size_MB) As min_size_MB, avg(size_MB) As avg_size_MB, max(size_MB) As max_size_MB, sum(size_MB) As sum_size_MB,\
    +min(elapsed_in_seconds) As min_elapsed_in_seconds, avg(elapsed_in_seconds) As avg_elapsed_in_seconds, max(elapsed_in_seconds) As max_elapsed_in_seconds, sum(elapsed_in_seconds) As sum_elapsed_in_seconds by _time\
    +| eval sum_nbr_lines_in_millions=round((sum_nbr_lines/1000/1000),2)\
    +| eval sum_size_GB=round((sum_size_KB/1000/1000),2)\
    +| eval avg_nbr_lines=round(avg_nbr_lines,0)\
    +| eval avg_size_MB=round(avg_size_MB,2)\
    +| eval avg_elapsed_in_seconds=round(avg_elapsed_in_seconds,2)
    +iseval = 0
    +
    +###################
    +# ALERTING MACROS #
    +###################
    +
    +[alerting_cpu_usage]
    +definition = mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_User_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Sys_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Wait_PCT OR metric_name=os.unix.nmon.cpu.lpar.VP_Idle_PCT OR metric_name=os.unix.nmon.cpu.lpar.PhysicalCPU OR metric_name=os.unix.nmon.cpu.lpar.virtualCPUs OR metric_name=os.unix.nmon.cpu.lpar.partition_active_processors) by metric_name, OStype, host span=1m\
    +| `def_all_os_cpu_load_percent`\
    +| fields _time, host, cpu_load_percent\
    +| `mapping_frameID`\
    +| lookup nmon_alerting_threshold_template frameID OUTPUT alert_cpu_max_percent as template_alert_cpu_max_percent, alert_cpu_min_time_seconds as template_alert_cpu_min_time_seconds\
    +| lookup nmon_alerting_threshold frameID host OUTPUT alert_cpu_max_percent as server_alert_cpu_max_percent, alert_cpu_min_time_seconds as server_alert_cpu_min_time_seconds\
    +| eval default_alert_cpu_max_percent="90", default_alert_cpu_min_time_seconds="300"\
    +| eval alert_cpu_max_percent=case(isnum(server_alert_cpu_max_percent), server_alert_cpu_max_percent, isnum(template_alert_cpu_max_percent), template_alert_cpu_max_percent, isnum(default_alert_cpu_max_percent), default_alert_cpu_max_percent),\
    +alert_cpu_min_time_seconds=case(isnum(server_alert_cpu_min_time_seconds), server_alert_cpu_min_time_seconds, isnum(template_alert_cpu_min_time_seconds), template_alert_cpu_min_time_seconds, isnum(default_alert_cpu_min_time_seconds), default_alert_cpu_min_time_seconds),\
    +alert_threshold_source=case(isnum(server_alert_cpu_max_percent), "server_thresholds", isnum(template_alert_cpu_max_percent), "template_thresholds", isnum(default_alert_cpu_max_percent), "default_threshold")\
    +| sort 0 - _time\
    +| eval status=if(cpu_load_percent>alert_cpu_max_percent, "red", "green")\
    +| eval {status}=status\
    +| transaction frameID host status keepevicted=t keeporphans=t maxpause=5m\
    +| stats max(_time) as _time, latest(duration) as duration, latest(cpu_load_percent) as latest_cpu_load_percent, latest(alert_cpu_max_percent) as alert_cpu_max_percent, latest(alert_cpu_min_time_seconds) as alert_cpu_min_time_seconds, latest(alert_threshold_source) as alert_threshold_source, latest(status) as status by frameID, host\
    +| eval "duration (hh:mm:ss)"=tostring(duration, "duration")\
    +| where (status="red") AND (duration>=alert_cpu_min_time_seconds)\
    +| fields frameID,host,_time,duration,"duration (hh:mm:ss)",latest_cpu_load_percent,alert_cpu_max_percent,alert_cpu_min_time_seconds,alert_threshold_source
    +iseval = 0
    +
    +[alerting_filesystem_usage]
    +definition = mstats avg(_value) as value where `nmon_metrics_index` (metric_name="os.unix.nmon.storage.df_storage.Use_pct" OR metric_name="os.unix.nmon.storage.jfsfile") by host, metric_name, dimension_mount span=1m\
    +| eval df_storage_value=case((metric_name == "os.unix.nmon.storage.df_storage.Use_pct"),value), jfsfile_value=case((metric_name == "os.unix.nmon.storage.jfsfile"),value), storage_used_percent=if(isnum(df_storage_value),df_storage_value,jfsfile_value)\
    +| stats latest(storage_used_percent) as storage_used_percent by _time, host, dimension_mount\
    +| rename dimension_mount as mount\
    +| `mapping_frameID`\
    +| lookup nmon_alerting_threshold_template_filesystem frameID mount OUTPUT alert_fs_max_percent as template_alert_fs_max_percent, alert_fs_min_time_seconds as template_alert_fs_min_time_seconds, is_shared, _key as fs_uuid\
    +| lookup nmon_alerting_threshold_filesystem frameID host mount OUTPUT alert_fs_max_percent as server_alert_fs_max_percent, alert_fs_min_time_seconds as server_alert_fs_min_time_seconds\
    +| eval is_shared=if(isnull(is_shared), "False", is_shared)\
    +| eval fs_uuid=if(is_shared="True", fs_uuid, md5(frameID . ":" . host . ":" . mount))\
    +| eval default_alert_fs_max_percent="90", default_alert_fs_min_time_seconds="300"\
    +| eval alert_fs_max_percent=case(isnum(server_alert_fs_max_percent), server_alert_fs_max_percent, isnum(template_alert_fs_max_percent), template_alert_fs_max_percent, isnum(default_alert_fs_max_percent), default_alert_fs_max_percent),\
    +alert_fs_min_time_seconds=case(isnum(server_alert_fs_min_time_seconds), server_alert_fs_min_time_seconds, isnum(template_alert_fs_min_time_seconds), template_alert_fs_min_time_seconds, isnum(default_alert_fs_min_time_seconds), default_alert_fs_min_time_seconds),\
    +alert_threshold_source=case(isnum(server_alert_fs_max_percent), "server_thresholds", isnum(template_alert_fs_max_percent), "template_thresholds", isnum(default_alert_fs_max_percent), "default_threshold")\
    +| lookup nmon_alerting_filesystem_global_exclusion mount OUTPUT exclude as global_exclude\
    +| lookup nmon_alerting_filesystem_template_exclusion frameID mount OUTPUT exclude as template_exclude\
    +| lookup nmon_alerting_filesystem_per_server_exclusion host mount OUTPUT exclude as host_exclude\
    +| fillnull value="false" global_exclude template_exclude host_exclude\
    +| where (global_exclude!="true" AND template_exclude!="true" AND host_exclude!="true")\
    +| sort 0 - _time\
    +| eval status=if(storage_used_percent>alert_fs_max_percent, "red", "green")\
    +| eval {status}=status\
    +| transaction fs_uuid status keepevicted=t keeporphans=t maxpause=5m\
    +| stats first(frameID) as frameID, first(host) as host, first(mount) as mount, max(_time) as _time, latest(duration) as duration, latest(storage_used_percent) as latest_storage_used_percent, latest(alert_fs_max_percent) as alert_fs_max_percent, latest(alert_fs_min_time_seconds) as alert_fs_min_time_seconds, latest(alert_threshold_source) as alert_threshold_source, latest(status) as status by fs_uuid\
    +| eval "duration (hh:mm:ss)"=tostring(duration, "duration")\
    +| where (status="red") AND (duration>=alert_fs_min_time_seconds)\
    +| fields frameID,host,_time,mount,fs_uuid,duration,"duration (hh:mm:ss)",latest_storage_used_percent,alert_fs_max_percent,alert_fs_min_time_seconds,alert_threshold_source
    +iseval = 0
    +
    +[alerting_realmemory_usage]
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.memnew.System_PCT OR metric_name=os.unix.nmon.memory.memnew.Process_PCT OR metric_name=os.unix.nmon.memory.mem.memtotal OR metric_name=os.unix.nmon.memory.mem.buffers OR metric_name=os.unix.nmon.memory.mem.cached OR metric_name=os.unix.nmon.memory.mem.memfree by OStype, host, metric_name span=1m\
    +| `def_memory_load_percent`\
    +| fields _time, host,mem_used_effective_PCT\
    +| `mapping_frameID`\
    +| lookup nmon_alerting_threshold_template frameID OUTPUT alert_physical_memory_max_percent as template_alert_physical_memory_max_percent, alert_physical_memory_min_time_seconds as template_alert_physical_memory_min_time_seconds\
    +| lookup nmon_alerting_threshold frameID host OUTPUT alert_physical_memory_max_percent as server_alert_physical_memory_max_percent, alert_physical_memory_min_time_seconds as server_alert_physical_memory_min_time_seconds\
    +| eval default_alert_physical_memory_max_percent="90", default_alert_physical_memory_min_time_seconds="300"\
    +| eval alert_physical_memory_max_percent=case(isnum(server_alert_physical_memory_max_percent), server_alert_physical_memory_max_percent, isnum(template_alert_physical_memory_max_percent), template_alert_physical_memory_max_percent, isnum(default_alert_physical_memory_max_percent), default_alert_physical_memory_max_percent),\
    +alert_physical_memory_min_time_seconds=case(isnum(server_alert_physical_memory_min_time_seconds), server_alert_physical_memory_min_time_seconds, isnum(template_alert_physical_memory_min_time_seconds), template_alert_physical_memory_min_time_seconds, isnum(default_alert_physical_memory_min_time_seconds), default_alert_physical_memory_min_time_seconds),\
    +alert_threshold_source=case(isnum(server_alert_physical_memory_max_percent), "server_thresholds", isnum(template_alert_physical_memory_max_percent), "template_thresholds", isnum(default_alert_physical_memory_max_percent), "default_threshold")\
    +| sort 0 - _time\
    +| eval status=if(mem_used_effective_PCT>alert_physical_memory_max_percent, "red", "green")\
    +| eval {status}=status\
    +| transaction frameID host status keepevicted=t keeporphans=t maxpause=5m\
    +| stats max(_time) as _time, latest(duration) as duration, latest(mem_used_effective_PCT) as latest_mem_used_effective_PCT, latest(alert_physical_memory_max_percent) as alert_physical_memory_max_percent, latest(alert_physical_memory_min_time_seconds) as alert_physical_memory_min_time_seconds, latest(alert_threshold_source) as alert_threshold_source, latest(status) as status by frameID, host\
    +| eval "duration (hh:mm:ss)"=tostring(duration, "duration")\
    +| where (status="red") AND (duration>=alert_physical_memory_min_time_seconds)\
    +| fields frameID,host,_time,duration,"duration (hh:mm:ss)",latest_mem_used_effective_PCT,alert_physical_memory_max_percent,alert_physical_memory_min_time_seconds,alert_threshold_source
    +iseval = 0
    +
    +[alerting_virtualmemory_usage]
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.memory.mem.Virtual_total_MB OR metric_name=os.unix.nmon.memory.mem.Virtual_free_MB OR metric_name=os.unix.nmon.memory.mem.swapcached OR metric_name=os.unix.nmon.memory.mem.swaptotal OR metric_name=os.unix.nmon.memory.mem.swapfree by OStype, host, metric_name span=1m\
    +| `def_memory_load_percent`\
    +| fields _time, host,swap_used_effective_PCT\
    +| `mapping_frameID`\
    +| lookup nmon_alerting_threshold_template frameID OUTPUT alert_virtual_memory_max_percent as template_alert_virtual_memory_max_percent, alert_virtual_memory_min_time_seconds as template_alert_virtual_memory_min_time_seconds\
    +| lookup nmon_alerting_threshold frameID host OUTPUT alert_virtual_memory_max_percent as server_alert_virtual_memory_max_percent, alert_virtual_memory_min_time_seconds as server_alert_virtual_memory_min_time_seconds\
    +| eval default_alert_virtual_memory_max_percent="40", default_alert_virtual_memory_min_time_seconds="300"\
    +| eval alert_virtual_memory_max_percent=case(isnum(server_alert_virtual_memory_max_percent), server_alert_virtual_memory_max_percent, isnum(template_alert_virtual_memory_max_percent), template_alert_virtual_memory_max_percent, isnum(default_alert_virtual_memory_max_percent), default_alert_virtual_memory_max_percent),\
    +alert_virtual_memory_min_time_seconds=case(isnum(server_alert_virtual_memory_min_time_seconds), server_alert_virtual_memory_min_time_seconds, isnum(template_alert_virtual_memory_min_time_seconds), template_alert_virtual_memory_min_time_seconds, isnum(default_alert_virtual_memory_min_time_seconds), default_alert_virtual_memory_min_time_seconds),\
    +alert_threshold_source=case(isnum(server_alert_virtual_memory_max_percent), "server_thresholds", isnum(template_alert_virtual_memory_max_percent), "template_thresholds", isnum(default_alert_virtual_memory_max_percent), "default_threshold")\
    +| sort 0 - _time\
    +| eval status=if(swap_used_effective_PCT>alert_virtual_memory_max_percent, "red", "green")\
    +| eval {status}=status\
    +| transaction frameID host status keepevicted=t keeporphans=t maxpause=5m\
    +| stats max(_time) as _time, latest(duration) as duration, latest(swap_used_effective_PCT) as latest_swap_used_effective_PCT, latest(alert_virtual_memory_max_percent) as alert_virtual_memory_max_percent, latest(alert_virtual_memory_min_time_seconds) as alert_virtual_memory_min_time_seconds, latest(alert_threshold_source) as alert_threshold_source, latest(status) as status by frameID, host\
    +| eval "duration (hh:mm:ss)"=tostring(duration, "duration")\
    +| where (status="red") AND (duration>=alert_virtual_memory_min_time_seconds)\
    +| fields frameID,host,_time,duration,"duration (hh:mm:ss)",latest_swap_used_effective_PCT,alert_virtual_memory_max_percent,alert_virtual_memory_min_time_seconds,alert_threshold_source
    +iseval = 0
    +
    +###################
    +# BASELINE MACROS #
    +###################
    +
    +### Baseline generation macros ###
    +
    +#
    +# CPU_ALL
    +# Average CPU usage, relevant for ALL OS
    +#
    +
    +# CPU usage with simple baseline able to chart in the future - future charting capable
    +[nmon_cpu_pct_simple_baseline_future(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT host=$host$  by metric_name, host span=5m\
    +| `def_cpu_load_percent`\
    +| rename host AS hostname\
    +| append [ | gentimes [| stats count | addinfo | eval start=strftime('info_min_time', "%m/%d/%Y:%H:%M:%S") | return start] [| stats count | addinfo | eval end=strftime('info_max_time', "%m/%d/%Y:%H:%M:%S")\
    +| return end] increment=5m | eval _time=starttime | eval hostname="$host$"\
    +| timechart span=5m count by hostname | untable _time hostname count | fields - count ]\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_CPU_ALL date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(cpu_load_percent) AS cpu_load_percent, avg(baseline_avg_cpu) AS baseline_avg_cpu
    +iseval = 0
    +
    +# CPU usage with simple baseline able to chart in the future - no future charting
    +[nmon_cpu_pct_simple_baseline(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT host=$host$  by metric_name, host span=5m\
    +| `def_cpu_load_percent`\
    +| rename host AS hostname\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_CPU_ALL date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(cpu_load_percent) AS cpu_load_percent, avg(baseline_avg_cpu) AS baseline_avg_cpu
    +iseval = 0
    +
    +# CPU usage with lower, average and upper baseline (predict command rendering) - future charting capable
    +[nmon_cpu_pct_full_baseline_future(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT host=$host$  by metric_name, host span=5m\
    +| `def_cpu_load_percent`\
    +| rename host AS hostname\
    +| append [ | gentimes [| stats count | addinfo | eval start=strftime('info_min_time', "%m/%d/%Y:%H:%M:%S") | return start] [| stats count | addinfo | eval end=strftime('info_max_time', "%m/%d/%Y:%H:%M:%S")\
    +| return end] increment=5m | eval _time=starttime | eval hostname="$host$"\
    +| timechart span=5m count by hostname | untable _time hostname count | fields - count ]\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_CPU_ALL date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(cpu_load_percent) AS cpu_load_percent, avg(lower_baseline_avg_cpu) AS lower, avg(baseline_avg_cpu) AS predicted, avg(upper_baseline_avg_cpu) AS upper\
    +| eval _lower = "lower" | eval _predicted = "predicted" | eval _upper = "upper"
    +iseval = 0
    +
    +# CPU usage with lower, average and upper baseline (predict command rendering) - no future charting
    +[nmon_cpu_pct_full_baseline(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT host=$host$  by metric_name, host span=5m\
    +| `def_cpu_load_percent`\
    +| rename host AS hostname\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_CPU_ALL date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(cpu_load_percent) AS cpu_load_percent, avg(lower_baseline_avg_cpu) AS lower, avg(baseline_avg_cpu) AS predicted, avg(upper_baseline_avg_cpu) AS upper\
    +| eval _lower = "lower" | eval _predicted = "predicted" | eval _upper = "upper"
    +iseval = 0
    +
    +#
    +# LPAR
    +# Average AIX micro-partitions Virtual CPU usage, relevant for AIX OS only
    +#
    +
    +# Virtual CPU usage with simple baseline - future charting capable
    +[nmon_vp_usage_simple_baseline_future(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.* host=$host$ by OStype, metric_name, host span=5m\
    +| `def_lpar_load_cores`\
    +| fields _time, host, lpar_load_cores, entitled, virtualCPUs\
    +| rename host AS hostname\
    +| append [ | gentimes [| stats count | addinfo | eval start=strftime('info_min_time', "%m/%d/%Y:%H:%M:%S") | return start] [| stats count | addinfo | eval end=strftime('info_max_time', "%m/%d/%Y:%H:%M:%S")\
    +| return end] increment=5m | eval _time=starttime | eval hostname="$host$"\
    +| timechart span=5m count by hostname | untable _time hostname count | fields - count ]\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_LPAR date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(lpar_load_cores) AS vp_usage, max(entitled) AS entitled, max(virtualCPUs) AS virtualCPUs, avg(baseline_avg_vp_usage) AS baseline_avg_vp_usage
    +iseval = 0
    +
    +# Virtual CPU usage with simple baseline - no future charting
    +[nmon_vp_usage_simple_baseline(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.* host=$host$ by OStype, metric_name, host span=5m\
    +| `def_lpar_load_cores`\
    +| fields _time, host, lpar_load_cores, entitled, virtualCPUs\
    +| rename host AS hostname\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_LPAR date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(lpar_load_cores) AS vp_usage, max(entitled) AS entitled, max(virtualCPUs) AS virtualCPUs, avg(baseline_avg_vp_usage) AS baseline_avg_vp_usage
    +iseval = 0
    +
    +# Virtual CPU usage with lower, average and upper baseline (predict command rendering) - future charting capable
    +[nmon_vp_usage_full_baseline_future(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.* host=$host$ by OStype, metric_name, host span=5m\
    +| `def_lpar_load_cores`\
    +| fields _time, host, lpar_load_cores, entitled, virtualCPUs\
    +| rename host AS hostname\
    +| append [ | gentimes [| stats count | addinfo | eval start=strftime('info_min_time', "%m/%d/%Y:%H:%M:%S") | return start] [| stats count | addinfo | eval end=strftime('info_max_time', "%m/%d/%Y:%H:%M:%S")\
    +| return end] increment=5m | eval _time=starttime | eval hostname="$host$"\
    +| timechart span=5m count by hostname | untable _time hostname count | fields - count ]\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_LPAR date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(lpar_load_cores) AS vp_usage, max(entitled) AS entitled, max(virtualCPUs) AS virtualCPUs\
    +avg(lower_baseline_avg_vp_usage) AS lower, avg(baseline_avg_vp_usage) AS predicted, avg(upper_baseline_avg_vp_usage) AS upper\
    +| eval _lower = "lower" | eval _predicted = "predicted" | eval _upper = "upper"
    +iseval = 0
    +
    +# Virtual CPU usage with lower, average and upper baseline (predict command rendering) - no future charting
    +[nmon_vp_usage_full_baseline(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.* host=$host$ by OStype, metric_name, host span=5m\
    +| `def_lpar_load_cores`\
    +| fields _time, host, lpar_load_cores, entitled, virtualCPUs\
    +| rename host AS hostname\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_LPAR date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(lpar_load_cores) AS vp_usage, max(entitled) AS entitled, max(virtualCPUs) AS virtualCPUs\
    +avg(lower_baseline_avg_vp_usage) AS lower, avg(baseline_avg_vp_usage) AS predicted, avg(upper_baseline_avg_vp_usage) AS upper\
    +| eval _lower = "lower" | eval _predicted = "predicted" | eval _upper = "upper"
    +iseval = 0
    +
    +# Pool Virtual CPU usage with simple baseline - future charting capable
    +[nmon_pool_usage_simple_baseline_future(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.* host="$host$" by OStype, metric_name, host span=5m\
    +| `def_all_os_lpar_pool_load_cores`\
    +| rename host AS hostname\
    +| append [ | gentimes [| stats count | addinfo | eval start=strftime('info_min_time', "%m/%d/%Y:%H:%M:%S") | return start] [| stats count | addinfo | eval end=strftime('info_max_time', "%m/%d/%Y:%H:%M:%S")\
    +| return end] increment=5m | eval _time=starttime | eval hostname="$host$"\
    +| timechart span=5m count by hostname | untable _time hostname count | fields - count ]\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_LPAR date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(lpar_pool_vp_usage) AS pool_usage, max(poolCPUs) AS poolCPUs, avg(baseline_avg_pool_usage) AS baseline_avg_pool_usage
    +iseval = 0
    +
    +# Pool Virtual CPU usage with simple baseline - no future charting
    +[nmon_pool_usage_simple_baseline(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.* host="$host$" by OStype, metric_name, host span=5m\
    +| `def_all_os_lpar_pool_load_cores`\
    +| rename host AS hostname\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_LPAR date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(lpar_pool_vp_usage) AS pool_usage, max(poolCPUs) AS poolCPUs, avg(baseline_avg_pool_usage) AS baseline_avg_pool_usage
    +iseval = 0
    +
    +# Pool CPU usage with lower, average and upper baseline (predict command rendering) - future charting capable
    +[nmon_pool_usage_full_baseline_future(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.* host="$host$" by OStype, metric_name, host span=5m\
    +| `def_all_os_lpar_pool_load_cores`\
    +| rename host AS hostname\
    +| append [ | gentimes [| stats count | addinfo | eval start=strftime('info_min_time', "%m/%d/%Y:%H:%M:%S") | return start] [| stats count | addinfo | eval end=strftime('info_max_time', "%m/%d/%Y:%H:%M:%S")\
    +| return end] increment=5m | eval _time=starttime | eval hostname="$host$"\
    +| timechart span=5m count by hostname | untable _time hostname count | fields - count ]\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_LPAR date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(lpar_pool_vp_usage) AS pool_usage, max(poolCPUs) AS poolCPUs, avg(lower_baseline_avg_pool_usage) AS lower, avg(baseline_avg_pool_usage) AS predicted, avg(upper_baseline_avg_pool_usage) AS upper\
    +| eval _lower = "lower" | eval _predicted = "predicted" | eval _upper = "upper"
    +iseval = 0
    +
    +# Pool CPU usage with lower, average and upper baseline (predict command rendering) - no future charting
    +[nmon_pool_usage_full_baseline(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.* host="$host$" by OStype, metric_name, host span=5m\
    +| `def_all_os_lpar_pool_load_cores`\
    +| rename host AS hostname\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_LPAR date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(lpar_pool_vp_usage) AS pool_usage, max(poolCPUs) AS poolCPUs, avg(lower_baseline_avg_pool_usage) AS lower, avg(baseline_avg_pool_usage) AS predicted, avg(upper_baseline_avg_pool_usage) AS upper\
    +| eval _lower = "lower" | eval _predicted = "predicted" | eval _upper = "upper"
    +iseval = 0
    +
    +#
    +# MEM
    +# Average Real and Virtual Memory usage, relevant for ALL OS
    +#
    +
    +# Real Memory Usage (in percentage) with simple baseline - future charting capabable
    +[nmon_real_mem_simple_baseline_future(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` (host=$host$) by OStype, metric_name, host span=5m\
    +| `def_memory_load_percent`\
    +| rename host AS hostname\
    +| append [ | gentimes [| stats count | addinfo | eval start=strftime('info_min_time', "%m/%d/%Y:%H:%M:%S") | return start] [| stats count | addinfo | eval end=strftime('info_max_time', "%m/%d/%Y:%H:%M:%S")\
    +| return end] increment=5m | eval _time=starttime | eval hostname="$host$"\
    +| timechart span=5m count by hostname | untable _time hostname count | fields - count ]\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_MEM date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(mem_used_effective_PCT) AS avg_real_mem, avg(baseline_avg_real_mem) AS baseline_avg_real_mem
    +iseval = 0
    +
    +# Real Memory Usage (in percentage) with simple baseline - no future charting
    +[nmon_real_mem_simple_baseline(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` (host=$host$) by OStype, metric_name, host span=5m\
    +| `def_memory_load_percent`\
    +| rename host AS hostname\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_MEM date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(mem_used_effective_PCT) AS avg_real_mem, avg(baseline_avg_real_mem) AS baseline_avg_real_mem
    +iseval = 0
    +
    +# Real Memory Usage (in percentage) with lower, average and upper baseline (predict command rendering) - future charting capable
    +[nmon_real_mem_full_baseline_future(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` (host=$host$) by OStype, metric_name, host span=5m\
    +| `def_memory_load_percent`\
    +| rename host AS hostname\
    +| append [ | gentimes [| stats count | addinfo | eval start=strftime('info_min_time', "%m/%d/%Y:%H:%M:%S") | return start] [| stats count | addinfo | eval end=strftime('info_max_time', "%m/%d/%Y:%H:%M:%S")\
    +| return end] increment=5m | eval _time=starttime | eval hostname="$host$"\
    +| timechart span=5m count by hostname | untable _time hostname count | fields - count ]\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_MEM date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(mem_used_effective_PCT) AS avg_real_mem, avg(lower_baseline_avg_real_mem) AS lower, avg(baseline_avg_real_mem) AS predicted, avg(upper_baseline_avg_real_mem) AS upper\
    +| eval _lower = "lower" | eval _predicted = "predicted" | eval _upper = "upper"
    +iseval = 0
    +
    +# Real Memory Usage (in percentage) with lower, average and upper baseline (predict command rendering) - no future charting
    +[nmon_real_mem_full_baseline(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` (host=$host$) by OStype, metric_name, host span=5m\
    +| `def_memory_load_percent`\
    +| rename host AS hostname\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_MEM date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(mem_used_effective_PCT) AS avg_real_mem, avg(lower_baseline_avg_real_mem) AS lower, avg(baseline_avg_real_mem) AS predicted, avg(upper_baseline_avg_real_mem) AS upper\
    +| eval _lower = "lower" | eval _predicted = "predicted" | eval _upper = "upper"
    +iseval = 0
    +
    +# Virtual Memory Usage (in percentage) with simple baseline - future charting capable
    +[nmon_virtual_mem_simple_baseline_future(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` (host=$host$) by OStype, metric_name, host span=5m\
    +| `def_memory_load_percent`\
    +| rename host AS hostname\
    +| append [ | gentimes [| stats count | addinfo | eval start=strftime('info_min_time', "%m/%d/%Y:%H:%M:%S") | return start] [| stats count | addinfo | eval end=strftime('info_max_time', "%m/%d/%Y:%H:%M:%S")\
    +| return end] increment=5m | eval _time=starttime | eval hostname="$host$"\
    +| timechart span=5m count by hostname | untable _time hostname count | fields - count ]\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_MEM date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(swap_used_effective_PCT) AS avg_virtual_mem, avg(baseline_avg_virtual_mem) AS baseline_avg_virtual_mem
    +iseval = 0
    +
    +# Virtual Memory Usage (in percentage) with simple baseline - no future charting
    +[nmon_virtual_mem_simple_baseline(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` (host=$host$) by OStype, metric_name, host span=5m\
    +| `def_memory_load_percent`\
    +| rename host AS hostname\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_MEM date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(swap_used_effective_PCT) AS avg_virtual_mem, avg(baseline_avg_virtual_mem) AS baseline_avg_virtual_mem
    +iseval = 0
    +
    +# Virtual Memory Usage (in percentage) with lower, average and upper baseline (predict command rendering) - future charting capable
    +[nmon_virtual_mem_full_baseline_future(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` (host=$host$) by OStype, metric_name, host span=5m\
    +| `def_memory_load_percent`\
    +| rename host AS hostname\
    +| append [ | gentimes [| stats count | addinfo | eval start=strftime('info_min_time', "%m/%d/%Y:%H:%M:%S") | return start] [| stats count | addinfo | eval end=strftime('info_max_time', "%m/%d/%Y:%H:%M:%S")\
    +| return end] increment=5m | eval _time=starttime | eval hostname="$host$"\
    +| timechart span=5m count by hostname | untable _time hostname count | fields - count ]\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_MEM date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(swap_used_effective_PCT) AS avg_virtual_mem, avg(lower_baseline_avg_virtual_mem) AS lower, avg(baseline_avg_virtual_mem) AS predicted, avg(upper_baseline_avg_virtual_mem) AS upper\
    +| eval _lower = "lower" | eval _predicted = "predicted" | eval _upper = "upper"
    +iseval = 0
    +
    +# Virtual Memory Usage (in percentage) with lower, average and upper baseline (predict command rendering) - no future charting
    +[nmon_virtual_mem_full_baseline(2)]
    +args= host,statsmode
    +definition = mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters` (host=$host$) by OStype, metric_name, host span=5m\
    +| `def_memory_load_percent`\
    +| rename host AS hostname\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_MEM date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(swap_used_effective_PCT) AS avg_virtual_mem, avg(lower_baseline_avg_virtual_mem) AS lower, avg(baseline_avg_virtual_mem) AS predicted, avg(upper_baseline_avg_virtual_mem) AS upper\
    +| eval _lower = "lower" | eval _predicted = "predicted" | eval _upper = "upper"
    +iseval = 0
    +
    +#
    +# DISKXFER
    +# Average Number of disk I/O per sec stats, relevant for ALL OS
    +#
    +
    +# Average IOPS with simple baseline - future charting capable
    +[nmon_iops_simple_baseline_future(2)]
    +args= host,statsmode
    +definition = mstats sum(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.storage.diskxfer OR metric_name=os.unix.nmon.storage.dgxfer host=$host$ by metric_name, host span=1m\
    +| `extract_metrics`\
    +| eval diskxfer_iops=case(metric_name=="os.unix.nmon.storage.diskxfer", value), dgxfer_iops=case(metric_name=="os.unix.nmon.storage.dgxfer", value)\
    +| stats max(diskxfer_iops) as diskxfer_iops, max(dgxfer_iops) as dgxfer_iops by _time, host\
    +| eval iops=if(isnum(dgxfer_iops), dgxfer_iops, diskxfer_iops)\
    +| bucket _time span=5m\
    +| stats avg(iops) as iops by _time, host\
    +| rename host AS hostname\
    +| append [ | gentimes [| stats count | addinfo | eval start=strftime('info_min_time', "%m/%d/%Y:%H:%M:%S") | return start] [| stats count | addinfo | eval end=strftime('info_max_time', "%m/%d/%Y:%H:%M:%S")\
    +| return end] increment=5m | eval _time=starttime | eval hostname="$host$"\
    +| timechart span=5m count by hostname | untable _time hostname count | fields - count ]\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_DISKXFER date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(iops) AS disk_iops, avg(baseline_avg_disk_iops) AS baseline_disk_iops
    +iseval = 0
    +
    +# Average IOPS with simple baseline - no future charting
    +[nmon_iops_simple_baseline(2)]
    +args= host,statsmode
    +definition = mstats sum(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.storage.diskxfer OR metric_name=os.unix.nmon.storage.dgxfer host=$host$ by metric_name, host span=1m\
    +| `extract_metrics`\
    +| eval diskxfer_iops=case(metric_name=="os.unix.nmon.storage.diskxfer", value), dgxfer_iops=case(metric_name=="os.unix.nmon.storage.dgxfer", value)\
    +| stats max(diskxfer_iops) as diskxfer_iops, max(dgxfer_iops) as dgxfer_iops by _time, host\
    +| eval iops=if(isnum(dgxfer_iops), dgxfer_iops, diskxfer_iops)\
    +| bucket _time span=5m\
    +| stats avg(iops) as iops by _time, host\
    +| rename host AS hostname\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_DISKXFER date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(iops) AS disk_iops, avg(baseline_avg_disk_iops) AS baseline_disk_iops
    +iseval = 0
    +
    +# Average IOPS with lower, average and upper baseline (predict command rendering) - future charting capable
    +[nmon_iops_full_baseline_future(2)]
    +args= host,statsmode
    +definition = mstats sum(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.storage.diskxfer OR metric_name=os.unix.nmon.storage.dgxfer host=$host$ by metric_name, host span=1m\
    +| `extract_metrics`\
    +| eval diskxfer_iops=case(metric_name=="os.unix.nmon.storage.diskxfer", value), dgxfer_iops=case(metric_name=="os.unix.nmon.storage.dgxfer", value)\
    +| stats max(diskxfer_iops) as diskxfer_iops, max(dgxfer_iops) as dgxfer_iops by _time, host\
    +| eval iops=if(isnum(dgxfer_iops), dgxfer_iops, diskxfer_iops)\
    +| bucket _time span=5m\
    +| stats avg(iops) as iops by _time, host\
    +| rename host AS hostname\
    +| append [ | gentimes [| stats count | addinfo | eval start=strftime('info_min_time', "%m/%d/%Y:%H:%M:%S") | return start] [| stats count | addinfo | eval end=strftime('info_max_time', "%m/%d/%Y:%H:%M:%S")\
    +| return end] increment=5m | eval _time=starttime | eval hostname="$host$"\
    +| timechart span=5m count by hostname | untable _time hostname count | fields - count ]\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_DISKXFER date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(iops) AS disk_iops,\
    +avg(lower_baseline_avg_disk_iops) AS lower, avg(baseline_avg_disk_iops) AS predicted, avg(upper_baseline_avg_disk_iops) AS upper\
    +| eval _lower = "lower" | eval _predicted = "predicted" | eval _upper = "upper"
    +iseval = 0
    +
    +# Average IOPS with lower, average and upper baseline (predict command rendering) - no future charting
    +[nmon_iops_full_baseline(2)]
    +args= host,statsmode
    +definition = mstats sum(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.storage.diskxfer OR metric_name=os.unix.nmon.storage.dgxfer host=$host$ by metric_name, host span=1m\
    +| `extract_metrics`\
    +| eval diskxfer_iops=case(metric_name=="os.unix.nmon.storage.diskxfer", value), dgxfer_iops=case(metric_name=="os.unix.nmon.storage.dgxfer", value)\
    +| stats max(diskxfer_iops) as diskxfer_iops, max(dgxfer_iops) as dgxfer_iops by _time, host\
    +| eval iops=if(isnum(dgxfer_iops), dgxfer_iops, diskxfer_iops)\
    +| bucket _time span=5m\
    +| stats avg(iops) as iops by _time, host\
    +| rename host AS hostname\
    +| eval date_wday=if(isnull(date_wday), lower(strftime('_time', "%A")), date_wday)\
    +| eval local_time=if(isnull(local_time), strftime('_time', "%H%M"), local_time)\
    +| lookup nmon_baseline_DISKXFER date_wday,local_time,hostname\
    +| timechart `baseline_span` $statsmode$(iops) AS disk_iops,\
    +avg(lower_baseline_avg_disk_iops) AS lower, avg(baseline_avg_disk_iops) AS predicted, avg(upper_baseline_avg_disk_iops) AS upper\
    +| eval _lower = "lower" | eval _predicted = "predicted" | eval _upper = "upper"
    +iseval = 0
    diff --git a/deployment-apps/metricator-for-nmon/default/metricator_for_nmon_settings.conf b/deployment-apps/metricator-for-nmon/default/metricator_for_nmon_settings.conf
    new file mode 100644
    index 0000000..e14b688
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/metricator_for_nmon_settings.conf
    @@ -0,0 +1 @@
    +[logging]
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/default/props.conf b/deployment-apps/metricator-for-nmon/default/props.conf
    new file mode 100644
    index 0000000..ac97066
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/props.conf
    @@ -0,0 +1,218 @@
    +# props.conf
    +
    +########################
    +# nmon metrics as events
    +########################
    +
    +[nmon_data]
    +
    +### frameID ###
    +
    +# frameID mapping:
    +
    +# The frameID mapping allows to group servers under a frameID label, globally available in every interface of the application
    +# Using a frameID to logically group servers will facilitate users selection and experience, specially when managing a large number of servers
    +
    +# Since the release 1.8.4, the mapping is operated using a KVstore collection, which you can manually edit using the provided management interface (see Settings menu)
    +# The update of the KVstore collection is now operated over the scheduled report "Generate NMON frameID mapping lookup table" which runs every hour by default
    +
    +# Generate the frameID mapping
    +LOOKUP-nmon_frameID_mapping = nmon_frameID_mapping serialnum AS serialnum, host as host OUTPUT frameID AS frameID, host_description as host_description
    +
    +# For nmon_data sent over http
    +[source::nmon_data:http]
    +KV_MODE=auto
    +
    +########################################
    +# CIM normalization / NMON extractions #
    +########################################
    +
    +# When applicable, be CIM compliant
    +
    +# Various CIM
    +FIELDALIAS-dest = host as dest
    +EVAL-hypervisor_id = if(isnotnull(frameID), frameID, serialnum)
    +
    +# UARG: map the command invocations fields with the TOP metric dimension name
    +FIELDALIAS-dimension_Command = ProgName as dimension_Command, COMM as dimension_Command
    +FIELDALIAS-dimension_PID = PID as dimension_PID
    +
    +#
    +# NMON EXTERNAL
    +#
    +
    +# uptime from nmon_external
    +
    +# extract the load average
    +EXTRACT-uptime_loadaverage = load[_\-\s]average:\s*(?<load_average_1min>[\d|\.]*);\s*(?<load_average_5min>[\d|\.]*);\s*(?<load_average_15min>[\d|\.]*)
    +
    +# extract the number of connected Unix users
    +EXTRACT-nb_users = (?<nb_users>\d*)[\_|\s]user
    +
    +# uptime
    +# Sic !!!
    +EXTRACT-uptime_days = \s{0,}[\d|\w|:]*[\s|_]*up[\s|_]*(?<uptime_days>\d*)[\s|_]*day[s|,|;]*[\s|_]*(?<uptime_dayshour>\d*):(?<uptime_daystime>\d*)
    +EXTRACT-uptime_days_only_alt = \s*\d\d:\d\d(?:s|AM|PM)\s*up\s*(?<uptime_days>\d*)\s*day
    +EXTRACT-uptime_days_with_min = \s{0,}[\d|\w|:]*[\s|_]*up[\s|_]*(?<uptime_days>\d*)[\s|_]*day[s|,|;]*[\s|_]*(?<uptime_daysmin>\d*)[\s|_]min
    +EXTRACT-uptime_days_with_min_alt = \s{0,}\d\d:\d\d(?:s|AM|PM)\s{0,}up\s{0,}(?<uptime_days>\d*)\s*(?:s|day)(?:s|days);\s{0,}(?<uptime_daysmin>\d*)\s{0,}(?:s|hr)(?:s|hrs)
    +EXTRACT-uptime_minutes = \s{0,}[\d|\w|:]*[\s|_]*up[\s|_]*(?<uptime_minutes>\d*)[\s|_]*min[\s|_]*[,|;]
    +EXTRACT-uptime_minutes_alt = \s*\d\d:\d\d(?:s|AM|PM)\s*up\s*(?<uptime_minutes>\d*)\s*(?:s|min)(?:s|mins)
    +EXTRACT-uptime_hours = \s{0,}[\d|\w|:]*[\s|_]*up[\s|_]*(?<uptime_hours>\d*:\d*)[\s|_]*[,|;]
    +EXTRACT-uptime_hours_alt = \s*\d\d:\d\d(?:s|AM|PM)\s*up\s*(?<uptime_hours>\d*)\s*hr
    +EXTRACT-uptime_hours_hours = \s{0,}[\d|\w|:]*[\s|_]*up[\s|_]*(?<uptime_hours_hours>\d*):\d*[\s|_]*[,|;]
    +EXTRACT-uptime_hours_minutes = \s{0,}[\d|\w|:]*[\s|_]*up[\s|_]*\d*:(?<uptime_hours_minutes>\d*)[\s|_]*[,|;]
    +EVAL-uptime_fromdays = (uptime_days*86400)
    +EVAL-uptime_fromminutes = (uptime_minutes*60)
    +EVAL-uptime_fromhours = (uptime_hours_hours*60*60) + (uptime_hours_minutes*60)
    +EVAL-uptime = case(isnotnull(uptime_daysmin) AND isnotnull(uptime_daysmin), ((uptime_days*86400)+(uptime_daysmin*60)),\
    +isnotnull(uptime_days) AND isnotnull(uptime_dayshour) AND isnotnull(uptime_daystime), ((uptime_days*86400)+(uptime_dayshour*3600)+(uptime_daystime*60)),\
    +isnotnull(uptime_minutes), (uptime_minutes*60),\
    +isnotnull(uptime_hours) AND isnotnull(uptime_hours_hours), (uptime_hours_hours*60*60) + (uptime_hours_minutes*60),\
    +isnotnull(uptime_hours), (uptime_hours*60*60),\
    +isnotnull(uptime_days), (uptime_days*86400) )
    +
    +#################
    +# nmon processing
    +#################
    +
    +[nmon_processing]
    +
    +# For TA-nmon
    +EXTRACT-splunk_home = (?i).+\w*\sRoot\sDirectory\s\(\$SPLUNK_HOME\)\:\s{0,}(?P<splunk_home>[a-zA-Z0-9\/\\\-\_\.\:]+)\s
    +
    +# For nmon-logger
    +EXTRACT-nmon_home = (?i).+\w*\sRoot\sDirectory\s\(\$NMON_VAR\)\:\s{0,}(?P<nmon_var>[a-zA-Z0-9\/\\\-\_\.\:]+)\s
    +EXTRACT-operating_system = (?i).+Guest\sOperating\sSystem\:\s{0,}(?P<operating_system>[a-zA-Z0-9]+)\s
    +EXTRACT-addon_type = (?i).*addon\s*type:\s.*\/(?<addon_type>[a-zA-Z0-9|\-\_]+)\s
    +EXTRACT-addon_version = (?i).+addon\sversion\:\s{0,}(?P<addon_version>[a-zA-Z0-9\.]+)\s
    +EXTRACT-python_version = (?i).+Python\sversion\:\s{0,}(?P<python_version>[a-zA-Z0-9\.]+)\s
    +EXTRACT-perl_version = (?i).+Perl\sversion\:\s{0,}(?P<perl_version>[a-zA-Z0-9\.]+)\s
    +EVAL-converter_inuse = case(isnotnull(python_version), "Python", isnotnull(perl_version), "Perl")
    +EVAL-interpreter_version = case(isnotnull(python_version), python_version, isnotnull(perl_version), perl_version)
    +EXTRACT-nmonparser_version = (?i).+nmonparser\sversion\:\s{0,}(?P<nmonparser_version>[0-9\.]+)\s
    +EXTRACT-hostname = (?i).+HOSTNAME\:\s{0,}(?P<hostname>[a-zA-Z0-9\-\_\.]+)
    +EXTRACT-nbr_lines = (?i).+Reading\sNMON\sdata:\s{0,}(?P<nbr_lines>\d+)\slines
    +EXTRACT-size_in_bytes = (?i).+lines\s(?P<size_in_bytes>\d+)\sbytes
    +EXTRACT-elapsed_in_seconds = (?i).+Elapsed\stime\swas\:\s{0,}(?P<elapsed_in_seconds>\d+\.\d+)\sseconds
    +EXTRACT-Nmon_version = (?i).+NMON\sVERSION\:\s{0,}(?P<Nmon_version>[a-zA-Z0-9\-\_\.\s]+)\s
    +EXTRACT-Time_of_Nmon_data = (?i).+TIME\sof\sNmon\sData\:\s{0,}(?P<Time_of_Nmon_Data>[0-9\:\.]+)\s
    +EXTRACT-Date_of_Nmon_data = (?i).+DATE\sof\sNmon\sData\:\s{0,}(?P<Date_of_Nmon_Data>[a-zA-Z0-9\-\/]+)\s
    +EXTRACT-INTERVAL = (?i).+INTERVAL\:\s{0,}(?P<INTERVAL>\d+)\s
    +EXTRACT-SNAPSHOTS = (?i).+SNAPSHOTS\:\s{0,}(?P<SNAPSHOTS>\d+)\s
    +EXTRACT-logical_cpus = (?i).+logical_cpus\:\s{0,}(?P<logical_cpus>\d+)\s
    +EXTRACT-virtual_cpus = (?i).+virtual_cpus\:\s{0,}(?P<virtual_cpus>\d+)\s
    +EXTRACT-Nmon_ID = (?i).+NMON\sID\:\s{0,}(?P<Nmon_ID>[a-zA-Z0-9\-\:\,\_\.]+)\s
    +EXTRACT-serial = (?i).+SerialNumber:\s{0,}(?P<serial>[a-zA-Z0-9\-\_]+)\s
    +
    +# Generate the frameID mapping
    +LOOKUP-nmon_frameID_mapping = nmon_frameID_mapping serialnum AS serial, host as host OUTPUT frameID AS frameID, host_description as host_description
    +
    +####################
    +# nmon config stanza
    +####################
    +
    +[nmon_config]
    +
    +# serial is extracted from the header added by the parsers.
    +# Notes: for AIX and PowerLinux, the serial number is as well available within the raw data
    +# unless it has been asked to do so, the parsers use the original serial for the header definition
    +EXTRACT-serial = CONFIG,[^,]*,[^,]*,(?P<serial>[a-zA-Z0-9\-\_]+)
    +
    +# Perform basic extractions
    +# Full extractions can be performed by calling associated macros, or using the data model
    +EXTRACT-AAA_OS = (?i),OS,(?P<AAA_OS>[^,]+)\s{0,}
    +EXTRACT-AIX_LEVEL = AAA,AIX,(?P<AIX_LEVEL>[a-zA-Z0-9\-\_\.]+)\s
    +EXTRACT-Linux_LEVEL = AAA,OS,Linux,(?P<Linux_LEVEL>[^,]+),
    +EXTRACT-Solaris_LEVEL = AAA,OS,Solaris,(?P<Solaris_LEVEL>[^,]+),
    +EVAL-OStype = case(AAA_OS == "Linux", "Linux", AAA_OS == "Solaris", "Solaris", isnotnull(AIX_LEVEL), "AIX", isnull(AAA_OS), "Unknown")
    +
    +# When applicable, be CIM compliant
    +
    +FIELDALIAS-dest = host as dest
    +EXTRACT-AAA_serial = AAA,SerialNumber,(?<AAA_serial>\w*)
    +EVAL-serial = if(isnotnull(AAA_serial), AAA_serial, host)
    +EVAL-hypervisor_id = if(isnotnull(AAA_serial), AAA_serial, hostname)
    +EVAL-hypervisor = if(isnotnull(AAA_serial), AAA_serial, hostname)
    +
    +# family
    +EXTRACT-AIX_processor_type = BBB\w*,[^,]+,lsconf,\"Processor\sType:\s(?<AIX_processor_type>\w*)\"
    +EXTRACT-Linux_processor_type = AAA,OS,Linux,[^,]+,[^,]+,(?<Linux_processor_type>\w*)
    +EXTRACT-Solaris_processor_type = BBB.+,[0-9].+psrinfo\s\-pv,\"\s+(?P<Solaris_processor_type>[\w\-\_]*)\s*\(.+\"
    +EVAL-family = case(isnotnull(Linux_LEVEL), Linux_processor_type, isnotnull(Solaris_LEVEL), Solaris_processor_type, isnotnull(AIX_LEVEL), AIX_processor_type)
    +
    +# Vendor / Product
    +EXTRACT-Linux_release_distribution = BBB\w*,[^,]*,.+etc+.release,\"(?!LSB_VERSION|DISTRIB|NAME|ID|VERSION)(?P<Linux_release_distribution>[^,]+)\"
    +EXTRACT-Linux_lsb_distribution = BBB\w*,[^,]*,lsb_release,\"Description:\s*(?<Linux_lsb_distribution>[^,]*)\"
    +EVAL-Linux_distribution = if(isnotnull(Linux_lsb_distribution), Linux_lsb_distribution, Linux_release_distribution)
    +EXTRACT-Solaris_version = BBB\w*,[^,]*,.+etc+.release,\"\s+(?P<Solaris_version>Oracle\s*Solaris\s[^\"]*)\"
    +EVAL-AIX_version = case(isnotnull(AIX_LEVEL), "IBM AIX" + " " + AIX_LEVEL)
    +
    +EVAL-vendor_product = case(isnotnull(Linux_LEVEL), (if(isnotnull(Linux_lsb_distribution), Linux_lsb_distribution, Linux_release_distribution)), isnotnull(Solaris_LEVEL), Solaris_version, isnotnull(AIX_LEVEL), "IBM AIX " + 'AIX_LEVEL' )
    +EVAL-version = case(isnotnull(Linux_LEVEL), Linux_LEVEL, isnotnull(Solaris_LEVEL), Solaris_LEVEL, isnotnull(AIX_LEVEL), AIX_LEVEL )
    +EVAL-os = case(isnotnull(Linux_LEVEL), (if(isnotnull(Linux_lsb_distribution), Linux_lsb_distribution, Linux_release_distribution)), isnotnull(Solaris_LEVEL), Solaris_version, isnotnull(AIX_LEVEL), "IBM AIX " + 'AIX_LEVEL' )
    +
    +# CPU
    +EXTRACT-AIX_virtualcpus = BBB\w*,[^,]+,lparstat\s-i,\"Online\sVirtual\sCPUs\s*:\s*(?<AIX_virtualcpus>\d*)\"
    +EXTRACT-cpu_cores_position1 = AAA,cpus,(?P<cpu_cores_position1>\d+)
    +EXTRACT-cpu_cores_position2 = AAA,cpus,\d+,(?P<cpu_cores_position2>\d+)
    +EVAL-cpu_cores_combo = AIX_virtualcpus . " / " . cpu_cores_position2
    +
    +EVAL-cpu_cores = if(isnotnull(AIX_virtualcpus), AIX_virtualcpus, cpu_cores_position1)
    +EVAL-cpu_count = case(isnotnull(AIX_LEVEL), AIX_virtualcpus, isnotnull(Solaris_LEVEL), cpu_cores_position1, isnotnull(Linux_LEVEL), cpu_cores_position1)
    +
    +EXTRACT-Solaris_processor_clockspeed = BBB.+,[0-9].+psrinfo\s\-pv,.+clock\s(?P<Solaris_processor_clockspeed>[\d\.]*)\s*\w*\)\"
    +EXTRACT-Linux_processor_clockspeed_1 = AAA,[^,]+,MHz,(?P<Linux_processor_clockspeed_1>[\d\.]*)
    +EXTRACT-Linux_processor_clockspeed_2 = BBB\w*,[^,]+,/proc/cpuinfo,\"cpu\s*MHz\s*:\s*(?<Linux_processor_clockspeed_2>[\d\.]*)\"
    +EXTRACT-Linux_processor_clockspeed_3 = BBB\w*,[^,]+,/proc/cpuinfo,\"clock\s{0,}:\s{0,}(?<Linux_processor_clockspeed_3>[\d|\.]*)\s{0,}MHz\"
    +EXTRACT-AIX_processor_clockspeed = BBBP,[^,]+,lsconf,"Processor\sClock\sSpeed:\s*(?<AIX_processor_clockspeed>[\d\.]*)\sMHz
    +EVAL-cpu_mhz = case(isnotnull(Linux_LEVEL), case(isnotnull(Linux_processor_clockspeed_1), Linux_processor_clockspeed_1, isnotnull(Linux_processor_clockspeed_2), Linux_processor_clockspeed_2, isnotnull(Linux_processor_clockspeed_3), Linux_processor_clockspeed_3), isnotnull(Solaris_LEVEL), Solaris_processor_clockspeed, isnotnull(AIX_LEVEL), AIX_processor_clockspeed)
    +
    +EXTRACT-Linux_realmemory_KB = BBB\w*,[^,]*,/proc/meminfo,\"MemTotal:\s*(?<Linux_realmemory_KB>\d*)\s*kB\"
    +EXTRACT-Solaris_realmemory_KB = BBB\w*,[^,]*,prtdiag,\"Memory\s*size:\s*(?<Solaris_realmemory_MB>\d*)\sMegabytes\"
    +EXTRACT-AIX_realmemory_online_MB = BBB\w*,[^,]*,online\s*Memory,(?<AIX_realmemory_online_MB>\d*)
    +EXTRACT-AIX_realmemory_lsconf_MB = BBB\w*,[^,]*,lsconf,\"Memory\s*Size:\s*(?<AIX_realmemory_lsconf_MB>\d*)\s*MB\"
    +EVAL-mem = case(isnotnull(Linux_LEVEL), round((Linux_realmemory_KB/1024),0), isnotnull(Solaris_LEVEL), Solaris_realmemory_MB, isnotnull(AIX_realmemory_online_MB), if(isnotnull(AIX_realmemory_online_MB), AIX_realmemory_online_MB, AIX_realmemory_lsconf_MB) )
    +
    +# Not in CIM
    +EXTRACT-Linux_swapmemory_KB = BBB\w*,[^,]*,/proc/meminfo,\"SwapTotal:\s*(?<Linux_swapmemory_KB>\d*)\s*kB\"
    +
    +# Processor extraction
    +EXTRACT-AIX_processor = BBB\w*,[0-9]*,lsconf,\"Processor\s*Type:\s*(?P<AIX_processor>[^\"]*)\"
    +EXTRACT-Linux_arch = BBB\w*,[0-9]*,lscpu,\"(Architecture)\s*:\s+(?P<Linux_arch>[^\"]*)\"
    +EXTRACT-Linux_processor_lscpu = BBB\w*,[0-9]*,lscpu,\"(Model\sname|Model|Vendor\sID)\s*:\s*(?P<Linux_processor_lscpu>[^\"]*)\"
    +EXTRACT-Linux_processor_cpuinfo = BBB\w*,[0-9].*cpuinfo,\"(model\sname)\s*:\s*(?P<Linux_processor_cpuinfo>[^\"]*)\"
    +EXTRACT-Solaris_processor_primary = BBB.+,[0-9].+psrinfo\s\-pv,\"\s+(?P<Solaris_processor_primary>.+)\s*\(.+clock.+\"
    +EXTRACT-Solaris_processor_alt = BBB.+,[0-9].+prtdiag,\"0\s*(?<Solaris_processor_clock_alt>[\d|\.]*\s*\w*)\s*(?P<Solaris_processor_alt>[\w|-]*)\s*
    +EVAL-processor = case(isnotnull(AIX_LEVEL), AIX_processor, AAA_OS == "Solaris", case(isnotnull(Solaris_processor_primary), Solaris_processor_primary, isnotnull(Solaris_processor_alt), Solaris_processor_alt), AAA_OS == "Linux", case(isnotnull(Linux_processor_lscpu), Linux_processor_lscpu + " (arch: " + Linux_arch + ")" , isnull(Linux_processor_lscpu), Linux_processor_cpuinfo) )
    +
    +# uptime
    +# Sic !!!
    +EXTRACT-uptime_days = \s{0,}[\d|\w|:]*[\s|_]*up[\s|_]*(?<uptime_days>\d*)[\s|_]*day[s|,|;]*[\s|_]*(?<uptime_dayshour>\d*):(?<uptime_daystime>\d*)
    +EXTRACT-uptime_days_only_alt = \s*\d\d:\d\d(?:s|AM|PM)\s*up\s*(?<uptime_days>\d*)\s*day
    +EXTRACT-uptime_days_with_min = \s{0,}[\d|\w|:]*[\s|_]*up[\s|_]*(?<uptime_days>\d*)[\s|_]*day[s|,|;]*[\s|_]*(?<uptime_daysmin>\d*)[\s|_]min
    +EXTRACT-uptime_days_with_min_alt = \s{0,}\d\d:\d\d(?:s|AM|PM)\s{0,}up\s{0,}(?<uptime_days>\d*)\s*(?:s|day)(?:s|days);\s{0,}(?<uptime_daysmin>\d*)\s{0,}(?:s|hr)(?:s|hrs)
    +EXTRACT-uptime_minutes = \s{0,}[\d|\w|:]*[\s|_]*up[\s|_]*(?<uptime_minutes>\d*)[\s|_]*min[\s|_]*[,|;]
    +EXTRACT-uptime_minutes_alt = \s*\d\d:\d\d(?:s|AM|PM)\s*up\s*(?<uptime_minutes>\d*)\s*(?:s|min)(?:s|mins)
    +EXTRACT-uptime_hours = \s{0,}[\d|\w|:]*[\s|_]*up[\s|_]*(?<uptime_hours>\d*:\d*)[\s|_]*[,|;]
    +EXTRACT-uptime_hours_alt = \s*\d\d:\d\d(?:s|AM|PM)\s*up\s*(?<uptime_hours>\d*)\s*hr
    +EXTRACT-uptime_hours_hours = \s{0,}[\d|\w|:]*[\s|_]*up[\s|_]*(?<uptime_hours_hours>\d*):\d*[\s|_]*[,|;]
    +EXTRACT-uptime_hours_minutes = \s{0,}[\d|\w|:]*[\s|_]*up[\s|_]*\d*:(?<uptime_hours_minutes>\d*)[\s|_]*[,|;]
    +EVAL-uptime_fromdays = (uptime_days*86400)
    +EVAL-uptime_fromminutes = (uptime_minutes*60)
    +EVAL-uptime_fromhours = (uptime_hours_hours*60*60) + (uptime_hours_minutes*60)
    +EVAL-uptime = case(isnotnull(uptime_daysmin) AND isnotnull(uptime_daysmin), ((uptime_days*86400)+(uptime_daysmin*60)),\
    +isnotnull(uptime_days) AND isnotnull(uptime_dayshour) AND isnotnull(uptime_daystime), ((uptime_days*86400)+(uptime_dayshour*3600)+(uptime_daystime*60)),\
    +isnotnull(uptime_minutes), (uptime_minutes*60),\
    +isnotnull(uptime_hours) AND isnotnull(uptime_hours_hours), (uptime_hours_hours*60*60) + (uptime_hours_minutes*60),\
    +isnotnull(uptime_hours), (uptime_hours*60*60),\
    +isnotnull(uptime_days), (uptime_days*86400) )
    +
    +# CIM Network
    +REPORT-inventory_network_extractions = inventory_network_interface, inventory_network_ip, inventory_network_mac
    +
    +# Generate the frameID mapping
    +LOOKUP-nmon_frameID_mapping = nmon_frameID_mapping serialnum AS serial, host as host OUTPUT frameID AS frameID, host_description as host_description
    +
    +# For nmon_config sent over http
    +[source::nmon_config:http]
    +KV_MODE=none
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/default/restmap.conf b/deployment-apps/metricator-for-nmon/default/restmap.conf
    new file mode 100644
    index 0000000..f47648c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/restmap.conf
    @@ -0,0 +1,11 @@
    +
    +[admin:metricator_for_nmon]
    +match = /
    +members = metricator_for_nmon_settings
    +
    +[admin_external:metricator_for_nmon_settings]
    +handlertype = python
    +python.version = python3
    +handlerfile = metricator_for_nmon_rh_settings.py
    +handleractions = edit, list
    +handlerpersistentmode = true
    diff --git a/deployment-apps/metricator-for-nmon/default/savedsearches.conf b/deployment-apps/metricator-for-nmon/default/savedsearches.conf
    new file mode 100644
    index 0000000..9f728ff
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/savedsearches.conf
    @@ -0,0 +1,1284 @@
    +
    +############################################################
    +#	Simple search used in Home page to show
    +#	numbers of hosts indexed within last 7 days
    +############################################################
    +
    +# Since version 1.9.7, and for run time optimization purposes, we use link this search with a KVstore base lookup table
    +# The lookup is used to store the state day after day, such that we can provide the same features that a full 7 days
    +# time range but having a search running on the current day only
    +# At large scale, the original tstats search could run up to 30 seconds which is too much for a good user experience
    +# As such, the number of hosts reported is the global number of hosts and linked anymore to the user context.
    +
    +[Hosts with data within last 7 days]
    +dispatch.earliest_time = -1d@d
    +dispatch.latest_time = now
    +display.general.type = visualizations
    +display.page.search.tab = visualizations
    +display.visualizations.singlevalue.colorBy = trend
    +display.visualizations.singlevalue.rangeColors = ["0x65a637","0x6db7c6","0xf7bc38","0xf58f39","0xd93f3c"]
    +display.visualizations.singlevalue.rangeValues = [0,30,70,100]
    +display.visualizations.singlevalue.trendInterval = auto
    +display.visualizations.singlevalue.underLabel = Hosts with recent activity
    +display.visualizations.singlevalue.useColors = 1
    +display.visualizations.singlevalueHeight = 173
    +display.visualizations.type = singlevalue
    +search = | mstats count(_value) as count where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.*" by host span=1d | stats dc(host) as dcount by _time\
    +| append\
    +[ | inputlookup nmon_hosts_last_7days ]\
    +|  eval time_limit=relative_time(now(), "-7d@d")\
    +|  where _time>time_limit\
    +|  stats max(dcount) as dcount by _time\
    +|  sort 0 _time
    +
    +# This scheduled report will fill the KVstore based lookup table for previous days
    +[Hosts with data within last 7 days (fill the nmon_hosts_last_7days lookup)]
    +cron_schedule = 1 * * * *
    +dispatch.earliest_time = -7d@d
    +dispatch.latest_time = now
    +display.general.type = visualizations
    +display.page.search.tab = visualizations
    +display.visualizations.singlevalue.colorBy = trend
    +display.visualizations.singlevalue.rangeColors = ["0x65a637","0x6db7c6","0xf7bc38","0xf58f39","0xd93f3c"]
    +display.visualizations.singlevalue.rangeValues = [0,30,70,100]
    +display.visualizations.singlevalue.trendInterval = auto
    +display.visualizations.singlevalue.underLabel = Hosts with recent activity
    +display.visualizations.singlevalue.useColors = 1
    +display.visualizations.singlevalueHeight = 173
    +display.visualizations.type = singlevalue
    +enableSched = 1
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +schedule_window = 15
    +search = | mstats count(_value) as count where `nmon_metrics_index` metric_name="os.unix.nmon.cpu.cpu_all.*" by host span=1d | stats dc(host) as dcount by _time\
    +|  outputlookup nmon_hosts_last_7days | stats count
    +
    +#############################################################
    +# Total Cost of Ownership
    +#############################################################
    +
    +[Volume of data indexed within last 7 days]
    +alert.digest_mode = 1
    +auto_summarize = 1
    +auto_summarize.dispatch.earliest_time = -7d@d
    +dispatch.earliest_time = -7d@d
    +dispatch.latest_time = now
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +search = index=_internal source=*license_usage.log* type=Usage `nmon_idx`\
    +| bucket _time span=2m\
    +| stats sum(b) as volume by _time\
    +| eval volume=round((volume/1024/1024), 2)\
    +| where volume>0
    +
    +[TCO - Volume indexing over time]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +description = Volume of data (GB) indexed per day
    +dispatch.earliest_time = -30d
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = visualizations
    +display.page.search.mode = fast
    +display.page.search.tab = visualizations
    +display.statistics.show = 0
    +display.visualizations.chartHeight = 565
    +display.visualizations.charting.legend.placement = top
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = index=_internal source=*license_usage.log* type=Usage `nmon_idx` | where b>0 | bucket _time span=1m | stats sum(b) AS b by _time,idx | timechart span=1d sum(b) AS b | eval volume_per_day_GB=round((b/1024/1024/1024),2) | eval user_is_admin=True | fields _time,volume_per_day_GB
    +
    +[TCO - Total Cost of Ownership per server]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +description = Total Cost of Ownership, per hour/server and estimated per day/server licencing cost
    +dispatch.earliest_time = -7d@d
    +dispatch.latest_time = @h
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.mode = fast
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 565
    +display.visualizations.charting.chart = pie
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = index=_internal source=*license_usage.log* type=Usage `nmon_idx` | where b>0 | timechart span=1h sum(b) AS b  | eval volume_MB = round(b/1024/1024,2) | fillnull value=0\
    +| appendcols [ | mstats max(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.logical_cpus by host span=1h\
    +| stats dc(host) as dcount by _time ]\
    +| eval cost_per_server_MB=(volume_MB/dcount) | stats avg(cost_per_server_MB) AS cost_per_server_MB | eval cost_per_server_MB=round(cost_per_server_MB, 2), estimated_cost_per_server_MB=round(cost_per_server_MB*24, 2)\
    +| rename cost_per_server_MB AS "per hour/server cost in MB", estimated_cost_per_server_MB AS "estimated per day/server cost in MB"
    +
    +[TCO - Total Cost of Ownership of global indexing]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -7d@d
    +dispatch.latest_time = @d
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.mode = fast
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 565
    +display.visualizations.charting.chart = pie
    +display.visualizations.show = 0
    +description = Average volume of data (GB) indexed per day
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = index=_internal source=*license_usage.log* type=Usage `nmon_idx` | where b>0 | timechart span=1d sum(b) AS b | fillnull value=0 | stats avg(b) AS avg_volume_per_day | eval avg_volume_per_day_GB=round((avg_volume_per_day/1024/1024/1024),2) | fields avg_volume_per_day_GB
    +
    +[TCO - Scheduling reporting]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -30d
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.mode = fast
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 565
    +display.visualizations.charting.chart = pie
    +display.visualizations.show = 0
    +description = Detailed reporting of scheduling searches cost
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = index=_internal host="*" source=*scheduler.log status="*" NOT (status="continued" OR status=delegated*) savedsearch_name!="*_ACCELERATE_*" app="nmon"\
    +| stats avg(run_time) AS avg_run_time, max(run_time) AS max_run_time, latest(run_time) AS latest_run_time, max(_time) AS "last_run (dd/mm/YYYY H:M:S)" by app,savedsearch_name\
    +| eval "last_run (dd/mm/YYYY H:M:S)"=strftime('last_run (dd/mm/YYYY H:M:S)', "%d/%m/%Y %H:%M:%S") | foreach *_run_time [ eval <<FIELD>>=round('<<FIELD>>', 2) ]\
    +| sort savedsearch_name | rename savedsearch_name AS "report (savedsearch_name)"\
    +| eval duration_avg=tostring(avg_run_time, "duration"), duration_max=tostring(max_run_time, "duration"), duration_latest=tostring(latest_run_time, "duration")\
    +| eval "Avg run time (seconds / duration)" = avg_run_time + " sec / " + duration_avg + " (HH:MM:SSS)"\
    +| eval "Max run time (seconds / duration)" = max_run_time + " sec / " + duration_avg + " (HH:MM:SSS)"\
    +| eval "Latest run time (seconds / duration)" = latest_run_time + " sec / " + duration_avg + " (HH:MM:SSS)"\
    +| fields app,report*,Avg*,Max*,Latest*,"last_run (dd/mm/YYYY H:M:S)"
    +
    +[TCO - Eventcount / Metadata Statistics: Indexes first and last event dates]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +description = Date of first and last event per sourcetype
    +dispatch.earliest_time = 0
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 565
    +display.visualizations.charting.chart = pie
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | `indexes_datestats` | eval show_eventcount=true | fields index,sourcetype,*Event
    +
    +[TCO - Index storage and buckets details]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = 0
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 565
    +display.visualizations.charting.chart = pie
    +display.visualizations.show = 0
    +description = Nmon index detailed statistics
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | dbinspect `nmon_index` | eval rawSize_MB=(rawSize/1024/1024) | stats sum(rawSize_MB) AS rawSize_MB, sum(sizeOnDiskMB) AS sizeOnDiskMB, dc(bucketId) AS dcount_bucket | eval compress_ratio = round(rawSize_MB / sizeOnDiskMB, 2)." : 1" | eval rawSize_GB=round(rawSize_MB/1024, 2), sizeOnDiskGB=round(sizeOnDiskMB/1024, 2) | eval avg_size_perbucket_GB=round(((sizeOnDiskMB/dcount_bucket)/1024), 2)
    +
    +#############################################################
    +# NMON Inventory
    +#############################################################
    +
    +# This report will generate the inventory lookup table used in many interfaces of the App.
    +# We arbitrary only keep one result per day and per host of the nmon_config sourcetype, then we keep the last value by field in case of multiple values found, typically an hardware configuration
    +# change
    +
    +[Generate NMON Inventory Lookup Table]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.digest_mode = True
    +alert.suppress = 0
    +alert.track = 0
    +auto_summarize = 0
    +auto_summarize.dispatch.earliest_time =
    +cron_schedule = 0 * * * *
    +description = Generation of NMON Inventory Lookup Table
    +dispatch.earliest_time = -48h
    +dispatch.latest_time = now
    +dispatch.ttl = 3600 # Keep 1 hour this job artifact
    +display.events.fields = ["host","source","sourcetype","hostname"]
    +display.events.type = raw
    +display.general.type = statistics
    +display.statistics.drilldown = none
    +display.statistics.rowNumbers = 1
    +display.visualizations.chartHeight = 420
    +display.visualizations.charting.chart = line
    +display.visualizations.charting.chart.style = minimal
    +display.visualizations.show = 0
    +display.visualizations.type = singlevalue
    +enableSched = 1
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +schedule_window = 15
    +search = | `nmon_inventory_update`\
    +|  append\
    +[ |  inputlookup nmon_inventory ]\
    +|  where OStype!="NA"\
    +|  eval _time=strptime(reporting_date, "%m/%d/%Y %H:%M"), limit=relative_time(now(), "-30d@d")\
    +|  where _time>=limit\
    +|  stats latest(*) as "*" by hostname\
    +|  fields - _time,limit\
    +| outputlookup nmon_inventory | stats count
    +
    +#############################################################
    +# NMON frameID mapping
    +#############################################################
    +
    +# Update the frameID mapping KVstore collection
    +# This report runs every hour by default, in addition it will also run on Splunk startup to ensure
    +# we populate the collection if required to prevent the frameID field from being null if not complete (this affects only SPL searches, not searches against data models)
    +
    +[Generate NMON frameID mapping lookup table]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +cron_schedule = 0 * * * *
    +description = This scheduled report will update the frameID mapping KVstore collection
    +dispatch.earliest_time = -7d@h
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.statistics.drilldown = none
    +display.visualizations.chartHeight = 524
    +display.visualizations.charting.chart = line
    +display.visualizations.show = 0
    +display.visualizations.type = singlevalue
    +enableSched = 1
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +schedule_window = 5
    +run_on_startup = true
    +search = | mcatalog values(serialnum) as serials where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.cpu_all.logical_cpus by host\
    +| rename serials as serialnum\
    +| lookup nmon_frameID_mapping host as host OUTPUT frameID\
    +| eval frameID=if(isnull(frameID), serialnum, frameID)\
    +| fields frameID, serialnum, host\
    +| lookup nmon_frameID_mapping serialnum AS serialnum, host as host OUTPUT host_description as host_description\
    +| fillnull value="none"\
    +| fields frameID,serialnum,host,host_description\
    +| search NOT [ | inputlookup nmon_frameID_mapping | fields host ]\
    +| outputlookup nmon_frameID_mapping append=t key_field=_key\
    +| stats count
    +
    +#############################################################
    +# NMON Baseline
    +#############################################################
    +
    +# These reports will generate the Nmon baseline and store results in nmon_baseline KV Store collections
    +# By default, schedules runs every sunday starting at midnight
    +
    +[Generate NMON Baseline KV Collection for CPU_ALL]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +cron_schedule = 0 0 * * 0
    +dispatch.earliest_time = -3mon@d
    +dispatch.latest_time = @d
    +dispatch.ttl = 3600 # Keep 1 hour this job artifact
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.enablePreview = 0
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 563
    +display.visualizations.charting.chart = line
    +display.visualizations.show = 0
    +enableSched = 1
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +schedule_window = 60
    +search = | mstats avg(_value) as value where `nmon_metrics_index` (metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT) by metric_name, host span=5m\
    +| `def_cpu_load_percent`\
    +| `mapping_frameID`\
    +| rename host as hostname\
    +| fields _time, frameID, hostname, cpu_load_percent\
    +| where isnotnull(cpu_load_percent)\
    +| eval date_wday=lower(strftime('_time', "%A")), local_time=strftime('_time', "%H%M")\
    +| stats perc05(cpu_load_percent) AS lower_baseline_avg_cpu, avg(cpu_load_percent) AS baseline_avg_cpu, perc95(cpu_load_percent) AS upper_baseline_avg_cpu by date_wday,local_time,frameID,hostname\
    +| foreach *baseline* [ eval <<FIELD>> = round(<<FIELD>>, 2) ]\
    +| eval ID=frameID + "_" + hostname + "_" + date_wday + "_" + local_time | table ID, date_wday, local_time, frameID, hostname, *\
    +| eval _key=ID\
    +| outputlookup nmon_baseline_CPU_ALL | stats count
    +
    +[Generate NMON Baseline KV Collection for LPAR]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +cron_schedule = 0 1 * * 0
    +dispatch.earliest_time = -3mon@d
    +dispatch.latest_time = @d
    +dispatch.ttl = 3600 # Keep 1 hour this job artifact
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.enablePreview = 0
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 563
    +display.visualizations.charting.chart = line
    +display.visualizations.show = 0
    +enableSched = 1
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +schedule_window = 60
    +search = | mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.cpu.lpar.* by OStype, metric_name, host span=5m\
    +| `def_all_os_lpar_load_and_pool_load_cores`\
    +| `mapping_frameID`\
    +| rename host AS hostname\
    +| fields _time, frameID, hostname, lpar_load_cores, lpar_pool_vp_usage\
    +| where isnotnull(lpar_load_cores)\
    +| eval date_wday=lower(strftime('_time', "%A")), local_time=strftime('_time', "%H%M")\
    +| stats\
    +perc05(lpar_load_cores) AS lower_baseline_avg_vp_usage, avg(lpar_load_cores) AS baseline_avg_vp_usage, perc95(lpar_load_cores) AS upper_baseline_avg_vp_usage,\
    +perc05(lpar_pool_vp_usage) AS lower_baseline_avg_pool_usage, avg(lpar_pool_vp_usage) AS baseline_avg_pool_usage, perc95(lpar_pool_vp_usage) AS upper_baseline_avg_pool_usage,\
    +by date_wday,local_time,frameID,hostname\
    +| foreach *baseline* [ eval <<FIELD>> = round(<<FIELD>>, 2) ] \
    +| eval ID=frameID + "_" + hostname + "_" + date_wday + "_" + local_time | fields ID, date_wday, local_time, frameID, hostname, *\
    +| eval _key=ID\
    +| outputlookup nmon_baseline_LPAR | stats count
    +
    +[Generate NMON Baseline KV Collection for MEM]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +cron_schedule = 0 2 * * 0
    +dispatch.earliest_time = -3mon@d
    +dispatch.latest_time = @d
    +dispatch.ttl = 3600 # Keep 1 hour this job artifact
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.enablePreview = 0
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 563
    +display.visualizations.charting.chart = line
    +display.visualizations.show = 0
    +enableSched = 1
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +schedule_window = 60
    +search = | mstats avg(_value) as value where `nmon_metrics_index` `def_memory_all_os_metric_filters`  by OStype, metric_name, host span=5m\
    +| `def_memory_load_percent`\
    +| `mapping_frameID`\
    +| rename host AS hostname\
    +| fields _time, frameID, hostname, mem_used_effective_PCT, swap_used_effective_PCT\
    +| where isnotnull(mem_used_effective_PCT)\
    +| eval date_wday=lower(strftime('_time', "%A")), local_time=strftime('_time', "%H%M")\
    +| stats\
    +perc05(mem_used_effective_PCT) AS lower_baseline_avg_real_mem, avg(mem_used_effective_PCT) AS baseline_avg_real_mem, perc95(mem_used_effective_PCT) AS upper_baseline_avg_real_mem,\
    +perc05(swap_used_effective_PCT) AS lower_baseline_avg_virtual_mem, avg(swap_used_effective_PCT) AS baseline_avg_virtual_mem, perc95(swap_used_effective_PCT) AS upper_baseline_avg_virtual_mem,\
    +by date_wday,local_time,frameID,hostname\
    +| foreach *baseline* [ eval <<FIELD>> = round(<<FIELD>>, 2) ]\
    +| outputlookup nmon_baseline_MEM | stats count
    +
    +[Generate NMON Baseline KV Collection for DISKXFER]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +cron_schedule = 0 3 * * 0
    +dispatch.earliest_time = -3mon@d
    +dispatch.latest_time = @d
    +dispatch.ttl = 3600 # Keep 1 hour this job artifact
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.enablePreview = 0
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 563
    +display.visualizations.charting.chart = line
    +display.visualizations.show = 0
    +enableSched = 1
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +schedule_window = 60
    +search = | mstats avg(_value) as value where `nmon_metrics_index` metric_name=os.unix.nmon.storage.diskxfer OR metric_name=os.unix.nmon.storage.dgxfer by metric_name, host span=1m\
    +| `extract_metrics`\
    +| eval diskxfer_iops=case(metric_name=="os.unix.nmon.storage.diskxfer", value), dgxfer_iops=case(metric_name=="os.unix.nmon.storage.dgxfer", value)\
    +| stats max(diskxfer_iops) as diskxfer_iops, max(dgxfer_iops) as dgxfer_iops by _time, host\
    +| eval iops=if(isnum(dgxfer_iops), dgxfer_iops, diskxfer_iops)\
    +| bucket _time span=5m\
    +| stats avg(iops) as iops by _time, host\
    +| `mapping_frameID`\
    +| rename host AS hostname\
    +| where isnotnull(iops)\
    +| eval date_wday=lower(strftime('_time', "%A")), local_time=strftime('_time', "%H%M")\
    +| stats perc05(iops) AS lower_baseline_avg_disk_iops, avg(iops) AS baseline_avg_disk_iops, perc95(iops) AS upper_baseline_avg_disk_iops by date_wday,local_time,frameID,hostname\
    +| foreach *baseline* [ eval <<FIELD>> = round(<<FIELD>>, 2) ]\
    +| eval ID=frameID + "_" + hostname + "_" + date_wday + "_" + local_time | fields ID, date_wday, local_time, frameID, hostname, *\
    +| eval _key=ID\
    +| outputlookup nmon_baseline_DISKXFER | stats count
    +
    +####################################################################
    +# Number of notable events in data processing and collect
    +####################################################################
    +
    +[Number of notable events in Data Processing or Data Collect since last 24 Hours]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.digest_mode = True
    +alert.suppress = 0
    +alert.track = 0
    +auto_summarize = 1
    +auto_summarize.dispatch.earliest_time = -1d@h
    +dispatch.earliest_time = -24h
    +dispatch.latest_time = now
    +dispatch.ttl = 600 # Keep 10m this job artifact
    +display.general.type = statistics
    +display.page.search.mode = fast
    +display.statistics.drilldown = none
    +display.statistics.rowNumbers = 1
    +display.visualizations.chartHeight = 420
    +display.visualizations.charting.chart.style = minimal
    +display.visualizations.show = 0
    +display.visualizations.singlevalue.rangeColors = ["0x555","0xf58f39"]
    +display.visualizations.singlevalue.rangeValues = [0]
    +display.visualizations.singlevalue.unit = notable events reported
    +display.visualizations.singlevalue.useColors = 1
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = (eventtype=nmon:processing OR eventtype=nmon:collect error) OR (index=_internal sourcetype=splunkd ERROR ExecProcessor nmon) NOT ("There is no python in" OR "python: not found") | stats count
    +
    +#############################################################
    +# NMON Processing Errors
    +#############################################################
    +
    +[Errors in NMON Data Processing]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h
    +dispatch.latest_time = now
    +display.events.fields = ["host","source","sourcetype","hostname"]
    +display.events.type = raw
    +display.statistics.drilldown = none
    +display.statistics.rowNumbers = 1
    +display.visualizations.chartHeight = 420
    +display.visualizations.charting.chart = line
    +display.visualizations.charting.chart.style = minimal
    +display.visualizations.show = 0
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = eventtype=nmon:processing error
    +
    +#############################################################
    +# NMON Collect Errors
    +#############################################################
    +
    +[Errors in NMON Data Collect]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h
    +dispatch.latest_time = now
    +display.events.fields = ["host","source","sourcetype","hostname"]
    +display.events.type = raw
    +display.statistics.drilldown = none
    +display.statistics.rowNumbers = 1
    +display.visualizations.chartHeight = 420
    +display.visualizations.charting.chart = line
    +display.visualizations.charting.chart.style = minimal
    +display.visualizations.show = 0
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = eventtype=nmon:collect error
    +
    +#############################################################
    +# NMON Collect Activity
    +#############################################################
    +
    +[Activity of NMON Data Collect]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h
    +dispatch.latest_time = now
    +display.events.fields = ["host","source","sourcetype","hostname"]
    +display.events.type = raw
    +display.general.type = statistics
    +display.statistics.drilldown = none
    +display.statistics.rowNumbers = 1
    +display.visualizations.chartHeight = 420
    +display.visualizations.charting.chart = line
    +display.visualizations.charting.chart.style = minimal
    +display.visualizations.show = 0
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = eventtype=nmon:collect | table _time,host,_raw | rename _raw as event
    +
    +#############################################################
    +# NMON Processing Activity
    +#############################################################
    +
    +[Activity of NMON Data Processing]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h
    +dispatch.latest_time = now
    +display.events.fields = ["host","source","sourcetype","hostname"]
    +display.events.type = raw
    +display.general.type = statistics
    +display.statistics.drilldown = none
    +display.statistics.rowNumbers = 1
    +display.visualizations.chartHeight = 420
    +display.visualizations.charting.chart = line
    +display.visualizations.charting.chart.style = minimal
    +display.visualizations.show = 0
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = eventtype=nmon:processing | stats values(hostname) As "hostname (Nmon host)", values(_raw) As event by _time,host | rename host As "host (collecter)" | sort - _time
    +
    +#############################################################
    +# NMON Activity - Splunkd events
    +#############################################################
    +
    +[Activity of NMON - Splunkd events]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h@h
    +dispatch.latest_time = now
    +display.events.fields = ["host","source","sourcetype","hostname"]
    +display.events.type = raw
    +display.statistics.drilldown = none
    +display.statistics.rowNumbers = 1
    +display.visualizations.chartHeight = 420
    +display.visualizations.charting.chart.style = minimal
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = index=_internal sourcetype=splunkd nmon *Processor
    +
    +#############################################################
    +# NMON Report Inventory
    +#############################################################
    +
    +[NMON Inventory Solaris]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +display.events.fields = ["host","source","sourcetype","hostname"]
    +display.events.type = raw
    +display.general.type = statistics
    +display.statistics.drilldown = none
    +display.statistics.rowNumbers = 1
    +display.visualizations.chartHeight = 420
    +display.visualizations.charting.chart = line
    +display.visualizations.charting.chart.style = minimal
    +display.visualizations.show = 0
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | inputlookup nmon_inventory | search OStype=Solaris\
    +| fields hostname,OStype,Solaris_sunOS_version,Solaris_version,cpu_cores,Processor,Solaris_processor_clockspeed,Physical_mem_MB,Virtual_mem_MB,nmon_version,uptime_duration,system_startup_date,reporting_date
    +
    +[NMON Inventory Linux]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +display.events.fields = ["host","source","sourcetype","hostname"]
    +display.events.type = raw
    +display.general.type = statistics
    +display.statistics.drilldown = none
    +display.statistics.rowNumbers = 1
    +display.visualizations.chartHeight = 420
    +display.visualizations.charting.chart = line
    +display.visualizations.charting.chart.style = minimal
    +display.visualizations.show = 0
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | inputlookup nmon_inventory | search OStype=Linux\
    +| fields hostname,OStype,cpu_cores,Processor,Physical_mem_MB,Virtual_mem_MB,Linux_distribution,Linux_kernelversion,nmon_version,uptime_duration,system_startup_date,reporting_date
    +
    +[NMON Inventory AIX]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +display.events.fields = ["host","source","sourcetype","hostname"]
    +display.events.type = raw
    +display.general.type = statistics
    +display.statistics.drilldown = none
    +display.statistics.rowNumbers = 1
    +display.visualizations.chartHeight = 420
    +display.visualizations.charting.chart = line
    +display.visualizations.charting.chart.style = minimal
    +display.visualizations.show = 0
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | inputlookup nmon_inventory | search OStype=AIX\
    +| fields  hostname,OStype,AIX_Machine_SerialNumber,AIX_LEVEL,AIX_virtualcpus,AIX_logicalcores,AIX_entitled,Processor,Physical_mem_MB,Virtual_mem_MB,AIX_processor_mode,AIX_processor_clockspeed,AIX_cpu_type,AIX_kernel_type,AIX_plateform_firmware_level,nmon_version,AIX_PoolID,AIX_system_installed_CPUs,AIX_system_active_CPUs,AIX_PoolCPUs,uptime_duration,system_startup_date,reporting_date
    +
    +#############################################################
    +# NMON Alerting
    +#############################################################
    +
    +[NMON - file-systems under saturation]
    +action.email = 0
    +action.email.include.trigger_time = 1
    +action.email.inline = 1
    +action.email.priority = 2
    +action.email.reportServerEnabled = 0
    +action.email.sendresults = 0
    +action.email.useNSSubject = 1
    +alert.digest_mode = 0
    +alert.severity = 4
    +alert.suppress = 1
    +alert.suppress.fields = fs_uuid
    +alert.suppress.period = 60m
    +alert.track = 1
    +counttype = number of events
    +cron_schedule = */5 * * * *
    +description = This alert will trigger hosts having a file-system under a superior saturation to the alert level configured for a duration higher or equal to the minimum configured consecutive time in seconds. (applicable for all OS)
    +dispatch.earliest_time = -60m
    +dispatch.latest_time = now
    +dispatch.ttl = 600 # Keep 10m this job artifact
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 571
    +display.visualizations.charting.chart = bar
    +enableSched = 1
    +quantity = 0
    +relation = greater than
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +schedule_window = 5
    +search = | `alerting_filesystem_usage`
    +
    +[NMON - physical memory usage saturation]
    +action.email = 0
    +action.email.include.trigger_time = 1
    +action.email.inline = 1
    +action.email.priority = 2
    +action.email.reportServerEnabled = 0
    +action.email.sendresults = 0
    +action.email.useNSSubject = 1
    +alert.digest_mode = 0
    +alert.severity = 4
    +alert.suppress = 1
    +alert.suppress.fields = frameID,host
    +alert.suppress.period = 60m
    +alert.track = 1
    +counttype = number of events
    +cron_schedule = */5 * * * *
    +description = This alert will trigger hosts having a physical memory usage superior to the alert level configured for a duration higher or equal to the minimum configured consecutive time in seconds. (applicable for all OS)
    +dispatch.earliest_time = -60m
    +dispatch.latest_time = now
    +dispatch.ttl = 600 # Keep 10m this job artifact
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 571
    +display.visualizations.charting.chart = bar
    +enableSched = 1
    +quantity = 0
    +relation = greater than
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +schedule_window = 5
    +search = | `alerting_realmemory_usage`
    +
    +[NMON - virtual usage saturation]
    +action.email = 0
    +action.email.include.trigger_time = 1
    +action.email.inline = 1
    +action.email.priority = 2
    +action.email.reportServerEnabled = 0
    +action.email.sendresults = 0
    +action.email.useNSSubject = 1
    +alert.digest_mode = 0
    +alert.severity = 4
    +alert.suppress = 1
    +alert.suppress.fields = frameID,host
    +alert.suppress.period = 60m
    +alert.track = 1
    +counttype = number of events
    +cron_schedule = 1-59/5 * * * *
    +description = This alert will trigger hosts having a virtual memory usage superior to the alert level configured for a duration higher or equal to the minimum configured consecutive time in seconds. (applicable for all OS)
    +dispatch.earliest_time = -60m
    +dispatch.latest_time = now
    +dispatch.ttl = 600 # Keep 10m this job artifact
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 571
    +display.visualizations.charting.chart = bar
    +enableSched = 1
    +quantity = 0
    +relation = greater than
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +schedule_window = 5
    +search = | `alerting_virtualmemory_usage`
    +
    +[NMON - cpu usage saturation]
    +action.email = 0
    +action.email.include.trigger_time = 1
    +action.email.inline = 1
    +action.email.priority = 2
    +action.email.reportServerEnabled = 0
    +action.email.sendresults = 0
    +action.email.useNSSubject = 1
    +alert.digest_mode = 0
    +alert.severity = 4
    +alert.suppress = 1
    +alert.suppress.fields = frameID,host
    +alert.suppress.period = 60m
    +alert.track = 1
    +counttype = number of events
    +cron_schedule = 2-59/5 * * * *
    +dispatch.ttl = 600 # Keep 10m this job artifact
    +description = This alert will trigger hosts having a cpu usage superior to the alert level configured for a duration higher or equal to the minimum configured consecutive time in seconds. (applicable for all OS)
    +dispatch.earliest_time = -60m
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 571
    +display.visualizations.charting.chart = bar
    +enableSched = 1
    +quantity = 0
    +relation = greater than
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +schedule_window = 5
    +search = | `alerting_cpu_usage`
    +
    +#############################################################
    +# Indexes stats
    +#############################################################
    +
    +[Dates of first and last event within indexes]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = 0
    +dispatch.latest_time = now
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 565
    +display.visualizations.charting.chart = pie
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = pivot
    +search = | `indexes_datestats` | eval summary='First Event' . " - " . 'Last Event' | fields summary
    +
    +#############################################################
    +# TA-NMON Agent Reporting
    +#############################################################
    +
    +[Add-on version per host]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -30d@d
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 565
    +display.visualizations.charting.chart = pie
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = pivot
    +search = | pivot metricator-nmon-processing NMON_Processing latest(addon_type) AS "addon_type" latest(addon_version) AS "addon_version" latest(_time) AS "latest_time" SPLITROW host AS host SORT 0 host ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1\
    +| eval addon_version = if(isnotnull(addon_version), addon_version, "previous_to_1.2.45"), addon_type = if(isnotnull(addon_type), addon_type, "Undefined")
    +
    +[TA-metricator package deployment reporting (requires _internal access)]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -30d@d
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.visualizations.chartHeight = 577
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = index="_internal" sourcetype="splunkd" source="*/splunkd.log" "DeployedApplication - Installing app=*nmon*"
    +
    +[List of interpreter and interpreter versions per host]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -30d@d
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 577
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | pivot metricator-nmon-processing NMON_Processing last(converter_inuse) AS "Type of coverter in use (last known value)" last(interpreter_version) AS "Version of Interpreter (last known value)" SPLITROW _time AS _time\
    +PERIOD minute SPLITROW hostname AS hostname SORT 0 _time ROWSUMMARY 0 COLSUMMARY 0 NUMCOLS 0 SHOWOTHER 1 | dedup hostname "Type of coverter in use (last known value)" "Version of Interpreter (last known value)" | fields - _time
    +
    +[TA-metricator package deployment reporting over time (requires _internal access)]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -30d@d
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = visualizations
    +display.page.search.tab = visualizations
    +display.visualizations.chartHeight = 577
    +display.visualizations.charting.chart.overlayFields = Nbr_of_deployment_actions
    +display.visualizations.charting.legend.placement = top
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = index=_internal sourcetype=splunkd "DeployedApplication - Installing app=*nmon*" | timechart span=1d dc(host) AS Number_hosts_deployed count AS Nbr_of_deployment_actions
    +
    +[Universal Forwarders Configuration Report]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -30d@d
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 534
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = index=_internal source=*metrics.log group=tcpin_connections version=* | eval hostname=if(isnull(hostname), sourceHost,hostname)\
    +| stats latest(sourceIp) AS sourceIp, latest(os) AS os, latest(version) AS version, latest(fwdType) AS fwdType, latest(arch) AS arch by hostname
    +
    +################
    +#	ALERT CENTER #
    +################
    +
    +#### CPU ####
    +
    +[ALERT CENTER - Number of active CPU alerts]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -60m
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = visualizations
    +display.page.search.tab = visualizations
    +display.visualizations.chartHeight = 534
    +display.visualizations.charting.chart = line
    +display.visualizations.singlevalue.afterLabel =
    +display.visualizations.singlevalue.drilldown = all
    +display.visualizations.singlevalue.rangeColors = ["0x65a637","0xf58f39"]
    +display.visualizations.singlevalue.rangeValues = [0]
    +display.visualizations.singlevalue.underLabel = cpu saturation
    +display.visualizations.singlevalue.unit = cpu active alerts
    +display.visualizations.singlevalue.useColors = 1
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = index=_audit action=alert_fired action=alert_fired ss_name="NMON - cpu usage saturation" ss_app="metricator-for-nmon" earliest="-60m" latest="now" | stats count AS count | rangemap field=count low=0-0 default=high
    +
    +[ALERT CENTER - Search historical CPU alerts]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h@h
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 534
    +display.visualizations.charting.chart = line
    +display.visualizations.singlevalue.afterLabel =
    +display.visualizations.singlevalue.drilldown = all
    +display.visualizations.singlevalue.rangeColors = ["0x65a637","0xf58f39"]
    +display.visualizations.singlevalue.rangeValues = [0]
    +display.visualizations.singlevalue.underLabel = cpu saturation
    +display.visualizations.singlevalue.unit = cpu active alerts
    +display.visualizations.singlevalue.useColors = 1
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | `alerting_cpu_usage`
    +
    +[ALERT CENTER - CPU issues]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h@h
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = visualizations
    +display.page.search.tab = visualizations
    +display.visualizations.chartHeight = 534
    +display.visualizations.charting.chart = line
    +display.visualizations.singlevalue.afterLabel = Host(s) with Potential CPU issue
    +display.visualizations.singlevalue.underLabel = cpu saturation
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | `alerting_cpu_usage`
    +
    +[ALERT CENTER - Number of active Real Memory alerts]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -60m
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = visualizations
    +display.page.search.tab = visualizations
    +display.visualizations.chartHeight = 534
    +display.visualizations.charting.chart = line
    +display.visualizations.singlevalue.afterLabel =
    +display.visualizations.singlevalue.drilldown = all
    +display.visualizations.singlevalue.rangeColors = ["0x65a637","0xf58f39"]
    +display.visualizations.singlevalue.rangeValues = [0]
    +display.visualizations.singlevalue.underLabel = physical memory saturation
    +display.visualizations.singlevalue.unit = physical memory active alerts
    +display.visualizations.singlevalue.useColors = 1
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = index=_audit action=alert_fired action=alert_fired ss_name="NMON - physical memory usage saturation" ss_app="metricator-for-nmon" earliest="-60m" latest="now" | stats count AS count | rangemap field=count low=0-0 default=high
    +
    +[ALERT CENTER - Search historical Real Memory alerts]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h@h
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 534
    +display.visualizations.charting.chart = line
    +display.visualizations.singlevalue.afterLabel =
    +display.visualizations.singlevalue.drilldown = all
    +display.visualizations.singlevalue.rangeColors = ["0x65a637","0xf58f39"]
    +display.visualizations.singlevalue.rangeValues = [0]
    +display.visualizations.singlevalue.underLabel = physical memory saturation
    +display.visualizations.singlevalue.unit = physical memory active alerts
    +display.visualizations.singlevalue.useColors = 1
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | `alerting_realmemory_usage`
    +
    +[ALERT CENTER - Real Memory issues]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h@h
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = visualizations
    +display.page.search.tab = visualizations
    +display.visualizations.chartHeight = 534
    +display.visualizations.charting.chart = line
    +display.visualizations.singlevalue.afterLabel = Host(s) with Potential Memory issue
    +display.visualizations.singlevalue.underLabel = physical memory saturation
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | `alerting_realmemory_usage`
    +
    +[ALERT CENTER - Number of active Virtual Memory alerts]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h@h
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = visualizations
    +display.page.search.tab = visualizations
    +display.visualizations.chartHeight = 534
    +display.visualizations.charting.chart = line
    +display.visualizations.singlevalue.afterLabel =
    +display.visualizations.singlevalue.drilldown = all
    +display.visualizations.singlevalue.rangeColors = ["0x65a637","0xf58f39"]
    +display.visualizations.singlevalue.rangeValues = [0]
    +display.visualizations.singlevalue.underLabel = virtual memory saturation
    +display.visualizations.singlevalue.unit = virtual memory active alerts
    +display.visualizations.singlevalue.useColors = 1
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = index=_audit action=alert_fired action=alert_fired ss_name="NMON - virtual usage saturation" ss_app="metricator-for-nmon" earliest="-60m" latest="now" | stats count AS count | rangemap field=count low=0-0 default=high
    +
    +[ALERT CENTER - Search historical Virtual Memory alerts]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h@h
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 534
    +display.visualizations.charting.chart = line
    +display.visualizations.singlevalue.afterLabel =
    +display.visualizations.singlevalue.drilldown = all
    +display.visualizations.singlevalue.rangeColors = ["0x65a637","0xf58f39"]
    +display.visualizations.singlevalue.rangeValues = [0]
    +display.visualizations.singlevalue.underLabel = virtual memory saturation
    +display.visualizations.singlevalue.unit = virtual memory active alerts
    +display.visualizations.singlevalue.useColors = 1
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | `alerting_virtualmemory_usage`
    +
    +[ALERT CENTER - Virtual Memory issues]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h@h
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = visualizations
    +display.page.search.tab = visualizations
    +display.visualizations.chartHeight = 534
    +display.visualizations.charting.chart = line
    +display.visualizations.singlevalue.afterLabel = Host(s) with Potential Virtual Memory issue
    +display.visualizations.singlevalue.underLabel = virtual memory saturation
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | `alerting_virtualmemory_usage`
    +
    +[ALERT CENTER - Number of active FS alerts]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -60m
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = visualizations
    +display.page.search.tab = visualizations
    +display.visualizations.singlevalue.afterLabel =
    +display.visualizations.singlevalue.drilldown = all
    +display.visualizations.singlevalue.rangeColors = ["0x65a637","0xf58f39"]
    +display.visualizations.singlevalue.rangeValues = [0]
    +display.visualizations.singlevalue.underLabel = file-systems saturation
    +display.visualizations.singlevalue.unit = file-systems active alerts
    +display.visualizations.singlevalue.useColors = 1
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = index=_audit action=alert_fired action=alert_fired ss_name="NMON - file-systems under saturation" ss_app="metricator-for-nmon" earliest="-60m" latest="now" | stats count AS count | rangemap field=count low=0-0 default=high
    +
    +[ALERT CENTER - Search historical FS alerts]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h@h
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.singlevalue.afterLabel =
    +display.visualizations.singlevalue.drilldown = all
    +display.visualizations.singlevalue.rangeColors = ["0x65a637","0xf58f39"]
    +display.visualizations.singlevalue.rangeValues = [0]
    +display.visualizations.singlevalue.underLabel = file-systems saturation
    +display.visualizations.singlevalue.unit = file-systems active alerts
    +display.visualizations.singlevalue.useColors = 1
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | `alerting_filesystem_usage`
    +
    +[ALERT CENTER - FS issues]
    +action.email.reportServerEnabled = 0
    +action.email.useNSSubject = 1
    +alert.track = 0
    +dispatch.earliest_time = -24h@h
    +dispatch.latest_time = now
    +display.events.fields = ["host","type","source","sourcetype"]
    +display.general.type = visualizations
    +display.page.search.tab = visualizations
    +display.visualizations.chartHeight = 534
    +display.visualizations.charting.chart = line
    +display.visualizations.singlevalue.afterLabel = Host(s) with file-system usage in excess
    +display.visualizations.singlevalue.underLabel = file-system saturation
    +display.visualizations.type = singlevalue
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | `alerting_filesystem_usage`
    +
    +#######################
    +#	Various Reports   #
    +#######################
    +
    +[UPTIME - servers recent reboot (last 60 minutes)]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +description = This report shows servers having rebooted within last 60 minutes
    +dispatch.earliest_time = -60m
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 606
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | tstats latest("metricator-nmon-config.uptime") AS uptime_seconds, latest("metricator-nmon-config.event_epoch") AS last_report from datamodel=metricator-nmon-config where (nodename = metricator-nmon-config) (sourcetype=nmon_config) by host prestats=true\
    +| tstats latest("Uptime.uptime") AS external_uptime_seconds latest(Uptime.event_epoch) as external_last_report from datamodel=metricator-nmon-config.Uptime where (nodename = Uptime) (Uptime.uptime = "*") by host append=true prestats=true\
    +| stats dedup_splitvals=t\
    +latest("metricator-nmon-config.uptime") AS uptime_seconds, latest("metricator-nmon-config.event_epoch") AS last_report, latest("Uptime.uptime") AS external_uptime_seconds latest(Uptime.event_epoch) as external_last_report by host\
    +| eval last_known_uptime=if(isnotnull(external_uptime_seconds), external_uptime_seconds, uptime_seconds)\
    +| eval epoch=if(isnotnull(external_last_report), external_last_report, last_report)\
    +| eval reporting_date=strftime(epoch, "%m/%d/%Y %H:%M")\
    +| eval now=now()\
    +| eval last_known_uptime=(last_known_uptime+(now-epoch))\
    +| where last_known_uptime<=3600\
    +| sort host\
    +| eval "Date of last system startup (mm/dd/Y HH:MM)"=strftime((now()-last_known_uptime), "%m/%d/%Y %H:%M")\
    +| eval "uptime (human duration)"=tostring(last_known_uptime, "duration")\
    +| fields host,last_known_uptime,"uptime (human duration)","Date of last system startup (mm/dd/Y HH:MM)",reporting_date | fields - _time\
    +| rename last_known_uptime AS "uptime (in seconds)", reporting_date AS "Last reporting date (mm/dd/Y HH:MM)"
    +
    +[Linux OS - Last known uptime by host]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +description = This report shows last known uptime for Linux hosts based on inventory data and nmon external
    +dispatch.earliest_time = -24h
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 606
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | tstats latest("metricator-nmon-config.uptime") AS uptime_seconds, latest("metricator-nmon-config.event_epoch") AS last_report from datamodel=metricator-nmon-config where (nodename = metricator-nmon-config) (sourcetype=nmon_config) (metricator-nmon-config.OStype = "Linux") by host prestats=true\
    +| tstats latest("Uptime.uptime") AS external_uptime_seconds latest(Uptime.event_epoch) as external_last_report from datamodel=metricator-nmon-config.Uptime where (nodename = Uptime) (Uptime.OStype = "Linux") (Uptime.uptime = "*") by host append=true prestats=true\
    +| stats dedup_splitvals=t\
    +latest("metricator-nmon-config.uptime") AS uptime_seconds, latest("metricator-nmon-config.event_epoch") AS last_report, latest("Uptime.uptime") AS external_uptime_seconds latest(Uptime.event_epoch) as external_last_report by host\
    +| eval last_known_uptime=if(isnotnull(external_uptime_seconds), external_uptime_seconds, uptime_seconds)\
    +| eval epoch=if(isnotnull(external_last_report), external_last_report, last_report)\
    +| eval reporting_date=strftime(epoch, "%m/%d/%Y %H:%M")\
    +| eval now=now()\
    +| eval last_known_uptime=(last_known_uptime+(now-epoch))\
    +| sort host\
    +| eval "Date of last system startup (mm/dd/Y HH:MM)"=strftime((now()-last_known_uptime), "%m/%d/%Y %H:%M")\
    +| eval "uptime (human duration)"=tostring(last_known_uptime, "duration")\
    +| fields host,last_known_uptime,"uptime (human duration)","Date of last system startup (mm/dd/Y HH:MM)",reporting_date | fields - _time\
    +| rename last_known_uptime AS "uptime (in seconds)", reporting_date AS "Last reporting date (mm/dd/Y HH:MM)"
    +
    +[AIX OS - Last known uptime by host]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +description = This report shows last known uptime for AIX hosts based on nmon external
    +dispatch.earliest_time = -24h
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 606
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | tstats latest("metricator-nmon-config.uptime") AS uptime_seconds, latest("metricator-nmon-config.event_epoch") AS last_report from datamodel=metricator-nmon-config where (nodename = metricator-nmon-config) (sourcetype=nmon_config) (metricator-nmon-config.OStype = "AIX") by host prestats=true\
    +| tstats latest("Uptime.uptime") AS external_uptime_seconds latest(Uptime.event_epoch) as external_last_report from datamodel=metricator-nmon-config.Uptime where (nodename = Uptime) (Uptime.OStype = "AIX") (Uptime.uptime = "*") by host append=true prestats=true\
    +| stats dedup_splitvals=t\
    +latest("metricator-nmon-config.uptime") AS uptime_seconds, latest("metricator-nmon-config.event_epoch") AS last_report, latest("Uptime.uptime") AS external_uptime_seconds latest(Uptime.event_epoch) as external_last_report by host\
    +| eval last_known_uptime=if(isnotnull(external_uptime_seconds), external_uptime_seconds, uptime_seconds)\
    +| eval epoch=if(isnotnull(external_last_report), external_last_report, last_report)\
    +| eval reporting_date=strftime(epoch, "%m/%d/%Y %H:%M")\
    +| eval now=now()\
    +| eval last_known_uptime=(last_known_uptime+(now-epoch))\
    +| sort host\
    +| eval "Date of last system startup (mm/dd/Y HH:MM)"=strftime((now()-last_known_uptime), "%m/%d/%Y %H:%M")\
    +| eval "uptime (human duration)"=tostring(last_known_uptime, "duration")\
    +| fields host,last_known_uptime,"uptime (human duration)","Date of last system startup (mm/dd/Y HH:MM)",reporting_date | fields - _time\
    +| rename last_known_uptime AS "uptime (in seconds)", reporting_date AS "Last reporting date (mm/dd/Y HH:MM)"
    +
    +[Linux OS - filesystems utilization reporting]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +description = This report shows filesystems utilization statistics for Linux hosts based on DF nmon external metrics
    +dispatch.earliest_time = -24h
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 606
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | mstats latest(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.*" OStype=Linux host=* by host, metric_name, dimension_mount\
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)\
    +| stats first(Available) as Available, first(Use_pct) as Use_pct, first(Used) as Used, first(blocks) as blocks by host, dimension_mount\
    +| rename dimension_mount as mount\
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)\
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free\
    +| foreach storage, storage_free, storage_used [ eval <<FIELD>> = round('<<FIELD>>'/1024/1024, 2) ]\
    +| foreach storage*percent [ eval <<FIELD>> = round('<<FIELD>>', 2) ]\
    +| rename storage as "storage (GB)", storage_free as "storage free (GB)", storage_used as "storage used (GB)", storage_free_percent as "storage free (%)", storage_used_percent as "storage used (%)"\
    +| eval UsedPct=if(isnum('storage used (%)'), 'storage used (%)', 0 )\
    +| fields host, mount, "storage (GB)", "storage free (GB)", "storage used (GB)", "storage free (%)", "storage used (%)", UsedPct\
    +| appendpipe [ stats sum("storage (GB)") as "storage (GB)", sum("storage free (GB)") as "storage free (GB)", sum("storage used (GB)") as "storage used (GB)" ]\
    +| eval "storage free (%)" = if(isnull('storage free (%)'), (('storage free (GB)'/'storage (GB)')*100), 'storage free (%)'), "storage used (%)" = if(isnull('storage used (%)'), (('storage used (GB)'/'storage (GB)')*100), 'storage used (%)'), UsedPct = if(isnull(UsedPct), 'storage used (%)', UsedPct)\
    +| fillnull value="*** TOTAL GB / AVERAGE % ****" mount\
    +| foreach storage*%* UsedPct [ eval <<FIELD>> = round('<<FIELD>>', 2) ]
    +
    +[AIX OS - filesystems utilization reporting]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +description = This report shows filesystems utilization statistics for AIX hosts based on inventory data
    +dispatch.earliest_time = -24h
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 606
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | mstats latest(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.*" OStype=AIX host=* by host, metric_name, dimension_mount\
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)\
    +| stats first(Available) as Available, first(Use_pct) as Use_pct, first(Used) as Used, first(blocks) as blocks by host, dimension_mount\
    +| rename dimension_mount as mount\
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)\
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free\
    +| foreach storage, storage_free, storage_used [ eval <<FIELD>> = round('<<FIELD>>'/1024/1024, 2) ]\
    +| foreach storage*percent [ eval <<FIELD>> = round('<<FIELD>>', 2) ]\
    +| rename storage as "storage (GB)", storage_free as "storage free (GB)", storage_used as "storage used (GB)", storage_free_percent as "storage free (%)", storage_used_percent as "storage used (%)"\
    +| eval UsedPct=if(isnum('storage used (%)'), 'storage used (%)', 0 )\
    +| fields host, mount, "storage (GB)", "storage free (GB)", "storage used (GB)", "storage free (%)", "storage used (%)", UsedPct\
    +| appendpipe [ stats sum("storage (GB)") as "storage (GB)", sum("storage free (GB)") as "storage free (GB)", sum("storage used (GB)") as "storage used (GB)" ]\
    +| eval "storage free (%)" = if(isnull('storage free (%)'), (('storage free (GB)'/'storage (GB)')*100), 'storage free (%)'), "storage used (%)" = if(isnull('storage used (%)'), (('storage used (GB)'/'storage (GB)')*100), 'storage used (%)'), UsedPct = if(isnull(UsedPct), 'storage used (%)', UsedPct)\
    +| fillnull value="*** TOTAL GB / AVERAGE % ****" mount\
    +| foreach storage*%* UsedPct [ eval <<FIELD>> = round('<<FIELD>>', 2) ]
    +
    +[Solaris OS - filesystems utilization reporting]
    +action.email.useNSSubject = 1
    +alert.track = 0
    +description = This report shows filesystems utilization statistics for Solaris hosts based on inventory data
    +dispatch.earliest_time = -24h
    +dispatch.latest_time = now
    +display.events.fields = ["host","hostname","type","source","sourcetype"]
    +display.general.type = statistics
    +display.page.search.tab = statistics
    +display.visualizations.chartHeight = 606
    +display.visualizations.show = 0
    +request.ui_dispatch_app = metricator-for-nmon
    +request.ui_dispatch_view = search
    +search = | mstats latest(_value) as value where `nmon_metrics_index` metric_name="os.unix.nmon.storage.df_storage.*" OStype=Solaris host=* by host, metric_name, dimension_mount\
    +| eval Available=case(metric_name=="os.unix.nmon.storage.df_storage.Available", value), Use_pct=case(metric_name=="os.unix.nmon.storage.df_storage.Use_pct", value), Used=case(metric_name=="os.unix.nmon.storage.df_storage.Used", value), blocks=case(metric_name=="os.unix.nmon.storage.df_storage.blocks", value)\
    +| stats first(Available) as Available, first(Use_pct) as Use_pct, first(Used) as Used, first(blocks) as blocks by host, dimension_mount\
    +| rename dimension_mount as mount\
    +| eval storage_free=blocks-Used, storage_free_percent=(100-Use_pct)\
    +| rename Use_pct as storage_used_percent, blocks as storage, Used as storage_used, Available as storage_free\
    +| foreach storage, storage_free, storage_used [ eval <<FIELD>> = round('<<FIELD>>'/1024/1024, 2) ]\
    +| foreach storage*percent [ eval <<FIELD>> = round('<<FIELD>>', 2) ]\
    +| rename storage as "storage (GB)", storage_free as "storage free (GB)", storage_used as "storage used (GB)", storage_free_percent as "storage free (%)", storage_used_percent as "storage used (%)"\
    +| eval UsedPct=if(isnum('storage used (%)'), 'storage used (%)', 0 )\
    +| fields host, mount, "storage (GB)", "storage free (GB)", "storage used (GB)", "storage free (%)", "storage used (%)", UsedPct\
    +| appendpipe [ stats sum("storage (GB)") as "storage (GB)", sum("storage free (GB)") as "storage free (GB)", sum("storage used (GB)") as "storage used (GB)" ]\
    +| eval "storage free (%)" = if(isnull('storage free (%)'), (('storage free (GB)'/'storage (GB)')*100), 'storage free (%)'), "storage used (%)" = if(isnull('storage used (%)'), (('storage used (GB)'/'storage (GB)')*100), 'storage used (%)'), UsedPct = if(isnull(UsedPct), 'storage used (%)', UsedPct)\
    +| fillnull value="*** TOTAL GB / AVERAGE % ****" mount\
    +| foreach storage*%* UsedPct [ eval <<FIELD>> = round('<<FIELD>>', 2) ]
    diff --git a/deployment-apps/metricator-for-nmon/default/transforms.conf b/deployment-apps/metricator-for-nmon/default/transforms.conf
    new file mode 100644
    index 0000000..57f54dc
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/transforms.conf
    @@ -0,0 +1,147 @@
    +# transforms.conf
    +
    +#############
    +# CIM various
    +#############
    +
    +[inventory_network_interface]
    +REGEX = BBB\w*,[^,]*,ifconfig,\"(?<interface>[a-zA-Z]{1,}\d{1,})
    +FORMAT = interface::$1
    +MV_ADD = true
    +
    +[inventory_network_ip]
    +REGEX = BBB\w*,[^,]*,ifconfig,\"\sinet\s(?:addr:)?(?<ip>[\d|\.]*)\s
    +FORMAT = ip::$1
    +MV_ADD = true
    +
    +# Linux only
    +[inventory_network_mac]
    +REGEX = BBB\w*,[^,]*,ifconfig,\".*HWaddr\s([0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2})
    +FORMAT = mac::$1
    +MV_ADD = true
    +
    +#########
    +# lookups
    +#########
    +
    +#
    +# NMON Inventory Lookup Table
    +#
    +
    +[nmon_inventory]
    +external_type = kvstore
    +collection = kv_nmon_inventory
    +fields_list = hostname, OStype, OSversion, Physical_mem_MB, Virtual_mem_MB, AIX_Machine_SerialNumber, AIX_virtualcpus, AIX_logicalcores, AIX_entitled, AIX_LEVEL, AIX_processor_mode, AIX_processor_clockspeed, AIX_cpu_type, AIX_kernel_type, AIX_plateform_firmware_level, AIX_PoolID, AIX_system_installed_CPUs, AIX_system_active_CPUs, AIX_PoolCPUs, AIX_memory_MB, AIX_pagingspace_MB, Linux_memory_MB, Linux_swap_MB, Linux_distribution, Linux_vendor, Linux_kernelversion, Solaris_version, Solaris_sunOS_version, Solaris_processor_clockspeed, Solaris_physical_memory_MB, Processor, cpu_cores, cpu_logicalcores, nmon_version, uptime_seconds, uptime_duration, system_startup_date, reporting_date
    +
    +#
    +# Data dictionary
    +#
    +
    +# Static data dictionary for VM Linux
    +[static_dictionary_VM_Linux]
    +filename = static_dictionary_VM_Linux.csv
    +
    +#
    +# ALERTING MANAGEMENT
    +#
    +
    +### Threshold and exclusion management:
    +
    +# nmon alerting threshold template management
    +[nmon_alerting_threshold_template]
    +external_type = kvstore
    +collection = kv_nmon_alerting_threshold_template
    +fields_list = _key, frameID, alert_cpu_max_percent, alert_cpu_min_time_seconds, alert_physical_memory_max_percent, alert_physical_memory_min_time_seconds, alert_virtual_memory_max_percent, alert_virtual_memory_min_time_seconds
    +
    +# nmon alerting threshold management
    +[nmon_alerting_threshold]
    +external_type = kvstore
    +collection = kv_nmon_alerting_threshold
    +fields_list = _key, frameID, serialnum, host, alert_cpu_max_percent, alert_cpu_min_time_seconds, alert_physical_memory_max_percent, alert_physical_memory_min_time_seconds, alert_virtual_memory_max_percent, alert_virtual_memory_min_time_seconds
    +
    +# nmon alerting threshold template management for file-systems
    +[nmon_alerting_threshold_template_filesystem]
    +external_type = kvstore
    +collection = kv_nmon_alerting_threshold_template_filesystem
    +fields_list = _key, frameID, mount, alert_fs_max_percent, alert_fs_min_time_seconds, is_shared
    +case_sensitive_match=false
    +match_type = WILDCARD(mount),WILDCARD(frameID)
    +
    +# nmon alerting threshold management for file-systems
    +[nmon_alerting_threshold_filesystem]
    +external_type = kvstore
    +collection = kv_nmon_alerting_threshold_filesystem
    +fields_list = _key, frameID, serialnum, host, mount, alert_fs_max_percent, alert_fs_min_time_seconds
    +case_sensitive_match=false
    +match_type = WILDCARD(mount)
    +
    +# File systems excluding for file systems usage alerting
    +# 3 collections are available:
    +# - nmon_alerting_filesystem_global_exclusion: will be applied for all systems to exclude file systems
    +# - nmon_alerting_filesystem_template_exclusion: will be applied for matched systems to exclude file systems
    +# - nmon_alerting_filesystem_per_server_exclusion: file system exclusion on per server basis
    +
    +[nmon_alerting_filesystem_global_exclusion]
    +external_type = kvstore
    +collection = kv_nmon_alerting_filesystem_global_exclusion
    +fields_list = _key, mount, exclude
    +case_sensitive_match=false
    +match_type = WILDCARD(mount)
    +
    +[nmon_alerting_filesystem_template_exclusion]
    +external_type = kvstore
    +collection = kv_nmon_alerting_filesystem_template_exclusion
    +fields_list = _key, frameID, mount, exclude
    +case_sensitive_match=false
    +match_type = WILDCARD(mount)
    +
    +[nmon_alerting_filesystem_per_server_exclusion]
    +external_type = kvstore
    +collection = kv_nmon_alerting_filesystem_per_server_exclusion
    +fields_list = _key, frameID, serialnum, host, mount, exclude
    +case_sensitive_match=false
    +match_type = WILDCARD(mount)
    +
    +# NMON metric catalog
    +# this lookup table contains the metric catalog definition, to be used by several interfaces to dynamically define metrics parameters
    +[nmon_metric_catalog]
    +filename = nmon_metric_catalog.csv
    +
    +# NMON hosts by day
    +# This lookup is a very simple lookup table used to store the state of the number of hosts known to the Nmon application
    +# We use this lookup in the "Hosts with data within last 7 days" reports for optimization purposes
    +# Instead of searching for the last 7 days of data, each day slice (but the current day) is retrieved from the lookup
    +[nmon_hosts_last_7days]
    +external_type = kvstore
    +collection = kv_nmon_hosts_last_7days
    +fields_list = _key, _time, dcount
    +
    +# NMON usual usage for main system metrics, known as the Nmon baseline
    +# Note: Why multiple collection ? Initially, the first baseline implementation was based on one unique collection
    +# But data of volume to manage is terribly high to generate the baseline, that's why i've decided to split the baseline into multiple to allow
    +# using existing data models
    +
    +[nmon_baseline_CPU_ALL]
    +external_type = kvstore
    +collection = kv_nmon_baseline_CPU_ALL
    +fields_list = _key, date_wday, local_time, frameID, hostname, lower_baseline_avg_cpu, baseline_avg_cpu, upper_baseline_avg_cpu
    +
    +[nmon_baseline_LPAR]
    +external_type = kvstore
    +collection = kv_nmon_baseline_LPAR
    +fields_list = _key, date_wday, local_time, frameID, hostname, lower_baseline_avg_vp_usage, baseline_avg_vp_usage, upper_baseline_avg_vp_usage, lower_baseline_avg_pool_usage, baseline_avg_pool_usage, upper_baseline_avg_pool_usage
    +
    +[nmon_baseline_MEM]
    +external_type = kvstore
    +collection = kv_nmon_baseline_MEM
    +fields_list = _key, date_wday, local_time, frameID, hostname, lower_baseline_avg_real_mem, baseline_avg_real_mem, upper_baseline_avg_real_mem, lower_baseline_avg_virtual_mem, baseline_avg_virtual_mem, upper_baseline_avg_virtual_mem
    +
    +[nmon_baseline_DISKXFER]
    +external_type = kvstore
    +collection = kv_nmon_baseline_DISKXFER
    +fields_list = _key, date_wday, local_time, frameID, hostname, lower_baseline_avg_disk_iops, baseline_avg_disk_iops, upper_baseline_avg_disk_iops
    +
    +[nmon_frameID_mapping]
    +external_type = kvstore
    +collection = kv_nmon_frameID_mapping
    +fields_list = _key, serialnum, frameID, host, host_description
    diff --git a/deployment-apps/metricator-for-nmon/default/web.conf b/deployment-apps/metricator-for-nmon/default/web.conf
    new file mode 100644
    index 0000000..dba8088
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/default/web.conf
    @@ -0,0 +1,8 @@
    +
    +[expose:metricator_for_nmon_settings]
    +pattern = metricator_for_nmon_settings
    +methods = POST, GET
    +
    +[expose:metricator_for_nmon_settings_specified]
    +pattern = metricator_for_nmon_settings/*
    +methods = POST, GET, DELETE
    diff --git a/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/INSTALLER b/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/INSTALLER
    new file mode 100644
    index 0000000..a1b589e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/INSTALLER
    @@ -0,0 +1 @@
    +pip
    diff --git a/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/LICENSE b/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/LICENSE
    new file mode 100644
    index 0000000..04b6b1f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/LICENSE
    @@ -0,0 +1,22 @@
    +Copyright 2006 Dan-Haim. All rights reserved.
    +
    +Redistribution and use in source and binary forms, with or without modification,
    +are permitted provided that the following conditions are met:
    +1. Redistributions of source code must retain the above copyright notice, this
    +   list of conditions and the following disclaimer.
    +2. Redistributions in binary form must reproduce the above copyright notice,
    +   this list of conditions and the following disclaimer in the documentation
    +   and/or other materials provided with the distribution.
    +3. Neither the name of Dan Haim nor the names of his contributors may be used
    +   to endorse or promote products derived from this software without specific
    +   prior written permission.
    +   
    +THIS SOFTWARE IS PROVIDED BY DAN HAIM "AS IS" AND ANY EXPRESS OR IMPLIED
    +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
    +EVENT SHALL DAN HAIM OR HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA
    +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMANGE.
    diff --git a/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/METADATA b/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/METADATA
    new file mode 100644
    index 0000000..ae2ae34
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/METADATA
    @@ -0,0 +1,321 @@
    +Metadata-Version: 2.1
    +Name: PySocks
    +Version: 1.7.1
    +Summary: A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information.
    +Home-page: https://github.com/Anorov/PySocks
    +Author: Anorov
    +Author-email: anorov.vorona@gmail.com
    +License: BSD
    +Keywords: socks,proxy
    +Platform: UNKNOWN
    +Classifier: Programming Language :: Python :: 2
    +Classifier: Programming Language :: Python :: 2.7
    +Classifier: Programming Language :: Python :: 3
    +Classifier: Programming Language :: Python :: 3.4
    +Classifier: Programming Language :: Python :: 3.5
    +Classifier: Programming Language :: Python :: 3.6
    +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
    +Description-Content-Type: text/markdown
    +
    +PySocks
    +=======
    +
    +PySocks lets you send traffic through SOCKS and HTTP proxy servers. It is a modern fork of [SocksiPy](http://socksipy.sourceforge.net/) with bug fixes and extra features.
    +
    +Acts as a drop-in replacement to the socket module. Seamlessly configure SOCKS proxies for any socket object by calling `socket_object.set_proxy()`.
    +
    +----------------
    +
    +Features
    +========
    +
    +* SOCKS proxy client for Python 2.7 and 3.4+
    +* TCP supported
    +* UDP mostly supported (issues may occur in some edge cases)
    +* HTTP proxy client included but not supported or recommended (you should use urllib2's or requests' own HTTP proxy interface)
    +* urllib2 handler included. `pip install` / `setup.py install` will automatically install the `sockshandler` module.
    +
    +Installation
    +============
    +
    +    pip install PySocks
    +
    +Or download the tarball / `git clone` and...
    +
    +    python setup.py install
    +
    +These will install both the `socks` and `sockshandler` modules.
    +
    +Alternatively, include just `socks.py` in your project.
    +
    +--------------------------------------------
    +
    +*Warning:* PySocks/SocksiPy only supports HTTP proxies that use CONNECT tunneling. Certain HTTP proxies may not work with this library. If you wish to use HTTP (not SOCKS) proxies, it is recommended that you rely on your HTTP client's native proxy support (`proxies` dict for `requests`, or `urllib2.ProxyHandler` for `urllib2`) instead.
    +
    +--------------------------------------------
    +
    +Usage
    +=====
    +
    +## socks.socksocket ##
    +
    +    import socks
    +
    +    s = socks.socksocket() # Same API as socket.socket in the standard lib
    +
    +    s.set_proxy(socks.SOCKS5, "localhost") # SOCKS4 and SOCKS5 use port 1080 by default
    +    # Or
    +    s.set_proxy(socks.SOCKS4, "localhost", 4444)
    +    # Or
    +    s.set_proxy(socks.HTTP, "5.5.5.5", 8888)
    +
    +    # Can be treated identical to a regular socket object
    +    s.connect(("www.somesite.com", 80))
    +    s.sendall("GET / HTTP/1.1 ...")
    +    print s.recv(4096)
    +
    +## Monkeypatching ##
    +
    +To monkeypatch the entire standard library with a single default proxy:
    +
    +    import urllib2
    +    import socket
    +    import socks
    +
    +    socks.set_default_proxy(socks.SOCKS5, "localhost")
    +    socket.socket = socks.socksocket
    +
    +    urllib2.urlopen("http://www.somesite.com/") # All requests will pass through the SOCKS proxy
    +
    +Note that monkeypatching may not work for all standard modules or for all third party modules, and generally isn't recommended. Monkeypatching is usually an anti-pattern in Python.
    +
    +## urllib2 Handler ##
    +
    +Example use case with the `sockshandler` urllib2 handler. Note that you must import both `socks` and `sockshandler`, as the handler is its own module separate from PySocks. The module is included in the PyPI package.
    +
    +    import urllib2
    +    import socks
    +    from sockshandler import SocksiPyHandler
    +
    +    opener = urllib2.build_opener(SocksiPyHandler(socks.SOCKS5, "127.0.0.1", 9050))
    +    print opener.open("http://www.somesite.com/") # All requests made by the opener will pass through the SOCKS proxy
    +
    +--------------------------------------------
    +
    +Original SocksiPy README attached below, amended to reflect API changes.
    +
    +--------------------------------------------
    +
    +SocksiPy
    +
    +A Python SOCKS module.
    +
    +(C) 2006 Dan-Haim. All rights reserved.
    +
    +See LICENSE file for details.
    +
    +
    +*WHAT IS A SOCKS PROXY?*
    +
    +A SOCKS proxy is a proxy server at the TCP level. In other words, it acts as
    +a tunnel, relaying all traffic going through it without modifying it.
    +SOCKS proxies can be used to relay traffic using any network protocol that
    +uses TCP.
    +
    +*WHAT IS SOCKSIPY?*
    +
    +This Python module allows you to create TCP connections through a SOCKS
    +proxy without any special effort.
    +It also supports relaying UDP packets with a SOCKS5 proxy.
    +
    +*PROXY COMPATIBILITY*
    +
    +SocksiPy is compatible with three different types of proxies:
    +
    +1. SOCKS Version 4 (SOCKS4), including the SOCKS4a extension.
    +2. SOCKS Version 5 (SOCKS5).
    +3. HTTP Proxies which support tunneling using the CONNECT method.
    +
    +*SYSTEM REQUIREMENTS*
    +
    +Being written in Python, SocksiPy can run on any platform that has a Python
    +interpreter and TCP/IP support.
    +This module has been tested with Python 2.3 and should work with greater versions
    +just as well.
    +
    +
    +INSTALLATION
    +-------------
    +
    +Simply copy the file "socks.py" to your Python's `lib/site-packages` directory,
    +and you're ready to go. [Editor's note: it is better to use `python setup.py install` for PySocks]
    +
    +
    +USAGE
    +------
    +
    +First load the socks module with the command:
    +
    +    >>> import socks
    +    >>>
    +
    +The socks module provides a class called `socksocket`, which is the base to all of the module's functionality.
    +
    +The `socksocket` object has the same initialization parameters as the normal socket
    +object to ensure maximal compatibility, however it should be noted that `socksocket` will only function with family being `AF_INET` and
    +type being either `SOCK_STREAM` or `SOCK_DGRAM`.
    +Generally, it is best to initialize the `socksocket` object with no parameters
    +
    +    >>> s = socks.socksocket()
    +    >>>
    +
    +The `socksocket` object has an interface which is very similiar to socket's (in fact
    +the `socksocket` class is derived from socket) with a few extra methods.
    +To select the proxy server you would like to use, use the `set_proxy` method, whose
    +syntax is:
    +
    +    set_proxy(proxy_type, addr[, port[, rdns[, username[, password]]]])
    +
    +Explanation of the parameters:
    +
    +`proxy_type` - The type of the proxy server. This can be one of three possible
    +choices: `PROXY_TYPE_SOCKS4`, `PROXY_TYPE_SOCKS5` and `PROXY_TYPE_HTTP` for SOCKS4,
    +SOCKS5 and HTTP servers respectively. `SOCKS4`, `SOCKS5`, and `HTTP` are all aliases, respectively.
    +
    +`addr` - The IP address or DNS name of the proxy server.
    +
    +`port` - The port of the proxy server. Defaults to 1080 for socks and 8080 for http.
    +
    +`rdns` - This is a boolean flag than modifies the behavior regarding DNS resolving.
    +If it is set to True, DNS resolving will be preformed remotely, on the server.
    +If it is set to False, DNS resolving will be preformed locally. Please note that
    +setting this to True with SOCKS4 servers actually use an extension to the protocol,
    +called SOCKS4a, which may not be supported on all servers (SOCKS5 and http servers
    +always support DNS). The default is True.
    +
    +`username` - For SOCKS5 servers, this allows simple username / password authentication
    +with the server. For SOCKS4 servers, this parameter will be sent as the userid.
    +This parameter is ignored if an HTTP server is being used. If it is not provided,
    +authentication will not be used (servers may accept unauthenticated requests).
    +
    +`password` - This parameter is valid only for SOCKS5 servers and specifies the
    +respective password for the username provided.
    +
    +Example of usage:
    +
    +    >>> s.set_proxy(socks.SOCKS5, "socks.example.com") # uses default port 1080
    +    >>> s.set_proxy(socks.SOCKS4, "socks.test.com", 1081)
    +
    +After the set_proxy method has been called, simply call the connect method with the
    +traditional parameters to establish a connection through the proxy:
    +
    +    >>> s.connect(("www.sourceforge.net", 80))
    +    >>>
    +
    +Connection will take a bit longer to allow negotiation with the proxy server.
    +Please note that calling connect without calling `set_proxy` earlier will connect
    +without a proxy (just like a regular socket).
    +
    +Errors: Any errors in the connection process will trigger exceptions. The exception
    +may either be generated by the underlying socket layer or may be custom module
    +exceptions, whose details follow:
    +
    +class `ProxyError` - This is a base exception class. It is not raised directly but
    +rather all other exception classes raised by this module are derived from it.
    +This allows an easy way to catch all proxy-related errors. It descends from `IOError`.
    +
    +All `ProxyError` exceptions have an attribute `socket_err`, which will contain either a
    +caught `socket.error` exception, or `None` if there wasn't any.
    +
    +class `GeneralProxyError` - When thrown, it indicates a problem which does not fall
    +into another category.
    +
    +* `Sent invalid data` - This error means that unexpected data has been received from
    +the server. The most common reason is that the server specified as the proxy is
    +not really a SOCKS4/SOCKS5/HTTP proxy, or maybe the proxy type specified is wrong.
    +
    +* `Connection closed unexpectedly` - The proxy server unexpectedly closed the connection.
    +This may indicate that the proxy server is experiencing network or software problems.
    +
    +* `Bad proxy type` - This will be raised if the type of the proxy supplied to the
    +set_proxy function was not one of `SOCKS4`/`SOCKS5`/`HTTP`.
    +
    +* `Bad input` - This will be raised if the `connect()` method is called with bad input
    +parameters.
    +
    +class `SOCKS5AuthError` - This indicates that the connection through a SOCKS5 server
    +failed due to an authentication problem.
    +
    +* `Authentication is required` - This will happen if you use a SOCKS5 server which
    +requires authentication without providing a username / password at all.
    +
    +* `All offered authentication methods were rejected` - This will happen if the proxy
    +requires a special authentication method which is not supported by this module.
    +
    +* `Unknown username or invalid password` - Self descriptive.
    +
    +class `SOCKS5Error` - This will be raised for SOCKS5 errors which are not related to
    +authentication.
    +The parameter is a tuple containing a code, as given by the server,
    +and a description of the
    +error. The possible errors, according to the RFC, are:
    +
    +* `0x01` - General SOCKS server failure - If for any reason the proxy server is unable to
    +fulfill your request (internal server error).
    +* `0x02` - connection not allowed by ruleset - If the address you're trying to connect to
    +is blacklisted on the server or requires authentication.
    +* `0x03` - Network unreachable - The target could not be contacted. A router on the network
    +had replied with a destination net unreachable error.
    +* `0x04` - Host unreachable - The target could not be contacted. A router on the network
    +had replied with a destination host unreachable error.
    +* `0x05` - Connection refused - The target server has actively refused the connection
    +(the requested port is closed).
    +* `0x06` - TTL expired - The TTL value of the SYN packet from the proxy to the target server
    +has expired. This usually means that there are network problems causing the packet
    +to be caught in a router-to-router "ping-pong".
    +* `0x07` - Command not supported - For instance if the server does not support UDP.
    +* `0x08` - Address type not supported - The client has provided an invalid address type.
    +When using this module, this error should not occur.
    +
    +class `SOCKS4Error` - This will be raised for SOCKS4 errors. The parameter is a tuple
    +containing a code and a description of the error, as given by the server. The
    +possible error, according to the specification are:
    +
    +* `0x5B` - Request rejected or failed - Will be raised in the event of an failure for any
    +reason other then the two mentioned next.
    +* `0x5C` - request rejected because SOCKS server cannot connect to identd on the client -
    +The Socks server had tried an ident lookup on your computer and has failed. In this
    +case you should run an identd server and/or configure your firewall to allow incoming
    +connections to local port 113 from the remote server.
    +* `0x5D` - request rejected because the client program and identd report different user-ids -
    +The Socks server had performed an ident lookup on your computer and has received a
    +different userid than the one you have provided. Change your userid (through the
    +username parameter of the set_proxy method) to match and try again.
    +
    +class `HTTPError` - This will be raised for HTTP errors. The message will contain
    +the HTTP status code and provided error message.
    +
    +After establishing the connection, the object behaves like a standard socket.
    +
    +Methods like `makefile()` and `settimeout()` should behave just like regular sockets.
    +Call the `close()` method to close the connection.
    +
    +In addition to the `socksocket` class, an additional function worth mentioning is the
    +`set_default_proxy` function. The parameters are the same as the `set_proxy` method.
    +This function will set default proxy settings for newly created `socksocket` objects,
    +in which the proxy settings haven't been changed via the `set_proxy` method.
    +This is quite useful if you wish to force 3rd party modules to use a SOCKS proxy,
    +by overriding the socket object.
    +For example:
    +
    +    >>> socks.set_default_proxy(socks.SOCKS5, "socks.example.com")
    +    >>> socket.socket = socks.socksocket
    +    >>> urllib.urlopen("http://www.sourceforge.net/")
    +
    +
    +PROBLEMS
    +---------
    +
    +Please open a GitHub issue at https://github.com/Anorov/PySocks
    +
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/RECORD b/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/RECORD
    new file mode 100644
    index 0000000..0c8247e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/RECORD
    @@ -0,0 +1,8 @@
    +PySocks-1.7.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
    +PySocks-1.7.1.dist-info/LICENSE,sha256=cCfiFOAU63i3rcwc7aWspxOnn8T2oMUsnaWz5wfm_-k,1401
    +PySocks-1.7.1.dist-info/METADATA,sha256=zbQMizjPOOP4DhEiEX24XXjNrYuIxF9UGUpN0uFDB6Y,13235
    +PySocks-1.7.1.dist-info/RECORD,,
    +PySocks-1.7.1.dist-info/WHEEL,sha256=t_MpApv386-8PVts2R6wsTifdIn0vbUDTVv61IbqFC8,92
    +PySocks-1.7.1.dist-info/top_level.txt,sha256=TKSOIfCFBoK9EY8FBYbYqC3PWd3--G15ph9n8-QHPDk,19
    +socks.py,sha256=xOYn27t9IGrbTBzWsUUuPa0YBuplgiUykzkOB5V5iFY,31086
    +sockshandler.py,sha256=2SYGj-pwt1kjgLoZAmyeaEXCeZDWRmfVS_QG6kErGtY,3966
    diff --git a/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/WHEEL b/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/WHEEL
    new file mode 100644
    index 0000000..129a673
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/PySocks-1.7.1.dist-info/WHEEL
    @@ -0,0 +1,5 @@
    +Wheel-Version: 1.0
    +Generator: bdist_wheel (0.33.3)
    +Root-Is-Purelib: true
    +Tag: py3-none-any
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/INSTALLER b/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/INSTALLER
    new file mode 100644
    index 0000000..a1b589e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/INSTALLER
    @@ -0,0 +1 @@
    +pip
    diff --git a/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/LICENSE b/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/LICENSE
    new file mode 100644
    index 0000000..0a64774
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/LICENSE
    @@ -0,0 +1,21 @@
    +This package contains a modified version of ca-bundle.crt:
    +
    +ca-bundle.crt -- Bundle of CA Root Certificates
    +
    +Certificate data from Mozilla as of: Thu Nov  3 19:04:19 2011#
    +This is a bundle of X.509 certificates of public Certificate Authorities
    +(CA). These were automatically extracted from Mozilla's root certificates
    +file (certdata.txt).  This file can be found in the mozilla source tree:
    +https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/ckfw/builtins/certdata.txt
    +It contains the certificates in PEM format and therefore
    +can be directly used with curl / libcurl / php_curl, or with
    +an Apache+mod_ssl webserver for SSL client authentication.
    +Just configure this file as the SSLCACertificateFile.#
    +
    +***** BEGIN LICENSE BLOCK *****
    +This Source Code Form is subject to the terms of the Mozilla Public License,
    +v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain
    +one at http://mozilla.org/MPL/2.0/.
    +
    +***** END LICENSE BLOCK *****
    +@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $
    diff --git a/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/METADATA b/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/METADATA
    new file mode 100644
    index 0000000..aeb1991
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/METADATA
    @@ -0,0 +1,83 @@
    +Metadata-Version: 2.1
    +Name: certifi
    +Version: 2022.12.7
    +Summary: Python package for providing Mozilla's CA Bundle.
    +Home-page: https://github.com/certifi/python-certifi
    +Author: Kenneth Reitz
    +Author-email: me@kennethreitz.com
    +License: MPL-2.0
    +Project-URL: Source, https://github.com/certifi/python-certifi
    +Platform: UNKNOWN
    +Classifier: Development Status :: 5 - Production/Stable
    +Classifier: Intended Audience :: Developers
    +Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
    +Classifier: Natural Language :: English
    +Classifier: Programming Language :: Python
    +Classifier: Programming Language :: Python :: 3
    +Classifier: Programming Language :: Python :: 3 :: Only
    +Classifier: Programming Language :: Python :: 3.6
    +Classifier: Programming Language :: Python :: 3.7
    +Classifier: Programming Language :: Python :: 3.8
    +Classifier: Programming Language :: Python :: 3.9
    +Classifier: Programming Language :: Python :: 3.10
    +Classifier: Programming Language :: Python :: 3.11
    +Requires-Python: >=3.6
    +License-File: LICENSE
    +
    +Certifi: Python SSL Certificates
    +================================
    +
    +Certifi provides Mozilla's carefully curated collection of Root Certificates for
    +validating the trustworthiness of SSL certificates while verifying the identity
    +of TLS hosts. It has been extracted from the `Requests`_ project.
    +
    +Installation
    +------------
    +
    +``certifi`` is available on PyPI. Simply install it with ``pip``::
    +
    +    $ pip install certifi
    +
    +Usage
    +-----
    +
    +To reference the installed certificate authority (CA) bundle, you can use the
    +built-in function::
    +
    +    >>> import certifi
    +
    +    >>> certifi.where()
    +    '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem'
    +
    +Or from the command line::
    +
    +    $ python -m certifi
    +    /usr/local/lib/python3.7/site-packages/certifi/cacert.pem
    +
    +Enjoy!
    +
    +1024-bit Root Certificates
    +~~~~~~~~~~~~~~~~~~~~~~~~~~
    +
    +Browsers and certificate authorities have concluded that 1024-bit keys are
    +unacceptably weak for certificates, particularly root certificates. For this
    +reason, Mozilla has removed any weak (i.e. 1024-bit key) certificate from its
    +bundle, replacing it with an equivalent strong (i.e. 2048-bit or greater key)
    +certificate from the same CA. Because Mozilla removed these certificates from
    +its bundle, ``certifi`` removed them as well.
    +
    +In previous versions, ``certifi`` provided the ``certifi.old_where()`` function
    +to intentionally re-add the 1024-bit roots back into your bundle. This was not
    +recommended in production and therefore was removed at the end of 2018.
    +
    +.. _`Requests`: https://requests.readthedocs.io/en/master/
    +
    +Addition/Removal of Certificates
    +--------------------------------
    +
    +Certifi does not support any addition/removal or other modification of the
    +CA trust store content. This project is intended to provide a reliable and
    +highly portable root of trust to python deployments. Look to upstream projects
    +for methods to use alternate trust.
    +
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/RECORD b/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/RECORD
    new file mode 100644
    index 0000000..1f00d6a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/RECORD
    @@ -0,0 +1,11 @@
    +certifi-2022.12.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
    +certifi-2022.12.7.dist-info/LICENSE,sha256=oC9sY4-fuE0G93ZMOrCF2K9-2luTwWbaVDEkeQd8b7A,1052
    +certifi-2022.12.7.dist-info/METADATA,sha256=chFpcxKhCPEQ3d8-Vz36zr2Micf1eQhKkFFk7_JvJNo,2911
    +certifi-2022.12.7.dist-info/RECORD,,
    +certifi-2022.12.7.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92
    +certifi-2022.12.7.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8
    +certifi/__init__.py,sha256=bK_nm9bLJzNvWZc2oZdiTwg2KWD4HSPBWGaM0zUDvMw,94
    +certifi/__main__.py,sha256=xBBoj905TUWBLRGANOcf7oi6e-3dMP4cEoG9OyMs11g,243
    +certifi/cacert.pem,sha256=LBHDzgj_xA05AxnHK8ENT5COnGNElNZe0svFUHMf1SQ,275233
    +certifi/core.py,sha256=lhewz0zFb2b4ULsQurElmloYwQoecjWzPqY67P8T7iM,4219
    +certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
    diff --git a/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/WHEEL b/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/WHEEL
    new file mode 100644
    index 0000000..5bad85f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/certifi-2022.12.7.dist-info/WHEEL
    @@ -0,0 +1,5 @@
    +Wheel-Version: 1.0
    +Generator: bdist_wheel (0.37.0)
    +Root-Is-Purelib: true
    +Tag: py3-none-any
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/certifi/__init__.py b/deployment-apps/metricator-for-nmon/lib/certifi/__init__.py
    new file mode 100644
    index 0000000..a3546f1
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/certifi/__init__.py
    @@ -0,0 +1,4 @@
    +from .core import contents, where
    +
    +__all__ = ["contents", "where"]
    +__version__ = "2022.12.07"
    diff --git a/deployment-apps/metricator-for-nmon/lib/certifi/__main__.py b/deployment-apps/metricator-for-nmon/lib/certifi/__main__.py
    new file mode 100644
    index 0000000..8945b5d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/certifi/__main__.py
    @@ -0,0 +1,12 @@
    +import argparse
    +
    +from certifi import contents, where
    +
    +parser = argparse.ArgumentParser()
    +parser.add_argument("-c", "--contents", action="store_true")
    +args = parser.parse_args()
    +
    +if args.contents:
    +    print(contents())
    +else:
    +    print(where())
    diff --git a/deployment-apps/metricator-for-nmon/lib/certifi/cacert.pem b/deployment-apps/metricator-for-nmon/lib/certifi/cacert.pem
    new file mode 100644
    index 0000000..df9e4e3
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/certifi/cacert.pem
    @@ -0,0 +1,4527 @@
    +
    +# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
    +# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
    +# Label: "GlobalSign Root CA"
    +# Serial: 4835703278459707669005204
    +# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a
    +# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c
    +# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99
    +-----BEGIN CERTIFICATE-----
    +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
    +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
    +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
    +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
    +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
    +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
    +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
    +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
    +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
    +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
    +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
    +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
    +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
    +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
    +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
    +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
    +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
    +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
    +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
    +# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
    +# Label: "Entrust.net Premium 2048 Secure Server CA"
    +# Serial: 946069240
    +# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90
    +# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31
    +# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77
    +-----BEGIN CERTIFICATE-----
    +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
    +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
    +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
    +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
    +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
    +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
    +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
    +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
    +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
    +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
    +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
    +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
    +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
    +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
    +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
    +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
    +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
    +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
    +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
    +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
    +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
    +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
    +fF6adulZkMV8gzURZVE=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
    +# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
    +# Label: "Baltimore CyberTrust Root"
    +# Serial: 33554617
    +# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4
    +# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74
    +# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb
    +-----BEGIN CERTIFICATE-----
    +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
    +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
    +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
    +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
    +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
    +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
    +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
    +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
    +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
    +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
    +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
    +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
    +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
    +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
    +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
    +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
    +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
    +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
    +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
    +# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
    +# Label: "Entrust Root Certification Authority"
    +# Serial: 1164660820
    +# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4
    +# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9
    +# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c
    +-----BEGIN CERTIFICATE-----
    +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
    +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
    +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
    +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
    +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
    +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
    +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
    +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
    +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
    +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
    +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
    +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
    +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
    +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
    +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
    +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
    +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
    +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
    +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
    +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
    +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
    +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
    +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
    +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
    +0vdXcDazv/wor3ElhVsT/h5/WrQ8
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=AAA Certificate Services O=Comodo CA Limited
    +# Subject: CN=AAA Certificate Services O=Comodo CA Limited
    +# Label: "Comodo AAA Services root"
    +# Serial: 1
    +# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0
    +# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49
    +# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4
    +-----BEGIN CERTIFICATE-----
    +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
    +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
    +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
    +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
    +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
    +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
    +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
    +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
    +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
    +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
    +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
    +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
    +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
    +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
    +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
    +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
    +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
    +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
    +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
    +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
    +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
    +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
    +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited
    +# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited
    +# Label: "QuoVadis Root CA 2"
    +# Serial: 1289
    +# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b
    +# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7
    +# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86
    +-----BEGIN CERTIFICATE-----
    +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
    +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
    +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
    +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
    +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa
    +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg
    +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J
    +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB
    +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp
    ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1
    +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i
    +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz
    +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og
    +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH
    +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI
    +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud
    +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2
    +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL
    +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
    +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f
    +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn
    +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl
    +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K
    +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha
    +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc
    +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR
    +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD
    +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
    +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
    +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
    +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited
    +# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited
    +# Label: "QuoVadis Root CA 3"
    +# Serial: 1478
    +# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf
    +# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85
    +# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35
    +-----BEGIN CERTIFICATE-----
    +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
    +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
    +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
    +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
    +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
    +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB
    +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr
    +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd
    +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv
    +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT
    +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe
    +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc
    +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt
    +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ
    +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A
    +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD
    +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG
    +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0
    +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
    +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
    +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw
    +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G
    +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC
    +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg
    +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0
    +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem
    +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd
    ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B
    +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN
    +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x
    +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57
    +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s
    +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
    +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
    +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
    +4SVhM7JZG+Ju1zdXtg2pEto=
    +-----END CERTIFICATE-----
    +
    +# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1
    +# Subject: O=SECOM Trust.net OU=Security Communication RootCA1
    +# Label: "Security Communication Root CA"
    +# Serial: 0
    +# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a
    +# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7
    +# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c
    +-----BEGIN CERTIFICATE-----
    +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY
    +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t
    +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5
    +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD
    +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3
    +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8
    +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ
    +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9
    +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N
    +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ
    +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G
    +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T
    +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG
    +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr
    +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5
    +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU
    +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot
    +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
    +# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
    +# Label: "XRamp Global CA Root"
    +# Serial: 107108908803651509692980124233745014957
    +# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1
    +# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6
    +# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2
    +-----BEGIN CERTIFICATE-----
    +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
    +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
    +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
    +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
    +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
    +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
    +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
    +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
    +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
    +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
    +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
    +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
    +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
    +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
    +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
    +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
    +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
    +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
    +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
    +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
    +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
    +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
    +O+7ETPTsJ3xCwnR8gooJybQDJbw=
    +-----END CERTIFICATE-----
    +
    +# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
    +# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
    +# Label: "Go Daddy Class 2 CA"
    +# Serial: 0
    +# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67
    +# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4
    +# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4
    +-----BEGIN CERTIFICATE-----
    +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
    +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
    +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
    +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
    +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
    +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
    +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
    +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
    +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
    +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
    +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
    +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
    +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
    +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
    +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
    +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
    +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
    +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
    +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
    +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
    +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
    +ReYNnyicsbkqWletNw+vHX/bvZ8=
    +-----END CERTIFICATE-----
    +
    +# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
    +# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
    +# Label: "Starfield Class 2 CA"
    +# Serial: 0
    +# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24
    +# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a
    +# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58
    +-----BEGIN CERTIFICATE-----
    +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
    +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
    +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
    +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
    +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
    +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
    +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
    +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
    ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
    +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
    +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
    +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
    +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
    +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
    +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
    +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
    +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
    +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
    +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
    +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
    +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
    +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
    +# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
    +# Label: "DigiCert Assured ID Root CA"
    +# Serial: 17154717934120587862167794914071425081
    +# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72
    +# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43
    +# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c
    +-----BEGIN CERTIFICATE-----
    +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
    +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
    +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
    +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
    +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
    +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
    +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
    +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
    +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
    +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
    +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
    +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
    +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
    +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
    +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
    +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
    +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
    +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
    +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
    ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
    +# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
    +# Label: "DigiCert Global Root CA"
    +# Serial: 10944719598952040374951832963794454346
    +# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e
    +# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36
    +# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61
    +-----BEGIN CERTIFICATE-----
    +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
    +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
    +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
    +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
    +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
    +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
    +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
    +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
    +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
    +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
    +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
    +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
    +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
    +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
    +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
    +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
    +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
    +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
    +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
    +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
    +# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
    +# Label: "DigiCert High Assurance EV Root CA"
    +# Serial: 3553400076410547919724730734378100087
    +# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a
    +# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25
    +# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf
    +-----BEGIN CERTIFICATE-----
    +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
    +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
    +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
    +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
    +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
    +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
    +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
    ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
    +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
    +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
    +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
    +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
    +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
    +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
    +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
    +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
    +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
    +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
    +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
    +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
    ++OkuE6N36B9K
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG
    +# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG
    +# Label: "SwissSign Gold CA - G2"
    +# Serial: 13492815561806991280
    +# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93
    +# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61
    +# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95
    +-----BEGIN CERTIFICATE-----
    +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
    +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
    +biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
    +MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
    +d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
    +CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
    +76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
    +bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
    +6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
    +emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
    +MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
    +MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
    +MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
    +FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
    +aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
    +gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
    +qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
    +lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
    +8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
    +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
    +45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
    +UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
    +O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
    +bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
    +GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
    +77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
    +hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
    +92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
    +Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
    +ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
    +Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG
    +# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG
    +# Label: "SwissSign Silver CA - G2"
    +# Serial: 5700383053117599563
    +# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13
    +# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb
    +# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5
    +-----BEGIN CERTIFICATE-----
    +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE
    +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu
    +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow
    +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY
    +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
    +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv
    +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br
    +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF
    +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH
    +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt
    +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/
    +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ
    +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH
    +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf
    +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6
    +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB
    +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
    +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c
    +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
    +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB
    +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp
    +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9
    +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ
    +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ
    +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8
    +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X
    +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR
    +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/
    +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+
    +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy
    +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=SecureTrust CA O=SecureTrust Corporation
    +# Subject: CN=SecureTrust CA O=SecureTrust Corporation
    +# Label: "SecureTrust CA"
    +# Serial: 17199774589125277788362757014266862032
    +# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1
    +# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11
    +# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73
    +-----BEGIN CERTIFICATE-----
    +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
    +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
    +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
    +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
    +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
    +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
    +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
    +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
    +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
    +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
    +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
    +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
    +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
    +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
    +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
    +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
    +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
    +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
    +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
    +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Secure Global CA O=SecureTrust Corporation
    +# Subject: CN=Secure Global CA O=SecureTrust Corporation
    +# Label: "Secure Global CA"
    +# Serial: 9751836167731051554232119481456978597
    +# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de
    +# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b
    +# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69
    +-----BEGIN CERTIFICATE-----
    +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
    +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
    +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
    +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
    +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
    +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
    +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
    +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
    +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
    +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
    +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
    +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
    +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
    +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
    +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
    +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
    +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
    +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
    +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
    +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited
    +# Subject: CN=COMODO Certification Authority O=COMODO CA Limited
    +# Label: "COMODO Certification Authority"
    +# Serial: 104350513648249232941998508985834464573
    +# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75
    +# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b
    +# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66
    +-----BEGIN CERTIFICATE-----
    +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
    +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
    +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
    +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
    +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
    +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
    +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
    +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
    +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
    +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
    +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
    ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
    +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
    +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
    +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
    +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
    +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
    +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
    +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
    +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
    +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
    +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
    +ZQ==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited
    +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited
    +# Label: "COMODO ECC Certification Authority"
    +# Serial: 41578283867086692638256921589707938090
    +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23
    +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11
    +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7
    +-----BEGIN CERTIFICATE-----
    +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
    +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
    +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
    +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
    +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
    +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
    +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
    +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
    +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
    +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
    +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
    +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
    +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
    +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Certigna O=Dhimyotis
    +# Subject: CN=Certigna O=Dhimyotis
    +# Label: "Certigna"
    +# Serial: 18364802974209362175
    +# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff
    +# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97
    +# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d
    +-----BEGIN CERTIFICATE-----
    +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
    +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
    +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
    +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
    +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
    +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
    +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
    +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
    +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
    +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
    +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
    +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
    +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
    +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
    +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
    +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
    +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
    +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
    +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
    +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
    +-----END CERTIFICATE-----
    +
    +# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority
    +# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority
    +# Label: "ePKI Root Certification Authority"
    +# Serial: 28956088682735189655030529057352760477
    +# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3
    +# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0
    +# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5
    +-----BEGIN CERTIFICATE-----
    +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
    +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
    +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
    +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
    +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
    +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
    +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
    +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
    +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
    +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
    +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
    +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
    +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
    +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
    +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
    +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
    +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
    +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
    +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
    +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
    +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
    +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
    +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
    +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
    +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
    +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
    +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
    +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
    +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
    +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
    +hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
    +-----END CERTIFICATE-----
    +
    +# Issuer: O=certSIGN OU=certSIGN ROOT CA
    +# Subject: O=certSIGN OU=certSIGN ROOT CA
    +# Label: "certSIGN ROOT CA"
    +# Serial: 35210227249154
    +# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17
    +# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b
    +# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb
    +-----BEGIN CERTIFICATE-----
    +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
    +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
    +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
    +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
    +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
    +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
    +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
    +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
    +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
    +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
    +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
    +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
    +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
    +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
    +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
    +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
    +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
    +9u6wWk5JRFRYX0KD
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services)
    +# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services)
    +# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny"
    +# Serial: 80544274841616
    +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88
    +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91
    +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98
    +-----BEGIN CERTIFICATE-----
    +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
    +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
    +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
    +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR
    +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB
    +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM
    +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm
    +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz
    +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
    +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT
    +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz
    +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5
    +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG
    +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2
    +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG
    +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M
    +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh
    +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
    ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
    +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
    +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
    +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post
    +# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post
    +# Label: "Hongkong Post Root CA 1"
    +# Serial: 1000
    +# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca
    +# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58
    +# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2
    +-----BEGIN CERTIFICATE-----
    +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx
    +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg
    +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG
    +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr
    +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
    +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ
    +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn
    +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh
    +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9
    +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h
    +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED
    +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC
    +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3
    +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB
    +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs
    +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO
    +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi
    +AmvZWg==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
    +# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
    +# Label: "SecureSign RootCA11"
    +# Serial: 1
    +# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26
    +# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3
    +# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12
    +-----BEGIN CERTIFICATE-----
    +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr
    +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG
    +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0
    +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp
    +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD
    +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz
    +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8
    +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV
    +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9
    +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni
    +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC
    +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD
    +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
    +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm
    +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ
    +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr
    +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5
    +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN
    +QSdJQO7e5iNEOdyhIta6A/I=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
    +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
    +# Label: "Microsec e-Szigno Root CA 2009"
    +# Serial: 14014712776195784473
    +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1
    +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e
    +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78
    +-----BEGIN CERTIFICATE-----
    +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
    +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
    +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
    +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y
    +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx
    +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp
    +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
    +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP
    +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc
    +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U
    +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7
    +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC
    +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1
    ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
    +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM
    +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG
    +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h
    +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk
    +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
    +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
    +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
    +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
    +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
    +# Label: "GlobalSign Root CA - R3"
    +# Serial: 4835703278459759426209954
    +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28
    +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad
    +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b
    +-----BEGIN CERTIFICATE-----
    +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
    +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
    +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
    +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
    +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
    +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
    +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
    +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
    +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
    +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
    +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
    +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
    +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
    +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
    +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
    +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
    +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
    +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
    +WD9f
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
    +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
    +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068"
    +# Serial: 6047274297262753887
    +# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3
    +# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa
    +# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef
    +-----BEGIN CERTIFICATE-----
    +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE
    +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
    +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy
    +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
    +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
    +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
    +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
    +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
    +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
    +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
    +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
    +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
    +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
    +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
    +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
    +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
    +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD
    +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD
    +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
    +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv
    +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl
    +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF
    +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9
    +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1
    +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481
    +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS
    +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k
    +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF
    +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM
    +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g
    +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz
    +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB
    +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Izenpe.com O=IZENPE S.A.
    +# Subject: CN=Izenpe.com O=IZENPE S.A.
    +# Label: "Izenpe.com"
    +# Serial: 917563065490389241595536686991402621
    +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73
    +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19
    +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f
    +-----BEGIN CERTIFICATE-----
    +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
    +MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
    +ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
    +VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
    +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
    +scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
    +xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
    +LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
    +uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
    +yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
    +JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
    +rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
    +BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
    +hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
    +QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
    +HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
    +Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
    +QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
    +BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
    +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
    +AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
    +A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
    +laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
    +awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
    +JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
    +LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
    +VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
    +LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
    +UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
    +QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
    +naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
    +QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
    +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
    +# Label: "Go Daddy Root Certificate Authority - G2"
    +# Serial: 0
    +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01
    +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b
    +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da
    +-----BEGIN CERTIFICATE-----
    +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
    +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
    +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
    +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
    +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
    +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
    +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
    +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
    +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
    +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
    +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
    +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
    +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
    +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
    +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
    +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
    +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
    +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
    +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
    +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
    +4uJEvlz36hz1
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
    +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
    +# Label: "Starfield Root Certificate Authority - G2"
    +# Serial: 0
    +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96
    +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e
    +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5
    +-----BEGIN CERTIFICATE-----
    +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
    +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
    +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
    +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
    +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
    +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
    +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
    +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
    +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
    +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
    +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
    +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
    +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
    +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
    +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
    +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
    +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
    +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
    +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
    +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
    +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
    +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
    +# Label: "Starfield Services Root Certificate Authority - G2"
    +# Serial: 0
    +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2
    +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f
    +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5
    +-----BEGIN CERTIFICATE-----
    +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
    +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
    +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
    +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
    +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
    +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
    +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
    +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
    +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
    +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
    +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
    +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
    +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
    +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
    +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
    +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
    +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
    +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
    +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
    +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
    +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
    +sSi6
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=AffirmTrust Commercial O=AffirmTrust
    +# Subject: CN=AffirmTrust Commercial O=AffirmTrust
    +# Label: "AffirmTrust Commercial"
    +# Serial: 8608355977964138876
    +# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7
    +# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7
    +# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7
    +-----BEGIN CERTIFICATE-----
    +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
    +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
    +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
    +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
    +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
    +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
    +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
    +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
    +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
    +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
    +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
    +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
    +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
    +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
    +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
    +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
    +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
    +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=AffirmTrust Networking O=AffirmTrust
    +# Subject: CN=AffirmTrust Networking O=AffirmTrust
    +# Label: "AffirmTrust Networking"
    +# Serial: 8957382827206547757
    +# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f
    +# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f
    +# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b
    +-----BEGIN CERTIFICATE-----
    +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
    +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
    +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
    +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
    +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
    +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y
    +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua
    +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL
    +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp
    +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG
    +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i
    +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
    +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO
    +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu
    +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ
    +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u
    +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48
    +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=AffirmTrust Premium O=AffirmTrust
    +# Subject: CN=AffirmTrust Premium O=AffirmTrust
    +# Label: "AffirmTrust Premium"
    +# Serial: 7893706540734352110
    +# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57
    +# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27
    +# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a
    +-----BEGIN CERTIFICATE-----
    +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
    +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz
    +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG
    +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U
    +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf
    +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ
    +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ
    ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS
    +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5
    +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7
    +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG
    +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S
    +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S
    +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia
    +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX
    +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE
    +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
    +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2
    +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
    +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B
    +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ
    +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc
    +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ
    +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF
    +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH
    +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8
    +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO
    +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e
    +KeC2uAloGRwYQw==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust
    +# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust
    +# Label: "AffirmTrust Premium ECC"
    +# Serial: 8401224907861490260
    +# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d
    +# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb
    +# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23
    +-----BEGIN CERTIFICATE-----
    +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
    +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
    +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
    +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
    +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
    +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
    +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
    +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
    +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
    +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
    +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
    +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
    +# Label: "Certum Trusted Network CA"
    +# Serial: 279744
    +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78
    +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e
    +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e
    +-----BEGIN CERTIFICATE-----
    +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
    +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
    +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
    +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
    +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
    +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
    +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
    +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
    +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
    +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
    +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
    +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
    +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
    +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
    +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
    +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
    +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
    +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
    +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
    +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
    +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
    +# Label: "TWCA Root Certification Authority"
    +# Serial: 1
    +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79
    +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48
    +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44
    +-----BEGIN CERTIFICATE-----
    +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES
    +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU
    +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz
    +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO
    +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm
    +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE
    +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH
    +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX
    +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z
    +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx
    +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
    +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq
    +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC
    +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls
    +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D
    +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn
    +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ
    +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
    +-----END CERTIFICATE-----
    +
    +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2
    +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2
    +# Label: "Security Communication RootCA2"
    +# Serial: 0
    +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43
    +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74
    +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6
    +-----BEGIN CERTIFICATE-----
    +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
    +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
    +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
    +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy
    +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj
    +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV
    +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr
    +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM
    +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ
    +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO
    +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw
    +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs
    +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
    +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF
    +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc
    +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
    +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
    +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
    +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967
    +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967
    +# Label: "Actalis Authentication Root CA"
    +# Serial: 6271844772424770508
    +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6
    +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac
    +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66
    +-----BEGIN CERTIFICATE-----
    +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
    +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w
    +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
    +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC
    +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1
    +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB
    +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv
    +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX
    +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9
    +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/
    +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb
    +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ
    +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F
    +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe
    +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F
    +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn
    +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7
    +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz
    +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
    +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL
    +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70
    +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz
    +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V
    +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j
    +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX
    +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok
    +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R
    +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU
    +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU
    +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
    +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
    +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
    +# Label: "Buypass Class 2 Root CA"
    +# Serial: 2
    +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29
    +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99
    +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48
    +-----BEGIN CERTIFICATE-----
    +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
    +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
    +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
    +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
    +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
    +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr
    +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV
    +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91
    +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx
    +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ
    +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB
    +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr
    +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi
    +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS
    +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN
    +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP
    +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz
    +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h
    +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
    +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t
    +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo
    ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7
    +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2
    +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us
    +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ
    +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
    +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
    +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
    +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327
    +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327
    +# Label: "Buypass Class 3 Root CA"
    +# Serial: 2
    +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec
    +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57
    +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d
    +-----BEGIN CERTIFICATE-----
    +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
    +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
    +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
    +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
    +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
    +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y
    +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E
    +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9
    +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX
    +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c
    +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X
    +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY
    +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS
    +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D
    +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP
    +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3
    +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv
    +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj
    +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
    +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS
    +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2
    +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa
    +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv
    +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u
    +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE
    +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
    +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
    +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
    +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
    +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
    +# Label: "T-TeleSec GlobalRoot Class 3"
    +# Serial: 1
    +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef
    +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1
    +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd
    +-----BEGIN CERTIFICATE-----
    +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
    +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
    +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
    +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
    +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
    +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
    +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
    +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
    +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
    +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
    +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
    +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
    +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
    +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
    +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
    +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
    +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
    +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
    +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
    +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
    +TpPDpFQUWw==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
    +# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
    +# Label: "D-TRUST Root Class 3 CA 2 2009"
    +# Serial: 623603
    +# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f
    +# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0
    +# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1
    +-----BEGIN CERTIFICATE-----
    +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
    +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
    +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
    +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
    +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
    +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
    +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
    +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
    +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
    +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
    +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
    +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
    +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
    +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
    +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
    +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
    +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
    +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
    +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
    +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
    +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
    +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
    +Johw1+qRzT65ysCQblrGXnRl11z+o+I=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH
    +# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH
    +# Label: "D-TRUST Root Class 3 CA 2 EV 2009"
    +# Serial: 623604
    +# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6
    +# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83
    +# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81
    +-----BEGIN CERTIFICATE-----
    +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
    +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
    +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
    +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV
    +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI
    +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn
    +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0
    +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z
    +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR
    +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8
    +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw
    +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea
    +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw
    +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh
    +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E
    +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt
    +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku
    +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp
    +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
    +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
    +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
    +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
    +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=CA Disig Root R2 O=Disig a.s.
    +# Subject: CN=CA Disig Root R2 O=Disig a.s.
    +# Label: "CA Disig Root R2"
    +# Serial: 10572350602393338211
    +# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03
    +# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71
    +# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03
    +-----BEGIN CERTIFICATE-----
    +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
    +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
    +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
    +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
    +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw
    +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe
    +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH
    +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I
    +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe
    +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR
    +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO
    +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912
    +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ
    +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD
    +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs
    +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1
    +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
    +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI
    +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
    +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf
    +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb
    +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka
    ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal
    +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i
    +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3
    +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
    +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
    +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
    +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV
    +# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV
    +# Label: "ACCVRAIZ1"
    +# Serial: 6828503384748696800
    +# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02
    +# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17
    +# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13
    +-----BEGIN CERTIFICATE-----
    +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE
    +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw
    +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ
    +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND
    +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb
    +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY
    +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo
    +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA
    +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr
    +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/
    +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH
    +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47
    +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO
    +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa
    +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl
    +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI
    +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls
    +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG
    +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
    +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT
    +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG
    +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA
    +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA
    +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA
    +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA
    +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA
    +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA
    +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu
    +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt
    +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud
    +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF
    +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp
    +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU
    +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m
    +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD
    +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms
    +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH
    +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
    +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA
    +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF
    +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H
    +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA
    +# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA
    +# Label: "TWCA Global Root CA"
    +# Serial: 3262
    +# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96
    +# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65
    +# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b
    +-----BEGIN CERTIFICATE-----
    +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx
    +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT
    +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5
    +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT
    +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG
    +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF
    +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz
    +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh
    +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH
    +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc
    +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2
    +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi
    +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP
    +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA
    +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE
    +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm
    +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
    +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL
    +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
    +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF
    +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo
    +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+
    +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh
    +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW
    +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW
    +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j
    +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz
    +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy
    +KwbQBM0=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera
    +# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera
    +# Label: "TeliaSonera Root CA v1"
    +# Serial: 199041966741090107964904287217786801558
    +# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c
    +# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37
    +# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89
    +-----BEGIN CERTIFICATE-----
    +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
    +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
    +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
    +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
    +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
    +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
    +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
    +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
    +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
    +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
    +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
    +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
    +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
    +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
    +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
    +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
    +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
    +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
    +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
    +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
    +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
    +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
    +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
    +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
    +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
    +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
    +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
    +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi
    +# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi
    +# Label: "E-Tugra Certification Authority"
    +# Serial: 7667447206703254355
    +# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49
    +# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39
    +# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c
    +-----BEGIN CERTIFICATE-----
    +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV
    +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC
    +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV
    +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1
    +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz
    +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+
    +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp
    +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
    +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
    +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY
    +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH
    +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF
    +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo
    +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D
    +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH
    +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut
    +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM
    +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8
    +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
    +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX
    +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6
    +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5
    +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF
    +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR
    +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY
    +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c
    +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3
    ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK
    +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6
    +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl
    +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P
    +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD
    +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d
    +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
    +# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
    +# Label: "T-TeleSec GlobalRoot Class 2"
    +# Serial: 1
    +# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a
    +# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9
    +# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52
    +-----BEGIN CERTIFICATE-----
    +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
    +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
    +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
    +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
    +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
    +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
    +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
    +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
    +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
    +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
    +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
    +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
    +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
    +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
    +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
    +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
    +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
    +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
    +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
    +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
    +BSeOE6Fuwg==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Atos TrustedRoot 2011 O=Atos
    +# Subject: CN=Atos TrustedRoot 2011 O=Atos
    +# Label: "Atos TrustedRoot 2011"
    +# Serial: 6643877497813316402
    +# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56
    +# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21
    +# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74
    +-----BEGIN CERTIFICATE-----
    +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE
    +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG
    +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM
    +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC
    +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp
    +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM
    +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+
    +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ
    +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L
    +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi
    +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV
    +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG
    +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3
    +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j
    +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP
    +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc
    +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D
    +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv
    +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited
    +# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited
    +# Label: "QuoVadis Root CA 1 G3"
    +# Serial: 687049649626669250736271037606554624078720034195
    +# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab
    +# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67
    +# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74
    +-----BEGIN CERTIFICATE-----
    +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL
    +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
    +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00
    +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
    +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG
    +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV
    +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe
    +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341
    +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh
    +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp
    +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o
    +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc
    +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G
    +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt
    +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO
    +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt
    +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
    +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD
    +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
    +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2
    +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN
    +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5
    +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv
    +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2
    +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k
    +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj
    +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp
    +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt
    +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited
    +# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited
    +# Label: "QuoVadis Root CA 2 G3"
    +# Serial: 390156079458959257446133169266079962026824725800
    +# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06
    +# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36
    +# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40
    +-----BEGIN CERTIFICATE-----
    +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
    +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
    +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
    +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
    +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG
    +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf
    +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW
    +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym
    +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+
    +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1
    +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j
    +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq
    +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz
    +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh
    +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l
    +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG
    +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
    +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD
    +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
    +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC
    +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga
    +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n
    +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE
    ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV
    +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd
    +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
    +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
    +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
    +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited
    +# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited
    +# Label: "QuoVadis Root CA 3 G3"
    +# Serial: 268090761170461462463995952157327242137089239581
    +# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7
    +# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d
    +# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46
    +-----BEGIN CERTIFICATE-----
    +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
    +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
    +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
    +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
    +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG
    +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR
    +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu
    +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR
    +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c
    +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR
    +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k
    +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw
    +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl
    +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp
    +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q
    +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+
    +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
    +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD
    +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
    +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI
    +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv
    +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg
    +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
    +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf
    +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl
    +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+
    +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
    +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
    +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com
    +# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com
    +# Label: "DigiCert Assured ID Root G2"
    +# Serial: 15385348160840213938643033620894905419
    +# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d
    +# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f
    +# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85
    +-----BEGIN CERTIFICATE-----
    +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
    +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
    +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
    +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
    +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
    +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
    +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
    +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
    +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
    +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
    +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
    +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
    +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
    +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
    +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
    +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
    +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
    +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
    +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
    +IhNzbM8m9Yop5w==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com
    +# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com
    +# Label: "DigiCert Assured ID Root G3"
    +# Serial: 15459312981008553731928384953135426796
    +# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb
    +# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89
    +# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2
    +-----BEGIN CERTIFICATE-----
    +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
    +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
    +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
    +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
    +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
    +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
    +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
    +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
    +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
    +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
    +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
    +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
    +6pZjamVFkpUBtA==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
    +# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
    +# Label: "DigiCert Global Root G2"
    +# Serial: 4293743540046975378534879503202253541
    +# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44
    +# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4
    +# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f
    +-----BEGIN CERTIFICATE-----
    +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
    +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
    +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
    +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
    +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
    +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
    +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
    +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
    +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
    +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
    +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
    +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
    +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
    +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
    +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
    +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
    +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
    +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
    +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
    +MrY=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
    +# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
    +# Label: "DigiCert Global Root G3"
    +# Serial: 7089244469030293291760083333884364146
    +# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca
    +# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e
    +# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0
    +-----BEGIN CERTIFICATE-----
    +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
    +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
    +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
    +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
    +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
    +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
    +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
    +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
    +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
    +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
    +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
    +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
    +sycX
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com
    +# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com
    +# Label: "DigiCert Trusted Root G4"
    +# Serial: 7451500558977370777930084869016614236
    +# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49
    +# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4
    +# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88
    +-----BEGIN CERTIFICATE-----
    +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
    +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
    +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
    +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
    +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
    +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
    +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
    +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
    +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
    +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
    +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
    +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
    +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
    +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
    +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
    +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
    +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
    +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
    +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
    +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
    +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
    ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
    +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
    +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
    +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
    +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
    +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
    +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
    +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
    +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited
    +# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited
    +# Label: "COMODO RSA Certification Authority"
    +# Serial: 101909084537582093308941363524873193117
    +# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18
    +# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4
    +# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34
    +-----BEGIN CERTIFICATE-----
    +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
    +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
    +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
    +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5
    +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
    +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
    +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh
    +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR
    +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X
    +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC
    +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV
    +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf
    +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z
    ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w
    +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah
    +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC
    +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf
    +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq
    +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
    +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB
    +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl
    +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM
    +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV
    +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna
    +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ
    +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK
    +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke
    +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL
    +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
    +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
    +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
    +NVOFBkpdn627G190
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
    +# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
    +# Label: "USERTrust RSA Certification Authority"
    +# Serial: 2645093764781058787591871645665788717
    +# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5
    +# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e
    +# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2
    +-----BEGIN CERTIFICATE-----
    +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
    +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
    +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
    +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
    +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
    +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
    +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
    +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
    +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
    +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
    +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
    +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
    +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
    +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
    +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
    +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
    +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
    +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
    +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
    +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
    +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
    +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
    +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
    +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
    +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
    +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
    +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
    +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
    +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
    +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
    +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
    +jjxDah2nGN59PRbxYvnKkKj9
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network
    +# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network
    +# Label: "USERTrust ECC Certification Authority"
    +# Serial: 123013823720199481456569720443997572134
    +# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1
    +# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0
    +# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a
    +-----BEGIN CERTIFICATE-----
    +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
    +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl
    +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT
    +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx
    +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
    +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg
    +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm
    +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo
    +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng
    +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G
    +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD
    +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB
    +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW
    +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5
    +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5
    +# Label: "GlobalSign ECC Root CA - R5"
    +# Serial: 32785792099990507226680698011560947931244
    +# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08
    +# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa
    +# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24
    +-----BEGIN CERTIFICATE-----
    +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
    +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
    +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
    +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
    +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
    +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
    +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
    +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
    +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
    +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
    +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
    +xwy8p2Fp8fc74SrL+SvzZpA3
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust
    +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust
    +# Label: "IdenTrust Commercial Root CA 1"
    +# Serial: 13298821034946342390520003877796839426
    +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7
    +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25
    +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae
    +-----BEGIN CERTIFICATE-----
    +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK
    +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu
    +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw
    +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw
    +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG
    +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT
    +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU
    ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp
    +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1
    +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi
    +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL
    +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK
    +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK
    +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT
    +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv
    +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N
    +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
    +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD
    +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
    +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt
    +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93
    +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3
    ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK
    +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT
    +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq
    +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG
    +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ
    +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A
    +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust
    +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust
    +# Label: "IdenTrust Public Sector Root CA 1"
    +# Serial: 13298821034946342390521976156843933698
    +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba
    +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd
    +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f
    +-----BEGIN CERTIFICATE-----
    +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN
    +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu
    +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN
    +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0
    +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi
    +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7
    +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy
    +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS
    +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF
    +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R
    +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw
    +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy
    +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V
    +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ
    +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV
    +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD
    +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
    +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN
    +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj
    +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV
    +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9
    +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G
    +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW
    +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df
    +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5
    ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ
    +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA
    +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv
    +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
    +# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
    +# Label: "Entrust Root Certification Authority - G2"
    +# Serial: 1246989352
    +# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2
    +# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4
    +# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39
    +-----BEGIN CERTIFICATE-----
    +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
    +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
    +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
    +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
    +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
    +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
    +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
    +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
    +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
    +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
    +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
    +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
    +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
    +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
    +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
    +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
    +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
    +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
    +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
    +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
    +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
    +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
    +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
    +# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
    +# Label: "Entrust Root Certification Authority - EC1"
    +# Serial: 51543124481930649114116133369
    +# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc
    +# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47
    +# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5
    +-----BEGIN CERTIFICATE-----
    +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
    +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
    +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
    +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
    +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
    +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
    +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
    +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
    +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
    +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
    +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
    +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
    +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
    +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
    +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
    +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority
    +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority
    +# Label: "CFCA EV ROOT"
    +# Serial: 407555286
    +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30
    +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83
    +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd
    +-----BEGIN CERTIFICATE-----
    +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD
    +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y
    +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx
    +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j
    +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP
    +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03
    +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL
    +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5
    +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp
    +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz
    +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt
    +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP
    +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot
    +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg
    +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV
    +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv
    +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL
    +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd
    +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB
    +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT
    +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL
    +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS
    +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy
    +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19
    +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d
    +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN
    +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe
    +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z
    +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ
    +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed
    +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed
    +# Label: "OISTE WISeKey Global Root GB CA"
    +# Serial: 157768595616588414422159278966750757568
    +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d
    +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed
    +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6
    +-----BEGIN CERTIFICATE-----
    +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt
    +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg
    +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i
    +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x
    +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG
    +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh
    +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3
    +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx
    +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX
    +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk
    +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P
    +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r
    +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
    +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB
    +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh
    +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5
    +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO
    +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf
    +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
    +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A.
    +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A.
    +# Label: "SZAFIR ROOT CA2"
    +# Serial: 357043034767186914217277344587386743377558296292
    +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99
    +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de
    +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe
    +-----BEGIN CERTIFICATE-----
    +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL
    +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6
    +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw
    +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L
    +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg
    +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN
    +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT
    +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw
    +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6
    +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5
    +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN
    +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
    +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF
    +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw
    +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG
    +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP
    +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy
    +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg
    +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority
    +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority
    +# Label: "Certum Trusted Network CA 2"
    +# Serial: 44979900017204383099463764357512596969
    +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2
    +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92
    +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04
    +-----BEGIN CERTIFICATE-----
    +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB
    +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
    +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG
    +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz
    +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ
    +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp
    +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3
    +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA
    +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn
    +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB
    +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE
    +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E
    +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m
    +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i
    +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW
    +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez
    +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS
    +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n
    +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
    +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC
    +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ
    +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf
    +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29
    +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm
    +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/
    +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb
    +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq
    +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko
    +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj
    +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P
    +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi
    +DrW5viSP
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
    +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
    +# Label: "Hellenic Academic and Research Institutions RootCA 2015"
    +# Serial: 0
    +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce
    +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6
    +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36
    +-----BEGIN CERTIFICATE-----
    +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix
    +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k
    +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT
    +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v
    +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG
    +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh
    +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx
    +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
    +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
    +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA
    +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0
    +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10
    +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C
    +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV
    +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD
    +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6
    +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq
    +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko
    +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc
    +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV
    +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd
    +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I
    +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI
    +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot
    +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V
    +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea
    +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh
    +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ
    +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf
    +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4
    +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK
    +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0
    +vm9qp/UsQu0yrbYhnr68
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
    +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
    +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015"
    +# Serial: 0
    +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef
    +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66
    +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33
    +-----BEGIN CERTIFICATE-----
    +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN
    +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
    +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl
    +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv
    +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ
    +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj
    +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5
    +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0
    +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg
    +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa
    +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC
    +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi
    +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep
    +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof
    +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=ISRG Root X1 O=Internet Security Research Group
    +# Subject: CN=ISRG Root X1 O=Internet Security Research Group
    +# Label: "ISRG Root X1"
    +# Serial: 172886928669790476064670243504169061120
    +# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e
    +# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8
    +# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6
    +-----BEGIN CERTIFICATE-----
    +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
    +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
    +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
    +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
    +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
    +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
    +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
    +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
    +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
    +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
    +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
    +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
    +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
    +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
    +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
    +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
    +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
    +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
    +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
    +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
    +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
    +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
    +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
    +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
    +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
    +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
    +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
    +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
    +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
    +-----END CERTIFICATE-----
    +
    +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM
    +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM
    +# Label: "AC RAIZ FNMT-RCM"
    +# Serial: 485876308206448804701554682760554759
    +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d
    +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20
    +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa
    +-----BEGIN CERTIFICATE-----
    +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx
    +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ
    +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ
    +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG
    +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/
    +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf
    +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz
    +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF
    +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z
    +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC
    +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL
    +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7
    +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS
    +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2
    +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet
    +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw
    +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H
    +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3
    +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD
    +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1
    +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM
    +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf
    +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N
    +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm
    +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp
    +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp
    +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B
    +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok
    +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv
    +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Amazon Root CA 1 O=Amazon
    +# Subject: CN=Amazon Root CA 1 O=Amazon
    +# Label: "Amazon Root CA 1"
    +# Serial: 143266978916655856878034712317230054538369994
    +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6
    +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16
    +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e
    +-----BEGIN CERTIFICATE-----
    +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
    +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
    +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
    +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
    +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
    +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
    +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
    +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
    +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
    +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
    +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
    +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
    +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
    +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
    +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
    +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
    +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
    +rqXRfboQnoZsG4q5WTP468SQvvG5
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Amazon Root CA 2 O=Amazon
    +# Subject: CN=Amazon Root CA 2 O=Amazon
    +# Label: "Amazon Root CA 2"
    +# Serial: 143266982885963551818349160658925006970653239
    +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66
    +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a
    +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4
    +-----BEGIN CERTIFICATE-----
    +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
    +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
    +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
    +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
    +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
    +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
    +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
    +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
    +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
    +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
    +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
    +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
    +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
    +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
    ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
    +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
    +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
    +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
    +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
    ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
    +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
    +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
    +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
    +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
    +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
    +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
    +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
    +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
    +4PsJYGw=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Amazon Root CA 3 O=Amazon
    +# Subject: CN=Amazon Root CA 3 O=Amazon
    +# Label: "Amazon Root CA 3"
    +# Serial: 143266986699090766294700635381230934788665930
    +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87
    +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e
    +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4
    +-----BEGIN CERTIFICATE-----
    +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
    +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
    +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
    +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
    +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
    +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
    +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
    +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
    +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
    +YyRIHN8wfdVoOw==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Amazon Root CA 4 O=Amazon
    +# Subject: CN=Amazon Root CA 4 O=Amazon
    +# Label: "Amazon Root CA 4"
    +# Serial: 143266989758080763974105200630763877849284878
    +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd
    +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be
    +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92
    +-----BEGIN CERTIFICATE-----
    +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
    +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
    +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
    +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
    +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
    +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
    +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
    +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
    +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
    +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
    +1KyLa2tJElMzrdfkviT8tQp21KW8EA==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM
    +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM
    +# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1"
    +# Serial: 1
    +# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49
    +# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca
    +# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16
    +-----BEGIN CERTIFICATE-----
    +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx
    +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp
    +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w
    +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0
    +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy
    +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG
    +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll
    +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU
    +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT
    +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg
    +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7
    +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr
    +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr
    +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X
    +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/
    +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f
    +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH
    +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
    +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh
    +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf
    +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4
    +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c
    +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf
    +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.
    +# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.
    +# Label: "GDCA TrustAUTH R5 ROOT"
    +# Serial: 9009899650740120186
    +# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4
    +# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4
    +# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93
    +-----BEGIN CERTIFICATE-----
    +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE
    +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ
    +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0
    +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV
    +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w
    +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF
    +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj
    +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj
    +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u
    +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj
    +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm
    +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12
    +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP
    +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk
    +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC
    +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA
    +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC
    +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB
    +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg
    +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm
    +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5
    +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry
    +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf
    +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg
    +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io
    +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV
    +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ
    +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq
    +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe
    +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation
    +# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation
    +# Label: "SSL.com Root Certification Authority RSA"
    +# Serial: 8875640296558310041
    +# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29
    +# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb
    +# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69
    +-----BEGIN CERTIFICATE-----
    +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE
    +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK
    +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp
    +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz
    +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
    +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv
    +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN
    +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R
    +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX
    +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC
    +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3
    +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh
    +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF
    +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E
    +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc
    +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8
    +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm
    ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi
    +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV
    +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G
    +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV
    +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc
    +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs
    +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/
    +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0
    +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr
    +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I
    +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y
    +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu
    +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf
    +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY
    +Ic2wBlX7Jz9TkHCpBB5XJ7k=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation
    +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation
    +# Label: "SSL.com Root Certification Authority ECC"
    +# Serial: 8495723813297216424
    +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e
    +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a
    +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65
    +-----BEGIN CERTIFICATE-----
    +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC
    +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
    +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0
    +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz
    +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0
    +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS
    +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB
    +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI
    +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg
    +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud
    +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD
    +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T
    +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+
    +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation
    +# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation
    +# Label: "SSL.com EV Root Certification Authority RSA R2"
    +# Serial: 6248227494352943350
    +# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95
    +# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a
    +# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c
    +-----BEGIN CERTIFICATE-----
    +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV
    +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE
    +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy
    +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy
    +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G
    +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD
    +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy
    +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq
    +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf
    +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa
    +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9
    +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR
    +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA
    +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ
    +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV
    +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO
    +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu
    +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY
    +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV
    +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4
    +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW
    +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5
    +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg
    +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM
    +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz
    +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt
    +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm
    +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK
    +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ
    +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi
    +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07
    +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation
    +# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation
    +# Label: "SSL.com EV Root Certification Authority ECC"
    +# Serial: 3182246526754555285
    +# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90
    +# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d
    +# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8
    +-----BEGIN CERTIFICATE-----
    +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC
    +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
    +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp
    +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx
    +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
    +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv
    +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49
    +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA
    +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku
    +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP
    +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX
    +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ
    +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg
    +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6
    +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6
    +# Label: "GlobalSign Root CA - R6"
    +# Serial: 1417766617973444989252670301619537
    +# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae
    +# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1
    +# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69
    +-----BEGIN CERTIFICATE-----
    +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg
    +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh
    +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx
    +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET
    +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ
    +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI
    +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k
    +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD
    +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw
    +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw
    +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX
    +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2
    +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h
    +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n
    +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY
    +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce
    +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD
    +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu
    +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN
    +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt
    +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61
    +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj
    +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf
    +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz
    +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp
    +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs
    +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v
    +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R
    +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4
    +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed
    +# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed
    +# Label: "OISTE WISeKey Global Root GC CA"
    +# Serial: 44084345621038548146064804565436152554
    +# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23
    +# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31
    +# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d
    +-----BEGIN CERTIFICATE-----
    +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw
    +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91
    +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg
    +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ
    +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu
    +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS
    +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni
    +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W
    +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E
    +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T
    +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV
    +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg
    +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=UCA Global G2 Root O=UniTrust
    +# Subject: CN=UCA Global G2 Root O=UniTrust
    +# Label: "UCA Global G2 Root"
    +# Serial: 124779693093741543919145257850076631279
    +# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8
    +# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a
    +# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c
    +-----BEGIN CERTIFICATE-----
    +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9
    +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH
    +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x
    +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds
    +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr
    +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9
    +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm
    +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R
    +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc
    +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj
    +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY
    +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv
    +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl
    +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6
    +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP
    +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/
    +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV
    +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj
    +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5
    +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl
    +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU
    +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV
    +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj
    +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb
    +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg
    +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI
    ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy
    +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX
    +UB+K+wb1whnw0A==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=UCA Extended Validation Root O=UniTrust
    +# Subject: CN=UCA Extended Validation Root O=UniTrust
    +# Label: "UCA Extended Validation Root"
    +# Serial: 106100277556486529736699587978573607008
    +# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2
    +# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a
    +# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24
    +-----BEGIN CERTIFICATE-----
    +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH
    +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF
    +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx
    +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV
    +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB
    +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog
    +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS
    +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop
    +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk
    +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi
    +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj
    +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz
    +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/
    +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G
    +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs
    +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD
    +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T
    +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN
    +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR
    +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ
    +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5
    +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp
    +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s
    +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj
    +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO
    +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C
    +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx
    +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM
    +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036
    +# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036
    +# Label: "Certigna Root CA"
    +# Serial: 269714418870597844693661054334862075617
    +# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77
    +# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43
    +# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68
    +-----BEGIN CERTIFICATE-----
    +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw
    +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw
    +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x
    +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD
    +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX
    +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
    +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO
    +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M
    +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu
    +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm
    +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh
    +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf
    +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz
    +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT
    +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k
    +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5
    +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB
    +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
    +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of
    +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov
    +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo
    +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr
    +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq
    +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L
    +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG
    +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6
    +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB
    +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi
    +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1
    +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v
    +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63
    +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh
    +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw
    +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI
    +# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI
    +# Label: "emSign Root CA - G1"
    +# Serial: 235931866688319308814040
    +# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac
    +# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c
    +# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67
    +-----BEGIN CERTIFICATE-----
    +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD
    +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU
    +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH
    +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO
    +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv
    +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN
    +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz
    +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO
    +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq
    +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM
    +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt
    +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB
    +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD
    +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x
    +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM
    +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d
    +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH
    +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby
    +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx
    +iN66zB+Afko=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI
    +# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI
    +# Label: "emSign ECC Root CA - G3"
    +# Serial: 287880440101571086945156
    +# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40
    +# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1
    +# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b
    +-----BEGIN CERTIFICATE-----
    +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG
    +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo
    +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g
    +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ
    +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s
    +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw
    +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0
    +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS
    +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB
    +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
    +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB
    +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD
    ++JbNR6iC8hZVdyR+EhCVBCyj
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI
    +# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI
    +# Label: "emSign Root CA - C1"
    +# Serial: 825510296613316004955058
    +# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68
    +# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01
    +# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f
    +-----BEGIN CERTIFICATE-----
    +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG
    +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg
    +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw
    +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln
    +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v
    +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ
    +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ
    +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH
    +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH
    +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c
    +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1
    +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq
    +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
    +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87
    +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4
    +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG
    +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT
    ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo
    +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI
    +# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI
    +# Label: "emSign ECC Root CA - C3"
    +# Serial: 582948710642506000014504
    +# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5
    +# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66
    +# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3
    +-----BEGIN CERTIFICATE-----
    +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG
    +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx
    +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw
    +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln
    +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND
    +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci
    +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti
    +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O
    +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB
    +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c
    +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J
    +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post
    +# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post
    +# Label: "Hongkong Post Root CA 3"
    +# Serial: 46170865288971385588281144162979347873371282084
    +# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0
    +# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02
    +# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6
    +-----BEGIN CERTIFICATE-----
    +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL
    +BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ
    +SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n
    +a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5
    +NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT
    +CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u
    +Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
    +AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO
    +dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI
    +VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV
    +9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY
    +2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY
    +vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt
    +bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb
    +x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+
    +l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK
    +TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj
    +Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP
    +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e
    +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw
    +DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG
    +7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk
    +MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr
    +gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk
    +GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS
    +3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm
    +Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+
    +l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c
    +JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP
    +L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa
    +LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG
    +mpv0
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only
    +# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only
    +# Label: "Entrust Root Certification Authority - G4"
    +# Serial: 289383649854506086828220374796556676440
    +# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88
    +# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01
    +# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88
    +-----BEGIN CERTIFICATE-----
    +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw
    +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL
    +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg
    +MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw
    +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0
    +MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT
    +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1
    +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ
    +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg
    +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B
    +AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ
    +2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E
    +T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j
    +5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM
    +C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T
    +DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX
    +wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A
    +2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm
    +nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8
    +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl
    +N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj
    +c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
    +VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS
    +5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS
    +Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr
    +hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/
    +B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI
    +AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw
    +H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+
    +b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk
    +2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol
    +IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk
    +5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY
    +n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation
    +# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation
    +# Label: "Microsoft ECC Root Certificate Authority 2017"
    +# Serial: 136839042543790627607696632466672567020
    +# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67
    +# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5
    +# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02
    +-----BEGIN CERTIFICATE-----
    +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw
    +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD
    +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw
    +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV
    +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy
    +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq
    +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR
    +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb
    +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E
    +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3
    +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV
    +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB
    +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation
    +# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation
    +# Label: "Microsoft RSA Root Certificate Authority 2017"
    +# Serial: 40975477897264996090493496164228220339
    +# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47
    +# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74
    +# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0
    +-----BEGIN CERTIFICATE-----
    +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl
    +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw
    +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
    +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG
    +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N
    +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi
    +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ
    +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0
    +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1
    +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm
    +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ
    +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc
    +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG
    +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6
    +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K
    +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH
    ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q
    +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/
    +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC
    +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC
    +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC
    +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6
    +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh
    +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2
    +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3
    +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR
    +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp
    +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9
    +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN
    +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB
    +RA+GsCyRxj3qrg+E
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd.
    +# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd.
    +# Label: "e-Szigno Root CA 2017"
    +# Serial: 411379200276854331539784714
    +# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98
    +# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1
    +# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99
    +-----BEGIN CERTIFICATE-----
    +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV
    +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk
    +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv
    +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ
    +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg
    +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v
    +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv
    +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H
    +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
    +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB
    +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo
    +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ
    ++efcMQ==
    +-----END CERTIFICATE-----
    +
    +# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2
    +# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2
    +# Label: "certSIGN Root CA G2"
    +# Serial: 313609486401300475190
    +# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7
    +# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32
    +# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05
    +-----BEGIN CERTIFICATE-----
    +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
    +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g
    +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ
    +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ
    +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF
    +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw
    +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ
    +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp
    +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs
    +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW
    +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P
    +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF
    +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx
    +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy
    +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C
    +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB
    +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ
    +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq
    +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC
    +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl
    +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0
    +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c
    +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk
    +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO
    +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj
    +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk
    +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE
    +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX
    +QRBdJ3NghVdJIgc=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc.
    +# Subject: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc.
    +# Label: "Trustwave Global Certification Authority"
    +# Serial: 1846098327275375458322922162
    +# MD5 Fingerprint: f8:1c:18:2d:2f:ba:5f:6d:a1:6c:bc:c7:ab:91:c7:0e
    +# SHA1 Fingerprint: 2f:8f:36:4f:e1:58:97:44:21:59:87:a5:2a:9a:d0:69:95:26:7f:b5
    +# SHA256 Fingerprint: 97:55:20:15:f5:dd:fc:3c:87:88:c0:06:94:45:55:40:88:94:45:00:84:f1:00:86:70:86:bc:1a:2b:b5:8d:c8
    +-----BEGIN CERTIFICATE-----
    +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw
    +CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x
    +ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1
    +c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx
    +OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI
    +SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI
    +b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp
    +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
    +ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn
    +swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu
    +7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8
    +1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW
    +80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP
    +JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l
    +RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw
    +hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10
    +coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc
    +BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n
    +twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud
    +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud
    +DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W
    +0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe
    +uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q
    +lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB
    +aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE
    +sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT
    +MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe
    +qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh
    +VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8
    +h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9
    +EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK
    +yeC2nOnOcXHebD8WpHk=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc.
    +# Subject: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc.
    +# Label: "Trustwave Global ECC P256 Certification Authority"
    +# Serial: 4151900041497450638097112925
    +# MD5 Fingerprint: 5b:44:e3:8d:5d:36:86:26:e8:0d:05:d2:59:a7:83:54
    +# SHA1 Fingerprint: b4:90:82:dd:45:0c:be:8b:5b:b1:66:d3:e2:a4:08:26:cd:ed:42:cf
    +# SHA256 Fingerprint: 94:5b:bc:82:5e:a5:54:f4:89:d1:fd:51:a7:3d:df:2e:a6:24:ac:70:19:a0:52:05:22:5c:22:a7:8c:cf:a8:b4
    +-----BEGIN CERTIFICATE-----
    +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD
    +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
    +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
    +YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
    +NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G
    +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
    +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
    +Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG
    +SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN
    +FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w
    +DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw
    +CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh
    +DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc.
    +# Subject: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc.
    +# Label: "Trustwave Global ECC P384 Certification Authority"
    +# Serial: 2704997926503831671788816187
    +# MD5 Fingerprint: ea:cf:60:c4:3b:b9:15:29:40:a1:97:ed:78:27:93:d6
    +# SHA1 Fingerprint: e7:f3:a3:c8:cf:6f:c3:04:2e:6d:0e:67:32:c5:9e:68:95:0d:5e:d2
    +# SHA256 Fingerprint: 55:90:38:59:c8:c0:c3:eb:b8:75:9e:ce:4e:25:57:22:5f:f5:75:8b:bd:38:eb:d4:82:76:60:1e:1b:d5:80:97
    +-----BEGIN CERTIFICATE-----
    +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD
    +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
    +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
    +YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
    +NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G
    +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
    +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
    +Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB
    +BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ
    +j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF
    +1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G
    +A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3
    +AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC
    +MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu
    +Sw==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp.
    +# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp.
    +# Label: "NAVER Global Root Certification Authority"
    +# Serial: 9013692873798656336226253319739695165984492813
    +# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b
    +# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1
    +# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65
    +-----BEGIN CERTIFICATE-----
    +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM
    +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG
    +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0
    +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx
    +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD
    +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB
    +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA
    +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH
    +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE
    +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz
    +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP
    +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq
    +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf
    +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG
    +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo
    +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a
    +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K
    +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I
    +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
    +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN
    +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj
    +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm
    ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL
    +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe
    +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7
    +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8
    +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR
    +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX
    +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO
    +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul
    +9XXeifdy
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres
    +# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres
    +# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS"
    +# Serial: 131542671362353147877283741781055151509
    +# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb
    +# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a
    +# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb
    +-----BEGIN CERTIFICATE-----
    +MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw
    +CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw
    +FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S
    +Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5
    +MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL
    +DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS
    +QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB
    +BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH
    +sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK
    +Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
    +VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu
    +SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC
    +MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy
    +v+c=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa
    +# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa
    +# Label: "GlobalSign Root R46"
    +# Serial: 1552617688466950547958867513931858518042577
    +# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef
    +# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90
    +# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9
    +-----BEGIN CERTIFICATE-----
    +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA
    +MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD
    +VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy
    +MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt
    +c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB
    +AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ
    +OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG
    +vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud
    +316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo
    +0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE
    +y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF
    +zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE
    ++cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN
    +I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs
    +x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa
    +ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC
    +4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
    +HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4
    +7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg
    +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti
    +2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk
    +pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF
    +FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt
    +rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk
    +ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5
    +u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP
    +4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6
    +N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3
    +vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa
    +# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa
    +# Label: "GlobalSign Root E46"
    +# Serial: 1552617690338932563915843282459653771421763
    +# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f
    +# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84
    +# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58
    +-----BEGIN CERTIFICATE-----
    +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx
    +CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD
    +ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw
    +MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex
    +HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
    +IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq
    +R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd
    +yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
    +DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ
    +7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8
    ++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH
    +# Subject: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH
    +# Label: "GLOBALTRUST 2020"
    +# Serial: 109160994242082918454945253
    +# MD5 Fingerprint: 8a:c7:6f:cb:6d:e3:cc:a2:f1:7c:83:fa:0e:78:d7:e8
    +# SHA1 Fingerprint: d0:67:c1:13:51:01:0c:aa:d0:c7:6a:65:37:31:16:26:4f:53:71:a2
    +# SHA256 Fingerprint: 9a:29:6a:51:82:d1:d4:51:a2:e3:7f:43:9b:74:da:af:a2:67:52:33:29:f9:0f:9a:0d:20:07:c3:34:e2:3c:9a
    +-----BEGIN CERTIFICATE-----
    +MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG
    +A1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw
    +FwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx
    +MDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u
    +aXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq
    +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b
    +RatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z
    +YybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3
    +QWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw
    +yJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+
    +BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ
    +SaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH
    +r96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0
    +4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me
    +dKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw
    +q7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2
    +nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
    +AQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu
    +H9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA
    +VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC
    +XtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd
    +6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf
    ++I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi
    +kvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7
    +wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB
    +TI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C
    +MUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn
    +4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I
    +aFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy
    +qfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz
    +# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz
    +# Label: "ANF Secure Server Root CA"
    +# Serial: 996390341000653745
    +# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96
    +# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74
    +# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99
    +-----BEGIN CERTIFICATE-----
    +MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV
    +BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk
    +YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV
    +BAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3QgQ0EwHhcNMTkwOTA0MTAwMDM4WhcN
    +MzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEwMQswCQYDVQQGEwJF
    +UzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQwEgYD
    +VQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9v
    +dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCj
    +cqQZAZ2cC4Ffc0m6p6zzBE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9q
    +yGFOtibBTI3/TO80sh9l2Ll49a2pcbnvT1gdpd50IJeh7WhM3pIXS7yr/2WanvtH
    +2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcvB2VSAKduyK9o7PQUlrZX
    +H1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXsezx76W0OL
    +zc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyR
    +p1RMVwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQz
    +W7i1o0TJrH93PB0j7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/
    +SiOL9V8BY9KHcyi1Swr1+KuCLH5zJTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJn
    +LNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe8TZBAQIvfXOn3kLMTOmJDVb3
    +n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVOHj1tyRRM4y5B
    +u8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj
    +o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAO
    +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
    +AgEATh65isagmD9uw2nAalxJUqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L
    +9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzxj6ptBZNscsdW699QIyjlRRA96Gej
    +rw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDtdD+4E5UGUcjohybK
    +pFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM5gf0
    +vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjq
    +OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ
    +/zo1PqVUSlJZS2Db7v54EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ9
    +2zg/LFis6ELhDtjTO0wugumDLmsx2d1Hhk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI
    ++PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2
    +MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo
    +tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority
    +# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority
    +# Label: "Certum EC-384 CA"
    +# Serial: 160250656287871593594747141429395092468
    +# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1
    +# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed
    +# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6
    +-----BEGIN CERTIFICATE-----
    +MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw
    +CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw
    +JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT
    +EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0
    +WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT
    +LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX
    +BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE
    +KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm
    +Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj
    +QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8
    +EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J
    +UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn
    +nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority
    +# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority
    +# Label: "Certum Trusted Root CA"
    +# Serial: 40870380103424195783807378461123655149
    +# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29
    +# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5
    +# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd
    +-----BEGIN CERTIFICATE-----
    +MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6
    +MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu
    +MScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNV
    +BAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwHhcNMTgwMzE2MTIxMDEzWhcNNDMw
    +MzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEg
    +U3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRo
    +b3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqG
    +SIb3DQEBAQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZ
    +n0EGze2jusDbCSzBfN8pfktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/q
    +p1x4EaTByIVcJdPTsuclzxFUl6s1wB52HO8AU5853BSlLCIls3Jy/I2z5T4IHhQq
    +NwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2fJmItdUDmj0VDT06qKhF
    +8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGtg/BKEiJ3
    +HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGa
    +mqi4NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi
    +7VdNIuJGmj8PkTQkfVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSF
    +ytKAQd8FqKPVhJBPC/PgP5sZ0jeJP/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0P
    +qafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSYnjYJdmZm/Bo/6khUHL4wvYBQ
    +v3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHKHRzQ+8S1h9E6
    +Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1
    +vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQAD
    +ggIBAEii1QALLtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4
    +WxmB82M+w85bj/UvXgF2Ez8sALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvo
    +zMrnadyHncI013nR03e4qllY/p0m+jiGPp2Kh2RX5Rc64vmNueMzeMGQ2Ljdt4NR
    +5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8CYyqOhNf6DR5UMEQ
    +GfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA4kZf
    +5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq
    +0Uc9NneoWWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7D
    +P78v3DSk+yshzWePS/Tj6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTM
    +qJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmTOPQD8rv7gmsHINFSH5pkAnuYZttcTVoP
    +0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZckbxJF0WddCajJFdr60qZf
    +E2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique
    +# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique
    +# Label: "TunTrust Root CA"
    +# Serial: 108534058042236574382096126452369648152337120275
    +# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4
    +# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb
    +# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41
    +-----BEGIN CERTIFICATE-----
    +MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL
    +BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg
    +Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv
    +b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG
    +EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u
    +IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ
    +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ
    +n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd
    +2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF
    +VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ
    +GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF
    +li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU
    +r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2
    +eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb
    +MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg
    +jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB
    +7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW
    +5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE
    +ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0
    +90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z
    +xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu
    +QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4
    +FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH
    +22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP
    +xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn
    +dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5
    +Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b
    +nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ
    +CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH
    +u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj
    +d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA
    +# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA
    +# Label: "HARICA TLS RSA Root CA 2021"
    +# Serial: 76817823531813593706434026085292783742
    +# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91
    +# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d
    +# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d
    +-----BEGIN CERTIFICATE-----
    +MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs
    +MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
    +c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg
    +Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL
    +MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl
    +YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv
    +b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l
    +mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE
    +4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv
    +a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M
    +pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw
    +Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b
    +LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY
    +AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB
    +AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq
    +E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr
    +W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ
    +CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF
    +MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE
    +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU
    +X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3
    +f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja
    +H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP
    +JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P
    +zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt
    +jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0
    +/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT
    +BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79
    +aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW
    +xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU
    +63ZTGI0RmLo=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA
    +# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA
    +# Label: "HARICA TLS ECC Root CA 2021"
    +# Serial: 137515985548005187474074462014555733966
    +# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0
    +# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48
    +# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01
    +-----BEGIN CERTIFICATE-----
    +MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw
    +CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh
    +cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v
    +dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG
    +A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj
    +aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg
    +Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7
    +KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y
    +STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw
    +AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD
    +AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw
    +SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN
    +nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
    +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
    +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068"
    +# Serial: 1977337328857672817
    +# MD5 Fingerprint: 4e:6e:9b:54:4c:ca:b7:fa:48:e4:90:b1:15:4b:1c:a3
    +# SHA1 Fingerprint: 0b:be:c2:27:22:49:cb:39:aa:db:35:5c:53:e3:8c:ae:78:ff:b6:fe
    +# SHA256 Fingerprint: 57:de:05:83:ef:d2:b2:6e:03:61:da:99:da:9d:f4:64:8d:ef:7e:e8:44:1c:3b:72:8a:fa:9b:cd:e0:f9:b2:6a
    +-----BEGIN CERTIFICATE-----
    +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE
    +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
    +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1
    +MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
    +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
    +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
    +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
    +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
    +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
    +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
    +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
    +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
    +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
    +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
    +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
    +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
    +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc
    +tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd
    +IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j
    +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC
    +AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw
    +ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m
    +iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF
    +Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ
    +hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P
    +Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE
    +EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV
    +1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t
    +CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR
    +5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw
    +f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9
    +ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK
    +GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd.
    +# Subject: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd.
    +# Label: "vTrus ECC Root CA"
    +# Serial: 630369271402956006249506845124680065938238527194
    +# MD5 Fingerprint: de:4b:c1:f5:52:8c:9b:43:e1:3e:8f:55:54:17:8d:85
    +# SHA1 Fingerprint: f6:9c:db:b0:fc:f6:02:13:b6:52:32:a6:a3:91:3f:16:70:da:c3:e1
    +# SHA256 Fingerprint: 30:fb:ba:2c:32:23:8e:2a:98:54:7a:f9:79:31:e5:50:42:8b:9b:3f:1c:8e:eb:66:33:dc:fa:86:c5:b2:7d:d3
    +-----BEGIN CERTIFICATE-----
    +MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw
    +RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY
    +BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz
    +MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u
    +LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF
    +K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0
    +v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd
    +e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD
    +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw
    +V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA
    +AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG
    +GJTO
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=vTrus Root CA O=iTrusChina Co.,Ltd.
    +# Subject: CN=vTrus Root CA O=iTrusChina Co.,Ltd.
    +# Label: "vTrus Root CA"
    +# Serial: 387574501246983434957692974888460947164905180485
    +# MD5 Fingerprint: b8:c9:37:df:fa:6b:31:84:64:c5:ea:11:6a:1b:75:fc
    +# SHA1 Fingerprint: 84:1a:69:fb:f5:cd:1a:25:34:13:3d:e3:f8:fc:b8:99:d0:c9:14:b7
    +# SHA256 Fingerprint: 8a:71:de:65:59:33:6f:42:6c:26:e5:38:80:d0:0d:88:a1:8d:a4:c6:a9:1f:0d:cb:61:94:e2:06:c5:c9:63:87
    +-----BEGIN CERTIFICATE-----
    +MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL
    +BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x
    +FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx
    +MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s
    +THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD
    +ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc
    +IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU
    +AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+
    +GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9
    +8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH
    +flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt
    +J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim
    +0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN
    +pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ
    +UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW
    +OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB
    +AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E
    +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet
    +8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd
    +nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j
    +bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM
    +Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv
    +TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS
    +S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr
    +I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9
    +b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB
    +UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P
    +Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven
    +sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=ISRG Root X2 O=Internet Security Research Group
    +# Subject: CN=ISRG Root X2 O=Internet Security Research Group
    +# Label: "ISRG Root X2"
    +# Serial: 87493402998870891108772069816698636114
    +# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5
    +# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af
    +# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70
    +-----BEGIN CERTIFICATE-----
    +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
    +CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
    +R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
    +MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
    +ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
    +EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
    ++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
    +ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
    +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
    +zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
    +tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
    +/q4AaOeMSQ+2b1tbFfLn
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd.
    +# Subject: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd.
    +# Label: "HiPKI Root CA - G1"
    +# Serial: 60966262342023497858655262305426234976
    +# MD5 Fingerprint: 69:45:df:16:65:4b:e8:68:9a:8f:76:5f:ff:80:9e:d3
    +# SHA1 Fingerprint: 6a:92:e4:a8:ee:1b:ec:96:45:37:e3:29:57:49:cd:96:e3:e5:d2:60
    +# SHA256 Fingerprint: f0:15:ce:3c:c2:39:bf:ef:06:4b:e9:f1:d2:c4:17:e1:a0:26:4a:0a:94:be:1f:0c:8d:12:18:64:eb:69:49:cc
    +-----BEGIN CERTIFICATE-----
    +MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP
    +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
    +ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa
    +Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3
    +YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx
    +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw
    +qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv
    +Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6
    +lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz
    +Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ
    +KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK
    +FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj
    +HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr
    +y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ
    +/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM
    +a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6
    +fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
    +HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG
    +SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi
    +7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc
    +SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza
    +ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc
    +XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg
    +iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho
    +L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF
    +Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr
    +kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+
    +vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU
    +YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4
    +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4
    +# Label: "GlobalSign ECC Root CA - R4"
    +# Serial: 159662223612894884239637590694
    +# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc
    +# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28
    +# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2
    +-----BEGIN CERTIFICATE-----
    +MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD
    +VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh
    +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw
    +MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g
    +UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT
    +BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx
    +uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV
    +HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/
    ++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147
    +bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC
    +# Subject: CN=GTS Root R1 O=Google Trust Services LLC
    +# Label: "GTS Root R1"
    +# Serial: 159662320309726417404178440727
    +# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40
    +# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a
    +# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf
    +-----BEGIN CERTIFICATE-----
    +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
    +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
    +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
    +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
    +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA
    +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo
    +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w
    +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw
    +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl
    +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH
    +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8
    +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk
    +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92
    +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p
    +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN
    +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID
    +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
    +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb
    +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe
    +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy
    +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4
    +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J
    +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef
    +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/
    +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
    +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ
    +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
    +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
    +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=GTS Root R2 O=Google Trust Services LLC
    +# Subject: CN=GTS Root R2 O=Google Trust Services LLC
    +# Label: "GTS Root R2"
    +# Serial: 159662449406622349769042896298
    +# MD5 Fingerprint: 1e:39:c0:53:e6:1e:29:82:0b:ca:52:55:36:5d:57:dc
    +# SHA1 Fingerprint: 9a:44:49:76:32:db:de:fa:d0:bc:fb:5a:7b:17:bd:9e:56:09:24:94
    +# SHA256 Fingerprint: 8d:25:cd:97:22:9d:bf:70:35:6b:da:4e:b3:cc:73:40:31:e2:4c:f0:0f:af:cf:d3:2d:c7:6e:b5:84:1c:7e:a8
    +-----BEGIN CERTIFICATE-----
    +MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw
    +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
    +MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
    +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
    +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA
    +A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt
    +nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY
    +6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu
    +MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k
    +RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg
    +f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV
    ++3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo
    +dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW
    +Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa
    +G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq
    +gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID
    +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
    +FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H
    +vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8
    +0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC
    +B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u
    +NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg
    +yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev
    +HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6
    +xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR
    +TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg
    +JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV
    +7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl
    +6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC
    +# Subject: CN=GTS Root R3 O=Google Trust Services LLC
    +# Label: "GTS Root R3"
    +# Serial: 159662495401136852707857743206
    +# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73
    +# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46
    +# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48
    +-----BEGIN CERTIFICATE-----
    +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD
    +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
    +A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
    +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz
    +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
    +AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G
    +jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2
    +4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
    +BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7
    +VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm
    +ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC
    +# Subject: CN=GTS Root R4 O=Google Trust Services LLC
    +# Label: "GTS Root R4"
    +# Serial: 159662532700760215368942768210
    +# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8
    +# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47
    +# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d
    +-----BEGIN CERTIFICATE-----
    +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD
    +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
    +A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
    +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz
    +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
    +AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi
    +QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR
    +HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
    +BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D
    +9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8
    +p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Telia Root CA v2 O=Telia Finland Oyj
    +# Subject: CN=Telia Root CA v2 O=Telia Finland Oyj
    +# Label: "Telia Root CA v2"
    +# Serial: 7288924052977061235122729490515358
    +# MD5 Fingerprint: 0e:8f:ac:aa:82:df:85:b1:f4:dc:10:1c:fc:99:d9:48
    +# SHA1 Fingerprint: b9:99:cd:d1:73:50:8a:c4:47:05:08:9c:8c:88:fb:be:a0:2b:40:cd
    +# SHA256 Fingerprint: 24:2b:69:74:2f:cb:1e:5b:2a:bf:98:89:8b:94:57:21:87:54:4e:5b:4d:99:11:78:65:73:62:1f:6a:74:b8:2c
    +-----BEGIN CERTIFICATE-----
    +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx
    +CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE
    +AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1
    +NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ
    +MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
    +ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq
    +AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9
    +vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9
    +lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD
    +n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT
    +7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o
    +6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC
    +TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6
    +WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R
    +DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI
    +pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj
    +YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy
    +rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
    +AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ
    +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi
    +0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM
    +A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS
    +SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K
    +TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF
    +6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er
    +3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt
    +Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT
    +VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW
    +ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA
    +rBPuUBQemMc=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH
    +# Subject: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH
    +# Label: "D-TRUST BR Root CA 1 2020"
    +# Serial: 165870826978392376648679885835942448534
    +# MD5 Fingerprint: b5:aa:4b:d5:ed:f7:e3:55:2e:8f:72:0a:f3:75:b8:ed
    +# SHA1 Fingerprint: 1f:5b:98:f0:e3:b5:f7:74:3c:ed:e6:b0:36:7d:32:cd:f4:09:41:67
    +# SHA256 Fingerprint: e5:9a:aa:81:60:09:c2:2b:ff:5b:25:ba:d3:7d:f3:06:f0:49:79:7c:1f:81:d8:5a:b0:89:e6:57:bd:8f:00:44
    +-----BEGIN CERTIFICATE-----
    +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw
    +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS
    +VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5
    +NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG
    +A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB
    +BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS
    +zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0
    +QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/
    +VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g
    +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf
    +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l
    +dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1
    +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO
    +PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW
    +wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV
    +dWNbFJWcHwHP2NVypw87
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH
    +# Subject: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH
    +# Label: "D-TRUST EV Root CA 1 2020"
    +# Serial: 126288379621884218666039612629459926992
    +# MD5 Fingerprint: 8c:2d:9d:70:9f:48:99:11:06:11:fb:e9:cb:30:c0:6e
    +# SHA1 Fingerprint: 61:db:8c:21:59:69:03:90:d8:7c:9c:12:86:54:cf:9d:3d:f4:dd:07
    +# SHA256 Fingerprint: 08:17:0d:1a:a3:64:53:90:1a:2f:95:92:45:e3:47:db:0c:8d:37:ab:aa:bc:56:b8:1a:a1:00:dc:95:89:70:db
    +-----BEGIN CERTIFICATE-----
    +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw
    +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS
    +VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5
    +NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG
    +A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB
    +BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC
    +/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD
    +wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3
    +OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g
    +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf
    +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l
    +dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1
    +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO
    +PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA
    +y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb
    +gfM0agPnIjhQW+0ZT0MW
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc.
    +# Subject: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc.
    +# Label: "DigiCert TLS ECC P384 Root G5"
    +# Serial: 13129116028163249804115411775095713523
    +# MD5 Fingerprint: d3:71:04:6a:43:1c:db:a6:59:e1:a8:a3:aa:c5:71:ed
    +# SHA1 Fingerprint: 17:f3:de:5e:9f:0f:19:e9:8e:f6:1f:32:26:6e:20:c4:07:ae:30:ee
    +# SHA256 Fingerprint: 01:8e:13:f0:77:25:32:cf:80:9b:d1:b1:72:81:86:72:83:fc:48:c6:e1:3b:e9:c6:98:12:85:4a:49:0c:1b:05
    +-----BEGIN CERTIFICATE-----
    +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw
    +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp
    +Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2
    +MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ
    +bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG
    +ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS
    +7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp
    +0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS
    +B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49
    +BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ
    +LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4
    +DXZDjC5Ty3zfDBeWUA==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc.
    +# Subject: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc.
    +# Label: "DigiCert TLS RSA4096 Root G5"
    +# Serial: 11930366277458970227240571539258396554
    +# MD5 Fingerprint: ac:fe:f7:34:96:a9:f2:b3:b4:12:4b:e4:27:41:6f:e1
    +# SHA1 Fingerprint: a7:88:49:dc:5d:7c:75:8c:8c:de:39:98:56:b3:aa:d0:b2:a5:71:35
    +# SHA256 Fingerprint: 37:1a:00:dc:05:33:b3:72:1a:7e:eb:40:e8:41:9e:70:79:9d:2b:0a:0f:2c:1d:80:69:31:65:f7:ce:c4:ad:75
    +-----BEGIN CERTIFICATE-----
    +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN
    +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT
    +HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN
    +NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs
    +IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi
    +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+
    +ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0
    +2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp
    +wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM
    +pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD
    +nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po
    +sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx
    +Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd
    +Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX
    +KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe
    +XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL
    +tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv
    +TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN
    +AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw
    +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H
    +PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF
    +O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ
    +REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik
    +AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv
    +/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+
    +p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw
    +MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF
    +qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK
    +ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Certainly Root R1 O=Certainly
    +# Subject: CN=Certainly Root R1 O=Certainly
    +# Label: "Certainly Root R1"
    +# Serial: 188833316161142517227353805653483829216
    +# MD5 Fingerprint: 07:70:d4:3e:82:87:a0:fa:33:36:13:f4:fa:33:e7:12
    +# SHA1 Fingerprint: a0:50:ee:0f:28:71:f4:27:b2:12:6d:6f:50:96:25:ba:cc:86:42:af
    +# SHA256 Fingerprint: 77:b8:2c:d8:64:4c:43:05:f7:ac:c5:cb:15:6b:45:67:50:04:03:3d:51:c6:0c:62:02:a8:e0:c3:34:67:d3:a0
    +-----BEGIN CERTIFICATE-----
    +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw
    +PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy
    +dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9
    +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0
    +YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2
    +1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT
    +vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed
    +aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0
    +1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5
    +r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5
    +cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ
    +wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ
    +6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA
    +2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH
    +Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR
    +eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB
    +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u
    +d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr
    +PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d
    +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi
    +1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd
    +rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di
    +taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7
    +lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj
    +yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn
    +Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy
    +yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n
    +wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6
    +OV+KmalBWQewLK8=
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Certainly Root E1 O=Certainly
    +# Subject: CN=Certainly Root E1 O=Certainly
    +# Label: "Certainly Root E1"
    +# Serial: 8168531406727139161245376702891150584
    +# MD5 Fingerprint: 0a:9e:ca:cd:3e:52:50:c6:36:f3:4b:a3:ed:a7:53:e9
    +# SHA1 Fingerprint: f9:e1:6d:dc:01:89:cf:d5:82:45:63:3e:c5:37:7d:c2:eb:93:6f:2b
    +# SHA256 Fingerprint: b4:58:5f:22:e4:ac:75:6a:4e:86:12:a1:36:1c:5d:9d:03:1a:93:fd:84:fe:bb:77:8f:a3:06:8b:0f:c4:2d:c2
    +-----BEGIN CERTIFICATE-----
    +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw
    +CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu
    +bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ
    +BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s
    +eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK
    ++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2
    +QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E
    +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4
    +hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm
    +ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG
    +BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center
    +# Subject: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center
    +# Label: "E-Tugra Global Root CA RSA v3"
    +# Serial: 75951268308633135324246244059508261641472512052
    +# MD5 Fingerprint: 22:be:10:f6:c2:f8:03:88:73:5f:33:29:47:28:47:a4
    +# SHA1 Fingerprint: e9:a8:5d:22:14:52:1c:5b:aa:0a:b4:be:24:6a:23:8a:c9:ba:e2:a9
    +# SHA256 Fingerprint: ef:66:b0:b1:0a:3c:db:9f:2e:36:48:c7:6b:d2:af:18:ea:d2:bf:e6:f1:17:65:5e:28:c4:06:0d:a1:a3:f4:c2
    +-----BEGIN CERTIFICATE-----
    +MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQEL
    +BQAwgYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUt
    +VHVncmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYw
    +JAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIFJTQSB2MzAeFw0yMDAzMTgw
    +OTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMG
    +QW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1
    +Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBD
    +QSBSU0EgdjMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J7
    +7gnJY9LTQ91ew6aEOErxjYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscx
    +uj7X/iWpKo429NEvx7epXTPcMHD4QGxLsqYxYdE0PD0xesevxKenhOGXpOhL9hd8
    +7jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF/YP9f4RtNGx/ardLAQO/
    +rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8qQedmCeFL
    +l+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bG
    +wzrwbMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4
    +znKS4iicvObpCdg604nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBO
    +M/J+JjKsBY04pOZ2PJ8QaQ5tndLBeSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK
    +5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiMbIedBi3x7+PmBvrFZhNb/FAH
    +nnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbgh3cXTJ2w2Amo
    +DVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD
    +AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSy
    +tK7mLfcm1ap1LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEL
    +BQADggIBAImocn+M684uGMQQgC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ
    +6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN438o2Fi+CiJ+8EUdPdk3ILY7r3y18
    +Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/qln0F7psTpURs+APQ
    +3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3sSdPk
    +vmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn9
    +9t2HVhjYsCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQ
    +mhty3QUBjYZgv6Rn7rWlDdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YA
    +VSgU7NbHEqIbZULpkejLPoeJVF3Zr52XnGnnCv8PWniLYypMfUeUP95L6VPQMPHF
    +9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFHIK+WEj5jlB0E5y67hscM
    +moi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiXYY60MGo8
    +bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center
    +# Subject: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center
    +# Label: "E-Tugra Global Root CA ECC v3"
    +# Serial: 218504919822255052842371958738296604628416471745
    +# MD5 Fingerprint: 46:bc:81:bb:f1:b5:1e:f7:4b:96:bc:14:e2:e7:27:64
    +# SHA1 Fingerprint: 8a:2f:af:57:53:b1:b0:e6:a1:04:ec:5b:6a:69:71:6d:f6:1c:e2:84
    +# SHA256 Fingerprint: 87:3f:46:85:fa:7f:56:36:25:25:2e:6d:36:bc:d7:f1:6f:c2:49:51:f2:64:e4:7e:1b:95:4f:49:08:cd:ca:13
    +-----BEGIN CERTIFICATE-----
    +MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMw
    +gYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVn
    +cmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYD
    +VQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIEVDQyB2MzAeFw0yMDAzMTgwOTQ2
    +NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMGQW5r
    +YXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1Z3Jh
    +IFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBF
    +Q0MgdjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQ
    +KczLWYHMjLiSF4mDKpL2w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YK
    +fWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMB
    +Af8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQzPUwHQYDVR0OBBYEFP+C
    +MXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNp
    +ADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/6
    +7W4WAie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFx
    +vmjkI6TZraE3
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD.
    +# Subject: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD.
    +# Label: "Security Communication RootCA3"
    +# Serial: 16247922307909811815
    +# MD5 Fingerprint: 1c:9a:16:ff:9e:5c:e0:4d:8a:14:01:f4:35:5d:29:26
    +# SHA1 Fingerprint: c3:03:c8:22:74:92:e5:61:a2:9c:5f:79:91:2b:1e:44:13:91:30:3a
    +# SHA256 Fingerprint: 24:a5:5c:2a:b0:51:44:2d:06:17:76:65:41:23:9a:4a:d0:32:d7:c5:51:75:aa:34:ff:de:2f:bc:4f:5c:52:94
    +-----BEGIN CERTIFICATE-----
    +MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNV
    +BAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScw
    +JQYDVQQDEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2
    +MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
    +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UEAxMeU2VjdXJpdHkg
    +Q29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
    +CgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4r
    +CmDvu20rhvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzA
    +lrenfna84xtSGc4RHwsENPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MG
    +TfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF7
    +9+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGmnpjKIG58u4iFW/vAEGK7
    +8vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtYXLVqAvO4
    +g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3we
    +GVPKp7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst
    ++3A7caoreyYn8xrC3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M
    +0V9hvqG8OmpI6iZVIhZdXw3/JzOfGAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQ
    +T9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0VcwCBEF/VfR2ccCAwEAAaNCMEAw
    +HQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB/wQEAwIBBjAP
    +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS
    +YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PA
    +FNr0Y/Dq9HHuTofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd
    +9XbXv8S2gVj/yP9kaWJ5rW4OH3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQI
    +UYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASxYfQAW0q3nHE3GYV5v4GwxxMOdnE+
    +OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZXSEIx2C/pHF7uNke
    +gr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml+LLf
    +iAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUV
    +nuiZIesnKwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD
    +2NCcnWXL0CsnMQMeNuE9dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI//
    +1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm6Vwdp6POXiUyK+OVrCoHzrQoeIY8Laad
    +TdJ0MN1kURXbg4NR16/9M51NZg==
    +-----END CERTIFICATE-----
    +
    +# Issuer: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD.
    +# Subject: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD.
    +# Label: "Security Communication ECC RootCA1"
    +# Serial: 15446673492073852651
    +# MD5 Fingerprint: 7e:43:b0:92:68:ec:05:43:4c:98:ab:5d:35:2e:7e:86
    +# SHA1 Fingerprint: b8:0e:26:a9:bf:d2:b2:3b:c0:ef:46:c9:ba:c7:bb:f6:1d:0d:41:41
    +# SHA256 Fingerprint: e7:4f:bd:a5:5b:d5:64:c4:73:a3:6b:44:1a:a7:99:c8:a6:8e:07:74:40:e8:28:8b:9f:a1:e5:0e:4b:ba:ca:11
    +-----BEGIN CERTIFICATE-----
    +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT
    +AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD
    +VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx
    +NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT
    +HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5
    +IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
    +AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl
    +dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK
    +ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E
    +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu
    +9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O
    +be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k=
    +-----END CERTIFICATE-----
    diff --git a/deployment-apps/metricator-for-nmon/lib/certifi/core.py b/deployment-apps/metricator-for-nmon/lib/certifi/core.py
    new file mode 100644
    index 0000000..de02898
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/certifi/core.py
    @@ -0,0 +1,108 @@
    +"""
    +certifi.py
    +~~~~~~~~~~
    +
    +This module returns the installation location of cacert.pem or its contents.
    +"""
    +import sys
    +
    +
    +if sys.version_info >= (3, 11):
    +
    +    from importlib.resources import as_file, files
    +
    +    _CACERT_CTX = None
    +    _CACERT_PATH = None
    +
    +    def where() -> str:
    +        # This is slightly terrible, but we want to delay extracting the file
    +        # in cases where we're inside of a zipimport situation until someone
    +        # actually calls where(), but we don't want to re-extract the file
    +        # on every call of where(), so we'll do it once then store it in a
    +        # global variable.
    +        global _CACERT_CTX
    +        global _CACERT_PATH
    +        if _CACERT_PATH is None:
    +            # This is slightly janky, the importlib.resources API wants you to
    +            # manage the cleanup of this file, so it doesn't actually return a
    +            # path, it returns a context manager that will give you the path
    +            # when you enter it and will do any cleanup when you leave it. In
    +            # the common case of not needing a temporary file, it will just
    +            # return the file system location and the __exit__() is a no-op.
    +            #
    +            # We also have to hold onto the actual context manager, because
    +            # it will do the cleanup whenever it gets garbage collected, so
    +            # we will also store that at the global level as well.
    +            _CACERT_CTX = as_file(files("certifi").joinpath("cacert.pem"))
    +            _CACERT_PATH = str(_CACERT_CTX.__enter__())
    +
    +        return _CACERT_PATH
    +
    +    def contents() -> str:
    +        return files("certifi").joinpath("cacert.pem").read_text(encoding="ascii")
    +
    +elif sys.version_info >= (3, 7):
    +
    +    from importlib.resources import path as get_path, read_text
    +
    +    _CACERT_CTX = None
    +    _CACERT_PATH = None
    +
    +    def where() -> str:
    +        # This is slightly terrible, but we want to delay extracting the
    +        # file in cases where we're inside of a zipimport situation until
    +        # someone actually calls where(), but we don't want to re-extract
    +        # the file on every call of where(), so we'll do it once then store
    +        # it in a global variable.
    +        global _CACERT_CTX
    +        global _CACERT_PATH
    +        if _CACERT_PATH is None:
    +            # This is slightly janky, the importlib.resources API wants you
    +            # to manage the cleanup of this file, so it doesn't actually
    +            # return a path, it returns a context manager that will give
    +            # you the path when you enter it and will do any cleanup when
    +            # you leave it. In the common case of not needing a temporary
    +            # file, it will just return the file system location and the
    +            # __exit__() is a no-op.
    +            #
    +            # We also have to hold onto the actual context manager, because
    +            # it will do the cleanup whenever it gets garbage collected, so
    +            # we will also store that at the global level as well.
    +            _CACERT_CTX = get_path("certifi", "cacert.pem")
    +            _CACERT_PATH = str(_CACERT_CTX.__enter__())
    +
    +        return _CACERT_PATH
    +
    +    def contents() -> str:
    +        return read_text("certifi", "cacert.pem", encoding="ascii")
    +
    +else:
    +    import os
    +    import types
    +    from typing import Union
    +
    +    Package = Union[types.ModuleType, str]
    +    Resource = Union[str, "os.PathLike"]
    +
    +    # This fallback will work for Python versions prior to 3.7 that lack the
    +    # importlib.resources module but relies on the existing `where` function
    +    # so won't address issues with environments like PyOxidizer that don't set
    +    # __file__ on modules.
    +    def read_text(
    +        package: Package,
    +        resource: Resource,
    +        encoding: str = 'utf-8',
    +        errors: str = 'strict'
    +    ) -> str:
    +        with open(where(), encoding=encoding) as data:
    +            return data.read()
    +
    +    # If we don't have importlib.resources, then we will just do the old logic
    +    # of assuming we're on the filesystem and munge the path directly.
    +    def where() -> str:
    +        f = os.path.dirname(__file__)
    +
    +        return os.path.join(f, "cacert.pem")
    +
    +    def contents() -> str:
    +        return read_text("certifi", "cacert.pem", encoding="ascii")
    diff --git a/deployment-apps/metricator-for-nmon/lib/certifi/py.typed b/deployment-apps/metricator-for-nmon/lib/certifi/py.typed
    new file mode 100644
    index 0000000..e69de29
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/INSTALLER b/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/INSTALLER
    new file mode 100644
    index 0000000..a1b589e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/INSTALLER
    @@ -0,0 +1 @@
    +pip
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/LICENSE b/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/LICENSE
    new file mode 100644
    index 0000000..ad82355
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/LICENSE
    @@ -0,0 +1,21 @@
    +MIT License
    +
    +Copyright (c) 2019 TAHRI Ahmed R.
    +
    +Permission is hereby granted, free of charge, to any person obtaining a copy
    +of this software and associated documentation files (the "Software"), to deal
    +in the Software without restriction, including without limitation the rights
    +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +copies of the Software, and to permit persons to whom the Software is
    +furnished to do so, subject to the following conditions:
    +
    +The above copyright notice and this permission notice shall be included in all
    +copies or substantial portions of the Software.
    +
    +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    +SOFTWARE.
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/METADATA b/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/METADATA
    new file mode 100644
    index 0000000..9f41f44
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/METADATA
    @@ -0,0 +1,585 @@
    +Metadata-Version: 2.1
    +Name: charset-normalizer
    +Version: 3.0.1
    +Summary: The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.
    +Home-page: https://github.com/Ousret/charset_normalizer
    +Author: Ahmed TAHRI
    +Author-email: ahmed.tahri@cloudnursery.dev
    +License: MIT
    +Project-URL: Bug Reports, https://github.com/Ousret/charset_normalizer/issues
    +Project-URL: Documentation, https://charset-normalizer.readthedocs.io/en/latest
    +Keywords: encoding,charset,charset-detector,detector,normalization,unicode,chardet,detect
    +Classifier: Development Status :: 5 - Production/Stable
    +Classifier: License :: OSI Approved :: MIT License
    +Classifier: Intended Audience :: Developers
    +Classifier: Topic :: Software Development :: Libraries :: Python Modules
    +Classifier: Operating System :: OS Independent
    +Classifier: Programming Language :: Python
    +Classifier: Programming Language :: Python :: 3
    +Classifier: Programming Language :: Python :: 3.6
    +Classifier: Programming Language :: Python :: 3.7
    +Classifier: Programming Language :: Python :: 3.8
    +Classifier: Programming Language :: Python :: 3.9
    +Classifier: Programming Language :: Python :: 3.10
    +Classifier: Programming Language :: Python :: 3.11
    +Classifier: Programming Language :: Python :: Implementation :: PyPy
    +Classifier: Topic :: Text Processing :: Linguistic
    +Classifier: Topic :: Utilities
    +Classifier: Typing :: Typed
    +Description-Content-Type: text/markdown
    +License-File: LICENSE
    +Provides-Extra: unicode_backport
    +
    +<h1 align="center">Charset Detection, for Everyone 👋 <a href="https://twitter.com/intent/tweet?text=The%20Real%20First%20Universal%20Charset%20%26%20Language%20Detector&url=https://www.github.com/Ousret/charset_normalizer&hashtags=python,encoding,chardet,developers"><img src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"/></a></h1>
    +
    +<p align="center">
    +  <sup>The Real First Universal Charset Detector</sup><br>
    +  <a href="https://pypi.org/project/charset-normalizer">
    +    <img src="https://img.shields.io/pypi/pyversions/charset_normalizer.svg?orange=blue" />
    +  </a>
    +  <a href="https://codecov.io/gh/Ousret/charset_normalizer">
    +      <img src="https://codecov.io/gh/Ousret/charset_normalizer/branch/master/graph/badge.svg" />
    +  </a>
    +  <a href="https://pepy.tech/project/charset-normalizer/">
    +    <img alt="Download Count Total" src="https://pepy.tech/badge/charset-normalizer/month" />
    +  </a>
    +</p>
    +
    +> A library that helps you read text from an unknown charset encoding.<br /> Motivated by `chardet`,
    +> I'm trying to resolve the issue by taking a new approach.
    +> All IANA character set names for which the Python core library provides codecs are supported.
    +
    +<p align="center">
    +  >>>>> <a href="https://charsetnormalizerweb.ousret.now.sh" target="_blank">👉 Try Me Online Now, Then Adopt Me 👈 </a> <<<<<
    +</p>
    +
    +This project offers you an alternative to **Universal Charset Encoding Detector**, also known as **Chardet**.
    +
    +| Feature       | [Chardet](https://github.com/chardet/chardet)       | Charset Normalizer | [cChardet](https://github.com/PyYoshi/cChardet) |
    +| ------------- | :-------------: | :------------------: | :------------------: |
    +| `Fast`         | ❌<br>          | ✅<br>             | ✅ <br> |
    +| `Universal**`     | ❌            | ✅                 | ❌ |
    +| `Reliable` **without** distinguishable standards | ❌ | ✅ | ✅ |
    +| `Reliable` **with** distinguishable standards | ✅ | ✅ | ✅ |
    +| `License` | LGPL-2.1<br>_restrictive_ | MIT | MPL-1.1<br>_restrictive_ |
    +| `Native Python` | ✅ | ✅ | ❌ |
    +| `Detect spoken language` | ❌ | ✅ | N/A |
    +| `UnicodeDecodeError Safety` | ❌ | ✅ | ❌ |
    +| `Whl Size` | 193.6 kB | 39.5 kB | ~200 kB |
    +| `Supported Encoding` | 33 | :tada: [90](https://charset-normalizer.readthedocs.io/en/latest/user/support.html#supported-encodings)  | 40
    +
    +<p align="center">
    +<img src="https://i.imgflip.com/373iay.gif" alt="Reading Normalized Text" width="226"/><img src="https://media.tenor.com/images/c0180f70732a18b4965448d33adba3d0/tenor.gif" alt="Cat Reading Text" width="200"/>
    +
    +*\*\* : They are clearly using specific code for a specific encoding even if covering most of used one*<br> 
    +Did you got there because of the logs? See [https://charset-normalizer.readthedocs.io/en/latest/user/miscellaneous.html](https://charset-normalizer.readthedocs.io/en/latest/user/miscellaneous.html)
    +
    +## ⭐ Your support
    +
    +*Fork, test-it, star-it, submit your ideas! We do listen.*
    +  
    +## ⚡ Performance
    +
    +This package offer better performance than its counterpart Chardet. Here are some numbers.
    +
    +| Package       | Accuracy       | Mean per file (ms) | File per sec (est) |
    +| ------------- | :-------------: | :------------------: | :------------------: |
    +|      [chardet](https://github.com/chardet/chardet)        |     86 %     |     200 ms      |       5 file/sec        |
    +| charset-normalizer |    **98 %**     |     **10 ms**      |       100 file/sec    |
    +
    +| Package       | 99th percentile       | 95th percentile | 50th percentile |
    +| ------------- | :-------------: | :------------------: | :------------------: |
    +|      [chardet](https://github.com/chardet/chardet)        |     1200 ms     |     287 ms      |       23 ms        |
    +| charset-normalizer |    100 ms     |     50 ms      |       5 ms    |
    +
    +Chardet's performance on larger file (1MB+) are very poor. Expect huge difference on large payload.
    +
    +> Stats are generated using 400+ files using default parameters. More details on used files, see GHA workflows.
    +> And yes, these results might change at any time. The dataset can be updated to include more files.
    +> The actual delays heavily depends on your CPU capabilities. The factors should remain the same.
    +> Keep in mind that the stats are generous and that Chardet accuracy vs our is measured using Chardet initial capability
    +> (eg. Supported Encoding) Challenge-them if you want.
    +
    +## ✨ Installation
    +
    +Using PyPi for latest stable
    +```sh
    +pip install charset-normalizer -U
    +```
    +
    +## 🚀 Basic Usage
    +
    +### CLI
    +This package comes with a CLI.
    +
    +```
    +usage: normalizer [-h] [-v] [-a] [-n] [-m] [-r] [-f] [-t THRESHOLD]
    +                  file [file ...]
    +
    +The Real First Universal Charset Detector. Discover originating encoding used
    +on text file. Normalize text to unicode.
    +
    +positional arguments:
    +  files                 File(s) to be analysed
    +
    +optional arguments:
    +  -h, --help            show this help message and exit
    +  -v, --verbose         Display complementary information about file if any.
    +                        Stdout will contain logs about the detection process.
    +  -a, --with-alternative
    +                        Output complementary possibilities if any. Top-level
    +                        JSON WILL be a list.
    +  -n, --normalize       Permit to normalize input file. If not set, program
    +                        does not write anything.
    +  -m, --minimal         Only output the charset detected to STDOUT. Disabling
    +                        JSON output.
    +  -r, --replace         Replace file when trying to normalize it instead of
    +                        creating a new one.
    +  -f, --force           Replace file without asking if you are sure, use this
    +                        flag with caution.
    +  -t THRESHOLD, --threshold THRESHOLD
    +                        Define a custom maximum amount of chaos allowed in
    +                        decoded content. 0. <= chaos <= 1.
    +  --version             Show version information and exit.
    +```
    +
    +```bash
    +normalizer ./data/sample.1.fr.srt
    +```
    +
    +:tada: Since version 1.4.0 the CLI produce easily usable stdout result in JSON format.
    +
    +```json
    +{
    +    "path": "/home/default/projects/charset_normalizer/data/sample.1.fr.srt",
    +    "encoding": "cp1252",
    +    "encoding_aliases": [
    +        "1252",
    +        "windows_1252"
    +    ],
    +    "alternative_encodings": [
    +        "cp1254",
    +        "cp1256",
    +        "cp1258",
    +        "iso8859_14",
    +        "iso8859_15",
    +        "iso8859_16",
    +        "iso8859_3",
    +        "iso8859_9",
    +        "latin_1",
    +        "mbcs"
    +    ],
    +    "language": "French",
    +    "alphabets": [
    +        "Basic Latin",
    +        "Latin-1 Supplement"
    +    ],
    +    "has_sig_or_bom": false,
    +    "chaos": 0.149,
    +    "coherence": 97.152,
    +    "unicode_path": null,
    +    "is_preferred": true
    +}
    +```
    +
    +### Python
    +*Just print out normalized text*
    +```python
    +from charset_normalizer import from_path
    +
    +results = from_path('./my_subtitle.srt')
    +
    +print(str(results.best()))
    +```
    +
    +*Upgrade your code without effort*
    +```python
    +from charset_normalizer import detect
    +```
    +
    +The above code will behave the same as **chardet**. We ensure that we offer the best (reasonable) BC result possible.
    +
    +See the docs for advanced usage : [readthedocs.io](https://charset-normalizer.readthedocs.io/en/latest/)
    +
    +## 😇 Why
    +
    +When I started using Chardet, I noticed that it was not suited to my expectations, and I wanted to propose a
    +reliable alternative using a completely different method. Also! I never back down on a good challenge!
    +
    +I **don't care** about the **originating charset** encoding, because **two different tables** can
    +produce **two identical rendered string.**
    +What I want is to get readable text, the best I can. 
    +
    +In a way, **I'm brute forcing text decoding.** How cool is that ? 😎
    +
    +Don't confuse package **ftfy** with charset-normalizer or chardet. ftfy goal is to repair unicode string whereas charset-normalizer to convert raw file in unknown encoding to unicode.
    +
    +## 🍰 How
    +
    +  - Discard all charset encoding table that could not fit the binary content.
    +  - Measure chaos, or the mess once opened (by chunks) with a corresponding charset encoding.
    +  - Extract matches with the lowest mess detected.
    +  - Additionally, we measure coherence / probe for a language.
    +
    +**Wait a minute**, what is chaos/mess and coherence according to **YOU ?**
    +
    +*Chaos :* I opened hundred of text files, **written by humans**, with the wrong encoding table. **I observed**, then
    +**I established** some ground rules about **what is obvious** when **it seems like** a mess.
    + I know that my interpretation of what is chaotic is very subjective, feel free to contribute in order to
    + improve or rewrite it.
    +
    +*Coherence :* For each language there is on earth, we have computed ranked letter appearance occurrences (the best we can). So I thought
    +that intel is worth something here. So I use those records against decoded text to check if I can detect intelligent design.
    +
    +## ⚡ Known limitations
    +
    +  - Language detection is unreliable when text contains two or more languages sharing identical letters. (eg. HTML (english tags) + Turkish content (Sharing Latin characters))
    +  - Every charset detector heavily depends on sufficient content. In common cases, do not bother run detection on very tiny content.
    +
    +## 👤 Contributing
    +
    +Contributions, issues and feature requests are very much welcome.<br />
    +Feel free to check [issues page](https://github.com/ousret/charset_normalizer/issues) if you want to contribute.
    +
    +## 📝 License
    +
    +Copyright © 2019 [Ahmed TAHRI @Ousret](https://github.com/Ousret).<br />
    +This project is [MIT](https://github.com/Ousret/charset_normalizer/blob/master/LICENSE) licensed.
    +
    +Characters frequencies used in this project © 2012 [Denny Vrandečić](http://simia.net/letters/)
    +
    +# Changelog
    +All notable changes to charset-normalizer will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
    +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
    +
    +## [3.0.1](https://github.com/Ousret/charset_normalizer/compare/3.0.0...3.0.1) (2022-11-18)
    +
    +### Fixed
    +- Multi-bytes cutter/chunk generator did not always cut correctly (PR #233)
    +
    +### Changed
    +- Speedup provided by mypy/c 0.990 on Python >= 3.7
    +
    +## [3.0.0](https://github.com/Ousret/charset_normalizer/compare/2.1.1...3.0.0) (2022-10-20)
    +
    +### Added
    +- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results
    +- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES
    +- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio
    +- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl)
    +
    +### Changed
    +- Build with static metadata using 'build' frontend
    +- Make the language detection stricter
    +- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1
    +
    +### Fixed
    +- CLI with opt --normalize fail when using full path for files
    +- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it
    +- Sphinx warnings when generating the documentation
    +
    +### Removed
    +- Coherence detector no longer return 'Simple English' instead return 'English'
    +- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese'
    +- Breaking: Method `first()` and `best()` from CharsetMatch
    +- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII)
    +- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches
    +- Breaking: Top-level function `normalize`
    +- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch
    +- Support for the backport `unicodedata2`
    +
    +## [3.0.0rc1](https://github.com/Ousret/charset_normalizer/compare/3.0.0b2...3.0.0rc1) (2022-10-18)
    +
    +### Added
    +- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results
    +- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES
    +- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio
    +
    +### Changed
    +- Build with static metadata using 'build' frontend
    +- Make the language detection stricter
    +
    +### Fixed
    +- CLI with opt --normalize fail when using full path for files
    +- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it
    +
    +### Removed
    +- Coherence detector no longer return 'Simple English' instead return 'English'
    +- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese'
    +
    +## [3.0.0b2](https://github.com/Ousret/charset_normalizer/compare/3.0.0b1...3.0.0b2) (2022-08-21)
    +
    +### Added
    +- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl)
    +
    +### Removed
    +- Breaking: Method `first()` and `best()` from CharsetMatch
    +- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII)
    +
    +### Fixed
    +- Sphinx warnings when generating the documentation
    +
    +## [3.0.0b1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...3.0.0b1) (2022-08-15)
    +
    +### Changed
    +- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1
    +
    +### Removed
    +- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches
    +- Breaking: Top-level function `normalize`
    +- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch
    +- Support for the backport `unicodedata2`
    +
    +## [2.1.1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...2.1.1) (2022-08-19)
    +
    +### Deprecated
    +- Function `normalize` scheduled for removal in 3.0
    +
    +### Changed
    +- Removed useless call to decode in fn is_unprintable (#206)
    +
    +### Fixed
    +- Third-party library (i18n xgettext) crashing not recognizing utf_8 (PEP 263) with underscore from [@aleksandernovikov](https://github.com/aleksandernovikov) (#204)
    +
    +## [2.1.0](https://github.com/Ousret/charset_normalizer/compare/2.0.12...2.1.0) (2022-06-19)
    +
    +### Added
    +- Output the Unicode table version when running the CLI with `--version` (PR #194)
    +
    +### Changed
    +- Re-use decoded buffer for single byte character sets from [@nijel](https://github.com/nijel) (PR #175)
    +- Fixing some performance bottlenecks from [@deedy5](https://github.com/deedy5) (PR #183)
    +
    +### Fixed
    +- Workaround potential bug in cpython with Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space (PR #175)
    +- CLI default threshold aligned with the API threshold from [@oleksandr-kuzmenko](https://github.com/oleksandr-kuzmenko) (PR #181)
    +
    +### Removed
    +- Support for Python 3.5 (PR #192)
    +
    +### Deprecated
    +- Use of backport unicodedata from `unicodedata2` as Python is quickly catching up, scheduled for removal in 3.0 (PR #194)
    +
    +## [2.0.12](https://github.com/Ousret/charset_normalizer/compare/2.0.11...2.0.12) (2022-02-12)
    +
    +### Fixed
    +- ASCII miss-detection on rare cases (PR #170) 
    +
    +## [2.0.11](https://github.com/Ousret/charset_normalizer/compare/2.0.10...2.0.11) (2022-01-30)
    +
    +### Added
    +- Explicit support for Python 3.11 (PR #164)
    +
    +### Changed
    +- The logging behavior have been completely reviewed, now using only TRACE and DEBUG levels (PR #163 #165)
    +
    +## [2.0.10](https://github.com/Ousret/charset_normalizer/compare/2.0.9...2.0.10) (2022-01-04)
    +
    +### Fixed
    +- Fallback match entries might lead to UnicodeDecodeError for large bytes sequence (PR #154)
    +
    +### Changed
    +- Skipping the language-detection (CD) on ASCII (PR #155)
    +
    +## [2.0.9](https://github.com/Ousret/charset_normalizer/compare/2.0.8...2.0.9) (2021-12-03)
    +
    +### Changed
    +- Moderating the logging impact (since 2.0.8) for specific environments (PR #147)
    +
    +### Fixed
    +- Wrong logging level applied when setting kwarg `explain` to True (PR #146)
    +
    +## [2.0.8](https://github.com/Ousret/charset_normalizer/compare/2.0.7...2.0.8) (2021-11-24)
    +### Changed
    +- Improvement over Vietnamese detection (PR #126)
    +- MD improvement on trailing data and long foreign (non-pure latin) data (PR #124)
    +- Efficiency improvements in cd/alphabet_languages from [@adbar](https://github.com/adbar) (PR #122)
    +- call sum() without an intermediary list following PEP 289 recommendations from [@adbar](https://github.com/adbar) (PR #129)
    +- Code style as refactored by Sourcery-AI (PR #131) 
    +- Minor adjustment on the MD around european words (PR #133)
    +- Remove and replace SRTs from assets / tests (PR #139)
    +- Initialize the library logger with a `NullHandler` by default from [@nmaynes](https://github.com/nmaynes) (PR #135)
    +- Setting kwarg `explain` to True will add provisionally (bounded to function lifespan) a specific stream handler (PR #135)
    +
    +### Fixed
    +- Fix large (misleading) sequence giving UnicodeDecodeError (PR #137)
    +- Avoid using too insignificant chunk (PR #137)
    +
    +### Added
    +- Add and expose function `set_logging_handler` to configure a specific StreamHandler from [@nmaynes](https://github.com/nmaynes) (PR #135)
    +- Add `CHANGELOG.md` entries, format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) (PR #141)
    +
    +## [2.0.7](https://github.com/Ousret/charset_normalizer/compare/2.0.6...2.0.7) (2021-10-11)
    +### Added
    +- Add support for Kazakh (Cyrillic) language detection (PR #109)
    +
    +### Changed
    +- Further, improve inferring the language from a given single-byte code page (PR #112)
    +- Vainly trying to leverage PEP263 when PEP3120 is not supported (PR #116)
    +- Refactoring for potential performance improvements in loops from [@adbar](https://github.com/adbar) (PR #113)
    +- Various detection improvement (MD+CD) (PR #117)
    +
    +### Removed
    +- Remove redundant logging entry about detected language(s) (PR #115)
    +
    +### Fixed
    +- Fix a minor inconsistency between Python 3.5 and other versions regarding language detection (PR #117 #102)
    +
    +## [2.0.6](https://github.com/Ousret/charset_normalizer/compare/2.0.5...2.0.6) (2021-09-18)
    +### Fixed
    +- Unforeseen regression with the loss of the backward-compatibility with some older minor of Python 3.5.x (PR #100)
    +- Fix CLI crash when using --minimal output in certain cases (PR #103)
    +
    +### Changed
    +- Minor improvement to the detection efficiency (less than 1%) (PR #106 #101)
    +
    +## [2.0.5](https://github.com/Ousret/charset_normalizer/compare/2.0.4...2.0.5) (2021-09-14)
    +### Changed
    +- The project now comply with: flake8, mypy, isort and black to ensure a better overall quality (PR #81)
    +- The BC-support with v1.x was improved, the old staticmethods are restored (PR #82)
    +- The Unicode detection is slightly improved (PR #93)
    +- Add syntax sugar \_\_bool\_\_ for results CharsetMatches list-container (PR #91)
    +
    +### Removed
    +- The project no longer raise warning on tiny content given for detection, will be simply logged as warning instead (PR #92)
    +
    +### Fixed
    +- In some rare case, the chunks extractor could cut in the middle of a multi-byte character and could mislead the mess detection (PR #95)
    +- Some rare 'space' characters could trip up the UnprintablePlugin/Mess detection (PR #96)
    +- The MANIFEST.in was not exhaustive (PR #78)
    +
    +## [2.0.4](https://github.com/Ousret/charset_normalizer/compare/2.0.3...2.0.4) (2021-07-30)
    +### Fixed
    +- The CLI no longer raise an unexpected exception when no encoding has been found (PR #70)
    +- Fix accessing the 'alphabets' property when the payload contains surrogate characters (PR #68)
    +- The logger could mislead (explain=True) on detected languages and the impact of one MBCS match (PR #72)
    +- Submatch factoring could be wrong in rare edge cases (PR #72)
    +- Multiple files given to the CLI were ignored when publishing results to STDOUT. (After the first path) (PR #72)
    +- Fix line endings from CRLF to LF for certain project files (PR #67)
    +
    +### Changed
    +- Adjust the MD to lower the sensitivity, thus improving the global detection reliability (PR #69 #76)
    +- Allow fallback on specified encoding if any (PR #71)
    +
    +## [2.0.3](https://github.com/Ousret/charset_normalizer/compare/2.0.2...2.0.3) (2021-07-16)
    +### Changed
    +- Part of the detection mechanism has been improved to be less sensitive, resulting in more accurate detection results. Especially ASCII. (PR #63)
    +- According to the community wishes, the detection will fall back on ASCII or UTF-8 in a last-resort case. (PR #64)
    +
    +## [2.0.2](https://github.com/Ousret/charset_normalizer/compare/2.0.1...2.0.2) (2021-07-15)
    +### Fixed
    +- Empty/Too small JSON payload miss-detection fixed. Report from [@tseaver](https://github.com/tseaver) (PR #59) 
    +
    +### Changed
    +- Don't inject unicodedata2 into sys.modules from [@akx](https://github.com/akx) (PR #57)
    +
    +## [2.0.1](https://github.com/Ousret/charset_normalizer/compare/2.0.0...2.0.1) (2021-07-13)
    +### Fixed
    +- Make it work where there isn't a filesystem available, dropping assets frequencies.json. Report from [@sethmlarson](https://github.com/sethmlarson). (PR #55)
    +- Using explain=False permanently disable the verbose output in the current runtime (PR #47)
    +- One log entry (language target preemptive) was not show in logs when using explain=True (PR #47)
    +- Fix undesired exception (ValueError) on getitem of instance CharsetMatches (PR #52)
    +
    +### Changed
    +- Public function normalize default args values were not aligned with from_bytes (PR #53)
    +
    +### Added
    +- You may now use charset aliases in cp_isolation and cp_exclusion arguments (PR #47)
    +
    +## [2.0.0](https://github.com/Ousret/charset_normalizer/compare/1.4.1...2.0.0) (2021-07-02)
    +### Changed
    +- 4x to 5 times faster than the previous 1.4.0 release. At least 2x faster than Chardet.
    +- Accent has been made on UTF-8 detection, should perform rather instantaneous.
    +- The backward compatibility with Chardet has been greatly improved. The legacy detect function returns an identical charset name whenever possible.
    +- The detection mechanism has been slightly improved, now Turkish content is detected correctly (most of the time)
    +- The program has been rewritten to ease the readability and maintainability. (+Using static typing)+
    +- utf_7 detection has been reinstated.
    +
    +### Removed
    +- This package no longer require anything when used with Python 3.5 (Dropped cached_property)
    +- Removed support for these languages: Catalan, Esperanto, Kazakh, Baque, Volapük, Azeri, Galician, Nynorsk, Macedonian, and Serbocroatian.
    +- The exception hook on UnicodeDecodeError has been removed.
    +
    +### Deprecated
    +- Methods coherence_non_latin, w_counter, chaos_secondary_pass of the class CharsetMatch are now deprecated and scheduled for removal in v3.0
    +
    +### Fixed
    +- The CLI output used the relative path of the file(s). Should be absolute.
    +
    +## [1.4.1](https://github.com/Ousret/charset_normalizer/compare/1.4.0...1.4.1) (2021-05-28)
    +### Fixed
    +- Logger configuration/usage no longer conflict with others (PR #44)
    +
    +## [1.4.0](https://github.com/Ousret/charset_normalizer/compare/1.3.9...1.4.0) (2021-05-21)
    +### Removed
    +- Using standard logging instead of using the package loguru.
    +- Dropping nose test framework in favor of the maintained pytest.
    +- Choose to not use dragonmapper package to help with gibberish Chinese/CJK text.
    +- Require cached_property only for Python 3.5 due to constraint. Dropping for every other interpreter version.
    +- Stop support for UTF-7 that does not contain a SIG.
    +- Dropping PrettyTable, replaced with pure JSON output in CLI.
    +
    +### Fixed
    +- BOM marker in a CharsetNormalizerMatch instance could be False in rare cases even if obviously present. Due to the sub-match factoring process.
    +- Not searching properly for the BOM when trying utf32/16 parent codec.
    +
    +### Changed
    +- Improving the package final size by compressing frequencies.json.
    +- Huge improvement over the larges payload.
    +
    +### Added
    +- CLI now produces JSON consumable output.
    +- Return ASCII if given sequences fit. Given reasonable confidence.
    +
    +## [1.3.9](https://github.com/Ousret/charset_normalizer/compare/1.3.8...1.3.9) (2021-05-13)
    +
    +### Fixed
    +- In some very rare cases, you may end up getting encode/decode errors due to a bad bytes payload (PR #40)
    +
    +## [1.3.8](https://github.com/Ousret/charset_normalizer/compare/1.3.7...1.3.8) (2021-05-12)
    +
    +### Fixed
    +- Empty given payload for detection may cause an exception if trying to access the `alphabets` property. (PR #39)
    +
    +## [1.3.7](https://github.com/Ousret/charset_normalizer/compare/1.3.6...1.3.7) (2021-05-12)
    +
    +### Fixed
    +- The legacy detect function should return UTF-8-SIG if sig is present in the payload. (PR #38)
    +
    +## [1.3.6](https://github.com/Ousret/charset_normalizer/compare/1.3.5...1.3.6) (2021-02-09)
    +
    +### Changed
    +- Amend the previous release to allow prettytable 2.0 (PR #35)
    +
    +## [1.3.5](https://github.com/Ousret/charset_normalizer/compare/1.3.4...1.3.5) (2021-02-08)
    +
    +### Fixed
    +- Fix error while using the package with a python pre-release interpreter (PR #33)
    +
    +### Changed
    +- Dependencies refactoring, constraints revised.
    +
    +### Added
    +- Add python 3.9 and 3.10 to the supported interpreters
    +
    +MIT License
    +
    +Copyright (c) 2019 TAHRI Ahmed R.
    +
    +Permission is hereby granted, free of charge, to any person obtaining a copy
    +of this software and associated documentation files (the "Software"), to deal
    +in the Software without restriction, including without limitation the rights
    +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +copies of the Software, and to permit persons to whom the Software is
    +furnished to do so, subject to the following conditions:
    +
    +The above copyright notice and this permission notice shall be included in all
    +copies or substantial portions of the Software.
    +
    +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    +SOFTWARE.
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/RECORD b/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/RECORD
    new file mode 100644
    index 0000000..f1dce3f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/RECORD
    @@ -0,0 +1,23 @@
    +../../bin/normalizer,sha256=_6VNRnw7MyVCL-CINQ044FaHcpLHwQVgd-_D0cWq4KI,244
    +charset_normalizer-3.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
    +charset_normalizer-3.0.1.dist-info/LICENSE,sha256=6zGgxaT7Cbik4yBV0lweX5w1iidS_vPNcgIT0cz-4kE,1070
    +charset_normalizer-3.0.1.dist-info/METADATA,sha256=gdghALADhXdezIq8a8vDHvGDuyJGr87Lo2xX7CS1DUI,27664
    +charset_normalizer-3.0.1.dist-info/RECORD,,
    +charset_normalizer-3.0.1.dist-info/WHEEL,sha256=AENPUwuTc6qB95Mrn5JB5boXegWw6oDhuwuuX0q_ONg,152
    +charset_normalizer-3.0.1.dist-info/entry_points.txt,sha256=uYo8aIGLWv8YgWfSna5HnfY_En4pkF1w4bgawNAXzP0,76
    +charset_normalizer-3.0.1.dist-info/top_level.txt,sha256=7ASyzePr8_xuZWJsnqJjIBtyV8vhEo0wBCv1MPRRi3Q,19
    +charset_normalizer/__init__.py,sha256=aAb_F9Zb23pb4NO6TfIfqLXLvf1PjnLBBOuPvQwPA18,1549
    +charset_normalizer/api.py,sha256=C4QjO6c_MP7eiBTXJwYQWpHQIdijPMOTFjX-NJjQ8Hs,18601
    +charset_normalizer/assets/__init__.py,sha256=wpRfujN7GJuEE5wHHo3wEDVoJ5ovzRIxsImyimCBfGU,20069
    +charset_normalizer/cd.py,sha256=2gSBjSgYXf0NeyptY8SAwSyiLD-lDorH825gVAH3iFs,12555
    +charset_normalizer/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
    +charset_normalizer/cli/normalizer.py,sha256=Q_XgPy_gHLxwUZjitWdgWbG3CSSCieAWhh4nINJxaFs,9746
    +charset_normalizer/constant.py,sha256=PmCeoKXqq3ZbCtCUpKHwwFBIv9DXMT_an1yd24q28mA,19101
    +charset_normalizer/legacy.py,sha256=W_LqD13PjxwgCRcccRAZbe6sBNEqF0XmsBf_a75TyCg,1652
    +charset_normalizer/md.cpython-310-x86_64-linux-gnu.so,sha256=isT111Hu0I4ZX0w0H4LxHQbKWho4A6nYe0qJ3lsSkqY,17496
    +charset_normalizer/md.py,sha256=MXPKP_oLbsubulEL_1rxcYKSd5FeEfyEfNNm5O6ADpc,18258
    +charset_normalizer/md__mypyc.cpython-310-x86_64-linux-gnu.so,sha256=XjsQ0DOK1vV41lBwKco2uNFiC8ThWpVV-dA6RD7dTT4,424376
    +charset_normalizer/models.py,sha256=mC11wo84l00u2o03TRNX7M5ItBAbPUKKXgJSFxA35GY,11492
    +charset_normalizer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
    +charset_normalizer/utils.py,sha256=dawALte_grHFeumYziYp6dZmzXM1SlSLElYyC8AG9pI,11548
    +charset_normalizer/version.py,sha256=Je2t56tjRtAcqjMzNvnVRWQMv9Et3wjPSdtsB7X5wgE,79
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/WHEEL b/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/WHEEL
    new file mode 100644
    index 0000000..14ff72d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer-3.0.1.dist-info/WHEEL
    @@ -0,0 +1,6 @@
    +Wheel-Version: 1.0
    +Generator: bdist_wheel (0.37.1)
    +Root-Is-Purelib: false
    +Tag: cp310-cp310-manylinux_2_17_x86_64
    +Tag: cp310-cp310-manylinux2014_x86_64
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/__init__.py b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/__init__.py
    new file mode 100644
    index 0000000..ebb5da8
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/__init__.py
    @@ -0,0 +1,45 @@
    +# -*- coding: utf-8 -*-
    +"""
    +Charset-Normalizer
    +~~~~~~~~~~~~~~
    +The Real First Universal Charset Detector.
    +A library that helps you read text from an unknown charset encoding.
    +Motivated by chardet, This package is trying to resolve the issue by taking a new approach.
    +All IANA character set names for which the Python core library provides codecs are supported.
    +
    +Basic usage:
    +   >>> from charset_normalizer import from_bytes
    +   >>> results = from_bytes('Bсеки човек има право на образование. Oбразованието!'.encode('utf_8'))
    +   >>> best_guess = results.best()
    +   >>> str(best_guess)
    +   'Bсеки човек има право на образование. Oбразованието!'
    +
    +Others methods and usages are available - see the full documentation
    +at <https://github.com/Ousret/charset_normalizer>.
    +:copyright: (c) 2021 by Ahmed TAHRI
    +:license: MIT, see LICENSE for more details.
    +"""
    +import logging
    +
    +from .api import from_bytes, from_fp, from_path
    +from .legacy import detect
    +from .models import CharsetMatch, CharsetMatches
    +from .utils import set_logging_handler
    +from .version import VERSION, __version__
    +
    +__all__ = (
    +    "from_fp",
    +    "from_path",
    +    "from_bytes",
    +    "detect",
    +    "CharsetMatch",
    +    "CharsetMatches",
    +    "__version__",
    +    "VERSION",
    +    "set_logging_handler",
    +)
    +
    +# Attach a NullHandler to the top level logger by default
    +# https://docs.python.org/3.3/howto/logging.html#configuring-logging-for-a-library
    +
    +logging.getLogger("charset_normalizer").addHandler(logging.NullHandler())
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/api.py b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/api.py
    new file mode 100644
    index 0000000..6c7e898
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/api.py
    @@ -0,0 +1,553 @@
    +import logging
    +from os import PathLike
    +from typing import Any, BinaryIO, List, Optional, Set
    +
    +from .cd import (
    +    coherence_ratio,
    +    encoding_languages,
    +    mb_encoding_languages,
    +    merge_coherence_ratios,
    +)
    +from .constant import IANA_SUPPORTED, TOO_BIG_SEQUENCE, TOO_SMALL_SEQUENCE, TRACE
    +from .md import mess_ratio
    +from .models import CharsetMatch, CharsetMatches
    +from .utils import (
    +    any_specified_encoding,
    +    cut_sequence_chunks,
    +    iana_name,
    +    identify_sig_or_bom,
    +    is_cp_similar,
    +    is_multi_byte_encoding,
    +    should_strip_sig_or_bom,
    +)
    +
    +# Will most likely be controversial
    +# logging.addLevelName(TRACE, "TRACE")
    +logger = logging.getLogger("charset_normalizer")
    +explain_handler = logging.StreamHandler()
    +explain_handler.setFormatter(
    +    logging.Formatter("%(asctime)s | %(levelname)s | %(message)s")
    +)
    +
    +
    +def from_bytes(
    +    sequences: bytes,
    +    steps: int = 5,
    +    chunk_size: int = 512,
    +    threshold: float = 0.2,
    +    cp_isolation: Optional[List[str]] = None,
    +    cp_exclusion: Optional[List[str]] = None,
    +    preemptive_behaviour: bool = True,
    +    explain: bool = False,
    +    language_threshold: float = 0.1,
    +) -> CharsetMatches:
    +    """
    +    Given a raw bytes sequence, return the best possibles charset usable to render str objects.
    +    If there is no results, it is a strong indicator that the source is binary/not text.
    +    By default, the process will extract 5 blocks of 512o each to assess the mess and coherence of a given sequence.
    +    And will give up a particular code page after 20% of measured mess. Those criteria are customizable at will.
    +
    +    The preemptive behavior DOES NOT replace the traditional detection workflow, it prioritize a particular code page
    +    but never take it for granted. Can improve the performance.
    +
    +    You may want to focus your attention to some code page or/and not others, use cp_isolation and cp_exclusion for that
    +    purpose.
    +
    +    This function will strip the SIG in the payload/sequence every time except on UTF-16, UTF-32.
    +    By default the library does not setup any handler other than the NullHandler, if you choose to set the 'explain'
    +    toggle to True it will alter the logger configuration to add a StreamHandler that is suitable for debugging.
    +    Custom logging format and handler can be set manually.
    +    """
    +
    +    if not isinstance(sequences, (bytearray, bytes)):
    +        raise TypeError(
    +            "Expected object of type bytes or bytearray, got: {0}".format(
    +                type(sequences)
    +            )
    +        )
    +
    +    if explain:
    +        previous_logger_level: int = logger.level
    +        logger.addHandler(explain_handler)
    +        logger.setLevel(TRACE)
    +
    +    length: int = len(sequences)
    +
    +    if length == 0:
    +        logger.debug("Encoding detection on empty bytes, assuming utf_8 intention.")
    +        if explain:
    +            logger.removeHandler(explain_handler)
    +            logger.setLevel(previous_logger_level or logging.WARNING)
    +        return CharsetMatches([CharsetMatch(sequences, "utf_8", 0.0, False, [], "")])
    +
    +    if cp_isolation is not None:
    +        logger.log(
    +            TRACE,
    +            "cp_isolation is set. use this flag for debugging purpose. "
    +            "limited list of encoding allowed : %s.",
    +            ", ".join(cp_isolation),
    +        )
    +        cp_isolation = [iana_name(cp, False) for cp in cp_isolation]
    +    else:
    +        cp_isolation = []
    +
    +    if cp_exclusion is not None:
    +        logger.log(
    +            TRACE,
    +            "cp_exclusion is set. use this flag for debugging purpose. "
    +            "limited list of encoding excluded : %s.",
    +            ", ".join(cp_exclusion),
    +        )
    +        cp_exclusion = [iana_name(cp, False) for cp in cp_exclusion]
    +    else:
    +        cp_exclusion = []
    +
    +    if length <= (chunk_size * steps):
    +        logger.log(
    +            TRACE,
    +            "override steps (%i) and chunk_size (%i) as content does not fit (%i byte(s) given) parameters.",
    +            steps,
    +            chunk_size,
    +            length,
    +        )
    +        steps = 1
    +        chunk_size = length
    +
    +    if steps > 1 and length / steps < chunk_size:
    +        chunk_size = int(length / steps)
    +
    +    is_too_small_sequence: bool = len(sequences) < TOO_SMALL_SEQUENCE
    +    is_too_large_sequence: bool = len(sequences) >= TOO_BIG_SEQUENCE
    +
    +    if is_too_small_sequence:
    +        logger.log(
    +            TRACE,
    +            "Trying to detect encoding from a tiny portion of ({}) byte(s).".format(
    +                length
    +            ),
    +        )
    +    elif is_too_large_sequence:
    +        logger.log(
    +            TRACE,
    +            "Using lazy str decoding because the payload is quite large, ({}) byte(s).".format(
    +                length
    +            ),
    +        )
    +
    +    prioritized_encodings: List[str] = []
    +
    +    specified_encoding: Optional[str] = (
    +        any_specified_encoding(sequences) if preemptive_behaviour else None
    +    )
    +
    +    if specified_encoding is not None:
    +        prioritized_encodings.append(specified_encoding)
    +        logger.log(
    +            TRACE,
    +            "Detected declarative mark in sequence. Priority +1 given for %s.",
    +            specified_encoding,
    +        )
    +
    +    tested: Set[str] = set()
    +    tested_but_hard_failure: List[str] = []
    +    tested_but_soft_failure: List[str] = []
    +
    +    fallback_ascii: Optional[CharsetMatch] = None
    +    fallback_u8: Optional[CharsetMatch] = None
    +    fallback_specified: Optional[CharsetMatch] = None
    +
    +    results: CharsetMatches = CharsetMatches()
    +
    +    sig_encoding, sig_payload = identify_sig_or_bom(sequences)
    +
    +    if sig_encoding is not None:
    +        prioritized_encodings.append(sig_encoding)
    +        logger.log(
    +            TRACE,
    +            "Detected a SIG or BOM mark on first %i byte(s). Priority +1 given for %s.",
    +            len(sig_payload),
    +            sig_encoding,
    +        )
    +
    +    prioritized_encodings.append("ascii")
    +
    +    if "utf_8" not in prioritized_encodings:
    +        prioritized_encodings.append("utf_8")
    +
    +    for encoding_iana in prioritized_encodings + IANA_SUPPORTED:
    +
    +        if cp_isolation and encoding_iana not in cp_isolation:
    +            continue
    +
    +        if cp_exclusion and encoding_iana in cp_exclusion:
    +            continue
    +
    +        if encoding_iana in tested:
    +            continue
    +
    +        tested.add(encoding_iana)
    +
    +        decoded_payload: Optional[str] = None
    +        bom_or_sig_available: bool = sig_encoding == encoding_iana
    +        strip_sig_or_bom: bool = bom_or_sig_available and should_strip_sig_or_bom(
    +            encoding_iana
    +        )
    +
    +        if encoding_iana in {"utf_16", "utf_32"} and not bom_or_sig_available:
    +            logger.log(
    +                TRACE,
    +                "Encoding %s won't be tested as-is because it require a BOM. Will try some sub-encoder LE/BE.",
    +                encoding_iana,
    +            )
    +            continue
    +        if encoding_iana in {"utf_7"} and not bom_or_sig_available:
    +            logger.log(
    +                TRACE,
    +                "Encoding %s won't be tested as-is because detection is unreliable without BOM/SIG.",
    +                encoding_iana,
    +            )
    +            continue
    +
    +        try:
    +            is_multi_byte_decoder: bool = is_multi_byte_encoding(encoding_iana)
    +        except (ModuleNotFoundError, ImportError):
    +            logger.log(
    +                TRACE,
    +                "Encoding %s does not provide an IncrementalDecoder",
    +                encoding_iana,
    +            )
    +            continue
    +
    +        try:
    +            if is_too_large_sequence and is_multi_byte_decoder is False:
    +                str(
    +                    sequences[: int(50e4)]
    +                    if strip_sig_or_bom is False
    +                    else sequences[len(sig_payload) : int(50e4)],
    +                    encoding=encoding_iana,
    +                )
    +            else:
    +                decoded_payload = str(
    +                    sequences
    +                    if strip_sig_or_bom is False
    +                    else sequences[len(sig_payload) :],
    +                    encoding=encoding_iana,
    +                )
    +        except (UnicodeDecodeError, LookupError) as e:
    +            if not isinstance(e, LookupError):
    +                logger.log(
    +                    TRACE,
    +                    "Code page %s does not fit given bytes sequence at ALL. %s",
    +                    encoding_iana,
    +                    str(e),
    +                )
    +            tested_but_hard_failure.append(encoding_iana)
    +            continue
    +
    +        similar_soft_failure_test: bool = False
    +
    +        for encoding_soft_failed in tested_but_soft_failure:
    +            if is_cp_similar(encoding_iana, encoding_soft_failed):
    +                similar_soft_failure_test = True
    +                break
    +
    +        if similar_soft_failure_test:
    +            logger.log(
    +                TRACE,
    +                "%s is deemed too similar to code page %s and was consider unsuited already. Continuing!",
    +                encoding_iana,
    +                encoding_soft_failed,
    +            )
    +            continue
    +
    +        r_ = range(
    +            0 if not bom_or_sig_available else len(sig_payload),
    +            length,
    +            int(length / steps),
    +        )
    +
    +        multi_byte_bonus: bool = (
    +            is_multi_byte_decoder
    +            and decoded_payload is not None
    +            and len(decoded_payload) < length
    +        )
    +
    +        if multi_byte_bonus:
    +            logger.log(
    +                TRACE,
    +                "Code page %s is a multi byte encoding table and it appear that at least one character "
    +                "was encoded using n-bytes.",
    +                encoding_iana,
    +            )
    +
    +        max_chunk_gave_up: int = int(len(r_) / 4)
    +
    +        max_chunk_gave_up = max(max_chunk_gave_up, 2)
    +        early_stop_count: int = 0
    +        lazy_str_hard_failure = False
    +
    +        md_chunks: List[str] = []
    +        md_ratios = []
    +
    +        try:
    +            for chunk in cut_sequence_chunks(
    +                sequences,
    +                encoding_iana,
    +                r_,
    +                chunk_size,
    +                bom_or_sig_available,
    +                strip_sig_or_bom,
    +                sig_payload,
    +                is_multi_byte_decoder,
    +                decoded_payload,
    +            ):
    +                md_chunks.append(chunk)
    +
    +                md_ratios.append(
    +                    mess_ratio(
    +                        chunk,
    +                        threshold,
    +                        explain is True and 1 <= len(cp_isolation) <= 2,
    +                    )
    +                )
    +
    +                if md_ratios[-1] >= threshold:
    +                    early_stop_count += 1
    +
    +                if (early_stop_count >= max_chunk_gave_up) or (
    +                    bom_or_sig_available and strip_sig_or_bom is False
    +                ):
    +                    break
    +        except UnicodeDecodeError as e:  # Lazy str loading may have missed something there
    +            logger.log(
    +                TRACE,
    +                "LazyStr Loading: After MD chunk decode, code page %s does not fit given bytes sequence at ALL. %s",
    +                encoding_iana,
    +                str(e),
    +            )
    +            early_stop_count = max_chunk_gave_up
    +            lazy_str_hard_failure = True
    +
    +        # We might want to check the sequence again with the whole content
    +        # Only if initial MD tests passes
    +        if (
    +            not lazy_str_hard_failure
    +            and is_too_large_sequence
    +            and not is_multi_byte_decoder
    +        ):
    +            try:
    +                sequences[int(50e3) :].decode(encoding_iana, errors="strict")
    +            except UnicodeDecodeError as e:
    +                logger.log(
    +                    TRACE,
    +                    "LazyStr Loading: After final lookup, code page %s does not fit given bytes sequence at ALL. %s",
    +                    encoding_iana,
    +                    str(e),
    +                )
    +                tested_but_hard_failure.append(encoding_iana)
    +                continue
    +
    +        mean_mess_ratio: float = sum(md_ratios) / len(md_ratios) if md_ratios else 0.0
    +        if mean_mess_ratio >= threshold or early_stop_count >= max_chunk_gave_up:
    +            tested_but_soft_failure.append(encoding_iana)
    +            logger.log(
    +                TRACE,
    +                "%s was excluded because of initial chaos probing. Gave up %i time(s). "
    +                "Computed mean chaos is %f %%.",
    +                encoding_iana,
    +                early_stop_count,
    +                round(mean_mess_ratio * 100, ndigits=3),
    +            )
    +            # Preparing those fallbacks in case we got nothing.
    +            if (
    +                encoding_iana in ["ascii", "utf_8", specified_encoding]
    +                and not lazy_str_hard_failure
    +            ):
    +                fallback_entry = CharsetMatch(
    +                    sequences, encoding_iana, threshold, False, [], decoded_payload
    +                )
    +                if encoding_iana == specified_encoding:
    +                    fallback_specified = fallback_entry
    +                elif encoding_iana == "ascii":
    +                    fallback_ascii = fallback_entry
    +                else:
    +                    fallback_u8 = fallback_entry
    +            continue
    +
    +        logger.log(
    +            TRACE,
    +            "%s passed initial chaos probing. Mean measured chaos is %f %%",
    +            encoding_iana,
    +            round(mean_mess_ratio * 100, ndigits=3),
    +        )
    +
    +        if not is_multi_byte_decoder:
    +            target_languages: List[str] = encoding_languages(encoding_iana)
    +        else:
    +            target_languages = mb_encoding_languages(encoding_iana)
    +
    +        if target_languages:
    +            logger.log(
    +                TRACE,
    +                "{} should target any language(s) of {}".format(
    +                    encoding_iana, str(target_languages)
    +                ),
    +            )
    +
    +        cd_ratios = []
    +
    +        # We shall skip the CD when its about ASCII
    +        # Most of the time its not relevant to run "language-detection" on it.
    +        if encoding_iana != "ascii":
    +            for chunk in md_chunks:
    +                chunk_languages = coherence_ratio(
    +                    chunk,
    +                    language_threshold,
    +                    ",".join(target_languages) if target_languages else None,
    +                )
    +
    +                cd_ratios.append(chunk_languages)
    +
    +        cd_ratios_merged = merge_coherence_ratios(cd_ratios)
    +
    +        if cd_ratios_merged:
    +            logger.log(
    +                TRACE,
    +                "We detected language {} using {}".format(
    +                    cd_ratios_merged, encoding_iana
    +                ),
    +            )
    +
    +        results.append(
    +            CharsetMatch(
    +                sequences,
    +                encoding_iana,
    +                mean_mess_ratio,
    +                bom_or_sig_available,
    +                cd_ratios_merged,
    +                decoded_payload,
    +            )
    +        )
    +
    +        if (
    +            encoding_iana in [specified_encoding, "ascii", "utf_8"]
    +            and mean_mess_ratio < 0.1
    +        ):
    +            logger.debug(
    +                "Encoding detection: %s is most likely the one.", encoding_iana
    +            )
    +            if explain:
    +                logger.removeHandler(explain_handler)
    +                logger.setLevel(previous_logger_level)
    +            return CharsetMatches([results[encoding_iana]])
    +
    +        if encoding_iana == sig_encoding:
    +            logger.debug(
    +                "Encoding detection: %s is most likely the one as we detected a BOM or SIG within "
    +                "the beginning of the sequence.",
    +                encoding_iana,
    +            )
    +            if explain:
    +                logger.removeHandler(explain_handler)
    +                logger.setLevel(previous_logger_level)
    +            return CharsetMatches([results[encoding_iana]])
    +
    +    if len(results) == 0:
    +        if fallback_u8 or fallback_ascii or fallback_specified:
    +            logger.log(
    +                TRACE,
    +                "Nothing got out of the detection process. Using ASCII/UTF-8/Specified fallback.",
    +            )
    +
    +        if fallback_specified:
    +            logger.debug(
    +                "Encoding detection: %s will be used as a fallback match",
    +                fallback_specified.encoding,
    +            )
    +            results.append(fallback_specified)
    +        elif (
    +            (fallback_u8 and fallback_ascii is None)
    +            or (
    +                fallback_u8
    +                and fallback_ascii
    +                and fallback_u8.fingerprint != fallback_ascii.fingerprint
    +            )
    +            or (fallback_u8 is not None)
    +        ):
    +            logger.debug("Encoding detection: utf_8 will be used as a fallback match")
    +            results.append(fallback_u8)
    +        elif fallback_ascii:
    +            logger.debug("Encoding detection: ascii will be used as a fallback match")
    +            results.append(fallback_ascii)
    +
    +    if results:
    +        logger.debug(
    +            "Encoding detection: Found %s as plausible (best-candidate) for content. With %i alternatives.",
    +            results.best().encoding,  # type: ignore
    +            len(results) - 1,
    +        )
    +    else:
    +        logger.debug("Encoding detection: Unable to determine any suitable charset.")
    +
    +    if explain:
    +        logger.removeHandler(explain_handler)
    +        logger.setLevel(previous_logger_level)
    +
    +    return results
    +
    +
    +def from_fp(
    +    fp: BinaryIO,
    +    steps: int = 5,
    +    chunk_size: int = 512,
    +    threshold: float = 0.20,
    +    cp_isolation: Optional[List[str]] = None,
    +    cp_exclusion: Optional[List[str]] = None,
    +    preemptive_behaviour: bool = True,
    +    explain: bool = False,
    +    language_threshold: float = 0.1,
    +) -> CharsetMatches:
    +    """
    +    Same thing than the function from_bytes but using a file pointer that is already ready.
    +    Will not close the file pointer.
    +    """
    +    return from_bytes(
    +        fp.read(),
    +        steps,
    +        chunk_size,
    +        threshold,
    +        cp_isolation,
    +        cp_exclusion,
    +        preemptive_behaviour,
    +        explain,
    +        language_threshold,
    +    )
    +
    +
    +def from_path(
    +    path: "PathLike[Any]",
    +    steps: int = 5,
    +    chunk_size: int = 512,
    +    threshold: float = 0.20,
    +    cp_isolation: Optional[List[str]] = None,
    +    cp_exclusion: Optional[List[str]] = None,
    +    preemptive_behaviour: bool = True,
    +    explain: bool = False,
    +    language_threshold: float = 0.1,
    +) -> CharsetMatches:
    +    """
    +    Same thing than the function from_bytes but with one extra step. Opening and reading given file path in binary mode.
    +    Can raise IOError.
    +    """
    +    with open(path, "rb") as fp:
    +        return from_fp(
    +            fp,
    +            steps,
    +            chunk_size,
    +            threshold,
    +            cp_isolation,
    +            cp_exclusion,
    +            preemptive_behaviour,
    +            explain,
    +            language_threshold,
    +        )
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/assets/__init__.py b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/assets/__init__.py
    new file mode 100644
    index 0000000..9075930
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/assets/__init__.py
    @@ -0,0 +1,1440 @@
    +# -*- coding: utf-8 -*-
    +from typing import Dict, List
    +
    +# Language label that contain the em dash "—"
    +# character are to be considered alternative seq to origin
    +FREQUENCIES: Dict[str, List[str]] = {
    +    "English": [
    +        "e",
    +        "a",
    +        "t",
    +        "i",
    +        "o",
    +        "n",
    +        "s",
    +        "r",
    +        "h",
    +        "l",
    +        "d",
    +        "c",
    +        "u",
    +        "m",
    +        "f",
    +        "p",
    +        "g",
    +        "w",
    +        "y",
    +        "b",
    +        "v",
    +        "k",
    +        "x",
    +        "j",
    +        "z",
    +        "q",
    +    ],
    +    "English—": [
    +        "e",
    +        "a",
    +        "t",
    +        "i",
    +        "o",
    +        "n",
    +        "s",
    +        "r",
    +        "h",
    +        "l",
    +        "d",
    +        "c",
    +        "m",
    +        "u",
    +        "f",
    +        "p",
    +        "g",
    +        "w",
    +        "b",
    +        "y",
    +        "v",
    +        "k",
    +        "j",
    +        "x",
    +        "z",
    +        "q",
    +    ],
    +    "German": [
    +        "e",
    +        "n",
    +        "i",
    +        "r",
    +        "s",
    +        "t",
    +        "a",
    +        "d",
    +        "h",
    +        "u",
    +        "l",
    +        "g",
    +        "o",
    +        "c",
    +        "m",
    +        "b",
    +        "f",
    +        "k",
    +        "w",
    +        "z",
    +        "p",
    +        "v",
    +        "ü",
    +        "ä",
    +        "ö",
    +        "j",
    +    ],
    +    "French": [
    +        "e",
    +        "a",
    +        "s",
    +        "n",
    +        "i",
    +        "t",
    +        "r",
    +        "l",
    +        "u",
    +        "o",
    +        "d",
    +        "c",
    +        "p",
    +        "m",
    +        "é",
    +        "v",
    +        "g",
    +        "f",
    +        "b",
    +        "h",
    +        "q",
    +        "à",
    +        "x",
    +        "è",
    +        "y",
    +        "j",
    +    ],
    +    "Dutch": [
    +        "e",
    +        "n",
    +        "a",
    +        "i",
    +        "r",
    +        "t",
    +        "o",
    +        "d",
    +        "s",
    +        "l",
    +        "g",
    +        "h",
    +        "v",
    +        "m",
    +        "u",
    +        "k",
    +        "c",
    +        "p",
    +        "b",
    +        "w",
    +        "j",
    +        "z",
    +        "f",
    +        "y",
    +        "x",
    +        "ë",
    +    ],
    +    "Italian": [
    +        "e",
    +        "i",
    +        "a",
    +        "o",
    +        "n",
    +        "l",
    +        "t",
    +        "r",
    +        "s",
    +        "c",
    +        "d",
    +        "u",
    +        "p",
    +        "m",
    +        "g",
    +        "v",
    +        "f",
    +        "b",
    +        "z",
    +        "h",
    +        "q",
    +        "è",
    +        "à",
    +        "k",
    +        "y",
    +        "ò",
    +    ],
    +    "Polish": [
    +        "a",
    +        "i",
    +        "o",
    +        "e",
    +        "n",
    +        "r",
    +        "z",
    +        "w",
    +        "s",
    +        "c",
    +        "t",
    +        "k",
    +        "y",
    +        "d",
    +        "p",
    +        "m",
    +        "u",
    +        "l",
    +        "j",
    +        "ł",
    +        "g",
    +        "b",
    +        "h",
    +        "ą",
    +        "ę",
    +        "ó",
    +    ],
    +    "Spanish": [
    +        "e",
    +        "a",
    +        "o",
    +        "n",
    +        "s",
    +        "r",
    +        "i",
    +        "l",
    +        "d",
    +        "t",
    +        "c",
    +        "u",
    +        "m",
    +        "p",
    +        "b",
    +        "g",
    +        "v",
    +        "f",
    +        "y",
    +        "ó",
    +        "h",
    +        "q",
    +        "í",
    +        "j",
    +        "z",
    +        "á",
    +    ],
    +    "Russian": [
    +        "о",
    +        "а",
    +        "е",
    +        "и",
    +        "н",
    +        "с",
    +        "т",
    +        "р",
    +        "в",
    +        "л",
    +        "к",
    +        "м",
    +        "д",
    +        "п",
    +        "у",
    +        "г",
    +        "я",
    +        "ы",
    +        "з",
    +        "б",
    +        "й",
    +        "ь",
    +        "ч",
    +        "х",
    +        "ж",
    +        "ц",
    +    ],
    +    # Jap-Kanji
    +    "Japanese": [
    +        "人",
    +        "一",
    +        "大",
    +        "亅",
    +        "丁",
    +        "丨",
    +        "竹",
    +        "笑",
    +        "口",
    +        "日",
    +        "今",
    +        "二",
    +        "彳",
    +        "行",
    +        "十",
    +        "土",
    +        "丶",
    +        "寸",
    +        "寺",
    +        "時",
    +        "乙",
    +        "丿",
    +        "乂",
    +        "气",
    +        "気",
    +        "冂",
    +        "巾",
    +        "亠",
    +        "市",
    +        "目",
    +        "儿",
    +        "見",
    +        "八",
    +        "小",
    +        "凵",
    +        "県",
    +        "月",
    +        "彐",
    +        "門",
    +        "間",
    +        "木",
    +        "東",
    +        "山",
    +        "出",
    +        "本",
    +        "中",
    +        "刀",
    +        "分",
    +        "耳",
    +        "又",
    +        "取",
    +        "最",
    +        "言",
    +        "田",
    +        "心",
    +        "思",
    +        "刂",
    +        "前",
    +        "京",
    +        "尹",
    +        "事",
    +        "生",
    +        "厶",
    +        "云",
    +        "会",
    +        "未",
    +        "来",
    +        "白",
    +        "冫",
    +        "楽",
    +        "灬",
    +        "馬",
    +        "尸",
    +        "尺",
    +        "駅",
    +        "明",
    +        "耂",
    +        "者",
    +        "了",
    +        "阝",
    +        "都",
    +        "高",
    +        "卜",
    +        "占",
    +        "厂",
    +        "广",
    +        "店",
    +        "子",
    +        "申",
    +        "奄",
    +        "亻",
    +        "俺",
    +        "上",
    +        "方",
    +        "冖",
    +        "学",
    +        "衣",
    +        "艮",
    +        "食",
    +        "自",
    +    ],
    +    # Jap-Katakana
    +    "Japanese—": [
    +        "ー",
    +        "ン",
    +        "ス",
    +        "・",
    +        "ル",
    +        "ト",
    +        "リ",
    +        "イ",
    +        "ア",
    +        "ラ",
    +        "ッ",
    +        "ク",
    +        "ド",
    +        "シ",
    +        "レ",
    +        "ジ",
    +        "タ",
    +        "フ",
    +        "ロ",
    +        "カ",
    +        "テ",
    +        "マ",
    +        "ィ",
    +        "グ",
    +        "バ",
    +        "ム",
    +        "プ",
    +        "オ",
    +        "コ",
    +        "デ",
    +        "ニ",
    +        "ウ",
    +        "メ",
    +        "サ",
    +        "ビ",
    +        "ナ",
    +        "ブ",
    +        "ャ",
    +        "エ",
    +        "ュ",
    +        "チ",
    +        "キ",
    +        "ズ",
    +        "ダ",
    +        "パ",
    +        "ミ",
    +        "ェ",
    +        "ョ",
    +        "ハ",
    +        "セ",
    +        "ベ",
    +        "ガ",
    +        "モ",
    +        "ツ",
    +        "ネ",
    +        "ボ",
    +        "ソ",
    +        "ノ",
    +        "ァ",
    +        "ヴ",
    +        "ワ",
    +        "ポ",
    +        "ペ",
    +        "ピ",
    +        "ケ",
    +        "ゴ",
    +        "ギ",
    +        "ザ",
    +        "ホ",
    +        "ゲ",
    +        "ォ",
    +        "ヤ",
    +        "ヒ",
    +        "ユ",
    +        "ヨ",
    +        "ヘ",
    +        "ゼ",
    +        "ヌ",
    +        "ゥ",
    +        "ゾ",
    +        "ヶ",
    +        "ヂ",
    +        "ヲ",
    +        "ヅ",
    +        "ヵ",
    +        "ヱ",
    +        "ヰ",
    +        "ヮ",
    +        "ヽ",
    +        "゠",
    +        "ヾ",
    +        "ヷ",
    +        "ヿ",
    +        "ヸ",
    +        "ヹ",
    +        "ヺ",
    +    ],
    +    # Jap-Hiragana
    +    "Japanese——": [
    +        "の",
    +        "に",
    +        "る",
    +        "た",
    +        "と",
    +        "は",
    +        "し",
    +        "い",
    +        "を",
    +        "で",
    +        "て",
    +        "が",
    +        "な",
    +        "れ",
    +        "か",
    +        "ら",
    +        "さ",
    +        "っ",
    +        "り",
    +        "す",
    +        "あ",
    +        "も",
    +        "こ",
    +        "ま",
    +        "う",
    +        "く",
    +        "よ",
    +        "き",
    +        "ん",
    +        "め",
    +        "お",
    +        "け",
    +        "そ",
    +        "つ",
    +        "だ",
    +        "や",
    +        "え",
    +        "ど",
    +        "わ",
    +        "ち",
    +        "み",
    +        "せ",
    +        "じ",
    +        "ば",
    +        "へ",
    +        "び",
    +        "ず",
    +        "ろ",
    +        "ほ",
    +        "げ",
    +        "む",
    +        "べ",
    +        "ひ",
    +        "ょ",
    +        "ゆ",
    +        "ぶ",
    +        "ご",
    +        "ゃ",
    +        "ね",
    +        "ふ",
    +        "ぐ",
    +        "ぎ",
    +        "ぼ",
    +        "ゅ",
    +        "づ",
    +        "ざ",
    +        "ぞ",
    +        "ぬ",
    +        "ぜ",
    +        "ぱ",
    +        "ぽ",
    +        "ぷ",
    +        "ぴ",
    +        "ぃ",
    +        "ぁ",
    +        "ぇ",
    +        "ぺ",
    +        "ゞ",
    +        "ぢ",
    +        "ぉ",
    +        "ぅ",
    +        "ゐ",
    +        "ゝ",
    +        "ゑ",
    +        "゛",
    +        "゜",
    +        "ゎ",
    +        "ゔ",
    +        "゚",
    +        "ゟ",
    +        "゙",
    +        "ゕ",
    +        "ゖ",
    +    ],
    +    "Portuguese": [
    +        "a",
    +        "e",
    +        "o",
    +        "s",
    +        "i",
    +        "r",
    +        "d",
    +        "n",
    +        "t",
    +        "m",
    +        "u",
    +        "c",
    +        "l",
    +        "p",
    +        "g",
    +        "v",
    +        "b",
    +        "f",
    +        "h",
    +        "ã",
    +        "q",
    +        "é",
    +        "ç",
    +        "á",
    +        "z",
    +        "í",
    +    ],
    +    "Swedish": [
    +        "e",
    +        "a",
    +        "n",
    +        "r",
    +        "t",
    +        "s",
    +        "i",
    +        "l",
    +        "d",
    +        "o",
    +        "m",
    +        "k",
    +        "g",
    +        "v",
    +        "h",
    +        "f",
    +        "u",
    +        "p",
    +        "ä",
    +        "c",
    +        "b",
    +        "ö",
    +        "å",
    +        "y",
    +        "j",
    +        "x",
    +    ],
    +    "Chinese": [
    +        "的",
    +        "一",
    +        "是",
    +        "不",
    +        "了",
    +        "在",
    +        "人",
    +        "有",
    +        "我",
    +        "他",
    +        "这",
    +        "个",
    +        "们",
    +        "中",
    +        "来",
    +        "上",
    +        "大",
    +        "为",
    +        "和",
    +        "国",
    +        "地",
    +        "到",
    +        "以",
    +        "说",
    +        "时",
    +        "要",
    +        "就",
    +        "出",
    +        "会",
    +        "可",
    +        "也",
    +        "你",
    +        "对",
    +        "生",
    +        "能",
    +        "而",
    +        "子",
    +        "那",
    +        "得",
    +        "于",
    +        "着",
    +        "下",
    +        "自",
    +        "之",
    +        "年",
    +        "过",
    +        "发",
    +        "后",
    +        "作",
    +        "里",
    +        "用",
    +        "道",
    +        "行",
    +        "所",
    +        "然",
    +        "家",
    +        "种",
    +        "事",
    +        "成",
    +        "方",
    +        "多",
    +        "经",
    +        "么",
    +        "去",
    +        "法",
    +        "学",
    +        "如",
    +        "都",
    +        "同",
    +        "现",
    +        "当",
    +        "没",
    +        "动",
    +        "面",
    +        "起",
    +        "看",
    +        "定",
    +        "天",
    +        "分",
    +        "还",
    +        "进",
    +        "好",
    +        "小",
    +        "部",
    +        "其",
    +        "些",
    +        "主",
    +        "样",
    +        "理",
    +        "心",
    +        "她",
    +        "本",
    +        "前",
    +        "开",
    +        "但",
    +        "因",
    +        "只",
    +        "从",
    +        "想",
    +        "实",
    +    ],
    +    "Ukrainian": [
    +        "о",
    +        "а",
    +        "н",
    +        "і",
    +        "и",
    +        "р",
    +        "в",
    +        "т",
    +        "е",
    +        "с",
    +        "к",
    +        "л",
    +        "у",
    +        "д",
    +        "м",
    +        "п",
    +        "з",
    +        "я",
    +        "ь",
    +        "б",
    +        "г",
    +        "й",
    +        "ч",
    +        "х",
    +        "ц",
    +        "ї",
    +    ],
    +    "Norwegian": [
    +        "e",
    +        "r",
    +        "n",
    +        "t",
    +        "a",
    +        "s",
    +        "i",
    +        "o",
    +        "l",
    +        "d",
    +        "g",
    +        "k",
    +        "m",
    +        "v",
    +        "f",
    +        "p",
    +        "u",
    +        "b",
    +        "h",
    +        "å",
    +        "y",
    +        "j",
    +        "ø",
    +        "c",
    +        "æ",
    +        "w",
    +    ],
    +    "Finnish": [
    +        "a",
    +        "i",
    +        "n",
    +        "t",
    +        "e",
    +        "s",
    +        "l",
    +        "o",
    +        "u",
    +        "k",
    +        "ä",
    +        "m",
    +        "r",
    +        "v",
    +        "j",
    +        "h",
    +        "p",
    +        "y",
    +        "d",
    +        "ö",
    +        "g",
    +        "c",
    +        "b",
    +        "f",
    +        "w",
    +        "z",
    +    ],
    +    "Vietnamese": [
    +        "n",
    +        "h",
    +        "t",
    +        "i",
    +        "c",
    +        "g",
    +        "a",
    +        "o",
    +        "u",
    +        "m",
    +        "l",
    +        "r",
    +        "à",
    +        "đ",
    +        "s",
    +        "e",
    +        "v",
    +        "p",
    +        "b",
    +        "y",
    +        "ư",
    +        "d",
    +        "á",
    +        "k",
    +        "ộ",
    +        "ế",
    +    ],
    +    "Czech": [
    +        "o",
    +        "e",
    +        "a",
    +        "n",
    +        "t",
    +        "s",
    +        "i",
    +        "l",
    +        "v",
    +        "r",
    +        "k",
    +        "d",
    +        "u",
    +        "m",
    +        "p",
    +        "í",
    +        "c",
    +        "h",
    +        "z",
    +        "á",
    +        "y",
    +        "j",
    +        "b",
    +        "ě",
    +        "é",
    +        "ř",
    +    ],
    +    "Hungarian": [
    +        "e",
    +        "a",
    +        "t",
    +        "l",
    +        "s",
    +        "n",
    +        "k",
    +        "r",
    +        "i",
    +        "o",
    +        "z",
    +        "á",
    +        "é",
    +        "g",
    +        "m",
    +        "b",
    +        "y",
    +        "v",
    +        "d",
    +        "h",
    +        "u",
    +        "p",
    +        "j",
    +        "ö",
    +        "f",
    +        "c",
    +    ],
    +    "Korean": [
    +        "이",
    +        "다",
    +        "에",
    +        "의",
    +        "는",
    +        "로",
    +        "하",
    +        "을",
    +        "가",
    +        "고",
    +        "지",
    +        "서",
    +        "한",
    +        "은",
    +        "기",
    +        "으",
    +        "년",
    +        "대",
    +        "사",
    +        "시",
    +        "를",
    +        "리",
    +        "도",
    +        "인",
    +        "스",
    +        "일",
    +    ],
    +    "Indonesian": [
    +        "a",
    +        "n",
    +        "e",
    +        "i",
    +        "r",
    +        "t",
    +        "u",
    +        "s",
    +        "d",
    +        "k",
    +        "m",
    +        "l",
    +        "g",
    +        "p",
    +        "b",
    +        "o",
    +        "h",
    +        "y",
    +        "j",
    +        "c",
    +        "w",
    +        "f",
    +        "v",
    +        "z",
    +        "x",
    +        "q",
    +    ],
    +    "Turkish": [
    +        "a",
    +        "e",
    +        "i",
    +        "n",
    +        "r",
    +        "l",
    +        "ı",
    +        "k",
    +        "d",
    +        "t",
    +        "s",
    +        "m",
    +        "y",
    +        "u",
    +        "o",
    +        "b",
    +        "ü",
    +        "ş",
    +        "v",
    +        "g",
    +        "z",
    +        "h",
    +        "c",
    +        "p",
    +        "ç",
    +        "ğ",
    +    ],
    +    "Romanian": [
    +        "e",
    +        "i",
    +        "a",
    +        "r",
    +        "n",
    +        "t",
    +        "u",
    +        "l",
    +        "o",
    +        "c",
    +        "s",
    +        "d",
    +        "p",
    +        "m",
    +        "ă",
    +        "f",
    +        "v",
    +        "î",
    +        "g",
    +        "b",
    +        "ș",
    +        "ț",
    +        "z",
    +        "h",
    +        "â",
    +        "j",
    +    ],
    +    "Farsi": [
    +        "ا",
    +        "ی",
    +        "ر",
    +        "د",
    +        "ن",
    +        "ه",
    +        "و",
    +        "م",
    +        "ت",
    +        "ب",
    +        "س",
    +        "ل",
    +        "ک",
    +        "ش",
    +        "ز",
    +        "ف",
    +        "گ",
    +        "ع",
    +        "خ",
    +        "ق",
    +        "ج",
    +        "آ",
    +        "پ",
    +        "ح",
    +        "ط",
    +        "ص",
    +    ],
    +    "Arabic": [
    +        "ا",
    +        "ل",
    +        "ي",
    +        "م",
    +        "و",
    +        "ن",
    +        "ر",
    +        "ت",
    +        "ب",
    +        "ة",
    +        "ع",
    +        "د",
    +        "س",
    +        "ف",
    +        "ه",
    +        "ك",
    +        "ق",
    +        "أ",
    +        "ح",
    +        "ج",
    +        "ش",
    +        "ط",
    +        "ص",
    +        "ى",
    +        "خ",
    +        "إ",
    +    ],
    +    "Danish": [
    +        "e",
    +        "r",
    +        "n",
    +        "t",
    +        "a",
    +        "i",
    +        "s",
    +        "d",
    +        "l",
    +        "o",
    +        "g",
    +        "m",
    +        "k",
    +        "f",
    +        "v",
    +        "u",
    +        "b",
    +        "h",
    +        "p",
    +        "å",
    +        "y",
    +        "ø",
    +        "æ",
    +        "c",
    +        "j",
    +        "w",
    +    ],
    +    "Serbian": [
    +        "а",
    +        "и",
    +        "о",
    +        "е",
    +        "н",
    +        "р",
    +        "с",
    +        "у",
    +        "т",
    +        "к",
    +        "ј",
    +        "в",
    +        "д",
    +        "м",
    +        "п",
    +        "л",
    +        "г",
    +        "з",
    +        "б",
    +        "a",
    +        "i",
    +        "e",
    +        "o",
    +        "n",
    +        "ц",
    +        "ш",
    +    ],
    +    "Lithuanian": [
    +        "i",
    +        "a",
    +        "s",
    +        "o",
    +        "r",
    +        "e",
    +        "t",
    +        "n",
    +        "u",
    +        "k",
    +        "m",
    +        "l",
    +        "p",
    +        "v",
    +        "d",
    +        "j",
    +        "g",
    +        "ė",
    +        "b",
    +        "y",
    +        "ų",
    +        "š",
    +        "ž",
    +        "c",
    +        "ą",
    +        "į",
    +    ],
    +    "Slovene": [
    +        "e",
    +        "a",
    +        "i",
    +        "o",
    +        "n",
    +        "r",
    +        "s",
    +        "l",
    +        "t",
    +        "j",
    +        "v",
    +        "k",
    +        "d",
    +        "p",
    +        "m",
    +        "u",
    +        "z",
    +        "b",
    +        "g",
    +        "h",
    +        "č",
    +        "c",
    +        "š",
    +        "ž",
    +        "f",
    +        "y",
    +    ],
    +    "Slovak": [
    +        "o",
    +        "a",
    +        "e",
    +        "n",
    +        "i",
    +        "r",
    +        "v",
    +        "t",
    +        "s",
    +        "l",
    +        "k",
    +        "d",
    +        "m",
    +        "p",
    +        "u",
    +        "c",
    +        "h",
    +        "j",
    +        "b",
    +        "z",
    +        "á",
    +        "y",
    +        "ý",
    +        "í",
    +        "č",
    +        "é",
    +    ],
    +    "Hebrew": [
    +        "י",
    +        "ו",
    +        "ה",
    +        "ל",
    +        "ר",
    +        "ב",
    +        "ת",
    +        "מ",
    +        "א",
    +        "ש",
    +        "נ",
    +        "ע",
    +        "ם",
    +        "ד",
    +        "ק",
    +        "ח",
    +        "פ",
    +        "ס",
    +        "כ",
    +        "ג",
    +        "ט",
    +        "צ",
    +        "ן",
    +        "ז",
    +        "ך",
    +    ],
    +    "Bulgarian": [
    +        "а",
    +        "и",
    +        "о",
    +        "е",
    +        "н",
    +        "т",
    +        "р",
    +        "с",
    +        "в",
    +        "л",
    +        "к",
    +        "д",
    +        "п",
    +        "м",
    +        "з",
    +        "г",
    +        "я",
    +        "ъ",
    +        "у",
    +        "б",
    +        "ч",
    +        "ц",
    +        "й",
    +        "ж",
    +        "щ",
    +        "х",
    +    ],
    +    "Croatian": [
    +        "a",
    +        "i",
    +        "o",
    +        "e",
    +        "n",
    +        "r",
    +        "j",
    +        "s",
    +        "t",
    +        "u",
    +        "k",
    +        "l",
    +        "v",
    +        "d",
    +        "m",
    +        "p",
    +        "g",
    +        "z",
    +        "b",
    +        "c",
    +        "č",
    +        "h",
    +        "š",
    +        "ž",
    +        "ć",
    +        "f",
    +    ],
    +    "Hindi": [
    +        "क",
    +        "र",
    +        "स",
    +        "न",
    +        "त",
    +        "म",
    +        "ह",
    +        "प",
    +        "य",
    +        "ल",
    +        "व",
    +        "ज",
    +        "द",
    +        "ग",
    +        "ब",
    +        "श",
    +        "ट",
    +        "अ",
    +        "ए",
    +        "थ",
    +        "भ",
    +        "ड",
    +        "च",
    +        "ध",
    +        "ष",
    +        "इ",
    +    ],
    +    "Estonian": [
    +        "a",
    +        "i",
    +        "e",
    +        "s",
    +        "t",
    +        "l",
    +        "u",
    +        "n",
    +        "o",
    +        "k",
    +        "r",
    +        "d",
    +        "m",
    +        "v",
    +        "g",
    +        "p",
    +        "j",
    +        "h",
    +        "ä",
    +        "b",
    +        "õ",
    +        "ü",
    +        "f",
    +        "c",
    +        "ö",
    +        "y",
    +    ],
    +    "Thai": [
    +        "า",
    +        "น",
    +        "ร",
    +        "อ",
    +        "ก",
    +        "เ",
    +        "ง",
    +        "ม",
    +        "ย",
    +        "ล",
    +        "ว",
    +        "ด",
    +        "ท",
    +        "ส",
    +        "ต",
    +        "ะ",
    +        "ป",
    +        "บ",
    +        "ค",
    +        "ห",
    +        "แ",
    +        "จ",
    +        "พ",
    +        "ช",
    +        "ข",
    +        "ใ",
    +    ],
    +    "Greek": [
    +        "α",
    +        "τ",
    +        "ο",
    +        "ι",
    +        "ε",
    +        "ν",
    +        "ρ",
    +        "σ",
    +        "κ",
    +        "η",
    +        "π",
    +        "ς",
    +        "υ",
    +        "μ",
    +        "λ",
    +        "ί",
    +        "ό",
    +        "ά",
    +        "γ",
    +        "έ",
    +        "δ",
    +        "ή",
    +        "ω",
    +        "χ",
    +        "θ",
    +        "ύ",
    +    ],
    +    "Tamil": [
    +        "க",
    +        "த",
    +        "ப",
    +        "ட",
    +        "ர",
    +        "ம",
    +        "ல",
    +        "ன",
    +        "வ",
    +        "ற",
    +        "ய",
    +        "ள",
    +        "ச",
    +        "ந",
    +        "இ",
    +        "ண",
    +        "அ",
    +        "ஆ",
    +        "ழ",
    +        "ங",
    +        "எ",
    +        "உ",
    +        "ஒ",
    +        "ஸ",
    +    ],
    +    "Kazakh": [
    +        "а",
    +        "ы",
    +        "е",
    +        "н",
    +        "т",
    +        "р",
    +        "л",
    +        "і",
    +        "д",
    +        "с",
    +        "м",
    +        "қ",
    +        "к",
    +        "о",
    +        "б",
    +        "и",
    +        "у",
    +        "ғ",
    +        "ж",
    +        "ң",
    +        "з",
    +        "ш",
    +        "й",
    +        "п",
    +        "г",
    +        "ө",
    +    ],
    +}
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/cd.py b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/cd.py
    new file mode 100644
    index 0000000..ae2813f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/cd.py
    @@ -0,0 +1,391 @@
    +import importlib
    +from codecs import IncrementalDecoder
    +from collections import Counter
    +from functools import lru_cache
    +from typing import Counter as TypeCounter, Dict, List, Optional, Tuple
    +
    +from .assets import FREQUENCIES
    +from .constant import KO_NAMES, LANGUAGE_SUPPORTED_COUNT, TOO_SMALL_SEQUENCE, ZH_NAMES
    +from .md import is_suspiciously_successive_range
    +from .models import CoherenceMatches
    +from .utils import (
    +    is_accentuated,
    +    is_latin,
    +    is_multi_byte_encoding,
    +    is_unicode_range_secondary,
    +    unicode_range,
    +)
    +
    +
    +def encoding_unicode_range(iana_name: str) -> List[str]:
    +    """
    +    Return associated unicode ranges in a single byte code page.
    +    """
    +    if is_multi_byte_encoding(iana_name):
    +        raise IOError("Function not supported on multi-byte code page")
    +
    +    decoder = importlib.import_module(
    +        "encodings.{}".format(iana_name)
    +    ).IncrementalDecoder
    +
    +    p: IncrementalDecoder = decoder(errors="ignore")
    +    seen_ranges: Dict[str, int] = {}
    +    character_count: int = 0
    +
    +    for i in range(0x40, 0xFF):
    +        chunk: str = p.decode(bytes([i]))
    +
    +        if chunk:
    +            character_range: Optional[str] = unicode_range(chunk)
    +
    +            if character_range is None:
    +                continue
    +
    +            if is_unicode_range_secondary(character_range) is False:
    +                if character_range not in seen_ranges:
    +                    seen_ranges[character_range] = 0
    +                seen_ranges[character_range] += 1
    +                character_count += 1
    +
    +    return sorted(
    +        [
    +            character_range
    +            for character_range in seen_ranges
    +            if seen_ranges[character_range] / character_count >= 0.15
    +        ]
    +    )
    +
    +
    +def unicode_range_languages(primary_range: str) -> List[str]:
    +    """
    +    Return inferred languages used with a unicode range.
    +    """
    +    languages: List[str] = []
    +
    +    for language, characters in FREQUENCIES.items():
    +        for character in characters:
    +            if unicode_range(character) == primary_range:
    +                languages.append(language)
    +                break
    +
    +    return languages
    +
    +
    +@lru_cache()
    +def encoding_languages(iana_name: str) -> List[str]:
    +    """
    +    Single-byte encoding language association. Some code page are heavily linked to particular language(s).
    +    This function does the correspondence.
    +    """
    +    unicode_ranges: List[str] = encoding_unicode_range(iana_name)
    +    primary_range: Optional[str] = None
    +
    +    for specified_range in unicode_ranges:
    +        if "Latin" not in specified_range:
    +            primary_range = specified_range
    +            break
    +
    +    if primary_range is None:
    +        return ["Latin Based"]
    +
    +    return unicode_range_languages(primary_range)
    +
    +
    +@lru_cache()
    +def mb_encoding_languages(iana_name: str) -> List[str]:
    +    """
    +    Multi-byte encoding language association. Some code page are heavily linked to particular language(s).
    +    This function does the correspondence.
    +    """
    +    if (
    +        iana_name.startswith("shift_")
    +        or iana_name.startswith("iso2022_jp")
    +        or iana_name.startswith("euc_j")
    +        or iana_name == "cp932"
    +    ):
    +        return ["Japanese"]
    +    if iana_name.startswith("gb") or iana_name in ZH_NAMES:
    +        return ["Chinese"]
    +    if iana_name.startswith("iso2022_kr") or iana_name in KO_NAMES:
    +        return ["Korean"]
    +
    +    return []
    +
    +
    +@lru_cache(maxsize=LANGUAGE_SUPPORTED_COUNT)
    +def get_target_features(language: str) -> Tuple[bool, bool]:
    +    """
    +    Determine main aspects from a supported language if it contains accents and if is pure Latin.
    +    """
    +    target_have_accents: bool = False
    +    target_pure_latin: bool = True
    +
    +    for character in FREQUENCIES[language]:
    +        if not target_have_accents and is_accentuated(character):
    +            target_have_accents = True
    +        if target_pure_latin and is_latin(character) is False:
    +            target_pure_latin = False
    +
    +    return target_have_accents, target_pure_latin
    +
    +
    +def alphabet_languages(
    +    characters: List[str], ignore_non_latin: bool = False
    +) -> List[str]:
    +    """
    +    Return associated languages associated to given characters.
    +    """
    +    languages: List[Tuple[str, float]] = []
    +
    +    source_have_accents = any(is_accentuated(character) for character in characters)
    +
    +    for language, language_characters in FREQUENCIES.items():
    +
    +        target_have_accents, target_pure_latin = get_target_features(language)
    +
    +        if ignore_non_latin and target_pure_latin is False:
    +            continue
    +
    +        if target_have_accents is False and source_have_accents:
    +            continue
    +
    +        character_count: int = len(language_characters)
    +
    +        character_match_count: int = len(
    +            [c for c in language_characters if c in characters]
    +        )
    +
    +        ratio: float = character_match_count / character_count
    +
    +        if ratio >= 0.2:
    +            languages.append((language, ratio))
    +
    +    languages = sorted(languages, key=lambda x: x[1], reverse=True)
    +
    +    return [compatible_language[0] for compatible_language in languages]
    +
    +
    +def characters_popularity_compare(
    +    language: str, ordered_characters: List[str]
    +) -> float:
    +    """
    +    Determine if a ordered characters list (by occurrence from most appearance to rarest) match a particular language.
    +    The result is a ratio between 0. (absolutely no correspondence) and 1. (near perfect fit).
    +    Beware that is function is not strict on the match in order to ease the detection. (Meaning close match is 1.)
    +    """
    +    if language not in FREQUENCIES:
    +        raise ValueError("{} not available".format(language))
    +
    +    character_approved_count: int = 0
    +    FREQUENCIES_language_set = set(FREQUENCIES[language])
    +
    +    ordered_characters_count: int = len(ordered_characters)
    +    target_language_characters_count: int = len(FREQUENCIES[language])
    +
    +    large_alphabet: bool = target_language_characters_count > 26
    +
    +    for character, character_rank in zip(
    +        ordered_characters, range(0, ordered_characters_count)
    +    ):
    +        if character not in FREQUENCIES_language_set:
    +            continue
    +
    +        character_rank_in_language: int = FREQUENCIES[language].index(character)
    +        expected_projection_ratio: float = (
    +            target_language_characters_count / ordered_characters_count
    +        )
    +        character_rank_projection: int = int(character_rank * expected_projection_ratio)
    +
    +        if (
    +            large_alphabet is False
    +            and abs(character_rank_projection - character_rank_in_language) > 4
    +        ):
    +            continue
    +
    +        if (
    +            large_alphabet is True
    +            and abs(character_rank_projection - character_rank_in_language)
    +            < target_language_characters_count / 3
    +        ):
    +            character_approved_count += 1
    +            continue
    +
    +        characters_before_source: List[str] = FREQUENCIES[language][
    +            0:character_rank_in_language
    +        ]
    +        characters_after_source: List[str] = FREQUENCIES[language][
    +            character_rank_in_language:
    +        ]
    +        characters_before: List[str] = ordered_characters[0:character_rank]
    +        characters_after: List[str] = ordered_characters[character_rank:]
    +
    +        before_match_count: int = len(
    +            set(characters_before) & set(characters_before_source)
    +        )
    +
    +        after_match_count: int = len(
    +            set(characters_after) & set(characters_after_source)
    +        )
    +
    +        if len(characters_before_source) == 0 and before_match_count <= 4:
    +            character_approved_count += 1
    +            continue
    +
    +        if len(characters_after_source) == 0 and after_match_count <= 4:
    +            character_approved_count += 1
    +            continue
    +
    +        if (
    +            before_match_count / len(characters_before_source) >= 0.4
    +            or after_match_count / len(characters_after_source) >= 0.4
    +        ):
    +            character_approved_count += 1
    +            continue
    +
    +    return character_approved_count / len(ordered_characters)
    +
    +
    +def alpha_unicode_split(decoded_sequence: str) -> List[str]:
    +    """
    +    Given a decoded text sequence, return a list of str. Unicode range / alphabet separation.
    +    Ex. a text containing English/Latin with a bit a Hebrew will return two items in the resulting list;
    +    One containing the latin letters and the other hebrew.
    +    """
    +    layers: Dict[str, str] = {}
    +
    +    for character in decoded_sequence:
    +        if character.isalpha() is False:
    +            continue
    +
    +        character_range: Optional[str] = unicode_range(character)
    +
    +        if character_range is None:
    +            continue
    +
    +        layer_target_range: Optional[str] = None
    +
    +        for discovered_range in layers:
    +            if (
    +                is_suspiciously_successive_range(discovered_range, character_range)
    +                is False
    +            ):
    +                layer_target_range = discovered_range
    +                break
    +
    +        if layer_target_range is None:
    +            layer_target_range = character_range
    +
    +        if layer_target_range not in layers:
    +            layers[layer_target_range] = character.lower()
    +            continue
    +
    +        layers[layer_target_range] += character.lower()
    +
    +    return list(layers.values())
    +
    +
    +def merge_coherence_ratios(results: List[CoherenceMatches]) -> CoherenceMatches:
    +    """
    +    This function merge results previously given by the function coherence_ratio.
    +    The return type is the same as coherence_ratio.
    +    """
    +    per_language_ratios: Dict[str, List[float]] = {}
    +    for result in results:
    +        for sub_result in result:
    +            language, ratio = sub_result
    +            if language not in per_language_ratios:
    +                per_language_ratios[language] = [ratio]
    +                continue
    +            per_language_ratios[language].append(ratio)
    +
    +    merge = [
    +        (
    +            language,
    +            round(
    +                sum(per_language_ratios[language]) / len(per_language_ratios[language]),
    +                4,
    +            ),
    +        )
    +        for language in per_language_ratios
    +    ]
    +
    +    return sorted(merge, key=lambda x: x[1], reverse=True)
    +
    +
    +def filter_alt_coherence_matches(results: CoherenceMatches) -> CoherenceMatches:
    +    """
    +    We shall NOT return "English—" in CoherenceMatches because it is an alternative
    +    of "English". This function only keeps the best match and remove the em-dash in it.
    +    """
    +    index_results: Dict[str, List[float]] = dict()
    +
    +    for result in results:
    +        language, ratio = result
    +        no_em_name: str = language.replace("—", "")
    +
    +        if no_em_name not in index_results:
    +            index_results[no_em_name] = []
    +
    +        index_results[no_em_name].append(ratio)
    +
    +    if any(len(index_results[e]) > 1 for e in index_results):
    +        filtered_results: CoherenceMatches = []
    +
    +        for language in index_results:
    +            filtered_results.append((language, max(index_results[language])))
    +
    +        return filtered_results
    +
    +    return results
    +
    +
    +@lru_cache(maxsize=2048)
    +def coherence_ratio(
    +    decoded_sequence: str, threshold: float = 0.1, lg_inclusion: Optional[str] = None
    +) -> CoherenceMatches:
    +    """
    +    Detect ANY language that can be identified in given sequence. The sequence will be analysed by layers.
    +    A layer = Character extraction by alphabets/ranges.
    +    """
    +
    +    results: List[Tuple[str, float]] = []
    +    ignore_non_latin: bool = False
    +
    +    sufficient_match_count: int = 0
    +
    +    lg_inclusion_list = lg_inclusion.split(",") if lg_inclusion is not None else []
    +    if "Latin Based" in lg_inclusion_list:
    +        ignore_non_latin = True
    +        lg_inclusion_list.remove("Latin Based")
    +
    +    for layer in alpha_unicode_split(decoded_sequence):
    +        sequence_frequencies: TypeCounter[str] = Counter(layer)
    +        most_common = sequence_frequencies.most_common()
    +
    +        character_count: int = sum(o for c, o in most_common)
    +
    +        if character_count <= TOO_SMALL_SEQUENCE:
    +            continue
    +
    +        popular_character_ordered: List[str] = [c for c, o in most_common]
    +
    +        for language in lg_inclusion_list or alphabet_languages(
    +            popular_character_ordered, ignore_non_latin
    +        ):
    +            ratio: float = characters_popularity_compare(
    +                language, popular_character_ordered
    +            )
    +
    +            if ratio < threshold:
    +                continue
    +            elif ratio >= 0.8:
    +                sufficient_match_count += 1
    +
    +            results.append((language, round(ratio, 4)))
    +
    +            if sufficient_match_count >= 3:
    +                break
    +
    +    return sorted(
    +        filter_alt_coherence_matches(results), key=lambda x: x[1], reverse=True
    +    )
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/cli/__init__.py b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/cli/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/cli/normalizer.py b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/cli/normalizer.py
    new file mode 100644
    index 0000000..ad26b4d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/cli/normalizer.py
    @@ -0,0 +1,298 @@
    +import argparse
    +import sys
    +from json import dumps
    +from os.path import abspath, basename, dirname, join, realpath
    +from platform import python_version
    +from typing import List, Optional
    +from unicodedata import unidata_version
    +
    +import charset_normalizer.md as md_module
    +from charset_normalizer import from_fp
    +from charset_normalizer.models import CliDetectionResult
    +from charset_normalizer.version import __version__
    +
    +
    +def query_yes_no(question: str, default: str = "yes") -> bool:
    +    """Ask a yes/no question via input() and return their answer.
    +
    +    "question" is a string that is presented to the user.
    +    "default" is the presumed answer if the user just hits <Enter>.
    +        It must be "yes" (the default), "no" or None (meaning
    +        an answer is required of the user).
    +
    +    The "answer" return value is True for "yes" or False for "no".
    +
    +    Credit goes to (c) https://stackoverflow.com/questions/3041986/apt-command-line-interface-like-yes-no-input
    +    """
    +    valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False}
    +    if default is None:
    +        prompt = " [y/n] "
    +    elif default == "yes":
    +        prompt = " [Y/n] "
    +    elif default == "no":
    +        prompt = " [y/N] "
    +    else:
    +        raise ValueError("invalid default answer: '%s'" % default)
    +
    +    while True:
    +        sys.stdout.write(question + prompt)
    +        choice = input().lower()
    +        if default is not None and choice == "":
    +            return valid[default]
    +        elif choice in valid:
    +            return valid[choice]
    +        else:
    +            sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n")
    +
    +
    +def cli_detect(argv: Optional[List[str]] = None) -> int:
    +    """
    +    CLI assistant using ARGV and ArgumentParser
    +    :param argv:
    +    :return: 0 if everything is fine, anything else equal trouble
    +    """
    +    parser = argparse.ArgumentParser(
    +        description="The Real First Universal Charset Detector. "
    +        "Discover originating encoding used on text file. "
    +        "Normalize text to unicode."
    +    )
    +
    +    parser.add_argument(
    +        "files", type=argparse.FileType("rb"), nargs="+", help="File(s) to be analysed"
    +    )
    +    parser.add_argument(
    +        "-v",
    +        "--verbose",
    +        action="store_true",
    +        default=False,
    +        dest="verbose",
    +        help="Display complementary information about file if any. "
    +        "Stdout will contain logs about the detection process.",
    +    )
    +    parser.add_argument(
    +        "-a",
    +        "--with-alternative",
    +        action="store_true",
    +        default=False,
    +        dest="alternatives",
    +        help="Output complementary possibilities if any. Top-level JSON WILL be a list.",
    +    )
    +    parser.add_argument(
    +        "-n",
    +        "--normalize",
    +        action="store_true",
    +        default=False,
    +        dest="normalize",
    +        help="Permit to normalize input file. If not set, program does not write anything.",
    +    )
    +    parser.add_argument(
    +        "-m",
    +        "--minimal",
    +        action="store_true",
    +        default=False,
    +        dest="minimal",
    +        help="Only output the charset detected to STDOUT. Disabling JSON output.",
    +    )
    +    parser.add_argument(
    +        "-r",
    +        "--replace",
    +        action="store_true",
    +        default=False,
    +        dest="replace",
    +        help="Replace file when trying to normalize it instead of creating a new one.",
    +    )
    +    parser.add_argument(
    +        "-f",
    +        "--force",
    +        action="store_true",
    +        default=False,
    +        dest="force",
    +        help="Replace file without asking if you are sure, use this flag with caution.",
    +    )
    +    parser.add_argument(
    +        "-t",
    +        "--threshold",
    +        action="store",
    +        default=0.2,
    +        type=float,
    +        dest="threshold",
    +        help="Define a custom maximum amount of chaos allowed in decoded content. 0. <= chaos <= 1.",
    +    )
    +    parser.add_argument(
    +        "--version",
    +        action="version",
    +        version="Charset-Normalizer {} - Python {} - Unicode {} - SpeedUp {}".format(
    +            __version__,
    +            python_version(),
    +            unidata_version,
    +            "OFF" if md_module.__file__.lower().endswith(".py") else "ON",
    +        ),
    +        help="Show version information and exit.",
    +    )
    +
    +    args = parser.parse_args(argv)
    +
    +    if args.replace is True and args.normalize is False:
    +        print("Use --replace in addition of --normalize only.", file=sys.stderr)
    +        return 1
    +
    +    if args.force is True and args.replace is False:
    +        print("Use --force in addition of --replace only.", file=sys.stderr)
    +        return 1
    +
    +    if args.threshold < 0.0 or args.threshold > 1.0:
    +        print("--threshold VALUE should be between 0. AND 1.", file=sys.stderr)
    +        return 1
    +
    +    x_ = []
    +
    +    for my_file in args.files:
    +
    +        matches = from_fp(my_file, threshold=args.threshold, explain=args.verbose)
    +
    +        best_guess = matches.best()
    +
    +        if best_guess is None:
    +            print(
    +                'Unable to identify originating encoding for "{}". {}'.format(
    +                    my_file.name,
    +                    "Maybe try increasing maximum amount of chaos."
    +                    if args.threshold < 1.0
    +                    else "",
    +                ),
    +                file=sys.stderr,
    +            )
    +            x_.append(
    +                CliDetectionResult(
    +                    abspath(my_file.name),
    +                    None,
    +                    [],
    +                    [],
    +                    "Unknown",
    +                    [],
    +                    False,
    +                    1.0,
    +                    0.0,
    +                    None,
    +                    True,
    +                )
    +            )
    +        else:
    +            x_.append(
    +                CliDetectionResult(
    +                    abspath(my_file.name),
    +                    best_guess.encoding,
    +                    best_guess.encoding_aliases,
    +                    [
    +                        cp
    +                        for cp in best_guess.could_be_from_charset
    +                        if cp != best_guess.encoding
    +                    ],
    +                    best_guess.language,
    +                    best_guess.alphabets,
    +                    best_guess.bom,
    +                    best_guess.percent_chaos,
    +                    best_guess.percent_coherence,
    +                    None,
    +                    True,
    +                )
    +            )
    +
    +            if len(matches) > 1 and args.alternatives:
    +                for el in matches:
    +                    if el != best_guess:
    +                        x_.append(
    +                            CliDetectionResult(
    +                                abspath(my_file.name),
    +                                el.encoding,
    +                                el.encoding_aliases,
    +                                [
    +                                    cp
    +                                    for cp in el.could_be_from_charset
    +                                    if cp != el.encoding
    +                                ],
    +                                el.language,
    +                                el.alphabets,
    +                                el.bom,
    +                                el.percent_chaos,
    +                                el.percent_coherence,
    +                                None,
    +                                False,
    +                            )
    +                        )
    +
    +            if args.normalize is True:
    +
    +                if best_guess.encoding.startswith("utf") is True:
    +                    print(
    +                        '"{}" file does not need to be normalized, as it already came from unicode.'.format(
    +                            my_file.name
    +                        ),
    +                        file=sys.stderr,
    +                    )
    +                    if my_file.closed is False:
    +                        my_file.close()
    +                    continue
    +
    +                dir_path = dirname(realpath(my_file.name))
    +                file_name = basename(realpath(my_file.name))
    +
    +                o_: List[str] = file_name.split(".")
    +
    +                if args.replace is False:
    +                    o_.insert(-1, best_guess.encoding)
    +                    if my_file.closed is False:
    +                        my_file.close()
    +                elif (
    +                    args.force is False
    +                    and query_yes_no(
    +                        'Are you sure to normalize "{}" by replacing it ?'.format(
    +                            my_file.name
    +                        ),
    +                        "no",
    +                    )
    +                    is False
    +                ):
    +                    if my_file.closed is False:
    +                        my_file.close()
    +                    continue
    +
    +                try:
    +                    x_[0].unicode_path = join(dir_path, ".".join(o_))
    +
    +                    with open(x_[0].unicode_path, "w", encoding="utf-8") as fp:
    +                        fp.write(str(best_guess))
    +                except IOError as e:
    +                    print(str(e), file=sys.stderr)
    +                    if my_file.closed is False:
    +                        my_file.close()
    +                    return 2
    +
    +        if my_file.closed is False:
    +            my_file.close()
    +
    +    if args.minimal is False:
    +        print(
    +            dumps(
    +                [el.__dict__ for el in x_] if len(x_) > 1 else x_[0].__dict__,
    +                ensure_ascii=True,
    +                indent=4,
    +            )
    +        )
    +    else:
    +        for my_file in args.files:
    +            print(
    +                ", ".join(
    +                    [
    +                        el.encoding or "undefined"
    +                        for el in x_
    +                        if el.path == abspath(my_file.name)
    +                    ]
    +                )
    +            )
    +
    +    return 0
    +
    +
    +if __name__ == "__main__":
    +    cli_detect()
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/constant.py b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/constant.py
    new file mode 100644
    index 0000000..3188108
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/constant.py
    @@ -0,0 +1,495 @@
    +from codecs import BOM_UTF8, BOM_UTF16_BE, BOM_UTF16_LE, BOM_UTF32_BE, BOM_UTF32_LE
    +from encodings.aliases import aliases
    +from re import IGNORECASE, compile as re_compile
    +from typing import Dict, List, Set, Union
    +
    +from .assets import FREQUENCIES
    +
    +# Contain for each eligible encoding a list of/item bytes SIG/BOM
    +ENCODING_MARKS: Dict[str, Union[bytes, List[bytes]]] = {
    +    "utf_8": BOM_UTF8,
    +    "utf_7": [
    +        b"\x2b\x2f\x76\x38",
    +        b"\x2b\x2f\x76\x39",
    +        b"\x2b\x2f\x76\x2b",
    +        b"\x2b\x2f\x76\x2f",
    +        b"\x2b\x2f\x76\x38\x2d",
    +    ],
    +    "gb18030": b"\x84\x31\x95\x33",
    +    "utf_32": [BOM_UTF32_BE, BOM_UTF32_LE],
    +    "utf_16": [BOM_UTF16_BE, BOM_UTF16_LE],
    +}
    +
    +TOO_SMALL_SEQUENCE: int = 32
    +TOO_BIG_SEQUENCE: int = int(10e6)
    +
    +UTF8_MAXIMAL_ALLOCATION: int = 1112064
    +
    +UNICODE_RANGES_COMBINED: Dict[str, range] = {
    +    "Control character": range(31 + 1),
    +    "Basic Latin": range(32, 127 + 1),
    +    "Latin-1 Supplement": range(128, 255 + 1),
    +    "Latin Extended-A": range(256, 383 + 1),
    +    "Latin Extended-B": range(384, 591 + 1),
    +    "IPA Extensions": range(592, 687 + 1),
    +    "Spacing Modifier Letters": range(688, 767 + 1),
    +    "Combining Diacritical Marks": range(768, 879 + 1),
    +    "Greek and Coptic": range(880, 1023 + 1),
    +    "Cyrillic": range(1024, 1279 + 1),
    +    "Cyrillic Supplement": range(1280, 1327 + 1),
    +    "Armenian": range(1328, 1423 + 1),
    +    "Hebrew": range(1424, 1535 + 1),
    +    "Arabic": range(1536, 1791 + 1),
    +    "Syriac": range(1792, 1871 + 1),
    +    "Arabic Supplement": range(1872, 1919 + 1),
    +    "Thaana": range(1920, 1983 + 1),
    +    "NKo": range(1984, 2047 + 1),
    +    "Samaritan": range(2048, 2111 + 1),
    +    "Mandaic": range(2112, 2143 + 1),
    +    "Syriac Supplement": range(2144, 2159 + 1),
    +    "Arabic Extended-A": range(2208, 2303 + 1),
    +    "Devanagari": range(2304, 2431 + 1),
    +    "Bengali": range(2432, 2559 + 1),
    +    "Gurmukhi": range(2560, 2687 + 1),
    +    "Gujarati": range(2688, 2815 + 1),
    +    "Oriya": range(2816, 2943 + 1),
    +    "Tamil": range(2944, 3071 + 1),
    +    "Telugu": range(3072, 3199 + 1),
    +    "Kannada": range(3200, 3327 + 1),
    +    "Malayalam": range(3328, 3455 + 1),
    +    "Sinhala": range(3456, 3583 + 1),
    +    "Thai": range(3584, 3711 + 1),
    +    "Lao": range(3712, 3839 + 1),
    +    "Tibetan": range(3840, 4095 + 1),
    +    "Myanmar": range(4096, 4255 + 1),
    +    "Georgian": range(4256, 4351 + 1),
    +    "Hangul Jamo": range(4352, 4607 + 1),
    +    "Ethiopic": range(4608, 4991 + 1),
    +    "Ethiopic Supplement": range(4992, 5023 + 1),
    +    "Cherokee": range(5024, 5119 + 1),
    +    "Unified Canadian Aboriginal Syllabics": range(5120, 5759 + 1),
    +    "Ogham": range(5760, 5791 + 1),
    +    "Runic": range(5792, 5887 + 1),
    +    "Tagalog": range(5888, 5919 + 1),
    +    "Hanunoo": range(5920, 5951 + 1),
    +    "Buhid": range(5952, 5983 + 1),
    +    "Tagbanwa": range(5984, 6015 + 1),
    +    "Khmer": range(6016, 6143 + 1),
    +    "Mongolian": range(6144, 6319 + 1),
    +    "Unified Canadian Aboriginal Syllabics Extended": range(6320, 6399 + 1),
    +    "Limbu": range(6400, 6479 + 1),
    +    "Tai Le": range(6480, 6527 + 1),
    +    "New Tai Lue": range(6528, 6623 + 1),
    +    "Khmer Symbols": range(6624, 6655 + 1),
    +    "Buginese": range(6656, 6687 + 1),
    +    "Tai Tham": range(6688, 6831 + 1),
    +    "Combining Diacritical Marks Extended": range(6832, 6911 + 1),
    +    "Balinese": range(6912, 7039 + 1),
    +    "Sundanese": range(7040, 7103 + 1),
    +    "Batak": range(7104, 7167 + 1),
    +    "Lepcha": range(7168, 7247 + 1),
    +    "Ol Chiki": range(7248, 7295 + 1),
    +    "Cyrillic Extended C": range(7296, 7311 + 1),
    +    "Sundanese Supplement": range(7360, 7375 + 1),
    +    "Vedic Extensions": range(7376, 7423 + 1),
    +    "Phonetic Extensions": range(7424, 7551 + 1),
    +    "Phonetic Extensions Supplement": range(7552, 7615 + 1),
    +    "Combining Diacritical Marks Supplement": range(7616, 7679 + 1),
    +    "Latin Extended Additional": range(7680, 7935 + 1),
    +    "Greek Extended": range(7936, 8191 + 1),
    +    "General Punctuation": range(8192, 8303 + 1),
    +    "Superscripts and Subscripts": range(8304, 8351 + 1),
    +    "Currency Symbols": range(8352, 8399 + 1),
    +    "Combining Diacritical Marks for Symbols": range(8400, 8447 + 1),
    +    "Letterlike Symbols": range(8448, 8527 + 1),
    +    "Number Forms": range(8528, 8591 + 1),
    +    "Arrows": range(8592, 8703 + 1),
    +    "Mathematical Operators": range(8704, 8959 + 1),
    +    "Miscellaneous Technical": range(8960, 9215 + 1),
    +    "Control Pictures": range(9216, 9279 + 1),
    +    "Optical Character Recognition": range(9280, 9311 + 1),
    +    "Enclosed Alphanumerics": range(9312, 9471 + 1),
    +    "Box Drawing": range(9472, 9599 + 1),
    +    "Block Elements": range(9600, 9631 + 1),
    +    "Geometric Shapes": range(9632, 9727 + 1),
    +    "Miscellaneous Symbols": range(9728, 9983 + 1),
    +    "Dingbats": range(9984, 10175 + 1),
    +    "Miscellaneous Mathematical Symbols-A": range(10176, 10223 + 1),
    +    "Supplemental Arrows-A": range(10224, 10239 + 1),
    +    "Braille Patterns": range(10240, 10495 + 1),
    +    "Supplemental Arrows-B": range(10496, 10623 + 1),
    +    "Miscellaneous Mathematical Symbols-B": range(10624, 10751 + 1),
    +    "Supplemental Mathematical Operators": range(10752, 11007 + 1),
    +    "Miscellaneous Symbols and Arrows": range(11008, 11263 + 1),
    +    "Glagolitic": range(11264, 11359 + 1),
    +    "Latin Extended-C": range(11360, 11391 + 1),
    +    "Coptic": range(11392, 11519 + 1),
    +    "Georgian Supplement": range(11520, 11567 + 1),
    +    "Tifinagh": range(11568, 11647 + 1),
    +    "Ethiopic Extended": range(11648, 11743 + 1),
    +    "Cyrillic Extended-A": range(11744, 11775 + 1),
    +    "Supplemental Punctuation": range(11776, 11903 + 1),
    +    "CJK Radicals Supplement": range(11904, 12031 + 1),
    +    "Kangxi Radicals": range(12032, 12255 + 1),
    +    "Ideographic Description Characters": range(12272, 12287 + 1),
    +    "CJK Symbols and Punctuation": range(12288, 12351 + 1),
    +    "Hiragana": range(12352, 12447 + 1),
    +    "Katakana": range(12448, 12543 + 1),
    +    "Bopomofo": range(12544, 12591 + 1),
    +    "Hangul Compatibility Jamo": range(12592, 12687 + 1),
    +    "Kanbun": range(12688, 12703 + 1),
    +    "Bopomofo Extended": range(12704, 12735 + 1),
    +    "CJK Strokes": range(12736, 12783 + 1),
    +    "Katakana Phonetic Extensions": range(12784, 12799 + 1),
    +    "Enclosed CJK Letters and Months": range(12800, 13055 + 1),
    +    "CJK Compatibility": range(13056, 13311 + 1),
    +    "CJK Unified Ideographs Extension A": range(13312, 19903 + 1),
    +    "Yijing Hexagram Symbols": range(19904, 19967 + 1),
    +    "CJK Unified Ideographs": range(19968, 40959 + 1),
    +    "Yi Syllables": range(40960, 42127 + 1),
    +    "Yi Radicals": range(42128, 42191 + 1),
    +    "Lisu": range(42192, 42239 + 1),
    +    "Vai": range(42240, 42559 + 1),
    +    "Cyrillic Extended-B": range(42560, 42655 + 1),
    +    "Bamum": range(42656, 42751 + 1),
    +    "Modifier Tone Letters": range(42752, 42783 + 1),
    +    "Latin Extended-D": range(42784, 43007 + 1),
    +    "Syloti Nagri": range(43008, 43055 + 1),
    +    "Common Indic Number Forms": range(43056, 43071 + 1),
    +    "Phags-pa": range(43072, 43135 + 1),
    +    "Saurashtra": range(43136, 43231 + 1),
    +    "Devanagari Extended": range(43232, 43263 + 1),
    +    "Kayah Li": range(43264, 43311 + 1),
    +    "Rejang": range(43312, 43359 + 1),
    +    "Hangul Jamo Extended-A": range(43360, 43391 + 1),
    +    "Javanese": range(43392, 43487 + 1),
    +    "Myanmar Extended-B": range(43488, 43519 + 1),
    +    "Cham": range(43520, 43615 + 1),
    +    "Myanmar Extended-A": range(43616, 43647 + 1),
    +    "Tai Viet": range(43648, 43743 + 1),
    +    "Meetei Mayek Extensions": range(43744, 43775 + 1),
    +    "Ethiopic Extended-A": range(43776, 43823 + 1),
    +    "Latin Extended-E": range(43824, 43887 + 1),
    +    "Cherokee Supplement": range(43888, 43967 + 1),
    +    "Meetei Mayek": range(43968, 44031 + 1),
    +    "Hangul Syllables": range(44032, 55215 + 1),
    +    "Hangul Jamo Extended-B": range(55216, 55295 + 1),
    +    "High Surrogates": range(55296, 56191 + 1),
    +    "High Private Use Surrogates": range(56192, 56319 + 1),
    +    "Low Surrogates": range(56320, 57343 + 1),
    +    "Private Use Area": range(57344, 63743 + 1),
    +    "CJK Compatibility Ideographs": range(63744, 64255 + 1),
    +    "Alphabetic Presentation Forms": range(64256, 64335 + 1),
    +    "Arabic Presentation Forms-A": range(64336, 65023 + 1),
    +    "Variation Selectors": range(65024, 65039 + 1),
    +    "Vertical Forms": range(65040, 65055 + 1),
    +    "Combining Half Marks": range(65056, 65071 + 1),
    +    "CJK Compatibility Forms": range(65072, 65103 + 1),
    +    "Small Form Variants": range(65104, 65135 + 1),
    +    "Arabic Presentation Forms-B": range(65136, 65279 + 1),
    +    "Halfwidth and Fullwidth Forms": range(65280, 65519 + 1),
    +    "Specials": range(65520, 65535 + 1),
    +    "Linear B Syllabary": range(65536, 65663 + 1),
    +    "Linear B Ideograms": range(65664, 65791 + 1),
    +    "Aegean Numbers": range(65792, 65855 + 1),
    +    "Ancient Greek Numbers": range(65856, 65935 + 1),
    +    "Ancient Symbols": range(65936, 65999 + 1),
    +    "Phaistos Disc": range(66000, 66047 + 1),
    +    "Lycian": range(66176, 66207 + 1),
    +    "Carian": range(66208, 66271 + 1),
    +    "Coptic Epact Numbers": range(66272, 66303 + 1),
    +    "Old Italic": range(66304, 66351 + 1),
    +    "Gothic": range(66352, 66383 + 1),
    +    "Old Permic": range(66384, 66431 + 1),
    +    "Ugaritic": range(66432, 66463 + 1),
    +    "Old Persian": range(66464, 66527 + 1),
    +    "Deseret": range(66560, 66639 + 1),
    +    "Shavian": range(66640, 66687 + 1),
    +    "Osmanya": range(66688, 66735 + 1),
    +    "Osage": range(66736, 66815 + 1),
    +    "Elbasan": range(66816, 66863 + 1),
    +    "Caucasian Albanian": range(66864, 66927 + 1),
    +    "Linear A": range(67072, 67455 + 1),
    +    "Cypriot Syllabary": range(67584, 67647 + 1),
    +    "Imperial Aramaic": range(67648, 67679 + 1),
    +    "Palmyrene": range(67680, 67711 + 1),
    +    "Nabataean": range(67712, 67759 + 1),
    +    "Hatran": range(67808, 67839 + 1),
    +    "Phoenician": range(67840, 67871 + 1),
    +    "Lydian": range(67872, 67903 + 1),
    +    "Meroitic Hieroglyphs": range(67968, 67999 + 1),
    +    "Meroitic Cursive": range(68000, 68095 + 1),
    +    "Kharoshthi": range(68096, 68191 + 1),
    +    "Old South Arabian": range(68192, 68223 + 1),
    +    "Old North Arabian": range(68224, 68255 + 1),
    +    "Manichaean": range(68288, 68351 + 1),
    +    "Avestan": range(68352, 68415 + 1),
    +    "Inscriptional Parthian": range(68416, 68447 + 1),
    +    "Inscriptional Pahlavi": range(68448, 68479 + 1),
    +    "Psalter Pahlavi": range(68480, 68527 + 1),
    +    "Old Turkic": range(68608, 68687 + 1),
    +    "Old Hungarian": range(68736, 68863 + 1),
    +    "Rumi Numeral Symbols": range(69216, 69247 + 1),
    +    "Brahmi": range(69632, 69759 + 1),
    +    "Kaithi": range(69760, 69839 + 1),
    +    "Sora Sompeng": range(69840, 69887 + 1),
    +    "Chakma": range(69888, 69967 + 1),
    +    "Mahajani": range(69968, 70015 + 1),
    +    "Sharada": range(70016, 70111 + 1),
    +    "Sinhala Archaic Numbers": range(70112, 70143 + 1),
    +    "Khojki": range(70144, 70223 + 1),
    +    "Multani": range(70272, 70319 + 1),
    +    "Khudawadi": range(70320, 70399 + 1),
    +    "Grantha": range(70400, 70527 + 1),
    +    "Newa": range(70656, 70783 + 1),
    +    "Tirhuta": range(70784, 70879 + 1),
    +    "Siddham": range(71040, 71167 + 1),
    +    "Modi": range(71168, 71263 + 1),
    +    "Mongolian Supplement": range(71264, 71295 + 1),
    +    "Takri": range(71296, 71375 + 1),
    +    "Ahom": range(71424, 71487 + 1),
    +    "Warang Citi": range(71840, 71935 + 1),
    +    "Zanabazar Square": range(72192, 72271 + 1),
    +    "Soyombo": range(72272, 72367 + 1),
    +    "Pau Cin Hau": range(72384, 72447 + 1),
    +    "Bhaiksuki": range(72704, 72815 + 1),
    +    "Marchen": range(72816, 72895 + 1),
    +    "Masaram Gondi": range(72960, 73055 + 1),
    +    "Cuneiform": range(73728, 74751 + 1),
    +    "Cuneiform Numbers and Punctuation": range(74752, 74879 + 1),
    +    "Early Dynastic Cuneiform": range(74880, 75087 + 1),
    +    "Egyptian Hieroglyphs": range(77824, 78895 + 1),
    +    "Anatolian Hieroglyphs": range(82944, 83583 + 1),
    +    "Bamum Supplement": range(92160, 92735 + 1),
    +    "Mro": range(92736, 92783 + 1),
    +    "Bassa Vah": range(92880, 92927 + 1),
    +    "Pahawh Hmong": range(92928, 93071 + 1),
    +    "Miao": range(93952, 94111 + 1),
    +    "Ideographic Symbols and Punctuation": range(94176, 94207 + 1),
    +    "Tangut": range(94208, 100351 + 1),
    +    "Tangut Components": range(100352, 101119 + 1),
    +    "Kana Supplement": range(110592, 110847 + 1),
    +    "Kana Extended-A": range(110848, 110895 + 1),
    +    "Nushu": range(110960, 111359 + 1),
    +    "Duployan": range(113664, 113823 + 1),
    +    "Shorthand Format Controls": range(113824, 113839 + 1),
    +    "Byzantine Musical Symbols": range(118784, 119039 + 1),
    +    "Musical Symbols": range(119040, 119295 + 1),
    +    "Ancient Greek Musical Notation": range(119296, 119375 + 1),
    +    "Tai Xuan Jing Symbols": range(119552, 119647 + 1),
    +    "Counting Rod Numerals": range(119648, 119679 + 1),
    +    "Mathematical Alphanumeric Symbols": range(119808, 120831 + 1),
    +    "Sutton SignWriting": range(120832, 121519 + 1),
    +    "Glagolitic Supplement": range(122880, 122927 + 1),
    +    "Mende Kikakui": range(124928, 125151 + 1),
    +    "Adlam": range(125184, 125279 + 1),
    +    "Arabic Mathematical Alphabetic Symbols": range(126464, 126719 + 1),
    +    "Mahjong Tiles": range(126976, 127023 + 1),
    +    "Domino Tiles": range(127024, 127135 + 1),
    +    "Playing Cards": range(127136, 127231 + 1),
    +    "Enclosed Alphanumeric Supplement": range(127232, 127487 + 1),
    +    "Enclosed Ideographic Supplement": range(127488, 127743 + 1),
    +    "Miscellaneous Symbols and Pictographs": range(127744, 128511 + 1),
    +    "Emoticons range(Emoji)": range(128512, 128591 + 1),
    +    "Ornamental Dingbats": range(128592, 128639 + 1),
    +    "Transport and Map Symbols": range(128640, 128767 + 1),
    +    "Alchemical Symbols": range(128768, 128895 + 1),
    +    "Geometric Shapes Extended": range(128896, 129023 + 1),
    +    "Supplemental Arrows-C": range(129024, 129279 + 1),
    +    "Supplemental Symbols and Pictographs": range(129280, 129535 + 1),
    +    "CJK Unified Ideographs Extension B": range(131072, 173791 + 1),
    +    "CJK Unified Ideographs Extension C": range(173824, 177983 + 1),
    +    "CJK Unified Ideographs Extension D": range(177984, 178207 + 1),
    +    "CJK Unified Ideographs Extension E": range(178208, 183983 + 1),
    +    "CJK Unified Ideographs Extension F": range(183984, 191471 + 1),
    +    "CJK Compatibility Ideographs Supplement": range(194560, 195103 + 1),
    +    "Tags": range(917504, 917631 + 1),
    +    "Variation Selectors Supplement": range(917760, 917999 + 1),
    +}
    +
    +
    +UNICODE_SECONDARY_RANGE_KEYWORD: List[str] = [
    +    "Supplement",
    +    "Extended",
    +    "Extensions",
    +    "Modifier",
    +    "Marks",
    +    "Punctuation",
    +    "Symbols",
    +    "Forms",
    +    "Operators",
    +    "Miscellaneous",
    +    "Drawing",
    +    "Block",
    +    "Shapes",
    +    "Supplemental",
    +    "Tags",
    +]
    +
    +RE_POSSIBLE_ENCODING_INDICATION = re_compile(
    +    r"(?:(?:encoding)|(?:charset)|(?:coding))(?:[\:= ]{1,10})(?:[\"\']?)([a-zA-Z0-9\-_]+)(?:[\"\']?)",
    +    IGNORECASE,
    +)
    +
    +IANA_SUPPORTED: List[str] = sorted(
    +    filter(
    +        lambda x: x.endswith("_codec") is False
    +        and x not in {"rot_13", "tactis", "mbcs"},
    +        list(set(aliases.values())),
    +    )
    +)
    +
    +IANA_SUPPORTED_COUNT: int = len(IANA_SUPPORTED)
    +
    +# pre-computed code page that are similar using the function cp_similarity.
    +IANA_SUPPORTED_SIMILAR: Dict[str, List[str]] = {
    +    "cp037": ["cp1026", "cp1140", "cp273", "cp500"],
    +    "cp1026": ["cp037", "cp1140", "cp273", "cp500"],
    +    "cp1125": ["cp866"],
    +    "cp1140": ["cp037", "cp1026", "cp273", "cp500"],
    +    "cp1250": ["iso8859_2"],
    +    "cp1251": ["kz1048", "ptcp154"],
    +    "cp1252": ["iso8859_15", "iso8859_9", "latin_1"],
    +    "cp1253": ["iso8859_7"],
    +    "cp1254": ["iso8859_15", "iso8859_9", "latin_1"],
    +    "cp1257": ["iso8859_13"],
    +    "cp273": ["cp037", "cp1026", "cp1140", "cp500"],
    +    "cp437": ["cp850", "cp858", "cp860", "cp861", "cp862", "cp863", "cp865"],
    +    "cp500": ["cp037", "cp1026", "cp1140", "cp273"],
    +    "cp850": ["cp437", "cp857", "cp858", "cp865"],
    +    "cp857": ["cp850", "cp858", "cp865"],
    +    "cp858": ["cp437", "cp850", "cp857", "cp865"],
    +    "cp860": ["cp437", "cp861", "cp862", "cp863", "cp865"],
    +    "cp861": ["cp437", "cp860", "cp862", "cp863", "cp865"],
    +    "cp862": ["cp437", "cp860", "cp861", "cp863", "cp865"],
    +    "cp863": ["cp437", "cp860", "cp861", "cp862", "cp865"],
    +    "cp865": ["cp437", "cp850", "cp857", "cp858", "cp860", "cp861", "cp862", "cp863"],
    +    "cp866": ["cp1125"],
    +    "iso8859_10": ["iso8859_14", "iso8859_15", "iso8859_4", "iso8859_9", "latin_1"],
    +    "iso8859_11": ["tis_620"],
    +    "iso8859_13": ["cp1257"],
    +    "iso8859_14": [
    +        "iso8859_10",
    +        "iso8859_15",
    +        "iso8859_16",
    +        "iso8859_3",
    +        "iso8859_9",
    +        "latin_1",
    +    ],
    +    "iso8859_15": [
    +        "cp1252",
    +        "cp1254",
    +        "iso8859_10",
    +        "iso8859_14",
    +        "iso8859_16",
    +        "iso8859_3",
    +        "iso8859_9",
    +        "latin_1",
    +    ],
    +    "iso8859_16": [
    +        "iso8859_14",
    +        "iso8859_15",
    +        "iso8859_2",
    +        "iso8859_3",
    +        "iso8859_9",
    +        "latin_1",
    +    ],
    +    "iso8859_2": ["cp1250", "iso8859_16", "iso8859_4"],
    +    "iso8859_3": ["iso8859_14", "iso8859_15", "iso8859_16", "iso8859_9", "latin_1"],
    +    "iso8859_4": ["iso8859_10", "iso8859_2", "iso8859_9", "latin_1"],
    +    "iso8859_7": ["cp1253"],
    +    "iso8859_9": [
    +        "cp1252",
    +        "cp1254",
    +        "cp1258",
    +        "iso8859_10",
    +        "iso8859_14",
    +        "iso8859_15",
    +        "iso8859_16",
    +        "iso8859_3",
    +        "iso8859_4",
    +        "latin_1",
    +    ],
    +    "kz1048": ["cp1251", "ptcp154"],
    +    "latin_1": [
    +        "cp1252",
    +        "cp1254",
    +        "cp1258",
    +        "iso8859_10",
    +        "iso8859_14",
    +        "iso8859_15",
    +        "iso8859_16",
    +        "iso8859_3",
    +        "iso8859_4",
    +        "iso8859_9",
    +    ],
    +    "mac_iceland": ["mac_roman", "mac_turkish"],
    +    "mac_roman": ["mac_iceland", "mac_turkish"],
    +    "mac_turkish": ["mac_iceland", "mac_roman"],
    +    "ptcp154": ["cp1251", "kz1048"],
    +    "tis_620": ["iso8859_11"],
    +}
    +
    +
    +CHARDET_CORRESPONDENCE: Dict[str, str] = {
    +    "iso2022_kr": "ISO-2022-KR",
    +    "iso2022_jp": "ISO-2022-JP",
    +    "euc_kr": "EUC-KR",
    +    "tis_620": "TIS-620",
    +    "utf_32": "UTF-32",
    +    "euc_jp": "EUC-JP",
    +    "koi8_r": "KOI8-R",
    +    "iso8859_1": "ISO-8859-1",
    +    "iso8859_2": "ISO-8859-2",
    +    "iso8859_5": "ISO-8859-5",
    +    "iso8859_6": "ISO-8859-6",
    +    "iso8859_7": "ISO-8859-7",
    +    "iso8859_8": "ISO-8859-8",
    +    "utf_16": "UTF-16",
    +    "cp855": "IBM855",
    +    "mac_cyrillic": "MacCyrillic",
    +    "gb2312": "GB2312",
    +    "gb18030": "GB18030",
    +    "cp932": "CP932",
    +    "cp866": "IBM866",
    +    "utf_8": "utf-8",
    +    "utf_8_sig": "UTF-8-SIG",
    +    "shift_jis": "SHIFT_JIS",
    +    "big5": "Big5",
    +    "cp1250": "windows-1250",
    +    "cp1251": "windows-1251",
    +    "cp1252": "Windows-1252",
    +    "cp1253": "windows-1253",
    +    "cp1255": "windows-1255",
    +    "cp1256": "windows-1256",
    +    "cp1254": "Windows-1254",
    +    "cp949": "CP949",
    +}
    +
    +
    +COMMON_SAFE_ASCII_CHARACTERS: Set[str] = {
    +    "<",
    +    ">",
    +    "=",
    +    ":",
    +    "/",
    +    "&",
    +    ";",
    +    "{",
    +    "}",
    +    "[",
    +    "]",
    +    ",",
    +    "|",
    +    '"',
    +    "-",
    +}
    +
    +
    +KO_NAMES: Set[str] = {"johab", "cp949", "euc_kr"}
    +ZH_NAMES: Set[str] = {"big5", "cp950", "big5hkscs", "hz"}
    +
    +LANGUAGE_SUPPORTED_COUNT: int = len(FREQUENCIES)
    +
    +# Logging LEVEL below DEBUG
    +TRACE: int = 5
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/legacy.py b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/legacy.py
    new file mode 100644
    index 0000000..b266d17
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/legacy.py
    @@ -0,0 +1,43 @@
    +from typing import Dict, Optional, Union
    +
    +from .api import from_bytes
    +from .constant import CHARDET_CORRESPONDENCE
    +
    +
    +def detect(byte_str: bytes) -> Dict[str, Optional[Union[str, float]]]:
    +    """
    +    chardet legacy method
    +    Detect the encoding of the given byte string. It should be mostly backward-compatible.
    +    Encoding name will match Chardet own writing whenever possible. (Not on encoding name unsupported by it)
    +    This function is deprecated and should be used to migrate your project easily, consult the documentation for
    +    further information. Not planned for removal.
    +
    +    :param byte_str:     The byte sequence to examine.
    +    """
    +    if not isinstance(byte_str, (bytearray, bytes)):
    +        raise TypeError(  # pragma: nocover
    +            "Expected object of type bytes or bytearray, got: "
    +            "{0}".format(type(byte_str))
    +        )
    +
    +    if isinstance(byte_str, bytearray):
    +        byte_str = bytes(byte_str)
    +
    +    r = from_bytes(byte_str).best()
    +
    +    encoding = r.encoding if r is not None else None
    +    language = r.language if r is not None and r.language != "Unknown" else ""
    +    confidence = 1.0 - r.chaos if r is not None else None
    +
    +    # Note: CharsetNormalizer does not return 'UTF-8-SIG' as the sig get stripped in the detection/normalization process
    +    # but chardet does return 'utf-8-sig' and it is a valid codec name.
    +    if r is not None and encoding == "utf_8" and r.bom:
    +        encoding += "_sig"
    +
    +    return {
    +        "encoding": encoding
    +        if encoding not in CHARDET_CORRESPONDENCE
    +        else CHARDET_CORRESPONDENCE[encoding],
    +        "language": language,
    +        "confidence": confidence,
    +    }
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/md.cpython-310-x86_64-linux-gnu.so b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/md.cpython-310-x86_64-linux-gnu.so
    new file mode 100644
    index 0000000..8ae9388
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/md.cpython-310-x86_64-linux-gnu.so differ
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/md.py b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/md.py
    new file mode 100644
    index 0000000..56e9321
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/md.py
    @@ -0,0 +1,571 @@
    +from functools import lru_cache
    +from logging import getLogger
    +from typing import List, Optional
    +
    +from .constant import (
    +    COMMON_SAFE_ASCII_CHARACTERS,
    +    TRACE,
    +    UNICODE_SECONDARY_RANGE_KEYWORD,
    +)
    +from .utils import (
    +    is_accentuated,
    +    is_ascii,
    +    is_case_variable,
    +    is_cjk,
    +    is_emoticon,
    +    is_hangul,
    +    is_hiragana,
    +    is_katakana,
    +    is_latin,
    +    is_punctuation,
    +    is_separator,
    +    is_symbol,
    +    is_thai,
    +    is_unprintable,
    +    remove_accent,
    +    unicode_range,
    +)
    +
    +
    +class MessDetectorPlugin:
    +    """
    +    Base abstract class used for mess detection plugins.
    +    All detectors MUST extend and implement given methods.
    +    """
    +
    +    def eligible(self, character: str) -> bool:
    +        """
    +        Determine if given character should be fed in.
    +        """
    +        raise NotImplementedError  # pragma: nocover
    +
    +    def feed(self, character: str) -> None:
    +        """
    +        The main routine to be executed upon character.
    +        Insert the logic in witch the text would be considered chaotic.
    +        """
    +        raise NotImplementedError  # pragma: nocover
    +
    +    def reset(self) -> None:  # pragma: no cover
    +        """
    +        Permit to reset the plugin to the initial state.
    +        """
    +        raise NotImplementedError
    +
    +    @property
    +    def ratio(self) -> float:
    +        """
    +        Compute the chaos ratio based on what your feed() has seen.
    +        Must NOT be lower than 0.; No restriction gt 0.
    +        """
    +        raise NotImplementedError  # pragma: nocover
    +
    +
    +class TooManySymbolOrPunctuationPlugin(MessDetectorPlugin):
    +    def __init__(self) -> None:
    +        self._punctuation_count: int = 0
    +        self._symbol_count: int = 0
    +        self._character_count: int = 0
    +
    +        self._last_printable_char: Optional[str] = None
    +        self._frenzy_symbol_in_word: bool = False
    +
    +    def eligible(self, character: str) -> bool:
    +        return character.isprintable()
    +
    +    def feed(self, character: str) -> None:
    +        self._character_count += 1
    +
    +        if (
    +            character != self._last_printable_char
    +            and character not in COMMON_SAFE_ASCII_CHARACTERS
    +        ):
    +            if is_punctuation(character):
    +                self._punctuation_count += 1
    +            elif (
    +                character.isdigit() is False
    +                and is_symbol(character)
    +                and is_emoticon(character) is False
    +            ):
    +                self._symbol_count += 2
    +
    +        self._last_printable_char = character
    +
    +    def reset(self) -> None:  # pragma: no cover
    +        self._punctuation_count = 0
    +        self._character_count = 0
    +        self._symbol_count = 0
    +
    +    @property
    +    def ratio(self) -> float:
    +        if self._character_count == 0:
    +            return 0.0
    +
    +        ratio_of_punctuation: float = (
    +            self._punctuation_count + self._symbol_count
    +        ) / self._character_count
    +
    +        return ratio_of_punctuation if ratio_of_punctuation >= 0.3 else 0.0
    +
    +
    +class TooManyAccentuatedPlugin(MessDetectorPlugin):
    +    def __init__(self) -> None:
    +        self._character_count: int = 0
    +        self._accentuated_count: int = 0
    +
    +    def eligible(self, character: str) -> bool:
    +        return character.isalpha()
    +
    +    def feed(self, character: str) -> None:
    +        self._character_count += 1
    +
    +        if is_accentuated(character):
    +            self._accentuated_count += 1
    +
    +    def reset(self) -> None:  # pragma: no cover
    +        self._character_count = 0
    +        self._accentuated_count = 0
    +
    +    @property
    +    def ratio(self) -> float:
    +        if self._character_count == 0 or self._character_count < 8:
    +            return 0.0
    +        ratio_of_accentuation: float = self._accentuated_count / self._character_count
    +        return ratio_of_accentuation if ratio_of_accentuation >= 0.35 else 0.0
    +
    +
    +class UnprintablePlugin(MessDetectorPlugin):
    +    def __init__(self) -> None:
    +        self._unprintable_count: int = 0
    +        self._character_count: int = 0
    +
    +    def eligible(self, character: str) -> bool:
    +        return True
    +
    +    def feed(self, character: str) -> None:
    +        if is_unprintable(character):
    +            self._unprintable_count += 1
    +        self._character_count += 1
    +
    +    def reset(self) -> None:  # pragma: no cover
    +        self._unprintable_count = 0
    +
    +    @property
    +    def ratio(self) -> float:
    +        if self._character_count == 0:
    +            return 0.0
    +
    +        return (self._unprintable_count * 8) / self._character_count
    +
    +
    +class SuspiciousDuplicateAccentPlugin(MessDetectorPlugin):
    +    def __init__(self) -> None:
    +        self._successive_count: int = 0
    +        self._character_count: int = 0
    +
    +        self._last_latin_character: Optional[str] = None
    +
    +    def eligible(self, character: str) -> bool:
    +        return character.isalpha() and is_latin(character)
    +
    +    def feed(self, character: str) -> None:
    +        self._character_count += 1
    +        if (
    +            self._last_latin_character is not None
    +            and is_accentuated(character)
    +            and is_accentuated(self._last_latin_character)
    +        ):
    +            if character.isupper() and self._last_latin_character.isupper():
    +                self._successive_count += 1
    +            # Worse if its the same char duplicated with different accent.
    +            if remove_accent(character) == remove_accent(self._last_latin_character):
    +                self._successive_count += 1
    +        self._last_latin_character = character
    +
    +    def reset(self) -> None:  # pragma: no cover
    +        self._successive_count = 0
    +        self._character_count = 0
    +        self._last_latin_character = None
    +
    +    @property
    +    def ratio(self) -> float:
    +        if self._character_count == 0:
    +            return 0.0
    +
    +        return (self._successive_count * 2) / self._character_count
    +
    +
    +class SuspiciousRange(MessDetectorPlugin):
    +    def __init__(self) -> None:
    +        self._suspicious_successive_range_count: int = 0
    +        self._character_count: int = 0
    +        self._last_printable_seen: Optional[str] = None
    +
    +    def eligible(self, character: str) -> bool:
    +        return character.isprintable()
    +
    +    def feed(self, character: str) -> None:
    +        self._character_count += 1
    +
    +        if (
    +            character.isspace()
    +            or is_punctuation(character)
    +            or character in COMMON_SAFE_ASCII_CHARACTERS
    +        ):
    +            self._last_printable_seen = None
    +            return
    +
    +        if self._last_printable_seen is None:
    +            self._last_printable_seen = character
    +            return
    +
    +        unicode_range_a: Optional[str] = unicode_range(self._last_printable_seen)
    +        unicode_range_b: Optional[str] = unicode_range(character)
    +
    +        if is_suspiciously_successive_range(unicode_range_a, unicode_range_b):
    +            self._suspicious_successive_range_count += 1
    +
    +        self._last_printable_seen = character
    +
    +    def reset(self) -> None:  # pragma: no cover
    +        self._character_count = 0
    +        self._suspicious_successive_range_count = 0
    +        self._last_printable_seen = None
    +
    +    @property
    +    def ratio(self) -> float:
    +        if self._character_count == 0:
    +            return 0.0
    +
    +        ratio_of_suspicious_range_usage: float = (
    +            self._suspicious_successive_range_count * 2
    +        ) / self._character_count
    +
    +        if ratio_of_suspicious_range_usage < 0.1:
    +            return 0.0
    +
    +        return ratio_of_suspicious_range_usage
    +
    +
    +class SuperWeirdWordPlugin(MessDetectorPlugin):
    +    def __init__(self) -> None:
    +        self._word_count: int = 0
    +        self._bad_word_count: int = 0
    +        self._foreign_long_count: int = 0
    +
    +        self._is_current_word_bad: bool = False
    +        self._foreign_long_watch: bool = False
    +
    +        self._character_count: int = 0
    +        self._bad_character_count: int = 0
    +
    +        self._buffer: str = ""
    +        self._buffer_accent_count: int = 0
    +
    +    def eligible(self, character: str) -> bool:
    +        return True
    +
    +    def feed(self, character: str) -> None:
    +        if character.isalpha():
    +            self._buffer += character
    +            if is_accentuated(character):
    +                self._buffer_accent_count += 1
    +            if (
    +                self._foreign_long_watch is False
    +                and (is_latin(character) is False or is_accentuated(character))
    +                and is_cjk(character) is False
    +                and is_hangul(character) is False
    +                and is_katakana(character) is False
    +                and is_hiragana(character) is False
    +                and is_thai(character) is False
    +            ):
    +                self._foreign_long_watch = True
    +            return
    +        if not self._buffer:
    +            return
    +        if (
    +            character.isspace() or is_punctuation(character) or is_separator(character)
    +        ) and self._buffer:
    +            self._word_count += 1
    +            buffer_length: int = len(self._buffer)
    +
    +            self._character_count += buffer_length
    +
    +            if buffer_length >= 4:
    +                if self._buffer_accent_count / buffer_length > 0.34:
    +                    self._is_current_word_bad = True
    +                # Word/Buffer ending with a upper case accentuated letter are so rare,
    +                # that we will consider them all as suspicious. Same weight as foreign_long suspicious.
    +                if is_accentuated(self._buffer[-1]) and self._buffer[-1].isupper():
    +                    self._foreign_long_count += 1
    +                    self._is_current_word_bad = True
    +            if buffer_length >= 24 and self._foreign_long_watch:
    +                self._foreign_long_count += 1
    +                self._is_current_word_bad = True
    +
    +            if self._is_current_word_bad:
    +                self._bad_word_count += 1
    +                self._bad_character_count += len(self._buffer)
    +                self._is_current_word_bad = False
    +
    +            self._foreign_long_watch = False
    +            self._buffer = ""
    +            self._buffer_accent_count = 0
    +        elif (
    +            character not in {"<", ">", "-", "=", "~", "|", "_"}
    +            and character.isdigit() is False
    +            and is_symbol(character)
    +        ):
    +            self._is_current_word_bad = True
    +            self._buffer += character
    +
    +    def reset(self) -> None:  # pragma: no cover
    +        self._buffer = ""
    +        self._is_current_word_bad = False
    +        self._foreign_long_watch = False
    +        self._bad_word_count = 0
    +        self._word_count = 0
    +        self._character_count = 0
    +        self._bad_character_count = 0
    +        self._foreign_long_count = 0
    +
    +    @property
    +    def ratio(self) -> float:
    +        if self._word_count <= 10 and self._foreign_long_count == 0:
    +            return 0.0
    +
    +        return self._bad_character_count / self._character_count
    +
    +
    +class CjkInvalidStopPlugin(MessDetectorPlugin):
    +    """
    +    GB(Chinese) based encoding often render the stop incorrectly when the content does not fit and
    +    can be easily detected. Searching for the overuse of '丅' and '丄'.
    +    """
    +
    +    def __init__(self) -> None:
    +        self._wrong_stop_count: int = 0
    +        self._cjk_character_count: int = 0
    +
    +    def eligible(self, character: str) -> bool:
    +        return True
    +
    +    def feed(self, character: str) -> None:
    +        if character in {"丅", "丄"}:
    +            self._wrong_stop_count += 1
    +            return
    +        if is_cjk(character):
    +            self._cjk_character_count += 1
    +
    +    def reset(self) -> None:  # pragma: no cover
    +        self._wrong_stop_count = 0
    +        self._cjk_character_count = 0
    +
    +    @property
    +    def ratio(self) -> float:
    +        if self._cjk_character_count < 16:
    +            return 0.0
    +        return self._wrong_stop_count / self._cjk_character_count
    +
    +
    +class ArchaicUpperLowerPlugin(MessDetectorPlugin):
    +    def __init__(self) -> None:
    +        self._buf: bool = False
    +
    +        self._character_count_since_last_sep: int = 0
    +
    +        self._successive_upper_lower_count: int = 0
    +        self._successive_upper_lower_count_final: int = 0
    +
    +        self._character_count: int = 0
    +
    +        self._last_alpha_seen: Optional[str] = None
    +        self._current_ascii_only: bool = True
    +
    +    def eligible(self, character: str) -> bool:
    +        return True
    +
    +    def feed(self, character: str) -> None:
    +        is_concerned = character.isalpha() and is_case_variable(character)
    +        chunk_sep = is_concerned is False
    +
    +        if chunk_sep and self._character_count_since_last_sep > 0:
    +            if (
    +                self._character_count_since_last_sep <= 64
    +                and character.isdigit() is False
    +                and self._current_ascii_only is False
    +            ):
    +                self._successive_upper_lower_count_final += (
    +                    self._successive_upper_lower_count
    +                )
    +
    +            self._successive_upper_lower_count = 0
    +            self._character_count_since_last_sep = 0
    +            self._last_alpha_seen = None
    +            self._buf = False
    +            self._character_count += 1
    +            self._current_ascii_only = True
    +
    +            return
    +
    +        if self._current_ascii_only is True and is_ascii(character) is False:
    +            self._current_ascii_only = False
    +
    +        if self._last_alpha_seen is not None:
    +            if (character.isupper() and self._last_alpha_seen.islower()) or (
    +                character.islower() and self._last_alpha_seen.isupper()
    +            ):
    +                if self._buf is True:
    +                    self._successive_upper_lower_count += 2
    +                    self._buf = False
    +                else:
    +                    self._buf = True
    +            else:
    +                self._buf = False
    +
    +        self._character_count += 1
    +        self._character_count_since_last_sep += 1
    +        self._last_alpha_seen = character
    +
    +    def reset(self) -> None:  # pragma: no cover
    +        self._character_count = 0
    +        self._character_count_since_last_sep = 0
    +        self._successive_upper_lower_count = 0
    +        self._successive_upper_lower_count_final = 0
    +        self._last_alpha_seen = None
    +        self._buf = False
    +        self._current_ascii_only = True
    +
    +    @property
    +    def ratio(self) -> float:
    +        if self._character_count == 0:
    +            return 0.0
    +
    +        return self._successive_upper_lower_count_final / self._character_count
    +
    +
    +@lru_cache(maxsize=1024)
    +def is_suspiciously_successive_range(
    +    unicode_range_a: Optional[str], unicode_range_b: Optional[str]
    +) -> bool:
    +    """
    +    Determine if two Unicode range seen next to each other can be considered as suspicious.
    +    """
    +    if unicode_range_a is None or unicode_range_b is None:
    +        return True
    +
    +    if unicode_range_a == unicode_range_b:
    +        return False
    +
    +    if "Latin" in unicode_range_a and "Latin" in unicode_range_b:
    +        return False
    +
    +    if "Emoticons" in unicode_range_a or "Emoticons" in unicode_range_b:
    +        return False
    +
    +    # Latin characters can be accompanied with a combining diacritical mark
    +    # eg. Vietnamese.
    +    if ("Latin" in unicode_range_a or "Latin" in unicode_range_b) and (
    +        "Combining" in unicode_range_a or "Combining" in unicode_range_b
    +    ):
    +        return False
    +
    +    keywords_range_a, keywords_range_b = unicode_range_a.split(
    +        " "
    +    ), unicode_range_b.split(" ")
    +
    +    for el in keywords_range_a:
    +        if el in UNICODE_SECONDARY_RANGE_KEYWORD:
    +            continue
    +        if el in keywords_range_b:
    +            return False
    +
    +    # Japanese Exception
    +    range_a_jp_chars, range_b_jp_chars = (
    +        unicode_range_a
    +        in (
    +            "Hiragana",
    +            "Katakana",
    +        ),
    +        unicode_range_b in ("Hiragana", "Katakana"),
    +    )
    +    if (range_a_jp_chars or range_b_jp_chars) and (
    +        "CJK" in unicode_range_a or "CJK" in unicode_range_b
    +    ):
    +        return False
    +    if range_a_jp_chars and range_b_jp_chars:
    +        return False
    +
    +    if "Hangul" in unicode_range_a or "Hangul" in unicode_range_b:
    +        if "CJK" in unicode_range_a or "CJK" in unicode_range_b:
    +            return False
    +        if unicode_range_a == "Basic Latin" or unicode_range_b == "Basic Latin":
    +            return False
    +
    +    # Chinese/Japanese use dedicated range for punctuation and/or separators.
    +    if ("CJK" in unicode_range_a or "CJK" in unicode_range_b) or (
    +        unicode_range_a in ["Katakana", "Hiragana"]
    +        and unicode_range_b in ["Katakana", "Hiragana"]
    +    ):
    +        if "Punctuation" in unicode_range_a or "Punctuation" in unicode_range_b:
    +            return False
    +        if "Forms" in unicode_range_a or "Forms" in unicode_range_b:
    +            return False
    +
    +    return True
    +
    +
    +@lru_cache(maxsize=2048)
    +def mess_ratio(
    +    decoded_sequence: str, maximum_threshold: float = 0.2, debug: bool = False
    +) -> float:
    +    """
    +    Compute a mess ratio given a decoded bytes sequence. The maximum threshold does stop the computation earlier.
    +    """
    +
    +    detectors: List[MessDetectorPlugin] = [
    +        md_class() for md_class in MessDetectorPlugin.__subclasses__()
    +    ]
    +
    +    length: int = len(decoded_sequence) + 1
    +
    +    mean_mess_ratio: float = 0.0
    +
    +    if length < 512:
    +        intermediary_mean_mess_ratio_calc: int = 32
    +    elif length <= 1024:
    +        intermediary_mean_mess_ratio_calc = 64
    +    else:
    +        intermediary_mean_mess_ratio_calc = 128
    +
    +    for character, index in zip(decoded_sequence + "\n", range(length)):
    +        for detector in detectors:
    +            if detector.eligible(character):
    +                detector.feed(character)
    +
    +        if (
    +            index > 0 and index % intermediary_mean_mess_ratio_calc == 0
    +        ) or index == length - 1:
    +            mean_mess_ratio = sum(dt.ratio for dt in detectors)
    +
    +            if mean_mess_ratio >= maximum_threshold:
    +                break
    +
    +    if debug:
    +        logger = getLogger("charset_normalizer")
    +
    +        logger.log(
    +            TRACE,
    +            "Mess-detector extended-analysis start. "
    +            f"intermediary_mean_mess_ratio_calc={intermediary_mean_mess_ratio_calc} mean_mess_ratio={mean_mess_ratio} "
    +            f"maximum_threshold={maximum_threshold}",
    +        )
    +
    +        if len(decoded_sequence) > 16:
    +            logger.log(TRACE, f"Starting with: {decoded_sequence[:16]}")
    +            logger.log(TRACE, f"Ending with: {decoded_sequence[-16::]}")
    +
    +        for dt in detectors:  # pragma: nocover
    +            logger.log(TRACE, f"{dt.__class__}: {dt.ratio}")
    +
    +    return round(mean_mess_ratio, 3)
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/md__mypyc.cpython-310-x86_64-linux-gnu.so b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/md__mypyc.cpython-310-x86_64-linux-gnu.so
    new file mode 100644
    index 0000000..6091f30
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/md__mypyc.cpython-310-x86_64-linux-gnu.so differ
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/models.py b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/models.py
    new file mode 100644
    index 0000000..7f8ca38
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/models.py
    @@ -0,0 +1,337 @@
    +from encodings.aliases import aliases
    +from hashlib import sha256
    +from json import dumps
    +from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
    +
    +from .constant import TOO_BIG_SEQUENCE
    +from .utils import iana_name, is_multi_byte_encoding, unicode_range
    +
    +
    +class CharsetMatch:
    +    def __init__(
    +        self,
    +        payload: bytes,
    +        guessed_encoding: str,
    +        mean_mess_ratio: float,
    +        has_sig_or_bom: bool,
    +        languages: "CoherenceMatches",
    +        decoded_payload: Optional[str] = None,
    +    ):
    +        self._payload: bytes = payload
    +
    +        self._encoding: str = guessed_encoding
    +        self._mean_mess_ratio: float = mean_mess_ratio
    +        self._languages: CoherenceMatches = languages
    +        self._has_sig_or_bom: bool = has_sig_or_bom
    +        self._unicode_ranges: Optional[List[str]] = None
    +
    +        self._leaves: List[CharsetMatch] = []
    +        self._mean_coherence_ratio: float = 0.0
    +
    +        self._output_payload: Optional[bytes] = None
    +        self._output_encoding: Optional[str] = None
    +
    +        self._string: Optional[str] = decoded_payload
    +
    +    def __eq__(self, other: object) -> bool:
    +        if not isinstance(other, CharsetMatch):
    +            raise TypeError(
    +                "__eq__ cannot be invoked on {} and {}.".format(
    +                    str(other.__class__), str(self.__class__)
    +                )
    +            )
    +        return self.encoding == other.encoding and self.fingerprint == other.fingerprint
    +
    +    def __lt__(self, other: object) -> bool:
    +        """
    +        Implemented to make sorted available upon CharsetMatches items.
    +        """
    +        if not isinstance(other, CharsetMatch):
    +            raise ValueError
    +
    +        chaos_difference: float = abs(self.chaos - other.chaos)
    +        coherence_difference: float = abs(self.coherence - other.coherence)
    +
    +        # Below 1% difference --> Use Coherence
    +        if chaos_difference < 0.01 and coherence_difference > 0.02:
    +            # When having a tough decision, use the result that decoded as many multi-byte as possible.
    +            if chaos_difference == 0.0 and self.coherence == other.coherence:
    +                return self.multi_byte_usage > other.multi_byte_usage
    +            return self.coherence > other.coherence
    +
    +        return self.chaos < other.chaos
    +
    +    @property
    +    def multi_byte_usage(self) -> float:
    +        return 1.0 - len(str(self)) / len(self.raw)
    +
    +    def __str__(self) -> str:
    +        # Lazy Str Loading
    +        if self._string is None:
    +            self._string = str(self._payload, self._encoding, "strict")
    +        return self._string
    +
    +    def __repr__(self) -> str:
    +        return "<CharsetMatch '{}' bytes({})>".format(self.encoding, self.fingerprint)
    +
    +    def add_submatch(self, other: "CharsetMatch") -> None:
    +        if not isinstance(other, CharsetMatch) or other == self:
    +            raise ValueError(
    +                "Unable to add instance <{}> as a submatch of a CharsetMatch".format(
    +                    other.__class__
    +                )
    +            )
    +
    +        other._string = None  # Unload RAM usage; dirty trick.
    +        self._leaves.append(other)
    +
    +    @property
    +    def encoding(self) -> str:
    +        return self._encoding
    +
    +    @property
    +    def encoding_aliases(self) -> List[str]:
    +        """
    +        Encoding name are known by many name, using this could help when searching for IBM855 when it's listed as CP855.
    +        """
    +        also_known_as: List[str] = []
    +        for u, p in aliases.items():
    +            if self.encoding == u:
    +                also_known_as.append(p)
    +            elif self.encoding == p:
    +                also_known_as.append(u)
    +        return also_known_as
    +
    +    @property
    +    def bom(self) -> bool:
    +        return self._has_sig_or_bom
    +
    +    @property
    +    def byte_order_mark(self) -> bool:
    +        return self._has_sig_or_bom
    +
    +    @property
    +    def languages(self) -> List[str]:
    +        """
    +        Return the complete list of possible languages found in decoded sequence.
    +        Usually not really useful. Returned list may be empty even if 'language' property return something != 'Unknown'.
    +        """
    +        return [e[0] for e in self._languages]
    +
    +    @property
    +    def language(self) -> str:
    +        """
    +        Most probable language found in decoded sequence. If none were detected or inferred, the property will return
    +        "Unknown".
    +        """
    +        if not self._languages:
    +            # Trying to infer the language based on the given encoding
    +            # Its either English or we should not pronounce ourselves in certain cases.
    +            if "ascii" in self.could_be_from_charset:
    +                return "English"
    +
    +            # doing it there to avoid circular import
    +            from charset_normalizer.cd import encoding_languages, mb_encoding_languages
    +
    +            languages = (
    +                mb_encoding_languages(self.encoding)
    +                if is_multi_byte_encoding(self.encoding)
    +                else encoding_languages(self.encoding)
    +            )
    +
    +            if len(languages) == 0 or "Latin Based" in languages:
    +                return "Unknown"
    +
    +            return languages[0]
    +
    +        return self._languages[0][0]
    +
    +    @property
    +    def chaos(self) -> float:
    +        return self._mean_mess_ratio
    +
    +    @property
    +    def coherence(self) -> float:
    +        if not self._languages:
    +            return 0.0
    +        return self._languages[0][1]
    +
    +    @property
    +    def percent_chaos(self) -> float:
    +        return round(self.chaos * 100, ndigits=3)
    +
    +    @property
    +    def percent_coherence(self) -> float:
    +        return round(self.coherence * 100, ndigits=3)
    +
    +    @property
    +    def raw(self) -> bytes:
    +        """
    +        Original untouched bytes.
    +        """
    +        return self._payload
    +
    +    @property
    +    def submatch(self) -> List["CharsetMatch"]:
    +        return self._leaves
    +
    +    @property
    +    def has_submatch(self) -> bool:
    +        return len(self._leaves) > 0
    +
    +    @property
    +    def alphabets(self) -> List[str]:
    +        if self._unicode_ranges is not None:
    +            return self._unicode_ranges
    +        # list detected ranges
    +        detected_ranges: List[Optional[str]] = [
    +            unicode_range(char) for char in str(self)
    +        ]
    +        # filter and sort
    +        self._unicode_ranges = sorted(list({r for r in detected_ranges if r}))
    +        return self._unicode_ranges
    +
    +    @property
    +    def could_be_from_charset(self) -> List[str]:
    +        """
    +        The complete list of encoding that output the exact SAME str result and therefore could be the originating
    +        encoding.
    +        This list does include the encoding available in property 'encoding'.
    +        """
    +        return [self._encoding] + [m.encoding for m in self._leaves]
    +
    +    def output(self, encoding: str = "utf_8") -> bytes:
    +        """
    +        Method to get re-encoded bytes payload using given target encoding. Default to UTF-8.
    +        Any errors will be simply ignored by the encoder NOT replaced.
    +        """
    +        if self._output_encoding is None or self._output_encoding != encoding:
    +            self._output_encoding = encoding
    +            self._output_payload = str(self).encode(encoding, "replace")
    +
    +        return self._output_payload  # type: ignore
    +
    +    @property
    +    def fingerprint(self) -> str:
    +        """
    +        Retrieve the unique SHA256 computed using the transformed (re-encoded) payload. Not the original one.
    +        """
    +        return sha256(self.output()).hexdigest()
    +
    +
    +class CharsetMatches:
    +    """
    +    Container with every CharsetMatch items ordered by default from most probable to the less one.
    +    Act like a list(iterable) but does not implements all related methods.
    +    """
    +
    +    def __init__(self, results: Optional[List[CharsetMatch]] = None):
    +        self._results: List[CharsetMatch] = sorted(results) if results else []
    +
    +    def __iter__(self) -> Iterator[CharsetMatch]:
    +        yield from self._results
    +
    +    def __getitem__(self, item: Union[int, str]) -> CharsetMatch:
    +        """
    +        Retrieve a single item either by its position or encoding name (alias may be used here).
    +        Raise KeyError upon invalid index or encoding not present in results.
    +        """
    +        if isinstance(item, int):
    +            return self._results[item]
    +        if isinstance(item, str):
    +            item = iana_name(item, False)
    +            for result in self._results:
    +                if item in result.could_be_from_charset:
    +                    return result
    +        raise KeyError
    +
    +    def __len__(self) -> int:
    +        return len(self._results)
    +
    +    def __bool__(self) -> bool:
    +        return len(self._results) > 0
    +
    +    def append(self, item: CharsetMatch) -> None:
    +        """
    +        Insert a single match. Will be inserted accordingly to preserve sort.
    +        Can be inserted as a submatch.
    +        """
    +        if not isinstance(item, CharsetMatch):
    +            raise ValueError(
    +                "Cannot append instance '{}' to CharsetMatches".format(
    +                    str(item.__class__)
    +                )
    +            )
    +        # We should disable the submatch factoring when the input file is too heavy (conserve RAM usage)
    +        if len(item.raw) <= TOO_BIG_SEQUENCE:
    +            for match in self._results:
    +                if match.fingerprint == item.fingerprint and match.chaos == item.chaos:
    +                    match.add_submatch(item)
    +                    return
    +        self._results.append(item)
    +        self._results = sorted(self._results)
    +
    +    def best(self) -> Optional["CharsetMatch"]:
    +        """
    +        Simply return the first match. Strict equivalent to matches[0].
    +        """
    +        if not self._results:
    +            return None
    +        return self._results[0]
    +
    +    def first(self) -> Optional["CharsetMatch"]:
    +        """
    +        Redundant method, call the method best(). Kept for BC reasons.
    +        """
    +        return self.best()
    +
    +
    +CoherenceMatch = Tuple[str, float]
    +CoherenceMatches = List[CoherenceMatch]
    +
    +
    +class CliDetectionResult:
    +    def __init__(
    +        self,
    +        path: str,
    +        encoding: Optional[str],
    +        encoding_aliases: List[str],
    +        alternative_encodings: List[str],
    +        language: str,
    +        alphabets: List[str],
    +        has_sig_or_bom: bool,
    +        chaos: float,
    +        coherence: float,
    +        unicode_path: Optional[str],
    +        is_preferred: bool,
    +    ):
    +        self.path: str = path
    +        self.unicode_path: Optional[str] = unicode_path
    +        self.encoding: Optional[str] = encoding
    +        self.encoding_aliases: List[str] = encoding_aliases
    +        self.alternative_encodings: List[str] = alternative_encodings
    +        self.language: str = language
    +        self.alphabets: List[str] = alphabets
    +        self.has_sig_or_bom: bool = has_sig_or_bom
    +        self.chaos: float = chaos
    +        self.coherence: float = coherence
    +        self.is_preferred: bool = is_preferred
    +
    +    @property
    +    def __dict__(self) -> Dict[str, Any]:  # type: ignore
    +        return {
    +            "path": self.path,
    +            "encoding": self.encoding,
    +            "encoding_aliases": self.encoding_aliases,
    +            "alternative_encodings": self.alternative_encodings,
    +            "language": self.language,
    +            "alphabets": self.alphabets,
    +            "has_sig_or_bom": self.has_sig_or_bom,
    +            "chaos": self.chaos,
    +            "coherence": self.coherence,
    +            "unicode_path": self.unicode_path,
    +            "is_preferred": self.is_preferred,
    +        }
    +
    +    def to_json(self) -> str:
    +        return dumps(self.__dict__, ensure_ascii=True, indent=4)
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/py.typed b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/py.typed
    new file mode 100644
    index 0000000..e69de29
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/utils.py b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/utils.py
    new file mode 100644
    index 0000000..e353626
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/utils.py
    @@ -0,0 +1,418 @@
    +import importlib
    +import logging
    +import unicodedata
    +from codecs import IncrementalDecoder
    +from encodings.aliases import aliases
    +from functools import lru_cache
    +from re import findall
    +from typing import Generator, List, Optional, Set, Tuple, Union
    +
    +from _multibytecodec import MultibyteIncrementalDecoder
    +
    +from .constant import (
    +    ENCODING_MARKS,
    +    IANA_SUPPORTED_SIMILAR,
    +    RE_POSSIBLE_ENCODING_INDICATION,
    +    UNICODE_RANGES_COMBINED,
    +    UNICODE_SECONDARY_RANGE_KEYWORD,
    +    UTF8_MAXIMAL_ALLOCATION,
    +)
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_accentuated(character: str) -> bool:
    +    try:
    +        description: str = unicodedata.name(character)
    +    except ValueError:
    +        return False
    +    return (
    +        "WITH GRAVE" in description
    +        or "WITH ACUTE" in description
    +        or "WITH CEDILLA" in description
    +        or "WITH DIAERESIS" in description
    +        or "WITH CIRCUMFLEX" in description
    +        or "WITH TILDE" in description
    +    )
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def remove_accent(character: str) -> str:
    +    decomposed: str = unicodedata.decomposition(character)
    +    if not decomposed:
    +        return character
    +
    +    codes: List[str] = decomposed.split(" ")
    +
    +    return chr(int(codes[0], 16))
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def unicode_range(character: str) -> Optional[str]:
    +    """
    +    Retrieve the Unicode range official name from a single character.
    +    """
    +    character_ord: int = ord(character)
    +
    +    for range_name, ord_range in UNICODE_RANGES_COMBINED.items():
    +        if character_ord in ord_range:
    +            return range_name
    +
    +    return None
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_latin(character: str) -> bool:
    +    try:
    +        description: str = unicodedata.name(character)
    +    except ValueError:
    +        return False
    +    return "LATIN" in description
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_ascii(character: str) -> bool:
    +    try:
    +        character.encode("ascii")
    +    except UnicodeEncodeError:
    +        return False
    +    return True
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_punctuation(character: str) -> bool:
    +    character_category: str = unicodedata.category(character)
    +
    +    if "P" in character_category:
    +        return True
    +
    +    character_range: Optional[str] = unicode_range(character)
    +
    +    if character_range is None:
    +        return False
    +
    +    return "Punctuation" in character_range
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_symbol(character: str) -> bool:
    +    character_category: str = unicodedata.category(character)
    +
    +    if "S" in character_category or "N" in character_category:
    +        return True
    +
    +    character_range: Optional[str] = unicode_range(character)
    +
    +    if character_range is None:
    +        return False
    +
    +    return "Forms" in character_range
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_emoticon(character: str) -> bool:
    +    character_range: Optional[str] = unicode_range(character)
    +
    +    if character_range is None:
    +        return False
    +
    +    return "Emoticons" in character_range
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_separator(character: str) -> bool:
    +    if character.isspace() or character in {"|", "+", ",", ";", "<", ">"}:
    +        return True
    +
    +    character_category: str = unicodedata.category(character)
    +
    +    return "Z" in character_category
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_case_variable(character: str) -> bool:
    +    return character.islower() != character.isupper()
    +
    +
    +def is_private_use_only(character: str) -> bool:
    +    character_category: str = unicodedata.category(character)
    +
    +    return character_category == "Co"
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_cjk(character: str) -> bool:
    +    try:
    +        character_name = unicodedata.name(character)
    +    except ValueError:
    +        return False
    +
    +    return "CJK" in character_name
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_hiragana(character: str) -> bool:
    +    try:
    +        character_name = unicodedata.name(character)
    +    except ValueError:
    +        return False
    +
    +    return "HIRAGANA" in character_name
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_katakana(character: str) -> bool:
    +    try:
    +        character_name = unicodedata.name(character)
    +    except ValueError:
    +        return False
    +
    +    return "KATAKANA" in character_name
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_hangul(character: str) -> bool:
    +    try:
    +        character_name = unicodedata.name(character)
    +    except ValueError:
    +        return False
    +
    +    return "HANGUL" in character_name
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_thai(character: str) -> bool:
    +    try:
    +        character_name = unicodedata.name(character)
    +    except ValueError:
    +        return False
    +
    +    return "THAI" in character_name
    +
    +
    +@lru_cache(maxsize=len(UNICODE_RANGES_COMBINED))
    +def is_unicode_range_secondary(range_name: str) -> bool:
    +    return any(keyword in range_name for keyword in UNICODE_SECONDARY_RANGE_KEYWORD)
    +
    +
    +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION)
    +def is_unprintable(character: str) -> bool:
    +    return (
    +        character.isspace() is False  # includes \n \t \r \v
    +        and character.isprintable() is False
    +        and character != "\x1A"  # Why? Its the ASCII substitute character.
    +        and character != "\ufeff"  # bug discovered in Python,
    +        # Zero Width No-Break Space located in 	Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space.
    +    )
    +
    +
    +def any_specified_encoding(sequence: bytes, search_zone: int = 4096) -> Optional[str]:
    +    """
    +    Extract using ASCII-only decoder any specified encoding in the first n-bytes.
    +    """
    +    if not isinstance(sequence, bytes):
    +        raise TypeError
    +
    +    seq_len: int = len(sequence)
    +
    +    results: List[str] = findall(
    +        RE_POSSIBLE_ENCODING_INDICATION,
    +        sequence[: min(seq_len, search_zone)].decode("ascii", errors="ignore"),
    +    )
    +
    +    if len(results) == 0:
    +        return None
    +
    +    for specified_encoding in results:
    +        specified_encoding = specified_encoding.lower().replace("-", "_")
    +
    +        encoding_alias: str
    +        encoding_iana: str
    +
    +        for encoding_alias, encoding_iana in aliases.items():
    +            if encoding_alias == specified_encoding:
    +                return encoding_iana
    +            if encoding_iana == specified_encoding:
    +                return encoding_iana
    +
    +    return None
    +
    +
    +@lru_cache(maxsize=128)
    +def is_multi_byte_encoding(name: str) -> bool:
    +    """
    +    Verify is a specific encoding is a multi byte one based on it IANA name
    +    """
    +    return name in {
    +        "utf_8",
    +        "utf_8_sig",
    +        "utf_16",
    +        "utf_16_be",
    +        "utf_16_le",
    +        "utf_32",
    +        "utf_32_le",
    +        "utf_32_be",
    +        "utf_7",
    +    } or issubclass(
    +        importlib.import_module("encodings.{}".format(name)).IncrementalDecoder,
    +        MultibyteIncrementalDecoder,
    +    )
    +
    +
    +def identify_sig_or_bom(sequence: bytes) -> Tuple[Optional[str], bytes]:
    +    """
    +    Identify and extract SIG/BOM in given sequence.
    +    """
    +
    +    for iana_encoding in ENCODING_MARKS:
    +        marks: Union[bytes, List[bytes]] = ENCODING_MARKS[iana_encoding]
    +
    +        if isinstance(marks, bytes):
    +            marks = [marks]
    +
    +        for mark in marks:
    +            if sequence.startswith(mark):
    +                return iana_encoding, mark
    +
    +    return None, b""
    +
    +
    +def should_strip_sig_or_bom(iana_encoding: str) -> bool:
    +    return iana_encoding not in {"utf_16", "utf_32"}
    +
    +
    +def iana_name(cp_name: str, strict: bool = True) -> str:
    +    cp_name = cp_name.lower().replace("-", "_")
    +
    +    encoding_alias: str
    +    encoding_iana: str
    +
    +    for encoding_alias, encoding_iana in aliases.items():
    +        if cp_name in [encoding_alias, encoding_iana]:
    +            return encoding_iana
    +
    +    if strict:
    +        raise ValueError("Unable to retrieve IANA for '{}'".format(cp_name))
    +
    +    return cp_name
    +
    +
    +def range_scan(decoded_sequence: str) -> List[str]:
    +    ranges: Set[str] = set()
    +
    +    for character in decoded_sequence:
    +        character_range: Optional[str] = unicode_range(character)
    +
    +        if character_range is None:
    +            continue
    +
    +        ranges.add(character_range)
    +
    +    return list(ranges)
    +
    +
    +def cp_similarity(iana_name_a: str, iana_name_b: str) -> float:
    +
    +    if is_multi_byte_encoding(iana_name_a) or is_multi_byte_encoding(iana_name_b):
    +        return 0.0
    +
    +    decoder_a = importlib.import_module(
    +        "encodings.{}".format(iana_name_a)
    +    ).IncrementalDecoder
    +    decoder_b = importlib.import_module(
    +        "encodings.{}".format(iana_name_b)
    +    ).IncrementalDecoder
    +
    +    id_a: IncrementalDecoder = decoder_a(errors="ignore")
    +    id_b: IncrementalDecoder = decoder_b(errors="ignore")
    +
    +    character_match_count: int = 0
    +
    +    for i in range(255):
    +        to_be_decoded: bytes = bytes([i])
    +        if id_a.decode(to_be_decoded) == id_b.decode(to_be_decoded):
    +            character_match_count += 1
    +
    +    return character_match_count / 254
    +
    +
    +def is_cp_similar(iana_name_a: str, iana_name_b: str) -> bool:
    +    """
    +    Determine if two code page are at least 80% similar. IANA_SUPPORTED_SIMILAR dict was generated using
    +    the function cp_similarity.
    +    """
    +    return (
    +        iana_name_a in IANA_SUPPORTED_SIMILAR
    +        and iana_name_b in IANA_SUPPORTED_SIMILAR[iana_name_a]
    +    )
    +
    +
    +def set_logging_handler(
    +    name: str = "charset_normalizer",
    +    level: int = logging.INFO,
    +    format_string: str = "%(asctime)s | %(levelname)s | %(message)s",
    +) -> None:
    +
    +    logger = logging.getLogger(name)
    +    logger.setLevel(level)
    +
    +    handler = logging.StreamHandler()
    +    handler.setFormatter(logging.Formatter(format_string))
    +    logger.addHandler(handler)
    +
    +
    +def cut_sequence_chunks(
    +    sequences: bytes,
    +    encoding_iana: str,
    +    offsets: range,
    +    chunk_size: int,
    +    bom_or_sig_available: bool,
    +    strip_sig_or_bom: bool,
    +    sig_payload: bytes,
    +    is_multi_byte_decoder: bool,
    +    decoded_payload: Optional[str] = None,
    +) -> Generator[str, None, None]:
    +
    +    if decoded_payload and is_multi_byte_decoder is False:
    +        for i in offsets:
    +            chunk = decoded_payload[i : i + chunk_size]
    +            if not chunk:
    +                break
    +            yield chunk
    +    else:
    +        for i in offsets:
    +            chunk_end = i + chunk_size
    +            if chunk_end > len(sequences) + 8:
    +                continue
    +
    +            cut_sequence = sequences[i : i + chunk_size]
    +
    +            if bom_or_sig_available and strip_sig_or_bom is False:
    +                cut_sequence = sig_payload + cut_sequence
    +
    +            chunk = cut_sequence.decode(
    +                encoding_iana,
    +                errors="ignore" if is_multi_byte_decoder else "strict",
    +            )
    +
    +            # multi-byte bad cutting detector and adjustment
    +            # not the cleanest way to perform that fix but clever enough for now.
    +            if is_multi_byte_decoder and i > 0:
    +
    +                chunk_partial_size_chk: int = min(chunk_size, 16)
    +
    +                if (
    +                    decoded_payload
    +                    and chunk[:chunk_partial_size_chk] not in decoded_payload
    +                ):
    +                    for j in range(i, i - 4, -1):
    +                        cut_sequence = sequences[j:chunk_end]
    +
    +                        if bom_or_sig_available and strip_sig_or_bom is False:
    +                            cut_sequence = sig_payload + cut_sequence
    +
    +                        chunk = cut_sequence.decode(encoding_iana, errors="ignore")
    +
    +                        if chunk[:chunk_partial_size_chk] in decoded_payload:
    +                            break
    +
    +            yield chunk
    diff --git a/deployment-apps/metricator-for-nmon/lib/charset_normalizer/version.py b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/version.py
    new file mode 100644
    index 0000000..cb50367
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/charset_normalizer/version.py
    @@ -0,0 +1,6 @@
    +"""
    +Expose version
    +"""
    +
    +__version__ = "3.0.1"
    +VERSION = __version__.split(".")
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/INSTALLER b/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/INSTALLER
    new file mode 100644
    index 0000000..a1b589e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/INSTALLER
    @@ -0,0 +1 @@
    +pip
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/LICENSE b/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/LICENSE
    new file mode 100644
    index 0000000..311690c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/LICENSE
    @@ -0,0 +1,49 @@
    +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
    +--------------------------------------------
    +
    +1. This LICENSE AGREEMENT is between the Python Software Foundation
    +("PSF"), and the Individual or Organization ("Licensee") accessing and
    +otherwise using this software ("Python") in source or binary form and
    +its associated documentation.
    +
    +2. Subject to the terms and conditions of this License Agreement, PSF
    +hereby grants Licensee a nonexclusive, royalty-free, world-wide
    +license to reproduce, analyze, test, perform and/or display publicly,
    +prepare derivative works, distribute, and otherwise use Python
    +alone or in any derivative version, provided, however, that PSF's
    +License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
    +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Python Software Foundation; 
    +All Rights Reserved" are retained in Python alone or in any derivative 
    +version prepared by Licensee.
    +
    +3. In the event Licensee prepares a derivative work that is based on
    +or incorporates Python or any part thereof, and wants to make
    +the derivative work available to others as provided herein, then
    +Licensee hereby agrees to include in any such work a brief summary of
    +the changes made to Python.
    +
    +4. PSF is making Python available to Licensee on an "AS IS"
    +basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
    +IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
    +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
    +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
    +INFRINGE ANY THIRD PARTY RIGHTS.
    +
    +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
    +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
    +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
    +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
    +
    +6. This License Agreement will automatically terminate upon a material
    +breach of its terms and conditions.
    +
    +7. Nothing in this License Agreement shall be deemed to create any
    +relationship of agency, partnership, or joint venture between PSF and
    +Licensee.  This License Agreement does not grant permission to use PSF
    +trademarks or trade name in a trademark sense to endorse or promote
    +products or services of Licensee, or any third party.
    +
    +8. By copying, installing or otherwise using Python, Licensee
    +agrees to be bound by the terms and conditions of this License
    +Agreement.
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/METADATA b/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/METADATA
    new file mode 100644
    index 0000000..f916e89
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/METADATA
    @@ -0,0 +1,978 @@
    +Metadata-Version: 2.1
    +Name: defusedxml
    +Version: 0.7.1
    +Summary: XML bomb protection for Python stdlib modules
    +Home-page: https://github.com/tiran/defusedxml
    +Author: Christian Heimes
    +Author-email: christian@python.org
    +Maintainer: Christian Heimes
    +Maintainer-email: christian@python.org
    +License: PSFL
    +Download-URL: https://pypi.python.org/pypi/defusedxml
    +Keywords: xml bomb DoS
    +Platform: all
    +Classifier: Development Status :: 5 - Production/Stable
    +Classifier: Intended Audience :: Developers
    +Classifier: License :: OSI Approved :: Python Software Foundation License
    +Classifier: Natural Language :: English
    +Classifier: Programming Language :: Python
    +Classifier: Programming Language :: Python :: 2
    +Classifier: Programming Language :: Python :: 2.7
    +Classifier: Programming Language :: Python :: 3
    +Classifier: Programming Language :: Python :: 3.5
    +Classifier: Programming Language :: Python :: 3.6
    +Classifier: Programming Language :: Python :: 3.7
    +Classifier: Programming Language :: Python :: 3.8
    +Classifier: Programming Language :: Python :: 3.9
    +Classifier: Topic :: Text Processing :: Markup :: XML
    +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
    +
    +===================================================
    +defusedxml -- defusing XML bombs and other exploits
    +===================================================
    +
    +.. image:: https://img.shields.io/pypi/v/defusedxml.svg
    +    :target: https://pypi.org/project/defusedxml/
    +    :alt: Latest Version
    +
    +.. image:: https://img.shields.io/pypi/pyversions/defusedxml.svg
    +    :target: https://pypi.org/project/defusedxml/
    +    :alt: Supported Python versions
    +
    +.. image:: https://travis-ci.org/tiran/defusedxml.svg?branch=master
    +    :target: https://travis-ci.org/tiran/defusedxml
    +    :alt: Travis CI
    +
    +.. image:: https://codecov.io/github/tiran/defusedxml/coverage.svg?branch=master
    +    :target: https://codecov.io/github/tiran/defusedxml?branch=master
    +    :alt: codecov
    +
    +.. image:: https://img.shields.io/pypi/dm/defusedxml.svg
    +    :target: https://pypistats.org/packages/defusedxml
    +    :alt: PyPI downloads
    +
    +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
    +    :target: https://github.com/psf/black
    +    :alt: Code style: black
    +
    +..
    +
    +    "It's just XML, what could probably go wrong?"
    +
    +Christian Heimes <christian@python.org>
    +
    +Synopsis
    +========
    +
    +The results of an attack on a vulnerable XML library can be fairly dramatic.
    +With just a few hundred **Bytes** of XML data an attacker can occupy several
    +**Gigabytes** of memory within **seconds**. An attacker can also keep
    +CPUs busy for a long time with a small to medium size request. Under some
    +circumstances it is even possible to access local files on your
    +server, to circumvent a firewall, or to abuse services to rebound attacks to
    +third parties.
    +
    +The attacks use and abuse less common features of XML and its parsers. The
    +majority of developers are unacquainted with features such as processing
    +instructions and entity expansions that XML inherited from SGML. At best
    +they know about ``<!DOCTYPE>`` from experience with HTML but they are not
    +aware that a document type definition (DTD) can generate an HTTP request
    +or load a file from the file system.
    +
    +None of the issues is new. They have been known for a long time. Billion
    +laughs was first reported in 2003. Nevertheless some XML libraries and
    +applications are still vulnerable and even heavy users of XML are
    +surprised by these features. It's hard to say whom to blame for the
    +situation. It's too short sighted to shift all blame on XML parsers and
    +XML libraries for using insecure default settings. After all they
    +properly implement XML specifications. Application developers must not rely
    +that a library is always configured for security and potential harmful data
    +by default.
    +
    +
    +.. contents:: Table of Contents
    +   :depth: 2
    +
    +
    +Attack vectors
    +==============
    +
    +billion laughs / exponential entity expansion
    +---------------------------------------------
    +
    +The `Billion Laughs`_ attack -- also known as exponential entity expansion --
    +uses multiple levels of nested entities. The original example uses 9 levels
    +of 10 expansions in each level to expand the string ``lol`` to a string of
    +3 * 10 :sup:`9` bytes, hence the name "billion laughs". The resulting string
    +occupies 3 GB (2.79 GiB) of memory; intermediate strings require additional
    +memory. Because most parsers don't cache the intermediate step for every
    +expansion it is repeated over and over again. It increases the CPU load even
    +more.
    +
    +An XML document of just a few hundred bytes can disrupt all services on a
    +machine within seconds.
    +
    +Example XML::
    +
    +    <!DOCTYPE xmlbomb [
    +    <!ENTITY a "1234567890" >
    +    <!ENTITY b "&a;&a;&a;&a;&a;&a;&a;&a;">
    +    <!ENTITY c "&b;&b;&b;&b;&b;&b;&b;&b;">
    +    <!ENTITY d "&c;&c;&c;&c;&c;&c;&c;&c;">
    +    ]>
    +    <bomb>&d;</bomb>
    +
    +
    +quadratic blowup entity expansion
    +---------------------------------
    +
    +A quadratic blowup attack is similar to a `Billion Laughs`_ attack; it abuses
    +entity expansion, too. Instead of nested entities it repeats one large entity
    +with a couple of thousand chars over and over again. The attack isn't as
    +efficient as the exponential case but it avoids triggering countermeasures of
    +parsers against heavily nested entities. Some parsers limit the depth and
    +breadth of a single entity but not the total amount of expanded text
    +throughout an entire XML document.
    +
    +A medium-sized XML document with a couple of hundred kilobytes can require a
    +couple of hundred MB to several GB of memory. When the attack is combined
    +with some level of nested expansion an attacker is able to achieve a higher
    +ratio of success.
    +
    +::
    +
    +    <!DOCTYPE bomb [
    +    <!ENTITY a "xxxxxxx... a couple of ten thousand chars">
    +    ]>
    +    <bomb>&a;&a;&a;... repeat</bomb>
    +
    +
    +external entity expansion (remote)
    +----------------------------------
    +
    +Entity declarations can contain more than just text for replacement. They can
    +also point to external resources by public identifiers or system identifiers.
    +System identifiers are standard URIs. When the URI is a URL (e.g. a
    +``http://`` locator) some parsers download the resource from the remote
    +location and embed them into the XML document verbatim.
    +
    +Simple example of a parsed external entity::
    +
    +    <!DOCTYPE external [
    +    <!ENTITY ee SYSTEM "http://www.python.org/some.xml">
    +    ]>
    +    <root>&ee;</root>
    +
    +The case of parsed external entities works only for valid XML content. The
    +XML standard also supports unparsed external entities with a
    +``NData declaration``.
    +
    +External entity expansion opens the door to plenty of exploits. An attacker
    +can abuse a vulnerable XML library and application to rebound and forward
    +network requests with the IP address of the server. It highly depends
    +on the parser and the application what kind of exploit is possible. For
    +example:
    +
    +* An attacker can circumvent firewalls and gain access to restricted
    +  resources as all the requests are made from an internal and trustworthy
    +  IP address, not from the outside.
    +* An attacker can abuse a service to attack, spy on or DoS your servers but
    +  also third party services. The attack is disguised with the IP address of
    +  the server and the attacker is able to utilize the high bandwidth of a big
    +  machine.
    +* An attacker can exhaust additional resources on the machine, e.g. with
    +  requests to a service that doesn't respond or responds with very large
    +  files.
    +* An attacker may gain knowledge, when, how often and from which IP address
    +  an XML document is accessed.
    +* An attacker could send mail from inside your network if the URL handler
    +  supports ``smtp://`` URIs.
    +
    +
    +external entity expansion (local file)
    +--------------------------------------
    +
    +External entities with references to local files are a sub-case of external
    +entity expansion. It's listed as an extra attack because it deserves extra
    +attention. Some XML libraries such as lxml disable network access by default
    +but still allow entity expansion with local file access by default. Local
    +files are either referenced with a ``file://`` URL or by a file path (either
    +relative or absolute).
    +
    +An attacker may be able to access and download all files that can be read by
    +the application process. This may include critical configuration files, too.
    +
    +::
    +
    +    <!DOCTYPE external [
    +    <!ENTITY ee SYSTEM "file:///PATH/TO/simple.xml">
    +    ]>
    +    <root>&ee;</root>
    +
    +
    +DTD retrieval
    +-------------
    +
    +This case is similar to external entity expansion, too. Some XML libraries
    +like Python's xml.dom.pulldom retrieve document type definitions from remote
    +or local locations. Several attack scenarios from the external entity case
    +apply to this issue as well.
    +
    +::
    +
    +    <?xml version="1.0" encoding="utf-8"?>
    +    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    +      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    +    <html>
    +        <head/>
    +        <body>text</body>
    +    </html>
    +
    +
    +Python XML Libraries
    +====================
    +
    +.. csv-table:: vulnerabilities and features
    +   :header: "kind", "sax", "etree", "minidom", "pulldom", "xmlrpc", "lxml", "genshi"
    +   :widths: 24, 7, 8, 8, 7, 8, 8, 8
    +   :stub-columns: 0
    +
    +   "billion laughs", "**True**", "**True**", "**True**", "**True**", "**True**", "False (1)", "False (5)"
    +   "quadratic blowup", "**True**", "**True**", "**True**", "**True**", "**True**", "**True**", "False (5)"
    +   "external entity expansion (remote)", "**True**", "False (3)", "False (4)", "**True**", "false", "False (1)", "False (5)"
    +   "external entity expansion (local file)", "**True**", "False (3)", "False (4)", "**True**", "false", "**True**", "False (5)"
    +   "DTD retrieval", "**True**", "False", "False", "**True**", "false", "False (1)", "False"
    +   "gzip bomb", "False", "False", "False", "False", "**True**", "**partly** (2)", "False"
    +   "xpath support (7)", "False", "False", "False", "False", "False", "**True**", "False"
    +   "xsl(t) support (7)", "False", "False", "False", "False", "False", "**True**", "False"
    +   "xinclude support (7)", "False", "**True** (6)", "False", "False", "False", "**True** (6)", "**True**"
    +   "C library", "expat", "expat", "expat", "expat", "expat", "libxml2", "expat"
    +
    +1. Lxml is protected against billion laughs attacks and doesn't do network
    +   lookups by default.
    +2. libxml2 and lxml are not directly vulnerable to gzip decompression bombs
    +   but they don't protect you against them either.
    +3. xml.etree doesn't expand entities and raises a ParserError when an entity
    +   occurs.
    +4. minidom doesn't expand entities and simply returns the unexpanded entity
    +   verbatim.
    +5. genshi.input of genshi 0.6 doesn't support entity expansion and raises a
    +   ParserError when an entity occurs.
    +6. Library has (limited) XInclude support but requires an additional step to
    +   process inclusion.
    +7. These are features but they may introduce exploitable holes, see
    +   `Other things to consider`_
    +
    +
    +Settings in standard library
    +----------------------------
    +
    +
    +xml.sax.handler Features
    +........................
    +
    +feature_external_ges (http://xml.org/sax/features/external-general-entities)
    +  disables external entity expansion
    +
    +feature_external_pes (http://xml.org/sax/features/external-parameter-entities)
    +  the option is ignored and doesn't modify any functionality
    +
    +DOM xml.dom.xmlbuilder.Options
    +..............................
    +
    +external_parameter_entities
    +  ignored
    +
    +external_general_entities
    +  ignored
    +
    +external_dtd_subset
    +  ignored
    +
    +entities
    +  unsure
    +
    +
    +defusedxml
    +==========
    +
    +The `defusedxml package`_ (`defusedxml on PyPI`_)
    +contains several Python-only workarounds and fixes
    +for denial of service and other vulnerabilities in Python's XML libraries.
    +In order to benefit from the protection you just have to import and use the
    +listed functions / classes from the right defusedxml module instead of the
    +original module. Merely `defusedxml.xmlrpc`_ is implemented as monkey patch.
    +
    +Instead of::
    +
    +   >>> from xml.etree.ElementTree import parse
    +   >>> et = parse(xmlfile)
    +
    +alter code to::
    +
    +   >>> from defusedxml.ElementTree import parse
    +   >>> et = parse(xmlfile)
    +
    +Additionally the package has an **untested** function to monkey patch
    +all stdlib modules with ``defusedxml.defuse_stdlib()``.
    +
    +All functions and parser classes accept three additional keyword arguments.
    +They return either the same objects as the original functions or compatible
    +subclasses.
    +
    +forbid_dtd (default: False)
    +  disallow XML with a ``<!DOCTYPE>`` processing instruction and raise a
    +  *DTDForbidden* exception when a DTD processing instruction is found.
    +
    +forbid_entities (default: True)
    +  disallow XML with ``<!ENTITY>`` declarations inside the DTD and raise an
    +  *EntitiesForbidden* exception when an entity is declared.
    +
    +forbid_external (default: True)
    +  disallow any access to remote or local resources in external entities
    +  or DTD and raising an *ExternalReferenceForbidden* exception when a DTD
    +  or entity references an external resource.
    +
    +
    +defusedxml (package)
    +--------------------
    +
    +DefusedXmlException, DTDForbidden, EntitiesForbidden,
    +ExternalReferenceForbidden, NotSupportedError
    +
    +defuse_stdlib() (*experimental*)
    +
    +
    +defusedxml.cElementTree
    +-----------------------
    +
    +**NOTE** ``defusedxml.cElementTree`` is deprecated and will be removed in a
    +future release. Import from ``defusedxml.ElementTree`` instead.
    +
    +parse(), iterparse(), fromstring(), XMLParser
    +
    +
    +defusedxml.ElementTree
    +-----------------------
    +
    +parse(), iterparse(), fromstring(), XMLParser
    +
    +
    +defusedxml.expatreader
    +----------------------
    +
    +create_parser(), DefusedExpatParser
    +
    +
    +defusedxml.sax
    +--------------
    +
    +parse(), parseString(), make_parser()
    +
    +
    +defusedxml.expatbuilder
    +-----------------------
    +
    +parse(), parseString(), DefusedExpatBuilder, DefusedExpatBuilderNS
    +
    +
    +defusedxml.minidom
    +------------------
    +
    +parse(), parseString()
    +
    +
    +defusedxml.pulldom
    +------------------
    +
    +parse(), parseString()
    +
    +
    +defusedxml.xmlrpc
    +-----------------
    +
    +The fix is implemented as monkey patch for the stdlib's xmlrpc package (3.x)
    +or xmlrpclib module (2.x). The function `monkey_patch()` enables the fixes,
    +`unmonkey_patch()` removes the patch and puts the code in its former state.
    +
    +The monkey patch protects against XML related attacks as well as
    +decompression bombs and excessively large requests or responses. The default
    +setting is 30 MB for requests, responses and gzip decompression. You can
    +modify the default by changing the module variable `MAX_DATA`. A value of
    +`-1` disables the limit.
    +
    +
    +defusedxml.lxml
    +---------------
    +
    +**DEPRECATED** The module is deprecated and will be removed in a future
    +release.
    +
    +The module acts as an *example* how you could protect code that uses
    +lxml.etree. It implements a custom Element class that filters out
    +Entity instances, a custom parser factory and a thread local storage for
    +parser instances. It also has a check_docinfo() function which inspects
    +a tree for internal or external DTDs and entity declarations. In order to
    +check for entities lxml > 3.0 is required.
    +
    +parse(), fromstring()
    +RestrictedElement, GlobalParserTLS, getDefaultParser(), check_docinfo()
    +
    +
    +defusedexpat
    +============
    +
    +The `defusedexpat package`_ (`defusedexpat on PyPI`_)
    +comes with binary extensions and a
    +`modified expat`_ library instead of the standard `expat parser`_. It's
    +basically a stand-alone version of the patches for Python's standard
    +library C extensions.
    +
    +Modifications in expat
    +----------------------
    +
    +new definitions::
    +
    +  XML_BOMB_PROTECTION
    +  XML_DEFAULT_MAX_ENTITY_INDIRECTIONS
    +  XML_DEFAULT_MAX_ENTITY_EXPANSIONS
    +  XML_DEFAULT_RESET_DTD
    +
    +new XML_FeatureEnum members::
    +
    +  XML_FEATURE_MAX_ENTITY_INDIRECTIONS
    +  XML_FEATURE_MAX_ENTITY_EXPANSIONS
    +  XML_FEATURE_IGNORE_DTD
    +
    +new XML_Error members::
    +
    +  XML_ERROR_ENTITY_INDIRECTIONS
    +  XML_ERROR_ENTITY_EXPANSION
    +
    +new API functions::
    +
    +  int XML_GetFeature(XML_Parser parser,
    +                     enum XML_FeatureEnum feature,
    +                     long *value);
    +  int XML_SetFeature(XML_Parser parser,
    +                     enum XML_FeatureEnum feature,
    +                     long value);
    +  int XML_GetFeatureDefault(enum XML_FeatureEnum feature,
    +                            long *value);
    +  int XML_SetFeatureDefault(enum XML_FeatureEnum feature,
    +                            long value);
    +
    +XML_FEATURE_MAX_ENTITY_INDIRECTIONS
    +   Limit the amount of indirections that are allowed to occur during the
    +   expansion of a nested entity. A counter starts when an entity reference
    +   is encountered. It resets after the entity is fully expanded. The limit
    +   protects the parser against exponential entity expansion attacks (aka
    +   billion laughs attack). When the limit is exceeded the parser stops and
    +   fails with `XML_ERROR_ENTITY_INDIRECTIONS`.
    +   A value of 0 disables the protection.
    +
    +   Supported range
    +     0 .. UINT_MAX
    +   Default
    +     40
    +
    +XML_FEATURE_MAX_ENTITY_EXPANSIONS
    +   Limit the total length of all entity expansions throughout the entire
    +   document. The lengths of all entities are accumulated in a parser variable.
    +   The setting protects against quadratic blowup attacks (lots of expansions
    +   of a large entity declaration). When the sum of all entities exceeds
    +   the limit, the parser stops and fails with `XML_ERROR_ENTITY_EXPANSION`.
    +   A value of 0 disables the protection.
    +
    +   Supported range
    +     0 .. UINT_MAX
    +   Default
    +     8 MiB
    +
    +XML_FEATURE_RESET_DTD
    +   Reset all DTD information after the <!DOCTYPE> block has been parsed. When
    +   the flag is set (default: false) all DTD information after the
    +   endDoctypeDeclHandler has been called. The flag can be set inside the
    +   endDoctypeDeclHandler. Without DTD information any entity reference in
    +   the document body leads to `XML_ERROR_UNDEFINED_ENTITY`.
    +
    +   Supported range
    +     0, 1
    +   Default
    +     0
    +
    +
    +How to avoid XML vulnerabilities
    +================================
    +
    +Best practices
    +--------------
    +
    +* Don't allow DTDs
    +* Don't expand entities
    +* Don't resolve externals
    +* Limit parse depth
    +* Limit total input size
    +* Limit parse time
    +* Favor a SAX or iterparse-like parser for potential large data
    +* Validate and properly quote arguments to XSL transformations and
    +  XPath queries
    +* Don't use XPath expression from untrusted sources
    +* Don't apply XSL transformations that come untrusted sources
    +
    +(based on Brad Hill's `Attacking XML Security`_)
    +
    +
    +Other things to consider
    +========================
    +
    +XML, XML parsers and processing libraries have more features and possible
    +issue that could lead to DoS vulnerabilities or security exploits in
    +applications. I have compiled an incomplete list of theoretical issues that
    +need further research and more attention. The list is deliberately pessimistic
    +and a bit paranoid, too. It contains things that might go wrong under daffy
    +circumstances.
    +
    +
    +attribute blowup / hash collision attack
    +----------------------------------------
    +
    +XML parsers may use an algorithm with quadratic runtime O(n :sup:`2`) to
    +handle attributes and namespaces. If it uses hash tables (dictionaries) to
    +store attributes and namespaces the implementation may be vulnerable to
    +hash collision attacks, thus reducing the performance to O(n :sup:`2`) again.
    +In either case an attacker is able to forge a denial of service attack with
    +an XML document that contains thousands upon thousands of attributes in
    +a single node.
    +
    +I haven't researched yet if expat, pyexpat or libxml2 are vulnerable.
    +
    +
    +decompression bomb
    +------------------
    +
    +The issue of decompression bombs (aka `ZIP bomb`_) apply to all XML libraries
    +that can parse compressed XML stream like gzipped HTTP streams or LZMA-ed
    +files. For an attacker it can reduce the amount of transmitted data by three
    +magnitudes or more. Gzip is able to compress 1 GiB zeros to roughly 1 MB,
    +lzma is even better::
    +
    +    $ dd if=/dev/zero bs=1M count=1024 | gzip > zeros.gz
    +    $ dd if=/dev/zero bs=1M count=1024 | lzma -z > zeros.xy
    +    $ ls -sh zeros.*
    +    1020K zeros.gz
    +     148K zeros.xy
    +
    +None of Python's standard XML libraries decompress streams except for
    +``xmlrpclib``. The module is vulnerable <https://bugs.python.org/issue16043>
    +to decompression bombs.
    +
    +lxml can load and process compressed data through libxml2 transparently.
    +libxml2 can handle even very large blobs of compressed data efficiently
    +without using too much memory. But it doesn't protect applications from
    +decompression bombs. A carefully written SAX or iterparse-like approach can
    +be safe.
    +
    +
    +Processing Instruction
    +----------------------
    +
    +`PI`_'s like::
    +
    +  <?xml-stylesheet type="text/xsl" href="style.xsl"?>
    +
    +may impose more threats for XML processing. It depends if and how a
    +processor handles processing instructions. The issue of URL retrieval with
    +network or local file access apply to processing instructions, too.
    +
    +
    +Other DTD features
    +------------------
    +
    +`DTD`_ has more features like ``<!NOTATION>``. I haven't researched how
    +these features may be a security threat.
    +
    +
    +XPath
    +-----
    +
    +XPath statements may introduce DoS vulnerabilities. Code should never execute
    +queries from untrusted sources. An attacker may also be able to create an XML
    +document that makes certain XPath queries costly or resource hungry.
    +
    +
    +XPath injection attacks
    +-----------------------
    +
    +XPath injeciton attacks pretty much work like SQL injection attacks.
    +Arguments to XPath queries must be quoted and validated properly, especially
    +when they are taken from the user. The page `Avoid the dangers of XPath injection`_
    +list some ramifications of XPath injections.
    +
    +Python's standard library doesn't have XPath support. Lxml supports
    +parameterized XPath queries which does proper quoting. You just have to use
    +its xpath() method correctly::
    +
    +   # DON'T
    +   >>> tree.xpath("/tag[@id='%s']" % value)
    +
    +   # instead do
    +   >>> tree.xpath("/tag[@id=$tagid]", tagid=name)
    +
    +
    +XInclude
    +--------
    +
    +`XML Inclusion`_ is another way to load and include external files::
    +
    +   <root xmlns:xi="http://www.w3.org/2001/XInclude">
    +     <xi:include href="filename.txt" parse="text" />
    +   </root>
    +
    +This feature should be disabled when XML files from an untrusted source are
    +processed. Some Python XML libraries and libxml2 support XInclude but don't
    +have an option to sandbox inclusion and limit it to allowed directories.
    +
    +
    +XMLSchema location
    +------------------
    +
    +A validating XML parser may download schema files from the information in a
    +``xsi:schemaLocation`` attribute.
    +
    +::
    +
    +  <ead xmlns="urn:isbn:1-931666-22-9"
    +       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    +       xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd">
    +  </ead>
    +
    +
    +XSL Transformation
    +------------------
    +
    +You should keep in mind that XSLT is a Turing complete language. Never
    +process XSLT code from unknown or untrusted source! XSLT processors may
    +allow you to interact with external resources in ways you can't even imagine.
    +Some processors even support extensions that allow read/write access to file
    +system, access to JRE objects or scripting with Jython.
    +
    +Example from `Attacking XML Security`_ for Xalan-J::
    +
    +    <xsl:stylesheet version="1.0"
    +     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    +     xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime"
    +     xmlns:ob="http://xml.apache.org/xalan/java/java.lang.Object"
    +     exclude-result-prefixes= "rt ob">
    +     <xsl:template match="/">
    +       <xsl:variable name="runtimeObject" select="rt:getRuntime()"/>
    +       <xsl:variable name="command"
    +         select="rt:exec($runtimeObject, &apos;c:\Windows\system32\cmd.exe&apos;)"/>
    +       <xsl:variable name="commandAsString" select="ob:toString($command)"/>
    +       <xsl:value-of select="$commandAsString"/>
    +     </xsl:template>
    +    </xsl:stylesheet>
    +
    +
    +Related CVEs
    +============
    +
    +CVE-2013-1664
    +  Unrestricted entity expansion induces DoS vulnerabilities in Python XML
    +  libraries (XML bomb)
    +
    +CVE-2013-1665
    +  External entity expansion in Python XML libraries inflicts potential
    +  security flaws and DoS vulnerabilities
    +
    +
    +Other languages / frameworks
    +=============================
    +
    +Several other programming languages and frameworks are vulnerable as well. A
    +couple of them are affected by the fact that libxml2 up to 2.9.0 has no
    +protection against quadratic blowup attacks. Most of them have potential
    +dangerous default settings for entity expansion and external entities, too.
    +
    +Perl
    +----
    +
    +Perl's XML::Simple is vulnerable to quadratic entity expansion and external
    +entity expansion (both local and remote).
    +
    +
    +Ruby
    +----
    +
    +Ruby's REXML document parser is vulnerable to entity expansion attacks
    +(both quadratic and exponential) but it doesn't do external entity
    +expansion by default. In order to counteract entity expansion you have to
    +disable the feature::
    +
    +  REXML::Document.entity_expansion_limit = 0
    +
    +libxml-ruby and hpricot don't expand entities in their default configuration.
    +
    +
    +PHP
    +---
    +
    +PHP's SimpleXML API is vulnerable to quadratic entity expansion and loads
    +entities from local and remote resources. The option ``LIBXML_NONET`` disables
    +network access but still allows local file access. ``LIBXML_NOENT`` seems to
    +have no effect on entity expansion in PHP 5.4.6.
    +
    +
    +C# / .NET / Mono
    +----------------
    +
    +Information in `XML DoS and Defenses (MSDN)`_ suggest that .NET is
    +vulnerable with its default settings. The article contains code snippets
    +how to create a secure XML reader::
    +
    +  XmlReaderSettings settings = new XmlReaderSettings();
    +  settings.ProhibitDtd = false;
    +  settings.MaxCharactersFromEntities = 1024;
    +  settings.XmlResolver = null;
    +  XmlReader reader = XmlReader.Create(stream, settings);
    +
    +
    +Java
    +----
    +
    +Untested. The documentation of Xerces and its `Xerces SecurityMananger`_
    +sounds like Xerces is also vulnerable to billion laugh attacks with its
    +default settings. It also does entity resolving when an
    +``org.xml.sax.EntityResolver`` is configured. I'm not yet sure about the
    +default setting here.
    +
    +Java specialists suggest to have a custom builder factory::
    +
    +  DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    +  builderFactory.setXIncludeAware(False);
    +  builderFactory.setExpandEntityReferences(False);
    +  builderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, True);
    +  # either
    +  builderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", True);
    +  # or if you need DTDs
    +  builderFactory.setFeature("http://xml.org/sax/features/external-general-entities", False);
    +  builderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", False);
    +  builderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", False);
    +  builderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", False);
    +
    +
    +TODO
    +====
    +
    +* DOM: Use xml.dom.xmlbuilder options for entity handling
    +* SAX: take feature_external_ges and feature_external_pes (?) into account
    +* test experimental monkey patching of stdlib modules
    +* improve documentation
    +
    +
    +License
    +=======
    +
    +Copyright (c) 2013-2017 by Christian Heimes <christian@python.org>
    +
    +Licensed to PSF under a Contributor Agreement.
    +
    +See https://www.python.org/psf/license for licensing details.
    +
    +
    +Acknowledgements
    +================
    +
    +Brett Cannon (Python Core developer)
    +  review and code cleanup
    +
    +Antoine Pitrou (Python Core developer)
    +  code review
    +
    +Aaron Patterson, Ben Murphy and Michael Koziarski (Ruby community)
    +  Many thanks to Aaron, Ben and Michael from the Ruby community for their
    +  report and assistance.
    +
    +Thierry Carrez (OpenStack)
    +  Many thanks to Thierry for his report to the Python Security Response
    +  Team on behalf of the OpenStack security team.
    +
    +Carl Meyer (Django)
    +  Many thanks to Carl for his report to PSRT on behalf of the Django security
    +  team.
    +
    +Daniel Veillard (libxml2)
    +  Many thanks to Daniel for his insight and assistance with libxml2.
    +
    +semantics GmbH (https://www.semantics.de/)
    +  Many thanks to my employer semantics for letting me work on the issue
    +  during working hours as part of semantics's open source initiative.
    +
    +
    +References
    +==========
    +
    +* `XML DoS and Defenses (MSDN)`_
    +* `Billion Laughs`_ on Wikipedia
    +* `ZIP bomb`_ on Wikipedia
    +* `Configure SAX parsers for secure processing`_
    +* `Testing for XML Injection`_
    +
    +.. _defusedxml package: https://github.com/tiran/defusedxml
    +.. _defusedxml on PyPI: https://pypi.python.org/pypi/defusedxml
    +.. _defusedexpat package: https://github.com/tiran/defusedexpat
    +.. _defusedexpat on PyPI: https://pypi.python.org/pypi/defusedexpat
    +.. _modified expat: https://github.com/tiran/expat
    +.. _expat parser: http://expat.sourceforge.net/
    +.. _Attacking XML Security: https://www.isecpartners.com/media/12976/iSEC-HILL-Attacking-XML-Security-bh07.pdf
    +.. _Billion Laughs: https://en.wikipedia.org/wiki/Billion_laughs
    +.. _XML DoS and Defenses (MSDN): https://msdn.microsoft.com/en-us/magazine/ee335713.aspx
    +.. _ZIP bomb: https://en.wikipedia.org/wiki/Zip_bomb
    +.. _DTD: https://en.wikipedia.org/wiki/Document_Type_Definition
    +.. _PI: https://en.wikipedia.org/wiki/Processing_Instruction
    +.. _Avoid the dangers of XPath injection: http://www.ibm.com/developerworks/xml/library/x-xpathinjection/index.html
    +.. _Configure SAX parsers for secure processing: http://www.ibm.com/developerworks/xml/library/x-tipcfsx/index.html
    +.. _Testing for XML Injection: https://www.owasp.org/index.php/Testing_for_XML_Injection_(OWASP-DV-008)
    +.. _Xerces SecurityMananger: https://xerces.apache.org/xerces2-j/javadocs/xerces2/org/apache/xerces/util/SecurityManager.html
    +.. _XML Inclusion: https://www.w3.org/TR/xinclude/#include_element
    +
    +Changelog
    +=========
    +
    +defusedxml 0.7.1
    +---------------------
    +
    +*Release date: 08-Mar-2021*
    +
    +- Fix regression ``defusedxml.ElementTree.ParseError`` (#63)
    +  The ``ParseError`` exception is now the same class object as
    +  ``xml.etree.ElementTree.ParseError`` again.
    +
    +
    +defusedxml 0.7.0
    +----------------
    +
    +*Release date: 4-Mar-2021*
    +
    +- No changes
    +
    +
    +defusedxml 0.7.0rc2
    +-------------------
    +
    +*Release date: 12-Jan-2021*
    +
    +- Re-add and deprecate ``defusedxml.cElementTree``
    +- Use GitHub Actions instead of TravisCI
    +- Restore ``ElementTree`` attribute of ``xml.etree`` module after patching
    +
    +defusedxml 0.7.0rc1
    +-------------------
    +
    +*Release date: 04-May-2020*
    +
    +- Add support for Python 3.9
    +- ``defusedxml.cElementTree`` is not available with Python 3.9.
    +- Python 2 is deprecate. Support for Python 2 will be removed in 0.8.0.
    +
    +
    +defusedxml 0.6.0
    +----------------
    +
    +*Release date: 17-Apr-2019*
    +
    +- Increase test coverage.
    +- Add badges to README.
    +
    +
    +defusedxml 0.6.0rc1
    +-------------------
    +
    +*Release date: 14-Apr-2019*
    +
    +- Test on Python 3.7 stable and 3.8-dev
    +- Drop support for Python 3.4
    +- No longer pass *html* argument to XMLParse. It has been deprecated and
    +  ignored for a long time. The DefusedXMLParser still takes a html argument.
    +  A deprecation warning is issued when the argument is False and a TypeError
    +  when it's True.
    +- defusedxml now fails early when pyexpat stdlib module is not available or
    +  broken.
    +- defusedxml.ElementTree.__all__ now lists ParseError as public attribute.
    +- The defusedxml.ElementTree and defusedxml.cElementTree modules had a typo
    +  and used XMLParse instead of XMLParser as an alias for DefusedXMLParser.
    +  Both the old and fixed name are now available.
    +
    +
    +defusedxml 0.5.0
    +----------------
    +
    +*Release date: 07-Feb-2017*
    +
    +- No changes
    +
    +
    +defusedxml 0.5.0.rc1
    +--------------------
    +
    +*Release date: 28-Jan-2017*
    +
    +- Add compatibility with Python 3.6
    +- Drop support for Python 2.6, 3.1, 3.2, 3.3
    +- Fix lxml tests (XMLSyntaxError: Detected an entity reference loop)
    +
    +
    +defusedxml 0.4.1
    +----------------
    +
    +*Release date: 28-Mar-2013*
    +
    +- Add more demo exploits, e.g. python_external.py and Xalan XSLT demos.
    +- Improved documentation.
    +
    +
    +defusedxml 0.4
    +--------------
    +
    +*Release date: 25-Feb-2013*
    +
    +- As per http://seclists.org/oss-sec/2013/q1/340 please REJECT
    +  CVE-2013-0278, CVE-2013-0279 and CVE-2013-0280 and use CVE-2013-1664,
    +  CVE-2013-1665 for OpenStack/etc.
    +- Add missing parser_list argument to sax.make_parser(). The argument is
    +  ignored, though. (thanks to Florian Apolloner)
    +- Add demo exploit for external entity attack on Python's SAX parser, XML-RPC
    +  and WebDAV.
    +
    +
    +defusedxml 0.3
    +--------------
    +
    +*Release date: 19-Feb-2013*
    +
    +- Improve documentation
    +
    +
    +defusedxml 0.2
    +--------------
    +
    +*Release date: 15-Feb-2013*
    +
    +- Rename ExternalEntitiesForbidden to ExternalReferenceForbidden
    +- Rename defusedxml.lxml.check_dtd() to check_docinfo()
    +- Unify argument names in callbacks
    +- Add arguments and formatted representation to exceptions
    +- Add forbid_external argument to all functions and classes
    +- More tests
    +- LOTS of documentation
    +- Add example code for other languages (Ruby, Perl, PHP) and parsers (Genshi)
    +- Add protection against XML and gzip attacks to xmlrpclib
    +
    +defusedxml 0.1
    +--------------
    +
    +*Release date: 08-Feb-2013*
    +
    +- Initial and internal release for PSRT review
    +
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/RECORD b/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/RECORD
    new file mode 100644
    index 0000000..0a2fa9c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/RECORD
    @@ -0,0 +1,17 @@
    +defusedxml-0.7.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
    +defusedxml-0.7.1.dist-info/LICENSE,sha256=uAzp2oxCofkQeWJ_u-K_JyEK4Qig_-Xwd9WwjgdsJMg,2409
    +defusedxml-0.7.1.dist-info/METADATA,sha256=Np0872SHDa-En7pxHLjQWn7-PI2asPdjrcNAef43i7E,32518
    +defusedxml-0.7.1.dist-info/RECORD,,
    +defusedxml-0.7.1.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110
    +defusedxml-0.7.1.dist-info/top_level.txt,sha256=QGHa90F50pVKhWSFlERI0jtSKtqDiGyfeZX7dQNZAAw,11
    +defusedxml/ElementTree.py,sha256=GLSqpCz58oXGPGyzf_HylsPS9_dcGVP5SN4dK7yvyPw,4640
    +defusedxml/__init__.py,sha256=RczeaVJG64p2Fgy1jlCzbuRdchEPnEaCBrxgk8JJ_pM,1444
    +defusedxml/cElementTree.py,sha256=PpaKMh3rU29sY8amAK4fzHQKl8gcAYD0h1LCoW62Rtk,1449
    +defusedxml/common.py,sha256=3d26jNW4fNXzgjWhvUfs83Afiz5EVxFDupQbugkSMZc,4036
    +defusedxml/expatbuilder.py,sha256=b4Q05vsBMJ5StkiTFf4my2rGGo1gZyEl_hC5MeFTOAA,3732
    +defusedxml/expatreader.py,sha256=KOpSrwkSvj5SGOY9pTXOM26Dnz00rsJt33WueVvzpvc,2196
    +defusedxml/lxml.py,sha256=HW-LFKdrfMRzHdi0Vcucq4-n8yz7v_OQwEQWFg1JQYA,4940
    +defusedxml/minidom.py,sha256=3QcgygVwJqcWDQ3IZ2iol8zsH4cx3BRX70SPcd0bG2g,1884
    +defusedxml/pulldom.py,sha256=DYj2D2lc7xoxZ38gfzujXmdznd8ovzDqGFXqyXbtxjk,1170
    +defusedxml/sax.py,sha256=-SF08Msc2mWEYAMw62pJ5FMwWccOctFSnQwDLYLLlVE,1477
    +defusedxml/xmlrpc.py,sha256=7rZQey3tqXcc1hrrM3RprOICU6fiFny9B9l4nmTioxA,5364
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/WHEEL b/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/WHEEL
    new file mode 100644
    index 0000000..ef99c6c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml-0.7.1.dist-info/WHEEL
    @@ -0,0 +1,6 @@
    +Wheel-Version: 1.0
    +Generator: bdist_wheel (0.34.2)
    +Root-Is-Purelib: true
    +Tag: py2-none-any
    +Tag: py3-none-any
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml/ElementTree.py b/deployment-apps/metricator-for-nmon/lib/defusedxml/ElementTree.py
    new file mode 100644
    index 0000000..5ba765f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml/ElementTree.py
    @@ -0,0 +1,154 @@
    +# defusedxml
    +#
    +# Copyright (c) 2013 by Christian Heimes <christian@python.org>
    +# Licensed to PSF under a Contributor Agreement.
    +# See https://www.python.org/psf/license for licensing details.
    +"""Defused xml.etree.ElementTree facade
    +"""
    +from __future__ import print_function, absolute_import
    +
    +import sys
    +import warnings
    +from xml.etree.ElementTree import ParseError
    +from xml.etree.ElementTree import TreeBuilder as _TreeBuilder
    +from xml.etree.ElementTree import parse as _parse
    +from xml.etree.ElementTree import tostring
    +
    +from .common import PY3
    +
    +if PY3:
    +    import importlib
    +else:
    +    from xml.etree.ElementTree import XMLParser as _XMLParser
    +    from xml.etree.ElementTree import iterparse as _iterparse
    +
    +
    +from .common import (
    +    DTDForbidden,
    +    EntitiesForbidden,
    +    ExternalReferenceForbidden,
    +    _generate_etree_functions,
    +)
    +
    +__origin__ = "xml.etree.ElementTree"
    +
    +
    +def _get_py3_cls():
    +    """Python 3.3 hides the pure Python code but defusedxml requires it.
    +
    +    The code is based on test.support.import_fresh_module().
    +    """
    +    pymodname = "xml.etree.ElementTree"
    +    cmodname = "_elementtree"
    +
    +    pymod = sys.modules.pop(pymodname, None)
    +    cmod = sys.modules.pop(cmodname, None)
    +
    +    sys.modules[cmodname] = None
    +    try:
    +        pure_pymod = importlib.import_module(pymodname)
    +    finally:
    +        # restore module
    +        sys.modules[pymodname] = pymod
    +        if cmod is not None:
    +            sys.modules[cmodname] = cmod
    +        else:
    +            sys.modules.pop(cmodname, None)
    +        # restore attribute on original package
    +        etree_pkg = sys.modules["xml.etree"]
    +        if pymod is not None:
    +            etree_pkg.ElementTree = pymod
    +        elif hasattr(etree_pkg, "ElementTree"):
    +            del etree_pkg.ElementTree
    +
    +    _XMLParser = pure_pymod.XMLParser
    +    _iterparse = pure_pymod.iterparse
    +    # patch pure module to use ParseError from C extension
    +    pure_pymod.ParseError = ParseError
    +
    +    return _XMLParser, _iterparse
    +
    +
    +if PY3:
    +    _XMLParser, _iterparse = _get_py3_cls()
    +
    +
    +_sentinel = object()
    +
    +
    +class DefusedXMLParser(_XMLParser):
    +    def __init__(
    +        self,
    +        html=_sentinel,
    +        target=None,
    +        encoding=None,
    +        forbid_dtd=False,
    +        forbid_entities=True,
    +        forbid_external=True,
    +    ):
    +        # Python 2.x old style class
    +        _XMLParser.__init__(self, target=target, encoding=encoding)
    +        if html is not _sentinel:
    +            # the 'html' argument has been deprecated and ignored in all
    +            # supported versions of Python. Python 3.8 finally removed it.
    +            if html:
    +                raise TypeError("'html=True' is no longer supported.")
    +            else:
    +                warnings.warn(
    +                    "'html' keyword argument is no longer supported. Pass "
    +                    "in arguments as keyword arguments.",
    +                    category=DeprecationWarning,
    +                )
    +
    +        self.forbid_dtd = forbid_dtd
    +        self.forbid_entities = forbid_entities
    +        self.forbid_external = forbid_external
    +        if PY3:
    +            parser = self.parser
    +        else:
    +            parser = self._parser
    +        if self.forbid_dtd:
    +            parser.StartDoctypeDeclHandler = self.defused_start_doctype_decl
    +        if self.forbid_entities:
    +            parser.EntityDeclHandler = self.defused_entity_decl
    +            parser.UnparsedEntityDeclHandler = self.defused_unparsed_entity_decl
    +        if self.forbid_external:
    +            parser.ExternalEntityRefHandler = self.defused_external_entity_ref_handler
    +
    +    def defused_start_doctype_decl(self, name, sysid, pubid, has_internal_subset):
    +        raise DTDForbidden(name, sysid, pubid)
    +
    +    def defused_entity_decl(
    +        self, name, is_parameter_entity, value, base, sysid, pubid, notation_name
    +    ):
    +        raise EntitiesForbidden(name, value, base, sysid, pubid, notation_name)
    +
    +    def defused_unparsed_entity_decl(self, name, base, sysid, pubid, notation_name):
    +        # expat 1.2
    +        raise EntitiesForbidden(name, None, base, sysid, pubid, notation_name)  # pragma: no cover
    +
    +    def defused_external_entity_ref_handler(self, context, base, sysid, pubid):
    +        raise ExternalReferenceForbidden(context, base, sysid, pubid)
    +
    +
    +# aliases
    +# XMLParse is a typo, keep it for backwards compatibility
    +XMLTreeBuilder = XMLParse = XMLParser = DefusedXMLParser
    +
    +parse, iterparse, fromstring = _generate_etree_functions(
    +    DefusedXMLParser, _TreeBuilder, _parse, _iterparse
    +)
    +XML = fromstring
    +
    +
    +__all__ = [
    +    "ParseError",
    +    "XML",
    +    "XMLParse",
    +    "XMLParser",
    +    "XMLTreeBuilder",
    +    "fromstring",
    +    "iterparse",
    +    "parse",
    +    "tostring",
    +]
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml/__init__.py b/deployment-apps/metricator-for-nmon/lib/defusedxml/__init__.py
    new file mode 100644
    index 0000000..4b5a230
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml/__init__.py
    @@ -0,0 +1,67 @@
    +# defusedxml
    +#
    +# Copyright (c) 2013 by Christian Heimes <christian@python.org>
    +# Licensed to PSF under a Contributor Agreement.
    +# See https://www.python.org/psf/license for licensing details.
    +"""Defuse XML bomb denial of service vulnerabilities
    +"""
    +from __future__ import print_function, absolute_import
    +
    +import warnings
    +
    +from .common import (
    +    DefusedXmlException,
    +    DTDForbidden,
    +    EntitiesForbidden,
    +    ExternalReferenceForbidden,
    +    NotSupportedError,
    +    _apply_defusing,
    +)
    +
    +
    +def defuse_stdlib():
    +    """Monkey patch and defuse all stdlib packages
    +
    +    :warning: The monkey patch is an EXPERIMETNAL feature.
    +    """
    +    defused = {}
    +
    +    with warnings.catch_warnings():
    +        from . import cElementTree
    +    from . import ElementTree
    +    from . import minidom
    +    from . import pulldom
    +    from . import sax
    +    from . import expatbuilder
    +    from . import expatreader
    +    from . import xmlrpc
    +
    +    xmlrpc.monkey_patch()
    +    defused[xmlrpc] = None
    +
    +    defused_mods = [
    +        cElementTree,
    +        ElementTree,
    +        minidom,
    +        pulldom,
    +        sax,
    +        expatbuilder,
    +        expatreader,
    +    ]
    +
    +    for defused_mod in defused_mods:
    +        stdlib_mod = _apply_defusing(defused_mod)
    +        defused[defused_mod] = stdlib_mod
    +
    +    return defused
    +
    +
    +__version__ = "0.7.1"
    +
    +__all__ = [
    +    "DefusedXmlException",
    +    "DTDForbidden",
    +    "EntitiesForbidden",
    +    "ExternalReferenceForbidden",
    +    "NotSupportedError",
    +]
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml/cElementTree.py b/deployment-apps/metricator-for-nmon/lib/defusedxml/cElementTree.py
    new file mode 100644
    index 0000000..84670c6
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml/cElementTree.py
    @@ -0,0 +1,62 @@
    +# defusedxml
    +#
    +# Copyright (c) 2013 by Christian Heimes <christian@python.org>
    +# Licensed to PSF under a Contributor Agreement.
    +# See https://www.python.org/psf/license for licensing details.
    +"""Defused xml.etree.cElementTree
    +"""
    +from __future__ import absolute_import
    +
    +import warnings
    +
    +from .common import _generate_etree_functions
    +
    +from xml.etree.cElementTree import TreeBuilder as _TreeBuilder
    +from xml.etree.cElementTree import parse as _parse
    +from xml.etree.cElementTree import tostring
    +
    +# iterparse from ElementTree!
    +from xml.etree.ElementTree import iterparse as _iterparse
    +
    +# This module is an alias for ElementTree just like xml.etree.cElementTree
    +from .ElementTree import (
    +    XML,
    +    XMLParse,
    +    XMLParser,
    +    XMLTreeBuilder,
    +    fromstring,
    +    iterparse,
    +    parse,
    +    tostring,
    +    DefusedXMLParser,
    +    ParseError,
    +)
    +
    +__origin__ = "xml.etree.cElementTree"
    +
    +
    +warnings.warn(
    +    "defusedxml.cElementTree is deprecated, import from defusedxml.ElementTree instead.",
    +    category=DeprecationWarning,
    +    stacklevel=2,
    +)
    +
    +# XMLParse is a typo, keep it for backwards compatibility
    +XMLTreeBuilder = XMLParse = XMLParser = DefusedXMLParser
    +
    +parse, iterparse, fromstring = _generate_etree_functions(
    +    DefusedXMLParser, _TreeBuilder, _parse, _iterparse
    +)
    +XML = fromstring
    +
    +__all__ = [
    +    "ParseError",
    +    "XML",
    +    "XMLParse",
    +    "XMLParser",
    +    "XMLTreeBuilder",
    +    "fromstring",
    +    "iterparse",
    +    "parse",
    +    "tostring",
    +]
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml/common.py b/deployment-apps/metricator-for-nmon/lib/defusedxml/common.py
    new file mode 100644
    index 0000000..5ceda1f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml/common.py
    @@ -0,0 +1,129 @@
    +# defusedxml
    +#
    +# Copyright (c) 2013 by Christian Heimes <christian@python.org>
    +# Licensed to PSF under a Contributor Agreement.
    +# See https://www.python.org/psf/license for licensing details.
    +"""Common constants, exceptions and helpe functions
    +"""
    +import sys
    +import xml.parsers.expat
    +
    +PY3 = sys.version_info[0] == 3
    +
    +# Fail early when pyexpat is not installed correctly
    +if not hasattr(xml.parsers.expat, "ParserCreate"):
    +    raise ImportError("pyexpat")  # pragma: no cover
    +
    +
    +class DefusedXmlException(ValueError):
    +    """Base exception"""
    +
    +    def __repr__(self):
    +        return str(self)
    +
    +
    +class DTDForbidden(DefusedXmlException):
    +    """Document type definition is forbidden"""
    +
    +    def __init__(self, name, sysid, pubid):
    +        super(DTDForbidden, self).__init__()
    +        self.name = name
    +        self.sysid = sysid
    +        self.pubid = pubid
    +
    +    def __str__(self):
    +        tpl = "DTDForbidden(name='{}', system_id={!r}, public_id={!r})"
    +        return tpl.format(self.name, self.sysid, self.pubid)
    +
    +
    +class EntitiesForbidden(DefusedXmlException):
    +    """Entity definition is forbidden"""
    +
    +    def __init__(self, name, value, base, sysid, pubid, notation_name):
    +        super(EntitiesForbidden, self).__init__()
    +        self.name = name
    +        self.value = value
    +        self.base = base
    +        self.sysid = sysid
    +        self.pubid = pubid
    +        self.notation_name = notation_name
    +
    +    def __str__(self):
    +        tpl = "EntitiesForbidden(name='{}', system_id={!r}, public_id={!r})"
    +        return tpl.format(self.name, self.sysid, self.pubid)
    +
    +
    +class ExternalReferenceForbidden(DefusedXmlException):
    +    """Resolving an external reference is forbidden"""
    +
    +    def __init__(self, context, base, sysid, pubid):
    +        super(ExternalReferenceForbidden, self).__init__()
    +        self.context = context
    +        self.base = base
    +        self.sysid = sysid
    +        self.pubid = pubid
    +
    +    def __str__(self):
    +        tpl = "ExternalReferenceForbidden(system_id='{}', public_id={})"
    +        return tpl.format(self.sysid, self.pubid)
    +
    +
    +class NotSupportedError(DefusedXmlException):
    +    """The operation is not supported"""
    +
    +
    +def _apply_defusing(defused_mod):
    +    assert defused_mod is sys.modules[defused_mod.__name__]
    +    stdlib_name = defused_mod.__origin__
    +    __import__(stdlib_name, {}, {}, ["*"])
    +    stdlib_mod = sys.modules[stdlib_name]
    +    stdlib_names = set(dir(stdlib_mod))
    +    for name, obj in vars(defused_mod).items():
    +        if name.startswith("_") or name not in stdlib_names:
    +            continue
    +        setattr(stdlib_mod, name, obj)
    +    return stdlib_mod
    +
    +
    +def _generate_etree_functions(DefusedXMLParser, _TreeBuilder, _parse, _iterparse):
    +    """Factory for functions needed by etree, dependent on whether
    +    cElementTree or ElementTree is used."""
    +
    +    def parse(source, parser=None, forbid_dtd=False, forbid_entities=True, forbid_external=True):
    +        if parser is None:
    +            parser = DefusedXMLParser(
    +                target=_TreeBuilder(),
    +                forbid_dtd=forbid_dtd,
    +                forbid_entities=forbid_entities,
    +                forbid_external=forbid_external,
    +            )
    +        return _parse(source, parser)
    +
    +    def iterparse(
    +        source,
    +        events=None,
    +        parser=None,
    +        forbid_dtd=False,
    +        forbid_entities=True,
    +        forbid_external=True,
    +    ):
    +        if parser is None:
    +            parser = DefusedXMLParser(
    +                target=_TreeBuilder(),
    +                forbid_dtd=forbid_dtd,
    +                forbid_entities=forbid_entities,
    +                forbid_external=forbid_external,
    +            )
    +        return _iterparse(source, events, parser)
    +
    +    def fromstring(text, forbid_dtd=False, forbid_entities=True, forbid_external=True):
    +        parser = DefusedXMLParser(
    +            target=_TreeBuilder(),
    +            forbid_dtd=forbid_dtd,
    +            forbid_entities=forbid_entities,
    +            forbid_external=forbid_external,
    +        )
    +        parser.feed(text)
    +        return parser.close()
    +
    +    return parse, iterparse, fromstring
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml/expatbuilder.py b/deployment-apps/metricator-for-nmon/lib/defusedxml/expatbuilder.py
    new file mode 100644
    index 0000000..7bfc57e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml/expatbuilder.py
    @@ -0,0 +1,107 @@
    +# defusedxml
    +#
    +# Copyright (c) 2013 by Christian Heimes <christian@python.org>
    +# Licensed to PSF under a Contributor Agreement.
    +# See https://www.python.org/psf/license for licensing details.
    +"""Defused xml.dom.expatbuilder
    +"""
    +from __future__ import print_function, absolute_import
    +
    +from xml.dom.expatbuilder import ExpatBuilder as _ExpatBuilder
    +from xml.dom.expatbuilder import Namespaces as _Namespaces
    +
    +from .common import DTDForbidden, EntitiesForbidden, ExternalReferenceForbidden
    +
    +__origin__ = "xml.dom.expatbuilder"
    +
    +
    +class DefusedExpatBuilder(_ExpatBuilder):
    +    """Defused document builder"""
    +
    +    def __init__(
    +        self, options=None, forbid_dtd=False, forbid_entities=True, forbid_external=True
    +    ):
    +        _ExpatBuilder.__init__(self, options)
    +        self.forbid_dtd = forbid_dtd
    +        self.forbid_entities = forbid_entities
    +        self.forbid_external = forbid_external
    +
    +    def defused_start_doctype_decl(self, name, sysid, pubid, has_internal_subset):
    +        raise DTDForbidden(name, sysid, pubid)
    +
    +    def defused_entity_decl(
    +        self, name, is_parameter_entity, value, base, sysid, pubid, notation_name
    +    ):
    +        raise EntitiesForbidden(name, value, base, sysid, pubid, notation_name)
    +
    +    def defused_unparsed_entity_decl(self, name, base, sysid, pubid, notation_name):
    +        # expat 1.2
    +        raise EntitiesForbidden(name, None, base, sysid, pubid, notation_name)  # pragma: no cover
    +
    +    def defused_external_entity_ref_handler(self, context, base, sysid, pubid):
    +        raise ExternalReferenceForbidden(context, base, sysid, pubid)
    +
    +    def install(self, parser):
    +        _ExpatBuilder.install(self, parser)
    +
    +        if self.forbid_dtd:
    +            parser.StartDoctypeDeclHandler = self.defused_start_doctype_decl
    +        if self.forbid_entities:
    +            # if self._options.entities:
    +            parser.EntityDeclHandler = self.defused_entity_decl
    +            parser.UnparsedEntityDeclHandler = self.defused_unparsed_entity_decl
    +        if self.forbid_external:
    +            parser.ExternalEntityRefHandler = self.defused_external_entity_ref_handler
    +
    +
    +class DefusedExpatBuilderNS(_Namespaces, DefusedExpatBuilder):
    +    """Defused document builder that supports namespaces."""
    +
    +    def install(self, parser):
    +        DefusedExpatBuilder.install(self, parser)
    +        if self._options.namespace_declarations:
    +            parser.StartNamespaceDeclHandler = self.start_namespace_decl_handler
    +
    +    def reset(self):
    +        DefusedExpatBuilder.reset(self)
    +        self._initNamespaces()
    +
    +
    +def parse(file, namespaces=True, forbid_dtd=False, forbid_entities=True, forbid_external=True):
    +    """Parse a document, returning the resulting Document node.
    +
    +    'file' may be either a file name or an open file object.
    +    """
    +    if namespaces:
    +        build_builder = DefusedExpatBuilderNS
    +    else:
    +        build_builder = DefusedExpatBuilder
    +    builder = build_builder(
    +        forbid_dtd=forbid_dtd, forbid_entities=forbid_entities, forbid_external=forbid_external
    +    )
    +
    +    if isinstance(file, str):
    +        fp = open(file, "rb")
    +        try:
    +            result = builder.parseFile(fp)
    +        finally:
    +            fp.close()
    +    else:
    +        result = builder.parseFile(file)
    +    return result
    +
    +
    +def parseString(
    +    string, namespaces=True, forbid_dtd=False, forbid_entities=True, forbid_external=True
    +):
    +    """Parse a document from a string, returning the resulting
    +    Document node.
    +    """
    +    if namespaces:
    +        build_builder = DefusedExpatBuilderNS
    +    else:
    +        build_builder = DefusedExpatBuilder
    +    builder = build_builder(
    +        forbid_dtd=forbid_dtd, forbid_entities=forbid_entities, forbid_external=forbid_external
    +    )
    +    return builder.parseString(string)
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml/expatreader.py b/deployment-apps/metricator-for-nmon/lib/defusedxml/expatreader.py
    new file mode 100644
    index 0000000..890e1d1
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml/expatreader.py
    @@ -0,0 +1,61 @@
    +# defusedxml
    +#
    +# Copyright (c) 2013 by Christian Heimes <christian@python.org>
    +# Licensed to PSF under a Contributor Agreement.
    +# See https://www.python.org/psf/license for licensing details.
    +"""Defused xml.sax.expatreader
    +"""
    +from __future__ import print_function, absolute_import
    +
    +from xml.sax.expatreader import ExpatParser as _ExpatParser
    +
    +from .common import DTDForbidden, EntitiesForbidden, ExternalReferenceForbidden
    +
    +__origin__ = "xml.sax.expatreader"
    +
    +
    +class DefusedExpatParser(_ExpatParser):
    +    """Defused SAX driver for the pyexpat C module."""
    +
    +    def __init__(
    +        self,
    +        namespaceHandling=0,
    +        bufsize=2 ** 16 - 20,
    +        forbid_dtd=False,
    +        forbid_entities=True,
    +        forbid_external=True,
    +    ):
    +        _ExpatParser.__init__(self, namespaceHandling, bufsize)
    +        self.forbid_dtd = forbid_dtd
    +        self.forbid_entities = forbid_entities
    +        self.forbid_external = forbid_external
    +
    +    def defused_start_doctype_decl(self, name, sysid, pubid, has_internal_subset):
    +        raise DTDForbidden(name, sysid, pubid)
    +
    +    def defused_entity_decl(
    +        self, name, is_parameter_entity, value, base, sysid, pubid, notation_name
    +    ):
    +        raise EntitiesForbidden(name, value, base, sysid, pubid, notation_name)
    +
    +    def defused_unparsed_entity_decl(self, name, base, sysid, pubid, notation_name):
    +        # expat 1.2
    +        raise EntitiesForbidden(name, None, base, sysid, pubid, notation_name)  # pragma: no cover
    +
    +    def defused_external_entity_ref_handler(self, context, base, sysid, pubid):
    +        raise ExternalReferenceForbidden(context, base, sysid, pubid)
    +
    +    def reset(self):
    +        _ExpatParser.reset(self)
    +        parser = self._parser
    +        if self.forbid_dtd:
    +            parser.StartDoctypeDeclHandler = self.defused_start_doctype_decl
    +        if self.forbid_entities:
    +            parser.EntityDeclHandler = self.defused_entity_decl
    +            parser.UnparsedEntityDeclHandler = self.defused_unparsed_entity_decl
    +        if self.forbid_external:
    +            parser.ExternalEntityRefHandler = self.defused_external_entity_ref_handler
    +
    +
    +def create_parser(*args, **kwargs):
    +    return DefusedExpatParser(*args, **kwargs)
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml/lxml.py b/deployment-apps/metricator-for-nmon/lib/defusedxml/lxml.py
    new file mode 100644
    index 0000000..99d5be9
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml/lxml.py
    @@ -0,0 +1,153 @@
    +# defusedxml
    +#
    +# Copyright (c) 2013 by Christian Heimes <christian@python.org>
    +# Licensed to PSF under a Contributor Agreement.
    +# See https://www.python.org/psf/license for licensing details.
    +"""DEPRECATED Example code for lxml.etree protection
    +
    +The code has NO protection against decompression bombs.
    +"""
    +from __future__ import print_function, absolute_import
    +
    +import threading
    +import warnings
    +
    +from lxml import etree as _etree
    +
    +from .common import DTDForbidden, EntitiesForbidden, NotSupportedError
    +
    +LXML3 = _etree.LXML_VERSION[0] >= 3
    +
    +__origin__ = "lxml.etree"
    +
    +tostring = _etree.tostring
    +
    +
    +warnings.warn(
    +    "defusedxml.lxml is no longer supported and will be removed in a future release.",
    +    category=DeprecationWarning,
    +    stacklevel=2,
    +)
    +
    +
    +class RestrictedElement(_etree.ElementBase):
    +    """A restricted Element class that filters out instances of some classes"""
    +
    +    __slots__ = ()
    +    # blacklist = (etree._Entity, etree._ProcessingInstruction, etree._Comment)
    +    blacklist = _etree._Entity
    +
    +    def _filter(self, iterator):
    +        blacklist = self.blacklist
    +        for child in iterator:
    +            if isinstance(child, blacklist):
    +                continue
    +            yield child
    +
    +    def __iter__(self):
    +        iterator = super(RestrictedElement, self).__iter__()
    +        return self._filter(iterator)
    +
    +    def iterchildren(self, tag=None, reversed=False):
    +        iterator = super(RestrictedElement, self).iterchildren(tag=tag, reversed=reversed)
    +        return self._filter(iterator)
    +
    +    def iter(self, tag=None, *tags):
    +        iterator = super(RestrictedElement, self).iter(tag=tag, *tags)
    +        return self._filter(iterator)
    +
    +    def iterdescendants(self, tag=None, *tags):
    +        iterator = super(RestrictedElement, self).iterdescendants(tag=tag, *tags)
    +        return self._filter(iterator)
    +
    +    def itersiblings(self, tag=None, preceding=False):
    +        iterator = super(RestrictedElement, self).itersiblings(tag=tag, preceding=preceding)
    +        return self._filter(iterator)
    +
    +    def getchildren(self):
    +        iterator = super(RestrictedElement, self).__iter__()
    +        return list(self._filter(iterator))
    +
    +    def getiterator(self, tag=None):
    +        iterator = super(RestrictedElement, self).getiterator(tag)
    +        return self._filter(iterator)
    +
    +
    +class GlobalParserTLS(threading.local):
    +    """Thread local context for custom parser instances"""
    +
    +    parser_config = {
    +        "resolve_entities": False,
    +        # 'remove_comments': True,
    +        # 'remove_pis': True,
    +    }
    +
    +    element_class = RestrictedElement
    +
    +    def createDefaultParser(self):
    +        parser = _etree.XMLParser(**self.parser_config)
    +        element_class = self.element_class
    +        if self.element_class is not None:
    +            lookup = _etree.ElementDefaultClassLookup(element=element_class)
    +            parser.set_element_class_lookup(lookup)
    +        return parser
    +
    +    def setDefaultParser(self, parser):
    +        self._default_parser = parser
    +
    +    def getDefaultParser(self):
    +        parser = getattr(self, "_default_parser", None)
    +        if parser is None:
    +            parser = self.createDefaultParser()
    +            self.setDefaultParser(parser)
    +        return parser
    +
    +
    +_parser_tls = GlobalParserTLS()
    +getDefaultParser = _parser_tls.getDefaultParser
    +
    +
    +def check_docinfo(elementtree, forbid_dtd=False, forbid_entities=True):
    +    """Check docinfo of an element tree for DTD and entity declarations
    +
    +    The check for entity declarations needs lxml 3 or newer. lxml 2.x does
    +    not support dtd.iterentities().
    +    """
    +    docinfo = elementtree.docinfo
    +    if docinfo.doctype:
    +        if forbid_dtd:
    +            raise DTDForbidden(docinfo.doctype, docinfo.system_url, docinfo.public_id)
    +        if forbid_entities and not LXML3:
    +            # lxml < 3 has no iterentities()
    +            raise NotSupportedError("Unable to check for entity declarations " "in lxml 2.x")
    +
    +    if forbid_entities:
    +        for dtd in docinfo.internalDTD, docinfo.externalDTD:
    +            if dtd is None:
    +                continue
    +            for entity in dtd.iterentities():
    +                raise EntitiesForbidden(entity.name, entity.content, None, None, None, None)
    +
    +
    +def parse(source, parser=None, base_url=None, forbid_dtd=False, forbid_entities=True):
    +    if parser is None:
    +        parser = getDefaultParser()
    +    elementtree = _etree.parse(source, parser, base_url=base_url)
    +    check_docinfo(elementtree, forbid_dtd, forbid_entities)
    +    return elementtree
    +
    +
    +def fromstring(text, parser=None, base_url=None, forbid_dtd=False, forbid_entities=True):
    +    if parser is None:
    +        parser = getDefaultParser()
    +    rootelement = _etree.fromstring(text, parser, base_url=base_url)
    +    elementtree = rootelement.getroottree()
    +    check_docinfo(elementtree, forbid_dtd, forbid_entities)
    +    return rootelement
    +
    +
    +XML = fromstring
    +
    +
    +def iterparse(*args, **kwargs):
    +    raise NotSupportedError("defused lxml.etree.iterparse not available")
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml/minidom.py b/deployment-apps/metricator-for-nmon/lib/defusedxml/minidom.py
    new file mode 100644
    index 0000000..78033b6
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml/minidom.py
    @@ -0,0 +1,63 @@
    +# defusedxml
    +#
    +# Copyright (c) 2013 by Christian Heimes <christian@python.org>
    +# Licensed to PSF under a Contributor Agreement.
    +# See https://www.python.org/psf/license for licensing details.
    +"""Defused xml.dom.minidom
    +"""
    +from __future__ import print_function, absolute_import
    +
    +from xml.dom.minidom import _do_pulldom_parse
    +from . import expatbuilder as _expatbuilder
    +from . import pulldom as _pulldom
    +
    +__origin__ = "xml.dom.minidom"
    +
    +
    +def parse(
    +    file, parser=None, bufsize=None, forbid_dtd=False, forbid_entities=True, forbid_external=True
    +):
    +    """Parse a file into a DOM by filename or file object."""
    +    if parser is None and not bufsize:
    +        return _expatbuilder.parse(
    +            file,
    +            forbid_dtd=forbid_dtd,
    +            forbid_entities=forbid_entities,
    +            forbid_external=forbid_external,
    +        )
    +    else:
    +        return _do_pulldom_parse(
    +            _pulldom.parse,
    +            (file,),
    +            {
    +                "parser": parser,
    +                "bufsize": bufsize,
    +                "forbid_dtd": forbid_dtd,
    +                "forbid_entities": forbid_entities,
    +                "forbid_external": forbid_external,
    +            },
    +        )
    +
    +
    +def parseString(
    +    string, parser=None, forbid_dtd=False, forbid_entities=True, forbid_external=True
    +):
    +    """Parse a file into a DOM from a string."""
    +    if parser is None:
    +        return _expatbuilder.parseString(
    +            string,
    +            forbid_dtd=forbid_dtd,
    +            forbid_entities=forbid_entities,
    +            forbid_external=forbid_external,
    +        )
    +    else:
    +        return _do_pulldom_parse(
    +            _pulldom.parseString,
    +            (string,),
    +            {
    +                "parser": parser,
    +                "forbid_dtd": forbid_dtd,
    +                "forbid_entities": forbid_entities,
    +                "forbid_external": forbid_external,
    +            },
    +        )
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml/pulldom.py b/deployment-apps/metricator-for-nmon/lib/defusedxml/pulldom.py
    new file mode 100644
    index 0000000..e3b10a4
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml/pulldom.py
    @@ -0,0 +1,41 @@
    +# defusedxml
    +#
    +# Copyright (c) 2013 by Christian Heimes <christian@python.org>
    +# Licensed to PSF under a Contributor Agreement.
    +# See https://www.python.org/psf/license for licensing details.
    +"""Defused xml.dom.pulldom
    +"""
    +from __future__ import print_function, absolute_import
    +
    +from xml.dom.pulldom import parse as _parse
    +from xml.dom.pulldom import parseString as _parseString
    +from .sax import make_parser
    +
    +__origin__ = "xml.dom.pulldom"
    +
    +
    +def parse(
    +    stream_or_string,
    +    parser=None,
    +    bufsize=None,
    +    forbid_dtd=False,
    +    forbid_entities=True,
    +    forbid_external=True,
    +):
    +    if parser is None:
    +        parser = make_parser()
    +        parser.forbid_dtd = forbid_dtd
    +        parser.forbid_entities = forbid_entities
    +        parser.forbid_external = forbid_external
    +    return _parse(stream_or_string, parser, bufsize)
    +
    +
    +def parseString(
    +    string, parser=None, forbid_dtd=False, forbid_entities=True, forbid_external=True
    +):
    +    if parser is None:
    +        parser = make_parser()
    +        parser.forbid_dtd = forbid_dtd
    +        parser.forbid_entities = forbid_entities
    +        parser.forbid_external = forbid_external
    +    return _parseString(string, parser)
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml/sax.py b/deployment-apps/metricator-for-nmon/lib/defusedxml/sax.py
    new file mode 100644
    index 0000000..b2786f7
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml/sax.py
    @@ -0,0 +1,60 @@
    +# defusedxml
    +#
    +# Copyright (c) 2013 by Christian Heimes <christian@python.org>
    +# Licensed to PSF under a Contributor Agreement.
    +# See https://www.python.org/psf/license for licensing details.
    +"""Defused xml.sax
    +"""
    +from __future__ import print_function, absolute_import
    +
    +from xml.sax import InputSource as _InputSource
    +from xml.sax import ErrorHandler as _ErrorHandler
    +
    +from . import expatreader
    +
    +__origin__ = "xml.sax"
    +
    +
    +def parse(
    +    source,
    +    handler,
    +    errorHandler=_ErrorHandler(),
    +    forbid_dtd=False,
    +    forbid_entities=True,
    +    forbid_external=True,
    +):
    +    parser = make_parser()
    +    parser.setContentHandler(handler)
    +    parser.setErrorHandler(errorHandler)
    +    parser.forbid_dtd = forbid_dtd
    +    parser.forbid_entities = forbid_entities
    +    parser.forbid_external = forbid_external
    +    parser.parse(source)
    +
    +
    +def parseString(
    +    string,
    +    handler,
    +    errorHandler=_ErrorHandler(),
    +    forbid_dtd=False,
    +    forbid_entities=True,
    +    forbid_external=True,
    +):
    +    from io import BytesIO
    +
    +    if errorHandler is None:
    +        errorHandler = _ErrorHandler()
    +    parser = make_parser()
    +    parser.setContentHandler(handler)
    +    parser.setErrorHandler(errorHandler)
    +    parser.forbid_dtd = forbid_dtd
    +    parser.forbid_entities = forbid_entities
    +    parser.forbid_external = forbid_external
    +
    +    inpsrc = _InputSource()
    +    inpsrc.setByteStream(BytesIO(string))
    +    parser.parse(inpsrc)
    +
    +
    +def make_parser(parser_list=[]):
    +    return expatreader.create_parser()
    diff --git a/deployment-apps/metricator-for-nmon/lib/defusedxml/xmlrpc.py b/deployment-apps/metricator-for-nmon/lib/defusedxml/xmlrpc.py
    new file mode 100644
    index 0000000..fbc674d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/defusedxml/xmlrpc.py
    @@ -0,0 +1,153 @@
    +# defusedxml
    +#
    +# Copyright (c) 2013 by Christian Heimes <christian@python.org>
    +# Licensed to PSF under a Contributor Agreement.
    +# See https://www.python.org/psf/license for licensing details.
    +"""Defused xmlrpclib
    +
    +Also defuses gzip bomb
    +"""
    +from __future__ import print_function, absolute_import
    +
    +import io
    +
    +from .common import DTDForbidden, EntitiesForbidden, ExternalReferenceForbidden, PY3
    +
    +if PY3:
    +    __origin__ = "xmlrpc.client"
    +    from xmlrpc.client import ExpatParser
    +    from xmlrpc import client as xmlrpc_client
    +    from xmlrpc import server as xmlrpc_server
    +    from xmlrpc.client import gzip_decode as _orig_gzip_decode
    +    from xmlrpc.client import GzipDecodedResponse as _OrigGzipDecodedResponse
    +else:
    +    __origin__ = "xmlrpclib"
    +    from xmlrpclib import ExpatParser
    +    import xmlrpclib as xmlrpc_client
    +
    +    xmlrpc_server = None
    +    from xmlrpclib import gzip_decode as _orig_gzip_decode
    +    from xmlrpclib import GzipDecodedResponse as _OrigGzipDecodedResponse
    +
    +try:
    +    import gzip
    +except ImportError:  # pragma: no cover
    +    gzip = None
    +
    +
    +# Limit maximum request size to prevent resource exhaustion DoS
    +# Also used to limit maximum amount of gzip decoded data in order to prevent
    +# decompression bombs
    +# A value of -1 or smaller disables the limit
    +MAX_DATA = 30 * 1024 * 1024  # 30 MB
    +
    +
    +def defused_gzip_decode(data, limit=None):
    +    """gzip encoded data -> unencoded data
    +
    +    Decode data using the gzip content encoding as described in RFC 1952
    +    """
    +    if not gzip:  # pragma: no cover
    +        raise NotImplementedError
    +    if limit is None:
    +        limit = MAX_DATA
    +    f = io.BytesIO(data)
    +    gzf = gzip.GzipFile(mode="rb", fileobj=f)
    +    try:
    +        if limit < 0:  # no limit
    +            decoded = gzf.read()
    +        else:
    +            decoded = gzf.read(limit + 1)
    +    except IOError:  # pragma: no cover
    +        raise ValueError("invalid data")
    +    f.close()
    +    gzf.close()
    +    if limit >= 0 and len(decoded) > limit:
    +        raise ValueError("max gzipped payload length exceeded")
    +    return decoded
    +
    +
    +class DefusedGzipDecodedResponse(gzip.GzipFile if gzip else object):
    +    """a file-like object to decode a response encoded with the gzip
    +    method, as described in RFC 1952.
    +    """
    +
    +    def __init__(self, response, limit=None):
    +        # response doesn't support tell() and read(), required by
    +        # GzipFile
    +        if not gzip:  # pragma: no cover
    +            raise NotImplementedError
    +        self.limit = limit = limit if limit is not None else MAX_DATA
    +        if limit < 0:  # no limit
    +            data = response.read()
    +            self.readlength = None
    +        else:
    +            data = response.read(limit + 1)
    +            self.readlength = 0
    +        if limit >= 0 and len(data) > limit:
    +            raise ValueError("max payload length exceeded")
    +        self.stringio = io.BytesIO(data)
    +        gzip.GzipFile.__init__(self, mode="rb", fileobj=self.stringio)
    +
    +    def read(self, n):
    +        if self.limit >= 0:
    +            left = self.limit - self.readlength
    +            n = min(n, left + 1)
    +            data = gzip.GzipFile.read(self, n)
    +            self.readlength += len(data)
    +            if self.readlength > self.limit:
    +                raise ValueError("max payload length exceeded")
    +            return data
    +        else:
    +            return gzip.GzipFile.read(self, n)
    +
    +    def close(self):
    +        gzip.GzipFile.close(self)
    +        self.stringio.close()
    +
    +
    +class DefusedExpatParser(ExpatParser):
    +    def __init__(self, target, forbid_dtd=False, forbid_entities=True, forbid_external=True):
    +        ExpatParser.__init__(self, target)
    +        self.forbid_dtd = forbid_dtd
    +        self.forbid_entities = forbid_entities
    +        self.forbid_external = forbid_external
    +        parser = self._parser
    +        if self.forbid_dtd:
    +            parser.StartDoctypeDeclHandler = self.defused_start_doctype_decl
    +        if self.forbid_entities:
    +            parser.EntityDeclHandler = self.defused_entity_decl
    +            parser.UnparsedEntityDeclHandler = self.defused_unparsed_entity_decl
    +        if self.forbid_external:
    +            parser.ExternalEntityRefHandler = self.defused_external_entity_ref_handler
    +
    +    def defused_start_doctype_decl(self, name, sysid, pubid, has_internal_subset):
    +        raise DTDForbidden(name, sysid, pubid)
    +
    +    def defused_entity_decl(
    +        self, name, is_parameter_entity, value, base, sysid, pubid, notation_name
    +    ):
    +        raise EntitiesForbidden(name, value, base, sysid, pubid, notation_name)
    +
    +    def defused_unparsed_entity_decl(self, name, base, sysid, pubid, notation_name):
    +        # expat 1.2
    +        raise EntitiesForbidden(name, None, base, sysid, pubid, notation_name)  # pragma: no cover
    +
    +    def defused_external_entity_ref_handler(self, context, base, sysid, pubid):
    +        raise ExternalReferenceForbidden(context, base, sysid, pubid)
    +
    +
    +def monkey_patch():
    +    xmlrpc_client.FastParser = DefusedExpatParser
    +    xmlrpc_client.GzipDecodedResponse = DefusedGzipDecodedResponse
    +    xmlrpc_client.gzip_decode = defused_gzip_decode
    +    if xmlrpc_server:
    +        xmlrpc_server.gzip_decode = defused_gzip_decode
    +
    +
    +def unmonkey_patch():
    +    xmlrpc_client.FastParser = None
    +    xmlrpc_client.GzipDecodedResponse = _OrigGzipDecodedResponse
    +    xmlrpc_client.gzip_decode = _orig_gzip_decode
    +    if xmlrpc_server:
    +        xmlrpc_server.gzip_decode = _orig_gzip_decode
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/INSTALLER b/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/INSTALLER
    new file mode 100644
    index 0000000..a1b589e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/INSTALLER
    @@ -0,0 +1 @@
    +pip
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/LICENSE.md b/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/LICENSE.md
    new file mode 100644
    index 0000000..b6f8732
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/LICENSE.md
    @@ -0,0 +1,29 @@
    +BSD 3-Clause License
    +
    +Copyright (c) 2013-2021, Kim Davies
    +All rights reserved.
    +
    +Redistribution and use in source and binary forms, with or without
    +modification, are permitted provided that the following conditions are met:
    +
    +1. Redistributions of source code must retain the above copyright notice, this
    +   list of conditions and the following disclaimer.
    +
    +2. Redistributions in binary form must reproduce the above copyright notice,
    +   this list of conditions and the following disclaimer in the documentation
    +   and/or other materials provided with the distribution.
    +
    +3. Neither the name of the copyright holder nor the names of its
    +   contributors may be used to endorse or promote products derived from
    +   this software without specific prior written permission.
    +
    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/METADATA b/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/METADATA
    new file mode 100644
    index 0000000..07f6193
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/METADATA
    @@ -0,0 +1,242 @@
    +Metadata-Version: 2.1
    +Name: idna
    +Version: 3.4
    +Summary: Internationalized Domain Names in Applications (IDNA)
    +Author-email: Kim Davies <kim@cynosure.com.au>
    +Requires-Python: >=3.5
    +Description-Content-Type: text/x-rst
    +Classifier: Development Status :: 5 - Production/Stable
    +Classifier: Intended Audience :: Developers
    +Classifier: Intended Audience :: System Administrators
    +Classifier: License :: OSI Approved :: BSD License
    +Classifier: Operating System :: OS Independent
    +Classifier: Programming Language :: Python
    +Classifier: Programming Language :: Python :: 3
    +Classifier: Programming Language :: Python :: 3 :: Only
    +Classifier: Programming Language :: Python :: 3.5
    +Classifier: Programming Language :: Python :: 3.6
    +Classifier: Programming Language :: Python :: 3.7
    +Classifier: Programming Language :: Python :: 3.8
    +Classifier: Programming Language :: Python :: 3.9
    +Classifier: Programming Language :: Python :: 3.10
    +Classifier: Programming Language :: Python :: 3.11
    +Classifier: Programming Language :: Python :: Implementation :: CPython
    +Classifier: Programming Language :: Python :: Implementation :: PyPy
    +Classifier: Topic :: Internet :: Name Service (DNS)
    +Classifier: Topic :: Software Development :: Libraries :: Python Modules
    +Classifier: Topic :: Utilities
    +Project-URL: Changelog, https://github.com/kjd/idna/blob/master/HISTORY.rst
    +Project-URL: Issue tracker, https://github.com/kjd/idna/issues
    +Project-URL: Source, https://github.com/kjd/idna
    +
    +Internationalized Domain Names in Applications (IDNA)
    +=====================================================
    +
    +Support for the Internationalized Domain Names in
    +Applications (IDNA) protocol as specified in `RFC 5891
    +<https://tools.ietf.org/html/rfc5891>`_. This is the latest version of
    +the protocol and is sometimes referred to as “IDNA 2008”.
    +
    +This library also provides support for Unicode Technical
    +Standard 46, `Unicode IDNA Compatibility Processing
    +<https://unicode.org/reports/tr46/>`_.
    +
    +This acts as a suitable replacement for the “encodings.idna”
    +module that comes with the Python standard library, but which
    +only supports the older superseded IDNA specification (`RFC 3490
    +<https://tools.ietf.org/html/rfc3490>`_).
    +
    +Basic functions are simply executed:
    +
    +.. code-block:: pycon
    +
    +    >>> import idna
    +    >>> idna.encode('ドメイン.テスト')
    +    b'xn--eckwd4c7c.xn--zckzah'
    +    >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah'))
    +    ドメイン.テスト
    +
    +
    +Installation
    +------------
    +
    +This package is available for installation from PyPI:
    +
    +.. code-block:: bash
    +
    +    $ python3 -m pip install idna
    +
    +
    +Usage
    +-----
    +
    +For typical usage, the ``encode`` and ``decode`` functions will take a
    +domain name argument and perform a conversion to A-labels or U-labels
    +respectively.
    +
    +.. code-block:: pycon
    +
    +    >>> import idna
    +    >>> idna.encode('ドメイン.テスト')
    +    b'xn--eckwd4c7c.xn--zckzah'
    +    >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah'))
    +    ドメイン.テスト
    +
    +You may use the codec encoding and decoding methods using the
    +``idna.codec`` module:
    +
    +.. code-block:: pycon
    +
    +    >>> import idna.codec
    +    >>> print('домен.испытание'.encode('idna'))
    +    b'xn--d1acufc.xn--80akhbyknj4f'
    +    >>> print(b'xn--d1acufc.xn--80akhbyknj4f'.decode('idna'))
    +    домен.испытание
    +
    +Conversions can be applied at a per-label basis using the ``ulabel`` or
    +``alabel`` functions if necessary:
    +
    +.. code-block:: pycon
    +
    +    >>> idna.alabel('测试')
    +    b'xn--0zwm56d'
    +
    +Compatibility Mapping (UTS #46)
    ++++++++++++++++++++++++++++++++
    +
    +As described in `RFC 5895 <https://tools.ietf.org/html/rfc5895>`_, the
    +IDNA specification does not normalize input from different potential
    +ways a user may input a domain name. This functionality, known as
    +a “mapping”, is considered by the specification to be a local
    +user-interface issue distinct from IDNA conversion functionality.
    +
    +This library provides one such mapping, that was developed by the
    +Unicode Consortium. Known as `Unicode IDNA Compatibility Processing
    +<https://unicode.org/reports/tr46/>`_, it provides for both a regular
    +mapping for typical applications, as well as a transitional mapping to
    +help migrate from older IDNA 2003 applications.
    +
    +For example, “Königsgäßchen” is not a permissible label as *LATIN
    +CAPITAL LETTER K* is not allowed (nor are capital letters in general).
    +UTS 46 will convert this into lower case prior to applying the IDNA
    +conversion.
    +
    +.. code-block:: pycon
    +
    +    >>> import idna
    +    >>> idna.encode('Königsgäßchen')
    +    ...
    +    idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'Königsgäßchen' not allowed
    +    >>> idna.encode('Königsgäßchen', uts46=True)
    +    b'xn--knigsgchen-b4a3dun'
    +    >>> print(idna.decode('xn--knigsgchen-b4a3dun'))
    +    königsgäßchen
    +
    +Transitional processing provides conversions to help transition from
    +the older 2003 standard to the current standard. For example, in the
    +original IDNA specification, the *LATIN SMALL LETTER SHARP S* (ß) was
    +converted into two *LATIN SMALL LETTER S* (ss), whereas in the current
    +IDNA specification this conversion is not performed.
    +
    +.. code-block:: pycon
    +
    +    >>> idna.encode('Königsgäßchen', uts46=True, transitional=True)
    +    'xn--knigsgsschen-lcb0w'
    +
    +Implementors should use transitional processing with caution, only in
    +rare cases where conversion from legacy labels to current labels must be
    +performed (i.e. IDNA implementations that pre-date 2008). For typical
    +applications that just need to convert labels, transitional processing
    +is unlikely to be beneficial and could produce unexpected incompatible
    +results.
    +
    +``encodings.idna`` Compatibility
    +++++++++++++++++++++++++++++++++
    +
    +Function calls from the Python built-in ``encodings.idna`` module are
    +mapped to their IDNA 2008 equivalents using the ``idna.compat`` module.
    +Simply substitute the ``import`` clause in your code to refer to the new
    +module name.
    +
    +Exceptions
    +----------
    +
    +All errors raised during the conversion following the specification
    +should raise an exception derived from the ``idna.IDNAError`` base
    +class.
    +
    +More specific exceptions that may be generated as ``idna.IDNABidiError``
    +when the error reflects an illegal combination of left-to-right and
    +right-to-left characters in a label; ``idna.InvalidCodepoint`` when
    +a specific codepoint is an illegal character in an IDN label (i.e.
    +INVALID); and ``idna.InvalidCodepointContext`` when the codepoint is
    +illegal based on its positional context (i.e. it is CONTEXTO or CONTEXTJ
    +but the contextual requirements are not satisfied.)
    +
    +Building and Diagnostics
    +------------------------
    +
    +The IDNA and UTS 46 functionality relies upon pre-calculated lookup
    +tables for performance. These tables are derived from computing against
    +eligibility criteria in the respective standards. These tables are
    +computed using the command-line script ``tools/idna-data``.
    +
    +This tool will fetch relevant codepoint data from the Unicode repository
    +and perform the required calculations to identify eligibility. There are
    +three main modes:
    +
    +* ``idna-data make-libdata``. Generates ``idnadata.py`` and
    +  ``uts46data.py``, the pre-calculated lookup tables using for IDNA and
    +  UTS 46 conversions. Implementors who wish to track this library against
    +  a different Unicode version may use this tool to manually generate a
    +  different version of the ``idnadata.py`` and ``uts46data.py`` files.
    +
    +* ``idna-data make-table``. Generate a table of the IDNA disposition
    +  (e.g. PVALID, CONTEXTJ, CONTEXTO) in the format found in Appendix
    +  B.1 of RFC 5892 and the pre-computed tables published by `IANA
    +  <https://www.iana.org/>`_.
    +
    +* ``idna-data U+0061``. Prints debugging output on the various
    +  properties associated with an individual Unicode codepoint (in this
    +  case, U+0061), that are used to assess the IDNA and UTS 46 status of a
    +  codepoint. This is helpful in debugging or analysis.
    +
    +The tool accepts a number of arguments, described using ``idna-data
    +-h``. Most notably, the ``--version`` argument allows the specification
    +of the version of Unicode to use in computing the table data. For
    +example, ``idna-data --version 9.0.0 make-libdata`` will generate
    +library data against Unicode 9.0.0.
    +
    +
    +Additional Notes
    +----------------
    +
    +* **Packages**. The latest tagged release version is published in the
    +  `Python Package Index <https://pypi.org/project/idna/>`_.
    +
    +* **Version support**. This library supports Python 3.5 and higher.
    +  As this library serves as a low-level toolkit for a variety of
    +  applications, many of which strive for broad compatibility with older
    +  Python versions, there is no rush to remove older intepreter support.
    +  Removing support for older versions should be well justified in that the
    +  maintenance burden has become too high.
    +
    +* **Python 2**. Python 2 is supported by version 2.x of this library.
    +  While active development of the version 2.x series has ended, notable
    +  issues being corrected may be backported to 2.x. Use "idna<3" in your
    +  requirements file if you need this library for a Python 2 application.
    +
    +* **Testing**. The library has a test suite based on each rule of the
    +  IDNA specification, as well as tests that are provided as part of the
    +  Unicode Technical Standard 46, `Unicode IDNA Compatibility Processing
    +  <https://unicode.org/reports/tr46/>`_.
    +
    +* **Emoji**. It is an occasional request to support emoji domains in
    +  this library. Encoding of symbols like emoji is expressly prohibited by
    +  the technical standard IDNA 2008 and emoji domains are broadly phased
    +  out across the domain industry due to associated security risks. For
    +  now, applications that wish need to support these non-compliant labels
    +  may wish to consider trying the encode/decode operation in this library
    +  first, and then falling back to using `encodings.idna`. See `the Github
    +  project <https://github.com/kjd/idna/issues/18>`_ for more discussion.
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/RECORD b/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/RECORD
    new file mode 100644
    index 0000000..ba63a2f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/RECORD
    @@ -0,0 +1,14 @@
    +idna-3.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
    +idna-3.4.dist-info/LICENSE.md,sha256=otbk2UC9JNvnuWRc3hmpeSzFHbeuDVrNMBrIYMqj6DY,1523
    +idna-3.4.dist-info/METADATA,sha256=8aLSf9MFS7oB26pZh2hprg7eJp0UJSc-3rpf_evp4DA,9830
    +idna-3.4.dist-info/RECORD,,
    +idna-3.4.dist-info/WHEEL,sha256=4TfKIB_xu-04bc2iKz6_zFt-gEFEEDU_31HGhqzOCE8,81
    +idna/__init__.py,sha256=KJQN1eQBr8iIK5SKrJ47lXvxG0BJ7Lm38W4zT0v_8lk,849
    +idna/codec.py,sha256=6ly5odKfqrytKT9_7UrlGklHnf1DSK2r9C6cSM4sa28,3374
    +idna/compat.py,sha256=0_sOEUMT4CVw9doD3vyRhX80X19PwqFoUBs7gWsFME4,321
    +idna/core.py,sha256=1JxchwKzkxBSn7R_oCE12oBu3eVux0VzdxolmIad24M,12950
    +idna/idnadata.py,sha256=xUjqKqiJV8Ho_XzBpAtv5JFoVPSupK-SUXvtjygUHqw,44375
    +idna/intranges.py,sha256=YBr4fRYuWH7kTKS2tXlFjM24ZF1Pdvcir-aywniInqg,1881
    +idna/package_data.py,sha256=C_jHJzmX8PI4xq0jpzmcTMxpb5lDsq4o5VyxQzlVrZE,21
    +idna/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
    +idna/uts46data.py,sha256=zvjZU24s58_uAS850Mcd0NnD0X7_gCMAMjzWNIeUJdc,206539
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/WHEEL b/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/WHEEL
    new file mode 100644
    index 0000000..668ba4d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna-3.4.dist-info/WHEEL
    @@ -0,0 +1,4 @@
    +Wheel-Version: 1.0
    +Generator: flit 3.7.1
    +Root-Is-Purelib: true
    +Tag: py3-none-any
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna/__init__.py b/deployment-apps/metricator-for-nmon/lib/idna/__init__.py
    new file mode 100644
    index 0000000..a40eeaf
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna/__init__.py
    @@ -0,0 +1,44 @@
    +from .package_data import __version__
    +from .core import (
    +    IDNABidiError,
    +    IDNAError,
    +    InvalidCodepoint,
    +    InvalidCodepointContext,
    +    alabel,
    +    check_bidi,
    +    check_hyphen_ok,
    +    check_initial_combiner,
    +    check_label,
    +    check_nfc,
    +    decode,
    +    encode,
    +    ulabel,
    +    uts46_remap,
    +    valid_contextj,
    +    valid_contexto,
    +    valid_label_length,
    +    valid_string_length,
    +)
    +from .intranges import intranges_contain
    +
    +__all__ = [
    +    "IDNABidiError",
    +    "IDNAError",
    +    "InvalidCodepoint",
    +    "InvalidCodepointContext",
    +    "alabel",
    +    "check_bidi",
    +    "check_hyphen_ok",
    +    "check_initial_combiner",
    +    "check_label",
    +    "check_nfc",
    +    "decode",
    +    "encode",
    +    "intranges_contain",
    +    "ulabel",
    +    "uts46_remap",
    +    "valid_contextj",
    +    "valid_contexto",
    +    "valid_label_length",
    +    "valid_string_length",
    +]
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna/codec.py b/deployment-apps/metricator-for-nmon/lib/idna/codec.py
    new file mode 100644
    index 0000000..1ca9ba6
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna/codec.py
    @@ -0,0 +1,112 @@
    +from .core import encode, decode, alabel, ulabel, IDNAError
    +import codecs
    +import re
    +from typing import Tuple, Optional
    +
    +_unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]')
    +
    +class Codec(codecs.Codec):
    +
    +    def encode(self, data: str, errors: str = 'strict') -> Tuple[bytes, int]:
    +        if errors != 'strict':
    +            raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
    +
    +        if not data:
    +            return b"", 0
    +
    +        return encode(data), len(data)
    +
    +    def decode(self, data: bytes, errors: str = 'strict') -> Tuple[str, int]:
    +        if errors != 'strict':
    +            raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
    +
    +        if not data:
    +            return '', 0
    +
    +        return decode(data), len(data)
    +
    +class IncrementalEncoder(codecs.BufferedIncrementalEncoder):
    +    def _buffer_encode(self, data: str, errors: str, final: bool) -> Tuple[str, int]:  # type: ignore
    +        if errors != 'strict':
    +            raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
    +
    +        if not data:
    +            return "", 0
    +
    +        labels = _unicode_dots_re.split(data)
    +        trailing_dot = ''
    +        if labels:
    +            if not labels[-1]:
    +                trailing_dot = '.'
    +                del labels[-1]
    +            elif not final:
    +                # Keep potentially unfinished label until the next call
    +                del labels[-1]
    +                if labels:
    +                    trailing_dot = '.'
    +
    +        result = []
    +        size = 0
    +        for label in labels:
    +            result.append(alabel(label))
    +            if size:
    +                size += 1
    +            size += len(label)
    +
    +        # Join with U+002E
    +        result_str = '.'.join(result) + trailing_dot  # type: ignore
    +        size += len(trailing_dot)
    +        return result_str, size
    +
    +class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
    +    def _buffer_decode(self, data: str, errors: str, final: bool) -> Tuple[str, int]:  # type: ignore
    +        if errors != 'strict':
    +            raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
    +
    +        if not data:
    +            return ('', 0)
    +
    +        labels = _unicode_dots_re.split(data)
    +        trailing_dot = ''
    +        if labels:
    +            if not labels[-1]:
    +                trailing_dot = '.'
    +                del labels[-1]
    +            elif not final:
    +                # Keep potentially unfinished label until the next call
    +                del labels[-1]
    +                if labels:
    +                    trailing_dot = '.'
    +
    +        result = []
    +        size = 0
    +        for label in labels:
    +            result.append(ulabel(label))
    +            if size:
    +                size += 1
    +            size += len(label)
    +
    +        result_str = '.'.join(result) + trailing_dot
    +        size += len(trailing_dot)
    +        return (result_str, size)
    +
    +
    +class StreamWriter(Codec, codecs.StreamWriter):
    +    pass
    +
    +
    +class StreamReader(Codec, codecs.StreamReader):
    +    pass
    +
    +
    +def getregentry() -> codecs.CodecInfo:
    +    # Compatibility as a search_function for codecs.register()
    +    return codecs.CodecInfo(
    +        name='idna',
    +        encode=Codec().encode,  # type: ignore
    +        decode=Codec().decode,  # type: ignore
    +        incrementalencoder=IncrementalEncoder,
    +        incrementaldecoder=IncrementalDecoder,
    +        streamwriter=StreamWriter,
    +        streamreader=StreamReader,
    +    )
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna/compat.py b/deployment-apps/metricator-for-nmon/lib/idna/compat.py
    new file mode 100644
    index 0000000..786e6bd
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna/compat.py
    @@ -0,0 +1,13 @@
    +from .core import *
    +from .codec import *
    +from typing import Any, Union
    +
    +def ToASCII(label: str) -> bytes:
    +    return encode(label)
    +
    +def ToUnicode(label: Union[bytes, bytearray]) -> str:
    +    return decode(label)
    +
    +def nameprep(s: Any) -> None:
    +    raise NotImplementedError('IDNA 2008 does not utilise nameprep protocol')
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna/core.py b/deployment-apps/metricator-for-nmon/lib/idna/core.py
    new file mode 100644
    index 0000000..4f30037
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna/core.py
    @@ -0,0 +1,400 @@
    +from . import idnadata
    +import bisect
    +import unicodedata
    +import re
    +from typing import Union, Optional
    +from .intranges import intranges_contain
    +
    +_virama_combining_class = 9
    +_alabel_prefix = b'xn--'
    +_unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]')
    +
    +class IDNAError(UnicodeError):
    +    """ Base exception for all IDNA-encoding related problems """
    +    pass
    +
    +
    +class IDNABidiError(IDNAError):
    +    """ Exception when bidirectional requirements are not satisfied """
    +    pass
    +
    +
    +class InvalidCodepoint(IDNAError):
    +    """ Exception when a disallowed or unallocated codepoint is used """
    +    pass
    +
    +
    +class InvalidCodepointContext(IDNAError):
    +    """ Exception when the codepoint is not valid in the context it is used """
    +    pass
    +
    +
    +def _combining_class(cp: int) -> int:
    +    v = unicodedata.combining(chr(cp))
    +    if v == 0:
    +        if not unicodedata.name(chr(cp)):
    +            raise ValueError('Unknown character in unicodedata')
    +    return v
    +
    +def _is_script(cp: str, script: str) -> bool:
    +    return intranges_contain(ord(cp), idnadata.scripts[script])
    +
    +def _punycode(s: str) -> bytes:
    +    return s.encode('punycode')
    +
    +def _unot(s: int) -> str:
    +    return 'U+{:04X}'.format(s)
    +
    +
    +def valid_label_length(label: Union[bytes, str]) -> bool:
    +    if len(label) > 63:
    +        return False
    +    return True
    +
    +
    +def valid_string_length(label: Union[bytes, str], trailing_dot: bool) -> bool:
    +    if len(label) > (254 if trailing_dot else 253):
    +        return False
    +    return True
    +
    +
    +def check_bidi(label: str, check_ltr: bool = False) -> bool:
    +    # Bidi rules should only be applied if string contains RTL characters
    +    bidi_label = False
    +    for (idx, cp) in enumerate(label, 1):
    +        direction = unicodedata.bidirectional(cp)
    +        if direction == '':
    +            # String likely comes from a newer version of Unicode
    +            raise IDNABidiError('Unknown directionality in label {} at position {}'.format(repr(label), idx))
    +        if direction in ['R', 'AL', 'AN']:
    +            bidi_label = True
    +    if not bidi_label and not check_ltr:
    +        return True
    +
    +    # Bidi rule 1
    +    direction = unicodedata.bidirectional(label[0])
    +    if direction in ['R', 'AL']:
    +        rtl = True
    +    elif direction == 'L':
    +        rtl = False
    +    else:
    +        raise IDNABidiError('First codepoint in label {} must be directionality L, R or AL'.format(repr(label)))
    +
    +    valid_ending = False
    +    number_type = None  # type: Optional[str]
    +    for (idx, cp) in enumerate(label, 1):
    +        direction = unicodedata.bidirectional(cp)
    +
    +        if rtl:
    +            # Bidi rule 2
    +            if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']:
    +                raise IDNABidiError('Invalid direction for codepoint at position {} in a right-to-left label'.format(idx))
    +            # Bidi rule 3
    +            if direction in ['R', 'AL', 'EN', 'AN']:
    +                valid_ending = True
    +            elif direction != 'NSM':
    +                valid_ending = False
    +            # Bidi rule 4
    +            if direction in ['AN', 'EN']:
    +                if not number_type:
    +                    number_type = direction
    +                else:
    +                    if number_type != direction:
    +                        raise IDNABidiError('Can not mix numeral types in a right-to-left label')
    +        else:
    +            # Bidi rule 5
    +            if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']:
    +                raise IDNABidiError('Invalid direction for codepoint at position {} in a left-to-right label'.format(idx))
    +            # Bidi rule 6
    +            if direction in ['L', 'EN']:
    +                valid_ending = True
    +            elif direction != 'NSM':
    +                valid_ending = False
    +
    +    if not valid_ending:
    +        raise IDNABidiError('Label ends with illegal codepoint directionality')
    +
    +    return True
    +
    +
    +def check_initial_combiner(label: str) -> bool:
    +    if unicodedata.category(label[0])[0] == 'M':
    +        raise IDNAError('Label begins with an illegal combining character')
    +    return True
    +
    +
    +def check_hyphen_ok(label: str) -> bool:
    +    if label[2:4] == '--':
    +        raise IDNAError('Label has disallowed hyphens in 3rd and 4th position')
    +    if label[0] == '-' or label[-1] == '-':
    +        raise IDNAError('Label must not start or end with a hyphen')
    +    return True
    +
    +
    +def check_nfc(label: str) -> None:
    +    if unicodedata.normalize('NFC', label) != label:
    +        raise IDNAError('Label must be in Normalization Form C')
    +
    +
    +def valid_contextj(label: str, pos: int) -> bool:
    +    cp_value = ord(label[pos])
    +
    +    if cp_value == 0x200c:
    +
    +        if pos > 0:
    +            if _combining_class(ord(label[pos - 1])) == _virama_combining_class:
    +                return True
    +
    +        ok = False
    +        for i in range(pos-1, -1, -1):
    +            joining_type = idnadata.joining_types.get(ord(label[i]))
    +            if joining_type == ord('T'):
    +                continue
    +            if joining_type in [ord('L'), ord('D')]:
    +                ok = True
    +                break
    +
    +        if not ok:
    +            return False
    +
    +        ok = False
    +        for i in range(pos+1, len(label)):
    +            joining_type = idnadata.joining_types.get(ord(label[i]))
    +            if joining_type == ord('T'):
    +                continue
    +            if joining_type in [ord('R'), ord('D')]:
    +                ok = True
    +                break
    +        return ok
    +
    +    if cp_value == 0x200d:
    +
    +        if pos > 0:
    +            if _combining_class(ord(label[pos - 1])) == _virama_combining_class:
    +                return True
    +        return False
    +
    +    else:
    +
    +        return False
    +
    +
    +def valid_contexto(label: str, pos: int, exception: bool = False) -> bool:
    +    cp_value = ord(label[pos])
    +
    +    if cp_value == 0x00b7:
    +        if 0 < pos < len(label)-1:
    +            if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c:
    +                return True
    +        return False
    +
    +    elif cp_value == 0x0375:
    +        if pos < len(label)-1 and len(label) > 1:
    +            return _is_script(label[pos + 1], 'Greek')
    +        return False
    +
    +    elif cp_value == 0x05f3 or cp_value == 0x05f4:
    +        if pos > 0:
    +            return _is_script(label[pos - 1], 'Hebrew')
    +        return False
    +
    +    elif cp_value == 0x30fb:
    +        for cp in label:
    +            if cp == '\u30fb':
    +                continue
    +            if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'):
    +                return True
    +        return False
    +
    +    elif 0x660 <= cp_value <= 0x669:
    +        for cp in label:
    +            if 0x6f0 <= ord(cp) <= 0x06f9:
    +                return False
    +        return True
    +
    +    elif 0x6f0 <= cp_value <= 0x6f9:
    +        for cp in label:
    +            if 0x660 <= ord(cp) <= 0x0669:
    +                return False
    +        return True
    +
    +    return False
    +
    +
    +def check_label(label: Union[str, bytes, bytearray]) -> None:
    +    if isinstance(label, (bytes, bytearray)):
    +        label = label.decode('utf-8')
    +    if len(label) == 0:
    +        raise IDNAError('Empty Label')
    +
    +    check_nfc(label)
    +    check_hyphen_ok(label)
    +    check_initial_combiner(label)
    +
    +    for (pos, cp) in enumerate(label):
    +        cp_value = ord(cp)
    +        if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']):
    +            continue
    +        elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']):
    +            try:
    +                if not valid_contextj(label, pos):
    +                    raise InvalidCodepointContext('Joiner {} not allowed at position {} in {}'.format(
    +                        _unot(cp_value), pos+1, repr(label)))
    +            except ValueError:
    +                raise IDNAError('Unknown codepoint adjacent to joiner {} at position {} in {}'.format(
    +                    _unot(cp_value), pos+1, repr(label)))
    +        elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']):
    +            if not valid_contexto(label, pos):
    +                raise InvalidCodepointContext('Codepoint {} not allowed at position {} in {}'.format(_unot(cp_value), pos+1, repr(label)))
    +        else:
    +            raise InvalidCodepoint('Codepoint {} at position {} of {} not allowed'.format(_unot(cp_value), pos+1, repr(label)))
    +
    +    check_bidi(label)
    +
    +
    +def alabel(label: str) -> bytes:
    +    try:
    +        label_bytes = label.encode('ascii')
    +        ulabel(label_bytes)
    +        if not valid_label_length(label_bytes):
    +            raise IDNAError('Label too long')
    +        return label_bytes
    +    except UnicodeEncodeError:
    +        pass
    +
    +    if not label:
    +        raise IDNAError('No Input')
    +
    +    label = str(label)
    +    check_label(label)
    +    label_bytes = _punycode(label)
    +    label_bytes = _alabel_prefix + label_bytes
    +
    +    if not valid_label_length(label_bytes):
    +        raise IDNAError('Label too long')
    +
    +    return label_bytes
    +
    +
    +def ulabel(label: Union[str, bytes, bytearray]) -> str:
    +    if not isinstance(label, (bytes, bytearray)):
    +        try:
    +            label_bytes = label.encode('ascii')
    +        except UnicodeEncodeError:
    +            check_label(label)
    +            return label
    +    else:
    +        label_bytes = label
    +
    +    label_bytes = label_bytes.lower()
    +    if label_bytes.startswith(_alabel_prefix):
    +        label_bytes = label_bytes[len(_alabel_prefix):]
    +        if not label_bytes:
    +            raise IDNAError('Malformed A-label, no Punycode eligible content found')
    +        if label_bytes.decode('ascii')[-1] == '-':
    +            raise IDNAError('A-label must not end with a hyphen')
    +    else:
    +        check_label(label_bytes)
    +        return label_bytes.decode('ascii')
    +
    +    try:
    +        label = label_bytes.decode('punycode')
    +    except UnicodeError:
    +        raise IDNAError('Invalid A-label')
    +    check_label(label)
    +    return label
    +
    +
    +def uts46_remap(domain: str, std3_rules: bool = True, transitional: bool = False) -> str:
    +    """Re-map the characters in the string according to UTS46 processing."""
    +    from .uts46data import uts46data
    +    output = ''
    +
    +    for pos, char in enumerate(domain):
    +        code_point = ord(char)
    +        try:
    +            uts46row = uts46data[code_point if code_point < 256 else
    +                bisect.bisect_left(uts46data, (code_point, 'Z')) - 1]
    +            status = uts46row[1]
    +            replacement = None  # type: Optional[str]
    +            if len(uts46row) == 3:
    +                replacement = uts46row[2]  # type: ignore
    +            if (status == 'V' or
    +                    (status == 'D' and not transitional) or
    +                    (status == '3' and not std3_rules and replacement is None)):
    +                output += char
    +            elif replacement is not None and (status == 'M' or
    +                    (status == '3' and not std3_rules) or
    +                    (status == 'D' and transitional)):
    +                output += replacement
    +            elif status != 'I':
    +                raise IndexError()
    +        except IndexError:
    +            raise InvalidCodepoint(
    +                'Codepoint {} not allowed at position {} in {}'.format(
    +                _unot(code_point), pos + 1, repr(domain)))
    +
    +    return unicodedata.normalize('NFC', output)
    +
    +
    +def encode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool = False, std3_rules: bool = False, transitional: bool = False) -> bytes:
    +    if isinstance(s, (bytes, bytearray)):
    +        try:
    +            s = s.decode('ascii')
    +        except UnicodeDecodeError:
    +            raise IDNAError('should pass a unicode string to the function rather than a byte string.')
    +    if uts46:
    +        s = uts46_remap(s, std3_rules, transitional)
    +    trailing_dot = False
    +    result = []
    +    if strict:
    +        labels = s.split('.')
    +    else:
    +        labels = _unicode_dots_re.split(s)
    +    if not labels or labels == ['']:
    +        raise IDNAError('Empty domain')
    +    if labels[-1] == '':
    +        del labels[-1]
    +        trailing_dot = True
    +    for label in labels:
    +        s = alabel(label)
    +        if s:
    +            result.append(s)
    +        else:
    +            raise IDNAError('Empty label')
    +    if trailing_dot:
    +        result.append(b'')
    +    s = b'.'.join(result)
    +    if not valid_string_length(s, trailing_dot):
    +        raise IDNAError('Domain too long')
    +    return s
    +
    +
    +def decode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool = False, std3_rules: bool = False) -> str:
    +    try:
    +        if isinstance(s, (bytes, bytearray)):
    +            s = s.decode('ascii')
    +    except UnicodeDecodeError:
    +        raise IDNAError('Invalid ASCII in A-label')
    +    if uts46:
    +        s = uts46_remap(s, std3_rules, False)
    +    trailing_dot = False
    +    result = []
    +    if not strict:
    +        labels = _unicode_dots_re.split(s)
    +    else:
    +        labels = s.split('.')
    +    if not labels or labels == ['']:
    +        raise IDNAError('Empty domain')
    +    if not labels[-1]:
    +        del labels[-1]
    +        trailing_dot = True
    +    for label in labels:
    +        s = ulabel(label)
    +        if s:
    +            result.append(s)
    +        else:
    +            raise IDNAError('Empty label')
    +    if trailing_dot:
    +        result.append('')
    +    return '.'.join(result)
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna/idnadata.py b/deployment-apps/metricator-for-nmon/lib/idna/idnadata.py
    new file mode 100644
    index 0000000..67db462
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna/idnadata.py
    @@ -0,0 +1,2151 @@
    +# This file is automatically generated by tools/idna-data
    +
    +__version__ = '15.0.0'
    +scripts = {
    +    'Greek': (
    +        0x37000000374,
    +        0x37500000378,
    +        0x37a0000037e,
    +        0x37f00000380,
    +        0x38400000385,
    +        0x38600000387,
    +        0x3880000038b,
    +        0x38c0000038d,
    +        0x38e000003a2,
    +        0x3a3000003e2,
    +        0x3f000000400,
    +        0x1d2600001d2b,
    +        0x1d5d00001d62,
    +        0x1d6600001d6b,
    +        0x1dbf00001dc0,
    +        0x1f0000001f16,
    +        0x1f1800001f1e,
    +        0x1f2000001f46,
    +        0x1f4800001f4e,
    +        0x1f5000001f58,
    +        0x1f5900001f5a,
    +        0x1f5b00001f5c,
    +        0x1f5d00001f5e,
    +        0x1f5f00001f7e,
    +        0x1f8000001fb5,
    +        0x1fb600001fc5,
    +        0x1fc600001fd4,
    +        0x1fd600001fdc,
    +        0x1fdd00001ff0,
    +        0x1ff200001ff5,
    +        0x1ff600001fff,
    +        0x212600002127,
    +        0xab650000ab66,
    +        0x101400001018f,
    +        0x101a0000101a1,
    +        0x1d2000001d246,
    +    ),
    +    'Han': (
    +        0x2e8000002e9a,
    +        0x2e9b00002ef4,
    +        0x2f0000002fd6,
    +        0x300500003006,
    +        0x300700003008,
    +        0x30210000302a,
    +        0x30380000303c,
    +        0x340000004dc0,
    +        0x4e000000a000,
    +        0xf9000000fa6e,
    +        0xfa700000fada,
    +        0x16fe200016fe4,
    +        0x16ff000016ff2,
    +        0x200000002a6e0,
    +        0x2a7000002b73a,
    +        0x2b7400002b81e,
    +        0x2b8200002cea2,
    +        0x2ceb00002ebe1,
    +        0x2f8000002fa1e,
    +        0x300000003134b,
    +        0x31350000323b0,
    +    ),
    +    'Hebrew': (
    +        0x591000005c8,
    +        0x5d0000005eb,
    +        0x5ef000005f5,
    +        0xfb1d0000fb37,
    +        0xfb380000fb3d,
    +        0xfb3e0000fb3f,
    +        0xfb400000fb42,
    +        0xfb430000fb45,
    +        0xfb460000fb50,
    +    ),
    +    'Hiragana': (
    +        0x304100003097,
    +        0x309d000030a0,
    +        0x1b0010001b120,
    +        0x1b1320001b133,
    +        0x1b1500001b153,
    +        0x1f2000001f201,
    +    ),
    +    'Katakana': (
    +        0x30a1000030fb,
    +        0x30fd00003100,
    +        0x31f000003200,
    +        0x32d0000032ff,
    +        0x330000003358,
    +        0xff660000ff70,
    +        0xff710000ff9e,
    +        0x1aff00001aff4,
    +        0x1aff50001affc,
    +        0x1affd0001afff,
    +        0x1b0000001b001,
    +        0x1b1200001b123,
    +        0x1b1550001b156,
    +        0x1b1640001b168,
    +    ),
    +}
    +joining_types = {
    +    0x600: 85,
    +    0x601: 85,
    +    0x602: 85,
    +    0x603: 85,
    +    0x604: 85,
    +    0x605: 85,
    +    0x608: 85,
    +    0x60b: 85,
    +    0x620: 68,
    +    0x621: 85,
    +    0x622: 82,
    +    0x623: 82,
    +    0x624: 82,
    +    0x625: 82,
    +    0x626: 68,
    +    0x627: 82,
    +    0x628: 68,
    +    0x629: 82,
    +    0x62a: 68,
    +    0x62b: 68,
    +    0x62c: 68,
    +    0x62d: 68,
    +    0x62e: 68,
    +    0x62f: 82,
    +    0x630: 82,
    +    0x631: 82,
    +    0x632: 82,
    +    0x633: 68,
    +    0x634: 68,
    +    0x635: 68,
    +    0x636: 68,
    +    0x637: 68,
    +    0x638: 68,
    +    0x639: 68,
    +    0x63a: 68,
    +    0x63b: 68,
    +    0x63c: 68,
    +    0x63d: 68,
    +    0x63e: 68,
    +    0x63f: 68,
    +    0x640: 67,
    +    0x641: 68,
    +    0x642: 68,
    +    0x643: 68,
    +    0x644: 68,
    +    0x645: 68,
    +    0x646: 68,
    +    0x647: 68,
    +    0x648: 82,
    +    0x649: 68,
    +    0x64a: 68,
    +    0x66e: 68,
    +    0x66f: 68,
    +    0x671: 82,
    +    0x672: 82,
    +    0x673: 82,
    +    0x674: 85,
    +    0x675: 82,
    +    0x676: 82,
    +    0x677: 82,
    +    0x678: 68,
    +    0x679: 68,
    +    0x67a: 68,
    +    0x67b: 68,
    +    0x67c: 68,
    +    0x67d: 68,
    +    0x67e: 68,
    +    0x67f: 68,
    +    0x680: 68,
    +    0x681: 68,
    +    0x682: 68,
    +    0x683: 68,
    +    0x684: 68,
    +    0x685: 68,
    +    0x686: 68,
    +    0x687: 68,
    +    0x688: 82,
    +    0x689: 82,
    +    0x68a: 82,
    +    0x68b: 82,
    +    0x68c: 82,
    +    0x68d: 82,
    +    0x68e: 82,
    +    0x68f: 82,
    +    0x690: 82,
    +    0x691: 82,
    +    0x692: 82,
    +    0x693: 82,
    +    0x694: 82,
    +    0x695: 82,
    +    0x696: 82,
    +    0x697: 82,
    +    0x698: 82,
    +    0x699: 82,
    +    0x69a: 68,
    +    0x69b: 68,
    +    0x69c: 68,
    +    0x69d: 68,
    +    0x69e: 68,
    +    0x69f: 68,
    +    0x6a0: 68,
    +    0x6a1: 68,
    +    0x6a2: 68,
    +    0x6a3: 68,
    +    0x6a4: 68,
    +    0x6a5: 68,
    +    0x6a6: 68,
    +    0x6a7: 68,
    +    0x6a8: 68,
    +    0x6a9: 68,
    +    0x6aa: 68,
    +    0x6ab: 68,
    +    0x6ac: 68,
    +    0x6ad: 68,
    +    0x6ae: 68,
    +    0x6af: 68,
    +    0x6b0: 68,
    +    0x6b1: 68,
    +    0x6b2: 68,
    +    0x6b3: 68,
    +    0x6b4: 68,
    +    0x6b5: 68,
    +    0x6b6: 68,
    +    0x6b7: 68,
    +    0x6b8: 68,
    +    0x6b9: 68,
    +    0x6ba: 68,
    +    0x6bb: 68,
    +    0x6bc: 68,
    +    0x6bd: 68,
    +    0x6be: 68,
    +    0x6bf: 68,
    +    0x6c0: 82,
    +    0x6c1: 68,
    +    0x6c2: 68,
    +    0x6c3: 82,
    +    0x6c4: 82,
    +    0x6c5: 82,
    +    0x6c6: 82,
    +    0x6c7: 82,
    +    0x6c8: 82,
    +    0x6c9: 82,
    +    0x6ca: 82,
    +    0x6cb: 82,
    +    0x6cc: 68,
    +    0x6cd: 82,
    +    0x6ce: 68,
    +    0x6cf: 82,
    +    0x6d0: 68,
    +    0x6d1: 68,
    +    0x6d2: 82,
    +    0x6d3: 82,
    +    0x6d5: 82,
    +    0x6dd: 85,
    +    0x6ee: 82,
    +    0x6ef: 82,
    +    0x6fa: 68,
    +    0x6fb: 68,
    +    0x6fc: 68,
    +    0x6ff: 68,
    +    0x70f: 84,
    +    0x710: 82,
    +    0x712: 68,
    +    0x713: 68,
    +    0x714: 68,
    +    0x715: 82,
    +    0x716: 82,
    +    0x717: 82,
    +    0x718: 82,
    +    0x719: 82,
    +    0x71a: 68,
    +    0x71b: 68,
    +    0x71c: 68,
    +    0x71d: 68,
    +    0x71e: 82,
    +    0x71f: 68,
    +    0x720: 68,
    +    0x721: 68,
    +    0x722: 68,
    +    0x723: 68,
    +    0x724: 68,
    +    0x725: 68,
    +    0x726: 68,
    +    0x727: 68,
    +    0x728: 82,
    +    0x729: 68,
    +    0x72a: 82,
    +    0x72b: 68,
    +    0x72c: 82,
    +    0x72d: 68,
    +    0x72e: 68,
    +    0x72f: 82,
    +    0x74d: 82,
    +    0x74e: 68,
    +    0x74f: 68,
    +    0x750: 68,
    +    0x751: 68,
    +    0x752: 68,
    +    0x753: 68,
    +    0x754: 68,
    +    0x755: 68,
    +    0x756: 68,
    +    0x757: 68,
    +    0x758: 68,
    +    0x759: 82,
    +    0x75a: 82,
    +    0x75b: 82,
    +    0x75c: 68,
    +    0x75d: 68,
    +    0x75e: 68,
    +    0x75f: 68,
    +    0x760: 68,
    +    0x761: 68,
    +    0x762: 68,
    +    0x763: 68,
    +    0x764: 68,
    +    0x765: 68,
    +    0x766: 68,
    +    0x767: 68,
    +    0x768: 68,
    +    0x769: 68,
    +    0x76a: 68,
    +    0x76b: 82,
    +    0x76c: 82,
    +    0x76d: 68,
    +    0x76e: 68,
    +    0x76f: 68,
    +    0x770: 68,
    +    0x771: 82,
    +    0x772: 68,
    +    0x773: 82,
    +    0x774: 82,
    +    0x775: 68,
    +    0x776: 68,
    +    0x777: 68,
    +    0x778: 82,
    +    0x779: 82,
    +    0x77a: 68,
    +    0x77b: 68,
    +    0x77c: 68,
    +    0x77d: 68,
    +    0x77e: 68,
    +    0x77f: 68,
    +    0x7ca: 68,
    +    0x7cb: 68,
    +    0x7cc: 68,
    +    0x7cd: 68,
    +    0x7ce: 68,
    +    0x7cf: 68,
    +    0x7d0: 68,
    +    0x7d1: 68,
    +    0x7d2: 68,
    +    0x7d3: 68,
    +    0x7d4: 68,
    +    0x7d5: 68,
    +    0x7d6: 68,
    +    0x7d7: 68,
    +    0x7d8: 68,
    +    0x7d9: 68,
    +    0x7da: 68,
    +    0x7db: 68,
    +    0x7dc: 68,
    +    0x7dd: 68,
    +    0x7de: 68,
    +    0x7df: 68,
    +    0x7e0: 68,
    +    0x7e1: 68,
    +    0x7e2: 68,
    +    0x7e3: 68,
    +    0x7e4: 68,
    +    0x7e5: 68,
    +    0x7e6: 68,
    +    0x7e7: 68,
    +    0x7e8: 68,
    +    0x7e9: 68,
    +    0x7ea: 68,
    +    0x7fa: 67,
    +    0x840: 82,
    +    0x841: 68,
    +    0x842: 68,
    +    0x843: 68,
    +    0x844: 68,
    +    0x845: 68,
    +    0x846: 82,
    +    0x847: 82,
    +    0x848: 68,
    +    0x849: 82,
    +    0x84a: 68,
    +    0x84b: 68,
    +    0x84c: 68,
    +    0x84d: 68,
    +    0x84e: 68,
    +    0x84f: 68,
    +    0x850: 68,
    +    0x851: 68,
    +    0x852: 68,
    +    0x853: 68,
    +    0x854: 82,
    +    0x855: 68,
    +    0x856: 82,
    +    0x857: 82,
    +    0x858: 82,
    +    0x860: 68,
    +    0x861: 85,
    +    0x862: 68,
    +    0x863: 68,
    +    0x864: 68,
    +    0x865: 68,
    +    0x866: 85,
    +    0x867: 82,
    +    0x868: 68,
    +    0x869: 82,
    +    0x86a: 82,
    +    0x870: 82,
    +    0x871: 82,
    +    0x872: 82,
    +    0x873: 82,
    +    0x874: 82,
    +    0x875: 82,
    +    0x876: 82,
    +    0x877: 82,
    +    0x878: 82,
    +    0x879: 82,
    +    0x87a: 82,
    +    0x87b: 82,
    +    0x87c: 82,
    +    0x87d: 82,
    +    0x87e: 82,
    +    0x87f: 82,
    +    0x880: 82,
    +    0x881: 82,
    +    0x882: 82,
    +    0x883: 67,
    +    0x884: 67,
    +    0x885: 67,
    +    0x886: 68,
    +    0x887: 85,
    +    0x888: 85,
    +    0x889: 68,
    +    0x88a: 68,
    +    0x88b: 68,
    +    0x88c: 68,
    +    0x88d: 68,
    +    0x88e: 82,
    +    0x890: 85,
    +    0x891: 85,
    +    0x8a0: 68,
    +    0x8a1: 68,
    +    0x8a2: 68,
    +    0x8a3: 68,
    +    0x8a4: 68,
    +    0x8a5: 68,
    +    0x8a6: 68,
    +    0x8a7: 68,
    +    0x8a8: 68,
    +    0x8a9: 68,
    +    0x8aa: 82,
    +    0x8ab: 82,
    +    0x8ac: 82,
    +    0x8ad: 85,
    +    0x8ae: 82,
    +    0x8af: 68,
    +    0x8b0: 68,
    +    0x8b1: 82,
    +    0x8b2: 82,
    +    0x8b3: 68,
    +    0x8b4: 68,
    +    0x8b5: 68,
    +    0x8b6: 68,
    +    0x8b7: 68,
    +    0x8b8: 68,
    +    0x8b9: 82,
    +    0x8ba: 68,
    +    0x8bb: 68,
    +    0x8bc: 68,
    +    0x8bd: 68,
    +    0x8be: 68,
    +    0x8bf: 68,
    +    0x8c0: 68,
    +    0x8c1: 68,
    +    0x8c2: 68,
    +    0x8c3: 68,
    +    0x8c4: 68,
    +    0x8c5: 68,
    +    0x8c6: 68,
    +    0x8c7: 68,
    +    0x8c8: 68,
    +    0x8e2: 85,
    +    0x1806: 85,
    +    0x1807: 68,
    +    0x180a: 67,
    +    0x180e: 85,
    +    0x1820: 68,
    +    0x1821: 68,
    +    0x1822: 68,
    +    0x1823: 68,
    +    0x1824: 68,
    +    0x1825: 68,
    +    0x1826: 68,
    +    0x1827: 68,
    +    0x1828: 68,
    +    0x1829: 68,
    +    0x182a: 68,
    +    0x182b: 68,
    +    0x182c: 68,
    +    0x182d: 68,
    +    0x182e: 68,
    +    0x182f: 68,
    +    0x1830: 68,
    +    0x1831: 68,
    +    0x1832: 68,
    +    0x1833: 68,
    +    0x1834: 68,
    +    0x1835: 68,
    +    0x1836: 68,
    +    0x1837: 68,
    +    0x1838: 68,
    +    0x1839: 68,
    +    0x183a: 68,
    +    0x183b: 68,
    +    0x183c: 68,
    +    0x183d: 68,
    +    0x183e: 68,
    +    0x183f: 68,
    +    0x1840: 68,
    +    0x1841: 68,
    +    0x1842: 68,
    +    0x1843: 68,
    +    0x1844: 68,
    +    0x1845: 68,
    +    0x1846: 68,
    +    0x1847: 68,
    +    0x1848: 68,
    +    0x1849: 68,
    +    0x184a: 68,
    +    0x184b: 68,
    +    0x184c: 68,
    +    0x184d: 68,
    +    0x184e: 68,
    +    0x184f: 68,
    +    0x1850: 68,
    +    0x1851: 68,
    +    0x1852: 68,
    +    0x1853: 68,
    +    0x1854: 68,
    +    0x1855: 68,
    +    0x1856: 68,
    +    0x1857: 68,
    +    0x1858: 68,
    +    0x1859: 68,
    +    0x185a: 68,
    +    0x185b: 68,
    +    0x185c: 68,
    +    0x185d: 68,
    +    0x185e: 68,
    +    0x185f: 68,
    +    0x1860: 68,
    +    0x1861: 68,
    +    0x1862: 68,
    +    0x1863: 68,
    +    0x1864: 68,
    +    0x1865: 68,
    +    0x1866: 68,
    +    0x1867: 68,
    +    0x1868: 68,
    +    0x1869: 68,
    +    0x186a: 68,
    +    0x186b: 68,
    +    0x186c: 68,
    +    0x186d: 68,
    +    0x186e: 68,
    +    0x186f: 68,
    +    0x1870: 68,
    +    0x1871: 68,
    +    0x1872: 68,
    +    0x1873: 68,
    +    0x1874: 68,
    +    0x1875: 68,
    +    0x1876: 68,
    +    0x1877: 68,
    +    0x1878: 68,
    +    0x1880: 85,
    +    0x1881: 85,
    +    0x1882: 85,
    +    0x1883: 85,
    +    0x1884: 85,
    +    0x1885: 84,
    +    0x1886: 84,
    +    0x1887: 68,
    +    0x1888: 68,
    +    0x1889: 68,
    +    0x188a: 68,
    +    0x188b: 68,
    +    0x188c: 68,
    +    0x188d: 68,
    +    0x188e: 68,
    +    0x188f: 68,
    +    0x1890: 68,
    +    0x1891: 68,
    +    0x1892: 68,
    +    0x1893: 68,
    +    0x1894: 68,
    +    0x1895: 68,
    +    0x1896: 68,
    +    0x1897: 68,
    +    0x1898: 68,
    +    0x1899: 68,
    +    0x189a: 68,
    +    0x189b: 68,
    +    0x189c: 68,
    +    0x189d: 68,
    +    0x189e: 68,
    +    0x189f: 68,
    +    0x18a0: 68,
    +    0x18a1: 68,
    +    0x18a2: 68,
    +    0x18a3: 68,
    +    0x18a4: 68,
    +    0x18a5: 68,
    +    0x18a6: 68,
    +    0x18a7: 68,
    +    0x18a8: 68,
    +    0x18aa: 68,
    +    0x200c: 85,
    +    0x200d: 67,
    +    0x202f: 85,
    +    0x2066: 85,
    +    0x2067: 85,
    +    0x2068: 85,
    +    0x2069: 85,
    +    0xa840: 68,
    +    0xa841: 68,
    +    0xa842: 68,
    +    0xa843: 68,
    +    0xa844: 68,
    +    0xa845: 68,
    +    0xa846: 68,
    +    0xa847: 68,
    +    0xa848: 68,
    +    0xa849: 68,
    +    0xa84a: 68,
    +    0xa84b: 68,
    +    0xa84c: 68,
    +    0xa84d: 68,
    +    0xa84e: 68,
    +    0xa84f: 68,
    +    0xa850: 68,
    +    0xa851: 68,
    +    0xa852: 68,
    +    0xa853: 68,
    +    0xa854: 68,
    +    0xa855: 68,
    +    0xa856: 68,
    +    0xa857: 68,
    +    0xa858: 68,
    +    0xa859: 68,
    +    0xa85a: 68,
    +    0xa85b: 68,
    +    0xa85c: 68,
    +    0xa85d: 68,
    +    0xa85e: 68,
    +    0xa85f: 68,
    +    0xa860: 68,
    +    0xa861: 68,
    +    0xa862: 68,
    +    0xa863: 68,
    +    0xa864: 68,
    +    0xa865: 68,
    +    0xa866: 68,
    +    0xa867: 68,
    +    0xa868: 68,
    +    0xa869: 68,
    +    0xa86a: 68,
    +    0xa86b: 68,
    +    0xa86c: 68,
    +    0xa86d: 68,
    +    0xa86e: 68,
    +    0xa86f: 68,
    +    0xa870: 68,
    +    0xa871: 68,
    +    0xa872: 76,
    +    0xa873: 85,
    +    0x10ac0: 68,
    +    0x10ac1: 68,
    +    0x10ac2: 68,
    +    0x10ac3: 68,
    +    0x10ac4: 68,
    +    0x10ac5: 82,
    +    0x10ac6: 85,
    +    0x10ac7: 82,
    +    0x10ac8: 85,
    +    0x10ac9: 82,
    +    0x10aca: 82,
    +    0x10acb: 85,
    +    0x10acc: 85,
    +    0x10acd: 76,
    +    0x10ace: 82,
    +    0x10acf: 82,
    +    0x10ad0: 82,
    +    0x10ad1: 82,
    +    0x10ad2: 82,
    +    0x10ad3: 68,
    +    0x10ad4: 68,
    +    0x10ad5: 68,
    +    0x10ad6: 68,
    +    0x10ad7: 76,
    +    0x10ad8: 68,
    +    0x10ad9: 68,
    +    0x10ada: 68,
    +    0x10adb: 68,
    +    0x10adc: 68,
    +    0x10add: 82,
    +    0x10ade: 68,
    +    0x10adf: 68,
    +    0x10ae0: 68,
    +    0x10ae1: 82,
    +    0x10ae2: 85,
    +    0x10ae3: 85,
    +    0x10ae4: 82,
    +    0x10aeb: 68,
    +    0x10aec: 68,
    +    0x10aed: 68,
    +    0x10aee: 68,
    +    0x10aef: 82,
    +    0x10b80: 68,
    +    0x10b81: 82,
    +    0x10b82: 68,
    +    0x10b83: 82,
    +    0x10b84: 82,
    +    0x10b85: 82,
    +    0x10b86: 68,
    +    0x10b87: 68,
    +    0x10b88: 68,
    +    0x10b89: 82,
    +    0x10b8a: 68,
    +    0x10b8b: 68,
    +    0x10b8c: 82,
    +    0x10b8d: 68,
    +    0x10b8e: 82,
    +    0x10b8f: 82,
    +    0x10b90: 68,
    +    0x10b91: 82,
    +    0x10ba9: 82,
    +    0x10baa: 82,
    +    0x10bab: 82,
    +    0x10bac: 82,
    +    0x10bad: 68,
    +    0x10bae: 68,
    +    0x10baf: 85,
    +    0x10d00: 76,
    +    0x10d01: 68,
    +    0x10d02: 68,
    +    0x10d03: 68,
    +    0x10d04: 68,
    +    0x10d05: 68,
    +    0x10d06: 68,
    +    0x10d07: 68,
    +    0x10d08: 68,
    +    0x10d09: 68,
    +    0x10d0a: 68,
    +    0x10d0b: 68,
    +    0x10d0c: 68,
    +    0x10d0d: 68,
    +    0x10d0e: 68,
    +    0x10d0f: 68,
    +    0x10d10: 68,
    +    0x10d11: 68,
    +    0x10d12: 68,
    +    0x10d13: 68,
    +    0x10d14: 68,
    +    0x10d15: 68,
    +    0x10d16: 68,
    +    0x10d17: 68,
    +    0x10d18: 68,
    +    0x10d19: 68,
    +    0x10d1a: 68,
    +    0x10d1b: 68,
    +    0x10d1c: 68,
    +    0x10d1d: 68,
    +    0x10d1e: 68,
    +    0x10d1f: 68,
    +    0x10d20: 68,
    +    0x10d21: 68,
    +    0x10d22: 82,
    +    0x10d23: 68,
    +    0x10f30: 68,
    +    0x10f31: 68,
    +    0x10f32: 68,
    +    0x10f33: 82,
    +    0x10f34: 68,
    +    0x10f35: 68,
    +    0x10f36: 68,
    +    0x10f37: 68,
    +    0x10f38: 68,
    +    0x10f39: 68,
    +    0x10f3a: 68,
    +    0x10f3b: 68,
    +    0x10f3c: 68,
    +    0x10f3d: 68,
    +    0x10f3e: 68,
    +    0x10f3f: 68,
    +    0x10f40: 68,
    +    0x10f41: 68,
    +    0x10f42: 68,
    +    0x10f43: 68,
    +    0x10f44: 68,
    +    0x10f45: 85,
    +    0x10f51: 68,
    +    0x10f52: 68,
    +    0x10f53: 68,
    +    0x10f54: 82,
    +    0x10f70: 68,
    +    0x10f71: 68,
    +    0x10f72: 68,
    +    0x10f73: 68,
    +    0x10f74: 82,
    +    0x10f75: 82,
    +    0x10f76: 68,
    +    0x10f77: 68,
    +    0x10f78: 68,
    +    0x10f79: 68,
    +    0x10f7a: 68,
    +    0x10f7b: 68,
    +    0x10f7c: 68,
    +    0x10f7d: 68,
    +    0x10f7e: 68,
    +    0x10f7f: 68,
    +    0x10f80: 68,
    +    0x10f81: 68,
    +    0x10fb0: 68,
    +    0x10fb1: 85,
    +    0x10fb2: 68,
    +    0x10fb3: 68,
    +    0x10fb4: 82,
    +    0x10fb5: 82,
    +    0x10fb6: 82,
    +    0x10fb7: 85,
    +    0x10fb8: 68,
    +    0x10fb9: 82,
    +    0x10fba: 82,
    +    0x10fbb: 68,
    +    0x10fbc: 68,
    +    0x10fbd: 82,
    +    0x10fbe: 68,
    +    0x10fbf: 68,
    +    0x10fc0: 85,
    +    0x10fc1: 68,
    +    0x10fc2: 82,
    +    0x10fc3: 82,
    +    0x10fc4: 68,
    +    0x10fc5: 85,
    +    0x10fc6: 85,
    +    0x10fc7: 85,
    +    0x10fc8: 85,
    +    0x10fc9: 82,
    +    0x10fca: 68,
    +    0x10fcb: 76,
    +    0x110bd: 85,
    +    0x110cd: 85,
    +    0x1e900: 68,
    +    0x1e901: 68,
    +    0x1e902: 68,
    +    0x1e903: 68,
    +    0x1e904: 68,
    +    0x1e905: 68,
    +    0x1e906: 68,
    +    0x1e907: 68,
    +    0x1e908: 68,
    +    0x1e909: 68,
    +    0x1e90a: 68,
    +    0x1e90b: 68,
    +    0x1e90c: 68,
    +    0x1e90d: 68,
    +    0x1e90e: 68,
    +    0x1e90f: 68,
    +    0x1e910: 68,
    +    0x1e911: 68,
    +    0x1e912: 68,
    +    0x1e913: 68,
    +    0x1e914: 68,
    +    0x1e915: 68,
    +    0x1e916: 68,
    +    0x1e917: 68,
    +    0x1e918: 68,
    +    0x1e919: 68,
    +    0x1e91a: 68,
    +    0x1e91b: 68,
    +    0x1e91c: 68,
    +    0x1e91d: 68,
    +    0x1e91e: 68,
    +    0x1e91f: 68,
    +    0x1e920: 68,
    +    0x1e921: 68,
    +    0x1e922: 68,
    +    0x1e923: 68,
    +    0x1e924: 68,
    +    0x1e925: 68,
    +    0x1e926: 68,
    +    0x1e927: 68,
    +    0x1e928: 68,
    +    0x1e929: 68,
    +    0x1e92a: 68,
    +    0x1e92b: 68,
    +    0x1e92c: 68,
    +    0x1e92d: 68,
    +    0x1e92e: 68,
    +    0x1e92f: 68,
    +    0x1e930: 68,
    +    0x1e931: 68,
    +    0x1e932: 68,
    +    0x1e933: 68,
    +    0x1e934: 68,
    +    0x1e935: 68,
    +    0x1e936: 68,
    +    0x1e937: 68,
    +    0x1e938: 68,
    +    0x1e939: 68,
    +    0x1e93a: 68,
    +    0x1e93b: 68,
    +    0x1e93c: 68,
    +    0x1e93d: 68,
    +    0x1e93e: 68,
    +    0x1e93f: 68,
    +    0x1e940: 68,
    +    0x1e941: 68,
    +    0x1e942: 68,
    +    0x1e943: 68,
    +    0x1e94b: 84,
    +}
    +codepoint_classes = {
    +    'PVALID': (
    +        0x2d0000002e,
    +        0x300000003a,
    +        0x610000007b,
    +        0xdf000000f7,
    +        0xf800000100,
    +        0x10100000102,
    +        0x10300000104,
    +        0x10500000106,
    +        0x10700000108,
    +        0x1090000010a,
    +        0x10b0000010c,
    +        0x10d0000010e,
    +        0x10f00000110,
    +        0x11100000112,
    +        0x11300000114,
    +        0x11500000116,
    +        0x11700000118,
    +        0x1190000011a,
    +        0x11b0000011c,
    +        0x11d0000011e,
    +        0x11f00000120,
    +        0x12100000122,
    +        0x12300000124,
    +        0x12500000126,
    +        0x12700000128,
    +        0x1290000012a,
    +        0x12b0000012c,
    +        0x12d0000012e,
    +        0x12f00000130,
    +        0x13100000132,
    +        0x13500000136,
    +        0x13700000139,
    +        0x13a0000013b,
    +        0x13c0000013d,
    +        0x13e0000013f,
    +        0x14200000143,
    +        0x14400000145,
    +        0x14600000147,
    +        0x14800000149,
    +        0x14b0000014c,
    +        0x14d0000014e,
    +        0x14f00000150,
    +        0x15100000152,
    +        0x15300000154,
    +        0x15500000156,
    +        0x15700000158,
    +        0x1590000015a,
    +        0x15b0000015c,
    +        0x15d0000015e,
    +        0x15f00000160,
    +        0x16100000162,
    +        0x16300000164,
    +        0x16500000166,
    +        0x16700000168,
    +        0x1690000016a,
    +        0x16b0000016c,
    +        0x16d0000016e,
    +        0x16f00000170,
    +        0x17100000172,
    +        0x17300000174,
    +        0x17500000176,
    +        0x17700000178,
    +        0x17a0000017b,
    +        0x17c0000017d,
    +        0x17e0000017f,
    +        0x18000000181,
    +        0x18300000184,
    +        0x18500000186,
    +        0x18800000189,
    +        0x18c0000018e,
    +        0x19200000193,
    +        0x19500000196,
    +        0x1990000019c,
    +        0x19e0000019f,
    +        0x1a1000001a2,
    +        0x1a3000001a4,
    +        0x1a5000001a6,
    +        0x1a8000001a9,
    +        0x1aa000001ac,
    +        0x1ad000001ae,
    +        0x1b0000001b1,
    +        0x1b4000001b5,
    +        0x1b6000001b7,
    +        0x1b9000001bc,
    +        0x1bd000001c4,
    +        0x1ce000001cf,
    +        0x1d0000001d1,
    +        0x1d2000001d3,
    +        0x1d4000001d5,
    +        0x1d6000001d7,
    +        0x1d8000001d9,
    +        0x1da000001db,
    +        0x1dc000001de,
    +        0x1df000001e0,
    +        0x1e1000001e2,
    +        0x1e3000001e4,
    +        0x1e5000001e6,
    +        0x1e7000001e8,
    +        0x1e9000001ea,
    +        0x1eb000001ec,
    +        0x1ed000001ee,
    +        0x1ef000001f1,
    +        0x1f5000001f6,
    +        0x1f9000001fa,
    +        0x1fb000001fc,
    +        0x1fd000001fe,
    +        0x1ff00000200,
    +        0x20100000202,
    +        0x20300000204,
    +        0x20500000206,
    +        0x20700000208,
    +        0x2090000020a,
    +        0x20b0000020c,
    +        0x20d0000020e,
    +        0x20f00000210,
    +        0x21100000212,
    +        0x21300000214,
    +        0x21500000216,
    +        0x21700000218,
    +        0x2190000021a,
    +        0x21b0000021c,
    +        0x21d0000021e,
    +        0x21f00000220,
    +        0x22100000222,
    +        0x22300000224,
    +        0x22500000226,
    +        0x22700000228,
    +        0x2290000022a,
    +        0x22b0000022c,
    +        0x22d0000022e,
    +        0x22f00000230,
    +        0x23100000232,
    +        0x2330000023a,
    +        0x23c0000023d,
    +        0x23f00000241,
    +        0x24200000243,
    +        0x24700000248,
    +        0x2490000024a,
    +        0x24b0000024c,
    +        0x24d0000024e,
    +        0x24f000002b0,
    +        0x2b9000002c2,
    +        0x2c6000002d2,
    +        0x2ec000002ed,
    +        0x2ee000002ef,
    +        0x30000000340,
    +        0x34200000343,
    +        0x3460000034f,
    +        0x35000000370,
    +        0x37100000372,
    +        0x37300000374,
    +        0x37700000378,
    +        0x37b0000037e,
    +        0x39000000391,
    +        0x3ac000003cf,
    +        0x3d7000003d8,
    +        0x3d9000003da,
    +        0x3db000003dc,
    +        0x3dd000003de,
    +        0x3df000003e0,
    +        0x3e1000003e2,
    +        0x3e3000003e4,
    +        0x3e5000003e6,
    +        0x3e7000003e8,
    +        0x3e9000003ea,
    +        0x3eb000003ec,
    +        0x3ed000003ee,
    +        0x3ef000003f0,
    +        0x3f3000003f4,
    +        0x3f8000003f9,
    +        0x3fb000003fd,
    +        0x43000000460,
    +        0x46100000462,
    +        0x46300000464,
    +        0x46500000466,
    +        0x46700000468,
    +        0x4690000046a,
    +        0x46b0000046c,
    +        0x46d0000046e,
    +        0x46f00000470,
    +        0x47100000472,
    +        0x47300000474,
    +        0x47500000476,
    +        0x47700000478,
    +        0x4790000047a,
    +        0x47b0000047c,
    +        0x47d0000047e,
    +        0x47f00000480,
    +        0x48100000482,
    +        0x48300000488,
    +        0x48b0000048c,
    +        0x48d0000048e,
    +        0x48f00000490,
    +        0x49100000492,
    +        0x49300000494,
    +        0x49500000496,
    +        0x49700000498,
    +        0x4990000049a,
    +        0x49b0000049c,
    +        0x49d0000049e,
    +        0x49f000004a0,
    +        0x4a1000004a2,
    +        0x4a3000004a4,
    +        0x4a5000004a6,
    +        0x4a7000004a8,
    +        0x4a9000004aa,
    +        0x4ab000004ac,
    +        0x4ad000004ae,
    +        0x4af000004b0,
    +        0x4b1000004b2,
    +        0x4b3000004b4,
    +        0x4b5000004b6,
    +        0x4b7000004b8,
    +        0x4b9000004ba,
    +        0x4bb000004bc,
    +        0x4bd000004be,
    +        0x4bf000004c0,
    +        0x4c2000004c3,
    +        0x4c4000004c5,
    +        0x4c6000004c7,
    +        0x4c8000004c9,
    +        0x4ca000004cb,
    +        0x4cc000004cd,
    +        0x4ce000004d0,
    +        0x4d1000004d2,
    +        0x4d3000004d4,
    +        0x4d5000004d6,
    +        0x4d7000004d8,
    +        0x4d9000004da,
    +        0x4db000004dc,
    +        0x4dd000004de,
    +        0x4df000004e0,
    +        0x4e1000004e2,
    +        0x4e3000004e4,
    +        0x4e5000004e6,
    +        0x4e7000004e8,
    +        0x4e9000004ea,
    +        0x4eb000004ec,
    +        0x4ed000004ee,
    +        0x4ef000004f0,
    +        0x4f1000004f2,
    +        0x4f3000004f4,
    +        0x4f5000004f6,
    +        0x4f7000004f8,
    +        0x4f9000004fa,
    +        0x4fb000004fc,
    +        0x4fd000004fe,
    +        0x4ff00000500,
    +        0x50100000502,
    +        0x50300000504,
    +        0x50500000506,
    +        0x50700000508,
    +        0x5090000050a,
    +        0x50b0000050c,
    +        0x50d0000050e,
    +        0x50f00000510,
    +        0x51100000512,
    +        0x51300000514,
    +        0x51500000516,
    +        0x51700000518,
    +        0x5190000051a,
    +        0x51b0000051c,
    +        0x51d0000051e,
    +        0x51f00000520,
    +        0x52100000522,
    +        0x52300000524,
    +        0x52500000526,
    +        0x52700000528,
    +        0x5290000052a,
    +        0x52b0000052c,
    +        0x52d0000052e,
    +        0x52f00000530,
    +        0x5590000055a,
    +        0x56000000587,
    +        0x58800000589,
    +        0x591000005be,
    +        0x5bf000005c0,
    +        0x5c1000005c3,
    +        0x5c4000005c6,
    +        0x5c7000005c8,
    +        0x5d0000005eb,
    +        0x5ef000005f3,
    +        0x6100000061b,
    +        0x62000000640,
    +        0x64100000660,
    +        0x66e00000675,
    +        0x679000006d4,
    +        0x6d5000006dd,
    +        0x6df000006e9,
    +        0x6ea000006f0,
    +        0x6fa00000700,
    +        0x7100000074b,
    +        0x74d000007b2,
    +        0x7c0000007f6,
    +        0x7fd000007fe,
    +        0x8000000082e,
    +        0x8400000085c,
    +        0x8600000086b,
    +        0x87000000888,
    +        0x8890000088f,
    +        0x898000008e2,
    +        0x8e300000958,
    +        0x96000000964,
    +        0x96600000970,
    +        0x97100000984,
    +        0x9850000098d,
    +        0x98f00000991,
    +        0x993000009a9,
    +        0x9aa000009b1,
    +        0x9b2000009b3,
    +        0x9b6000009ba,
    +        0x9bc000009c5,
    +        0x9c7000009c9,
    +        0x9cb000009cf,
    +        0x9d7000009d8,
    +        0x9e0000009e4,
    +        0x9e6000009f2,
    +        0x9fc000009fd,
    +        0x9fe000009ff,
    +        0xa0100000a04,
    +        0xa0500000a0b,
    +        0xa0f00000a11,
    +        0xa1300000a29,
    +        0xa2a00000a31,
    +        0xa3200000a33,
    +        0xa3500000a36,
    +        0xa3800000a3a,
    +        0xa3c00000a3d,
    +        0xa3e00000a43,
    +        0xa4700000a49,
    +        0xa4b00000a4e,
    +        0xa5100000a52,
    +        0xa5c00000a5d,
    +        0xa6600000a76,
    +        0xa8100000a84,
    +        0xa8500000a8e,
    +        0xa8f00000a92,
    +        0xa9300000aa9,
    +        0xaaa00000ab1,
    +        0xab200000ab4,
    +        0xab500000aba,
    +        0xabc00000ac6,
    +        0xac700000aca,
    +        0xacb00000ace,
    +        0xad000000ad1,
    +        0xae000000ae4,
    +        0xae600000af0,
    +        0xaf900000b00,
    +        0xb0100000b04,
    +        0xb0500000b0d,
    +        0xb0f00000b11,
    +        0xb1300000b29,
    +        0xb2a00000b31,
    +        0xb3200000b34,
    +        0xb3500000b3a,
    +        0xb3c00000b45,
    +        0xb4700000b49,
    +        0xb4b00000b4e,
    +        0xb5500000b58,
    +        0xb5f00000b64,
    +        0xb6600000b70,
    +        0xb7100000b72,
    +        0xb8200000b84,
    +        0xb8500000b8b,
    +        0xb8e00000b91,
    +        0xb9200000b96,
    +        0xb9900000b9b,
    +        0xb9c00000b9d,
    +        0xb9e00000ba0,
    +        0xba300000ba5,
    +        0xba800000bab,
    +        0xbae00000bba,
    +        0xbbe00000bc3,
    +        0xbc600000bc9,
    +        0xbca00000bce,
    +        0xbd000000bd1,
    +        0xbd700000bd8,
    +        0xbe600000bf0,
    +        0xc0000000c0d,
    +        0xc0e00000c11,
    +        0xc1200000c29,
    +        0xc2a00000c3a,
    +        0xc3c00000c45,
    +        0xc4600000c49,
    +        0xc4a00000c4e,
    +        0xc5500000c57,
    +        0xc5800000c5b,
    +        0xc5d00000c5e,
    +        0xc6000000c64,
    +        0xc6600000c70,
    +        0xc8000000c84,
    +        0xc8500000c8d,
    +        0xc8e00000c91,
    +        0xc9200000ca9,
    +        0xcaa00000cb4,
    +        0xcb500000cba,
    +        0xcbc00000cc5,
    +        0xcc600000cc9,
    +        0xcca00000cce,
    +        0xcd500000cd7,
    +        0xcdd00000cdf,
    +        0xce000000ce4,
    +        0xce600000cf0,
    +        0xcf100000cf4,
    +        0xd0000000d0d,
    +        0xd0e00000d11,
    +        0xd1200000d45,
    +        0xd4600000d49,
    +        0xd4a00000d4f,
    +        0xd5400000d58,
    +        0xd5f00000d64,
    +        0xd6600000d70,
    +        0xd7a00000d80,
    +        0xd8100000d84,
    +        0xd8500000d97,
    +        0xd9a00000db2,
    +        0xdb300000dbc,
    +        0xdbd00000dbe,
    +        0xdc000000dc7,
    +        0xdca00000dcb,
    +        0xdcf00000dd5,
    +        0xdd600000dd7,
    +        0xdd800000de0,
    +        0xde600000df0,
    +        0xdf200000df4,
    +        0xe0100000e33,
    +        0xe3400000e3b,
    +        0xe4000000e4f,
    +        0xe5000000e5a,
    +        0xe8100000e83,
    +        0xe8400000e85,
    +        0xe8600000e8b,
    +        0xe8c00000ea4,
    +        0xea500000ea6,
    +        0xea700000eb3,
    +        0xeb400000ebe,
    +        0xec000000ec5,
    +        0xec600000ec7,
    +        0xec800000ecf,
    +        0xed000000eda,
    +        0xede00000ee0,
    +        0xf0000000f01,
    +        0xf0b00000f0c,
    +        0xf1800000f1a,
    +        0xf2000000f2a,
    +        0xf3500000f36,
    +        0xf3700000f38,
    +        0xf3900000f3a,
    +        0xf3e00000f43,
    +        0xf4400000f48,
    +        0xf4900000f4d,
    +        0xf4e00000f52,
    +        0xf5300000f57,
    +        0xf5800000f5c,
    +        0xf5d00000f69,
    +        0xf6a00000f6d,
    +        0xf7100000f73,
    +        0xf7400000f75,
    +        0xf7a00000f81,
    +        0xf8200000f85,
    +        0xf8600000f93,
    +        0xf9400000f98,
    +        0xf9900000f9d,
    +        0xf9e00000fa2,
    +        0xfa300000fa7,
    +        0xfa800000fac,
    +        0xfad00000fb9,
    +        0xfba00000fbd,
    +        0xfc600000fc7,
    +        0x10000000104a,
    +        0x10500000109e,
    +        0x10d0000010fb,
    +        0x10fd00001100,
    +        0x120000001249,
    +        0x124a0000124e,
    +        0x125000001257,
    +        0x125800001259,
    +        0x125a0000125e,
    +        0x126000001289,
    +        0x128a0000128e,
    +        0x1290000012b1,
    +        0x12b2000012b6,
    +        0x12b8000012bf,
    +        0x12c0000012c1,
    +        0x12c2000012c6,
    +        0x12c8000012d7,
    +        0x12d800001311,
    +        0x131200001316,
    +        0x13180000135b,
    +        0x135d00001360,
    +        0x138000001390,
    +        0x13a0000013f6,
    +        0x14010000166d,
    +        0x166f00001680,
    +        0x16810000169b,
    +        0x16a0000016eb,
    +        0x16f1000016f9,
    +        0x170000001716,
    +        0x171f00001735,
    +        0x174000001754,
    +        0x17600000176d,
    +        0x176e00001771,
    +        0x177200001774,
    +        0x1780000017b4,
    +        0x17b6000017d4,
    +        0x17d7000017d8,
    +        0x17dc000017de,
    +        0x17e0000017ea,
    +        0x18100000181a,
    +        0x182000001879,
    +        0x1880000018ab,
    +        0x18b0000018f6,
    +        0x19000000191f,
    +        0x19200000192c,
    +        0x19300000193c,
    +        0x19460000196e,
    +        0x197000001975,
    +        0x1980000019ac,
    +        0x19b0000019ca,
    +        0x19d0000019da,
    +        0x1a0000001a1c,
    +        0x1a2000001a5f,
    +        0x1a6000001a7d,
    +        0x1a7f00001a8a,
    +        0x1a9000001a9a,
    +        0x1aa700001aa8,
    +        0x1ab000001abe,
    +        0x1abf00001acf,
    +        0x1b0000001b4d,
    +        0x1b5000001b5a,
    +        0x1b6b00001b74,
    +        0x1b8000001bf4,
    +        0x1c0000001c38,
    +        0x1c4000001c4a,
    +        0x1c4d00001c7e,
    +        0x1cd000001cd3,
    +        0x1cd400001cfb,
    +        0x1d0000001d2c,
    +        0x1d2f00001d30,
    +        0x1d3b00001d3c,
    +        0x1d4e00001d4f,
    +        0x1d6b00001d78,
    +        0x1d7900001d9b,
    +        0x1dc000001e00,
    +        0x1e0100001e02,
    +        0x1e0300001e04,
    +        0x1e0500001e06,
    +        0x1e0700001e08,
    +        0x1e0900001e0a,
    +        0x1e0b00001e0c,
    +        0x1e0d00001e0e,
    +        0x1e0f00001e10,
    +        0x1e1100001e12,
    +        0x1e1300001e14,
    +        0x1e1500001e16,
    +        0x1e1700001e18,
    +        0x1e1900001e1a,
    +        0x1e1b00001e1c,
    +        0x1e1d00001e1e,
    +        0x1e1f00001e20,
    +        0x1e2100001e22,
    +        0x1e2300001e24,
    +        0x1e2500001e26,
    +        0x1e2700001e28,
    +        0x1e2900001e2a,
    +        0x1e2b00001e2c,
    +        0x1e2d00001e2e,
    +        0x1e2f00001e30,
    +        0x1e3100001e32,
    +        0x1e3300001e34,
    +        0x1e3500001e36,
    +        0x1e3700001e38,
    +        0x1e3900001e3a,
    +        0x1e3b00001e3c,
    +        0x1e3d00001e3e,
    +        0x1e3f00001e40,
    +        0x1e4100001e42,
    +        0x1e4300001e44,
    +        0x1e4500001e46,
    +        0x1e4700001e48,
    +        0x1e4900001e4a,
    +        0x1e4b00001e4c,
    +        0x1e4d00001e4e,
    +        0x1e4f00001e50,
    +        0x1e5100001e52,
    +        0x1e5300001e54,
    +        0x1e5500001e56,
    +        0x1e5700001e58,
    +        0x1e5900001e5a,
    +        0x1e5b00001e5c,
    +        0x1e5d00001e5e,
    +        0x1e5f00001e60,
    +        0x1e6100001e62,
    +        0x1e6300001e64,
    +        0x1e6500001e66,
    +        0x1e6700001e68,
    +        0x1e6900001e6a,
    +        0x1e6b00001e6c,
    +        0x1e6d00001e6e,
    +        0x1e6f00001e70,
    +        0x1e7100001e72,
    +        0x1e7300001e74,
    +        0x1e7500001e76,
    +        0x1e7700001e78,
    +        0x1e7900001e7a,
    +        0x1e7b00001e7c,
    +        0x1e7d00001e7e,
    +        0x1e7f00001e80,
    +        0x1e8100001e82,
    +        0x1e8300001e84,
    +        0x1e8500001e86,
    +        0x1e8700001e88,
    +        0x1e8900001e8a,
    +        0x1e8b00001e8c,
    +        0x1e8d00001e8e,
    +        0x1e8f00001e90,
    +        0x1e9100001e92,
    +        0x1e9300001e94,
    +        0x1e9500001e9a,
    +        0x1e9c00001e9e,
    +        0x1e9f00001ea0,
    +        0x1ea100001ea2,
    +        0x1ea300001ea4,
    +        0x1ea500001ea6,
    +        0x1ea700001ea8,
    +        0x1ea900001eaa,
    +        0x1eab00001eac,
    +        0x1ead00001eae,
    +        0x1eaf00001eb0,
    +        0x1eb100001eb2,
    +        0x1eb300001eb4,
    +        0x1eb500001eb6,
    +        0x1eb700001eb8,
    +        0x1eb900001eba,
    +        0x1ebb00001ebc,
    +        0x1ebd00001ebe,
    +        0x1ebf00001ec0,
    +        0x1ec100001ec2,
    +        0x1ec300001ec4,
    +        0x1ec500001ec6,
    +        0x1ec700001ec8,
    +        0x1ec900001eca,
    +        0x1ecb00001ecc,
    +        0x1ecd00001ece,
    +        0x1ecf00001ed0,
    +        0x1ed100001ed2,
    +        0x1ed300001ed4,
    +        0x1ed500001ed6,
    +        0x1ed700001ed8,
    +        0x1ed900001eda,
    +        0x1edb00001edc,
    +        0x1edd00001ede,
    +        0x1edf00001ee0,
    +        0x1ee100001ee2,
    +        0x1ee300001ee4,
    +        0x1ee500001ee6,
    +        0x1ee700001ee8,
    +        0x1ee900001eea,
    +        0x1eeb00001eec,
    +        0x1eed00001eee,
    +        0x1eef00001ef0,
    +        0x1ef100001ef2,
    +        0x1ef300001ef4,
    +        0x1ef500001ef6,
    +        0x1ef700001ef8,
    +        0x1ef900001efa,
    +        0x1efb00001efc,
    +        0x1efd00001efe,
    +        0x1eff00001f08,
    +        0x1f1000001f16,
    +        0x1f2000001f28,
    +        0x1f3000001f38,
    +        0x1f4000001f46,
    +        0x1f5000001f58,
    +        0x1f6000001f68,
    +        0x1f7000001f71,
    +        0x1f7200001f73,
    +        0x1f7400001f75,
    +        0x1f7600001f77,
    +        0x1f7800001f79,
    +        0x1f7a00001f7b,
    +        0x1f7c00001f7d,
    +        0x1fb000001fb2,
    +        0x1fb600001fb7,
    +        0x1fc600001fc7,
    +        0x1fd000001fd3,
    +        0x1fd600001fd8,
    +        0x1fe000001fe3,
    +        0x1fe400001fe8,
    +        0x1ff600001ff7,
    +        0x214e0000214f,
    +        0x218400002185,
    +        0x2c3000002c60,
    +        0x2c6100002c62,
    +        0x2c6500002c67,
    +        0x2c6800002c69,
    +        0x2c6a00002c6b,
    +        0x2c6c00002c6d,
    +        0x2c7100002c72,
    +        0x2c7300002c75,
    +        0x2c7600002c7c,
    +        0x2c8100002c82,
    +        0x2c8300002c84,
    +        0x2c8500002c86,
    +        0x2c8700002c88,
    +        0x2c8900002c8a,
    +        0x2c8b00002c8c,
    +        0x2c8d00002c8e,
    +        0x2c8f00002c90,
    +        0x2c9100002c92,
    +        0x2c9300002c94,
    +        0x2c9500002c96,
    +        0x2c9700002c98,
    +        0x2c9900002c9a,
    +        0x2c9b00002c9c,
    +        0x2c9d00002c9e,
    +        0x2c9f00002ca0,
    +        0x2ca100002ca2,
    +        0x2ca300002ca4,
    +        0x2ca500002ca6,
    +        0x2ca700002ca8,
    +        0x2ca900002caa,
    +        0x2cab00002cac,
    +        0x2cad00002cae,
    +        0x2caf00002cb0,
    +        0x2cb100002cb2,
    +        0x2cb300002cb4,
    +        0x2cb500002cb6,
    +        0x2cb700002cb8,
    +        0x2cb900002cba,
    +        0x2cbb00002cbc,
    +        0x2cbd00002cbe,
    +        0x2cbf00002cc0,
    +        0x2cc100002cc2,
    +        0x2cc300002cc4,
    +        0x2cc500002cc6,
    +        0x2cc700002cc8,
    +        0x2cc900002cca,
    +        0x2ccb00002ccc,
    +        0x2ccd00002cce,
    +        0x2ccf00002cd0,
    +        0x2cd100002cd2,
    +        0x2cd300002cd4,
    +        0x2cd500002cd6,
    +        0x2cd700002cd8,
    +        0x2cd900002cda,
    +        0x2cdb00002cdc,
    +        0x2cdd00002cde,
    +        0x2cdf00002ce0,
    +        0x2ce100002ce2,
    +        0x2ce300002ce5,
    +        0x2cec00002ced,
    +        0x2cee00002cf2,
    +        0x2cf300002cf4,
    +        0x2d0000002d26,
    +        0x2d2700002d28,
    +        0x2d2d00002d2e,
    +        0x2d3000002d68,
    +        0x2d7f00002d97,
    +        0x2da000002da7,
    +        0x2da800002daf,
    +        0x2db000002db7,
    +        0x2db800002dbf,
    +        0x2dc000002dc7,
    +        0x2dc800002dcf,
    +        0x2dd000002dd7,
    +        0x2dd800002ddf,
    +        0x2de000002e00,
    +        0x2e2f00002e30,
    +        0x300500003008,
    +        0x302a0000302e,
    +        0x303c0000303d,
    +        0x304100003097,
    +        0x30990000309b,
    +        0x309d0000309f,
    +        0x30a1000030fb,
    +        0x30fc000030ff,
    +        0x310500003130,
    +        0x31a0000031c0,
    +        0x31f000003200,
    +        0x340000004dc0,
    +        0x4e000000a48d,
    +        0xa4d00000a4fe,
    +        0xa5000000a60d,
    +        0xa6100000a62c,
    +        0xa6410000a642,
    +        0xa6430000a644,
    +        0xa6450000a646,
    +        0xa6470000a648,
    +        0xa6490000a64a,
    +        0xa64b0000a64c,
    +        0xa64d0000a64e,
    +        0xa64f0000a650,
    +        0xa6510000a652,
    +        0xa6530000a654,
    +        0xa6550000a656,
    +        0xa6570000a658,
    +        0xa6590000a65a,
    +        0xa65b0000a65c,
    +        0xa65d0000a65e,
    +        0xa65f0000a660,
    +        0xa6610000a662,
    +        0xa6630000a664,
    +        0xa6650000a666,
    +        0xa6670000a668,
    +        0xa6690000a66a,
    +        0xa66b0000a66c,
    +        0xa66d0000a670,
    +        0xa6740000a67e,
    +        0xa67f0000a680,
    +        0xa6810000a682,
    +        0xa6830000a684,
    +        0xa6850000a686,
    +        0xa6870000a688,
    +        0xa6890000a68a,
    +        0xa68b0000a68c,
    +        0xa68d0000a68e,
    +        0xa68f0000a690,
    +        0xa6910000a692,
    +        0xa6930000a694,
    +        0xa6950000a696,
    +        0xa6970000a698,
    +        0xa6990000a69a,
    +        0xa69b0000a69c,
    +        0xa69e0000a6e6,
    +        0xa6f00000a6f2,
    +        0xa7170000a720,
    +        0xa7230000a724,
    +        0xa7250000a726,
    +        0xa7270000a728,
    +        0xa7290000a72a,
    +        0xa72b0000a72c,
    +        0xa72d0000a72e,
    +        0xa72f0000a732,
    +        0xa7330000a734,
    +        0xa7350000a736,
    +        0xa7370000a738,
    +        0xa7390000a73a,
    +        0xa73b0000a73c,
    +        0xa73d0000a73e,
    +        0xa73f0000a740,
    +        0xa7410000a742,
    +        0xa7430000a744,
    +        0xa7450000a746,
    +        0xa7470000a748,
    +        0xa7490000a74a,
    +        0xa74b0000a74c,
    +        0xa74d0000a74e,
    +        0xa74f0000a750,
    +        0xa7510000a752,
    +        0xa7530000a754,
    +        0xa7550000a756,
    +        0xa7570000a758,
    +        0xa7590000a75a,
    +        0xa75b0000a75c,
    +        0xa75d0000a75e,
    +        0xa75f0000a760,
    +        0xa7610000a762,
    +        0xa7630000a764,
    +        0xa7650000a766,
    +        0xa7670000a768,
    +        0xa7690000a76a,
    +        0xa76b0000a76c,
    +        0xa76d0000a76e,
    +        0xa76f0000a770,
    +        0xa7710000a779,
    +        0xa77a0000a77b,
    +        0xa77c0000a77d,
    +        0xa77f0000a780,
    +        0xa7810000a782,
    +        0xa7830000a784,
    +        0xa7850000a786,
    +        0xa7870000a789,
    +        0xa78c0000a78d,
    +        0xa78e0000a790,
    +        0xa7910000a792,
    +        0xa7930000a796,
    +        0xa7970000a798,
    +        0xa7990000a79a,
    +        0xa79b0000a79c,
    +        0xa79d0000a79e,
    +        0xa79f0000a7a0,
    +        0xa7a10000a7a2,
    +        0xa7a30000a7a4,
    +        0xa7a50000a7a6,
    +        0xa7a70000a7a8,
    +        0xa7a90000a7aa,
    +        0xa7af0000a7b0,
    +        0xa7b50000a7b6,
    +        0xa7b70000a7b8,
    +        0xa7b90000a7ba,
    +        0xa7bb0000a7bc,
    +        0xa7bd0000a7be,
    +        0xa7bf0000a7c0,
    +        0xa7c10000a7c2,
    +        0xa7c30000a7c4,
    +        0xa7c80000a7c9,
    +        0xa7ca0000a7cb,
    +        0xa7d10000a7d2,
    +        0xa7d30000a7d4,
    +        0xa7d50000a7d6,
    +        0xa7d70000a7d8,
    +        0xa7d90000a7da,
    +        0xa7f20000a7f5,
    +        0xa7f60000a7f8,
    +        0xa7fa0000a828,
    +        0xa82c0000a82d,
    +        0xa8400000a874,
    +        0xa8800000a8c6,
    +        0xa8d00000a8da,
    +        0xa8e00000a8f8,
    +        0xa8fb0000a8fc,
    +        0xa8fd0000a92e,
    +        0xa9300000a954,
    +        0xa9800000a9c1,
    +        0xa9cf0000a9da,
    +        0xa9e00000a9ff,
    +        0xaa000000aa37,
    +        0xaa400000aa4e,
    +        0xaa500000aa5a,
    +        0xaa600000aa77,
    +        0xaa7a0000aac3,
    +        0xaadb0000aade,
    +        0xaae00000aaf0,
    +        0xaaf20000aaf7,
    +        0xab010000ab07,
    +        0xab090000ab0f,
    +        0xab110000ab17,
    +        0xab200000ab27,
    +        0xab280000ab2f,
    +        0xab300000ab5b,
    +        0xab600000ab69,
    +        0xabc00000abeb,
    +        0xabec0000abee,
    +        0xabf00000abfa,
    +        0xac000000d7a4,
    +        0xfa0e0000fa10,
    +        0xfa110000fa12,
    +        0xfa130000fa15,
    +        0xfa1f0000fa20,
    +        0xfa210000fa22,
    +        0xfa230000fa25,
    +        0xfa270000fa2a,
    +        0xfb1e0000fb1f,
    +        0xfe200000fe30,
    +        0xfe730000fe74,
    +        0x100000001000c,
    +        0x1000d00010027,
    +        0x100280001003b,
    +        0x1003c0001003e,
    +        0x1003f0001004e,
    +        0x100500001005e,
    +        0x10080000100fb,
    +        0x101fd000101fe,
    +        0x102800001029d,
    +        0x102a0000102d1,
    +        0x102e0000102e1,
    +        0x1030000010320,
    +        0x1032d00010341,
    +        0x103420001034a,
    +        0x103500001037b,
    +        0x103800001039e,
    +        0x103a0000103c4,
    +        0x103c8000103d0,
    +        0x104280001049e,
    +        0x104a0000104aa,
    +        0x104d8000104fc,
    +        0x1050000010528,
    +        0x1053000010564,
    +        0x10597000105a2,
    +        0x105a3000105b2,
    +        0x105b3000105ba,
    +        0x105bb000105bd,
    +        0x1060000010737,
    +        0x1074000010756,
    +        0x1076000010768,
    +        0x1078000010786,
    +        0x10787000107b1,
    +        0x107b2000107bb,
    +        0x1080000010806,
    +        0x1080800010809,
    +        0x1080a00010836,
    +        0x1083700010839,
    +        0x1083c0001083d,
    +        0x1083f00010856,
    +        0x1086000010877,
    +        0x108800001089f,
    +        0x108e0000108f3,
    +        0x108f4000108f6,
    +        0x1090000010916,
    +        0x109200001093a,
    +        0x10980000109b8,
    +        0x109be000109c0,
    +        0x10a0000010a04,
    +        0x10a0500010a07,
    +        0x10a0c00010a14,
    +        0x10a1500010a18,
    +        0x10a1900010a36,
    +        0x10a3800010a3b,
    +        0x10a3f00010a40,
    +        0x10a6000010a7d,
    +        0x10a8000010a9d,
    +        0x10ac000010ac8,
    +        0x10ac900010ae7,
    +        0x10b0000010b36,
    +        0x10b4000010b56,
    +        0x10b6000010b73,
    +        0x10b8000010b92,
    +        0x10c0000010c49,
    +        0x10cc000010cf3,
    +        0x10d0000010d28,
    +        0x10d3000010d3a,
    +        0x10e8000010eaa,
    +        0x10eab00010ead,
    +        0x10eb000010eb2,
    +        0x10efd00010f1d,
    +        0x10f2700010f28,
    +        0x10f3000010f51,
    +        0x10f7000010f86,
    +        0x10fb000010fc5,
    +        0x10fe000010ff7,
    +        0x1100000011047,
    +        0x1106600011076,
    +        0x1107f000110bb,
    +        0x110c2000110c3,
    +        0x110d0000110e9,
    +        0x110f0000110fa,
    +        0x1110000011135,
    +        0x1113600011140,
    +        0x1114400011148,
    +        0x1115000011174,
    +        0x1117600011177,
    +        0x11180000111c5,
    +        0x111c9000111cd,
    +        0x111ce000111db,
    +        0x111dc000111dd,
    +        0x1120000011212,
    +        0x1121300011238,
    +        0x1123e00011242,
    +        0x1128000011287,
    +        0x1128800011289,
    +        0x1128a0001128e,
    +        0x1128f0001129e,
    +        0x1129f000112a9,
    +        0x112b0000112eb,
    +        0x112f0000112fa,
    +        0x1130000011304,
    +        0x113050001130d,
    +        0x1130f00011311,
    +        0x1131300011329,
    +        0x1132a00011331,
    +        0x1133200011334,
    +        0x113350001133a,
    +        0x1133b00011345,
    +        0x1134700011349,
    +        0x1134b0001134e,
    +        0x1135000011351,
    +        0x1135700011358,
    +        0x1135d00011364,
    +        0x113660001136d,
    +        0x1137000011375,
    +        0x114000001144b,
    +        0x114500001145a,
    +        0x1145e00011462,
    +        0x11480000114c6,
    +        0x114c7000114c8,
    +        0x114d0000114da,
    +        0x11580000115b6,
    +        0x115b8000115c1,
    +        0x115d8000115de,
    +        0x1160000011641,
    +        0x1164400011645,
    +        0x116500001165a,
    +        0x11680000116b9,
    +        0x116c0000116ca,
    +        0x117000001171b,
    +        0x1171d0001172c,
    +        0x117300001173a,
    +        0x1174000011747,
    +        0x118000001183b,
    +        0x118c0000118ea,
    +        0x118ff00011907,
    +        0x119090001190a,
    +        0x1190c00011914,
    +        0x1191500011917,
    +        0x1191800011936,
    +        0x1193700011939,
    +        0x1193b00011944,
    +        0x119500001195a,
    +        0x119a0000119a8,
    +        0x119aa000119d8,
    +        0x119da000119e2,
    +        0x119e3000119e5,
    +        0x11a0000011a3f,
    +        0x11a4700011a48,
    +        0x11a5000011a9a,
    +        0x11a9d00011a9e,
    +        0x11ab000011af9,
    +        0x11c0000011c09,
    +        0x11c0a00011c37,
    +        0x11c3800011c41,
    +        0x11c5000011c5a,
    +        0x11c7200011c90,
    +        0x11c9200011ca8,
    +        0x11ca900011cb7,
    +        0x11d0000011d07,
    +        0x11d0800011d0a,
    +        0x11d0b00011d37,
    +        0x11d3a00011d3b,
    +        0x11d3c00011d3e,
    +        0x11d3f00011d48,
    +        0x11d5000011d5a,
    +        0x11d6000011d66,
    +        0x11d6700011d69,
    +        0x11d6a00011d8f,
    +        0x11d9000011d92,
    +        0x11d9300011d99,
    +        0x11da000011daa,
    +        0x11ee000011ef7,
    +        0x11f0000011f11,
    +        0x11f1200011f3b,
    +        0x11f3e00011f43,
    +        0x11f5000011f5a,
    +        0x11fb000011fb1,
    +        0x120000001239a,
    +        0x1248000012544,
    +        0x12f9000012ff1,
    +        0x1300000013430,
    +        0x1344000013456,
    +        0x1440000014647,
    +        0x1680000016a39,
    +        0x16a4000016a5f,
    +        0x16a6000016a6a,
    +        0x16a7000016abf,
    +        0x16ac000016aca,
    +        0x16ad000016aee,
    +        0x16af000016af5,
    +        0x16b0000016b37,
    +        0x16b4000016b44,
    +        0x16b5000016b5a,
    +        0x16b6300016b78,
    +        0x16b7d00016b90,
    +        0x16e6000016e80,
    +        0x16f0000016f4b,
    +        0x16f4f00016f88,
    +        0x16f8f00016fa0,
    +        0x16fe000016fe2,
    +        0x16fe300016fe5,
    +        0x16ff000016ff2,
    +        0x17000000187f8,
    +        0x1880000018cd6,
    +        0x18d0000018d09,
    +        0x1aff00001aff4,
    +        0x1aff50001affc,
    +        0x1affd0001afff,
    +        0x1b0000001b123,
    +        0x1b1320001b133,
    +        0x1b1500001b153,
    +        0x1b1550001b156,
    +        0x1b1640001b168,
    +        0x1b1700001b2fc,
    +        0x1bc000001bc6b,
    +        0x1bc700001bc7d,
    +        0x1bc800001bc89,
    +        0x1bc900001bc9a,
    +        0x1bc9d0001bc9f,
    +        0x1cf000001cf2e,
    +        0x1cf300001cf47,
    +        0x1da000001da37,
    +        0x1da3b0001da6d,
    +        0x1da750001da76,
    +        0x1da840001da85,
    +        0x1da9b0001daa0,
    +        0x1daa10001dab0,
    +        0x1df000001df1f,
    +        0x1df250001df2b,
    +        0x1e0000001e007,
    +        0x1e0080001e019,
    +        0x1e01b0001e022,
    +        0x1e0230001e025,
    +        0x1e0260001e02b,
    +        0x1e0300001e06e,
    +        0x1e08f0001e090,
    +        0x1e1000001e12d,
    +        0x1e1300001e13e,
    +        0x1e1400001e14a,
    +        0x1e14e0001e14f,
    +        0x1e2900001e2af,
    +        0x1e2c00001e2fa,
    +        0x1e4d00001e4fa,
    +        0x1e7e00001e7e7,
    +        0x1e7e80001e7ec,
    +        0x1e7ed0001e7ef,
    +        0x1e7f00001e7ff,
    +        0x1e8000001e8c5,
    +        0x1e8d00001e8d7,
    +        0x1e9220001e94c,
    +        0x1e9500001e95a,
    +        0x200000002a6e0,
    +        0x2a7000002b73a,
    +        0x2b7400002b81e,
    +        0x2b8200002cea2,
    +        0x2ceb00002ebe1,
    +        0x300000003134b,
    +        0x31350000323b0,
    +    ),
    +    'CONTEXTJ': (
    +        0x200c0000200e,
    +    ),
    +    'CONTEXTO': (
    +        0xb7000000b8,
    +        0x37500000376,
    +        0x5f3000005f5,
    +        0x6600000066a,
    +        0x6f0000006fa,
    +        0x30fb000030fc,
    +    ),
    +}
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna/intranges.py b/deployment-apps/metricator-for-nmon/lib/idna/intranges.py
    new file mode 100644
    index 0000000..6a43b04
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna/intranges.py
    @@ -0,0 +1,54 @@
    +"""
    +Given a list of integers, made up of (hopefully) a small number of long runs
    +of consecutive integers, compute a representation of the form
    +((start1, end1), (start2, end2) ...). Then answer the question "was x present
    +in the original list?" in time O(log(# runs)).
    +"""
    +
    +import bisect
    +from typing import List, Tuple
    +
    +def intranges_from_list(list_: List[int]) -> Tuple[int, ...]:
    +    """Represent a list of integers as a sequence of ranges:
    +    ((start_0, end_0), (start_1, end_1), ...), such that the original
    +    integers are exactly those x such that start_i <= x < end_i for some i.
    +
    +    Ranges are encoded as single integers (start << 32 | end), not as tuples.
    +    """
    +
    +    sorted_list = sorted(list_)
    +    ranges = []
    +    last_write = -1
    +    for i in range(len(sorted_list)):
    +        if i+1 < len(sorted_list):
    +            if sorted_list[i] == sorted_list[i+1]-1:
    +                continue
    +        current_range = sorted_list[last_write+1:i+1]
    +        ranges.append(_encode_range(current_range[0], current_range[-1] + 1))
    +        last_write = i
    +
    +    return tuple(ranges)
    +
    +def _encode_range(start: int, end: int) -> int:
    +    return (start << 32) | end
    +
    +def _decode_range(r: int) -> Tuple[int, int]:
    +    return (r >> 32), (r & ((1 << 32) - 1))
    +
    +
    +def intranges_contain(int_: int, ranges: Tuple[int, ...]) -> bool:
    +    """Determine if `int_` falls into one of the ranges in `ranges`."""
    +    tuple_ = _encode_range(int_, 0)
    +    pos = bisect.bisect_left(ranges, tuple_)
    +    # we could be immediately ahead of a tuple (start, end)
    +    # with start < int_ <= end
    +    if pos > 0:
    +        left, right = _decode_range(ranges[pos-1])
    +        if left <= int_ < right:
    +            return True
    +    # or we could be immediately behind a tuple (int_, end)
    +    if pos < len(ranges):
    +        left, _ = _decode_range(ranges[pos])
    +        if left == int_:
    +            return True
    +    return False
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna/package_data.py b/deployment-apps/metricator-for-nmon/lib/idna/package_data.py
    new file mode 100644
    index 0000000..8501893
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna/package_data.py
    @@ -0,0 +1,2 @@
    +__version__ = '3.4'
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna/py.typed b/deployment-apps/metricator-for-nmon/lib/idna/py.typed
    new file mode 100644
    index 0000000..e69de29
    diff --git a/deployment-apps/metricator-for-nmon/lib/idna/uts46data.py b/deployment-apps/metricator-for-nmon/lib/idna/uts46data.py
    new file mode 100644
    index 0000000..186796c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/idna/uts46data.py
    @@ -0,0 +1,8600 @@
    +# This file is automatically generated by tools/idna-data
    +# vim: set fileencoding=utf-8 :
    +
    +from typing import List, Tuple, Union
    +
    +
    +"""IDNA Mapping Table from UTS46."""
    +
    +
    +__version__ = '15.0.0'
    +def _seg_0() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x0, '3'),
    +    (0x1, '3'),
    +    (0x2, '3'),
    +    (0x3, '3'),
    +    (0x4, '3'),
    +    (0x5, '3'),
    +    (0x6, '3'),
    +    (0x7, '3'),
    +    (0x8, '3'),
    +    (0x9, '3'),
    +    (0xA, '3'),
    +    (0xB, '3'),
    +    (0xC, '3'),
    +    (0xD, '3'),
    +    (0xE, '3'),
    +    (0xF, '3'),
    +    (0x10, '3'),
    +    (0x11, '3'),
    +    (0x12, '3'),
    +    (0x13, '3'),
    +    (0x14, '3'),
    +    (0x15, '3'),
    +    (0x16, '3'),
    +    (0x17, '3'),
    +    (0x18, '3'),
    +    (0x19, '3'),
    +    (0x1A, '3'),
    +    (0x1B, '3'),
    +    (0x1C, '3'),
    +    (0x1D, '3'),
    +    (0x1E, '3'),
    +    (0x1F, '3'),
    +    (0x20, '3'),
    +    (0x21, '3'),
    +    (0x22, '3'),
    +    (0x23, '3'),
    +    (0x24, '3'),
    +    (0x25, '3'),
    +    (0x26, '3'),
    +    (0x27, '3'),
    +    (0x28, '3'),
    +    (0x29, '3'),
    +    (0x2A, '3'),
    +    (0x2B, '3'),
    +    (0x2C, '3'),
    +    (0x2D, 'V'),
    +    (0x2E, 'V'),
    +    (0x2F, '3'),
    +    (0x30, 'V'),
    +    (0x31, 'V'),
    +    (0x32, 'V'),
    +    (0x33, 'V'),
    +    (0x34, 'V'),
    +    (0x35, 'V'),
    +    (0x36, 'V'),
    +    (0x37, 'V'),
    +    (0x38, 'V'),
    +    (0x39, 'V'),
    +    (0x3A, '3'),
    +    (0x3B, '3'),
    +    (0x3C, '3'),
    +    (0x3D, '3'),
    +    (0x3E, '3'),
    +    (0x3F, '3'),
    +    (0x40, '3'),
    +    (0x41, 'M', 'a'),
    +    (0x42, 'M', 'b'),
    +    (0x43, 'M', 'c'),
    +    (0x44, 'M', 'd'),
    +    (0x45, 'M', 'e'),
    +    (0x46, 'M', 'f'),
    +    (0x47, 'M', 'g'),
    +    (0x48, 'M', 'h'),
    +    (0x49, 'M', 'i'),
    +    (0x4A, 'M', 'j'),
    +    (0x4B, 'M', 'k'),
    +    (0x4C, 'M', 'l'),
    +    (0x4D, 'M', 'm'),
    +    (0x4E, 'M', 'n'),
    +    (0x4F, 'M', 'o'),
    +    (0x50, 'M', 'p'),
    +    (0x51, 'M', 'q'),
    +    (0x52, 'M', 'r'),
    +    (0x53, 'M', 's'),
    +    (0x54, 'M', 't'),
    +    (0x55, 'M', 'u'),
    +    (0x56, 'M', 'v'),
    +    (0x57, 'M', 'w'),
    +    (0x58, 'M', 'x'),
    +    (0x59, 'M', 'y'),
    +    (0x5A, 'M', 'z'),
    +    (0x5B, '3'),
    +    (0x5C, '3'),
    +    (0x5D, '3'),
    +    (0x5E, '3'),
    +    (0x5F, '3'),
    +    (0x60, '3'),
    +    (0x61, 'V'),
    +    (0x62, 'V'),
    +    (0x63, 'V'),
    +    ]
    +
    +def _seg_1() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x64, 'V'),
    +    (0x65, 'V'),
    +    (0x66, 'V'),
    +    (0x67, 'V'),
    +    (0x68, 'V'),
    +    (0x69, 'V'),
    +    (0x6A, 'V'),
    +    (0x6B, 'V'),
    +    (0x6C, 'V'),
    +    (0x6D, 'V'),
    +    (0x6E, 'V'),
    +    (0x6F, 'V'),
    +    (0x70, 'V'),
    +    (0x71, 'V'),
    +    (0x72, 'V'),
    +    (0x73, 'V'),
    +    (0x74, 'V'),
    +    (0x75, 'V'),
    +    (0x76, 'V'),
    +    (0x77, 'V'),
    +    (0x78, 'V'),
    +    (0x79, 'V'),
    +    (0x7A, 'V'),
    +    (0x7B, '3'),
    +    (0x7C, '3'),
    +    (0x7D, '3'),
    +    (0x7E, '3'),
    +    (0x7F, '3'),
    +    (0x80, 'X'),
    +    (0x81, 'X'),
    +    (0x82, 'X'),
    +    (0x83, 'X'),
    +    (0x84, 'X'),
    +    (0x85, 'X'),
    +    (0x86, 'X'),
    +    (0x87, 'X'),
    +    (0x88, 'X'),
    +    (0x89, 'X'),
    +    (0x8A, 'X'),
    +    (0x8B, 'X'),
    +    (0x8C, 'X'),
    +    (0x8D, 'X'),
    +    (0x8E, 'X'),
    +    (0x8F, 'X'),
    +    (0x90, 'X'),
    +    (0x91, 'X'),
    +    (0x92, 'X'),
    +    (0x93, 'X'),
    +    (0x94, 'X'),
    +    (0x95, 'X'),
    +    (0x96, 'X'),
    +    (0x97, 'X'),
    +    (0x98, 'X'),
    +    (0x99, 'X'),
    +    (0x9A, 'X'),
    +    (0x9B, 'X'),
    +    (0x9C, 'X'),
    +    (0x9D, 'X'),
    +    (0x9E, 'X'),
    +    (0x9F, 'X'),
    +    (0xA0, '3', ' '),
    +    (0xA1, 'V'),
    +    (0xA2, 'V'),
    +    (0xA3, 'V'),
    +    (0xA4, 'V'),
    +    (0xA5, 'V'),
    +    (0xA6, 'V'),
    +    (0xA7, 'V'),
    +    (0xA8, '3', ' ̈'),
    +    (0xA9, 'V'),
    +    (0xAA, 'M', 'a'),
    +    (0xAB, 'V'),
    +    (0xAC, 'V'),
    +    (0xAD, 'I'),
    +    (0xAE, 'V'),
    +    (0xAF, '3', ' ̄'),
    +    (0xB0, 'V'),
    +    (0xB1, 'V'),
    +    (0xB2, 'M', '2'),
    +    (0xB3, 'M', '3'),
    +    (0xB4, '3', ' ́'),
    +    (0xB5, 'M', 'μ'),
    +    (0xB6, 'V'),
    +    (0xB7, 'V'),
    +    (0xB8, '3', ' ̧'),
    +    (0xB9, 'M', '1'),
    +    (0xBA, 'M', 'o'),
    +    (0xBB, 'V'),
    +    (0xBC, 'M', '1⁄4'),
    +    (0xBD, 'M', '1⁄2'),
    +    (0xBE, 'M', '3⁄4'),
    +    (0xBF, 'V'),
    +    (0xC0, 'M', 'à'),
    +    (0xC1, 'M', 'á'),
    +    (0xC2, 'M', 'â'),
    +    (0xC3, 'M', 'ã'),
    +    (0xC4, 'M', 'ä'),
    +    (0xC5, 'M', 'å'),
    +    (0xC6, 'M', 'æ'),
    +    (0xC7, 'M', 'ç'),
    +    ]
    +
    +def _seg_2() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xC8, 'M', 'è'),
    +    (0xC9, 'M', 'é'),
    +    (0xCA, 'M', 'ê'),
    +    (0xCB, 'M', 'ë'),
    +    (0xCC, 'M', 'ì'),
    +    (0xCD, 'M', 'í'),
    +    (0xCE, 'M', 'î'),
    +    (0xCF, 'M', 'ï'),
    +    (0xD0, 'M', 'ð'),
    +    (0xD1, 'M', 'ñ'),
    +    (0xD2, 'M', 'ò'),
    +    (0xD3, 'M', 'ó'),
    +    (0xD4, 'M', 'ô'),
    +    (0xD5, 'M', 'õ'),
    +    (0xD6, 'M', 'ö'),
    +    (0xD7, 'V'),
    +    (0xD8, 'M', 'ø'),
    +    (0xD9, 'M', 'ù'),
    +    (0xDA, 'M', 'ú'),
    +    (0xDB, 'M', 'û'),
    +    (0xDC, 'M', 'ü'),
    +    (0xDD, 'M', 'ý'),
    +    (0xDE, 'M', 'þ'),
    +    (0xDF, 'D', 'ss'),
    +    (0xE0, 'V'),
    +    (0xE1, 'V'),
    +    (0xE2, 'V'),
    +    (0xE3, 'V'),
    +    (0xE4, 'V'),
    +    (0xE5, 'V'),
    +    (0xE6, 'V'),
    +    (0xE7, 'V'),
    +    (0xE8, 'V'),
    +    (0xE9, 'V'),
    +    (0xEA, 'V'),
    +    (0xEB, 'V'),
    +    (0xEC, 'V'),
    +    (0xED, 'V'),
    +    (0xEE, 'V'),
    +    (0xEF, 'V'),
    +    (0xF0, 'V'),
    +    (0xF1, 'V'),
    +    (0xF2, 'V'),
    +    (0xF3, 'V'),
    +    (0xF4, 'V'),
    +    (0xF5, 'V'),
    +    (0xF6, 'V'),
    +    (0xF7, 'V'),
    +    (0xF8, 'V'),
    +    (0xF9, 'V'),
    +    (0xFA, 'V'),
    +    (0xFB, 'V'),
    +    (0xFC, 'V'),
    +    (0xFD, 'V'),
    +    (0xFE, 'V'),
    +    (0xFF, 'V'),
    +    (0x100, 'M', 'ā'),
    +    (0x101, 'V'),
    +    (0x102, 'M', 'ă'),
    +    (0x103, 'V'),
    +    (0x104, 'M', 'ą'),
    +    (0x105, 'V'),
    +    (0x106, 'M', 'ć'),
    +    (0x107, 'V'),
    +    (0x108, 'M', 'ĉ'),
    +    (0x109, 'V'),
    +    (0x10A, 'M', 'ċ'),
    +    (0x10B, 'V'),
    +    (0x10C, 'M', 'č'),
    +    (0x10D, 'V'),
    +    (0x10E, 'M', 'ď'),
    +    (0x10F, 'V'),
    +    (0x110, 'M', 'đ'),
    +    (0x111, 'V'),
    +    (0x112, 'M', 'ē'),
    +    (0x113, 'V'),
    +    (0x114, 'M', 'ĕ'),
    +    (0x115, 'V'),
    +    (0x116, 'M', 'ė'),
    +    (0x117, 'V'),
    +    (0x118, 'M', 'ę'),
    +    (0x119, 'V'),
    +    (0x11A, 'M', 'ě'),
    +    (0x11B, 'V'),
    +    (0x11C, 'M', 'ĝ'),
    +    (0x11D, 'V'),
    +    (0x11E, 'M', 'ğ'),
    +    (0x11F, 'V'),
    +    (0x120, 'M', 'ġ'),
    +    (0x121, 'V'),
    +    (0x122, 'M', 'ģ'),
    +    (0x123, 'V'),
    +    (0x124, 'M', 'ĥ'),
    +    (0x125, 'V'),
    +    (0x126, 'M', 'ħ'),
    +    (0x127, 'V'),
    +    (0x128, 'M', 'ĩ'),
    +    (0x129, 'V'),
    +    (0x12A, 'M', 'ī'),
    +    (0x12B, 'V'),
    +    ]
    +
    +def _seg_3() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x12C, 'M', 'ĭ'),
    +    (0x12D, 'V'),
    +    (0x12E, 'M', 'į'),
    +    (0x12F, 'V'),
    +    (0x130, 'M', 'i̇'),
    +    (0x131, 'V'),
    +    (0x132, 'M', 'ij'),
    +    (0x134, 'M', 'ĵ'),
    +    (0x135, 'V'),
    +    (0x136, 'M', 'ķ'),
    +    (0x137, 'V'),
    +    (0x139, 'M', 'ĺ'),
    +    (0x13A, 'V'),
    +    (0x13B, 'M', 'ļ'),
    +    (0x13C, 'V'),
    +    (0x13D, 'M', 'ľ'),
    +    (0x13E, 'V'),
    +    (0x13F, 'M', 'l·'),
    +    (0x141, 'M', 'ł'),
    +    (0x142, 'V'),
    +    (0x143, 'M', 'ń'),
    +    (0x144, 'V'),
    +    (0x145, 'M', 'ņ'),
    +    (0x146, 'V'),
    +    (0x147, 'M', 'ň'),
    +    (0x148, 'V'),
    +    (0x149, 'M', 'ʼn'),
    +    (0x14A, 'M', 'ŋ'),
    +    (0x14B, 'V'),
    +    (0x14C, 'M', 'ō'),
    +    (0x14D, 'V'),
    +    (0x14E, 'M', 'ŏ'),
    +    (0x14F, 'V'),
    +    (0x150, 'M', 'ő'),
    +    (0x151, 'V'),
    +    (0x152, 'M', 'œ'),
    +    (0x153, 'V'),
    +    (0x154, 'M', 'ŕ'),
    +    (0x155, 'V'),
    +    (0x156, 'M', 'ŗ'),
    +    (0x157, 'V'),
    +    (0x158, 'M', 'ř'),
    +    (0x159, 'V'),
    +    (0x15A, 'M', 'ś'),
    +    (0x15B, 'V'),
    +    (0x15C, 'M', 'ŝ'),
    +    (0x15D, 'V'),
    +    (0x15E, 'M', 'ş'),
    +    (0x15F, 'V'),
    +    (0x160, 'M', 'š'),
    +    (0x161, 'V'),
    +    (0x162, 'M', 'ţ'),
    +    (0x163, 'V'),
    +    (0x164, 'M', 'ť'),
    +    (0x165, 'V'),
    +    (0x166, 'M', 'ŧ'),
    +    (0x167, 'V'),
    +    (0x168, 'M', 'ũ'),
    +    (0x169, 'V'),
    +    (0x16A, 'M', 'ū'),
    +    (0x16B, 'V'),
    +    (0x16C, 'M', 'ŭ'),
    +    (0x16D, 'V'),
    +    (0x16E, 'M', 'ů'),
    +    (0x16F, 'V'),
    +    (0x170, 'M', 'ű'),
    +    (0x171, 'V'),
    +    (0x172, 'M', 'ų'),
    +    (0x173, 'V'),
    +    (0x174, 'M', 'ŵ'),
    +    (0x175, 'V'),
    +    (0x176, 'M', 'ŷ'),
    +    (0x177, 'V'),
    +    (0x178, 'M', 'ÿ'),
    +    (0x179, 'M', 'ź'),
    +    (0x17A, 'V'),
    +    (0x17B, 'M', 'ż'),
    +    (0x17C, 'V'),
    +    (0x17D, 'M', 'ž'),
    +    (0x17E, 'V'),
    +    (0x17F, 'M', 's'),
    +    (0x180, 'V'),
    +    (0x181, 'M', 'ɓ'),
    +    (0x182, 'M', 'ƃ'),
    +    (0x183, 'V'),
    +    (0x184, 'M', 'ƅ'),
    +    (0x185, 'V'),
    +    (0x186, 'M', 'ɔ'),
    +    (0x187, 'M', 'ƈ'),
    +    (0x188, 'V'),
    +    (0x189, 'M', 'ɖ'),
    +    (0x18A, 'M', 'ɗ'),
    +    (0x18B, 'M', 'ƌ'),
    +    (0x18C, 'V'),
    +    (0x18E, 'M', 'ǝ'),
    +    (0x18F, 'M', 'ə'),
    +    (0x190, 'M', 'ɛ'),
    +    (0x191, 'M', 'ƒ'),
    +    (0x192, 'V'),
    +    (0x193, 'M', 'ɠ'),
    +    ]
    +
    +def _seg_4() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x194, 'M', 'ɣ'),
    +    (0x195, 'V'),
    +    (0x196, 'M', 'ɩ'),
    +    (0x197, 'M', 'ɨ'),
    +    (0x198, 'M', 'ƙ'),
    +    (0x199, 'V'),
    +    (0x19C, 'M', 'ɯ'),
    +    (0x19D, 'M', 'ɲ'),
    +    (0x19E, 'V'),
    +    (0x19F, 'M', 'ɵ'),
    +    (0x1A0, 'M', 'ơ'),
    +    (0x1A1, 'V'),
    +    (0x1A2, 'M', 'ƣ'),
    +    (0x1A3, 'V'),
    +    (0x1A4, 'M', 'ƥ'),
    +    (0x1A5, 'V'),
    +    (0x1A6, 'M', 'ʀ'),
    +    (0x1A7, 'M', 'ƨ'),
    +    (0x1A8, 'V'),
    +    (0x1A9, 'M', 'ʃ'),
    +    (0x1AA, 'V'),
    +    (0x1AC, 'M', 'ƭ'),
    +    (0x1AD, 'V'),
    +    (0x1AE, 'M', 'ʈ'),
    +    (0x1AF, 'M', 'ư'),
    +    (0x1B0, 'V'),
    +    (0x1B1, 'M', 'ʊ'),
    +    (0x1B2, 'M', 'ʋ'),
    +    (0x1B3, 'M', 'ƴ'),
    +    (0x1B4, 'V'),
    +    (0x1B5, 'M', 'ƶ'),
    +    (0x1B6, 'V'),
    +    (0x1B7, 'M', 'ʒ'),
    +    (0x1B8, 'M', 'ƹ'),
    +    (0x1B9, 'V'),
    +    (0x1BC, 'M', 'ƽ'),
    +    (0x1BD, 'V'),
    +    (0x1C4, 'M', 'dž'),
    +    (0x1C7, 'M', 'lj'),
    +    (0x1CA, 'M', 'nj'),
    +    (0x1CD, 'M', 'ǎ'),
    +    (0x1CE, 'V'),
    +    (0x1CF, 'M', 'ǐ'),
    +    (0x1D0, 'V'),
    +    (0x1D1, 'M', 'ǒ'),
    +    (0x1D2, 'V'),
    +    (0x1D3, 'M', 'ǔ'),
    +    (0x1D4, 'V'),
    +    (0x1D5, 'M', 'ǖ'),
    +    (0x1D6, 'V'),
    +    (0x1D7, 'M', 'ǘ'),
    +    (0x1D8, 'V'),
    +    (0x1D9, 'M', 'ǚ'),
    +    (0x1DA, 'V'),
    +    (0x1DB, 'M', 'ǜ'),
    +    (0x1DC, 'V'),
    +    (0x1DE, 'M', 'ǟ'),
    +    (0x1DF, 'V'),
    +    (0x1E0, 'M', 'ǡ'),
    +    (0x1E1, 'V'),
    +    (0x1E2, 'M', 'ǣ'),
    +    (0x1E3, 'V'),
    +    (0x1E4, 'M', 'ǥ'),
    +    (0x1E5, 'V'),
    +    (0x1E6, 'M', 'ǧ'),
    +    (0x1E7, 'V'),
    +    (0x1E8, 'M', 'ǩ'),
    +    (0x1E9, 'V'),
    +    (0x1EA, 'M', 'ǫ'),
    +    (0x1EB, 'V'),
    +    (0x1EC, 'M', 'ǭ'),
    +    (0x1ED, 'V'),
    +    (0x1EE, 'M', 'ǯ'),
    +    (0x1EF, 'V'),
    +    (0x1F1, 'M', 'dz'),
    +    (0x1F4, 'M', 'ǵ'),
    +    (0x1F5, 'V'),
    +    (0x1F6, 'M', 'ƕ'),
    +    (0x1F7, 'M', 'ƿ'),
    +    (0x1F8, 'M', 'ǹ'),
    +    (0x1F9, 'V'),
    +    (0x1FA, 'M', 'ǻ'),
    +    (0x1FB, 'V'),
    +    (0x1FC, 'M', 'ǽ'),
    +    (0x1FD, 'V'),
    +    (0x1FE, 'M', 'ǿ'),
    +    (0x1FF, 'V'),
    +    (0x200, 'M', 'ȁ'),
    +    (0x201, 'V'),
    +    (0x202, 'M', 'ȃ'),
    +    (0x203, 'V'),
    +    (0x204, 'M', 'ȅ'),
    +    (0x205, 'V'),
    +    (0x206, 'M', 'ȇ'),
    +    (0x207, 'V'),
    +    (0x208, 'M', 'ȉ'),
    +    (0x209, 'V'),
    +    (0x20A, 'M', 'ȋ'),
    +    (0x20B, 'V'),
    +    (0x20C, 'M', 'ȍ'),
    +    ]
    +
    +def _seg_5() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x20D, 'V'),
    +    (0x20E, 'M', 'ȏ'),
    +    (0x20F, 'V'),
    +    (0x210, 'M', 'ȑ'),
    +    (0x211, 'V'),
    +    (0x212, 'M', 'ȓ'),
    +    (0x213, 'V'),
    +    (0x214, 'M', 'ȕ'),
    +    (0x215, 'V'),
    +    (0x216, 'M', 'ȗ'),
    +    (0x217, 'V'),
    +    (0x218, 'M', 'ș'),
    +    (0x219, 'V'),
    +    (0x21A, 'M', 'ț'),
    +    (0x21B, 'V'),
    +    (0x21C, 'M', 'ȝ'),
    +    (0x21D, 'V'),
    +    (0x21E, 'M', 'ȟ'),
    +    (0x21F, 'V'),
    +    (0x220, 'M', 'ƞ'),
    +    (0x221, 'V'),
    +    (0x222, 'M', 'ȣ'),
    +    (0x223, 'V'),
    +    (0x224, 'M', 'ȥ'),
    +    (0x225, 'V'),
    +    (0x226, 'M', 'ȧ'),
    +    (0x227, 'V'),
    +    (0x228, 'M', 'ȩ'),
    +    (0x229, 'V'),
    +    (0x22A, 'M', 'ȫ'),
    +    (0x22B, 'V'),
    +    (0x22C, 'M', 'ȭ'),
    +    (0x22D, 'V'),
    +    (0x22E, 'M', 'ȯ'),
    +    (0x22F, 'V'),
    +    (0x230, 'M', 'ȱ'),
    +    (0x231, 'V'),
    +    (0x232, 'M', 'ȳ'),
    +    (0x233, 'V'),
    +    (0x23A, 'M', 'ⱥ'),
    +    (0x23B, 'M', 'ȼ'),
    +    (0x23C, 'V'),
    +    (0x23D, 'M', 'ƚ'),
    +    (0x23E, 'M', 'ⱦ'),
    +    (0x23F, 'V'),
    +    (0x241, 'M', 'ɂ'),
    +    (0x242, 'V'),
    +    (0x243, 'M', 'ƀ'),
    +    (0x244, 'M', 'ʉ'),
    +    (0x245, 'M', 'ʌ'),
    +    (0x246, 'M', 'ɇ'),
    +    (0x247, 'V'),
    +    (0x248, 'M', 'ɉ'),
    +    (0x249, 'V'),
    +    (0x24A, 'M', 'ɋ'),
    +    (0x24B, 'V'),
    +    (0x24C, 'M', 'ɍ'),
    +    (0x24D, 'V'),
    +    (0x24E, 'M', 'ɏ'),
    +    (0x24F, 'V'),
    +    (0x2B0, 'M', 'h'),
    +    (0x2B1, 'M', 'ɦ'),
    +    (0x2B2, 'M', 'j'),
    +    (0x2B3, 'M', 'r'),
    +    (0x2B4, 'M', 'ɹ'),
    +    (0x2B5, 'M', 'ɻ'),
    +    (0x2B6, 'M', 'ʁ'),
    +    (0x2B7, 'M', 'w'),
    +    (0x2B8, 'M', 'y'),
    +    (0x2B9, 'V'),
    +    (0x2D8, '3', ' ̆'),
    +    (0x2D9, '3', ' ̇'),
    +    (0x2DA, '3', ' ̊'),
    +    (0x2DB, '3', ' ̨'),
    +    (0x2DC, '3', ' ̃'),
    +    (0x2DD, '3', ' ̋'),
    +    (0x2DE, 'V'),
    +    (0x2E0, 'M', 'ɣ'),
    +    (0x2E1, 'M', 'l'),
    +    (0x2E2, 'M', 's'),
    +    (0x2E3, 'M', 'x'),
    +    (0x2E4, 'M', 'ʕ'),
    +    (0x2E5, 'V'),
    +    (0x340, 'M', '̀'),
    +    (0x341, 'M', '́'),
    +    (0x342, 'V'),
    +    (0x343, 'M', '̓'),
    +    (0x344, 'M', '̈́'),
    +    (0x345, 'M', 'ι'),
    +    (0x346, 'V'),
    +    (0x34F, 'I'),
    +    (0x350, 'V'),
    +    (0x370, 'M', 'ͱ'),
    +    (0x371, 'V'),
    +    (0x372, 'M', 'ͳ'),
    +    (0x373, 'V'),
    +    (0x374, 'M', 'ʹ'),
    +    (0x375, 'V'),
    +    (0x376, 'M', 'ͷ'),
    +    (0x377, 'V'),
    +    ]
    +
    +def _seg_6() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x378, 'X'),
    +    (0x37A, '3', ' ι'),
    +    (0x37B, 'V'),
    +    (0x37E, '3', ';'),
    +    (0x37F, 'M', 'ϳ'),
    +    (0x380, 'X'),
    +    (0x384, '3', ' ́'),
    +    (0x385, '3', ' ̈́'),
    +    (0x386, 'M', 'ά'),
    +    (0x387, 'M', '·'),
    +    (0x388, 'M', 'έ'),
    +    (0x389, 'M', 'ή'),
    +    (0x38A, 'M', 'ί'),
    +    (0x38B, 'X'),
    +    (0x38C, 'M', 'ό'),
    +    (0x38D, 'X'),
    +    (0x38E, 'M', 'ύ'),
    +    (0x38F, 'M', 'ώ'),
    +    (0x390, 'V'),
    +    (0x391, 'M', 'α'),
    +    (0x392, 'M', 'β'),
    +    (0x393, 'M', 'γ'),
    +    (0x394, 'M', 'δ'),
    +    (0x395, 'M', 'ε'),
    +    (0x396, 'M', 'ζ'),
    +    (0x397, 'M', 'η'),
    +    (0x398, 'M', 'θ'),
    +    (0x399, 'M', 'ι'),
    +    (0x39A, 'M', 'κ'),
    +    (0x39B, 'M', 'λ'),
    +    (0x39C, 'M', 'μ'),
    +    (0x39D, 'M', 'ν'),
    +    (0x39E, 'M', 'ξ'),
    +    (0x39F, 'M', 'ο'),
    +    (0x3A0, 'M', 'π'),
    +    (0x3A1, 'M', 'ρ'),
    +    (0x3A2, 'X'),
    +    (0x3A3, 'M', 'σ'),
    +    (0x3A4, 'M', 'τ'),
    +    (0x3A5, 'M', 'υ'),
    +    (0x3A6, 'M', 'φ'),
    +    (0x3A7, 'M', 'χ'),
    +    (0x3A8, 'M', 'ψ'),
    +    (0x3A9, 'M', 'ω'),
    +    (0x3AA, 'M', 'ϊ'),
    +    (0x3AB, 'M', 'ϋ'),
    +    (0x3AC, 'V'),
    +    (0x3C2, 'D', 'σ'),
    +    (0x3C3, 'V'),
    +    (0x3CF, 'M', 'ϗ'),
    +    (0x3D0, 'M', 'β'),
    +    (0x3D1, 'M', 'θ'),
    +    (0x3D2, 'M', 'υ'),
    +    (0x3D3, 'M', 'ύ'),
    +    (0x3D4, 'M', 'ϋ'),
    +    (0x3D5, 'M', 'φ'),
    +    (0x3D6, 'M', 'π'),
    +    (0x3D7, 'V'),
    +    (0x3D8, 'M', 'ϙ'),
    +    (0x3D9, 'V'),
    +    (0x3DA, 'M', 'ϛ'),
    +    (0x3DB, 'V'),
    +    (0x3DC, 'M', 'ϝ'),
    +    (0x3DD, 'V'),
    +    (0x3DE, 'M', 'ϟ'),
    +    (0x3DF, 'V'),
    +    (0x3E0, 'M', 'ϡ'),
    +    (0x3E1, 'V'),
    +    (0x3E2, 'M', 'ϣ'),
    +    (0x3E3, 'V'),
    +    (0x3E4, 'M', 'ϥ'),
    +    (0x3E5, 'V'),
    +    (0x3E6, 'M', 'ϧ'),
    +    (0x3E7, 'V'),
    +    (0x3E8, 'M', 'ϩ'),
    +    (0x3E9, 'V'),
    +    (0x3EA, 'M', 'ϫ'),
    +    (0x3EB, 'V'),
    +    (0x3EC, 'M', 'ϭ'),
    +    (0x3ED, 'V'),
    +    (0x3EE, 'M', 'ϯ'),
    +    (0x3EF, 'V'),
    +    (0x3F0, 'M', 'κ'),
    +    (0x3F1, 'M', 'ρ'),
    +    (0x3F2, 'M', 'σ'),
    +    (0x3F3, 'V'),
    +    (0x3F4, 'M', 'θ'),
    +    (0x3F5, 'M', 'ε'),
    +    (0x3F6, 'V'),
    +    (0x3F7, 'M', 'ϸ'),
    +    (0x3F8, 'V'),
    +    (0x3F9, 'M', 'σ'),
    +    (0x3FA, 'M', 'ϻ'),
    +    (0x3FB, 'V'),
    +    (0x3FD, 'M', 'ͻ'),
    +    (0x3FE, 'M', 'ͼ'),
    +    (0x3FF, 'M', 'ͽ'),
    +    (0x400, 'M', 'ѐ'),
    +    (0x401, 'M', 'ё'),
    +    (0x402, 'M', 'ђ'),
    +    ]
    +
    +def _seg_7() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x403, 'M', 'ѓ'),
    +    (0x404, 'M', 'є'),
    +    (0x405, 'M', 'ѕ'),
    +    (0x406, 'M', 'і'),
    +    (0x407, 'M', 'ї'),
    +    (0x408, 'M', 'ј'),
    +    (0x409, 'M', 'љ'),
    +    (0x40A, 'M', 'њ'),
    +    (0x40B, 'M', 'ћ'),
    +    (0x40C, 'M', 'ќ'),
    +    (0x40D, 'M', 'ѝ'),
    +    (0x40E, 'M', 'ў'),
    +    (0x40F, 'M', 'џ'),
    +    (0x410, 'M', 'а'),
    +    (0x411, 'M', 'б'),
    +    (0x412, 'M', 'в'),
    +    (0x413, 'M', 'г'),
    +    (0x414, 'M', 'д'),
    +    (0x415, 'M', 'е'),
    +    (0x416, 'M', 'ж'),
    +    (0x417, 'M', 'з'),
    +    (0x418, 'M', 'и'),
    +    (0x419, 'M', 'й'),
    +    (0x41A, 'M', 'к'),
    +    (0x41B, 'M', 'л'),
    +    (0x41C, 'M', 'м'),
    +    (0x41D, 'M', 'н'),
    +    (0x41E, 'M', 'о'),
    +    (0x41F, 'M', 'п'),
    +    (0x420, 'M', 'р'),
    +    (0x421, 'M', 'с'),
    +    (0x422, 'M', 'т'),
    +    (0x423, 'M', 'у'),
    +    (0x424, 'M', 'ф'),
    +    (0x425, 'M', 'х'),
    +    (0x426, 'M', 'ц'),
    +    (0x427, 'M', 'ч'),
    +    (0x428, 'M', 'ш'),
    +    (0x429, 'M', 'щ'),
    +    (0x42A, 'M', 'ъ'),
    +    (0x42B, 'M', 'ы'),
    +    (0x42C, 'M', 'ь'),
    +    (0x42D, 'M', 'э'),
    +    (0x42E, 'M', 'ю'),
    +    (0x42F, 'M', 'я'),
    +    (0x430, 'V'),
    +    (0x460, 'M', 'ѡ'),
    +    (0x461, 'V'),
    +    (0x462, 'M', 'ѣ'),
    +    (0x463, 'V'),
    +    (0x464, 'M', 'ѥ'),
    +    (0x465, 'V'),
    +    (0x466, 'M', 'ѧ'),
    +    (0x467, 'V'),
    +    (0x468, 'M', 'ѩ'),
    +    (0x469, 'V'),
    +    (0x46A, 'M', 'ѫ'),
    +    (0x46B, 'V'),
    +    (0x46C, 'M', 'ѭ'),
    +    (0x46D, 'V'),
    +    (0x46E, 'M', 'ѯ'),
    +    (0x46F, 'V'),
    +    (0x470, 'M', 'ѱ'),
    +    (0x471, 'V'),
    +    (0x472, 'M', 'ѳ'),
    +    (0x473, 'V'),
    +    (0x474, 'M', 'ѵ'),
    +    (0x475, 'V'),
    +    (0x476, 'M', 'ѷ'),
    +    (0x477, 'V'),
    +    (0x478, 'M', 'ѹ'),
    +    (0x479, 'V'),
    +    (0x47A, 'M', 'ѻ'),
    +    (0x47B, 'V'),
    +    (0x47C, 'M', 'ѽ'),
    +    (0x47D, 'V'),
    +    (0x47E, 'M', 'ѿ'),
    +    (0x47F, 'V'),
    +    (0x480, 'M', 'ҁ'),
    +    (0x481, 'V'),
    +    (0x48A, 'M', 'ҋ'),
    +    (0x48B, 'V'),
    +    (0x48C, 'M', 'ҍ'),
    +    (0x48D, 'V'),
    +    (0x48E, 'M', 'ҏ'),
    +    (0x48F, 'V'),
    +    (0x490, 'M', 'ґ'),
    +    (0x491, 'V'),
    +    (0x492, 'M', 'ғ'),
    +    (0x493, 'V'),
    +    (0x494, 'M', 'ҕ'),
    +    (0x495, 'V'),
    +    (0x496, 'M', 'җ'),
    +    (0x497, 'V'),
    +    (0x498, 'M', 'ҙ'),
    +    (0x499, 'V'),
    +    (0x49A, 'M', 'қ'),
    +    (0x49B, 'V'),
    +    (0x49C, 'M', 'ҝ'),
    +    (0x49D, 'V'),
    +    ]
    +
    +def _seg_8() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x49E, 'M', 'ҟ'),
    +    (0x49F, 'V'),
    +    (0x4A0, 'M', 'ҡ'),
    +    (0x4A1, 'V'),
    +    (0x4A2, 'M', 'ң'),
    +    (0x4A3, 'V'),
    +    (0x4A4, 'M', 'ҥ'),
    +    (0x4A5, 'V'),
    +    (0x4A6, 'M', 'ҧ'),
    +    (0x4A7, 'V'),
    +    (0x4A8, 'M', 'ҩ'),
    +    (0x4A9, 'V'),
    +    (0x4AA, 'M', 'ҫ'),
    +    (0x4AB, 'V'),
    +    (0x4AC, 'M', 'ҭ'),
    +    (0x4AD, 'V'),
    +    (0x4AE, 'M', 'ү'),
    +    (0x4AF, 'V'),
    +    (0x4B0, 'M', 'ұ'),
    +    (0x4B1, 'V'),
    +    (0x4B2, 'M', 'ҳ'),
    +    (0x4B3, 'V'),
    +    (0x4B4, 'M', 'ҵ'),
    +    (0x4B5, 'V'),
    +    (0x4B6, 'M', 'ҷ'),
    +    (0x4B7, 'V'),
    +    (0x4B8, 'M', 'ҹ'),
    +    (0x4B9, 'V'),
    +    (0x4BA, 'M', 'һ'),
    +    (0x4BB, 'V'),
    +    (0x4BC, 'M', 'ҽ'),
    +    (0x4BD, 'V'),
    +    (0x4BE, 'M', 'ҿ'),
    +    (0x4BF, 'V'),
    +    (0x4C0, 'X'),
    +    (0x4C1, 'M', 'ӂ'),
    +    (0x4C2, 'V'),
    +    (0x4C3, 'M', 'ӄ'),
    +    (0x4C4, 'V'),
    +    (0x4C5, 'M', 'ӆ'),
    +    (0x4C6, 'V'),
    +    (0x4C7, 'M', 'ӈ'),
    +    (0x4C8, 'V'),
    +    (0x4C9, 'M', 'ӊ'),
    +    (0x4CA, 'V'),
    +    (0x4CB, 'M', 'ӌ'),
    +    (0x4CC, 'V'),
    +    (0x4CD, 'M', 'ӎ'),
    +    (0x4CE, 'V'),
    +    (0x4D0, 'M', 'ӑ'),
    +    (0x4D1, 'V'),
    +    (0x4D2, 'M', 'ӓ'),
    +    (0x4D3, 'V'),
    +    (0x4D4, 'M', 'ӕ'),
    +    (0x4D5, 'V'),
    +    (0x4D6, 'M', 'ӗ'),
    +    (0x4D7, 'V'),
    +    (0x4D8, 'M', 'ә'),
    +    (0x4D9, 'V'),
    +    (0x4DA, 'M', 'ӛ'),
    +    (0x4DB, 'V'),
    +    (0x4DC, 'M', 'ӝ'),
    +    (0x4DD, 'V'),
    +    (0x4DE, 'M', 'ӟ'),
    +    (0x4DF, 'V'),
    +    (0x4E0, 'M', 'ӡ'),
    +    (0x4E1, 'V'),
    +    (0x4E2, 'M', 'ӣ'),
    +    (0x4E3, 'V'),
    +    (0x4E4, 'M', 'ӥ'),
    +    (0x4E5, 'V'),
    +    (0x4E6, 'M', 'ӧ'),
    +    (0x4E7, 'V'),
    +    (0x4E8, 'M', 'ө'),
    +    (0x4E9, 'V'),
    +    (0x4EA, 'M', 'ӫ'),
    +    (0x4EB, 'V'),
    +    (0x4EC, 'M', 'ӭ'),
    +    (0x4ED, 'V'),
    +    (0x4EE, 'M', 'ӯ'),
    +    (0x4EF, 'V'),
    +    (0x4F0, 'M', 'ӱ'),
    +    (0x4F1, 'V'),
    +    (0x4F2, 'M', 'ӳ'),
    +    (0x4F3, 'V'),
    +    (0x4F4, 'M', 'ӵ'),
    +    (0x4F5, 'V'),
    +    (0x4F6, 'M', 'ӷ'),
    +    (0x4F7, 'V'),
    +    (0x4F8, 'M', 'ӹ'),
    +    (0x4F9, 'V'),
    +    (0x4FA, 'M', 'ӻ'),
    +    (0x4FB, 'V'),
    +    (0x4FC, 'M', 'ӽ'),
    +    (0x4FD, 'V'),
    +    (0x4FE, 'M', 'ӿ'),
    +    (0x4FF, 'V'),
    +    (0x500, 'M', 'ԁ'),
    +    (0x501, 'V'),
    +    (0x502, 'M', 'ԃ'),
    +    ]
    +
    +def _seg_9() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x503, 'V'),
    +    (0x504, 'M', 'ԅ'),
    +    (0x505, 'V'),
    +    (0x506, 'M', 'ԇ'),
    +    (0x507, 'V'),
    +    (0x508, 'M', 'ԉ'),
    +    (0x509, 'V'),
    +    (0x50A, 'M', 'ԋ'),
    +    (0x50B, 'V'),
    +    (0x50C, 'M', 'ԍ'),
    +    (0x50D, 'V'),
    +    (0x50E, 'M', 'ԏ'),
    +    (0x50F, 'V'),
    +    (0x510, 'M', 'ԑ'),
    +    (0x511, 'V'),
    +    (0x512, 'M', 'ԓ'),
    +    (0x513, 'V'),
    +    (0x514, 'M', 'ԕ'),
    +    (0x515, 'V'),
    +    (0x516, 'M', 'ԗ'),
    +    (0x517, 'V'),
    +    (0x518, 'M', 'ԙ'),
    +    (0x519, 'V'),
    +    (0x51A, 'M', 'ԛ'),
    +    (0x51B, 'V'),
    +    (0x51C, 'M', 'ԝ'),
    +    (0x51D, 'V'),
    +    (0x51E, 'M', 'ԟ'),
    +    (0x51F, 'V'),
    +    (0x520, 'M', 'ԡ'),
    +    (0x521, 'V'),
    +    (0x522, 'M', 'ԣ'),
    +    (0x523, 'V'),
    +    (0x524, 'M', 'ԥ'),
    +    (0x525, 'V'),
    +    (0x526, 'M', 'ԧ'),
    +    (0x527, 'V'),
    +    (0x528, 'M', 'ԩ'),
    +    (0x529, 'V'),
    +    (0x52A, 'M', 'ԫ'),
    +    (0x52B, 'V'),
    +    (0x52C, 'M', 'ԭ'),
    +    (0x52D, 'V'),
    +    (0x52E, 'M', 'ԯ'),
    +    (0x52F, 'V'),
    +    (0x530, 'X'),
    +    (0x531, 'M', 'ա'),
    +    (0x532, 'M', 'բ'),
    +    (0x533, 'M', 'գ'),
    +    (0x534, 'M', 'դ'),
    +    (0x535, 'M', 'ե'),
    +    (0x536, 'M', 'զ'),
    +    (0x537, 'M', 'է'),
    +    (0x538, 'M', 'ը'),
    +    (0x539, 'M', 'թ'),
    +    (0x53A, 'M', 'ժ'),
    +    (0x53B, 'M', 'ի'),
    +    (0x53C, 'M', 'լ'),
    +    (0x53D, 'M', 'խ'),
    +    (0x53E, 'M', 'ծ'),
    +    (0x53F, 'M', 'կ'),
    +    (0x540, 'M', 'հ'),
    +    (0x541, 'M', 'ձ'),
    +    (0x542, 'M', 'ղ'),
    +    (0x543, 'M', 'ճ'),
    +    (0x544, 'M', 'մ'),
    +    (0x545, 'M', 'յ'),
    +    (0x546, 'M', 'ն'),
    +    (0x547, 'M', 'շ'),
    +    (0x548, 'M', 'ո'),
    +    (0x549, 'M', 'չ'),
    +    (0x54A, 'M', 'պ'),
    +    (0x54B, 'M', 'ջ'),
    +    (0x54C, 'M', 'ռ'),
    +    (0x54D, 'M', 'ս'),
    +    (0x54E, 'M', 'վ'),
    +    (0x54F, 'M', 'տ'),
    +    (0x550, 'M', 'ր'),
    +    (0x551, 'M', 'ց'),
    +    (0x552, 'M', 'ւ'),
    +    (0x553, 'M', 'փ'),
    +    (0x554, 'M', 'ք'),
    +    (0x555, 'M', 'օ'),
    +    (0x556, 'M', 'ֆ'),
    +    (0x557, 'X'),
    +    (0x559, 'V'),
    +    (0x587, 'M', 'եւ'),
    +    (0x588, 'V'),
    +    (0x58B, 'X'),
    +    (0x58D, 'V'),
    +    (0x590, 'X'),
    +    (0x591, 'V'),
    +    (0x5C8, 'X'),
    +    (0x5D0, 'V'),
    +    (0x5EB, 'X'),
    +    (0x5EF, 'V'),
    +    (0x5F5, 'X'),
    +    (0x606, 'V'),
    +    (0x61C, 'X'),
    +    (0x61D, 'V'),
    +    ]
    +
    +def _seg_10() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x675, 'M', 'اٴ'),
    +    (0x676, 'M', 'وٴ'),
    +    (0x677, 'M', 'ۇٴ'),
    +    (0x678, 'M', 'يٴ'),
    +    (0x679, 'V'),
    +    (0x6DD, 'X'),
    +    (0x6DE, 'V'),
    +    (0x70E, 'X'),
    +    (0x710, 'V'),
    +    (0x74B, 'X'),
    +    (0x74D, 'V'),
    +    (0x7B2, 'X'),
    +    (0x7C0, 'V'),
    +    (0x7FB, 'X'),
    +    (0x7FD, 'V'),
    +    (0x82E, 'X'),
    +    (0x830, 'V'),
    +    (0x83F, 'X'),
    +    (0x840, 'V'),
    +    (0x85C, 'X'),
    +    (0x85E, 'V'),
    +    (0x85F, 'X'),
    +    (0x860, 'V'),
    +    (0x86B, 'X'),
    +    (0x870, 'V'),
    +    (0x88F, 'X'),
    +    (0x898, 'V'),
    +    (0x8E2, 'X'),
    +    (0x8E3, 'V'),
    +    (0x958, 'M', 'क़'),
    +    (0x959, 'M', 'ख़'),
    +    (0x95A, 'M', 'ग़'),
    +    (0x95B, 'M', 'ज़'),
    +    (0x95C, 'M', 'ड़'),
    +    (0x95D, 'M', 'ढ़'),
    +    (0x95E, 'M', 'फ़'),
    +    (0x95F, 'M', 'य़'),
    +    (0x960, 'V'),
    +    (0x984, 'X'),
    +    (0x985, 'V'),
    +    (0x98D, 'X'),
    +    (0x98F, 'V'),
    +    (0x991, 'X'),
    +    (0x993, 'V'),
    +    (0x9A9, 'X'),
    +    (0x9AA, 'V'),
    +    (0x9B1, 'X'),
    +    (0x9B2, 'V'),
    +    (0x9B3, 'X'),
    +    (0x9B6, 'V'),
    +    (0x9BA, 'X'),
    +    (0x9BC, 'V'),
    +    (0x9C5, 'X'),
    +    (0x9C7, 'V'),
    +    (0x9C9, 'X'),
    +    (0x9CB, 'V'),
    +    (0x9CF, 'X'),
    +    (0x9D7, 'V'),
    +    (0x9D8, 'X'),
    +    (0x9DC, 'M', 'ড়'),
    +    (0x9DD, 'M', 'ঢ়'),
    +    (0x9DE, 'X'),
    +    (0x9DF, 'M', 'য়'),
    +    (0x9E0, 'V'),
    +    (0x9E4, 'X'),
    +    (0x9E6, 'V'),
    +    (0x9FF, 'X'),
    +    (0xA01, 'V'),
    +    (0xA04, 'X'),
    +    (0xA05, 'V'),
    +    (0xA0B, 'X'),
    +    (0xA0F, 'V'),
    +    (0xA11, 'X'),
    +    (0xA13, 'V'),
    +    (0xA29, 'X'),
    +    (0xA2A, 'V'),
    +    (0xA31, 'X'),
    +    (0xA32, 'V'),
    +    (0xA33, 'M', 'ਲ਼'),
    +    (0xA34, 'X'),
    +    (0xA35, 'V'),
    +    (0xA36, 'M', 'ਸ਼'),
    +    (0xA37, 'X'),
    +    (0xA38, 'V'),
    +    (0xA3A, 'X'),
    +    (0xA3C, 'V'),
    +    (0xA3D, 'X'),
    +    (0xA3E, 'V'),
    +    (0xA43, 'X'),
    +    (0xA47, 'V'),
    +    (0xA49, 'X'),
    +    (0xA4B, 'V'),
    +    (0xA4E, 'X'),
    +    (0xA51, 'V'),
    +    (0xA52, 'X'),
    +    (0xA59, 'M', 'ਖ਼'),
    +    (0xA5A, 'M', 'ਗ਼'),
    +    (0xA5B, 'M', 'ਜ਼'),
    +    (0xA5C, 'V'),
    +    (0xA5D, 'X'),
    +    ]
    +
    +def _seg_11() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xA5E, 'M', 'ਫ਼'),
    +    (0xA5F, 'X'),
    +    (0xA66, 'V'),
    +    (0xA77, 'X'),
    +    (0xA81, 'V'),
    +    (0xA84, 'X'),
    +    (0xA85, 'V'),
    +    (0xA8E, 'X'),
    +    (0xA8F, 'V'),
    +    (0xA92, 'X'),
    +    (0xA93, 'V'),
    +    (0xAA9, 'X'),
    +    (0xAAA, 'V'),
    +    (0xAB1, 'X'),
    +    (0xAB2, 'V'),
    +    (0xAB4, 'X'),
    +    (0xAB5, 'V'),
    +    (0xABA, 'X'),
    +    (0xABC, 'V'),
    +    (0xAC6, 'X'),
    +    (0xAC7, 'V'),
    +    (0xACA, 'X'),
    +    (0xACB, 'V'),
    +    (0xACE, 'X'),
    +    (0xAD0, 'V'),
    +    (0xAD1, 'X'),
    +    (0xAE0, 'V'),
    +    (0xAE4, 'X'),
    +    (0xAE6, 'V'),
    +    (0xAF2, 'X'),
    +    (0xAF9, 'V'),
    +    (0xB00, 'X'),
    +    (0xB01, 'V'),
    +    (0xB04, 'X'),
    +    (0xB05, 'V'),
    +    (0xB0D, 'X'),
    +    (0xB0F, 'V'),
    +    (0xB11, 'X'),
    +    (0xB13, 'V'),
    +    (0xB29, 'X'),
    +    (0xB2A, 'V'),
    +    (0xB31, 'X'),
    +    (0xB32, 'V'),
    +    (0xB34, 'X'),
    +    (0xB35, 'V'),
    +    (0xB3A, 'X'),
    +    (0xB3C, 'V'),
    +    (0xB45, 'X'),
    +    (0xB47, 'V'),
    +    (0xB49, 'X'),
    +    (0xB4B, 'V'),
    +    (0xB4E, 'X'),
    +    (0xB55, 'V'),
    +    (0xB58, 'X'),
    +    (0xB5C, 'M', 'ଡ଼'),
    +    (0xB5D, 'M', 'ଢ଼'),
    +    (0xB5E, 'X'),
    +    (0xB5F, 'V'),
    +    (0xB64, 'X'),
    +    (0xB66, 'V'),
    +    (0xB78, 'X'),
    +    (0xB82, 'V'),
    +    (0xB84, 'X'),
    +    (0xB85, 'V'),
    +    (0xB8B, 'X'),
    +    (0xB8E, 'V'),
    +    (0xB91, 'X'),
    +    (0xB92, 'V'),
    +    (0xB96, 'X'),
    +    (0xB99, 'V'),
    +    (0xB9B, 'X'),
    +    (0xB9C, 'V'),
    +    (0xB9D, 'X'),
    +    (0xB9E, 'V'),
    +    (0xBA0, 'X'),
    +    (0xBA3, 'V'),
    +    (0xBA5, 'X'),
    +    (0xBA8, 'V'),
    +    (0xBAB, 'X'),
    +    (0xBAE, 'V'),
    +    (0xBBA, 'X'),
    +    (0xBBE, 'V'),
    +    (0xBC3, 'X'),
    +    (0xBC6, 'V'),
    +    (0xBC9, 'X'),
    +    (0xBCA, 'V'),
    +    (0xBCE, 'X'),
    +    (0xBD0, 'V'),
    +    (0xBD1, 'X'),
    +    (0xBD7, 'V'),
    +    (0xBD8, 'X'),
    +    (0xBE6, 'V'),
    +    (0xBFB, 'X'),
    +    (0xC00, 'V'),
    +    (0xC0D, 'X'),
    +    (0xC0E, 'V'),
    +    (0xC11, 'X'),
    +    (0xC12, 'V'),
    +    (0xC29, 'X'),
    +    (0xC2A, 'V'),
    +    ]
    +
    +def _seg_12() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xC3A, 'X'),
    +    (0xC3C, 'V'),
    +    (0xC45, 'X'),
    +    (0xC46, 'V'),
    +    (0xC49, 'X'),
    +    (0xC4A, 'V'),
    +    (0xC4E, 'X'),
    +    (0xC55, 'V'),
    +    (0xC57, 'X'),
    +    (0xC58, 'V'),
    +    (0xC5B, 'X'),
    +    (0xC5D, 'V'),
    +    (0xC5E, 'X'),
    +    (0xC60, 'V'),
    +    (0xC64, 'X'),
    +    (0xC66, 'V'),
    +    (0xC70, 'X'),
    +    (0xC77, 'V'),
    +    (0xC8D, 'X'),
    +    (0xC8E, 'V'),
    +    (0xC91, 'X'),
    +    (0xC92, 'V'),
    +    (0xCA9, 'X'),
    +    (0xCAA, 'V'),
    +    (0xCB4, 'X'),
    +    (0xCB5, 'V'),
    +    (0xCBA, 'X'),
    +    (0xCBC, 'V'),
    +    (0xCC5, 'X'),
    +    (0xCC6, 'V'),
    +    (0xCC9, 'X'),
    +    (0xCCA, 'V'),
    +    (0xCCE, 'X'),
    +    (0xCD5, 'V'),
    +    (0xCD7, 'X'),
    +    (0xCDD, 'V'),
    +    (0xCDF, 'X'),
    +    (0xCE0, 'V'),
    +    (0xCE4, 'X'),
    +    (0xCE6, 'V'),
    +    (0xCF0, 'X'),
    +    (0xCF1, 'V'),
    +    (0xCF4, 'X'),
    +    (0xD00, 'V'),
    +    (0xD0D, 'X'),
    +    (0xD0E, 'V'),
    +    (0xD11, 'X'),
    +    (0xD12, 'V'),
    +    (0xD45, 'X'),
    +    (0xD46, 'V'),
    +    (0xD49, 'X'),
    +    (0xD4A, 'V'),
    +    (0xD50, 'X'),
    +    (0xD54, 'V'),
    +    (0xD64, 'X'),
    +    (0xD66, 'V'),
    +    (0xD80, 'X'),
    +    (0xD81, 'V'),
    +    (0xD84, 'X'),
    +    (0xD85, 'V'),
    +    (0xD97, 'X'),
    +    (0xD9A, 'V'),
    +    (0xDB2, 'X'),
    +    (0xDB3, 'V'),
    +    (0xDBC, 'X'),
    +    (0xDBD, 'V'),
    +    (0xDBE, 'X'),
    +    (0xDC0, 'V'),
    +    (0xDC7, 'X'),
    +    (0xDCA, 'V'),
    +    (0xDCB, 'X'),
    +    (0xDCF, 'V'),
    +    (0xDD5, 'X'),
    +    (0xDD6, 'V'),
    +    (0xDD7, 'X'),
    +    (0xDD8, 'V'),
    +    (0xDE0, 'X'),
    +    (0xDE6, 'V'),
    +    (0xDF0, 'X'),
    +    (0xDF2, 'V'),
    +    (0xDF5, 'X'),
    +    (0xE01, 'V'),
    +    (0xE33, 'M', 'ํา'),
    +    (0xE34, 'V'),
    +    (0xE3B, 'X'),
    +    (0xE3F, 'V'),
    +    (0xE5C, 'X'),
    +    (0xE81, 'V'),
    +    (0xE83, 'X'),
    +    (0xE84, 'V'),
    +    (0xE85, 'X'),
    +    (0xE86, 'V'),
    +    (0xE8B, 'X'),
    +    (0xE8C, 'V'),
    +    (0xEA4, 'X'),
    +    (0xEA5, 'V'),
    +    (0xEA6, 'X'),
    +    (0xEA7, 'V'),
    +    (0xEB3, 'M', 'ໍາ'),
    +    (0xEB4, 'V'),
    +    ]
    +
    +def _seg_13() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xEBE, 'X'),
    +    (0xEC0, 'V'),
    +    (0xEC5, 'X'),
    +    (0xEC6, 'V'),
    +    (0xEC7, 'X'),
    +    (0xEC8, 'V'),
    +    (0xECF, 'X'),
    +    (0xED0, 'V'),
    +    (0xEDA, 'X'),
    +    (0xEDC, 'M', 'ຫນ'),
    +    (0xEDD, 'M', 'ຫມ'),
    +    (0xEDE, 'V'),
    +    (0xEE0, 'X'),
    +    (0xF00, 'V'),
    +    (0xF0C, 'M', '་'),
    +    (0xF0D, 'V'),
    +    (0xF43, 'M', 'གྷ'),
    +    (0xF44, 'V'),
    +    (0xF48, 'X'),
    +    (0xF49, 'V'),
    +    (0xF4D, 'M', 'ཌྷ'),
    +    (0xF4E, 'V'),
    +    (0xF52, 'M', 'དྷ'),
    +    (0xF53, 'V'),
    +    (0xF57, 'M', 'བྷ'),
    +    (0xF58, 'V'),
    +    (0xF5C, 'M', 'ཛྷ'),
    +    (0xF5D, 'V'),
    +    (0xF69, 'M', 'ཀྵ'),
    +    (0xF6A, 'V'),
    +    (0xF6D, 'X'),
    +    (0xF71, 'V'),
    +    (0xF73, 'M', 'ཱི'),
    +    (0xF74, 'V'),
    +    (0xF75, 'M', 'ཱུ'),
    +    (0xF76, 'M', 'ྲྀ'),
    +    (0xF77, 'M', 'ྲཱྀ'),
    +    (0xF78, 'M', 'ླྀ'),
    +    (0xF79, 'M', 'ླཱྀ'),
    +    (0xF7A, 'V'),
    +    (0xF81, 'M', 'ཱྀ'),
    +    (0xF82, 'V'),
    +    (0xF93, 'M', 'ྒྷ'),
    +    (0xF94, 'V'),
    +    (0xF98, 'X'),
    +    (0xF99, 'V'),
    +    (0xF9D, 'M', 'ྜྷ'),
    +    (0xF9E, 'V'),
    +    (0xFA2, 'M', 'ྡྷ'),
    +    (0xFA3, 'V'),
    +    (0xFA7, 'M', 'ྦྷ'),
    +    (0xFA8, 'V'),
    +    (0xFAC, 'M', 'ྫྷ'),
    +    (0xFAD, 'V'),
    +    (0xFB9, 'M', 'ྐྵ'),
    +    (0xFBA, 'V'),
    +    (0xFBD, 'X'),
    +    (0xFBE, 'V'),
    +    (0xFCD, 'X'),
    +    (0xFCE, 'V'),
    +    (0xFDB, 'X'),
    +    (0x1000, 'V'),
    +    (0x10A0, 'X'),
    +    (0x10C7, 'M', 'ⴧ'),
    +    (0x10C8, 'X'),
    +    (0x10CD, 'M', 'ⴭ'),
    +    (0x10CE, 'X'),
    +    (0x10D0, 'V'),
    +    (0x10FC, 'M', 'ნ'),
    +    (0x10FD, 'V'),
    +    (0x115F, 'X'),
    +    (0x1161, 'V'),
    +    (0x1249, 'X'),
    +    (0x124A, 'V'),
    +    (0x124E, 'X'),
    +    (0x1250, 'V'),
    +    (0x1257, 'X'),
    +    (0x1258, 'V'),
    +    (0x1259, 'X'),
    +    (0x125A, 'V'),
    +    (0x125E, 'X'),
    +    (0x1260, 'V'),
    +    (0x1289, 'X'),
    +    (0x128A, 'V'),
    +    (0x128E, 'X'),
    +    (0x1290, 'V'),
    +    (0x12B1, 'X'),
    +    (0x12B2, 'V'),
    +    (0x12B6, 'X'),
    +    (0x12B8, 'V'),
    +    (0x12BF, 'X'),
    +    (0x12C0, 'V'),
    +    (0x12C1, 'X'),
    +    (0x12C2, 'V'),
    +    (0x12C6, 'X'),
    +    (0x12C8, 'V'),
    +    (0x12D7, 'X'),
    +    (0x12D8, 'V'),
    +    (0x1311, 'X'),
    +    (0x1312, 'V'),
    +    ]
    +
    +def _seg_14() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1316, 'X'),
    +    (0x1318, 'V'),
    +    (0x135B, 'X'),
    +    (0x135D, 'V'),
    +    (0x137D, 'X'),
    +    (0x1380, 'V'),
    +    (0x139A, 'X'),
    +    (0x13A0, 'V'),
    +    (0x13F6, 'X'),
    +    (0x13F8, 'M', 'Ᏸ'),
    +    (0x13F9, 'M', 'Ᏹ'),
    +    (0x13FA, 'M', 'Ᏺ'),
    +    (0x13FB, 'M', 'Ᏻ'),
    +    (0x13FC, 'M', 'Ᏼ'),
    +    (0x13FD, 'M', 'Ᏽ'),
    +    (0x13FE, 'X'),
    +    (0x1400, 'V'),
    +    (0x1680, 'X'),
    +    (0x1681, 'V'),
    +    (0x169D, 'X'),
    +    (0x16A0, 'V'),
    +    (0x16F9, 'X'),
    +    (0x1700, 'V'),
    +    (0x1716, 'X'),
    +    (0x171F, 'V'),
    +    (0x1737, 'X'),
    +    (0x1740, 'V'),
    +    (0x1754, 'X'),
    +    (0x1760, 'V'),
    +    (0x176D, 'X'),
    +    (0x176E, 'V'),
    +    (0x1771, 'X'),
    +    (0x1772, 'V'),
    +    (0x1774, 'X'),
    +    (0x1780, 'V'),
    +    (0x17B4, 'X'),
    +    (0x17B6, 'V'),
    +    (0x17DE, 'X'),
    +    (0x17E0, 'V'),
    +    (0x17EA, 'X'),
    +    (0x17F0, 'V'),
    +    (0x17FA, 'X'),
    +    (0x1800, 'V'),
    +    (0x1806, 'X'),
    +    (0x1807, 'V'),
    +    (0x180B, 'I'),
    +    (0x180E, 'X'),
    +    (0x180F, 'I'),
    +    (0x1810, 'V'),
    +    (0x181A, 'X'),
    +    (0x1820, 'V'),
    +    (0x1879, 'X'),
    +    (0x1880, 'V'),
    +    (0x18AB, 'X'),
    +    (0x18B0, 'V'),
    +    (0x18F6, 'X'),
    +    (0x1900, 'V'),
    +    (0x191F, 'X'),
    +    (0x1920, 'V'),
    +    (0x192C, 'X'),
    +    (0x1930, 'V'),
    +    (0x193C, 'X'),
    +    (0x1940, 'V'),
    +    (0x1941, 'X'),
    +    (0x1944, 'V'),
    +    (0x196E, 'X'),
    +    (0x1970, 'V'),
    +    (0x1975, 'X'),
    +    (0x1980, 'V'),
    +    (0x19AC, 'X'),
    +    (0x19B0, 'V'),
    +    (0x19CA, 'X'),
    +    (0x19D0, 'V'),
    +    (0x19DB, 'X'),
    +    (0x19DE, 'V'),
    +    (0x1A1C, 'X'),
    +    (0x1A1E, 'V'),
    +    (0x1A5F, 'X'),
    +    (0x1A60, 'V'),
    +    (0x1A7D, 'X'),
    +    (0x1A7F, 'V'),
    +    (0x1A8A, 'X'),
    +    (0x1A90, 'V'),
    +    (0x1A9A, 'X'),
    +    (0x1AA0, 'V'),
    +    (0x1AAE, 'X'),
    +    (0x1AB0, 'V'),
    +    (0x1ACF, 'X'),
    +    (0x1B00, 'V'),
    +    (0x1B4D, 'X'),
    +    (0x1B50, 'V'),
    +    (0x1B7F, 'X'),
    +    (0x1B80, 'V'),
    +    (0x1BF4, 'X'),
    +    (0x1BFC, 'V'),
    +    (0x1C38, 'X'),
    +    (0x1C3B, 'V'),
    +    (0x1C4A, 'X'),
    +    (0x1C4D, 'V'),
    +    (0x1C80, 'M', 'в'),
    +    ]
    +
    +def _seg_15() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1C81, 'M', 'д'),
    +    (0x1C82, 'M', 'о'),
    +    (0x1C83, 'M', 'с'),
    +    (0x1C84, 'M', 'т'),
    +    (0x1C86, 'M', 'ъ'),
    +    (0x1C87, 'M', 'ѣ'),
    +    (0x1C88, 'M', 'ꙋ'),
    +    (0x1C89, 'X'),
    +    (0x1C90, 'M', 'ა'),
    +    (0x1C91, 'M', 'ბ'),
    +    (0x1C92, 'M', 'გ'),
    +    (0x1C93, 'M', 'დ'),
    +    (0x1C94, 'M', 'ე'),
    +    (0x1C95, 'M', 'ვ'),
    +    (0x1C96, 'M', 'ზ'),
    +    (0x1C97, 'M', 'თ'),
    +    (0x1C98, 'M', 'ი'),
    +    (0x1C99, 'M', 'კ'),
    +    (0x1C9A, 'M', 'ლ'),
    +    (0x1C9B, 'M', 'მ'),
    +    (0x1C9C, 'M', 'ნ'),
    +    (0x1C9D, 'M', 'ო'),
    +    (0x1C9E, 'M', 'პ'),
    +    (0x1C9F, 'M', 'ჟ'),
    +    (0x1CA0, 'M', 'რ'),
    +    (0x1CA1, 'M', 'ს'),
    +    (0x1CA2, 'M', 'ტ'),
    +    (0x1CA3, 'M', 'უ'),
    +    (0x1CA4, 'M', 'ფ'),
    +    (0x1CA5, 'M', 'ქ'),
    +    (0x1CA6, 'M', 'ღ'),
    +    (0x1CA7, 'M', 'ყ'),
    +    (0x1CA8, 'M', 'შ'),
    +    (0x1CA9, 'M', 'ჩ'),
    +    (0x1CAA, 'M', 'ც'),
    +    (0x1CAB, 'M', 'ძ'),
    +    (0x1CAC, 'M', 'წ'),
    +    (0x1CAD, 'M', 'ჭ'),
    +    (0x1CAE, 'M', 'ხ'),
    +    (0x1CAF, 'M', 'ჯ'),
    +    (0x1CB0, 'M', 'ჰ'),
    +    (0x1CB1, 'M', 'ჱ'),
    +    (0x1CB2, 'M', 'ჲ'),
    +    (0x1CB3, 'M', 'ჳ'),
    +    (0x1CB4, 'M', 'ჴ'),
    +    (0x1CB5, 'M', 'ჵ'),
    +    (0x1CB6, 'M', 'ჶ'),
    +    (0x1CB7, 'M', 'ჷ'),
    +    (0x1CB8, 'M', 'ჸ'),
    +    (0x1CB9, 'M', 'ჹ'),
    +    (0x1CBA, 'M', 'ჺ'),
    +    (0x1CBB, 'X'),
    +    (0x1CBD, 'M', 'ჽ'),
    +    (0x1CBE, 'M', 'ჾ'),
    +    (0x1CBF, 'M', 'ჿ'),
    +    (0x1CC0, 'V'),
    +    (0x1CC8, 'X'),
    +    (0x1CD0, 'V'),
    +    (0x1CFB, 'X'),
    +    (0x1D00, 'V'),
    +    (0x1D2C, 'M', 'a'),
    +    (0x1D2D, 'M', 'æ'),
    +    (0x1D2E, 'M', 'b'),
    +    (0x1D2F, 'V'),
    +    (0x1D30, 'M', 'd'),
    +    (0x1D31, 'M', 'e'),
    +    (0x1D32, 'M', 'ǝ'),
    +    (0x1D33, 'M', 'g'),
    +    (0x1D34, 'M', 'h'),
    +    (0x1D35, 'M', 'i'),
    +    (0x1D36, 'M', 'j'),
    +    (0x1D37, 'M', 'k'),
    +    (0x1D38, 'M', 'l'),
    +    (0x1D39, 'M', 'm'),
    +    (0x1D3A, 'M', 'n'),
    +    (0x1D3B, 'V'),
    +    (0x1D3C, 'M', 'o'),
    +    (0x1D3D, 'M', 'ȣ'),
    +    (0x1D3E, 'M', 'p'),
    +    (0x1D3F, 'M', 'r'),
    +    (0x1D40, 'M', 't'),
    +    (0x1D41, 'M', 'u'),
    +    (0x1D42, 'M', 'w'),
    +    (0x1D43, 'M', 'a'),
    +    (0x1D44, 'M', 'ɐ'),
    +    (0x1D45, 'M', 'ɑ'),
    +    (0x1D46, 'M', 'ᴂ'),
    +    (0x1D47, 'M', 'b'),
    +    (0x1D48, 'M', 'd'),
    +    (0x1D49, 'M', 'e'),
    +    (0x1D4A, 'M', 'ə'),
    +    (0x1D4B, 'M', 'ɛ'),
    +    (0x1D4C, 'M', 'ɜ'),
    +    (0x1D4D, 'M', 'g'),
    +    (0x1D4E, 'V'),
    +    (0x1D4F, 'M', 'k'),
    +    (0x1D50, 'M', 'm'),
    +    (0x1D51, 'M', 'ŋ'),
    +    (0x1D52, 'M', 'o'),
    +    (0x1D53, 'M', 'ɔ'),
    +    ]
    +
    +def _seg_16() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1D54, 'M', 'ᴖ'),
    +    (0x1D55, 'M', 'ᴗ'),
    +    (0x1D56, 'M', 'p'),
    +    (0x1D57, 'M', 't'),
    +    (0x1D58, 'M', 'u'),
    +    (0x1D59, 'M', 'ᴝ'),
    +    (0x1D5A, 'M', 'ɯ'),
    +    (0x1D5B, 'M', 'v'),
    +    (0x1D5C, 'M', 'ᴥ'),
    +    (0x1D5D, 'M', 'β'),
    +    (0x1D5E, 'M', 'γ'),
    +    (0x1D5F, 'M', 'δ'),
    +    (0x1D60, 'M', 'φ'),
    +    (0x1D61, 'M', 'χ'),
    +    (0x1D62, 'M', 'i'),
    +    (0x1D63, 'M', 'r'),
    +    (0x1D64, 'M', 'u'),
    +    (0x1D65, 'M', 'v'),
    +    (0x1D66, 'M', 'β'),
    +    (0x1D67, 'M', 'γ'),
    +    (0x1D68, 'M', 'ρ'),
    +    (0x1D69, 'M', 'φ'),
    +    (0x1D6A, 'M', 'χ'),
    +    (0x1D6B, 'V'),
    +    (0x1D78, 'M', 'н'),
    +    (0x1D79, 'V'),
    +    (0x1D9B, 'M', 'ɒ'),
    +    (0x1D9C, 'M', 'c'),
    +    (0x1D9D, 'M', 'ɕ'),
    +    (0x1D9E, 'M', 'ð'),
    +    (0x1D9F, 'M', 'ɜ'),
    +    (0x1DA0, 'M', 'f'),
    +    (0x1DA1, 'M', 'ɟ'),
    +    (0x1DA2, 'M', 'ɡ'),
    +    (0x1DA3, 'M', 'ɥ'),
    +    (0x1DA4, 'M', 'ɨ'),
    +    (0x1DA5, 'M', 'ɩ'),
    +    (0x1DA6, 'M', 'ɪ'),
    +    (0x1DA7, 'M', 'ᵻ'),
    +    (0x1DA8, 'M', 'ʝ'),
    +    (0x1DA9, 'M', 'ɭ'),
    +    (0x1DAA, 'M', 'ᶅ'),
    +    (0x1DAB, 'M', 'ʟ'),
    +    (0x1DAC, 'M', 'ɱ'),
    +    (0x1DAD, 'M', 'ɰ'),
    +    (0x1DAE, 'M', 'ɲ'),
    +    (0x1DAF, 'M', 'ɳ'),
    +    (0x1DB0, 'M', 'ɴ'),
    +    (0x1DB1, 'M', 'ɵ'),
    +    (0x1DB2, 'M', 'ɸ'),
    +    (0x1DB3, 'M', 'ʂ'),
    +    (0x1DB4, 'M', 'ʃ'),
    +    (0x1DB5, 'M', 'ƫ'),
    +    (0x1DB6, 'M', 'ʉ'),
    +    (0x1DB7, 'M', 'ʊ'),
    +    (0x1DB8, 'M', 'ᴜ'),
    +    (0x1DB9, 'M', 'ʋ'),
    +    (0x1DBA, 'M', 'ʌ'),
    +    (0x1DBB, 'M', 'z'),
    +    (0x1DBC, 'M', 'ʐ'),
    +    (0x1DBD, 'M', 'ʑ'),
    +    (0x1DBE, 'M', 'ʒ'),
    +    (0x1DBF, 'M', 'θ'),
    +    (0x1DC0, 'V'),
    +    (0x1E00, 'M', 'ḁ'),
    +    (0x1E01, 'V'),
    +    (0x1E02, 'M', 'ḃ'),
    +    (0x1E03, 'V'),
    +    (0x1E04, 'M', 'ḅ'),
    +    (0x1E05, 'V'),
    +    (0x1E06, 'M', 'ḇ'),
    +    (0x1E07, 'V'),
    +    (0x1E08, 'M', 'ḉ'),
    +    (0x1E09, 'V'),
    +    (0x1E0A, 'M', 'ḋ'),
    +    (0x1E0B, 'V'),
    +    (0x1E0C, 'M', 'ḍ'),
    +    (0x1E0D, 'V'),
    +    (0x1E0E, 'M', 'ḏ'),
    +    (0x1E0F, 'V'),
    +    (0x1E10, 'M', 'ḑ'),
    +    (0x1E11, 'V'),
    +    (0x1E12, 'M', 'ḓ'),
    +    (0x1E13, 'V'),
    +    (0x1E14, 'M', 'ḕ'),
    +    (0x1E15, 'V'),
    +    (0x1E16, 'M', 'ḗ'),
    +    (0x1E17, 'V'),
    +    (0x1E18, 'M', 'ḙ'),
    +    (0x1E19, 'V'),
    +    (0x1E1A, 'M', 'ḛ'),
    +    (0x1E1B, 'V'),
    +    (0x1E1C, 'M', 'ḝ'),
    +    (0x1E1D, 'V'),
    +    (0x1E1E, 'M', 'ḟ'),
    +    (0x1E1F, 'V'),
    +    (0x1E20, 'M', 'ḡ'),
    +    (0x1E21, 'V'),
    +    (0x1E22, 'M', 'ḣ'),
    +    (0x1E23, 'V'),
    +    ]
    +
    +def _seg_17() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1E24, 'M', 'ḥ'),
    +    (0x1E25, 'V'),
    +    (0x1E26, 'M', 'ḧ'),
    +    (0x1E27, 'V'),
    +    (0x1E28, 'M', 'ḩ'),
    +    (0x1E29, 'V'),
    +    (0x1E2A, 'M', 'ḫ'),
    +    (0x1E2B, 'V'),
    +    (0x1E2C, 'M', 'ḭ'),
    +    (0x1E2D, 'V'),
    +    (0x1E2E, 'M', 'ḯ'),
    +    (0x1E2F, 'V'),
    +    (0x1E30, 'M', 'ḱ'),
    +    (0x1E31, 'V'),
    +    (0x1E32, 'M', 'ḳ'),
    +    (0x1E33, 'V'),
    +    (0x1E34, 'M', 'ḵ'),
    +    (0x1E35, 'V'),
    +    (0x1E36, 'M', 'ḷ'),
    +    (0x1E37, 'V'),
    +    (0x1E38, 'M', 'ḹ'),
    +    (0x1E39, 'V'),
    +    (0x1E3A, 'M', 'ḻ'),
    +    (0x1E3B, 'V'),
    +    (0x1E3C, 'M', 'ḽ'),
    +    (0x1E3D, 'V'),
    +    (0x1E3E, 'M', 'ḿ'),
    +    (0x1E3F, 'V'),
    +    (0x1E40, 'M', 'ṁ'),
    +    (0x1E41, 'V'),
    +    (0x1E42, 'M', 'ṃ'),
    +    (0x1E43, 'V'),
    +    (0x1E44, 'M', 'ṅ'),
    +    (0x1E45, 'V'),
    +    (0x1E46, 'M', 'ṇ'),
    +    (0x1E47, 'V'),
    +    (0x1E48, 'M', 'ṉ'),
    +    (0x1E49, 'V'),
    +    (0x1E4A, 'M', 'ṋ'),
    +    (0x1E4B, 'V'),
    +    (0x1E4C, 'M', 'ṍ'),
    +    (0x1E4D, 'V'),
    +    (0x1E4E, 'M', 'ṏ'),
    +    (0x1E4F, 'V'),
    +    (0x1E50, 'M', 'ṑ'),
    +    (0x1E51, 'V'),
    +    (0x1E52, 'M', 'ṓ'),
    +    (0x1E53, 'V'),
    +    (0x1E54, 'M', 'ṕ'),
    +    (0x1E55, 'V'),
    +    (0x1E56, 'M', 'ṗ'),
    +    (0x1E57, 'V'),
    +    (0x1E58, 'M', 'ṙ'),
    +    (0x1E59, 'V'),
    +    (0x1E5A, 'M', 'ṛ'),
    +    (0x1E5B, 'V'),
    +    (0x1E5C, 'M', 'ṝ'),
    +    (0x1E5D, 'V'),
    +    (0x1E5E, 'M', 'ṟ'),
    +    (0x1E5F, 'V'),
    +    (0x1E60, 'M', 'ṡ'),
    +    (0x1E61, 'V'),
    +    (0x1E62, 'M', 'ṣ'),
    +    (0x1E63, 'V'),
    +    (0x1E64, 'M', 'ṥ'),
    +    (0x1E65, 'V'),
    +    (0x1E66, 'M', 'ṧ'),
    +    (0x1E67, 'V'),
    +    (0x1E68, 'M', 'ṩ'),
    +    (0x1E69, 'V'),
    +    (0x1E6A, 'M', 'ṫ'),
    +    (0x1E6B, 'V'),
    +    (0x1E6C, 'M', 'ṭ'),
    +    (0x1E6D, 'V'),
    +    (0x1E6E, 'M', 'ṯ'),
    +    (0x1E6F, 'V'),
    +    (0x1E70, 'M', 'ṱ'),
    +    (0x1E71, 'V'),
    +    (0x1E72, 'M', 'ṳ'),
    +    (0x1E73, 'V'),
    +    (0x1E74, 'M', 'ṵ'),
    +    (0x1E75, 'V'),
    +    (0x1E76, 'M', 'ṷ'),
    +    (0x1E77, 'V'),
    +    (0x1E78, 'M', 'ṹ'),
    +    (0x1E79, 'V'),
    +    (0x1E7A, 'M', 'ṻ'),
    +    (0x1E7B, 'V'),
    +    (0x1E7C, 'M', 'ṽ'),
    +    (0x1E7D, 'V'),
    +    (0x1E7E, 'M', 'ṿ'),
    +    (0x1E7F, 'V'),
    +    (0x1E80, 'M', 'ẁ'),
    +    (0x1E81, 'V'),
    +    (0x1E82, 'M', 'ẃ'),
    +    (0x1E83, 'V'),
    +    (0x1E84, 'M', 'ẅ'),
    +    (0x1E85, 'V'),
    +    (0x1E86, 'M', 'ẇ'),
    +    (0x1E87, 'V'),
    +    ]
    +
    +def _seg_18() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1E88, 'M', 'ẉ'),
    +    (0x1E89, 'V'),
    +    (0x1E8A, 'M', 'ẋ'),
    +    (0x1E8B, 'V'),
    +    (0x1E8C, 'M', 'ẍ'),
    +    (0x1E8D, 'V'),
    +    (0x1E8E, 'M', 'ẏ'),
    +    (0x1E8F, 'V'),
    +    (0x1E90, 'M', 'ẑ'),
    +    (0x1E91, 'V'),
    +    (0x1E92, 'M', 'ẓ'),
    +    (0x1E93, 'V'),
    +    (0x1E94, 'M', 'ẕ'),
    +    (0x1E95, 'V'),
    +    (0x1E9A, 'M', 'aʾ'),
    +    (0x1E9B, 'M', 'ṡ'),
    +    (0x1E9C, 'V'),
    +    (0x1E9E, 'M', 'ss'),
    +    (0x1E9F, 'V'),
    +    (0x1EA0, 'M', 'ạ'),
    +    (0x1EA1, 'V'),
    +    (0x1EA2, 'M', 'ả'),
    +    (0x1EA3, 'V'),
    +    (0x1EA4, 'M', 'ấ'),
    +    (0x1EA5, 'V'),
    +    (0x1EA6, 'M', 'ầ'),
    +    (0x1EA7, 'V'),
    +    (0x1EA8, 'M', 'ẩ'),
    +    (0x1EA9, 'V'),
    +    (0x1EAA, 'M', 'ẫ'),
    +    (0x1EAB, 'V'),
    +    (0x1EAC, 'M', 'ậ'),
    +    (0x1EAD, 'V'),
    +    (0x1EAE, 'M', 'ắ'),
    +    (0x1EAF, 'V'),
    +    (0x1EB0, 'M', 'ằ'),
    +    (0x1EB1, 'V'),
    +    (0x1EB2, 'M', 'ẳ'),
    +    (0x1EB3, 'V'),
    +    (0x1EB4, 'M', 'ẵ'),
    +    (0x1EB5, 'V'),
    +    (0x1EB6, 'M', 'ặ'),
    +    (0x1EB7, 'V'),
    +    (0x1EB8, 'M', 'ẹ'),
    +    (0x1EB9, 'V'),
    +    (0x1EBA, 'M', 'ẻ'),
    +    (0x1EBB, 'V'),
    +    (0x1EBC, 'M', 'ẽ'),
    +    (0x1EBD, 'V'),
    +    (0x1EBE, 'M', 'ế'),
    +    (0x1EBF, 'V'),
    +    (0x1EC0, 'M', 'ề'),
    +    (0x1EC1, 'V'),
    +    (0x1EC2, 'M', 'ể'),
    +    (0x1EC3, 'V'),
    +    (0x1EC4, 'M', 'ễ'),
    +    (0x1EC5, 'V'),
    +    (0x1EC6, 'M', 'ệ'),
    +    (0x1EC7, 'V'),
    +    (0x1EC8, 'M', 'ỉ'),
    +    (0x1EC9, 'V'),
    +    (0x1ECA, 'M', 'ị'),
    +    (0x1ECB, 'V'),
    +    (0x1ECC, 'M', 'ọ'),
    +    (0x1ECD, 'V'),
    +    (0x1ECE, 'M', 'ỏ'),
    +    (0x1ECF, 'V'),
    +    (0x1ED0, 'M', 'ố'),
    +    (0x1ED1, 'V'),
    +    (0x1ED2, 'M', 'ồ'),
    +    (0x1ED3, 'V'),
    +    (0x1ED4, 'M', 'ổ'),
    +    (0x1ED5, 'V'),
    +    (0x1ED6, 'M', 'ỗ'),
    +    (0x1ED7, 'V'),
    +    (0x1ED8, 'M', 'ộ'),
    +    (0x1ED9, 'V'),
    +    (0x1EDA, 'M', 'ớ'),
    +    (0x1EDB, 'V'),
    +    (0x1EDC, 'M', 'ờ'),
    +    (0x1EDD, 'V'),
    +    (0x1EDE, 'M', 'ở'),
    +    (0x1EDF, 'V'),
    +    (0x1EE0, 'M', 'ỡ'),
    +    (0x1EE1, 'V'),
    +    (0x1EE2, 'M', 'ợ'),
    +    (0x1EE3, 'V'),
    +    (0x1EE4, 'M', 'ụ'),
    +    (0x1EE5, 'V'),
    +    (0x1EE6, 'M', 'ủ'),
    +    (0x1EE7, 'V'),
    +    (0x1EE8, 'M', 'ứ'),
    +    (0x1EE9, 'V'),
    +    (0x1EEA, 'M', 'ừ'),
    +    (0x1EEB, 'V'),
    +    (0x1EEC, 'M', 'ử'),
    +    (0x1EED, 'V'),
    +    (0x1EEE, 'M', 'ữ'),
    +    (0x1EEF, 'V'),
    +    (0x1EF0, 'M', 'ự'),
    +    ]
    +
    +def _seg_19() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1EF1, 'V'),
    +    (0x1EF2, 'M', 'ỳ'),
    +    (0x1EF3, 'V'),
    +    (0x1EF4, 'M', 'ỵ'),
    +    (0x1EF5, 'V'),
    +    (0x1EF6, 'M', 'ỷ'),
    +    (0x1EF7, 'V'),
    +    (0x1EF8, 'M', 'ỹ'),
    +    (0x1EF9, 'V'),
    +    (0x1EFA, 'M', 'ỻ'),
    +    (0x1EFB, 'V'),
    +    (0x1EFC, 'M', 'ỽ'),
    +    (0x1EFD, 'V'),
    +    (0x1EFE, 'M', 'ỿ'),
    +    (0x1EFF, 'V'),
    +    (0x1F08, 'M', 'ἀ'),
    +    (0x1F09, 'M', 'ἁ'),
    +    (0x1F0A, 'M', 'ἂ'),
    +    (0x1F0B, 'M', 'ἃ'),
    +    (0x1F0C, 'M', 'ἄ'),
    +    (0x1F0D, 'M', 'ἅ'),
    +    (0x1F0E, 'M', 'ἆ'),
    +    (0x1F0F, 'M', 'ἇ'),
    +    (0x1F10, 'V'),
    +    (0x1F16, 'X'),
    +    (0x1F18, 'M', 'ἐ'),
    +    (0x1F19, 'M', 'ἑ'),
    +    (0x1F1A, 'M', 'ἒ'),
    +    (0x1F1B, 'M', 'ἓ'),
    +    (0x1F1C, 'M', 'ἔ'),
    +    (0x1F1D, 'M', 'ἕ'),
    +    (0x1F1E, 'X'),
    +    (0x1F20, 'V'),
    +    (0x1F28, 'M', 'ἠ'),
    +    (0x1F29, 'M', 'ἡ'),
    +    (0x1F2A, 'M', 'ἢ'),
    +    (0x1F2B, 'M', 'ἣ'),
    +    (0x1F2C, 'M', 'ἤ'),
    +    (0x1F2D, 'M', 'ἥ'),
    +    (0x1F2E, 'M', 'ἦ'),
    +    (0x1F2F, 'M', 'ἧ'),
    +    (0x1F30, 'V'),
    +    (0x1F38, 'M', 'ἰ'),
    +    (0x1F39, 'M', 'ἱ'),
    +    (0x1F3A, 'M', 'ἲ'),
    +    (0x1F3B, 'M', 'ἳ'),
    +    (0x1F3C, 'M', 'ἴ'),
    +    (0x1F3D, 'M', 'ἵ'),
    +    (0x1F3E, 'M', 'ἶ'),
    +    (0x1F3F, 'M', 'ἷ'),
    +    (0x1F40, 'V'),
    +    (0x1F46, 'X'),
    +    (0x1F48, 'M', 'ὀ'),
    +    (0x1F49, 'M', 'ὁ'),
    +    (0x1F4A, 'M', 'ὂ'),
    +    (0x1F4B, 'M', 'ὃ'),
    +    (0x1F4C, 'M', 'ὄ'),
    +    (0x1F4D, 'M', 'ὅ'),
    +    (0x1F4E, 'X'),
    +    (0x1F50, 'V'),
    +    (0x1F58, 'X'),
    +    (0x1F59, 'M', 'ὑ'),
    +    (0x1F5A, 'X'),
    +    (0x1F5B, 'M', 'ὓ'),
    +    (0x1F5C, 'X'),
    +    (0x1F5D, 'M', 'ὕ'),
    +    (0x1F5E, 'X'),
    +    (0x1F5F, 'M', 'ὗ'),
    +    (0x1F60, 'V'),
    +    (0x1F68, 'M', 'ὠ'),
    +    (0x1F69, 'M', 'ὡ'),
    +    (0x1F6A, 'M', 'ὢ'),
    +    (0x1F6B, 'M', 'ὣ'),
    +    (0x1F6C, 'M', 'ὤ'),
    +    (0x1F6D, 'M', 'ὥ'),
    +    (0x1F6E, 'M', 'ὦ'),
    +    (0x1F6F, 'M', 'ὧ'),
    +    (0x1F70, 'V'),
    +    (0x1F71, 'M', 'ά'),
    +    (0x1F72, 'V'),
    +    (0x1F73, 'M', 'έ'),
    +    (0x1F74, 'V'),
    +    (0x1F75, 'M', 'ή'),
    +    (0x1F76, 'V'),
    +    (0x1F77, 'M', 'ί'),
    +    (0x1F78, 'V'),
    +    (0x1F79, 'M', 'ό'),
    +    (0x1F7A, 'V'),
    +    (0x1F7B, 'M', 'ύ'),
    +    (0x1F7C, 'V'),
    +    (0x1F7D, 'M', 'ώ'),
    +    (0x1F7E, 'X'),
    +    (0x1F80, 'M', 'ἀι'),
    +    (0x1F81, 'M', 'ἁι'),
    +    (0x1F82, 'M', 'ἂι'),
    +    (0x1F83, 'M', 'ἃι'),
    +    (0x1F84, 'M', 'ἄι'),
    +    (0x1F85, 'M', 'ἅι'),
    +    (0x1F86, 'M', 'ἆι'),
    +    (0x1F87, 'M', 'ἇι'),
    +    ]
    +
    +def _seg_20() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1F88, 'M', 'ἀι'),
    +    (0x1F89, 'M', 'ἁι'),
    +    (0x1F8A, 'M', 'ἂι'),
    +    (0x1F8B, 'M', 'ἃι'),
    +    (0x1F8C, 'M', 'ἄι'),
    +    (0x1F8D, 'M', 'ἅι'),
    +    (0x1F8E, 'M', 'ἆι'),
    +    (0x1F8F, 'M', 'ἇι'),
    +    (0x1F90, 'M', 'ἠι'),
    +    (0x1F91, 'M', 'ἡι'),
    +    (0x1F92, 'M', 'ἢι'),
    +    (0x1F93, 'M', 'ἣι'),
    +    (0x1F94, 'M', 'ἤι'),
    +    (0x1F95, 'M', 'ἥι'),
    +    (0x1F96, 'M', 'ἦι'),
    +    (0x1F97, 'M', 'ἧι'),
    +    (0x1F98, 'M', 'ἠι'),
    +    (0x1F99, 'M', 'ἡι'),
    +    (0x1F9A, 'M', 'ἢι'),
    +    (0x1F9B, 'M', 'ἣι'),
    +    (0x1F9C, 'M', 'ἤι'),
    +    (0x1F9D, 'M', 'ἥι'),
    +    (0x1F9E, 'M', 'ἦι'),
    +    (0x1F9F, 'M', 'ἧι'),
    +    (0x1FA0, 'M', 'ὠι'),
    +    (0x1FA1, 'M', 'ὡι'),
    +    (0x1FA2, 'M', 'ὢι'),
    +    (0x1FA3, 'M', 'ὣι'),
    +    (0x1FA4, 'M', 'ὤι'),
    +    (0x1FA5, 'M', 'ὥι'),
    +    (0x1FA6, 'M', 'ὦι'),
    +    (0x1FA7, 'M', 'ὧι'),
    +    (0x1FA8, 'M', 'ὠι'),
    +    (0x1FA9, 'M', 'ὡι'),
    +    (0x1FAA, 'M', 'ὢι'),
    +    (0x1FAB, 'M', 'ὣι'),
    +    (0x1FAC, 'M', 'ὤι'),
    +    (0x1FAD, 'M', 'ὥι'),
    +    (0x1FAE, 'M', 'ὦι'),
    +    (0x1FAF, 'M', 'ὧι'),
    +    (0x1FB0, 'V'),
    +    (0x1FB2, 'M', 'ὰι'),
    +    (0x1FB3, 'M', 'αι'),
    +    (0x1FB4, 'M', 'άι'),
    +    (0x1FB5, 'X'),
    +    (0x1FB6, 'V'),
    +    (0x1FB7, 'M', 'ᾶι'),
    +    (0x1FB8, 'M', 'ᾰ'),
    +    (0x1FB9, 'M', 'ᾱ'),
    +    (0x1FBA, 'M', 'ὰ'),
    +    (0x1FBB, 'M', 'ά'),
    +    (0x1FBC, 'M', 'αι'),
    +    (0x1FBD, '3', ' ̓'),
    +    (0x1FBE, 'M', 'ι'),
    +    (0x1FBF, '3', ' ̓'),
    +    (0x1FC0, '3', ' ͂'),
    +    (0x1FC1, '3', ' ̈͂'),
    +    (0x1FC2, 'M', 'ὴι'),
    +    (0x1FC3, 'M', 'ηι'),
    +    (0x1FC4, 'M', 'ήι'),
    +    (0x1FC5, 'X'),
    +    (0x1FC6, 'V'),
    +    (0x1FC7, 'M', 'ῆι'),
    +    (0x1FC8, 'M', 'ὲ'),
    +    (0x1FC9, 'M', 'έ'),
    +    (0x1FCA, 'M', 'ὴ'),
    +    (0x1FCB, 'M', 'ή'),
    +    (0x1FCC, 'M', 'ηι'),
    +    (0x1FCD, '3', ' ̓̀'),
    +    (0x1FCE, '3', ' ̓́'),
    +    (0x1FCF, '3', ' ̓͂'),
    +    (0x1FD0, 'V'),
    +    (0x1FD3, 'M', 'ΐ'),
    +    (0x1FD4, 'X'),
    +    (0x1FD6, 'V'),
    +    (0x1FD8, 'M', 'ῐ'),
    +    (0x1FD9, 'M', 'ῑ'),
    +    (0x1FDA, 'M', 'ὶ'),
    +    (0x1FDB, 'M', 'ί'),
    +    (0x1FDC, 'X'),
    +    (0x1FDD, '3', ' ̔̀'),
    +    (0x1FDE, '3', ' ̔́'),
    +    (0x1FDF, '3', ' ̔͂'),
    +    (0x1FE0, 'V'),
    +    (0x1FE3, 'M', 'ΰ'),
    +    (0x1FE4, 'V'),
    +    (0x1FE8, 'M', 'ῠ'),
    +    (0x1FE9, 'M', 'ῡ'),
    +    (0x1FEA, 'M', 'ὺ'),
    +    (0x1FEB, 'M', 'ύ'),
    +    (0x1FEC, 'M', 'ῥ'),
    +    (0x1FED, '3', ' ̈̀'),
    +    (0x1FEE, '3', ' ̈́'),
    +    (0x1FEF, '3', '`'),
    +    (0x1FF0, 'X'),
    +    (0x1FF2, 'M', 'ὼι'),
    +    (0x1FF3, 'M', 'ωι'),
    +    (0x1FF4, 'M', 'ώι'),
    +    (0x1FF5, 'X'),
    +    (0x1FF6, 'V'),
    +    ]
    +
    +def _seg_21() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1FF7, 'M', 'ῶι'),
    +    (0x1FF8, 'M', 'ὸ'),
    +    (0x1FF9, 'M', 'ό'),
    +    (0x1FFA, 'M', 'ὼ'),
    +    (0x1FFB, 'M', 'ώ'),
    +    (0x1FFC, 'M', 'ωι'),
    +    (0x1FFD, '3', ' ́'),
    +    (0x1FFE, '3', ' ̔'),
    +    (0x1FFF, 'X'),
    +    (0x2000, '3', ' '),
    +    (0x200B, 'I'),
    +    (0x200C, 'D', ''),
    +    (0x200E, 'X'),
    +    (0x2010, 'V'),
    +    (0x2011, 'M', '‐'),
    +    (0x2012, 'V'),
    +    (0x2017, '3', ' ̳'),
    +    (0x2018, 'V'),
    +    (0x2024, 'X'),
    +    (0x2027, 'V'),
    +    (0x2028, 'X'),
    +    (0x202F, '3', ' '),
    +    (0x2030, 'V'),
    +    (0x2033, 'M', '′′'),
    +    (0x2034, 'M', '′′′'),
    +    (0x2035, 'V'),
    +    (0x2036, 'M', '‵‵'),
    +    (0x2037, 'M', '‵‵‵'),
    +    (0x2038, 'V'),
    +    (0x203C, '3', '!!'),
    +    (0x203D, 'V'),
    +    (0x203E, '3', ' ̅'),
    +    (0x203F, 'V'),
    +    (0x2047, '3', '??'),
    +    (0x2048, '3', '?!'),
    +    (0x2049, '3', '!?'),
    +    (0x204A, 'V'),
    +    (0x2057, 'M', '′′′′'),
    +    (0x2058, 'V'),
    +    (0x205F, '3', ' '),
    +    (0x2060, 'I'),
    +    (0x2061, 'X'),
    +    (0x2064, 'I'),
    +    (0x2065, 'X'),
    +    (0x2070, 'M', '0'),
    +    (0x2071, 'M', 'i'),
    +    (0x2072, 'X'),
    +    (0x2074, 'M', '4'),
    +    (0x2075, 'M', '5'),
    +    (0x2076, 'M', '6'),
    +    (0x2077, 'M', '7'),
    +    (0x2078, 'M', '8'),
    +    (0x2079, 'M', '9'),
    +    (0x207A, '3', '+'),
    +    (0x207B, 'M', '−'),
    +    (0x207C, '3', '='),
    +    (0x207D, '3', '('),
    +    (0x207E, '3', ')'),
    +    (0x207F, 'M', 'n'),
    +    (0x2080, 'M', '0'),
    +    (0x2081, 'M', '1'),
    +    (0x2082, 'M', '2'),
    +    (0x2083, 'M', '3'),
    +    (0x2084, 'M', '4'),
    +    (0x2085, 'M', '5'),
    +    (0x2086, 'M', '6'),
    +    (0x2087, 'M', '7'),
    +    (0x2088, 'M', '8'),
    +    (0x2089, 'M', '9'),
    +    (0x208A, '3', '+'),
    +    (0x208B, 'M', '−'),
    +    (0x208C, '3', '='),
    +    (0x208D, '3', '('),
    +    (0x208E, '3', ')'),
    +    (0x208F, 'X'),
    +    (0x2090, 'M', 'a'),
    +    (0x2091, 'M', 'e'),
    +    (0x2092, 'M', 'o'),
    +    (0x2093, 'M', 'x'),
    +    (0x2094, 'M', 'ə'),
    +    (0x2095, 'M', 'h'),
    +    (0x2096, 'M', 'k'),
    +    (0x2097, 'M', 'l'),
    +    (0x2098, 'M', 'm'),
    +    (0x2099, 'M', 'n'),
    +    (0x209A, 'M', 'p'),
    +    (0x209B, 'M', 's'),
    +    (0x209C, 'M', 't'),
    +    (0x209D, 'X'),
    +    (0x20A0, 'V'),
    +    (0x20A8, 'M', 'rs'),
    +    (0x20A9, 'V'),
    +    (0x20C1, 'X'),
    +    (0x20D0, 'V'),
    +    (0x20F1, 'X'),
    +    (0x2100, '3', 'a/c'),
    +    (0x2101, '3', 'a/s'),
    +    (0x2102, 'M', 'c'),
    +    (0x2103, 'M', '°c'),
    +    (0x2104, 'V'),
    +    ]
    +
    +def _seg_22() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x2105, '3', 'c/o'),
    +    (0x2106, '3', 'c/u'),
    +    (0x2107, 'M', 'ɛ'),
    +    (0x2108, 'V'),
    +    (0x2109, 'M', '°f'),
    +    (0x210A, 'M', 'g'),
    +    (0x210B, 'M', 'h'),
    +    (0x210F, 'M', 'ħ'),
    +    (0x2110, 'M', 'i'),
    +    (0x2112, 'M', 'l'),
    +    (0x2114, 'V'),
    +    (0x2115, 'M', 'n'),
    +    (0x2116, 'M', 'no'),
    +    (0x2117, 'V'),
    +    (0x2119, 'M', 'p'),
    +    (0x211A, 'M', 'q'),
    +    (0x211B, 'M', 'r'),
    +    (0x211E, 'V'),
    +    (0x2120, 'M', 'sm'),
    +    (0x2121, 'M', 'tel'),
    +    (0x2122, 'M', 'tm'),
    +    (0x2123, 'V'),
    +    (0x2124, 'M', 'z'),
    +    (0x2125, 'V'),
    +    (0x2126, 'M', 'ω'),
    +    (0x2127, 'V'),
    +    (0x2128, 'M', 'z'),
    +    (0x2129, 'V'),
    +    (0x212A, 'M', 'k'),
    +    (0x212B, 'M', 'å'),
    +    (0x212C, 'M', 'b'),
    +    (0x212D, 'M', 'c'),
    +    (0x212E, 'V'),
    +    (0x212F, 'M', 'e'),
    +    (0x2131, 'M', 'f'),
    +    (0x2132, 'X'),
    +    (0x2133, 'M', 'm'),
    +    (0x2134, 'M', 'o'),
    +    (0x2135, 'M', 'א'),
    +    (0x2136, 'M', 'ב'),
    +    (0x2137, 'M', 'ג'),
    +    (0x2138, 'M', 'ד'),
    +    (0x2139, 'M', 'i'),
    +    (0x213A, 'V'),
    +    (0x213B, 'M', 'fax'),
    +    (0x213C, 'M', 'π'),
    +    (0x213D, 'M', 'γ'),
    +    (0x213F, 'M', 'π'),
    +    (0x2140, 'M', '∑'),
    +    (0x2141, 'V'),
    +    (0x2145, 'M', 'd'),
    +    (0x2147, 'M', 'e'),
    +    (0x2148, 'M', 'i'),
    +    (0x2149, 'M', 'j'),
    +    (0x214A, 'V'),
    +    (0x2150, 'M', '1⁄7'),
    +    (0x2151, 'M', '1⁄9'),
    +    (0x2152, 'M', '1⁄10'),
    +    (0x2153, 'M', '1⁄3'),
    +    (0x2154, 'M', '2⁄3'),
    +    (0x2155, 'M', '1⁄5'),
    +    (0x2156, 'M', '2⁄5'),
    +    (0x2157, 'M', '3⁄5'),
    +    (0x2158, 'M', '4⁄5'),
    +    (0x2159, 'M', '1⁄6'),
    +    (0x215A, 'M', '5⁄6'),
    +    (0x215B, 'M', '1⁄8'),
    +    (0x215C, 'M', '3⁄8'),
    +    (0x215D, 'M', '5⁄8'),
    +    (0x215E, 'M', '7⁄8'),
    +    (0x215F, 'M', '1⁄'),
    +    (0x2160, 'M', 'i'),
    +    (0x2161, 'M', 'ii'),
    +    (0x2162, 'M', 'iii'),
    +    (0x2163, 'M', 'iv'),
    +    (0x2164, 'M', 'v'),
    +    (0x2165, 'M', 'vi'),
    +    (0x2166, 'M', 'vii'),
    +    (0x2167, 'M', 'viii'),
    +    (0x2168, 'M', 'ix'),
    +    (0x2169, 'M', 'x'),
    +    (0x216A, 'M', 'xi'),
    +    (0x216B, 'M', 'xii'),
    +    (0x216C, 'M', 'l'),
    +    (0x216D, 'M', 'c'),
    +    (0x216E, 'M', 'd'),
    +    (0x216F, 'M', 'm'),
    +    (0x2170, 'M', 'i'),
    +    (0x2171, 'M', 'ii'),
    +    (0x2172, 'M', 'iii'),
    +    (0x2173, 'M', 'iv'),
    +    (0x2174, 'M', 'v'),
    +    (0x2175, 'M', 'vi'),
    +    (0x2176, 'M', 'vii'),
    +    (0x2177, 'M', 'viii'),
    +    (0x2178, 'M', 'ix'),
    +    (0x2179, 'M', 'x'),
    +    (0x217A, 'M', 'xi'),
    +    (0x217B, 'M', 'xii'),
    +    (0x217C, 'M', 'l'),
    +    ]
    +
    +def _seg_23() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x217D, 'M', 'c'),
    +    (0x217E, 'M', 'd'),
    +    (0x217F, 'M', 'm'),
    +    (0x2180, 'V'),
    +    (0x2183, 'X'),
    +    (0x2184, 'V'),
    +    (0x2189, 'M', '0⁄3'),
    +    (0x218A, 'V'),
    +    (0x218C, 'X'),
    +    (0x2190, 'V'),
    +    (0x222C, 'M', '∫∫'),
    +    (0x222D, 'M', '∫∫∫'),
    +    (0x222E, 'V'),
    +    (0x222F, 'M', '∮∮'),
    +    (0x2230, 'M', '∮∮∮'),
    +    (0x2231, 'V'),
    +    (0x2260, '3'),
    +    (0x2261, 'V'),
    +    (0x226E, '3'),
    +    (0x2270, 'V'),
    +    (0x2329, 'M', '〈'),
    +    (0x232A, 'M', '〉'),
    +    (0x232B, 'V'),
    +    (0x2427, 'X'),
    +    (0x2440, 'V'),
    +    (0x244B, 'X'),
    +    (0x2460, 'M', '1'),
    +    (0x2461, 'M', '2'),
    +    (0x2462, 'M', '3'),
    +    (0x2463, 'M', '4'),
    +    (0x2464, 'M', '5'),
    +    (0x2465, 'M', '6'),
    +    (0x2466, 'M', '7'),
    +    (0x2467, 'M', '8'),
    +    (0x2468, 'M', '9'),
    +    (0x2469, 'M', '10'),
    +    (0x246A, 'M', '11'),
    +    (0x246B, 'M', '12'),
    +    (0x246C, 'M', '13'),
    +    (0x246D, 'M', '14'),
    +    (0x246E, 'M', '15'),
    +    (0x246F, 'M', '16'),
    +    (0x2470, 'M', '17'),
    +    (0x2471, 'M', '18'),
    +    (0x2472, 'M', '19'),
    +    (0x2473, 'M', '20'),
    +    (0x2474, '3', '(1)'),
    +    (0x2475, '3', '(2)'),
    +    (0x2476, '3', '(3)'),
    +    (0x2477, '3', '(4)'),
    +    (0x2478, '3', '(5)'),
    +    (0x2479, '3', '(6)'),
    +    (0x247A, '3', '(7)'),
    +    (0x247B, '3', '(8)'),
    +    (0x247C, '3', '(9)'),
    +    (0x247D, '3', '(10)'),
    +    (0x247E, '3', '(11)'),
    +    (0x247F, '3', '(12)'),
    +    (0x2480, '3', '(13)'),
    +    (0x2481, '3', '(14)'),
    +    (0x2482, '3', '(15)'),
    +    (0x2483, '3', '(16)'),
    +    (0x2484, '3', '(17)'),
    +    (0x2485, '3', '(18)'),
    +    (0x2486, '3', '(19)'),
    +    (0x2487, '3', '(20)'),
    +    (0x2488, 'X'),
    +    (0x249C, '3', '(a)'),
    +    (0x249D, '3', '(b)'),
    +    (0x249E, '3', '(c)'),
    +    (0x249F, '3', '(d)'),
    +    (0x24A0, '3', '(e)'),
    +    (0x24A1, '3', '(f)'),
    +    (0x24A2, '3', '(g)'),
    +    (0x24A3, '3', '(h)'),
    +    (0x24A4, '3', '(i)'),
    +    (0x24A5, '3', '(j)'),
    +    (0x24A6, '3', '(k)'),
    +    (0x24A7, '3', '(l)'),
    +    (0x24A8, '3', '(m)'),
    +    (0x24A9, '3', '(n)'),
    +    (0x24AA, '3', '(o)'),
    +    (0x24AB, '3', '(p)'),
    +    (0x24AC, '3', '(q)'),
    +    (0x24AD, '3', '(r)'),
    +    (0x24AE, '3', '(s)'),
    +    (0x24AF, '3', '(t)'),
    +    (0x24B0, '3', '(u)'),
    +    (0x24B1, '3', '(v)'),
    +    (0x24B2, '3', '(w)'),
    +    (0x24B3, '3', '(x)'),
    +    (0x24B4, '3', '(y)'),
    +    (0x24B5, '3', '(z)'),
    +    (0x24B6, 'M', 'a'),
    +    (0x24B7, 'M', 'b'),
    +    (0x24B8, 'M', 'c'),
    +    (0x24B9, 'M', 'd'),
    +    (0x24BA, 'M', 'e'),
    +    (0x24BB, 'M', 'f'),
    +    (0x24BC, 'M', 'g'),
    +    ]
    +
    +def _seg_24() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x24BD, 'M', 'h'),
    +    (0x24BE, 'M', 'i'),
    +    (0x24BF, 'M', 'j'),
    +    (0x24C0, 'M', 'k'),
    +    (0x24C1, 'M', 'l'),
    +    (0x24C2, 'M', 'm'),
    +    (0x24C3, 'M', 'n'),
    +    (0x24C4, 'M', 'o'),
    +    (0x24C5, 'M', 'p'),
    +    (0x24C6, 'M', 'q'),
    +    (0x24C7, 'M', 'r'),
    +    (0x24C8, 'M', 's'),
    +    (0x24C9, 'M', 't'),
    +    (0x24CA, 'M', 'u'),
    +    (0x24CB, 'M', 'v'),
    +    (0x24CC, 'M', 'w'),
    +    (0x24CD, 'M', 'x'),
    +    (0x24CE, 'M', 'y'),
    +    (0x24CF, 'M', 'z'),
    +    (0x24D0, 'M', 'a'),
    +    (0x24D1, 'M', 'b'),
    +    (0x24D2, 'M', 'c'),
    +    (0x24D3, 'M', 'd'),
    +    (0x24D4, 'M', 'e'),
    +    (0x24D5, 'M', 'f'),
    +    (0x24D6, 'M', 'g'),
    +    (0x24D7, 'M', 'h'),
    +    (0x24D8, 'M', 'i'),
    +    (0x24D9, 'M', 'j'),
    +    (0x24DA, 'M', 'k'),
    +    (0x24DB, 'M', 'l'),
    +    (0x24DC, 'M', 'm'),
    +    (0x24DD, 'M', 'n'),
    +    (0x24DE, 'M', 'o'),
    +    (0x24DF, 'M', 'p'),
    +    (0x24E0, 'M', 'q'),
    +    (0x24E1, 'M', 'r'),
    +    (0x24E2, 'M', 's'),
    +    (0x24E3, 'M', 't'),
    +    (0x24E4, 'M', 'u'),
    +    (0x24E5, 'M', 'v'),
    +    (0x24E6, 'M', 'w'),
    +    (0x24E7, 'M', 'x'),
    +    (0x24E8, 'M', 'y'),
    +    (0x24E9, 'M', 'z'),
    +    (0x24EA, 'M', '0'),
    +    (0x24EB, 'V'),
    +    (0x2A0C, 'M', '∫∫∫∫'),
    +    (0x2A0D, 'V'),
    +    (0x2A74, '3', '::='),
    +    (0x2A75, '3', '=='),
    +    (0x2A76, '3', '==='),
    +    (0x2A77, 'V'),
    +    (0x2ADC, 'M', '⫝̸'),
    +    (0x2ADD, 'V'),
    +    (0x2B74, 'X'),
    +    (0x2B76, 'V'),
    +    (0x2B96, 'X'),
    +    (0x2B97, 'V'),
    +    (0x2C00, 'M', 'ⰰ'),
    +    (0x2C01, 'M', 'ⰱ'),
    +    (0x2C02, 'M', 'ⰲ'),
    +    (0x2C03, 'M', 'ⰳ'),
    +    (0x2C04, 'M', 'ⰴ'),
    +    (0x2C05, 'M', 'ⰵ'),
    +    (0x2C06, 'M', 'ⰶ'),
    +    (0x2C07, 'M', 'ⰷ'),
    +    (0x2C08, 'M', 'ⰸ'),
    +    (0x2C09, 'M', 'ⰹ'),
    +    (0x2C0A, 'M', 'ⰺ'),
    +    (0x2C0B, 'M', 'ⰻ'),
    +    (0x2C0C, 'M', 'ⰼ'),
    +    (0x2C0D, 'M', 'ⰽ'),
    +    (0x2C0E, 'M', 'ⰾ'),
    +    (0x2C0F, 'M', 'ⰿ'),
    +    (0x2C10, 'M', 'ⱀ'),
    +    (0x2C11, 'M', 'ⱁ'),
    +    (0x2C12, 'M', 'ⱂ'),
    +    (0x2C13, 'M', 'ⱃ'),
    +    (0x2C14, 'M', 'ⱄ'),
    +    (0x2C15, 'M', 'ⱅ'),
    +    (0x2C16, 'M', 'ⱆ'),
    +    (0x2C17, 'M', 'ⱇ'),
    +    (0x2C18, 'M', 'ⱈ'),
    +    (0x2C19, 'M', 'ⱉ'),
    +    (0x2C1A, 'M', 'ⱊ'),
    +    (0x2C1B, 'M', 'ⱋ'),
    +    (0x2C1C, 'M', 'ⱌ'),
    +    (0x2C1D, 'M', 'ⱍ'),
    +    (0x2C1E, 'M', 'ⱎ'),
    +    (0x2C1F, 'M', 'ⱏ'),
    +    (0x2C20, 'M', 'ⱐ'),
    +    (0x2C21, 'M', 'ⱑ'),
    +    (0x2C22, 'M', 'ⱒ'),
    +    (0x2C23, 'M', 'ⱓ'),
    +    (0x2C24, 'M', 'ⱔ'),
    +    (0x2C25, 'M', 'ⱕ'),
    +    (0x2C26, 'M', 'ⱖ'),
    +    (0x2C27, 'M', 'ⱗ'),
    +    (0x2C28, 'M', 'ⱘ'),
    +    ]
    +
    +def _seg_25() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x2C29, 'M', 'ⱙ'),
    +    (0x2C2A, 'M', 'ⱚ'),
    +    (0x2C2B, 'M', 'ⱛ'),
    +    (0x2C2C, 'M', 'ⱜ'),
    +    (0x2C2D, 'M', 'ⱝ'),
    +    (0x2C2E, 'M', 'ⱞ'),
    +    (0x2C2F, 'M', 'ⱟ'),
    +    (0x2C30, 'V'),
    +    (0x2C60, 'M', 'ⱡ'),
    +    (0x2C61, 'V'),
    +    (0x2C62, 'M', 'ɫ'),
    +    (0x2C63, 'M', 'ᵽ'),
    +    (0x2C64, 'M', 'ɽ'),
    +    (0x2C65, 'V'),
    +    (0x2C67, 'M', 'ⱨ'),
    +    (0x2C68, 'V'),
    +    (0x2C69, 'M', 'ⱪ'),
    +    (0x2C6A, 'V'),
    +    (0x2C6B, 'M', 'ⱬ'),
    +    (0x2C6C, 'V'),
    +    (0x2C6D, 'M', 'ɑ'),
    +    (0x2C6E, 'M', 'ɱ'),
    +    (0x2C6F, 'M', 'ɐ'),
    +    (0x2C70, 'M', 'ɒ'),
    +    (0x2C71, 'V'),
    +    (0x2C72, 'M', 'ⱳ'),
    +    (0x2C73, 'V'),
    +    (0x2C75, 'M', 'ⱶ'),
    +    (0x2C76, 'V'),
    +    (0x2C7C, 'M', 'j'),
    +    (0x2C7D, 'M', 'v'),
    +    (0x2C7E, 'M', 'ȿ'),
    +    (0x2C7F, 'M', 'ɀ'),
    +    (0x2C80, 'M', 'ⲁ'),
    +    (0x2C81, 'V'),
    +    (0x2C82, 'M', 'ⲃ'),
    +    (0x2C83, 'V'),
    +    (0x2C84, 'M', 'ⲅ'),
    +    (0x2C85, 'V'),
    +    (0x2C86, 'M', 'ⲇ'),
    +    (0x2C87, 'V'),
    +    (0x2C88, 'M', 'ⲉ'),
    +    (0x2C89, 'V'),
    +    (0x2C8A, 'M', 'ⲋ'),
    +    (0x2C8B, 'V'),
    +    (0x2C8C, 'M', 'ⲍ'),
    +    (0x2C8D, 'V'),
    +    (0x2C8E, 'M', 'ⲏ'),
    +    (0x2C8F, 'V'),
    +    (0x2C90, 'M', 'ⲑ'),
    +    (0x2C91, 'V'),
    +    (0x2C92, 'M', 'ⲓ'),
    +    (0x2C93, 'V'),
    +    (0x2C94, 'M', 'ⲕ'),
    +    (0x2C95, 'V'),
    +    (0x2C96, 'M', 'ⲗ'),
    +    (0x2C97, 'V'),
    +    (0x2C98, 'M', 'ⲙ'),
    +    (0x2C99, 'V'),
    +    (0x2C9A, 'M', 'ⲛ'),
    +    (0x2C9B, 'V'),
    +    (0x2C9C, 'M', 'ⲝ'),
    +    (0x2C9D, 'V'),
    +    (0x2C9E, 'M', 'ⲟ'),
    +    (0x2C9F, 'V'),
    +    (0x2CA0, 'M', 'ⲡ'),
    +    (0x2CA1, 'V'),
    +    (0x2CA2, 'M', 'ⲣ'),
    +    (0x2CA3, 'V'),
    +    (0x2CA4, 'M', 'ⲥ'),
    +    (0x2CA5, 'V'),
    +    (0x2CA6, 'M', 'ⲧ'),
    +    (0x2CA7, 'V'),
    +    (0x2CA8, 'M', 'ⲩ'),
    +    (0x2CA9, 'V'),
    +    (0x2CAA, 'M', 'ⲫ'),
    +    (0x2CAB, 'V'),
    +    (0x2CAC, 'M', 'ⲭ'),
    +    (0x2CAD, 'V'),
    +    (0x2CAE, 'M', 'ⲯ'),
    +    (0x2CAF, 'V'),
    +    (0x2CB0, 'M', 'ⲱ'),
    +    (0x2CB1, 'V'),
    +    (0x2CB2, 'M', 'ⲳ'),
    +    (0x2CB3, 'V'),
    +    (0x2CB4, 'M', 'ⲵ'),
    +    (0x2CB5, 'V'),
    +    (0x2CB6, 'M', 'ⲷ'),
    +    (0x2CB7, 'V'),
    +    (0x2CB8, 'M', 'ⲹ'),
    +    (0x2CB9, 'V'),
    +    (0x2CBA, 'M', 'ⲻ'),
    +    (0x2CBB, 'V'),
    +    (0x2CBC, 'M', 'ⲽ'),
    +    (0x2CBD, 'V'),
    +    (0x2CBE, 'M', 'ⲿ'),
    +    (0x2CBF, 'V'),
    +    (0x2CC0, 'M', 'ⳁ'),
    +    (0x2CC1, 'V'),
    +    (0x2CC2, 'M', 'ⳃ'),
    +    ]
    +
    +def _seg_26() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x2CC3, 'V'),
    +    (0x2CC4, 'M', 'ⳅ'),
    +    (0x2CC5, 'V'),
    +    (0x2CC6, 'M', 'ⳇ'),
    +    (0x2CC7, 'V'),
    +    (0x2CC8, 'M', 'ⳉ'),
    +    (0x2CC9, 'V'),
    +    (0x2CCA, 'M', 'ⳋ'),
    +    (0x2CCB, 'V'),
    +    (0x2CCC, 'M', 'ⳍ'),
    +    (0x2CCD, 'V'),
    +    (0x2CCE, 'M', 'ⳏ'),
    +    (0x2CCF, 'V'),
    +    (0x2CD0, 'M', 'ⳑ'),
    +    (0x2CD1, 'V'),
    +    (0x2CD2, 'M', 'ⳓ'),
    +    (0x2CD3, 'V'),
    +    (0x2CD4, 'M', 'ⳕ'),
    +    (0x2CD5, 'V'),
    +    (0x2CD6, 'M', 'ⳗ'),
    +    (0x2CD7, 'V'),
    +    (0x2CD8, 'M', 'ⳙ'),
    +    (0x2CD9, 'V'),
    +    (0x2CDA, 'M', 'ⳛ'),
    +    (0x2CDB, 'V'),
    +    (0x2CDC, 'M', 'ⳝ'),
    +    (0x2CDD, 'V'),
    +    (0x2CDE, 'M', 'ⳟ'),
    +    (0x2CDF, 'V'),
    +    (0x2CE0, 'M', 'ⳡ'),
    +    (0x2CE1, 'V'),
    +    (0x2CE2, 'M', 'ⳣ'),
    +    (0x2CE3, 'V'),
    +    (0x2CEB, 'M', 'ⳬ'),
    +    (0x2CEC, 'V'),
    +    (0x2CED, 'M', 'ⳮ'),
    +    (0x2CEE, 'V'),
    +    (0x2CF2, 'M', 'ⳳ'),
    +    (0x2CF3, 'V'),
    +    (0x2CF4, 'X'),
    +    (0x2CF9, 'V'),
    +    (0x2D26, 'X'),
    +    (0x2D27, 'V'),
    +    (0x2D28, 'X'),
    +    (0x2D2D, 'V'),
    +    (0x2D2E, 'X'),
    +    (0x2D30, 'V'),
    +    (0x2D68, 'X'),
    +    (0x2D6F, 'M', 'ⵡ'),
    +    (0x2D70, 'V'),
    +    (0x2D71, 'X'),
    +    (0x2D7F, 'V'),
    +    (0x2D97, 'X'),
    +    (0x2DA0, 'V'),
    +    (0x2DA7, 'X'),
    +    (0x2DA8, 'V'),
    +    (0x2DAF, 'X'),
    +    (0x2DB0, 'V'),
    +    (0x2DB7, 'X'),
    +    (0x2DB8, 'V'),
    +    (0x2DBF, 'X'),
    +    (0x2DC0, 'V'),
    +    (0x2DC7, 'X'),
    +    (0x2DC8, 'V'),
    +    (0x2DCF, 'X'),
    +    (0x2DD0, 'V'),
    +    (0x2DD7, 'X'),
    +    (0x2DD8, 'V'),
    +    (0x2DDF, 'X'),
    +    (0x2DE0, 'V'),
    +    (0x2E5E, 'X'),
    +    (0x2E80, 'V'),
    +    (0x2E9A, 'X'),
    +    (0x2E9B, 'V'),
    +    (0x2E9F, 'M', '母'),
    +    (0x2EA0, 'V'),
    +    (0x2EF3, 'M', '龟'),
    +    (0x2EF4, 'X'),
    +    (0x2F00, 'M', '一'),
    +    (0x2F01, 'M', '丨'),
    +    (0x2F02, 'M', '丶'),
    +    (0x2F03, 'M', '丿'),
    +    (0x2F04, 'M', '乙'),
    +    (0x2F05, 'M', '亅'),
    +    (0x2F06, 'M', '二'),
    +    (0x2F07, 'M', '亠'),
    +    (0x2F08, 'M', '人'),
    +    (0x2F09, 'M', '儿'),
    +    (0x2F0A, 'M', '入'),
    +    (0x2F0B, 'M', '八'),
    +    (0x2F0C, 'M', '冂'),
    +    (0x2F0D, 'M', '冖'),
    +    (0x2F0E, 'M', '冫'),
    +    (0x2F0F, 'M', '几'),
    +    (0x2F10, 'M', '凵'),
    +    (0x2F11, 'M', '刀'),
    +    (0x2F12, 'M', '力'),
    +    (0x2F13, 'M', '勹'),
    +    (0x2F14, 'M', '匕'),
    +    (0x2F15, 'M', '匚'),
    +    ]
    +
    +def _seg_27() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x2F16, 'M', '匸'),
    +    (0x2F17, 'M', '十'),
    +    (0x2F18, 'M', '卜'),
    +    (0x2F19, 'M', '卩'),
    +    (0x2F1A, 'M', '厂'),
    +    (0x2F1B, 'M', '厶'),
    +    (0x2F1C, 'M', '又'),
    +    (0x2F1D, 'M', '口'),
    +    (0x2F1E, 'M', '囗'),
    +    (0x2F1F, 'M', '土'),
    +    (0x2F20, 'M', '士'),
    +    (0x2F21, 'M', '夂'),
    +    (0x2F22, 'M', '夊'),
    +    (0x2F23, 'M', '夕'),
    +    (0x2F24, 'M', '大'),
    +    (0x2F25, 'M', '女'),
    +    (0x2F26, 'M', '子'),
    +    (0x2F27, 'M', '宀'),
    +    (0x2F28, 'M', '寸'),
    +    (0x2F29, 'M', '小'),
    +    (0x2F2A, 'M', '尢'),
    +    (0x2F2B, 'M', '尸'),
    +    (0x2F2C, 'M', '屮'),
    +    (0x2F2D, 'M', '山'),
    +    (0x2F2E, 'M', '巛'),
    +    (0x2F2F, 'M', '工'),
    +    (0x2F30, 'M', '己'),
    +    (0x2F31, 'M', '巾'),
    +    (0x2F32, 'M', '干'),
    +    (0x2F33, 'M', '幺'),
    +    (0x2F34, 'M', '广'),
    +    (0x2F35, 'M', '廴'),
    +    (0x2F36, 'M', '廾'),
    +    (0x2F37, 'M', '弋'),
    +    (0x2F38, 'M', '弓'),
    +    (0x2F39, 'M', '彐'),
    +    (0x2F3A, 'M', '彡'),
    +    (0x2F3B, 'M', '彳'),
    +    (0x2F3C, 'M', '心'),
    +    (0x2F3D, 'M', '戈'),
    +    (0x2F3E, 'M', '戶'),
    +    (0x2F3F, 'M', '手'),
    +    (0x2F40, 'M', '支'),
    +    (0x2F41, 'M', '攴'),
    +    (0x2F42, 'M', '文'),
    +    (0x2F43, 'M', '斗'),
    +    (0x2F44, 'M', '斤'),
    +    (0x2F45, 'M', '方'),
    +    (0x2F46, 'M', '无'),
    +    (0x2F47, 'M', '日'),
    +    (0x2F48, 'M', '曰'),
    +    (0x2F49, 'M', '月'),
    +    (0x2F4A, 'M', '木'),
    +    (0x2F4B, 'M', '欠'),
    +    (0x2F4C, 'M', '止'),
    +    (0x2F4D, 'M', '歹'),
    +    (0x2F4E, 'M', '殳'),
    +    (0x2F4F, 'M', '毋'),
    +    (0x2F50, 'M', '比'),
    +    (0x2F51, 'M', '毛'),
    +    (0x2F52, 'M', '氏'),
    +    (0x2F53, 'M', '气'),
    +    (0x2F54, 'M', '水'),
    +    (0x2F55, 'M', '火'),
    +    (0x2F56, 'M', '爪'),
    +    (0x2F57, 'M', '父'),
    +    (0x2F58, 'M', '爻'),
    +    (0x2F59, 'M', '爿'),
    +    (0x2F5A, 'M', '片'),
    +    (0x2F5B, 'M', '牙'),
    +    (0x2F5C, 'M', '牛'),
    +    (0x2F5D, 'M', '犬'),
    +    (0x2F5E, 'M', '玄'),
    +    (0x2F5F, 'M', '玉'),
    +    (0x2F60, 'M', '瓜'),
    +    (0x2F61, 'M', '瓦'),
    +    (0x2F62, 'M', '甘'),
    +    (0x2F63, 'M', '生'),
    +    (0x2F64, 'M', '用'),
    +    (0x2F65, 'M', '田'),
    +    (0x2F66, 'M', '疋'),
    +    (0x2F67, 'M', '疒'),
    +    (0x2F68, 'M', '癶'),
    +    (0x2F69, 'M', '白'),
    +    (0x2F6A, 'M', '皮'),
    +    (0x2F6B, 'M', '皿'),
    +    (0x2F6C, 'M', '目'),
    +    (0x2F6D, 'M', '矛'),
    +    (0x2F6E, 'M', '矢'),
    +    (0x2F6F, 'M', '石'),
    +    (0x2F70, 'M', '示'),
    +    (0x2F71, 'M', '禸'),
    +    (0x2F72, 'M', '禾'),
    +    (0x2F73, 'M', '穴'),
    +    (0x2F74, 'M', '立'),
    +    (0x2F75, 'M', '竹'),
    +    (0x2F76, 'M', '米'),
    +    (0x2F77, 'M', '糸'),
    +    (0x2F78, 'M', '缶'),
    +    (0x2F79, 'M', '网'),
    +    ]
    +
    +def _seg_28() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x2F7A, 'M', '羊'),
    +    (0x2F7B, 'M', '羽'),
    +    (0x2F7C, 'M', '老'),
    +    (0x2F7D, 'M', '而'),
    +    (0x2F7E, 'M', '耒'),
    +    (0x2F7F, 'M', '耳'),
    +    (0x2F80, 'M', '聿'),
    +    (0x2F81, 'M', '肉'),
    +    (0x2F82, 'M', '臣'),
    +    (0x2F83, 'M', '自'),
    +    (0x2F84, 'M', '至'),
    +    (0x2F85, 'M', '臼'),
    +    (0x2F86, 'M', '舌'),
    +    (0x2F87, 'M', '舛'),
    +    (0x2F88, 'M', '舟'),
    +    (0x2F89, 'M', '艮'),
    +    (0x2F8A, 'M', '色'),
    +    (0x2F8B, 'M', '艸'),
    +    (0x2F8C, 'M', '虍'),
    +    (0x2F8D, 'M', '虫'),
    +    (0x2F8E, 'M', '血'),
    +    (0x2F8F, 'M', '行'),
    +    (0x2F90, 'M', '衣'),
    +    (0x2F91, 'M', '襾'),
    +    (0x2F92, 'M', '見'),
    +    (0x2F93, 'M', '角'),
    +    (0x2F94, 'M', '言'),
    +    (0x2F95, 'M', '谷'),
    +    (0x2F96, 'M', '豆'),
    +    (0x2F97, 'M', '豕'),
    +    (0x2F98, 'M', '豸'),
    +    (0x2F99, 'M', '貝'),
    +    (0x2F9A, 'M', '赤'),
    +    (0x2F9B, 'M', '走'),
    +    (0x2F9C, 'M', '足'),
    +    (0x2F9D, 'M', '身'),
    +    (0x2F9E, 'M', '車'),
    +    (0x2F9F, 'M', '辛'),
    +    (0x2FA0, 'M', '辰'),
    +    (0x2FA1, 'M', '辵'),
    +    (0x2FA2, 'M', '邑'),
    +    (0x2FA3, 'M', '酉'),
    +    (0x2FA4, 'M', '釆'),
    +    (0x2FA5, 'M', '里'),
    +    (0x2FA6, 'M', '金'),
    +    (0x2FA7, 'M', '長'),
    +    (0x2FA8, 'M', '門'),
    +    (0x2FA9, 'M', '阜'),
    +    (0x2FAA, 'M', '隶'),
    +    (0x2FAB, 'M', '隹'),
    +    (0x2FAC, 'M', '雨'),
    +    (0x2FAD, 'M', '靑'),
    +    (0x2FAE, 'M', '非'),
    +    (0x2FAF, 'M', '面'),
    +    (0x2FB0, 'M', '革'),
    +    (0x2FB1, 'M', '韋'),
    +    (0x2FB2, 'M', '韭'),
    +    (0x2FB3, 'M', '音'),
    +    (0x2FB4, 'M', '頁'),
    +    (0x2FB5, 'M', '風'),
    +    (0x2FB6, 'M', '飛'),
    +    (0x2FB7, 'M', '食'),
    +    (0x2FB8, 'M', '首'),
    +    (0x2FB9, 'M', '香'),
    +    (0x2FBA, 'M', '馬'),
    +    (0x2FBB, 'M', '骨'),
    +    (0x2FBC, 'M', '高'),
    +    (0x2FBD, 'M', '髟'),
    +    (0x2FBE, 'M', '鬥'),
    +    (0x2FBF, 'M', '鬯'),
    +    (0x2FC0, 'M', '鬲'),
    +    (0x2FC1, 'M', '鬼'),
    +    (0x2FC2, 'M', '魚'),
    +    (0x2FC3, 'M', '鳥'),
    +    (0x2FC4, 'M', '鹵'),
    +    (0x2FC5, 'M', '鹿'),
    +    (0x2FC6, 'M', '麥'),
    +    (0x2FC7, 'M', '麻'),
    +    (0x2FC8, 'M', '黃'),
    +    (0x2FC9, 'M', '黍'),
    +    (0x2FCA, 'M', '黑'),
    +    (0x2FCB, 'M', '黹'),
    +    (0x2FCC, 'M', '黽'),
    +    (0x2FCD, 'M', '鼎'),
    +    (0x2FCE, 'M', '鼓'),
    +    (0x2FCF, 'M', '鼠'),
    +    (0x2FD0, 'M', '鼻'),
    +    (0x2FD1, 'M', '齊'),
    +    (0x2FD2, 'M', '齒'),
    +    (0x2FD3, 'M', '龍'),
    +    (0x2FD4, 'M', '龜'),
    +    (0x2FD5, 'M', '龠'),
    +    (0x2FD6, 'X'),
    +    (0x3000, '3', ' '),
    +    (0x3001, 'V'),
    +    (0x3002, 'M', '.'),
    +    (0x3003, 'V'),
    +    (0x3036, 'M', '〒'),
    +    (0x3037, 'V'),
    +    (0x3038, 'M', '十'),
    +    ]
    +
    +def _seg_29() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x3039, 'M', '卄'),
    +    (0x303A, 'M', '卅'),
    +    (0x303B, 'V'),
    +    (0x3040, 'X'),
    +    (0x3041, 'V'),
    +    (0x3097, 'X'),
    +    (0x3099, 'V'),
    +    (0x309B, '3', ' ゙'),
    +    (0x309C, '3', ' ゚'),
    +    (0x309D, 'V'),
    +    (0x309F, 'M', 'より'),
    +    (0x30A0, 'V'),
    +    (0x30FF, 'M', 'コト'),
    +    (0x3100, 'X'),
    +    (0x3105, 'V'),
    +    (0x3130, 'X'),
    +    (0x3131, 'M', 'ᄀ'),
    +    (0x3132, 'M', 'ᄁ'),
    +    (0x3133, 'M', 'ᆪ'),
    +    (0x3134, 'M', 'ᄂ'),
    +    (0x3135, 'M', 'ᆬ'),
    +    (0x3136, 'M', 'ᆭ'),
    +    (0x3137, 'M', 'ᄃ'),
    +    (0x3138, 'M', 'ᄄ'),
    +    (0x3139, 'M', 'ᄅ'),
    +    (0x313A, 'M', 'ᆰ'),
    +    (0x313B, 'M', 'ᆱ'),
    +    (0x313C, 'M', 'ᆲ'),
    +    (0x313D, 'M', 'ᆳ'),
    +    (0x313E, 'M', 'ᆴ'),
    +    (0x313F, 'M', 'ᆵ'),
    +    (0x3140, 'M', 'ᄚ'),
    +    (0x3141, 'M', 'ᄆ'),
    +    (0x3142, 'M', 'ᄇ'),
    +    (0x3143, 'M', 'ᄈ'),
    +    (0x3144, 'M', 'ᄡ'),
    +    (0x3145, 'M', 'ᄉ'),
    +    (0x3146, 'M', 'ᄊ'),
    +    (0x3147, 'M', 'ᄋ'),
    +    (0x3148, 'M', 'ᄌ'),
    +    (0x3149, 'M', 'ᄍ'),
    +    (0x314A, 'M', 'ᄎ'),
    +    (0x314B, 'M', 'ᄏ'),
    +    (0x314C, 'M', 'ᄐ'),
    +    (0x314D, 'M', 'ᄑ'),
    +    (0x314E, 'M', 'ᄒ'),
    +    (0x314F, 'M', 'ᅡ'),
    +    (0x3150, 'M', 'ᅢ'),
    +    (0x3151, 'M', 'ᅣ'),
    +    (0x3152, 'M', 'ᅤ'),
    +    (0x3153, 'M', 'ᅥ'),
    +    (0x3154, 'M', 'ᅦ'),
    +    (0x3155, 'M', 'ᅧ'),
    +    (0x3156, 'M', 'ᅨ'),
    +    (0x3157, 'M', 'ᅩ'),
    +    (0x3158, 'M', 'ᅪ'),
    +    (0x3159, 'M', 'ᅫ'),
    +    (0x315A, 'M', 'ᅬ'),
    +    (0x315B, 'M', 'ᅭ'),
    +    (0x315C, 'M', 'ᅮ'),
    +    (0x315D, 'M', 'ᅯ'),
    +    (0x315E, 'M', 'ᅰ'),
    +    (0x315F, 'M', 'ᅱ'),
    +    (0x3160, 'M', 'ᅲ'),
    +    (0x3161, 'M', 'ᅳ'),
    +    (0x3162, 'M', 'ᅴ'),
    +    (0x3163, 'M', 'ᅵ'),
    +    (0x3164, 'X'),
    +    (0x3165, 'M', 'ᄔ'),
    +    (0x3166, 'M', 'ᄕ'),
    +    (0x3167, 'M', 'ᇇ'),
    +    (0x3168, 'M', 'ᇈ'),
    +    (0x3169, 'M', 'ᇌ'),
    +    (0x316A, 'M', 'ᇎ'),
    +    (0x316B, 'M', 'ᇓ'),
    +    (0x316C, 'M', 'ᇗ'),
    +    (0x316D, 'M', 'ᇙ'),
    +    (0x316E, 'M', 'ᄜ'),
    +    (0x316F, 'M', 'ᇝ'),
    +    (0x3170, 'M', 'ᇟ'),
    +    (0x3171, 'M', 'ᄝ'),
    +    (0x3172, 'M', 'ᄞ'),
    +    (0x3173, 'M', 'ᄠ'),
    +    (0x3174, 'M', 'ᄢ'),
    +    (0x3175, 'M', 'ᄣ'),
    +    (0x3176, 'M', 'ᄧ'),
    +    (0x3177, 'M', 'ᄩ'),
    +    (0x3178, 'M', 'ᄫ'),
    +    (0x3179, 'M', 'ᄬ'),
    +    (0x317A, 'M', 'ᄭ'),
    +    (0x317B, 'M', 'ᄮ'),
    +    (0x317C, 'M', 'ᄯ'),
    +    (0x317D, 'M', 'ᄲ'),
    +    (0x317E, 'M', 'ᄶ'),
    +    (0x317F, 'M', 'ᅀ'),
    +    (0x3180, 'M', 'ᅇ'),
    +    (0x3181, 'M', 'ᅌ'),
    +    (0x3182, 'M', 'ᇱ'),
    +    (0x3183, 'M', 'ᇲ'),
    +    (0x3184, 'M', 'ᅗ'),
    +    ]
    +
    +def _seg_30() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x3185, 'M', 'ᅘ'),
    +    (0x3186, 'M', 'ᅙ'),
    +    (0x3187, 'M', 'ᆄ'),
    +    (0x3188, 'M', 'ᆅ'),
    +    (0x3189, 'M', 'ᆈ'),
    +    (0x318A, 'M', 'ᆑ'),
    +    (0x318B, 'M', 'ᆒ'),
    +    (0x318C, 'M', 'ᆔ'),
    +    (0x318D, 'M', 'ᆞ'),
    +    (0x318E, 'M', 'ᆡ'),
    +    (0x318F, 'X'),
    +    (0x3190, 'V'),
    +    (0x3192, 'M', '一'),
    +    (0x3193, 'M', '二'),
    +    (0x3194, 'M', '三'),
    +    (0x3195, 'M', '四'),
    +    (0x3196, 'M', '上'),
    +    (0x3197, 'M', '中'),
    +    (0x3198, 'M', '下'),
    +    (0x3199, 'M', '甲'),
    +    (0x319A, 'M', '乙'),
    +    (0x319B, 'M', '丙'),
    +    (0x319C, 'M', '丁'),
    +    (0x319D, 'M', '天'),
    +    (0x319E, 'M', '地'),
    +    (0x319F, 'M', '人'),
    +    (0x31A0, 'V'),
    +    (0x31E4, 'X'),
    +    (0x31F0, 'V'),
    +    (0x3200, '3', '(ᄀ)'),
    +    (0x3201, '3', '(ᄂ)'),
    +    (0x3202, '3', '(ᄃ)'),
    +    (0x3203, '3', '(ᄅ)'),
    +    (0x3204, '3', '(ᄆ)'),
    +    (0x3205, '3', '(ᄇ)'),
    +    (0x3206, '3', '(ᄉ)'),
    +    (0x3207, '3', '(ᄋ)'),
    +    (0x3208, '3', '(ᄌ)'),
    +    (0x3209, '3', '(ᄎ)'),
    +    (0x320A, '3', '(ᄏ)'),
    +    (0x320B, '3', '(ᄐ)'),
    +    (0x320C, '3', '(ᄑ)'),
    +    (0x320D, '3', '(ᄒ)'),
    +    (0x320E, '3', '(가)'),
    +    (0x320F, '3', '(나)'),
    +    (0x3210, '3', '(다)'),
    +    (0x3211, '3', '(라)'),
    +    (0x3212, '3', '(마)'),
    +    (0x3213, '3', '(바)'),
    +    (0x3214, '3', '(사)'),
    +    (0x3215, '3', '(아)'),
    +    (0x3216, '3', '(자)'),
    +    (0x3217, '3', '(차)'),
    +    (0x3218, '3', '(카)'),
    +    (0x3219, '3', '(타)'),
    +    (0x321A, '3', '(파)'),
    +    (0x321B, '3', '(하)'),
    +    (0x321C, '3', '(주)'),
    +    (0x321D, '3', '(오전)'),
    +    (0x321E, '3', '(오후)'),
    +    (0x321F, 'X'),
    +    (0x3220, '3', '(一)'),
    +    (0x3221, '3', '(二)'),
    +    (0x3222, '3', '(三)'),
    +    (0x3223, '3', '(四)'),
    +    (0x3224, '3', '(五)'),
    +    (0x3225, '3', '(六)'),
    +    (0x3226, '3', '(七)'),
    +    (0x3227, '3', '(八)'),
    +    (0x3228, '3', '(九)'),
    +    (0x3229, '3', '(十)'),
    +    (0x322A, '3', '(月)'),
    +    (0x322B, '3', '(火)'),
    +    (0x322C, '3', '(水)'),
    +    (0x322D, '3', '(木)'),
    +    (0x322E, '3', '(金)'),
    +    (0x322F, '3', '(土)'),
    +    (0x3230, '3', '(日)'),
    +    (0x3231, '3', '(株)'),
    +    (0x3232, '3', '(有)'),
    +    (0x3233, '3', '(社)'),
    +    (0x3234, '3', '(名)'),
    +    (0x3235, '3', '(特)'),
    +    (0x3236, '3', '(財)'),
    +    (0x3237, '3', '(祝)'),
    +    (0x3238, '3', '(労)'),
    +    (0x3239, '3', '(代)'),
    +    (0x323A, '3', '(呼)'),
    +    (0x323B, '3', '(学)'),
    +    (0x323C, '3', '(監)'),
    +    (0x323D, '3', '(企)'),
    +    (0x323E, '3', '(資)'),
    +    (0x323F, '3', '(協)'),
    +    (0x3240, '3', '(祭)'),
    +    (0x3241, '3', '(休)'),
    +    (0x3242, '3', '(自)'),
    +    (0x3243, '3', '(至)'),
    +    (0x3244, 'M', '問'),
    +    (0x3245, 'M', '幼'),
    +    (0x3246, 'M', '文'),
    +    ]
    +
    +def _seg_31() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x3247, 'M', '箏'),
    +    (0x3248, 'V'),
    +    (0x3250, 'M', 'pte'),
    +    (0x3251, 'M', '21'),
    +    (0x3252, 'M', '22'),
    +    (0x3253, 'M', '23'),
    +    (0x3254, 'M', '24'),
    +    (0x3255, 'M', '25'),
    +    (0x3256, 'M', '26'),
    +    (0x3257, 'M', '27'),
    +    (0x3258, 'M', '28'),
    +    (0x3259, 'M', '29'),
    +    (0x325A, 'M', '30'),
    +    (0x325B, 'M', '31'),
    +    (0x325C, 'M', '32'),
    +    (0x325D, 'M', '33'),
    +    (0x325E, 'M', '34'),
    +    (0x325F, 'M', '35'),
    +    (0x3260, 'M', 'ᄀ'),
    +    (0x3261, 'M', 'ᄂ'),
    +    (0x3262, 'M', 'ᄃ'),
    +    (0x3263, 'M', 'ᄅ'),
    +    (0x3264, 'M', 'ᄆ'),
    +    (0x3265, 'M', 'ᄇ'),
    +    (0x3266, 'M', 'ᄉ'),
    +    (0x3267, 'M', 'ᄋ'),
    +    (0x3268, 'M', 'ᄌ'),
    +    (0x3269, 'M', 'ᄎ'),
    +    (0x326A, 'M', 'ᄏ'),
    +    (0x326B, 'M', 'ᄐ'),
    +    (0x326C, 'M', 'ᄑ'),
    +    (0x326D, 'M', 'ᄒ'),
    +    (0x326E, 'M', '가'),
    +    (0x326F, 'M', '나'),
    +    (0x3270, 'M', '다'),
    +    (0x3271, 'M', '라'),
    +    (0x3272, 'M', '마'),
    +    (0x3273, 'M', '바'),
    +    (0x3274, 'M', '사'),
    +    (0x3275, 'M', '아'),
    +    (0x3276, 'M', '자'),
    +    (0x3277, 'M', '차'),
    +    (0x3278, 'M', '카'),
    +    (0x3279, 'M', '타'),
    +    (0x327A, 'M', '파'),
    +    (0x327B, 'M', '하'),
    +    (0x327C, 'M', '참고'),
    +    (0x327D, 'M', '주의'),
    +    (0x327E, 'M', '우'),
    +    (0x327F, 'V'),
    +    (0x3280, 'M', '一'),
    +    (0x3281, 'M', '二'),
    +    (0x3282, 'M', '三'),
    +    (0x3283, 'M', '四'),
    +    (0x3284, 'M', '五'),
    +    (0x3285, 'M', '六'),
    +    (0x3286, 'M', '七'),
    +    (0x3287, 'M', '八'),
    +    (0x3288, 'M', '九'),
    +    (0x3289, 'M', '十'),
    +    (0x328A, 'M', '月'),
    +    (0x328B, 'M', '火'),
    +    (0x328C, 'M', '水'),
    +    (0x328D, 'M', '木'),
    +    (0x328E, 'M', '金'),
    +    (0x328F, 'M', '土'),
    +    (0x3290, 'M', '日'),
    +    (0x3291, 'M', '株'),
    +    (0x3292, 'M', '有'),
    +    (0x3293, 'M', '社'),
    +    (0x3294, 'M', '名'),
    +    (0x3295, 'M', '特'),
    +    (0x3296, 'M', '財'),
    +    (0x3297, 'M', '祝'),
    +    (0x3298, 'M', '労'),
    +    (0x3299, 'M', '秘'),
    +    (0x329A, 'M', '男'),
    +    (0x329B, 'M', '女'),
    +    (0x329C, 'M', '適'),
    +    (0x329D, 'M', '優'),
    +    (0x329E, 'M', '印'),
    +    (0x329F, 'M', '注'),
    +    (0x32A0, 'M', '項'),
    +    (0x32A1, 'M', '休'),
    +    (0x32A2, 'M', '写'),
    +    (0x32A3, 'M', '正'),
    +    (0x32A4, 'M', '上'),
    +    (0x32A5, 'M', '中'),
    +    (0x32A6, 'M', '下'),
    +    (0x32A7, 'M', '左'),
    +    (0x32A8, 'M', '右'),
    +    (0x32A9, 'M', '医'),
    +    (0x32AA, 'M', '宗'),
    +    (0x32AB, 'M', '学'),
    +    (0x32AC, 'M', '監'),
    +    (0x32AD, 'M', '企'),
    +    (0x32AE, 'M', '資'),
    +    (0x32AF, 'M', '協'),
    +    (0x32B0, 'M', '夜'),
    +    (0x32B1, 'M', '36'),
    +    ]
    +
    +def _seg_32() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x32B2, 'M', '37'),
    +    (0x32B3, 'M', '38'),
    +    (0x32B4, 'M', '39'),
    +    (0x32B5, 'M', '40'),
    +    (0x32B6, 'M', '41'),
    +    (0x32B7, 'M', '42'),
    +    (0x32B8, 'M', '43'),
    +    (0x32B9, 'M', '44'),
    +    (0x32BA, 'M', '45'),
    +    (0x32BB, 'M', '46'),
    +    (0x32BC, 'M', '47'),
    +    (0x32BD, 'M', '48'),
    +    (0x32BE, 'M', '49'),
    +    (0x32BF, 'M', '50'),
    +    (0x32C0, 'M', '1月'),
    +    (0x32C1, 'M', '2月'),
    +    (0x32C2, 'M', '3月'),
    +    (0x32C3, 'M', '4月'),
    +    (0x32C4, 'M', '5月'),
    +    (0x32C5, 'M', '6月'),
    +    (0x32C6, 'M', '7月'),
    +    (0x32C7, 'M', '8月'),
    +    (0x32C8, 'M', '9月'),
    +    (0x32C9, 'M', '10月'),
    +    (0x32CA, 'M', '11月'),
    +    (0x32CB, 'M', '12月'),
    +    (0x32CC, 'M', 'hg'),
    +    (0x32CD, 'M', 'erg'),
    +    (0x32CE, 'M', 'ev'),
    +    (0x32CF, 'M', 'ltd'),
    +    (0x32D0, 'M', 'ア'),
    +    (0x32D1, 'M', 'イ'),
    +    (0x32D2, 'M', 'ウ'),
    +    (0x32D3, 'M', 'エ'),
    +    (0x32D4, 'M', 'オ'),
    +    (0x32D5, 'M', 'カ'),
    +    (0x32D6, 'M', 'キ'),
    +    (0x32D7, 'M', 'ク'),
    +    (0x32D8, 'M', 'ケ'),
    +    (0x32D9, 'M', 'コ'),
    +    (0x32DA, 'M', 'サ'),
    +    (0x32DB, 'M', 'シ'),
    +    (0x32DC, 'M', 'ス'),
    +    (0x32DD, 'M', 'セ'),
    +    (0x32DE, 'M', 'ソ'),
    +    (0x32DF, 'M', 'タ'),
    +    (0x32E0, 'M', 'チ'),
    +    (0x32E1, 'M', 'ツ'),
    +    (0x32E2, 'M', 'テ'),
    +    (0x32E3, 'M', 'ト'),
    +    (0x32E4, 'M', 'ナ'),
    +    (0x32E5, 'M', 'ニ'),
    +    (0x32E6, 'M', 'ヌ'),
    +    (0x32E7, 'M', 'ネ'),
    +    (0x32E8, 'M', 'ノ'),
    +    (0x32E9, 'M', 'ハ'),
    +    (0x32EA, 'M', 'ヒ'),
    +    (0x32EB, 'M', 'フ'),
    +    (0x32EC, 'M', 'ヘ'),
    +    (0x32ED, 'M', 'ホ'),
    +    (0x32EE, 'M', 'マ'),
    +    (0x32EF, 'M', 'ミ'),
    +    (0x32F0, 'M', 'ム'),
    +    (0x32F1, 'M', 'メ'),
    +    (0x32F2, 'M', 'モ'),
    +    (0x32F3, 'M', 'ヤ'),
    +    (0x32F4, 'M', 'ユ'),
    +    (0x32F5, 'M', 'ヨ'),
    +    (0x32F6, 'M', 'ラ'),
    +    (0x32F7, 'M', 'リ'),
    +    (0x32F8, 'M', 'ル'),
    +    (0x32F9, 'M', 'レ'),
    +    (0x32FA, 'M', 'ロ'),
    +    (0x32FB, 'M', 'ワ'),
    +    (0x32FC, 'M', 'ヰ'),
    +    (0x32FD, 'M', 'ヱ'),
    +    (0x32FE, 'M', 'ヲ'),
    +    (0x32FF, 'M', '令和'),
    +    (0x3300, 'M', 'アパート'),
    +    (0x3301, 'M', 'アルファ'),
    +    (0x3302, 'M', 'アンペア'),
    +    (0x3303, 'M', 'アール'),
    +    (0x3304, 'M', 'イニング'),
    +    (0x3305, 'M', 'インチ'),
    +    (0x3306, 'M', 'ウォン'),
    +    (0x3307, 'M', 'エスクード'),
    +    (0x3308, 'M', 'エーカー'),
    +    (0x3309, 'M', 'オンス'),
    +    (0x330A, 'M', 'オーム'),
    +    (0x330B, 'M', 'カイリ'),
    +    (0x330C, 'M', 'カラット'),
    +    (0x330D, 'M', 'カロリー'),
    +    (0x330E, 'M', 'ガロン'),
    +    (0x330F, 'M', 'ガンマ'),
    +    (0x3310, 'M', 'ギガ'),
    +    (0x3311, 'M', 'ギニー'),
    +    (0x3312, 'M', 'キュリー'),
    +    (0x3313, 'M', 'ギルダー'),
    +    (0x3314, 'M', 'キロ'),
    +    (0x3315, 'M', 'キログラム'),
    +    ]
    +
    +def _seg_33() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x3316, 'M', 'キロメートル'),
    +    (0x3317, 'M', 'キロワット'),
    +    (0x3318, 'M', 'グラム'),
    +    (0x3319, 'M', 'グラムトン'),
    +    (0x331A, 'M', 'クルゼイロ'),
    +    (0x331B, 'M', 'クローネ'),
    +    (0x331C, 'M', 'ケース'),
    +    (0x331D, 'M', 'コルナ'),
    +    (0x331E, 'M', 'コーポ'),
    +    (0x331F, 'M', 'サイクル'),
    +    (0x3320, 'M', 'サンチーム'),
    +    (0x3321, 'M', 'シリング'),
    +    (0x3322, 'M', 'センチ'),
    +    (0x3323, 'M', 'セント'),
    +    (0x3324, 'M', 'ダース'),
    +    (0x3325, 'M', 'デシ'),
    +    (0x3326, 'M', 'ドル'),
    +    (0x3327, 'M', 'トン'),
    +    (0x3328, 'M', 'ナノ'),
    +    (0x3329, 'M', 'ノット'),
    +    (0x332A, 'M', 'ハイツ'),
    +    (0x332B, 'M', 'パーセント'),
    +    (0x332C, 'M', 'パーツ'),
    +    (0x332D, 'M', 'バーレル'),
    +    (0x332E, 'M', 'ピアストル'),
    +    (0x332F, 'M', 'ピクル'),
    +    (0x3330, 'M', 'ピコ'),
    +    (0x3331, 'M', 'ビル'),
    +    (0x3332, 'M', 'ファラッド'),
    +    (0x3333, 'M', 'フィート'),
    +    (0x3334, 'M', 'ブッシェル'),
    +    (0x3335, 'M', 'フラン'),
    +    (0x3336, 'M', 'ヘクタール'),
    +    (0x3337, 'M', 'ペソ'),
    +    (0x3338, 'M', 'ペニヒ'),
    +    (0x3339, 'M', 'ヘルツ'),
    +    (0x333A, 'M', 'ペンス'),
    +    (0x333B, 'M', 'ページ'),
    +    (0x333C, 'M', 'ベータ'),
    +    (0x333D, 'M', 'ポイント'),
    +    (0x333E, 'M', 'ボルト'),
    +    (0x333F, 'M', 'ホン'),
    +    (0x3340, 'M', 'ポンド'),
    +    (0x3341, 'M', 'ホール'),
    +    (0x3342, 'M', 'ホーン'),
    +    (0x3343, 'M', 'マイクロ'),
    +    (0x3344, 'M', 'マイル'),
    +    (0x3345, 'M', 'マッハ'),
    +    (0x3346, 'M', 'マルク'),
    +    (0x3347, 'M', 'マンション'),
    +    (0x3348, 'M', 'ミクロン'),
    +    (0x3349, 'M', 'ミリ'),
    +    (0x334A, 'M', 'ミリバール'),
    +    (0x334B, 'M', 'メガ'),
    +    (0x334C, 'M', 'メガトン'),
    +    (0x334D, 'M', 'メートル'),
    +    (0x334E, 'M', 'ヤード'),
    +    (0x334F, 'M', 'ヤール'),
    +    (0x3350, 'M', 'ユアン'),
    +    (0x3351, 'M', 'リットル'),
    +    (0x3352, 'M', 'リラ'),
    +    (0x3353, 'M', 'ルピー'),
    +    (0x3354, 'M', 'ルーブル'),
    +    (0x3355, 'M', 'レム'),
    +    (0x3356, 'M', 'レントゲン'),
    +    (0x3357, 'M', 'ワット'),
    +    (0x3358, 'M', '0点'),
    +    (0x3359, 'M', '1点'),
    +    (0x335A, 'M', '2点'),
    +    (0x335B, 'M', '3点'),
    +    (0x335C, 'M', '4点'),
    +    (0x335D, 'M', '5点'),
    +    (0x335E, 'M', '6点'),
    +    (0x335F, 'M', '7点'),
    +    (0x3360, 'M', '8点'),
    +    (0x3361, 'M', '9点'),
    +    (0x3362, 'M', '10点'),
    +    (0x3363, 'M', '11点'),
    +    (0x3364, 'M', '12点'),
    +    (0x3365, 'M', '13点'),
    +    (0x3366, 'M', '14点'),
    +    (0x3367, 'M', '15点'),
    +    (0x3368, 'M', '16点'),
    +    (0x3369, 'M', '17点'),
    +    (0x336A, 'M', '18点'),
    +    (0x336B, 'M', '19点'),
    +    (0x336C, 'M', '20点'),
    +    (0x336D, 'M', '21点'),
    +    (0x336E, 'M', '22点'),
    +    (0x336F, 'M', '23点'),
    +    (0x3370, 'M', '24点'),
    +    (0x3371, 'M', 'hpa'),
    +    (0x3372, 'M', 'da'),
    +    (0x3373, 'M', 'au'),
    +    (0x3374, 'M', 'bar'),
    +    (0x3375, 'M', 'ov'),
    +    (0x3376, 'M', 'pc'),
    +    (0x3377, 'M', 'dm'),
    +    (0x3378, 'M', 'dm2'),
    +    (0x3379, 'M', 'dm3'),
    +    ]
    +
    +def _seg_34() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x337A, 'M', 'iu'),
    +    (0x337B, 'M', '平成'),
    +    (0x337C, 'M', '昭和'),
    +    (0x337D, 'M', '大正'),
    +    (0x337E, 'M', '明治'),
    +    (0x337F, 'M', '株式会社'),
    +    (0x3380, 'M', 'pa'),
    +    (0x3381, 'M', 'na'),
    +    (0x3382, 'M', 'μa'),
    +    (0x3383, 'M', 'ma'),
    +    (0x3384, 'M', 'ka'),
    +    (0x3385, 'M', 'kb'),
    +    (0x3386, 'M', 'mb'),
    +    (0x3387, 'M', 'gb'),
    +    (0x3388, 'M', 'cal'),
    +    (0x3389, 'M', 'kcal'),
    +    (0x338A, 'M', 'pf'),
    +    (0x338B, 'M', 'nf'),
    +    (0x338C, 'M', 'μf'),
    +    (0x338D, 'M', 'μg'),
    +    (0x338E, 'M', 'mg'),
    +    (0x338F, 'M', 'kg'),
    +    (0x3390, 'M', 'hz'),
    +    (0x3391, 'M', 'khz'),
    +    (0x3392, 'M', 'mhz'),
    +    (0x3393, 'M', 'ghz'),
    +    (0x3394, 'M', 'thz'),
    +    (0x3395, 'M', 'μl'),
    +    (0x3396, 'M', 'ml'),
    +    (0x3397, 'M', 'dl'),
    +    (0x3398, 'M', 'kl'),
    +    (0x3399, 'M', 'fm'),
    +    (0x339A, 'M', 'nm'),
    +    (0x339B, 'M', 'μm'),
    +    (0x339C, 'M', 'mm'),
    +    (0x339D, 'M', 'cm'),
    +    (0x339E, 'M', 'km'),
    +    (0x339F, 'M', 'mm2'),
    +    (0x33A0, 'M', 'cm2'),
    +    (0x33A1, 'M', 'm2'),
    +    (0x33A2, 'M', 'km2'),
    +    (0x33A3, 'M', 'mm3'),
    +    (0x33A4, 'M', 'cm3'),
    +    (0x33A5, 'M', 'm3'),
    +    (0x33A6, 'M', 'km3'),
    +    (0x33A7, 'M', 'm∕s'),
    +    (0x33A8, 'M', 'm∕s2'),
    +    (0x33A9, 'M', 'pa'),
    +    (0x33AA, 'M', 'kpa'),
    +    (0x33AB, 'M', 'mpa'),
    +    (0x33AC, 'M', 'gpa'),
    +    (0x33AD, 'M', 'rad'),
    +    (0x33AE, 'M', 'rad∕s'),
    +    (0x33AF, 'M', 'rad∕s2'),
    +    (0x33B0, 'M', 'ps'),
    +    (0x33B1, 'M', 'ns'),
    +    (0x33B2, 'M', 'μs'),
    +    (0x33B3, 'M', 'ms'),
    +    (0x33B4, 'M', 'pv'),
    +    (0x33B5, 'M', 'nv'),
    +    (0x33B6, 'M', 'μv'),
    +    (0x33B7, 'M', 'mv'),
    +    (0x33B8, 'M', 'kv'),
    +    (0x33B9, 'M', 'mv'),
    +    (0x33BA, 'M', 'pw'),
    +    (0x33BB, 'M', 'nw'),
    +    (0x33BC, 'M', 'μw'),
    +    (0x33BD, 'M', 'mw'),
    +    (0x33BE, 'M', 'kw'),
    +    (0x33BF, 'M', 'mw'),
    +    (0x33C0, 'M', 'kω'),
    +    (0x33C1, 'M', 'mω'),
    +    (0x33C2, 'X'),
    +    (0x33C3, 'M', 'bq'),
    +    (0x33C4, 'M', 'cc'),
    +    (0x33C5, 'M', 'cd'),
    +    (0x33C6, 'M', 'c∕kg'),
    +    (0x33C7, 'X'),
    +    (0x33C8, 'M', 'db'),
    +    (0x33C9, 'M', 'gy'),
    +    (0x33CA, 'M', 'ha'),
    +    (0x33CB, 'M', 'hp'),
    +    (0x33CC, 'M', 'in'),
    +    (0x33CD, 'M', 'kk'),
    +    (0x33CE, 'M', 'km'),
    +    (0x33CF, 'M', 'kt'),
    +    (0x33D0, 'M', 'lm'),
    +    (0x33D1, 'M', 'ln'),
    +    (0x33D2, 'M', 'log'),
    +    (0x33D3, 'M', 'lx'),
    +    (0x33D4, 'M', 'mb'),
    +    (0x33D5, 'M', 'mil'),
    +    (0x33D6, 'M', 'mol'),
    +    (0x33D7, 'M', 'ph'),
    +    (0x33D8, 'X'),
    +    (0x33D9, 'M', 'ppm'),
    +    (0x33DA, 'M', 'pr'),
    +    (0x33DB, 'M', 'sr'),
    +    (0x33DC, 'M', 'sv'),
    +    (0x33DD, 'M', 'wb'),
    +    ]
    +
    +def _seg_35() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x33DE, 'M', 'v∕m'),
    +    (0x33DF, 'M', 'a∕m'),
    +    (0x33E0, 'M', '1日'),
    +    (0x33E1, 'M', '2日'),
    +    (0x33E2, 'M', '3日'),
    +    (0x33E3, 'M', '4日'),
    +    (0x33E4, 'M', '5日'),
    +    (0x33E5, 'M', '6日'),
    +    (0x33E6, 'M', '7日'),
    +    (0x33E7, 'M', '8日'),
    +    (0x33E8, 'M', '9日'),
    +    (0x33E9, 'M', '10日'),
    +    (0x33EA, 'M', '11日'),
    +    (0x33EB, 'M', '12日'),
    +    (0x33EC, 'M', '13日'),
    +    (0x33ED, 'M', '14日'),
    +    (0x33EE, 'M', '15日'),
    +    (0x33EF, 'M', '16日'),
    +    (0x33F0, 'M', '17日'),
    +    (0x33F1, 'M', '18日'),
    +    (0x33F2, 'M', '19日'),
    +    (0x33F3, 'M', '20日'),
    +    (0x33F4, 'M', '21日'),
    +    (0x33F5, 'M', '22日'),
    +    (0x33F6, 'M', '23日'),
    +    (0x33F7, 'M', '24日'),
    +    (0x33F8, 'M', '25日'),
    +    (0x33F9, 'M', '26日'),
    +    (0x33FA, 'M', '27日'),
    +    (0x33FB, 'M', '28日'),
    +    (0x33FC, 'M', '29日'),
    +    (0x33FD, 'M', '30日'),
    +    (0x33FE, 'M', '31日'),
    +    (0x33FF, 'M', 'gal'),
    +    (0x3400, 'V'),
    +    (0xA48D, 'X'),
    +    (0xA490, 'V'),
    +    (0xA4C7, 'X'),
    +    (0xA4D0, 'V'),
    +    (0xA62C, 'X'),
    +    (0xA640, 'M', 'ꙁ'),
    +    (0xA641, 'V'),
    +    (0xA642, 'M', 'ꙃ'),
    +    (0xA643, 'V'),
    +    (0xA644, 'M', 'ꙅ'),
    +    (0xA645, 'V'),
    +    (0xA646, 'M', 'ꙇ'),
    +    (0xA647, 'V'),
    +    (0xA648, 'M', 'ꙉ'),
    +    (0xA649, 'V'),
    +    (0xA64A, 'M', 'ꙋ'),
    +    (0xA64B, 'V'),
    +    (0xA64C, 'M', 'ꙍ'),
    +    (0xA64D, 'V'),
    +    (0xA64E, 'M', 'ꙏ'),
    +    (0xA64F, 'V'),
    +    (0xA650, 'M', 'ꙑ'),
    +    (0xA651, 'V'),
    +    (0xA652, 'M', 'ꙓ'),
    +    (0xA653, 'V'),
    +    (0xA654, 'M', 'ꙕ'),
    +    (0xA655, 'V'),
    +    (0xA656, 'M', 'ꙗ'),
    +    (0xA657, 'V'),
    +    (0xA658, 'M', 'ꙙ'),
    +    (0xA659, 'V'),
    +    (0xA65A, 'M', 'ꙛ'),
    +    (0xA65B, 'V'),
    +    (0xA65C, 'M', 'ꙝ'),
    +    (0xA65D, 'V'),
    +    (0xA65E, 'M', 'ꙟ'),
    +    (0xA65F, 'V'),
    +    (0xA660, 'M', 'ꙡ'),
    +    (0xA661, 'V'),
    +    (0xA662, 'M', 'ꙣ'),
    +    (0xA663, 'V'),
    +    (0xA664, 'M', 'ꙥ'),
    +    (0xA665, 'V'),
    +    (0xA666, 'M', 'ꙧ'),
    +    (0xA667, 'V'),
    +    (0xA668, 'M', 'ꙩ'),
    +    (0xA669, 'V'),
    +    (0xA66A, 'M', 'ꙫ'),
    +    (0xA66B, 'V'),
    +    (0xA66C, 'M', 'ꙭ'),
    +    (0xA66D, 'V'),
    +    (0xA680, 'M', 'ꚁ'),
    +    (0xA681, 'V'),
    +    (0xA682, 'M', 'ꚃ'),
    +    (0xA683, 'V'),
    +    (0xA684, 'M', 'ꚅ'),
    +    (0xA685, 'V'),
    +    (0xA686, 'M', 'ꚇ'),
    +    (0xA687, 'V'),
    +    (0xA688, 'M', 'ꚉ'),
    +    (0xA689, 'V'),
    +    (0xA68A, 'M', 'ꚋ'),
    +    (0xA68B, 'V'),
    +    (0xA68C, 'M', 'ꚍ'),
    +    (0xA68D, 'V'),
    +    ]
    +
    +def _seg_36() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xA68E, 'M', 'ꚏ'),
    +    (0xA68F, 'V'),
    +    (0xA690, 'M', 'ꚑ'),
    +    (0xA691, 'V'),
    +    (0xA692, 'M', 'ꚓ'),
    +    (0xA693, 'V'),
    +    (0xA694, 'M', 'ꚕ'),
    +    (0xA695, 'V'),
    +    (0xA696, 'M', 'ꚗ'),
    +    (0xA697, 'V'),
    +    (0xA698, 'M', 'ꚙ'),
    +    (0xA699, 'V'),
    +    (0xA69A, 'M', 'ꚛ'),
    +    (0xA69B, 'V'),
    +    (0xA69C, 'M', 'ъ'),
    +    (0xA69D, 'M', 'ь'),
    +    (0xA69E, 'V'),
    +    (0xA6F8, 'X'),
    +    (0xA700, 'V'),
    +    (0xA722, 'M', 'ꜣ'),
    +    (0xA723, 'V'),
    +    (0xA724, 'M', 'ꜥ'),
    +    (0xA725, 'V'),
    +    (0xA726, 'M', 'ꜧ'),
    +    (0xA727, 'V'),
    +    (0xA728, 'M', 'ꜩ'),
    +    (0xA729, 'V'),
    +    (0xA72A, 'M', 'ꜫ'),
    +    (0xA72B, 'V'),
    +    (0xA72C, 'M', 'ꜭ'),
    +    (0xA72D, 'V'),
    +    (0xA72E, 'M', 'ꜯ'),
    +    (0xA72F, 'V'),
    +    (0xA732, 'M', 'ꜳ'),
    +    (0xA733, 'V'),
    +    (0xA734, 'M', 'ꜵ'),
    +    (0xA735, 'V'),
    +    (0xA736, 'M', 'ꜷ'),
    +    (0xA737, 'V'),
    +    (0xA738, 'M', 'ꜹ'),
    +    (0xA739, 'V'),
    +    (0xA73A, 'M', 'ꜻ'),
    +    (0xA73B, 'V'),
    +    (0xA73C, 'M', 'ꜽ'),
    +    (0xA73D, 'V'),
    +    (0xA73E, 'M', 'ꜿ'),
    +    (0xA73F, 'V'),
    +    (0xA740, 'M', 'ꝁ'),
    +    (0xA741, 'V'),
    +    (0xA742, 'M', 'ꝃ'),
    +    (0xA743, 'V'),
    +    (0xA744, 'M', 'ꝅ'),
    +    (0xA745, 'V'),
    +    (0xA746, 'M', 'ꝇ'),
    +    (0xA747, 'V'),
    +    (0xA748, 'M', 'ꝉ'),
    +    (0xA749, 'V'),
    +    (0xA74A, 'M', 'ꝋ'),
    +    (0xA74B, 'V'),
    +    (0xA74C, 'M', 'ꝍ'),
    +    (0xA74D, 'V'),
    +    (0xA74E, 'M', 'ꝏ'),
    +    (0xA74F, 'V'),
    +    (0xA750, 'M', 'ꝑ'),
    +    (0xA751, 'V'),
    +    (0xA752, 'M', 'ꝓ'),
    +    (0xA753, 'V'),
    +    (0xA754, 'M', 'ꝕ'),
    +    (0xA755, 'V'),
    +    (0xA756, 'M', 'ꝗ'),
    +    (0xA757, 'V'),
    +    (0xA758, 'M', 'ꝙ'),
    +    (0xA759, 'V'),
    +    (0xA75A, 'M', 'ꝛ'),
    +    (0xA75B, 'V'),
    +    (0xA75C, 'M', 'ꝝ'),
    +    (0xA75D, 'V'),
    +    (0xA75E, 'M', 'ꝟ'),
    +    (0xA75F, 'V'),
    +    (0xA760, 'M', 'ꝡ'),
    +    (0xA761, 'V'),
    +    (0xA762, 'M', 'ꝣ'),
    +    (0xA763, 'V'),
    +    (0xA764, 'M', 'ꝥ'),
    +    (0xA765, 'V'),
    +    (0xA766, 'M', 'ꝧ'),
    +    (0xA767, 'V'),
    +    (0xA768, 'M', 'ꝩ'),
    +    (0xA769, 'V'),
    +    (0xA76A, 'M', 'ꝫ'),
    +    (0xA76B, 'V'),
    +    (0xA76C, 'M', 'ꝭ'),
    +    (0xA76D, 'V'),
    +    (0xA76E, 'M', 'ꝯ'),
    +    (0xA76F, 'V'),
    +    (0xA770, 'M', 'ꝯ'),
    +    (0xA771, 'V'),
    +    (0xA779, 'M', 'ꝺ'),
    +    (0xA77A, 'V'),
    +    (0xA77B, 'M', 'ꝼ'),
    +    ]
    +
    +def _seg_37() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xA77C, 'V'),
    +    (0xA77D, 'M', 'ᵹ'),
    +    (0xA77E, 'M', 'ꝿ'),
    +    (0xA77F, 'V'),
    +    (0xA780, 'M', 'ꞁ'),
    +    (0xA781, 'V'),
    +    (0xA782, 'M', 'ꞃ'),
    +    (0xA783, 'V'),
    +    (0xA784, 'M', 'ꞅ'),
    +    (0xA785, 'V'),
    +    (0xA786, 'M', 'ꞇ'),
    +    (0xA787, 'V'),
    +    (0xA78B, 'M', 'ꞌ'),
    +    (0xA78C, 'V'),
    +    (0xA78D, 'M', 'ɥ'),
    +    (0xA78E, 'V'),
    +    (0xA790, 'M', 'ꞑ'),
    +    (0xA791, 'V'),
    +    (0xA792, 'M', 'ꞓ'),
    +    (0xA793, 'V'),
    +    (0xA796, 'M', 'ꞗ'),
    +    (0xA797, 'V'),
    +    (0xA798, 'M', 'ꞙ'),
    +    (0xA799, 'V'),
    +    (0xA79A, 'M', 'ꞛ'),
    +    (0xA79B, 'V'),
    +    (0xA79C, 'M', 'ꞝ'),
    +    (0xA79D, 'V'),
    +    (0xA79E, 'M', 'ꞟ'),
    +    (0xA79F, 'V'),
    +    (0xA7A0, 'M', 'ꞡ'),
    +    (0xA7A1, 'V'),
    +    (0xA7A2, 'M', 'ꞣ'),
    +    (0xA7A3, 'V'),
    +    (0xA7A4, 'M', 'ꞥ'),
    +    (0xA7A5, 'V'),
    +    (0xA7A6, 'M', 'ꞧ'),
    +    (0xA7A7, 'V'),
    +    (0xA7A8, 'M', 'ꞩ'),
    +    (0xA7A9, 'V'),
    +    (0xA7AA, 'M', 'ɦ'),
    +    (0xA7AB, 'M', 'ɜ'),
    +    (0xA7AC, 'M', 'ɡ'),
    +    (0xA7AD, 'M', 'ɬ'),
    +    (0xA7AE, 'M', 'ɪ'),
    +    (0xA7AF, 'V'),
    +    (0xA7B0, 'M', 'ʞ'),
    +    (0xA7B1, 'M', 'ʇ'),
    +    (0xA7B2, 'M', 'ʝ'),
    +    (0xA7B3, 'M', 'ꭓ'),
    +    (0xA7B4, 'M', 'ꞵ'),
    +    (0xA7B5, 'V'),
    +    (0xA7B6, 'M', 'ꞷ'),
    +    (0xA7B7, 'V'),
    +    (0xA7B8, 'M', 'ꞹ'),
    +    (0xA7B9, 'V'),
    +    (0xA7BA, 'M', 'ꞻ'),
    +    (0xA7BB, 'V'),
    +    (0xA7BC, 'M', 'ꞽ'),
    +    (0xA7BD, 'V'),
    +    (0xA7BE, 'M', 'ꞿ'),
    +    (0xA7BF, 'V'),
    +    (0xA7C0, 'M', 'ꟁ'),
    +    (0xA7C1, 'V'),
    +    (0xA7C2, 'M', 'ꟃ'),
    +    (0xA7C3, 'V'),
    +    (0xA7C4, 'M', 'ꞔ'),
    +    (0xA7C5, 'M', 'ʂ'),
    +    (0xA7C6, 'M', 'ᶎ'),
    +    (0xA7C7, 'M', 'ꟈ'),
    +    (0xA7C8, 'V'),
    +    (0xA7C9, 'M', 'ꟊ'),
    +    (0xA7CA, 'V'),
    +    (0xA7CB, 'X'),
    +    (0xA7D0, 'M', 'ꟑ'),
    +    (0xA7D1, 'V'),
    +    (0xA7D2, 'X'),
    +    (0xA7D3, 'V'),
    +    (0xA7D4, 'X'),
    +    (0xA7D5, 'V'),
    +    (0xA7D6, 'M', 'ꟗ'),
    +    (0xA7D7, 'V'),
    +    (0xA7D8, 'M', 'ꟙ'),
    +    (0xA7D9, 'V'),
    +    (0xA7DA, 'X'),
    +    (0xA7F2, 'M', 'c'),
    +    (0xA7F3, 'M', 'f'),
    +    (0xA7F4, 'M', 'q'),
    +    (0xA7F5, 'M', 'ꟶ'),
    +    (0xA7F6, 'V'),
    +    (0xA7F8, 'M', 'ħ'),
    +    (0xA7F9, 'M', 'œ'),
    +    (0xA7FA, 'V'),
    +    (0xA82D, 'X'),
    +    (0xA830, 'V'),
    +    (0xA83A, 'X'),
    +    (0xA840, 'V'),
    +    (0xA878, 'X'),
    +    (0xA880, 'V'),
    +    (0xA8C6, 'X'),
    +    ]
    +
    +def _seg_38() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xA8CE, 'V'),
    +    (0xA8DA, 'X'),
    +    (0xA8E0, 'V'),
    +    (0xA954, 'X'),
    +    (0xA95F, 'V'),
    +    (0xA97D, 'X'),
    +    (0xA980, 'V'),
    +    (0xA9CE, 'X'),
    +    (0xA9CF, 'V'),
    +    (0xA9DA, 'X'),
    +    (0xA9DE, 'V'),
    +    (0xA9FF, 'X'),
    +    (0xAA00, 'V'),
    +    (0xAA37, 'X'),
    +    (0xAA40, 'V'),
    +    (0xAA4E, 'X'),
    +    (0xAA50, 'V'),
    +    (0xAA5A, 'X'),
    +    (0xAA5C, 'V'),
    +    (0xAAC3, 'X'),
    +    (0xAADB, 'V'),
    +    (0xAAF7, 'X'),
    +    (0xAB01, 'V'),
    +    (0xAB07, 'X'),
    +    (0xAB09, 'V'),
    +    (0xAB0F, 'X'),
    +    (0xAB11, 'V'),
    +    (0xAB17, 'X'),
    +    (0xAB20, 'V'),
    +    (0xAB27, 'X'),
    +    (0xAB28, 'V'),
    +    (0xAB2F, 'X'),
    +    (0xAB30, 'V'),
    +    (0xAB5C, 'M', 'ꜧ'),
    +    (0xAB5D, 'M', 'ꬷ'),
    +    (0xAB5E, 'M', 'ɫ'),
    +    (0xAB5F, 'M', 'ꭒ'),
    +    (0xAB60, 'V'),
    +    (0xAB69, 'M', 'ʍ'),
    +    (0xAB6A, 'V'),
    +    (0xAB6C, 'X'),
    +    (0xAB70, 'M', 'Ꭰ'),
    +    (0xAB71, 'M', 'Ꭱ'),
    +    (0xAB72, 'M', 'Ꭲ'),
    +    (0xAB73, 'M', 'Ꭳ'),
    +    (0xAB74, 'M', 'Ꭴ'),
    +    (0xAB75, 'M', 'Ꭵ'),
    +    (0xAB76, 'M', 'Ꭶ'),
    +    (0xAB77, 'M', 'Ꭷ'),
    +    (0xAB78, 'M', 'Ꭸ'),
    +    (0xAB79, 'M', 'Ꭹ'),
    +    (0xAB7A, 'M', 'Ꭺ'),
    +    (0xAB7B, 'M', 'Ꭻ'),
    +    (0xAB7C, 'M', 'Ꭼ'),
    +    (0xAB7D, 'M', 'Ꭽ'),
    +    (0xAB7E, 'M', 'Ꭾ'),
    +    (0xAB7F, 'M', 'Ꭿ'),
    +    (0xAB80, 'M', 'Ꮀ'),
    +    (0xAB81, 'M', 'Ꮁ'),
    +    (0xAB82, 'M', 'Ꮂ'),
    +    (0xAB83, 'M', 'Ꮃ'),
    +    (0xAB84, 'M', 'Ꮄ'),
    +    (0xAB85, 'M', 'Ꮅ'),
    +    (0xAB86, 'M', 'Ꮆ'),
    +    (0xAB87, 'M', 'Ꮇ'),
    +    (0xAB88, 'M', 'Ꮈ'),
    +    (0xAB89, 'M', 'Ꮉ'),
    +    (0xAB8A, 'M', 'Ꮊ'),
    +    (0xAB8B, 'M', 'Ꮋ'),
    +    (0xAB8C, 'M', 'Ꮌ'),
    +    (0xAB8D, 'M', 'Ꮍ'),
    +    (0xAB8E, 'M', 'Ꮎ'),
    +    (0xAB8F, 'M', 'Ꮏ'),
    +    (0xAB90, 'M', 'Ꮐ'),
    +    (0xAB91, 'M', 'Ꮑ'),
    +    (0xAB92, 'M', 'Ꮒ'),
    +    (0xAB93, 'M', 'Ꮓ'),
    +    (0xAB94, 'M', 'Ꮔ'),
    +    (0xAB95, 'M', 'Ꮕ'),
    +    (0xAB96, 'M', 'Ꮖ'),
    +    (0xAB97, 'M', 'Ꮗ'),
    +    (0xAB98, 'M', 'Ꮘ'),
    +    (0xAB99, 'M', 'Ꮙ'),
    +    (0xAB9A, 'M', 'Ꮚ'),
    +    (0xAB9B, 'M', 'Ꮛ'),
    +    (0xAB9C, 'M', 'Ꮜ'),
    +    (0xAB9D, 'M', 'Ꮝ'),
    +    (0xAB9E, 'M', 'Ꮞ'),
    +    (0xAB9F, 'M', 'Ꮟ'),
    +    (0xABA0, 'M', 'Ꮠ'),
    +    (0xABA1, 'M', 'Ꮡ'),
    +    (0xABA2, 'M', 'Ꮢ'),
    +    (0xABA3, 'M', 'Ꮣ'),
    +    (0xABA4, 'M', 'Ꮤ'),
    +    (0xABA5, 'M', 'Ꮥ'),
    +    (0xABA6, 'M', 'Ꮦ'),
    +    (0xABA7, 'M', 'Ꮧ'),
    +    (0xABA8, 'M', 'Ꮨ'),
    +    (0xABA9, 'M', 'Ꮩ'),
    +    (0xABAA, 'M', 'Ꮪ'),
    +    ]
    +
    +def _seg_39() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xABAB, 'M', 'Ꮫ'),
    +    (0xABAC, 'M', 'Ꮬ'),
    +    (0xABAD, 'M', 'Ꮭ'),
    +    (0xABAE, 'M', 'Ꮮ'),
    +    (0xABAF, 'M', 'Ꮯ'),
    +    (0xABB0, 'M', 'Ꮰ'),
    +    (0xABB1, 'M', 'Ꮱ'),
    +    (0xABB2, 'M', 'Ꮲ'),
    +    (0xABB3, 'M', 'Ꮳ'),
    +    (0xABB4, 'M', 'Ꮴ'),
    +    (0xABB5, 'M', 'Ꮵ'),
    +    (0xABB6, 'M', 'Ꮶ'),
    +    (0xABB7, 'M', 'Ꮷ'),
    +    (0xABB8, 'M', 'Ꮸ'),
    +    (0xABB9, 'M', 'Ꮹ'),
    +    (0xABBA, 'M', 'Ꮺ'),
    +    (0xABBB, 'M', 'Ꮻ'),
    +    (0xABBC, 'M', 'Ꮼ'),
    +    (0xABBD, 'M', 'Ꮽ'),
    +    (0xABBE, 'M', 'Ꮾ'),
    +    (0xABBF, 'M', 'Ꮿ'),
    +    (0xABC0, 'V'),
    +    (0xABEE, 'X'),
    +    (0xABF0, 'V'),
    +    (0xABFA, 'X'),
    +    (0xAC00, 'V'),
    +    (0xD7A4, 'X'),
    +    (0xD7B0, 'V'),
    +    (0xD7C7, 'X'),
    +    (0xD7CB, 'V'),
    +    (0xD7FC, 'X'),
    +    (0xF900, 'M', '豈'),
    +    (0xF901, 'M', '更'),
    +    (0xF902, 'M', '車'),
    +    (0xF903, 'M', '賈'),
    +    (0xF904, 'M', '滑'),
    +    (0xF905, 'M', '串'),
    +    (0xF906, 'M', '句'),
    +    (0xF907, 'M', '龜'),
    +    (0xF909, 'M', '契'),
    +    (0xF90A, 'M', '金'),
    +    (0xF90B, 'M', '喇'),
    +    (0xF90C, 'M', '奈'),
    +    (0xF90D, 'M', '懶'),
    +    (0xF90E, 'M', '癩'),
    +    (0xF90F, 'M', '羅'),
    +    (0xF910, 'M', '蘿'),
    +    (0xF911, 'M', '螺'),
    +    (0xF912, 'M', '裸'),
    +    (0xF913, 'M', '邏'),
    +    (0xF914, 'M', '樂'),
    +    (0xF915, 'M', '洛'),
    +    (0xF916, 'M', '烙'),
    +    (0xF917, 'M', '珞'),
    +    (0xF918, 'M', '落'),
    +    (0xF919, 'M', '酪'),
    +    (0xF91A, 'M', '駱'),
    +    (0xF91B, 'M', '亂'),
    +    (0xF91C, 'M', '卵'),
    +    (0xF91D, 'M', '欄'),
    +    (0xF91E, 'M', '爛'),
    +    (0xF91F, 'M', '蘭'),
    +    (0xF920, 'M', '鸞'),
    +    (0xF921, 'M', '嵐'),
    +    (0xF922, 'M', '濫'),
    +    (0xF923, 'M', '藍'),
    +    (0xF924, 'M', '襤'),
    +    (0xF925, 'M', '拉'),
    +    (0xF926, 'M', '臘'),
    +    (0xF927, 'M', '蠟'),
    +    (0xF928, 'M', '廊'),
    +    (0xF929, 'M', '朗'),
    +    (0xF92A, 'M', '浪'),
    +    (0xF92B, 'M', '狼'),
    +    (0xF92C, 'M', '郎'),
    +    (0xF92D, 'M', '來'),
    +    (0xF92E, 'M', '冷'),
    +    (0xF92F, 'M', '勞'),
    +    (0xF930, 'M', '擄'),
    +    (0xF931, 'M', '櫓'),
    +    (0xF932, 'M', '爐'),
    +    (0xF933, 'M', '盧'),
    +    (0xF934, 'M', '老'),
    +    (0xF935, 'M', '蘆'),
    +    (0xF936, 'M', '虜'),
    +    (0xF937, 'M', '路'),
    +    (0xF938, 'M', '露'),
    +    (0xF939, 'M', '魯'),
    +    (0xF93A, 'M', '鷺'),
    +    (0xF93B, 'M', '碌'),
    +    (0xF93C, 'M', '祿'),
    +    (0xF93D, 'M', '綠'),
    +    (0xF93E, 'M', '菉'),
    +    (0xF93F, 'M', '錄'),
    +    (0xF940, 'M', '鹿'),
    +    (0xF941, 'M', '論'),
    +    (0xF942, 'M', '壟'),
    +    (0xF943, 'M', '弄'),
    +    (0xF944, 'M', '籠'),
    +    (0xF945, 'M', '聾'),
    +    ]
    +
    +def _seg_40() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xF946, 'M', '牢'),
    +    (0xF947, 'M', '磊'),
    +    (0xF948, 'M', '賂'),
    +    (0xF949, 'M', '雷'),
    +    (0xF94A, 'M', '壘'),
    +    (0xF94B, 'M', '屢'),
    +    (0xF94C, 'M', '樓'),
    +    (0xF94D, 'M', '淚'),
    +    (0xF94E, 'M', '漏'),
    +    (0xF94F, 'M', '累'),
    +    (0xF950, 'M', '縷'),
    +    (0xF951, 'M', '陋'),
    +    (0xF952, 'M', '勒'),
    +    (0xF953, 'M', '肋'),
    +    (0xF954, 'M', '凜'),
    +    (0xF955, 'M', '凌'),
    +    (0xF956, 'M', '稜'),
    +    (0xF957, 'M', '綾'),
    +    (0xF958, 'M', '菱'),
    +    (0xF959, 'M', '陵'),
    +    (0xF95A, 'M', '讀'),
    +    (0xF95B, 'M', '拏'),
    +    (0xF95C, 'M', '樂'),
    +    (0xF95D, 'M', '諾'),
    +    (0xF95E, 'M', '丹'),
    +    (0xF95F, 'M', '寧'),
    +    (0xF960, 'M', '怒'),
    +    (0xF961, 'M', '率'),
    +    (0xF962, 'M', '異'),
    +    (0xF963, 'M', '北'),
    +    (0xF964, 'M', '磻'),
    +    (0xF965, 'M', '便'),
    +    (0xF966, 'M', '復'),
    +    (0xF967, 'M', '不'),
    +    (0xF968, 'M', '泌'),
    +    (0xF969, 'M', '數'),
    +    (0xF96A, 'M', '索'),
    +    (0xF96B, 'M', '參'),
    +    (0xF96C, 'M', '塞'),
    +    (0xF96D, 'M', '省'),
    +    (0xF96E, 'M', '葉'),
    +    (0xF96F, 'M', '說'),
    +    (0xF970, 'M', '殺'),
    +    (0xF971, 'M', '辰'),
    +    (0xF972, 'M', '沈'),
    +    (0xF973, 'M', '拾'),
    +    (0xF974, 'M', '若'),
    +    (0xF975, 'M', '掠'),
    +    (0xF976, 'M', '略'),
    +    (0xF977, 'M', '亮'),
    +    (0xF978, 'M', '兩'),
    +    (0xF979, 'M', '凉'),
    +    (0xF97A, 'M', '梁'),
    +    (0xF97B, 'M', '糧'),
    +    (0xF97C, 'M', '良'),
    +    (0xF97D, 'M', '諒'),
    +    (0xF97E, 'M', '量'),
    +    (0xF97F, 'M', '勵'),
    +    (0xF980, 'M', '呂'),
    +    (0xF981, 'M', '女'),
    +    (0xF982, 'M', '廬'),
    +    (0xF983, 'M', '旅'),
    +    (0xF984, 'M', '濾'),
    +    (0xF985, 'M', '礪'),
    +    (0xF986, 'M', '閭'),
    +    (0xF987, 'M', '驪'),
    +    (0xF988, 'M', '麗'),
    +    (0xF989, 'M', '黎'),
    +    (0xF98A, 'M', '力'),
    +    (0xF98B, 'M', '曆'),
    +    (0xF98C, 'M', '歷'),
    +    (0xF98D, 'M', '轢'),
    +    (0xF98E, 'M', '年'),
    +    (0xF98F, 'M', '憐'),
    +    (0xF990, 'M', '戀'),
    +    (0xF991, 'M', '撚'),
    +    (0xF992, 'M', '漣'),
    +    (0xF993, 'M', '煉'),
    +    (0xF994, 'M', '璉'),
    +    (0xF995, 'M', '秊'),
    +    (0xF996, 'M', '練'),
    +    (0xF997, 'M', '聯'),
    +    (0xF998, 'M', '輦'),
    +    (0xF999, 'M', '蓮'),
    +    (0xF99A, 'M', '連'),
    +    (0xF99B, 'M', '鍊'),
    +    (0xF99C, 'M', '列'),
    +    (0xF99D, 'M', '劣'),
    +    (0xF99E, 'M', '咽'),
    +    (0xF99F, 'M', '烈'),
    +    (0xF9A0, 'M', '裂'),
    +    (0xF9A1, 'M', '說'),
    +    (0xF9A2, 'M', '廉'),
    +    (0xF9A3, 'M', '念'),
    +    (0xF9A4, 'M', '捻'),
    +    (0xF9A5, 'M', '殮'),
    +    (0xF9A6, 'M', '簾'),
    +    (0xF9A7, 'M', '獵'),
    +    (0xF9A8, 'M', '令'),
    +    (0xF9A9, 'M', '囹'),
    +    ]
    +
    +def _seg_41() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xF9AA, 'M', '寧'),
    +    (0xF9AB, 'M', '嶺'),
    +    (0xF9AC, 'M', '怜'),
    +    (0xF9AD, 'M', '玲'),
    +    (0xF9AE, 'M', '瑩'),
    +    (0xF9AF, 'M', '羚'),
    +    (0xF9B0, 'M', '聆'),
    +    (0xF9B1, 'M', '鈴'),
    +    (0xF9B2, 'M', '零'),
    +    (0xF9B3, 'M', '靈'),
    +    (0xF9B4, 'M', '領'),
    +    (0xF9B5, 'M', '例'),
    +    (0xF9B6, 'M', '禮'),
    +    (0xF9B7, 'M', '醴'),
    +    (0xF9B8, 'M', '隸'),
    +    (0xF9B9, 'M', '惡'),
    +    (0xF9BA, 'M', '了'),
    +    (0xF9BB, 'M', '僚'),
    +    (0xF9BC, 'M', '寮'),
    +    (0xF9BD, 'M', '尿'),
    +    (0xF9BE, 'M', '料'),
    +    (0xF9BF, 'M', '樂'),
    +    (0xF9C0, 'M', '燎'),
    +    (0xF9C1, 'M', '療'),
    +    (0xF9C2, 'M', '蓼'),
    +    (0xF9C3, 'M', '遼'),
    +    (0xF9C4, 'M', '龍'),
    +    (0xF9C5, 'M', '暈'),
    +    (0xF9C6, 'M', '阮'),
    +    (0xF9C7, 'M', '劉'),
    +    (0xF9C8, 'M', '杻'),
    +    (0xF9C9, 'M', '柳'),
    +    (0xF9CA, 'M', '流'),
    +    (0xF9CB, 'M', '溜'),
    +    (0xF9CC, 'M', '琉'),
    +    (0xF9CD, 'M', '留'),
    +    (0xF9CE, 'M', '硫'),
    +    (0xF9CF, 'M', '紐'),
    +    (0xF9D0, 'M', '類'),
    +    (0xF9D1, 'M', '六'),
    +    (0xF9D2, 'M', '戮'),
    +    (0xF9D3, 'M', '陸'),
    +    (0xF9D4, 'M', '倫'),
    +    (0xF9D5, 'M', '崙'),
    +    (0xF9D6, 'M', '淪'),
    +    (0xF9D7, 'M', '輪'),
    +    (0xF9D8, 'M', '律'),
    +    (0xF9D9, 'M', '慄'),
    +    (0xF9DA, 'M', '栗'),
    +    (0xF9DB, 'M', '率'),
    +    (0xF9DC, 'M', '隆'),
    +    (0xF9DD, 'M', '利'),
    +    (0xF9DE, 'M', '吏'),
    +    (0xF9DF, 'M', '履'),
    +    (0xF9E0, 'M', '易'),
    +    (0xF9E1, 'M', '李'),
    +    (0xF9E2, 'M', '梨'),
    +    (0xF9E3, 'M', '泥'),
    +    (0xF9E4, 'M', '理'),
    +    (0xF9E5, 'M', '痢'),
    +    (0xF9E6, 'M', '罹'),
    +    (0xF9E7, 'M', '裏'),
    +    (0xF9E8, 'M', '裡'),
    +    (0xF9E9, 'M', '里'),
    +    (0xF9EA, 'M', '離'),
    +    (0xF9EB, 'M', '匿'),
    +    (0xF9EC, 'M', '溺'),
    +    (0xF9ED, 'M', '吝'),
    +    (0xF9EE, 'M', '燐'),
    +    (0xF9EF, 'M', '璘'),
    +    (0xF9F0, 'M', '藺'),
    +    (0xF9F1, 'M', '隣'),
    +    (0xF9F2, 'M', '鱗'),
    +    (0xF9F3, 'M', '麟'),
    +    (0xF9F4, 'M', '林'),
    +    (0xF9F5, 'M', '淋'),
    +    (0xF9F6, 'M', '臨'),
    +    (0xF9F7, 'M', '立'),
    +    (0xF9F8, 'M', '笠'),
    +    (0xF9F9, 'M', '粒'),
    +    (0xF9FA, 'M', '狀'),
    +    (0xF9FB, 'M', '炙'),
    +    (0xF9FC, 'M', '識'),
    +    (0xF9FD, 'M', '什'),
    +    (0xF9FE, 'M', '茶'),
    +    (0xF9FF, 'M', '刺'),
    +    (0xFA00, 'M', '切'),
    +    (0xFA01, 'M', '度'),
    +    (0xFA02, 'M', '拓'),
    +    (0xFA03, 'M', '糖'),
    +    (0xFA04, 'M', '宅'),
    +    (0xFA05, 'M', '洞'),
    +    (0xFA06, 'M', '暴'),
    +    (0xFA07, 'M', '輻'),
    +    (0xFA08, 'M', '行'),
    +    (0xFA09, 'M', '降'),
    +    (0xFA0A, 'M', '見'),
    +    (0xFA0B, 'M', '廓'),
    +    (0xFA0C, 'M', '兀'),
    +    (0xFA0D, 'M', '嗀'),
    +    ]
    +
    +def _seg_42() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xFA0E, 'V'),
    +    (0xFA10, 'M', '塚'),
    +    (0xFA11, 'V'),
    +    (0xFA12, 'M', '晴'),
    +    (0xFA13, 'V'),
    +    (0xFA15, 'M', '凞'),
    +    (0xFA16, 'M', '猪'),
    +    (0xFA17, 'M', '益'),
    +    (0xFA18, 'M', '礼'),
    +    (0xFA19, 'M', '神'),
    +    (0xFA1A, 'M', '祥'),
    +    (0xFA1B, 'M', '福'),
    +    (0xFA1C, 'M', '靖'),
    +    (0xFA1D, 'M', '精'),
    +    (0xFA1E, 'M', '羽'),
    +    (0xFA1F, 'V'),
    +    (0xFA20, 'M', '蘒'),
    +    (0xFA21, 'V'),
    +    (0xFA22, 'M', '諸'),
    +    (0xFA23, 'V'),
    +    (0xFA25, 'M', '逸'),
    +    (0xFA26, 'M', '都'),
    +    (0xFA27, 'V'),
    +    (0xFA2A, 'M', '飯'),
    +    (0xFA2B, 'M', '飼'),
    +    (0xFA2C, 'M', '館'),
    +    (0xFA2D, 'M', '鶴'),
    +    (0xFA2E, 'M', '郞'),
    +    (0xFA2F, 'M', '隷'),
    +    (0xFA30, 'M', '侮'),
    +    (0xFA31, 'M', '僧'),
    +    (0xFA32, 'M', '免'),
    +    (0xFA33, 'M', '勉'),
    +    (0xFA34, 'M', '勤'),
    +    (0xFA35, 'M', '卑'),
    +    (0xFA36, 'M', '喝'),
    +    (0xFA37, 'M', '嘆'),
    +    (0xFA38, 'M', '器'),
    +    (0xFA39, 'M', '塀'),
    +    (0xFA3A, 'M', '墨'),
    +    (0xFA3B, 'M', '層'),
    +    (0xFA3C, 'M', '屮'),
    +    (0xFA3D, 'M', '悔'),
    +    (0xFA3E, 'M', '慨'),
    +    (0xFA3F, 'M', '憎'),
    +    (0xFA40, 'M', '懲'),
    +    (0xFA41, 'M', '敏'),
    +    (0xFA42, 'M', '既'),
    +    (0xFA43, 'M', '暑'),
    +    (0xFA44, 'M', '梅'),
    +    (0xFA45, 'M', '海'),
    +    (0xFA46, 'M', '渚'),
    +    (0xFA47, 'M', '漢'),
    +    (0xFA48, 'M', '煮'),
    +    (0xFA49, 'M', '爫'),
    +    (0xFA4A, 'M', '琢'),
    +    (0xFA4B, 'M', '碑'),
    +    (0xFA4C, 'M', '社'),
    +    (0xFA4D, 'M', '祉'),
    +    (0xFA4E, 'M', '祈'),
    +    (0xFA4F, 'M', '祐'),
    +    (0xFA50, 'M', '祖'),
    +    (0xFA51, 'M', '祝'),
    +    (0xFA52, 'M', '禍'),
    +    (0xFA53, 'M', '禎'),
    +    (0xFA54, 'M', '穀'),
    +    (0xFA55, 'M', '突'),
    +    (0xFA56, 'M', '節'),
    +    (0xFA57, 'M', '練'),
    +    (0xFA58, 'M', '縉'),
    +    (0xFA59, 'M', '繁'),
    +    (0xFA5A, 'M', '署'),
    +    (0xFA5B, 'M', '者'),
    +    (0xFA5C, 'M', '臭'),
    +    (0xFA5D, 'M', '艹'),
    +    (0xFA5F, 'M', '著'),
    +    (0xFA60, 'M', '褐'),
    +    (0xFA61, 'M', '視'),
    +    (0xFA62, 'M', '謁'),
    +    (0xFA63, 'M', '謹'),
    +    (0xFA64, 'M', '賓'),
    +    (0xFA65, 'M', '贈'),
    +    (0xFA66, 'M', '辶'),
    +    (0xFA67, 'M', '逸'),
    +    (0xFA68, 'M', '難'),
    +    (0xFA69, 'M', '響'),
    +    (0xFA6A, 'M', '頻'),
    +    (0xFA6B, 'M', '恵'),
    +    (0xFA6C, 'M', '𤋮'),
    +    (0xFA6D, 'M', '舘'),
    +    (0xFA6E, 'X'),
    +    (0xFA70, 'M', '並'),
    +    (0xFA71, 'M', '况'),
    +    (0xFA72, 'M', '全'),
    +    (0xFA73, 'M', '侀'),
    +    (0xFA74, 'M', '充'),
    +    (0xFA75, 'M', '冀'),
    +    (0xFA76, 'M', '勇'),
    +    (0xFA77, 'M', '勺'),
    +    (0xFA78, 'M', '喝'),
    +    ]
    +
    +def _seg_43() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xFA79, 'M', '啕'),
    +    (0xFA7A, 'M', '喙'),
    +    (0xFA7B, 'M', '嗢'),
    +    (0xFA7C, 'M', '塚'),
    +    (0xFA7D, 'M', '墳'),
    +    (0xFA7E, 'M', '奄'),
    +    (0xFA7F, 'M', '奔'),
    +    (0xFA80, 'M', '婢'),
    +    (0xFA81, 'M', '嬨'),
    +    (0xFA82, 'M', '廒'),
    +    (0xFA83, 'M', '廙'),
    +    (0xFA84, 'M', '彩'),
    +    (0xFA85, 'M', '徭'),
    +    (0xFA86, 'M', '惘'),
    +    (0xFA87, 'M', '慎'),
    +    (0xFA88, 'M', '愈'),
    +    (0xFA89, 'M', '憎'),
    +    (0xFA8A, 'M', '慠'),
    +    (0xFA8B, 'M', '懲'),
    +    (0xFA8C, 'M', '戴'),
    +    (0xFA8D, 'M', '揄'),
    +    (0xFA8E, 'M', '搜'),
    +    (0xFA8F, 'M', '摒'),
    +    (0xFA90, 'M', '敖'),
    +    (0xFA91, 'M', '晴'),
    +    (0xFA92, 'M', '朗'),
    +    (0xFA93, 'M', '望'),
    +    (0xFA94, 'M', '杖'),
    +    (0xFA95, 'M', '歹'),
    +    (0xFA96, 'M', '殺'),
    +    (0xFA97, 'M', '流'),
    +    (0xFA98, 'M', '滛'),
    +    (0xFA99, 'M', '滋'),
    +    (0xFA9A, 'M', '漢'),
    +    (0xFA9B, 'M', '瀞'),
    +    (0xFA9C, 'M', '煮'),
    +    (0xFA9D, 'M', '瞧'),
    +    (0xFA9E, 'M', '爵'),
    +    (0xFA9F, 'M', '犯'),
    +    (0xFAA0, 'M', '猪'),
    +    (0xFAA1, 'M', '瑱'),
    +    (0xFAA2, 'M', '甆'),
    +    (0xFAA3, 'M', '画'),
    +    (0xFAA4, 'M', '瘝'),
    +    (0xFAA5, 'M', '瘟'),
    +    (0xFAA6, 'M', '益'),
    +    (0xFAA7, 'M', '盛'),
    +    (0xFAA8, 'M', '直'),
    +    (0xFAA9, 'M', '睊'),
    +    (0xFAAA, 'M', '着'),
    +    (0xFAAB, 'M', '磌'),
    +    (0xFAAC, 'M', '窱'),
    +    (0xFAAD, 'M', '節'),
    +    (0xFAAE, 'M', '类'),
    +    (0xFAAF, 'M', '絛'),
    +    (0xFAB0, 'M', '練'),
    +    (0xFAB1, 'M', '缾'),
    +    (0xFAB2, 'M', '者'),
    +    (0xFAB3, 'M', '荒'),
    +    (0xFAB4, 'M', '華'),
    +    (0xFAB5, 'M', '蝹'),
    +    (0xFAB6, 'M', '襁'),
    +    (0xFAB7, 'M', '覆'),
    +    (0xFAB8, 'M', '視'),
    +    (0xFAB9, 'M', '調'),
    +    (0xFABA, 'M', '諸'),
    +    (0xFABB, 'M', '請'),
    +    (0xFABC, 'M', '謁'),
    +    (0xFABD, 'M', '諾'),
    +    (0xFABE, 'M', '諭'),
    +    (0xFABF, 'M', '謹'),
    +    (0xFAC0, 'M', '變'),
    +    (0xFAC1, 'M', '贈'),
    +    (0xFAC2, 'M', '輸'),
    +    (0xFAC3, 'M', '遲'),
    +    (0xFAC4, 'M', '醙'),
    +    (0xFAC5, 'M', '鉶'),
    +    (0xFAC6, 'M', '陼'),
    +    (0xFAC7, 'M', '難'),
    +    (0xFAC8, 'M', '靖'),
    +    (0xFAC9, 'M', '韛'),
    +    (0xFACA, 'M', '響'),
    +    (0xFACB, 'M', '頋'),
    +    (0xFACC, 'M', '頻'),
    +    (0xFACD, 'M', '鬒'),
    +    (0xFACE, 'M', '龜'),
    +    (0xFACF, 'M', '𢡊'),
    +    (0xFAD0, 'M', '𢡄'),
    +    (0xFAD1, 'M', '𣏕'),
    +    (0xFAD2, 'M', '㮝'),
    +    (0xFAD3, 'M', '䀘'),
    +    (0xFAD4, 'M', '䀹'),
    +    (0xFAD5, 'M', '𥉉'),
    +    (0xFAD6, 'M', '𥳐'),
    +    (0xFAD7, 'M', '𧻓'),
    +    (0xFAD8, 'M', '齃'),
    +    (0xFAD9, 'M', '龎'),
    +    (0xFADA, 'X'),
    +    (0xFB00, 'M', 'ff'),
    +    (0xFB01, 'M', 'fi'),
    +    ]
    +
    +def _seg_44() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xFB02, 'M', 'fl'),
    +    (0xFB03, 'M', 'ffi'),
    +    (0xFB04, 'M', 'ffl'),
    +    (0xFB05, 'M', 'st'),
    +    (0xFB07, 'X'),
    +    (0xFB13, 'M', 'մն'),
    +    (0xFB14, 'M', 'մե'),
    +    (0xFB15, 'M', 'մի'),
    +    (0xFB16, 'M', 'վն'),
    +    (0xFB17, 'M', 'մխ'),
    +    (0xFB18, 'X'),
    +    (0xFB1D, 'M', 'יִ'),
    +    (0xFB1E, 'V'),
    +    (0xFB1F, 'M', 'ײַ'),
    +    (0xFB20, 'M', 'ע'),
    +    (0xFB21, 'M', 'א'),
    +    (0xFB22, 'M', 'ד'),
    +    (0xFB23, 'M', 'ה'),
    +    (0xFB24, 'M', 'כ'),
    +    (0xFB25, 'M', 'ל'),
    +    (0xFB26, 'M', 'ם'),
    +    (0xFB27, 'M', 'ר'),
    +    (0xFB28, 'M', 'ת'),
    +    (0xFB29, '3', '+'),
    +    (0xFB2A, 'M', 'שׁ'),
    +    (0xFB2B, 'M', 'שׂ'),
    +    (0xFB2C, 'M', 'שּׁ'),
    +    (0xFB2D, 'M', 'שּׂ'),
    +    (0xFB2E, 'M', 'אַ'),
    +    (0xFB2F, 'M', 'אָ'),
    +    (0xFB30, 'M', 'אּ'),
    +    (0xFB31, 'M', 'בּ'),
    +    (0xFB32, 'M', 'גּ'),
    +    (0xFB33, 'M', 'דּ'),
    +    (0xFB34, 'M', 'הּ'),
    +    (0xFB35, 'M', 'וּ'),
    +    (0xFB36, 'M', 'זּ'),
    +    (0xFB37, 'X'),
    +    (0xFB38, 'M', 'טּ'),
    +    (0xFB39, 'M', 'יּ'),
    +    (0xFB3A, 'M', 'ךּ'),
    +    (0xFB3B, 'M', 'כּ'),
    +    (0xFB3C, 'M', 'לּ'),
    +    (0xFB3D, 'X'),
    +    (0xFB3E, 'M', 'מּ'),
    +    (0xFB3F, 'X'),
    +    (0xFB40, 'M', 'נּ'),
    +    (0xFB41, 'M', 'סּ'),
    +    (0xFB42, 'X'),
    +    (0xFB43, 'M', 'ףּ'),
    +    (0xFB44, 'M', 'פּ'),
    +    (0xFB45, 'X'),
    +    (0xFB46, 'M', 'צּ'),
    +    (0xFB47, 'M', 'קּ'),
    +    (0xFB48, 'M', 'רּ'),
    +    (0xFB49, 'M', 'שּ'),
    +    (0xFB4A, 'M', 'תּ'),
    +    (0xFB4B, 'M', 'וֹ'),
    +    (0xFB4C, 'M', 'בֿ'),
    +    (0xFB4D, 'M', 'כֿ'),
    +    (0xFB4E, 'M', 'פֿ'),
    +    (0xFB4F, 'M', 'אל'),
    +    (0xFB50, 'M', 'ٱ'),
    +    (0xFB52, 'M', 'ٻ'),
    +    (0xFB56, 'M', 'پ'),
    +    (0xFB5A, 'M', 'ڀ'),
    +    (0xFB5E, 'M', 'ٺ'),
    +    (0xFB62, 'M', 'ٿ'),
    +    (0xFB66, 'M', 'ٹ'),
    +    (0xFB6A, 'M', 'ڤ'),
    +    (0xFB6E, 'M', 'ڦ'),
    +    (0xFB72, 'M', 'ڄ'),
    +    (0xFB76, 'M', 'ڃ'),
    +    (0xFB7A, 'M', 'چ'),
    +    (0xFB7E, 'M', 'ڇ'),
    +    (0xFB82, 'M', 'ڍ'),
    +    (0xFB84, 'M', 'ڌ'),
    +    (0xFB86, 'M', 'ڎ'),
    +    (0xFB88, 'M', 'ڈ'),
    +    (0xFB8A, 'M', 'ژ'),
    +    (0xFB8C, 'M', 'ڑ'),
    +    (0xFB8E, 'M', 'ک'),
    +    (0xFB92, 'M', 'گ'),
    +    (0xFB96, 'M', 'ڳ'),
    +    (0xFB9A, 'M', 'ڱ'),
    +    (0xFB9E, 'M', 'ں'),
    +    (0xFBA0, 'M', 'ڻ'),
    +    (0xFBA4, 'M', 'ۀ'),
    +    (0xFBA6, 'M', 'ہ'),
    +    (0xFBAA, 'M', 'ھ'),
    +    (0xFBAE, 'M', 'ے'),
    +    (0xFBB0, 'M', 'ۓ'),
    +    (0xFBB2, 'V'),
    +    (0xFBC3, 'X'),
    +    (0xFBD3, 'M', 'ڭ'),
    +    (0xFBD7, 'M', 'ۇ'),
    +    (0xFBD9, 'M', 'ۆ'),
    +    (0xFBDB, 'M', 'ۈ'),
    +    (0xFBDD, 'M', 'ۇٴ'),
    +    (0xFBDE, 'M', 'ۋ'),
    +    ]
    +
    +def _seg_45() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xFBE0, 'M', 'ۅ'),
    +    (0xFBE2, 'M', 'ۉ'),
    +    (0xFBE4, 'M', 'ې'),
    +    (0xFBE8, 'M', 'ى'),
    +    (0xFBEA, 'M', 'ئا'),
    +    (0xFBEC, 'M', 'ئە'),
    +    (0xFBEE, 'M', 'ئو'),
    +    (0xFBF0, 'M', 'ئۇ'),
    +    (0xFBF2, 'M', 'ئۆ'),
    +    (0xFBF4, 'M', 'ئۈ'),
    +    (0xFBF6, 'M', 'ئې'),
    +    (0xFBF9, 'M', 'ئى'),
    +    (0xFBFC, 'M', 'ی'),
    +    (0xFC00, 'M', 'ئج'),
    +    (0xFC01, 'M', 'ئح'),
    +    (0xFC02, 'M', 'ئم'),
    +    (0xFC03, 'M', 'ئى'),
    +    (0xFC04, 'M', 'ئي'),
    +    (0xFC05, 'M', 'بج'),
    +    (0xFC06, 'M', 'بح'),
    +    (0xFC07, 'M', 'بخ'),
    +    (0xFC08, 'M', 'بم'),
    +    (0xFC09, 'M', 'بى'),
    +    (0xFC0A, 'M', 'بي'),
    +    (0xFC0B, 'M', 'تج'),
    +    (0xFC0C, 'M', 'تح'),
    +    (0xFC0D, 'M', 'تخ'),
    +    (0xFC0E, 'M', 'تم'),
    +    (0xFC0F, 'M', 'تى'),
    +    (0xFC10, 'M', 'تي'),
    +    (0xFC11, 'M', 'ثج'),
    +    (0xFC12, 'M', 'ثم'),
    +    (0xFC13, 'M', 'ثى'),
    +    (0xFC14, 'M', 'ثي'),
    +    (0xFC15, 'M', 'جح'),
    +    (0xFC16, 'M', 'جم'),
    +    (0xFC17, 'M', 'حج'),
    +    (0xFC18, 'M', 'حم'),
    +    (0xFC19, 'M', 'خج'),
    +    (0xFC1A, 'M', 'خح'),
    +    (0xFC1B, 'M', 'خم'),
    +    (0xFC1C, 'M', 'سج'),
    +    (0xFC1D, 'M', 'سح'),
    +    (0xFC1E, 'M', 'سخ'),
    +    (0xFC1F, 'M', 'سم'),
    +    (0xFC20, 'M', 'صح'),
    +    (0xFC21, 'M', 'صم'),
    +    (0xFC22, 'M', 'ضج'),
    +    (0xFC23, 'M', 'ضح'),
    +    (0xFC24, 'M', 'ضخ'),
    +    (0xFC25, 'M', 'ضم'),
    +    (0xFC26, 'M', 'طح'),
    +    (0xFC27, 'M', 'طم'),
    +    (0xFC28, 'M', 'ظم'),
    +    (0xFC29, 'M', 'عج'),
    +    (0xFC2A, 'M', 'عم'),
    +    (0xFC2B, 'M', 'غج'),
    +    (0xFC2C, 'M', 'غم'),
    +    (0xFC2D, 'M', 'فج'),
    +    (0xFC2E, 'M', 'فح'),
    +    (0xFC2F, 'M', 'فخ'),
    +    (0xFC30, 'M', 'فم'),
    +    (0xFC31, 'M', 'فى'),
    +    (0xFC32, 'M', 'في'),
    +    (0xFC33, 'M', 'قح'),
    +    (0xFC34, 'M', 'قم'),
    +    (0xFC35, 'M', 'قى'),
    +    (0xFC36, 'M', 'قي'),
    +    (0xFC37, 'M', 'كا'),
    +    (0xFC38, 'M', 'كج'),
    +    (0xFC39, 'M', 'كح'),
    +    (0xFC3A, 'M', 'كخ'),
    +    (0xFC3B, 'M', 'كل'),
    +    (0xFC3C, 'M', 'كم'),
    +    (0xFC3D, 'M', 'كى'),
    +    (0xFC3E, 'M', 'كي'),
    +    (0xFC3F, 'M', 'لج'),
    +    (0xFC40, 'M', 'لح'),
    +    (0xFC41, 'M', 'لخ'),
    +    (0xFC42, 'M', 'لم'),
    +    (0xFC43, 'M', 'لى'),
    +    (0xFC44, 'M', 'لي'),
    +    (0xFC45, 'M', 'مج'),
    +    (0xFC46, 'M', 'مح'),
    +    (0xFC47, 'M', 'مخ'),
    +    (0xFC48, 'M', 'مم'),
    +    (0xFC49, 'M', 'مى'),
    +    (0xFC4A, 'M', 'مي'),
    +    (0xFC4B, 'M', 'نج'),
    +    (0xFC4C, 'M', 'نح'),
    +    (0xFC4D, 'M', 'نخ'),
    +    (0xFC4E, 'M', 'نم'),
    +    (0xFC4F, 'M', 'نى'),
    +    (0xFC50, 'M', 'ني'),
    +    (0xFC51, 'M', 'هج'),
    +    (0xFC52, 'M', 'هم'),
    +    (0xFC53, 'M', 'هى'),
    +    (0xFC54, 'M', 'هي'),
    +    (0xFC55, 'M', 'يج'),
    +    (0xFC56, 'M', 'يح'),
    +    ]
    +
    +def _seg_46() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xFC57, 'M', 'يخ'),
    +    (0xFC58, 'M', 'يم'),
    +    (0xFC59, 'M', 'يى'),
    +    (0xFC5A, 'M', 'يي'),
    +    (0xFC5B, 'M', 'ذٰ'),
    +    (0xFC5C, 'M', 'رٰ'),
    +    (0xFC5D, 'M', 'ىٰ'),
    +    (0xFC5E, '3', ' ٌّ'),
    +    (0xFC5F, '3', ' ٍّ'),
    +    (0xFC60, '3', ' َّ'),
    +    (0xFC61, '3', ' ُّ'),
    +    (0xFC62, '3', ' ِّ'),
    +    (0xFC63, '3', ' ّٰ'),
    +    (0xFC64, 'M', 'ئر'),
    +    (0xFC65, 'M', 'ئز'),
    +    (0xFC66, 'M', 'ئم'),
    +    (0xFC67, 'M', 'ئن'),
    +    (0xFC68, 'M', 'ئى'),
    +    (0xFC69, 'M', 'ئي'),
    +    (0xFC6A, 'M', 'بر'),
    +    (0xFC6B, 'M', 'بز'),
    +    (0xFC6C, 'M', 'بم'),
    +    (0xFC6D, 'M', 'بن'),
    +    (0xFC6E, 'M', 'بى'),
    +    (0xFC6F, 'M', 'بي'),
    +    (0xFC70, 'M', 'تر'),
    +    (0xFC71, 'M', 'تز'),
    +    (0xFC72, 'M', 'تم'),
    +    (0xFC73, 'M', 'تن'),
    +    (0xFC74, 'M', 'تى'),
    +    (0xFC75, 'M', 'تي'),
    +    (0xFC76, 'M', 'ثر'),
    +    (0xFC77, 'M', 'ثز'),
    +    (0xFC78, 'M', 'ثم'),
    +    (0xFC79, 'M', 'ثن'),
    +    (0xFC7A, 'M', 'ثى'),
    +    (0xFC7B, 'M', 'ثي'),
    +    (0xFC7C, 'M', 'فى'),
    +    (0xFC7D, 'M', 'في'),
    +    (0xFC7E, 'M', 'قى'),
    +    (0xFC7F, 'M', 'قي'),
    +    (0xFC80, 'M', 'كا'),
    +    (0xFC81, 'M', 'كل'),
    +    (0xFC82, 'M', 'كم'),
    +    (0xFC83, 'M', 'كى'),
    +    (0xFC84, 'M', 'كي'),
    +    (0xFC85, 'M', 'لم'),
    +    (0xFC86, 'M', 'لى'),
    +    (0xFC87, 'M', 'لي'),
    +    (0xFC88, 'M', 'ما'),
    +    (0xFC89, 'M', 'مم'),
    +    (0xFC8A, 'M', 'نر'),
    +    (0xFC8B, 'M', 'نز'),
    +    (0xFC8C, 'M', 'نم'),
    +    (0xFC8D, 'M', 'نن'),
    +    (0xFC8E, 'M', 'نى'),
    +    (0xFC8F, 'M', 'ني'),
    +    (0xFC90, 'M', 'ىٰ'),
    +    (0xFC91, 'M', 'ير'),
    +    (0xFC92, 'M', 'يز'),
    +    (0xFC93, 'M', 'يم'),
    +    (0xFC94, 'M', 'ين'),
    +    (0xFC95, 'M', 'يى'),
    +    (0xFC96, 'M', 'يي'),
    +    (0xFC97, 'M', 'ئج'),
    +    (0xFC98, 'M', 'ئح'),
    +    (0xFC99, 'M', 'ئخ'),
    +    (0xFC9A, 'M', 'ئم'),
    +    (0xFC9B, 'M', 'ئه'),
    +    (0xFC9C, 'M', 'بج'),
    +    (0xFC9D, 'M', 'بح'),
    +    (0xFC9E, 'M', 'بخ'),
    +    (0xFC9F, 'M', 'بم'),
    +    (0xFCA0, 'M', 'به'),
    +    (0xFCA1, 'M', 'تج'),
    +    (0xFCA2, 'M', 'تح'),
    +    (0xFCA3, 'M', 'تخ'),
    +    (0xFCA4, 'M', 'تم'),
    +    (0xFCA5, 'M', 'ته'),
    +    (0xFCA6, 'M', 'ثم'),
    +    (0xFCA7, 'M', 'جح'),
    +    (0xFCA8, 'M', 'جم'),
    +    (0xFCA9, 'M', 'حج'),
    +    (0xFCAA, 'M', 'حم'),
    +    (0xFCAB, 'M', 'خج'),
    +    (0xFCAC, 'M', 'خم'),
    +    (0xFCAD, 'M', 'سج'),
    +    (0xFCAE, 'M', 'سح'),
    +    (0xFCAF, 'M', 'سخ'),
    +    (0xFCB0, 'M', 'سم'),
    +    (0xFCB1, 'M', 'صح'),
    +    (0xFCB2, 'M', 'صخ'),
    +    (0xFCB3, 'M', 'صم'),
    +    (0xFCB4, 'M', 'ضج'),
    +    (0xFCB5, 'M', 'ضح'),
    +    (0xFCB6, 'M', 'ضخ'),
    +    (0xFCB7, 'M', 'ضم'),
    +    (0xFCB8, 'M', 'طح'),
    +    (0xFCB9, 'M', 'ظم'),
    +    (0xFCBA, 'M', 'عج'),
    +    ]
    +
    +def _seg_47() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xFCBB, 'M', 'عم'),
    +    (0xFCBC, 'M', 'غج'),
    +    (0xFCBD, 'M', 'غم'),
    +    (0xFCBE, 'M', 'فج'),
    +    (0xFCBF, 'M', 'فح'),
    +    (0xFCC0, 'M', 'فخ'),
    +    (0xFCC1, 'M', 'فم'),
    +    (0xFCC2, 'M', 'قح'),
    +    (0xFCC3, 'M', 'قم'),
    +    (0xFCC4, 'M', 'كج'),
    +    (0xFCC5, 'M', 'كح'),
    +    (0xFCC6, 'M', 'كخ'),
    +    (0xFCC7, 'M', 'كل'),
    +    (0xFCC8, 'M', 'كم'),
    +    (0xFCC9, 'M', 'لج'),
    +    (0xFCCA, 'M', 'لح'),
    +    (0xFCCB, 'M', 'لخ'),
    +    (0xFCCC, 'M', 'لم'),
    +    (0xFCCD, 'M', 'له'),
    +    (0xFCCE, 'M', 'مج'),
    +    (0xFCCF, 'M', 'مح'),
    +    (0xFCD0, 'M', 'مخ'),
    +    (0xFCD1, 'M', 'مم'),
    +    (0xFCD2, 'M', 'نج'),
    +    (0xFCD3, 'M', 'نح'),
    +    (0xFCD4, 'M', 'نخ'),
    +    (0xFCD5, 'M', 'نم'),
    +    (0xFCD6, 'M', 'نه'),
    +    (0xFCD7, 'M', 'هج'),
    +    (0xFCD8, 'M', 'هم'),
    +    (0xFCD9, 'M', 'هٰ'),
    +    (0xFCDA, 'M', 'يج'),
    +    (0xFCDB, 'M', 'يح'),
    +    (0xFCDC, 'M', 'يخ'),
    +    (0xFCDD, 'M', 'يم'),
    +    (0xFCDE, 'M', 'يه'),
    +    (0xFCDF, 'M', 'ئم'),
    +    (0xFCE0, 'M', 'ئه'),
    +    (0xFCE1, 'M', 'بم'),
    +    (0xFCE2, 'M', 'به'),
    +    (0xFCE3, 'M', 'تم'),
    +    (0xFCE4, 'M', 'ته'),
    +    (0xFCE5, 'M', 'ثم'),
    +    (0xFCE6, 'M', 'ثه'),
    +    (0xFCE7, 'M', 'سم'),
    +    (0xFCE8, 'M', 'سه'),
    +    (0xFCE9, 'M', 'شم'),
    +    (0xFCEA, 'M', 'شه'),
    +    (0xFCEB, 'M', 'كل'),
    +    (0xFCEC, 'M', 'كم'),
    +    (0xFCED, 'M', 'لم'),
    +    (0xFCEE, 'M', 'نم'),
    +    (0xFCEF, 'M', 'نه'),
    +    (0xFCF0, 'M', 'يم'),
    +    (0xFCF1, 'M', 'يه'),
    +    (0xFCF2, 'M', 'ـَّ'),
    +    (0xFCF3, 'M', 'ـُّ'),
    +    (0xFCF4, 'M', 'ـِّ'),
    +    (0xFCF5, 'M', 'طى'),
    +    (0xFCF6, 'M', 'طي'),
    +    (0xFCF7, 'M', 'عى'),
    +    (0xFCF8, 'M', 'عي'),
    +    (0xFCF9, 'M', 'غى'),
    +    (0xFCFA, 'M', 'غي'),
    +    (0xFCFB, 'M', 'سى'),
    +    (0xFCFC, 'M', 'سي'),
    +    (0xFCFD, 'M', 'شى'),
    +    (0xFCFE, 'M', 'شي'),
    +    (0xFCFF, 'M', 'حى'),
    +    (0xFD00, 'M', 'حي'),
    +    (0xFD01, 'M', 'جى'),
    +    (0xFD02, 'M', 'جي'),
    +    (0xFD03, 'M', 'خى'),
    +    (0xFD04, 'M', 'خي'),
    +    (0xFD05, 'M', 'صى'),
    +    (0xFD06, 'M', 'صي'),
    +    (0xFD07, 'M', 'ضى'),
    +    (0xFD08, 'M', 'ضي'),
    +    (0xFD09, 'M', 'شج'),
    +    (0xFD0A, 'M', 'شح'),
    +    (0xFD0B, 'M', 'شخ'),
    +    (0xFD0C, 'M', 'شم'),
    +    (0xFD0D, 'M', 'شر'),
    +    (0xFD0E, 'M', 'سر'),
    +    (0xFD0F, 'M', 'صر'),
    +    (0xFD10, 'M', 'ضر'),
    +    (0xFD11, 'M', 'طى'),
    +    (0xFD12, 'M', 'طي'),
    +    (0xFD13, 'M', 'عى'),
    +    (0xFD14, 'M', 'عي'),
    +    (0xFD15, 'M', 'غى'),
    +    (0xFD16, 'M', 'غي'),
    +    (0xFD17, 'M', 'سى'),
    +    (0xFD18, 'M', 'سي'),
    +    (0xFD19, 'M', 'شى'),
    +    (0xFD1A, 'M', 'شي'),
    +    (0xFD1B, 'M', 'حى'),
    +    (0xFD1C, 'M', 'حي'),
    +    (0xFD1D, 'M', 'جى'),
    +    (0xFD1E, 'M', 'جي'),
    +    ]
    +
    +def _seg_48() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xFD1F, 'M', 'خى'),
    +    (0xFD20, 'M', 'خي'),
    +    (0xFD21, 'M', 'صى'),
    +    (0xFD22, 'M', 'صي'),
    +    (0xFD23, 'M', 'ضى'),
    +    (0xFD24, 'M', 'ضي'),
    +    (0xFD25, 'M', 'شج'),
    +    (0xFD26, 'M', 'شح'),
    +    (0xFD27, 'M', 'شخ'),
    +    (0xFD28, 'M', 'شم'),
    +    (0xFD29, 'M', 'شر'),
    +    (0xFD2A, 'M', 'سر'),
    +    (0xFD2B, 'M', 'صر'),
    +    (0xFD2C, 'M', 'ضر'),
    +    (0xFD2D, 'M', 'شج'),
    +    (0xFD2E, 'M', 'شح'),
    +    (0xFD2F, 'M', 'شخ'),
    +    (0xFD30, 'M', 'شم'),
    +    (0xFD31, 'M', 'سه'),
    +    (0xFD32, 'M', 'شه'),
    +    (0xFD33, 'M', 'طم'),
    +    (0xFD34, 'M', 'سج'),
    +    (0xFD35, 'M', 'سح'),
    +    (0xFD36, 'M', 'سخ'),
    +    (0xFD37, 'M', 'شج'),
    +    (0xFD38, 'M', 'شح'),
    +    (0xFD39, 'M', 'شخ'),
    +    (0xFD3A, 'M', 'طم'),
    +    (0xFD3B, 'M', 'ظم'),
    +    (0xFD3C, 'M', 'اً'),
    +    (0xFD3E, 'V'),
    +    (0xFD50, 'M', 'تجم'),
    +    (0xFD51, 'M', 'تحج'),
    +    (0xFD53, 'M', 'تحم'),
    +    (0xFD54, 'M', 'تخم'),
    +    (0xFD55, 'M', 'تمج'),
    +    (0xFD56, 'M', 'تمح'),
    +    (0xFD57, 'M', 'تمخ'),
    +    (0xFD58, 'M', 'جمح'),
    +    (0xFD5A, 'M', 'حمي'),
    +    (0xFD5B, 'M', 'حمى'),
    +    (0xFD5C, 'M', 'سحج'),
    +    (0xFD5D, 'M', 'سجح'),
    +    (0xFD5E, 'M', 'سجى'),
    +    (0xFD5F, 'M', 'سمح'),
    +    (0xFD61, 'M', 'سمج'),
    +    (0xFD62, 'M', 'سمم'),
    +    (0xFD64, 'M', 'صحح'),
    +    (0xFD66, 'M', 'صمم'),
    +    (0xFD67, 'M', 'شحم'),
    +    (0xFD69, 'M', 'شجي'),
    +    (0xFD6A, 'M', 'شمخ'),
    +    (0xFD6C, 'M', 'شمم'),
    +    (0xFD6E, 'M', 'ضحى'),
    +    (0xFD6F, 'M', 'ضخم'),
    +    (0xFD71, 'M', 'طمح'),
    +    (0xFD73, 'M', 'طمم'),
    +    (0xFD74, 'M', 'طمي'),
    +    (0xFD75, 'M', 'عجم'),
    +    (0xFD76, 'M', 'عمم'),
    +    (0xFD78, 'M', 'عمى'),
    +    (0xFD79, 'M', 'غمم'),
    +    (0xFD7A, 'M', 'غمي'),
    +    (0xFD7B, 'M', 'غمى'),
    +    (0xFD7C, 'M', 'فخم'),
    +    (0xFD7E, 'M', 'قمح'),
    +    (0xFD7F, 'M', 'قمم'),
    +    (0xFD80, 'M', 'لحم'),
    +    (0xFD81, 'M', 'لحي'),
    +    (0xFD82, 'M', 'لحى'),
    +    (0xFD83, 'M', 'لجج'),
    +    (0xFD85, 'M', 'لخم'),
    +    (0xFD87, 'M', 'لمح'),
    +    (0xFD89, 'M', 'محج'),
    +    (0xFD8A, 'M', 'محم'),
    +    (0xFD8B, 'M', 'محي'),
    +    (0xFD8C, 'M', 'مجح'),
    +    (0xFD8D, 'M', 'مجم'),
    +    (0xFD8E, 'M', 'مخج'),
    +    (0xFD8F, 'M', 'مخم'),
    +    (0xFD90, 'X'),
    +    (0xFD92, 'M', 'مجخ'),
    +    (0xFD93, 'M', 'همج'),
    +    (0xFD94, 'M', 'همم'),
    +    (0xFD95, 'M', 'نحم'),
    +    (0xFD96, 'M', 'نحى'),
    +    (0xFD97, 'M', 'نجم'),
    +    (0xFD99, 'M', 'نجى'),
    +    (0xFD9A, 'M', 'نمي'),
    +    (0xFD9B, 'M', 'نمى'),
    +    (0xFD9C, 'M', 'يمم'),
    +    (0xFD9E, 'M', 'بخي'),
    +    (0xFD9F, 'M', 'تجي'),
    +    (0xFDA0, 'M', 'تجى'),
    +    (0xFDA1, 'M', 'تخي'),
    +    (0xFDA2, 'M', 'تخى'),
    +    (0xFDA3, 'M', 'تمي'),
    +    (0xFDA4, 'M', 'تمى'),
    +    (0xFDA5, 'M', 'جمي'),
    +    (0xFDA6, 'M', 'جحى'),
    +    ]
    +
    +def _seg_49() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xFDA7, 'M', 'جمى'),
    +    (0xFDA8, 'M', 'سخى'),
    +    (0xFDA9, 'M', 'صحي'),
    +    (0xFDAA, 'M', 'شحي'),
    +    (0xFDAB, 'M', 'ضحي'),
    +    (0xFDAC, 'M', 'لجي'),
    +    (0xFDAD, 'M', 'لمي'),
    +    (0xFDAE, 'M', 'يحي'),
    +    (0xFDAF, 'M', 'يجي'),
    +    (0xFDB0, 'M', 'يمي'),
    +    (0xFDB1, 'M', 'ممي'),
    +    (0xFDB2, 'M', 'قمي'),
    +    (0xFDB3, 'M', 'نحي'),
    +    (0xFDB4, 'M', 'قمح'),
    +    (0xFDB5, 'M', 'لحم'),
    +    (0xFDB6, 'M', 'عمي'),
    +    (0xFDB7, 'M', 'كمي'),
    +    (0xFDB8, 'M', 'نجح'),
    +    (0xFDB9, 'M', 'مخي'),
    +    (0xFDBA, 'M', 'لجم'),
    +    (0xFDBB, 'M', 'كمم'),
    +    (0xFDBC, 'M', 'لجم'),
    +    (0xFDBD, 'M', 'نجح'),
    +    (0xFDBE, 'M', 'جحي'),
    +    (0xFDBF, 'M', 'حجي'),
    +    (0xFDC0, 'M', 'مجي'),
    +    (0xFDC1, 'M', 'فمي'),
    +    (0xFDC2, 'M', 'بحي'),
    +    (0xFDC3, 'M', 'كمم'),
    +    (0xFDC4, 'M', 'عجم'),
    +    (0xFDC5, 'M', 'صمم'),
    +    (0xFDC6, 'M', 'سخي'),
    +    (0xFDC7, 'M', 'نجي'),
    +    (0xFDC8, 'X'),
    +    (0xFDCF, 'V'),
    +    (0xFDD0, 'X'),
    +    (0xFDF0, 'M', 'صلے'),
    +    (0xFDF1, 'M', 'قلے'),
    +    (0xFDF2, 'M', 'الله'),
    +    (0xFDF3, 'M', 'اكبر'),
    +    (0xFDF4, 'M', 'محمد'),
    +    (0xFDF5, 'M', 'صلعم'),
    +    (0xFDF6, 'M', 'رسول'),
    +    (0xFDF7, 'M', 'عليه'),
    +    (0xFDF8, 'M', 'وسلم'),
    +    (0xFDF9, 'M', 'صلى'),
    +    (0xFDFA, '3', 'صلى الله عليه وسلم'),
    +    (0xFDFB, '3', 'جل جلاله'),
    +    (0xFDFC, 'M', 'ریال'),
    +    (0xFDFD, 'V'),
    +    (0xFE00, 'I'),
    +    (0xFE10, '3', ','),
    +    (0xFE11, 'M', '、'),
    +    (0xFE12, 'X'),
    +    (0xFE13, '3', ':'),
    +    (0xFE14, '3', ';'),
    +    (0xFE15, '3', '!'),
    +    (0xFE16, '3', '?'),
    +    (0xFE17, 'M', '〖'),
    +    (0xFE18, 'M', '〗'),
    +    (0xFE19, 'X'),
    +    (0xFE20, 'V'),
    +    (0xFE30, 'X'),
    +    (0xFE31, 'M', '—'),
    +    (0xFE32, 'M', '–'),
    +    (0xFE33, '3', '_'),
    +    (0xFE35, '3', '('),
    +    (0xFE36, '3', ')'),
    +    (0xFE37, '3', '{'),
    +    (0xFE38, '3', '}'),
    +    (0xFE39, 'M', '〔'),
    +    (0xFE3A, 'M', '〕'),
    +    (0xFE3B, 'M', '【'),
    +    (0xFE3C, 'M', '】'),
    +    (0xFE3D, 'M', '《'),
    +    (0xFE3E, 'M', '》'),
    +    (0xFE3F, 'M', '〈'),
    +    (0xFE40, 'M', '〉'),
    +    (0xFE41, 'M', '「'),
    +    (0xFE42, 'M', '」'),
    +    (0xFE43, 'M', '『'),
    +    (0xFE44, 'M', '』'),
    +    (0xFE45, 'V'),
    +    (0xFE47, '3', '['),
    +    (0xFE48, '3', ']'),
    +    (0xFE49, '3', ' ̅'),
    +    (0xFE4D, '3', '_'),
    +    (0xFE50, '3', ','),
    +    (0xFE51, 'M', '、'),
    +    (0xFE52, 'X'),
    +    (0xFE54, '3', ';'),
    +    (0xFE55, '3', ':'),
    +    (0xFE56, '3', '?'),
    +    (0xFE57, '3', '!'),
    +    (0xFE58, 'M', '—'),
    +    (0xFE59, '3', '('),
    +    (0xFE5A, '3', ')'),
    +    (0xFE5B, '3', '{'),
    +    (0xFE5C, '3', '}'),
    +    (0xFE5D, 'M', '〔'),
    +    ]
    +
    +def _seg_50() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xFE5E, 'M', '〕'),
    +    (0xFE5F, '3', '#'),
    +    (0xFE60, '3', '&'),
    +    (0xFE61, '3', '*'),
    +    (0xFE62, '3', '+'),
    +    (0xFE63, 'M', '-'),
    +    (0xFE64, '3', '<'),
    +    (0xFE65, '3', '>'),
    +    (0xFE66, '3', '='),
    +    (0xFE67, 'X'),
    +    (0xFE68, '3', '\\'),
    +    (0xFE69, '3', '$'),
    +    (0xFE6A, '3', '%'),
    +    (0xFE6B, '3', '@'),
    +    (0xFE6C, 'X'),
    +    (0xFE70, '3', ' ً'),
    +    (0xFE71, 'M', 'ـً'),
    +    (0xFE72, '3', ' ٌ'),
    +    (0xFE73, 'V'),
    +    (0xFE74, '3', ' ٍ'),
    +    (0xFE75, 'X'),
    +    (0xFE76, '3', ' َ'),
    +    (0xFE77, 'M', 'ـَ'),
    +    (0xFE78, '3', ' ُ'),
    +    (0xFE79, 'M', 'ـُ'),
    +    (0xFE7A, '3', ' ِ'),
    +    (0xFE7B, 'M', 'ـِ'),
    +    (0xFE7C, '3', ' ّ'),
    +    (0xFE7D, 'M', 'ـّ'),
    +    (0xFE7E, '3', ' ْ'),
    +    (0xFE7F, 'M', 'ـْ'),
    +    (0xFE80, 'M', 'ء'),
    +    (0xFE81, 'M', 'آ'),
    +    (0xFE83, 'M', 'أ'),
    +    (0xFE85, 'M', 'ؤ'),
    +    (0xFE87, 'M', 'إ'),
    +    (0xFE89, 'M', 'ئ'),
    +    (0xFE8D, 'M', 'ا'),
    +    (0xFE8F, 'M', 'ب'),
    +    (0xFE93, 'M', 'ة'),
    +    (0xFE95, 'M', 'ت'),
    +    (0xFE99, 'M', 'ث'),
    +    (0xFE9D, 'M', 'ج'),
    +    (0xFEA1, 'M', 'ح'),
    +    (0xFEA5, 'M', 'خ'),
    +    (0xFEA9, 'M', 'د'),
    +    (0xFEAB, 'M', 'ذ'),
    +    (0xFEAD, 'M', 'ر'),
    +    (0xFEAF, 'M', 'ز'),
    +    (0xFEB1, 'M', 'س'),
    +    (0xFEB5, 'M', 'ش'),
    +    (0xFEB9, 'M', 'ص'),
    +    (0xFEBD, 'M', 'ض'),
    +    (0xFEC1, 'M', 'ط'),
    +    (0xFEC5, 'M', 'ظ'),
    +    (0xFEC9, 'M', 'ع'),
    +    (0xFECD, 'M', 'غ'),
    +    (0xFED1, 'M', 'ف'),
    +    (0xFED5, 'M', 'ق'),
    +    (0xFED9, 'M', 'ك'),
    +    (0xFEDD, 'M', 'ل'),
    +    (0xFEE1, 'M', 'م'),
    +    (0xFEE5, 'M', 'ن'),
    +    (0xFEE9, 'M', 'ه'),
    +    (0xFEED, 'M', 'و'),
    +    (0xFEEF, 'M', 'ى'),
    +    (0xFEF1, 'M', 'ي'),
    +    (0xFEF5, 'M', 'لآ'),
    +    (0xFEF7, 'M', 'لأ'),
    +    (0xFEF9, 'M', 'لإ'),
    +    (0xFEFB, 'M', 'لا'),
    +    (0xFEFD, 'X'),
    +    (0xFEFF, 'I'),
    +    (0xFF00, 'X'),
    +    (0xFF01, '3', '!'),
    +    (0xFF02, '3', '"'),
    +    (0xFF03, '3', '#'),
    +    (0xFF04, '3', '$'),
    +    (0xFF05, '3', '%'),
    +    (0xFF06, '3', '&'),
    +    (0xFF07, '3', '\''),
    +    (0xFF08, '3', '('),
    +    (0xFF09, '3', ')'),
    +    (0xFF0A, '3', '*'),
    +    (0xFF0B, '3', '+'),
    +    (0xFF0C, '3', ','),
    +    (0xFF0D, 'M', '-'),
    +    (0xFF0E, 'M', '.'),
    +    (0xFF0F, '3', '/'),
    +    (0xFF10, 'M', '0'),
    +    (0xFF11, 'M', '1'),
    +    (0xFF12, 'M', '2'),
    +    (0xFF13, 'M', '3'),
    +    (0xFF14, 'M', '4'),
    +    (0xFF15, 'M', '5'),
    +    (0xFF16, 'M', '6'),
    +    (0xFF17, 'M', '7'),
    +    (0xFF18, 'M', '8'),
    +    (0xFF19, 'M', '9'),
    +    (0xFF1A, '3', ':'),
    +    ]
    +
    +def _seg_51() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xFF1B, '3', ';'),
    +    (0xFF1C, '3', '<'),
    +    (0xFF1D, '3', '='),
    +    (0xFF1E, '3', '>'),
    +    (0xFF1F, '3', '?'),
    +    (0xFF20, '3', '@'),
    +    (0xFF21, 'M', 'a'),
    +    (0xFF22, 'M', 'b'),
    +    (0xFF23, 'M', 'c'),
    +    (0xFF24, 'M', 'd'),
    +    (0xFF25, 'M', 'e'),
    +    (0xFF26, 'M', 'f'),
    +    (0xFF27, 'M', 'g'),
    +    (0xFF28, 'M', 'h'),
    +    (0xFF29, 'M', 'i'),
    +    (0xFF2A, 'M', 'j'),
    +    (0xFF2B, 'M', 'k'),
    +    (0xFF2C, 'M', 'l'),
    +    (0xFF2D, 'M', 'm'),
    +    (0xFF2E, 'M', 'n'),
    +    (0xFF2F, 'M', 'o'),
    +    (0xFF30, 'M', 'p'),
    +    (0xFF31, 'M', 'q'),
    +    (0xFF32, 'M', 'r'),
    +    (0xFF33, 'M', 's'),
    +    (0xFF34, 'M', 't'),
    +    (0xFF35, 'M', 'u'),
    +    (0xFF36, 'M', 'v'),
    +    (0xFF37, 'M', 'w'),
    +    (0xFF38, 'M', 'x'),
    +    (0xFF39, 'M', 'y'),
    +    (0xFF3A, 'M', 'z'),
    +    (0xFF3B, '3', '['),
    +    (0xFF3C, '3', '\\'),
    +    (0xFF3D, '3', ']'),
    +    (0xFF3E, '3', '^'),
    +    (0xFF3F, '3', '_'),
    +    (0xFF40, '3', '`'),
    +    (0xFF41, 'M', 'a'),
    +    (0xFF42, 'M', 'b'),
    +    (0xFF43, 'M', 'c'),
    +    (0xFF44, 'M', 'd'),
    +    (0xFF45, 'M', 'e'),
    +    (0xFF46, 'M', 'f'),
    +    (0xFF47, 'M', 'g'),
    +    (0xFF48, 'M', 'h'),
    +    (0xFF49, 'M', 'i'),
    +    (0xFF4A, 'M', 'j'),
    +    (0xFF4B, 'M', 'k'),
    +    (0xFF4C, 'M', 'l'),
    +    (0xFF4D, 'M', 'm'),
    +    (0xFF4E, 'M', 'n'),
    +    (0xFF4F, 'M', 'o'),
    +    (0xFF50, 'M', 'p'),
    +    (0xFF51, 'M', 'q'),
    +    (0xFF52, 'M', 'r'),
    +    (0xFF53, 'M', 's'),
    +    (0xFF54, 'M', 't'),
    +    (0xFF55, 'M', 'u'),
    +    (0xFF56, 'M', 'v'),
    +    (0xFF57, 'M', 'w'),
    +    (0xFF58, 'M', 'x'),
    +    (0xFF59, 'M', 'y'),
    +    (0xFF5A, 'M', 'z'),
    +    (0xFF5B, '3', '{'),
    +    (0xFF5C, '3', '|'),
    +    (0xFF5D, '3', '}'),
    +    (0xFF5E, '3', '~'),
    +    (0xFF5F, 'M', '⦅'),
    +    (0xFF60, 'M', '⦆'),
    +    (0xFF61, 'M', '.'),
    +    (0xFF62, 'M', '「'),
    +    (0xFF63, 'M', '」'),
    +    (0xFF64, 'M', '、'),
    +    (0xFF65, 'M', '・'),
    +    (0xFF66, 'M', 'ヲ'),
    +    (0xFF67, 'M', 'ァ'),
    +    (0xFF68, 'M', 'ィ'),
    +    (0xFF69, 'M', 'ゥ'),
    +    (0xFF6A, 'M', 'ェ'),
    +    (0xFF6B, 'M', 'ォ'),
    +    (0xFF6C, 'M', 'ャ'),
    +    (0xFF6D, 'M', 'ュ'),
    +    (0xFF6E, 'M', 'ョ'),
    +    (0xFF6F, 'M', 'ッ'),
    +    (0xFF70, 'M', 'ー'),
    +    (0xFF71, 'M', 'ア'),
    +    (0xFF72, 'M', 'イ'),
    +    (0xFF73, 'M', 'ウ'),
    +    (0xFF74, 'M', 'エ'),
    +    (0xFF75, 'M', 'オ'),
    +    (0xFF76, 'M', 'カ'),
    +    (0xFF77, 'M', 'キ'),
    +    (0xFF78, 'M', 'ク'),
    +    (0xFF79, 'M', 'ケ'),
    +    (0xFF7A, 'M', 'コ'),
    +    (0xFF7B, 'M', 'サ'),
    +    (0xFF7C, 'M', 'シ'),
    +    (0xFF7D, 'M', 'ス'),
    +    (0xFF7E, 'M', 'セ'),
    +    ]
    +
    +def _seg_52() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xFF7F, 'M', 'ソ'),
    +    (0xFF80, 'M', 'タ'),
    +    (0xFF81, 'M', 'チ'),
    +    (0xFF82, 'M', 'ツ'),
    +    (0xFF83, 'M', 'テ'),
    +    (0xFF84, 'M', 'ト'),
    +    (0xFF85, 'M', 'ナ'),
    +    (0xFF86, 'M', 'ニ'),
    +    (0xFF87, 'M', 'ヌ'),
    +    (0xFF88, 'M', 'ネ'),
    +    (0xFF89, 'M', 'ノ'),
    +    (0xFF8A, 'M', 'ハ'),
    +    (0xFF8B, 'M', 'ヒ'),
    +    (0xFF8C, 'M', 'フ'),
    +    (0xFF8D, 'M', 'ヘ'),
    +    (0xFF8E, 'M', 'ホ'),
    +    (0xFF8F, 'M', 'マ'),
    +    (0xFF90, 'M', 'ミ'),
    +    (0xFF91, 'M', 'ム'),
    +    (0xFF92, 'M', 'メ'),
    +    (0xFF93, 'M', 'モ'),
    +    (0xFF94, 'M', 'ヤ'),
    +    (0xFF95, 'M', 'ユ'),
    +    (0xFF96, 'M', 'ヨ'),
    +    (0xFF97, 'M', 'ラ'),
    +    (0xFF98, 'M', 'リ'),
    +    (0xFF99, 'M', 'ル'),
    +    (0xFF9A, 'M', 'レ'),
    +    (0xFF9B, 'M', 'ロ'),
    +    (0xFF9C, 'M', 'ワ'),
    +    (0xFF9D, 'M', 'ン'),
    +    (0xFF9E, 'M', '゙'),
    +    (0xFF9F, 'M', '゚'),
    +    (0xFFA0, 'X'),
    +    (0xFFA1, 'M', 'ᄀ'),
    +    (0xFFA2, 'M', 'ᄁ'),
    +    (0xFFA3, 'M', 'ᆪ'),
    +    (0xFFA4, 'M', 'ᄂ'),
    +    (0xFFA5, 'M', 'ᆬ'),
    +    (0xFFA6, 'M', 'ᆭ'),
    +    (0xFFA7, 'M', 'ᄃ'),
    +    (0xFFA8, 'M', 'ᄄ'),
    +    (0xFFA9, 'M', 'ᄅ'),
    +    (0xFFAA, 'M', 'ᆰ'),
    +    (0xFFAB, 'M', 'ᆱ'),
    +    (0xFFAC, 'M', 'ᆲ'),
    +    (0xFFAD, 'M', 'ᆳ'),
    +    (0xFFAE, 'M', 'ᆴ'),
    +    (0xFFAF, 'M', 'ᆵ'),
    +    (0xFFB0, 'M', 'ᄚ'),
    +    (0xFFB1, 'M', 'ᄆ'),
    +    (0xFFB2, 'M', 'ᄇ'),
    +    (0xFFB3, 'M', 'ᄈ'),
    +    (0xFFB4, 'M', 'ᄡ'),
    +    (0xFFB5, 'M', 'ᄉ'),
    +    (0xFFB6, 'M', 'ᄊ'),
    +    (0xFFB7, 'M', 'ᄋ'),
    +    (0xFFB8, 'M', 'ᄌ'),
    +    (0xFFB9, 'M', 'ᄍ'),
    +    (0xFFBA, 'M', 'ᄎ'),
    +    (0xFFBB, 'M', 'ᄏ'),
    +    (0xFFBC, 'M', 'ᄐ'),
    +    (0xFFBD, 'M', 'ᄑ'),
    +    (0xFFBE, 'M', 'ᄒ'),
    +    (0xFFBF, 'X'),
    +    (0xFFC2, 'M', 'ᅡ'),
    +    (0xFFC3, 'M', 'ᅢ'),
    +    (0xFFC4, 'M', 'ᅣ'),
    +    (0xFFC5, 'M', 'ᅤ'),
    +    (0xFFC6, 'M', 'ᅥ'),
    +    (0xFFC7, 'M', 'ᅦ'),
    +    (0xFFC8, 'X'),
    +    (0xFFCA, 'M', 'ᅧ'),
    +    (0xFFCB, 'M', 'ᅨ'),
    +    (0xFFCC, 'M', 'ᅩ'),
    +    (0xFFCD, 'M', 'ᅪ'),
    +    (0xFFCE, 'M', 'ᅫ'),
    +    (0xFFCF, 'M', 'ᅬ'),
    +    (0xFFD0, 'X'),
    +    (0xFFD2, 'M', 'ᅭ'),
    +    (0xFFD3, 'M', 'ᅮ'),
    +    (0xFFD4, 'M', 'ᅯ'),
    +    (0xFFD5, 'M', 'ᅰ'),
    +    (0xFFD6, 'M', 'ᅱ'),
    +    (0xFFD7, 'M', 'ᅲ'),
    +    (0xFFD8, 'X'),
    +    (0xFFDA, 'M', 'ᅳ'),
    +    (0xFFDB, 'M', 'ᅴ'),
    +    (0xFFDC, 'M', 'ᅵ'),
    +    (0xFFDD, 'X'),
    +    (0xFFE0, 'M', '¢'),
    +    (0xFFE1, 'M', '£'),
    +    (0xFFE2, 'M', '¬'),
    +    (0xFFE3, '3', ' ̄'),
    +    (0xFFE4, 'M', '¦'),
    +    (0xFFE5, 'M', '¥'),
    +    (0xFFE6, 'M', '₩'),
    +    (0xFFE7, 'X'),
    +    (0xFFE8, 'M', '│'),
    +    (0xFFE9, 'M', '←'),
    +    ]
    +
    +def _seg_53() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0xFFEA, 'M', '↑'),
    +    (0xFFEB, 'M', '→'),
    +    (0xFFEC, 'M', '↓'),
    +    (0xFFED, 'M', '■'),
    +    (0xFFEE, 'M', '○'),
    +    (0xFFEF, 'X'),
    +    (0x10000, 'V'),
    +    (0x1000C, 'X'),
    +    (0x1000D, 'V'),
    +    (0x10027, 'X'),
    +    (0x10028, 'V'),
    +    (0x1003B, 'X'),
    +    (0x1003C, 'V'),
    +    (0x1003E, 'X'),
    +    (0x1003F, 'V'),
    +    (0x1004E, 'X'),
    +    (0x10050, 'V'),
    +    (0x1005E, 'X'),
    +    (0x10080, 'V'),
    +    (0x100FB, 'X'),
    +    (0x10100, 'V'),
    +    (0x10103, 'X'),
    +    (0x10107, 'V'),
    +    (0x10134, 'X'),
    +    (0x10137, 'V'),
    +    (0x1018F, 'X'),
    +    (0x10190, 'V'),
    +    (0x1019D, 'X'),
    +    (0x101A0, 'V'),
    +    (0x101A1, 'X'),
    +    (0x101D0, 'V'),
    +    (0x101FE, 'X'),
    +    (0x10280, 'V'),
    +    (0x1029D, 'X'),
    +    (0x102A0, 'V'),
    +    (0x102D1, 'X'),
    +    (0x102E0, 'V'),
    +    (0x102FC, 'X'),
    +    (0x10300, 'V'),
    +    (0x10324, 'X'),
    +    (0x1032D, 'V'),
    +    (0x1034B, 'X'),
    +    (0x10350, 'V'),
    +    (0x1037B, 'X'),
    +    (0x10380, 'V'),
    +    (0x1039E, 'X'),
    +    (0x1039F, 'V'),
    +    (0x103C4, 'X'),
    +    (0x103C8, 'V'),
    +    (0x103D6, 'X'),
    +    (0x10400, 'M', '𐐨'),
    +    (0x10401, 'M', '𐐩'),
    +    (0x10402, 'M', '𐐪'),
    +    (0x10403, 'M', '𐐫'),
    +    (0x10404, 'M', '𐐬'),
    +    (0x10405, 'M', '𐐭'),
    +    (0x10406, 'M', '𐐮'),
    +    (0x10407, 'M', '𐐯'),
    +    (0x10408, 'M', '𐐰'),
    +    (0x10409, 'M', '𐐱'),
    +    (0x1040A, 'M', '𐐲'),
    +    (0x1040B, 'M', '𐐳'),
    +    (0x1040C, 'M', '𐐴'),
    +    (0x1040D, 'M', '𐐵'),
    +    (0x1040E, 'M', '𐐶'),
    +    (0x1040F, 'M', '𐐷'),
    +    (0x10410, 'M', '𐐸'),
    +    (0x10411, 'M', '𐐹'),
    +    (0x10412, 'M', '𐐺'),
    +    (0x10413, 'M', '𐐻'),
    +    (0x10414, 'M', '𐐼'),
    +    (0x10415, 'M', '𐐽'),
    +    (0x10416, 'M', '𐐾'),
    +    (0x10417, 'M', '𐐿'),
    +    (0x10418, 'M', '𐑀'),
    +    (0x10419, 'M', '𐑁'),
    +    (0x1041A, 'M', '𐑂'),
    +    (0x1041B, 'M', '𐑃'),
    +    (0x1041C, 'M', '𐑄'),
    +    (0x1041D, 'M', '𐑅'),
    +    (0x1041E, 'M', '𐑆'),
    +    (0x1041F, 'M', '𐑇'),
    +    (0x10420, 'M', '𐑈'),
    +    (0x10421, 'M', '𐑉'),
    +    (0x10422, 'M', '𐑊'),
    +    (0x10423, 'M', '𐑋'),
    +    (0x10424, 'M', '𐑌'),
    +    (0x10425, 'M', '𐑍'),
    +    (0x10426, 'M', '𐑎'),
    +    (0x10427, 'M', '𐑏'),
    +    (0x10428, 'V'),
    +    (0x1049E, 'X'),
    +    (0x104A0, 'V'),
    +    (0x104AA, 'X'),
    +    (0x104B0, 'M', '𐓘'),
    +    (0x104B1, 'M', '𐓙'),
    +    (0x104B2, 'M', '𐓚'),
    +    (0x104B3, 'M', '𐓛'),
    +    (0x104B4, 'M', '𐓜'),
    +    (0x104B5, 'M', '𐓝'),
    +    ]
    +
    +def _seg_54() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x104B6, 'M', '𐓞'),
    +    (0x104B7, 'M', '𐓟'),
    +    (0x104B8, 'M', '𐓠'),
    +    (0x104B9, 'M', '𐓡'),
    +    (0x104BA, 'M', '𐓢'),
    +    (0x104BB, 'M', '𐓣'),
    +    (0x104BC, 'M', '𐓤'),
    +    (0x104BD, 'M', '𐓥'),
    +    (0x104BE, 'M', '𐓦'),
    +    (0x104BF, 'M', '𐓧'),
    +    (0x104C0, 'M', '𐓨'),
    +    (0x104C1, 'M', '𐓩'),
    +    (0x104C2, 'M', '𐓪'),
    +    (0x104C3, 'M', '𐓫'),
    +    (0x104C4, 'M', '𐓬'),
    +    (0x104C5, 'M', '𐓭'),
    +    (0x104C6, 'M', '𐓮'),
    +    (0x104C7, 'M', '𐓯'),
    +    (0x104C8, 'M', '𐓰'),
    +    (0x104C9, 'M', '𐓱'),
    +    (0x104CA, 'M', '𐓲'),
    +    (0x104CB, 'M', '𐓳'),
    +    (0x104CC, 'M', '𐓴'),
    +    (0x104CD, 'M', '𐓵'),
    +    (0x104CE, 'M', '𐓶'),
    +    (0x104CF, 'M', '𐓷'),
    +    (0x104D0, 'M', '𐓸'),
    +    (0x104D1, 'M', '𐓹'),
    +    (0x104D2, 'M', '𐓺'),
    +    (0x104D3, 'M', '𐓻'),
    +    (0x104D4, 'X'),
    +    (0x104D8, 'V'),
    +    (0x104FC, 'X'),
    +    (0x10500, 'V'),
    +    (0x10528, 'X'),
    +    (0x10530, 'V'),
    +    (0x10564, 'X'),
    +    (0x1056F, 'V'),
    +    (0x10570, 'M', '𐖗'),
    +    (0x10571, 'M', '𐖘'),
    +    (0x10572, 'M', '𐖙'),
    +    (0x10573, 'M', '𐖚'),
    +    (0x10574, 'M', '𐖛'),
    +    (0x10575, 'M', '𐖜'),
    +    (0x10576, 'M', '𐖝'),
    +    (0x10577, 'M', '𐖞'),
    +    (0x10578, 'M', '𐖟'),
    +    (0x10579, 'M', '𐖠'),
    +    (0x1057A, 'M', '𐖡'),
    +    (0x1057B, 'X'),
    +    (0x1057C, 'M', '𐖣'),
    +    (0x1057D, 'M', '𐖤'),
    +    (0x1057E, 'M', '𐖥'),
    +    (0x1057F, 'M', '𐖦'),
    +    (0x10580, 'M', '𐖧'),
    +    (0x10581, 'M', '𐖨'),
    +    (0x10582, 'M', '𐖩'),
    +    (0x10583, 'M', '𐖪'),
    +    (0x10584, 'M', '𐖫'),
    +    (0x10585, 'M', '𐖬'),
    +    (0x10586, 'M', '𐖭'),
    +    (0x10587, 'M', '𐖮'),
    +    (0x10588, 'M', '𐖯'),
    +    (0x10589, 'M', '𐖰'),
    +    (0x1058A, 'M', '𐖱'),
    +    (0x1058B, 'X'),
    +    (0x1058C, 'M', '𐖳'),
    +    (0x1058D, 'M', '𐖴'),
    +    (0x1058E, 'M', '𐖵'),
    +    (0x1058F, 'M', '𐖶'),
    +    (0x10590, 'M', '𐖷'),
    +    (0x10591, 'M', '𐖸'),
    +    (0x10592, 'M', '𐖹'),
    +    (0x10593, 'X'),
    +    (0x10594, 'M', '𐖻'),
    +    (0x10595, 'M', '𐖼'),
    +    (0x10596, 'X'),
    +    (0x10597, 'V'),
    +    (0x105A2, 'X'),
    +    (0x105A3, 'V'),
    +    (0x105B2, 'X'),
    +    (0x105B3, 'V'),
    +    (0x105BA, 'X'),
    +    (0x105BB, 'V'),
    +    (0x105BD, 'X'),
    +    (0x10600, 'V'),
    +    (0x10737, 'X'),
    +    (0x10740, 'V'),
    +    (0x10756, 'X'),
    +    (0x10760, 'V'),
    +    (0x10768, 'X'),
    +    (0x10780, 'V'),
    +    (0x10781, 'M', 'ː'),
    +    (0x10782, 'M', 'ˑ'),
    +    (0x10783, 'M', 'æ'),
    +    (0x10784, 'M', 'ʙ'),
    +    (0x10785, 'M', 'ɓ'),
    +    (0x10786, 'X'),
    +    (0x10787, 'M', 'ʣ'),
    +    (0x10788, 'M', 'ꭦ'),
    +    ]
    +
    +def _seg_55() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x10789, 'M', 'ʥ'),
    +    (0x1078A, 'M', 'ʤ'),
    +    (0x1078B, 'M', 'ɖ'),
    +    (0x1078C, 'M', 'ɗ'),
    +    (0x1078D, 'M', 'ᶑ'),
    +    (0x1078E, 'M', 'ɘ'),
    +    (0x1078F, 'M', 'ɞ'),
    +    (0x10790, 'M', 'ʩ'),
    +    (0x10791, 'M', 'ɤ'),
    +    (0x10792, 'M', 'ɢ'),
    +    (0x10793, 'M', 'ɠ'),
    +    (0x10794, 'M', 'ʛ'),
    +    (0x10795, 'M', 'ħ'),
    +    (0x10796, 'M', 'ʜ'),
    +    (0x10797, 'M', 'ɧ'),
    +    (0x10798, 'M', 'ʄ'),
    +    (0x10799, 'M', 'ʪ'),
    +    (0x1079A, 'M', 'ʫ'),
    +    (0x1079B, 'M', 'ɬ'),
    +    (0x1079C, 'M', '𝼄'),
    +    (0x1079D, 'M', 'ꞎ'),
    +    (0x1079E, 'M', 'ɮ'),
    +    (0x1079F, 'M', '𝼅'),
    +    (0x107A0, 'M', 'ʎ'),
    +    (0x107A1, 'M', '𝼆'),
    +    (0x107A2, 'M', 'ø'),
    +    (0x107A3, 'M', 'ɶ'),
    +    (0x107A4, 'M', 'ɷ'),
    +    (0x107A5, 'M', 'q'),
    +    (0x107A6, 'M', 'ɺ'),
    +    (0x107A7, 'M', '𝼈'),
    +    (0x107A8, 'M', 'ɽ'),
    +    (0x107A9, 'M', 'ɾ'),
    +    (0x107AA, 'M', 'ʀ'),
    +    (0x107AB, 'M', 'ʨ'),
    +    (0x107AC, 'M', 'ʦ'),
    +    (0x107AD, 'M', 'ꭧ'),
    +    (0x107AE, 'M', 'ʧ'),
    +    (0x107AF, 'M', 'ʈ'),
    +    (0x107B0, 'M', 'ⱱ'),
    +    (0x107B1, 'X'),
    +    (0x107B2, 'M', 'ʏ'),
    +    (0x107B3, 'M', 'ʡ'),
    +    (0x107B4, 'M', 'ʢ'),
    +    (0x107B5, 'M', 'ʘ'),
    +    (0x107B6, 'M', 'ǀ'),
    +    (0x107B7, 'M', 'ǁ'),
    +    (0x107B8, 'M', 'ǂ'),
    +    (0x107B9, 'M', '𝼊'),
    +    (0x107BA, 'M', '𝼞'),
    +    (0x107BB, 'X'),
    +    (0x10800, 'V'),
    +    (0x10806, 'X'),
    +    (0x10808, 'V'),
    +    (0x10809, 'X'),
    +    (0x1080A, 'V'),
    +    (0x10836, 'X'),
    +    (0x10837, 'V'),
    +    (0x10839, 'X'),
    +    (0x1083C, 'V'),
    +    (0x1083D, 'X'),
    +    (0x1083F, 'V'),
    +    (0x10856, 'X'),
    +    (0x10857, 'V'),
    +    (0x1089F, 'X'),
    +    (0x108A7, 'V'),
    +    (0x108B0, 'X'),
    +    (0x108E0, 'V'),
    +    (0x108F3, 'X'),
    +    (0x108F4, 'V'),
    +    (0x108F6, 'X'),
    +    (0x108FB, 'V'),
    +    (0x1091C, 'X'),
    +    (0x1091F, 'V'),
    +    (0x1093A, 'X'),
    +    (0x1093F, 'V'),
    +    (0x10940, 'X'),
    +    (0x10980, 'V'),
    +    (0x109B8, 'X'),
    +    (0x109BC, 'V'),
    +    (0x109D0, 'X'),
    +    (0x109D2, 'V'),
    +    (0x10A04, 'X'),
    +    (0x10A05, 'V'),
    +    (0x10A07, 'X'),
    +    (0x10A0C, 'V'),
    +    (0x10A14, 'X'),
    +    (0x10A15, 'V'),
    +    (0x10A18, 'X'),
    +    (0x10A19, 'V'),
    +    (0x10A36, 'X'),
    +    (0x10A38, 'V'),
    +    (0x10A3B, 'X'),
    +    (0x10A3F, 'V'),
    +    (0x10A49, 'X'),
    +    (0x10A50, 'V'),
    +    (0x10A59, 'X'),
    +    (0x10A60, 'V'),
    +    (0x10AA0, 'X'),
    +    (0x10AC0, 'V'),
    +    ]
    +
    +def _seg_56() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x10AE7, 'X'),
    +    (0x10AEB, 'V'),
    +    (0x10AF7, 'X'),
    +    (0x10B00, 'V'),
    +    (0x10B36, 'X'),
    +    (0x10B39, 'V'),
    +    (0x10B56, 'X'),
    +    (0x10B58, 'V'),
    +    (0x10B73, 'X'),
    +    (0x10B78, 'V'),
    +    (0x10B92, 'X'),
    +    (0x10B99, 'V'),
    +    (0x10B9D, 'X'),
    +    (0x10BA9, 'V'),
    +    (0x10BB0, 'X'),
    +    (0x10C00, 'V'),
    +    (0x10C49, 'X'),
    +    (0x10C80, 'M', '𐳀'),
    +    (0x10C81, 'M', '𐳁'),
    +    (0x10C82, 'M', '𐳂'),
    +    (0x10C83, 'M', '𐳃'),
    +    (0x10C84, 'M', '𐳄'),
    +    (0x10C85, 'M', '𐳅'),
    +    (0x10C86, 'M', '𐳆'),
    +    (0x10C87, 'M', '𐳇'),
    +    (0x10C88, 'M', '𐳈'),
    +    (0x10C89, 'M', '𐳉'),
    +    (0x10C8A, 'M', '𐳊'),
    +    (0x10C8B, 'M', '𐳋'),
    +    (0x10C8C, 'M', '𐳌'),
    +    (0x10C8D, 'M', '𐳍'),
    +    (0x10C8E, 'M', '𐳎'),
    +    (0x10C8F, 'M', '𐳏'),
    +    (0x10C90, 'M', '𐳐'),
    +    (0x10C91, 'M', '𐳑'),
    +    (0x10C92, 'M', '𐳒'),
    +    (0x10C93, 'M', '𐳓'),
    +    (0x10C94, 'M', '𐳔'),
    +    (0x10C95, 'M', '𐳕'),
    +    (0x10C96, 'M', '𐳖'),
    +    (0x10C97, 'M', '𐳗'),
    +    (0x10C98, 'M', '𐳘'),
    +    (0x10C99, 'M', '𐳙'),
    +    (0x10C9A, 'M', '𐳚'),
    +    (0x10C9B, 'M', '𐳛'),
    +    (0x10C9C, 'M', '𐳜'),
    +    (0x10C9D, 'M', '𐳝'),
    +    (0x10C9E, 'M', '𐳞'),
    +    (0x10C9F, 'M', '𐳟'),
    +    (0x10CA0, 'M', '𐳠'),
    +    (0x10CA1, 'M', '𐳡'),
    +    (0x10CA2, 'M', '𐳢'),
    +    (0x10CA3, 'M', '𐳣'),
    +    (0x10CA4, 'M', '𐳤'),
    +    (0x10CA5, 'M', '𐳥'),
    +    (0x10CA6, 'M', '𐳦'),
    +    (0x10CA7, 'M', '𐳧'),
    +    (0x10CA8, 'M', '𐳨'),
    +    (0x10CA9, 'M', '𐳩'),
    +    (0x10CAA, 'M', '𐳪'),
    +    (0x10CAB, 'M', '𐳫'),
    +    (0x10CAC, 'M', '𐳬'),
    +    (0x10CAD, 'M', '𐳭'),
    +    (0x10CAE, 'M', '𐳮'),
    +    (0x10CAF, 'M', '𐳯'),
    +    (0x10CB0, 'M', '𐳰'),
    +    (0x10CB1, 'M', '𐳱'),
    +    (0x10CB2, 'M', '𐳲'),
    +    (0x10CB3, 'X'),
    +    (0x10CC0, 'V'),
    +    (0x10CF3, 'X'),
    +    (0x10CFA, 'V'),
    +    (0x10D28, 'X'),
    +    (0x10D30, 'V'),
    +    (0x10D3A, 'X'),
    +    (0x10E60, 'V'),
    +    (0x10E7F, 'X'),
    +    (0x10E80, 'V'),
    +    (0x10EAA, 'X'),
    +    (0x10EAB, 'V'),
    +    (0x10EAE, 'X'),
    +    (0x10EB0, 'V'),
    +    (0x10EB2, 'X'),
    +    (0x10EFD, 'V'),
    +    (0x10F28, 'X'),
    +    (0x10F30, 'V'),
    +    (0x10F5A, 'X'),
    +    (0x10F70, 'V'),
    +    (0x10F8A, 'X'),
    +    (0x10FB0, 'V'),
    +    (0x10FCC, 'X'),
    +    (0x10FE0, 'V'),
    +    (0x10FF7, 'X'),
    +    (0x11000, 'V'),
    +    (0x1104E, 'X'),
    +    (0x11052, 'V'),
    +    (0x11076, 'X'),
    +    (0x1107F, 'V'),
    +    (0x110BD, 'X'),
    +    (0x110BE, 'V'),
    +    ]
    +
    +def _seg_57() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x110C3, 'X'),
    +    (0x110D0, 'V'),
    +    (0x110E9, 'X'),
    +    (0x110F0, 'V'),
    +    (0x110FA, 'X'),
    +    (0x11100, 'V'),
    +    (0x11135, 'X'),
    +    (0x11136, 'V'),
    +    (0x11148, 'X'),
    +    (0x11150, 'V'),
    +    (0x11177, 'X'),
    +    (0x11180, 'V'),
    +    (0x111E0, 'X'),
    +    (0x111E1, 'V'),
    +    (0x111F5, 'X'),
    +    (0x11200, 'V'),
    +    (0x11212, 'X'),
    +    (0x11213, 'V'),
    +    (0x11242, 'X'),
    +    (0x11280, 'V'),
    +    (0x11287, 'X'),
    +    (0x11288, 'V'),
    +    (0x11289, 'X'),
    +    (0x1128A, 'V'),
    +    (0x1128E, 'X'),
    +    (0x1128F, 'V'),
    +    (0x1129E, 'X'),
    +    (0x1129F, 'V'),
    +    (0x112AA, 'X'),
    +    (0x112B0, 'V'),
    +    (0x112EB, 'X'),
    +    (0x112F0, 'V'),
    +    (0x112FA, 'X'),
    +    (0x11300, 'V'),
    +    (0x11304, 'X'),
    +    (0x11305, 'V'),
    +    (0x1130D, 'X'),
    +    (0x1130F, 'V'),
    +    (0x11311, 'X'),
    +    (0x11313, 'V'),
    +    (0x11329, 'X'),
    +    (0x1132A, 'V'),
    +    (0x11331, 'X'),
    +    (0x11332, 'V'),
    +    (0x11334, 'X'),
    +    (0x11335, 'V'),
    +    (0x1133A, 'X'),
    +    (0x1133B, 'V'),
    +    (0x11345, 'X'),
    +    (0x11347, 'V'),
    +    (0x11349, 'X'),
    +    (0x1134B, 'V'),
    +    (0x1134E, 'X'),
    +    (0x11350, 'V'),
    +    (0x11351, 'X'),
    +    (0x11357, 'V'),
    +    (0x11358, 'X'),
    +    (0x1135D, 'V'),
    +    (0x11364, 'X'),
    +    (0x11366, 'V'),
    +    (0x1136D, 'X'),
    +    (0x11370, 'V'),
    +    (0x11375, 'X'),
    +    (0x11400, 'V'),
    +    (0x1145C, 'X'),
    +    (0x1145D, 'V'),
    +    (0x11462, 'X'),
    +    (0x11480, 'V'),
    +    (0x114C8, 'X'),
    +    (0x114D0, 'V'),
    +    (0x114DA, 'X'),
    +    (0x11580, 'V'),
    +    (0x115B6, 'X'),
    +    (0x115B8, 'V'),
    +    (0x115DE, 'X'),
    +    (0x11600, 'V'),
    +    (0x11645, 'X'),
    +    (0x11650, 'V'),
    +    (0x1165A, 'X'),
    +    (0x11660, 'V'),
    +    (0x1166D, 'X'),
    +    (0x11680, 'V'),
    +    (0x116BA, 'X'),
    +    (0x116C0, 'V'),
    +    (0x116CA, 'X'),
    +    (0x11700, 'V'),
    +    (0x1171B, 'X'),
    +    (0x1171D, 'V'),
    +    (0x1172C, 'X'),
    +    (0x11730, 'V'),
    +    (0x11747, 'X'),
    +    (0x11800, 'V'),
    +    (0x1183C, 'X'),
    +    (0x118A0, 'M', '𑣀'),
    +    (0x118A1, 'M', '𑣁'),
    +    (0x118A2, 'M', '𑣂'),
    +    (0x118A3, 'M', '𑣃'),
    +    (0x118A4, 'M', '𑣄'),
    +    (0x118A5, 'M', '𑣅'),
    +    (0x118A6, 'M', '𑣆'),
    +    ]
    +
    +def _seg_58() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x118A7, 'M', '𑣇'),
    +    (0x118A8, 'M', '𑣈'),
    +    (0x118A9, 'M', '𑣉'),
    +    (0x118AA, 'M', '𑣊'),
    +    (0x118AB, 'M', '𑣋'),
    +    (0x118AC, 'M', '𑣌'),
    +    (0x118AD, 'M', '𑣍'),
    +    (0x118AE, 'M', '𑣎'),
    +    (0x118AF, 'M', '𑣏'),
    +    (0x118B0, 'M', '𑣐'),
    +    (0x118B1, 'M', '𑣑'),
    +    (0x118B2, 'M', '𑣒'),
    +    (0x118B3, 'M', '𑣓'),
    +    (0x118B4, 'M', '𑣔'),
    +    (0x118B5, 'M', '𑣕'),
    +    (0x118B6, 'M', '𑣖'),
    +    (0x118B7, 'M', '𑣗'),
    +    (0x118B8, 'M', '𑣘'),
    +    (0x118B9, 'M', '𑣙'),
    +    (0x118BA, 'M', '𑣚'),
    +    (0x118BB, 'M', '𑣛'),
    +    (0x118BC, 'M', '𑣜'),
    +    (0x118BD, 'M', '𑣝'),
    +    (0x118BE, 'M', '𑣞'),
    +    (0x118BF, 'M', '𑣟'),
    +    (0x118C0, 'V'),
    +    (0x118F3, 'X'),
    +    (0x118FF, 'V'),
    +    (0x11907, 'X'),
    +    (0x11909, 'V'),
    +    (0x1190A, 'X'),
    +    (0x1190C, 'V'),
    +    (0x11914, 'X'),
    +    (0x11915, 'V'),
    +    (0x11917, 'X'),
    +    (0x11918, 'V'),
    +    (0x11936, 'X'),
    +    (0x11937, 'V'),
    +    (0x11939, 'X'),
    +    (0x1193B, 'V'),
    +    (0x11947, 'X'),
    +    (0x11950, 'V'),
    +    (0x1195A, 'X'),
    +    (0x119A0, 'V'),
    +    (0x119A8, 'X'),
    +    (0x119AA, 'V'),
    +    (0x119D8, 'X'),
    +    (0x119DA, 'V'),
    +    (0x119E5, 'X'),
    +    (0x11A00, 'V'),
    +    (0x11A48, 'X'),
    +    (0x11A50, 'V'),
    +    (0x11AA3, 'X'),
    +    (0x11AB0, 'V'),
    +    (0x11AF9, 'X'),
    +    (0x11B00, 'V'),
    +    (0x11B0A, 'X'),
    +    (0x11C00, 'V'),
    +    (0x11C09, 'X'),
    +    (0x11C0A, 'V'),
    +    (0x11C37, 'X'),
    +    (0x11C38, 'V'),
    +    (0x11C46, 'X'),
    +    (0x11C50, 'V'),
    +    (0x11C6D, 'X'),
    +    (0x11C70, 'V'),
    +    (0x11C90, 'X'),
    +    (0x11C92, 'V'),
    +    (0x11CA8, 'X'),
    +    (0x11CA9, 'V'),
    +    (0x11CB7, 'X'),
    +    (0x11D00, 'V'),
    +    (0x11D07, 'X'),
    +    (0x11D08, 'V'),
    +    (0x11D0A, 'X'),
    +    (0x11D0B, 'V'),
    +    (0x11D37, 'X'),
    +    (0x11D3A, 'V'),
    +    (0x11D3B, 'X'),
    +    (0x11D3C, 'V'),
    +    (0x11D3E, 'X'),
    +    (0x11D3F, 'V'),
    +    (0x11D48, 'X'),
    +    (0x11D50, 'V'),
    +    (0x11D5A, 'X'),
    +    (0x11D60, 'V'),
    +    (0x11D66, 'X'),
    +    (0x11D67, 'V'),
    +    (0x11D69, 'X'),
    +    (0x11D6A, 'V'),
    +    (0x11D8F, 'X'),
    +    (0x11D90, 'V'),
    +    (0x11D92, 'X'),
    +    (0x11D93, 'V'),
    +    (0x11D99, 'X'),
    +    (0x11DA0, 'V'),
    +    (0x11DAA, 'X'),
    +    (0x11EE0, 'V'),
    +    (0x11EF9, 'X'),
    +    (0x11F00, 'V'),
    +    ]
    +
    +def _seg_59() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x11F11, 'X'),
    +    (0x11F12, 'V'),
    +    (0x11F3B, 'X'),
    +    (0x11F3E, 'V'),
    +    (0x11F5A, 'X'),
    +    (0x11FB0, 'V'),
    +    (0x11FB1, 'X'),
    +    (0x11FC0, 'V'),
    +    (0x11FF2, 'X'),
    +    (0x11FFF, 'V'),
    +    (0x1239A, 'X'),
    +    (0x12400, 'V'),
    +    (0x1246F, 'X'),
    +    (0x12470, 'V'),
    +    (0x12475, 'X'),
    +    (0x12480, 'V'),
    +    (0x12544, 'X'),
    +    (0x12F90, 'V'),
    +    (0x12FF3, 'X'),
    +    (0x13000, 'V'),
    +    (0x13430, 'X'),
    +    (0x13440, 'V'),
    +    (0x13456, 'X'),
    +    (0x14400, 'V'),
    +    (0x14647, 'X'),
    +    (0x16800, 'V'),
    +    (0x16A39, 'X'),
    +    (0x16A40, 'V'),
    +    (0x16A5F, 'X'),
    +    (0x16A60, 'V'),
    +    (0x16A6A, 'X'),
    +    (0x16A6E, 'V'),
    +    (0x16ABF, 'X'),
    +    (0x16AC0, 'V'),
    +    (0x16ACA, 'X'),
    +    (0x16AD0, 'V'),
    +    (0x16AEE, 'X'),
    +    (0x16AF0, 'V'),
    +    (0x16AF6, 'X'),
    +    (0x16B00, 'V'),
    +    (0x16B46, 'X'),
    +    (0x16B50, 'V'),
    +    (0x16B5A, 'X'),
    +    (0x16B5B, 'V'),
    +    (0x16B62, 'X'),
    +    (0x16B63, 'V'),
    +    (0x16B78, 'X'),
    +    (0x16B7D, 'V'),
    +    (0x16B90, 'X'),
    +    (0x16E40, 'M', '𖹠'),
    +    (0x16E41, 'M', '𖹡'),
    +    (0x16E42, 'M', '𖹢'),
    +    (0x16E43, 'M', '𖹣'),
    +    (0x16E44, 'M', '𖹤'),
    +    (0x16E45, 'M', '𖹥'),
    +    (0x16E46, 'M', '𖹦'),
    +    (0x16E47, 'M', '𖹧'),
    +    (0x16E48, 'M', '𖹨'),
    +    (0x16E49, 'M', '𖹩'),
    +    (0x16E4A, 'M', '𖹪'),
    +    (0x16E4B, 'M', '𖹫'),
    +    (0x16E4C, 'M', '𖹬'),
    +    (0x16E4D, 'M', '𖹭'),
    +    (0x16E4E, 'M', '𖹮'),
    +    (0x16E4F, 'M', '𖹯'),
    +    (0x16E50, 'M', '𖹰'),
    +    (0x16E51, 'M', '𖹱'),
    +    (0x16E52, 'M', '𖹲'),
    +    (0x16E53, 'M', '𖹳'),
    +    (0x16E54, 'M', '𖹴'),
    +    (0x16E55, 'M', '𖹵'),
    +    (0x16E56, 'M', '𖹶'),
    +    (0x16E57, 'M', '𖹷'),
    +    (0x16E58, 'M', '𖹸'),
    +    (0x16E59, 'M', '𖹹'),
    +    (0x16E5A, 'M', '𖹺'),
    +    (0x16E5B, 'M', '𖹻'),
    +    (0x16E5C, 'M', '𖹼'),
    +    (0x16E5D, 'M', '𖹽'),
    +    (0x16E5E, 'M', '𖹾'),
    +    (0x16E5F, 'M', '𖹿'),
    +    (0x16E60, 'V'),
    +    (0x16E9B, 'X'),
    +    (0x16F00, 'V'),
    +    (0x16F4B, 'X'),
    +    (0x16F4F, 'V'),
    +    (0x16F88, 'X'),
    +    (0x16F8F, 'V'),
    +    (0x16FA0, 'X'),
    +    (0x16FE0, 'V'),
    +    (0x16FE5, 'X'),
    +    (0x16FF0, 'V'),
    +    (0x16FF2, 'X'),
    +    (0x17000, 'V'),
    +    (0x187F8, 'X'),
    +    (0x18800, 'V'),
    +    (0x18CD6, 'X'),
    +    (0x18D00, 'V'),
    +    (0x18D09, 'X'),
    +    (0x1AFF0, 'V'),
    +    ]
    +
    +def _seg_60() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1AFF4, 'X'),
    +    (0x1AFF5, 'V'),
    +    (0x1AFFC, 'X'),
    +    (0x1AFFD, 'V'),
    +    (0x1AFFF, 'X'),
    +    (0x1B000, 'V'),
    +    (0x1B123, 'X'),
    +    (0x1B132, 'V'),
    +    (0x1B133, 'X'),
    +    (0x1B150, 'V'),
    +    (0x1B153, 'X'),
    +    (0x1B155, 'V'),
    +    (0x1B156, 'X'),
    +    (0x1B164, 'V'),
    +    (0x1B168, 'X'),
    +    (0x1B170, 'V'),
    +    (0x1B2FC, 'X'),
    +    (0x1BC00, 'V'),
    +    (0x1BC6B, 'X'),
    +    (0x1BC70, 'V'),
    +    (0x1BC7D, 'X'),
    +    (0x1BC80, 'V'),
    +    (0x1BC89, 'X'),
    +    (0x1BC90, 'V'),
    +    (0x1BC9A, 'X'),
    +    (0x1BC9C, 'V'),
    +    (0x1BCA0, 'I'),
    +    (0x1BCA4, 'X'),
    +    (0x1CF00, 'V'),
    +    (0x1CF2E, 'X'),
    +    (0x1CF30, 'V'),
    +    (0x1CF47, 'X'),
    +    (0x1CF50, 'V'),
    +    (0x1CFC4, 'X'),
    +    (0x1D000, 'V'),
    +    (0x1D0F6, 'X'),
    +    (0x1D100, 'V'),
    +    (0x1D127, 'X'),
    +    (0x1D129, 'V'),
    +    (0x1D15E, 'M', '𝅗𝅥'),
    +    (0x1D15F, 'M', '𝅘𝅥'),
    +    (0x1D160, 'M', '𝅘𝅥𝅮'),
    +    (0x1D161, 'M', '𝅘𝅥𝅯'),
    +    (0x1D162, 'M', '𝅘𝅥𝅰'),
    +    (0x1D163, 'M', '𝅘𝅥𝅱'),
    +    (0x1D164, 'M', '𝅘𝅥𝅲'),
    +    (0x1D165, 'V'),
    +    (0x1D173, 'X'),
    +    (0x1D17B, 'V'),
    +    (0x1D1BB, 'M', '𝆹𝅥'),
    +    (0x1D1BC, 'M', '𝆺𝅥'),
    +    (0x1D1BD, 'M', '𝆹𝅥𝅮'),
    +    (0x1D1BE, 'M', '𝆺𝅥𝅮'),
    +    (0x1D1BF, 'M', '𝆹𝅥𝅯'),
    +    (0x1D1C0, 'M', '𝆺𝅥𝅯'),
    +    (0x1D1C1, 'V'),
    +    (0x1D1EB, 'X'),
    +    (0x1D200, 'V'),
    +    (0x1D246, 'X'),
    +    (0x1D2C0, 'V'),
    +    (0x1D2D4, 'X'),
    +    (0x1D2E0, 'V'),
    +    (0x1D2F4, 'X'),
    +    (0x1D300, 'V'),
    +    (0x1D357, 'X'),
    +    (0x1D360, 'V'),
    +    (0x1D379, 'X'),
    +    (0x1D400, 'M', 'a'),
    +    (0x1D401, 'M', 'b'),
    +    (0x1D402, 'M', 'c'),
    +    (0x1D403, 'M', 'd'),
    +    (0x1D404, 'M', 'e'),
    +    (0x1D405, 'M', 'f'),
    +    (0x1D406, 'M', 'g'),
    +    (0x1D407, 'M', 'h'),
    +    (0x1D408, 'M', 'i'),
    +    (0x1D409, 'M', 'j'),
    +    (0x1D40A, 'M', 'k'),
    +    (0x1D40B, 'M', 'l'),
    +    (0x1D40C, 'M', 'm'),
    +    (0x1D40D, 'M', 'n'),
    +    (0x1D40E, 'M', 'o'),
    +    (0x1D40F, 'M', 'p'),
    +    (0x1D410, 'M', 'q'),
    +    (0x1D411, 'M', 'r'),
    +    (0x1D412, 'M', 's'),
    +    (0x1D413, 'M', 't'),
    +    (0x1D414, 'M', 'u'),
    +    (0x1D415, 'M', 'v'),
    +    (0x1D416, 'M', 'w'),
    +    (0x1D417, 'M', 'x'),
    +    (0x1D418, 'M', 'y'),
    +    (0x1D419, 'M', 'z'),
    +    (0x1D41A, 'M', 'a'),
    +    (0x1D41B, 'M', 'b'),
    +    (0x1D41C, 'M', 'c'),
    +    (0x1D41D, 'M', 'd'),
    +    (0x1D41E, 'M', 'e'),
    +    (0x1D41F, 'M', 'f'),
    +    (0x1D420, 'M', 'g'),
    +    ]
    +
    +def _seg_61() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1D421, 'M', 'h'),
    +    (0x1D422, 'M', 'i'),
    +    (0x1D423, 'M', 'j'),
    +    (0x1D424, 'M', 'k'),
    +    (0x1D425, 'M', 'l'),
    +    (0x1D426, 'M', 'm'),
    +    (0x1D427, 'M', 'n'),
    +    (0x1D428, 'M', 'o'),
    +    (0x1D429, 'M', 'p'),
    +    (0x1D42A, 'M', 'q'),
    +    (0x1D42B, 'M', 'r'),
    +    (0x1D42C, 'M', 's'),
    +    (0x1D42D, 'M', 't'),
    +    (0x1D42E, 'M', 'u'),
    +    (0x1D42F, 'M', 'v'),
    +    (0x1D430, 'M', 'w'),
    +    (0x1D431, 'M', 'x'),
    +    (0x1D432, 'M', 'y'),
    +    (0x1D433, 'M', 'z'),
    +    (0x1D434, 'M', 'a'),
    +    (0x1D435, 'M', 'b'),
    +    (0x1D436, 'M', 'c'),
    +    (0x1D437, 'M', 'd'),
    +    (0x1D438, 'M', 'e'),
    +    (0x1D439, 'M', 'f'),
    +    (0x1D43A, 'M', 'g'),
    +    (0x1D43B, 'M', 'h'),
    +    (0x1D43C, 'M', 'i'),
    +    (0x1D43D, 'M', 'j'),
    +    (0x1D43E, 'M', 'k'),
    +    (0x1D43F, 'M', 'l'),
    +    (0x1D440, 'M', 'm'),
    +    (0x1D441, 'M', 'n'),
    +    (0x1D442, 'M', 'o'),
    +    (0x1D443, 'M', 'p'),
    +    (0x1D444, 'M', 'q'),
    +    (0x1D445, 'M', 'r'),
    +    (0x1D446, 'M', 's'),
    +    (0x1D447, 'M', 't'),
    +    (0x1D448, 'M', 'u'),
    +    (0x1D449, 'M', 'v'),
    +    (0x1D44A, 'M', 'w'),
    +    (0x1D44B, 'M', 'x'),
    +    (0x1D44C, 'M', 'y'),
    +    (0x1D44D, 'M', 'z'),
    +    (0x1D44E, 'M', 'a'),
    +    (0x1D44F, 'M', 'b'),
    +    (0x1D450, 'M', 'c'),
    +    (0x1D451, 'M', 'd'),
    +    (0x1D452, 'M', 'e'),
    +    (0x1D453, 'M', 'f'),
    +    (0x1D454, 'M', 'g'),
    +    (0x1D455, 'X'),
    +    (0x1D456, 'M', 'i'),
    +    (0x1D457, 'M', 'j'),
    +    (0x1D458, 'M', 'k'),
    +    (0x1D459, 'M', 'l'),
    +    (0x1D45A, 'M', 'm'),
    +    (0x1D45B, 'M', 'n'),
    +    (0x1D45C, 'M', 'o'),
    +    (0x1D45D, 'M', 'p'),
    +    (0x1D45E, 'M', 'q'),
    +    (0x1D45F, 'M', 'r'),
    +    (0x1D460, 'M', 's'),
    +    (0x1D461, 'M', 't'),
    +    (0x1D462, 'M', 'u'),
    +    (0x1D463, 'M', 'v'),
    +    (0x1D464, 'M', 'w'),
    +    (0x1D465, 'M', 'x'),
    +    (0x1D466, 'M', 'y'),
    +    (0x1D467, 'M', 'z'),
    +    (0x1D468, 'M', 'a'),
    +    (0x1D469, 'M', 'b'),
    +    (0x1D46A, 'M', 'c'),
    +    (0x1D46B, 'M', 'd'),
    +    (0x1D46C, 'M', 'e'),
    +    (0x1D46D, 'M', 'f'),
    +    (0x1D46E, 'M', 'g'),
    +    (0x1D46F, 'M', 'h'),
    +    (0x1D470, 'M', 'i'),
    +    (0x1D471, 'M', 'j'),
    +    (0x1D472, 'M', 'k'),
    +    (0x1D473, 'M', 'l'),
    +    (0x1D474, 'M', 'm'),
    +    (0x1D475, 'M', 'n'),
    +    (0x1D476, 'M', 'o'),
    +    (0x1D477, 'M', 'p'),
    +    (0x1D478, 'M', 'q'),
    +    (0x1D479, 'M', 'r'),
    +    (0x1D47A, 'M', 's'),
    +    (0x1D47B, 'M', 't'),
    +    (0x1D47C, 'M', 'u'),
    +    (0x1D47D, 'M', 'v'),
    +    (0x1D47E, 'M', 'w'),
    +    (0x1D47F, 'M', 'x'),
    +    (0x1D480, 'M', 'y'),
    +    (0x1D481, 'M', 'z'),
    +    (0x1D482, 'M', 'a'),
    +    (0x1D483, 'M', 'b'),
    +    (0x1D484, 'M', 'c'),
    +    ]
    +
    +def _seg_62() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1D485, 'M', 'd'),
    +    (0x1D486, 'M', 'e'),
    +    (0x1D487, 'M', 'f'),
    +    (0x1D488, 'M', 'g'),
    +    (0x1D489, 'M', 'h'),
    +    (0x1D48A, 'M', 'i'),
    +    (0x1D48B, 'M', 'j'),
    +    (0x1D48C, 'M', 'k'),
    +    (0x1D48D, 'M', 'l'),
    +    (0x1D48E, 'M', 'm'),
    +    (0x1D48F, 'M', 'n'),
    +    (0x1D490, 'M', 'o'),
    +    (0x1D491, 'M', 'p'),
    +    (0x1D492, 'M', 'q'),
    +    (0x1D493, 'M', 'r'),
    +    (0x1D494, 'M', 's'),
    +    (0x1D495, 'M', 't'),
    +    (0x1D496, 'M', 'u'),
    +    (0x1D497, 'M', 'v'),
    +    (0x1D498, 'M', 'w'),
    +    (0x1D499, 'M', 'x'),
    +    (0x1D49A, 'M', 'y'),
    +    (0x1D49B, 'M', 'z'),
    +    (0x1D49C, 'M', 'a'),
    +    (0x1D49D, 'X'),
    +    (0x1D49E, 'M', 'c'),
    +    (0x1D49F, 'M', 'd'),
    +    (0x1D4A0, 'X'),
    +    (0x1D4A2, 'M', 'g'),
    +    (0x1D4A3, 'X'),
    +    (0x1D4A5, 'M', 'j'),
    +    (0x1D4A6, 'M', 'k'),
    +    (0x1D4A7, 'X'),
    +    (0x1D4A9, 'M', 'n'),
    +    (0x1D4AA, 'M', 'o'),
    +    (0x1D4AB, 'M', 'p'),
    +    (0x1D4AC, 'M', 'q'),
    +    (0x1D4AD, 'X'),
    +    (0x1D4AE, 'M', 's'),
    +    (0x1D4AF, 'M', 't'),
    +    (0x1D4B0, 'M', 'u'),
    +    (0x1D4B1, 'M', 'v'),
    +    (0x1D4B2, 'M', 'w'),
    +    (0x1D4B3, 'M', 'x'),
    +    (0x1D4B4, 'M', 'y'),
    +    (0x1D4B5, 'M', 'z'),
    +    (0x1D4B6, 'M', 'a'),
    +    (0x1D4B7, 'M', 'b'),
    +    (0x1D4B8, 'M', 'c'),
    +    (0x1D4B9, 'M', 'd'),
    +    (0x1D4BA, 'X'),
    +    (0x1D4BB, 'M', 'f'),
    +    (0x1D4BC, 'X'),
    +    (0x1D4BD, 'M', 'h'),
    +    (0x1D4BE, 'M', 'i'),
    +    (0x1D4BF, 'M', 'j'),
    +    (0x1D4C0, 'M', 'k'),
    +    (0x1D4C1, 'M', 'l'),
    +    (0x1D4C2, 'M', 'm'),
    +    (0x1D4C3, 'M', 'n'),
    +    (0x1D4C4, 'X'),
    +    (0x1D4C5, 'M', 'p'),
    +    (0x1D4C6, 'M', 'q'),
    +    (0x1D4C7, 'M', 'r'),
    +    (0x1D4C8, 'M', 's'),
    +    (0x1D4C9, 'M', 't'),
    +    (0x1D4CA, 'M', 'u'),
    +    (0x1D4CB, 'M', 'v'),
    +    (0x1D4CC, 'M', 'w'),
    +    (0x1D4CD, 'M', 'x'),
    +    (0x1D4CE, 'M', 'y'),
    +    (0x1D4CF, 'M', 'z'),
    +    (0x1D4D0, 'M', 'a'),
    +    (0x1D4D1, 'M', 'b'),
    +    (0x1D4D2, 'M', 'c'),
    +    (0x1D4D3, 'M', 'd'),
    +    (0x1D4D4, 'M', 'e'),
    +    (0x1D4D5, 'M', 'f'),
    +    (0x1D4D6, 'M', 'g'),
    +    (0x1D4D7, 'M', 'h'),
    +    (0x1D4D8, 'M', 'i'),
    +    (0x1D4D9, 'M', 'j'),
    +    (0x1D4DA, 'M', 'k'),
    +    (0x1D4DB, 'M', 'l'),
    +    (0x1D4DC, 'M', 'm'),
    +    (0x1D4DD, 'M', 'n'),
    +    (0x1D4DE, 'M', 'o'),
    +    (0x1D4DF, 'M', 'p'),
    +    (0x1D4E0, 'M', 'q'),
    +    (0x1D4E1, 'M', 'r'),
    +    (0x1D4E2, 'M', 's'),
    +    (0x1D4E3, 'M', 't'),
    +    (0x1D4E4, 'M', 'u'),
    +    (0x1D4E5, 'M', 'v'),
    +    (0x1D4E6, 'M', 'w'),
    +    (0x1D4E7, 'M', 'x'),
    +    (0x1D4E8, 'M', 'y'),
    +    (0x1D4E9, 'M', 'z'),
    +    (0x1D4EA, 'M', 'a'),
    +    (0x1D4EB, 'M', 'b'),
    +    ]
    +
    +def _seg_63() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1D4EC, 'M', 'c'),
    +    (0x1D4ED, 'M', 'd'),
    +    (0x1D4EE, 'M', 'e'),
    +    (0x1D4EF, 'M', 'f'),
    +    (0x1D4F0, 'M', 'g'),
    +    (0x1D4F1, 'M', 'h'),
    +    (0x1D4F2, 'M', 'i'),
    +    (0x1D4F3, 'M', 'j'),
    +    (0x1D4F4, 'M', 'k'),
    +    (0x1D4F5, 'M', 'l'),
    +    (0x1D4F6, 'M', 'm'),
    +    (0x1D4F7, 'M', 'n'),
    +    (0x1D4F8, 'M', 'o'),
    +    (0x1D4F9, 'M', 'p'),
    +    (0x1D4FA, 'M', 'q'),
    +    (0x1D4FB, 'M', 'r'),
    +    (0x1D4FC, 'M', 's'),
    +    (0x1D4FD, 'M', 't'),
    +    (0x1D4FE, 'M', 'u'),
    +    (0x1D4FF, 'M', 'v'),
    +    (0x1D500, 'M', 'w'),
    +    (0x1D501, 'M', 'x'),
    +    (0x1D502, 'M', 'y'),
    +    (0x1D503, 'M', 'z'),
    +    (0x1D504, 'M', 'a'),
    +    (0x1D505, 'M', 'b'),
    +    (0x1D506, 'X'),
    +    (0x1D507, 'M', 'd'),
    +    (0x1D508, 'M', 'e'),
    +    (0x1D509, 'M', 'f'),
    +    (0x1D50A, 'M', 'g'),
    +    (0x1D50B, 'X'),
    +    (0x1D50D, 'M', 'j'),
    +    (0x1D50E, 'M', 'k'),
    +    (0x1D50F, 'M', 'l'),
    +    (0x1D510, 'M', 'm'),
    +    (0x1D511, 'M', 'n'),
    +    (0x1D512, 'M', 'o'),
    +    (0x1D513, 'M', 'p'),
    +    (0x1D514, 'M', 'q'),
    +    (0x1D515, 'X'),
    +    (0x1D516, 'M', 's'),
    +    (0x1D517, 'M', 't'),
    +    (0x1D518, 'M', 'u'),
    +    (0x1D519, 'M', 'v'),
    +    (0x1D51A, 'M', 'w'),
    +    (0x1D51B, 'M', 'x'),
    +    (0x1D51C, 'M', 'y'),
    +    (0x1D51D, 'X'),
    +    (0x1D51E, 'M', 'a'),
    +    (0x1D51F, 'M', 'b'),
    +    (0x1D520, 'M', 'c'),
    +    (0x1D521, 'M', 'd'),
    +    (0x1D522, 'M', 'e'),
    +    (0x1D523, 'M', 'f'),
    +    (0x1D524, 'M', 'g'),
    +    (0x1D525, 'M', 'h'),
    +    (0x1D526, 'M', 'i'),
    +    (0x1D527, 'M', 'j'),
    +    (0x1D528, 'M', 'k'),
    +    (0x1D529, 'M', 'l'),
    +    (0x1D52A, 'M', 'm'),
    +    (0x1D52B, 'M', 'n'),
    +    (0x1D52C, 'M', 'o'),
    +    (0x1D52D, 'M', 'p'),
    +    (0x1D52E, 'M', 'q'),
    +    (0x1D52F, 'M', 'r'),
    +    (0x1D530, 'M', 's'),
    +    (0x1D531, 'M', 't'),
    +    (0x1D532, 'M', 'u'),
    +    (0x1D533, 'M', 'v'),
    +    (0x1D534, 'M', 'w'),
    +    (0x1D535, 'M', 'x'),
    +    (0x1D536, 'M', 'y'),
    +    (0x1D537, 'M', 'z'),
    +    (0x1D538, 'M', 'a'),
    +    (0x1D539, 'M', 'b'),
    +    (0x1D53A, 'X'),
    +    (0x1D53B, 'M', 'd'),
    +    (0x1D53C, 'M', 'e'),
    +    (0x1D53D, 'M', 'f'),
    +    (0x1D53E, 'M', 'g'),
    +    (0x1D53F, 'X'),
    +    (0x1D540, 'M', 'i'),
    +    (0x1D541, 'M', 'j'),
    +    (0x1D542, 'M', 'k'),
    +    (0x1D543, 'M', 'l'),
    +    (0x1D544, 'M', 'm'),
    +    (0x1D545, 'X'),
    +    (0x1D546, 'M', 'o'),
    +    (0x1D547, 'X'),
    +    (0x1D54A, 'M', 's'),
    +    (0x1D54B, 'M', 't'),
    +    (0x1D54C, 'M', 'u'),
    +    (0x1D54D, 'M', 'v'),
    +    (0x1D54E, 'M', 'w'),
    +    (0x1D54F, 'M', 'x'),
    +    (0x1D550, 'M', 'y'),
    +    (0x1D551, 'X'),
    +    (0x1D552, 'M', 'a'),
    +    ]
    +
    +def _seg_64() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1D553, 'M', 'b'),
    +    (0x1D554, 'M', 'c'),
    +    (0x1D555, 'M', 'd'),
    +    (0x1D556, 'M', 'e'),
    +    (0x1D557, 'M', 'f'),
    +    (0x1D558, 'M', 'g'),
    +    (0x1D559, 'M', 'h'),
    +    (0x1D55A, 'M', 'i'),
    +    (0x1D55B, 'M', 'j'),
    +    (0x1D55C, 'M', 'k'),
    +    (0x1D55D, 'M', 'l'),
    +    (0x1D55E, 'M', 'm'),
    +    (0x1D55F, 'M', 'n'),
    +    (0x1D560, 'M', 'o'),
    +    (0x1D561, 'M', 'p'),
    +    (0x1D562, 'M', 'q'),
    +    (0x1D563, 'M', 'r'),
    +    (0x1D564, 'M', 's'),
    +    (0x1D565, 'M', 't'),
    +    (0x1D566, 'M', 'u'),
    +    (0x1D567, 'M', 'v'),
    +    (0x1D568, 'M', 'w'),
    +    (0x1D569, 'M', 'x'),
    +    (0x1D56A, 'M', 'y'),
    +    (0x1D56B, 'M', 'z'),
    +    (0x1D56C, 'M', 'a'),
    +    (0x1D56D, 'M', 'b'),
    +    (0x1D56E, 'M', 'c'),
    +    (0x1D56F, 'M', 'd'),
    +    (0x1D570, 'M', 'e'),
    +    (0x1D571, 'M', 'f'),
    +    (0x1D572, 'M', 'g'),
    +    (0x1D573, 'M', 'h'),
    +    (0x1D574, 'M', 'i'),
    +    (0x1D575, 'M', 'j'),
    +    (0x1D576, 'M', 'k'),
    +    (0x1D577, 'M', 'l'),
    +    (0x1D578, 'M', 'm'),
    +    (0x1D579, 'M', 'n'),
    +    (0x1D57A, 'M', 'o'),
    +    (0x1D57B, 'M', 'p'),
    +    (0x1D57C, 'M', 'q'),
    +    (0x1D57D, 'M', 'r'),
    +    (0x1D57E, 'M', 's'),
    +    (0x1D57F, 'M', 't'),
    +    (0x1D580, 'M', 'u'),
    +    (0x1D581, 'M', 'v'),
    +    (0x1D582, 'M', 'w'),
    +    (0x1D583, 'M', 'x'),
    +    (0x1D584, 'M', 'y'),
    +    (0x1D585, 'M', 'z'),
    +    (0x1D586, 'M', 'a'),
    +    (0x1D587, 'M', 'b'),
    +    (0x1D588, 'M', 'c'),
    +    (0x1D589, 'M', 'd'),
    +    (0x1D58A, 'M', 'e'),
    +    (0x1D58B, 'M', 'f'),
    +    (0x1D58C, 'M', 'g'),
    +    (0x1D58D, 'M', 'h'),
    +    (0x1D58E, 'M', 'i'),
    +    (0x1D58F, 'M', 'j'),
    +    (0x1D590, 'M', 'k'),
    +    (0x1D591, 'M', 'l'),
    +    (0x1D592, 'M', 'm'),
    +    (0x1D593, 'M', 'n'),
    +    (0x1D594, 'M', 'o'),
    +    (0x1D595, 'M', 'p'),
    +    (0x1D596, 'M', 'q'),
    +    (0x1D597, 'M', 'r'),
    +    (0x1D598, 'M', 's'),
    +    (0x1D599, 'M', 't'),
    +    (0x1D59A, 'M', 'u'),
    +    (0x1D59B, 'M', 'v'),
    +    (0x1D59C, 'M', 'w'),
    +    (0x1D59D, 'M', 'x'),
    +    (0x1D59E, 'M', 'y'),
    +    (0x1D59F, 'M', 'z'),
    +    (0x1D5A0, 'M', 'a'),
    +    (0x1D5A1, 'M', 'b'),
    +    (0x1D5A2, 'M', 'c'),
    +    (0x1D5A3, 'M', 'd'),
    +    (0x1D5A4, 'M', 'e'),
    +    (0x1D5A5, 'M', 'f'),
    +    (0x1D5A6, 'M', 'g'),
    +    (0x1D5A7, 'M', 'h'),
    +    (0x1D5A8, 'M', 'i'),
    +    (0x1D5A9, 'M', 'j'),
    +    (0x1D5AA, 'M', 'k'),
    +    (0x1D5AB, 'M', 'l'),
    +    (0x1D5AC, 'M', 'm'),
    +    (0x1D5AD, 'M', 'n'),
    +    (0x1D5AE, 'M', 'o'),
    +    (0x1D5AF, 'M', 'p'),
    +    (0x1D5B0, 'M', 'q'),
    +    (0x1D5B1, 'M', 'r'),
    +    (0x1D5B2, 'M', 's'),
    +    (0x1D5B3, 'M', 't'),
    +    (0x1D5B4, 'M', 'u'),
    +    (0x1D5B5, 'M', 'v'),
    +    (0x1D5B6, 'M', 'w'),
    +    ]
    +
    +def _seg_65() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1D5B7, 'M', 'x'),
    +    (0x1D5B8, 'M', 'y'),
    +    (0x1D5B9, 'M', 'z'),
    +    (0x1D5BA, 'M', 'a'),
    +    (0x1D5BB, 'M', 'b'),
    +    (0x1D5BC, 'M', 'c'),
    +    (0x1D5BD, 'M', 'd'),
    +    (0x1D5BE, 'M', 'e'),
    +    (0x1D5BF, 'M', 'f'),
    +    (0x1D5C0, 'M', 'g'),
    +    (0x1D5C1, 'M', 'h'),
    +    (0x1D5C2, 'M', 'i'),
    +    (0x1D5C3, 'M', 'j'),
    +    (0x1D5C4, 'M', 'k'),
    +    (0x1D5C5, 'M', 'l'),
    +    (0x1D5C6, 'M', 'm'),
    +    (0x1D5C7, 'M', 'n'),
    +    (0x1D5C8, 'M', 'o'),
    +    (0x1D5C9, 'M', 'p'),
    +    (0x1D5CA, 'M', 'q'),
    +    (0x1D5CB, 'M', 'r'),
    +    (0x1D5CC, 'M', 's'),
    +    (0x1D5CD, 'M', 't'),
    +    (0x1D5CE, 'M', 'u'),
    +    (0x1D5CF, 'M', 'v'),
    +    (0x1D5D0, 'M', 'w'),
    +    (0x1D5D1, 'M', 'x'),
    +    (0x1D5D2, 'M', 'y'),
    +    (0x1D5D3, 'M', 'z'),
    +    (0x1D5D4, 'M', 'a'),
    +    (0x1D5D5, 'M', 'b'),
    +    (0x1D5D6, 'M', 'c'),
    +    (0x1D5D7, 'M', 'd'),
    +    (0x1D5D8, 'M', 'e'),
    +    (0x1D5D9, 'M', 'f'),
    +    (0x1D5DA, 'M', 'g'),
    +    (0x1D5DB, 'M', 'h'),
    +    (0x1D5DC, 'M', 'i'),
    +    (0x1D5DD, 'M', 'j'),
    +    (0x1D5DE, 'M', 'k'),
    +    (0x1D5DF, 'M', 'l'),
    +    (0x1D5E0, 'M', 'm'),
    +    (0x1D5E1, 'M', 'n'),
    +    (0x1D5E2, 'M', 'o'),
    +    (0x1D5E3, 'M', 'p'),
    +    (0x1D5E4, 'M', 'q'),
    +    (0x1D5E5, 'M', 'r'),
    +    (0x1D5E6, 'M', 's'),
    +    (0x1D5E7, 'M', 't'),
    +    (0x1D5E8, 'M', 'u'),
    +    (0x1D5E9, 'M', 'v'),
    +    (0x1D5EA, 'M', 'w'),
    +    (0x1D5EB, 'M', 'x'),
    +    (0x1D5EC, 'M', 'y'),
    +    (0x1D5ED, 'M', 'z'),
    +    (0x1D5EE, 'M', 'a'),
    +    (0x1D5EF, 'M', 'b'),
    +    (0x1D5F0, 'M', 'c'),
    +    (0x1D5F1, 'M', 'd'),
    +    (0x1D5F2, 'M', 'e'),
    +    (0x1D5F3, 'M', 'f'),
    +    (0x1D5F4, 'M', 'g'),
    +    (0x1D5F5, 'M', 'h'),
    +    (0x1D5F6, 'M', 'i'),
    +    (0x1D5F7, 'M', 'j'),
    +    (0x1D5F8, 'M', 'k'),
    +    (0x1D5F9, 'M', 'l'),
    +    (0x1D5FA, 'M', 'm'),
    +    (0x1D5FB, 'M', 'n'),
    +    (0x1D5FC, 'M', 'o'),
    +    (0x1D5FD, 'M', 'p'),
    +    (0x1D5FE, 'M', 'q'),
    +    (0x1D5FF, 'M', 'r'),
    +    (0x1D600, 'M', 's'),
    +    (0x1D601, 'M', 't'),
    +    (0x1D602, 'M', 'u'),
    +    (0x1D603, 'M', 'v'),
    +    (0x1D604, 'M', 'w'),
    +    (0x1D605, 'M', 'x'),
    +    (0x1D606, 'M', 'y'),
    +    (0x1D607, 'M', 'z'),
    +    (0x1D608, 'M', 'a'),
    +    (0x1D609, 'M', 'b'),
    +    (0x1D60A, 'M', 'c'),
    +    (0x1D60B, 'M', 'd'),
    +    (0x1D60C, 'M', 'e'),
    +    (0x1D60D, 'M', 'f'),
    +    (0x1D60E, 'M', 'g'),
    +    (0x1D60F, 'M', 'h'),
    +    (0x1D610, 'M', 'i'),
    +    (0x1D611, 'M', 'j'),
    +    (0x1D612, 'M', 'k'),
    +    (0x1D613, 'M', 'l'),
    +    (0x1D614, 'M', 'm'),
    +    (0x1D615, 'M', 'n'),
    +    (0x1D616, 'M', 'o'),
    +    (0x1D617, 'M', 'p'),
    +    (0x1D618, 'M', 'q'),
    +    (0x1D619, 'M', 'r'),
    +    (0x1D61A, 'M', 's'),
    +    ]
    +
    +def _seg_66() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1D61B, 'M', 't'),
    +    (0x1D61C, 'M', 'u'),
    +    (0x1D61D, 'M', 'v'),
    +    (0x1D61E, 'M', 'w'),
    +    (0x1D61F, 'M', 'x'),
    +    (0x1D620, 'M', 'y'),
    +    (0x1D621, 'M', 'z'),
    +    (0x1D622, 'M', 'a'),
    +    (0x1D623, 'M', 'b'),
    +    (0x1D624, 'M', 'c'),
    +    (0x1D625, 'M', 'd'),
    +    (0x1D626, 'M', 'e'),
    +    (0x1D627, 'M', 'f'),
    +    (0x1D628, 'M', 'g'),
    +    (0x1D629, 'M', 'h'),
    +    (0x1D62A, 'M', 'i'),
    +    (0x1D62B, 'M', 'j'),
    +    (0x1D62C, 'M', 'k'),
    +    (0x1D62D, 'M', 'l'),
    +    (0x1D62E, 'M', 'm'),
    +    (0x1D62F, 'M', 'n'),
    +    (0x1D630, 'M', 'o'),
    +    (0x1D631, 'M', 'p'),
    +    (0x1D632, 'M', 'q'),
    +    (0x1D633, 'M', 'r'),
    +    (0x1D634, 'M', 's'),
    +    (0x1D635, 'M', 't'),
    +    (0x1D636, 'M', 'u'),
    +    (0x1D637, 'M', 'v'),
    +    (0x1D638, 'M', 'w'),
    +    (0x1D639, 'M', 'x'),
    +    (0x1D63A, 'M', 'y'),
    +    (0x1D63B, 'M', 'z'),
    +    (0x1D63C, 'M', 'a'),
    +    (0x1D63D, 'M', 'b'),
    +    (0x1D63E, 'M', 'c'),
    +    (0x1D63F, 'M', 'd'),
    +    (0x1D640, 'M', 'e'),
    +    (0x1D641, 'M', 'f'),
    +    (0x1D642, 'M', 'g'),
    +    (0x1D643, 'M', 'h'),
    +    (0x1D644, 'M', 'i'),
    +    (0x1D645, 'M', 'j'),
    +    (0x1D646, 'M', 'k'),
    +    (0x1D647, 'M', 'l'),
    +    (0x1D648, 'M', 'm'),
    +    (0x1D649, 'M', 'n'),
    +    (0x1D64A, 'M', 'o'),
    +    (0x1D64B, 'M', 'p'),
    +    (0x1D64C, 'M', 'q'),
    +    (0x1D64D, 'M', 'r'),
    +    (0x1D64E, 'M', 's'),
    +    (0x1D64F, 'M', 't'),
    +    (0x1D650, 'M', 'u'),
    +    (0x1D651, 'M', 'v'),
    +    (0x1D652, 'M', 'w'),
    +    (0x1D653, 'M', 'x'),
    +    (0x1D654, 'M', 'y'),
    +    (0x1D655, 'M', 'z'),
    +    (0x1D656, 'M', 'a'),
    +    (0x1D657, 'M', 'b'),
    +    (0x1D658, 'M', 'c'),
    +    (0x1D659, 'M', 'd'),
    +    (0x1D65A, 'M', 'e'),
    +    (0x1D65B, 'M', 'f'),
    +    (0x1D65C, 'M', 'g'),
    +    (0x1D65D, 'M', 'h'),
    +    (0x1D65E, 'M', 'i'),
    +    (0x1D65F, 'M', 'j'),
    +    (0x1D660, 'M', 'k'),
    +    (0x1D661, 'M', 'l'),
    +    (0x1D662, 'M', 'm'),
    +    (0x1D663, 'M', 'n'),
    +    (0x1D664, 'M', 'o'),
    +    (0x1D665, 'M', 'p'),
    +    (0x1D666, 'M', 'q'),
    +    (0x1D667, 'M', 'r'),
    +    (0x1D668, 'M', 's'),
    +    (0x1D669, 'M', 't'),
    +    (0x1D66A, 'M', 'u'),
    +    (0x1D66B, 'M', 'v'),
    +    (0x1D66C, 'M', 'w'),
    +    (0x1D66D, 'M', 'x'),
    +    (0x1D66E, 'M', 'y'),
    +    (0x1D66F, 'M', 'z'),
    +    (0x1D670, 'M', 'a'),
    +    (0x1D671, 'M', 'b'),
    +    (0x1D672, 'M', 'c'),
    +    (0x1D673, 'M', 'd'),
    +    (0x1D674, 'M', 'e'),
    +    (0x1D675, 'M', 'f'),
    +    (0x1D676, 'M', 'g'),
    +    (0x1D677, 'M', 'h'),
    +    (0x1D678, 'M', 'i'),
    +    (0x1D679, 'M', 'j'),
    +    (0x1D67A, 'M', 'k'),
    +    (0x1D67B, 'M', 'l'),
    +    (0x1D67C, 'M', 'm'),
    +    (0x1D67D, 'M', 'n'),
    +    (0x1D67E, 'M', 'o'),
    +    ]
    +
    +def _seg_67() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1D67F, 'M', 'p'),
    +    (0x1D680, 'M', 'q'),
    +    (0x1D681, 'M', 'r'),
    +    (0x1D682, 'M', 's'),
    +    (0x1D683, 'M', 't'),
    +    (0x1D684, 'M', 'u'),
    +    (0x1D685, 'M', 'v'),
    +    (0x1D686, 'M', 'w'),
    +    (0x1D687, 'M', 'x'),
    +    (0x1D688, 'M', 'y'),
    +    (0x1D689, 'M', 'z'),
    +    (0x1D68A, 'M', 'a'),
    +    (0x1D68B, 'M', 'b'),
    +    (0x1D68C, 'M', 'c'),
    +    (0x1D68D, 'M', 'd'),
    +    (0x1D68E, 'M', 'e'),
    +    (0x1D68F, 'M', 'f'),
    +    (0x1D690, 'M', 'g'),
    +    (0x1D691, 'M', 'h'),
    +    (0x1D692, 'M', 'i'),
    +    (0x1D693, 'M', 'j'),
    +    (0x1D694, 'M', 'k'),
    +    (0x1D695, 'M', 'l'),
    +    (0x1D696, 'M', 'm'),
    +    (0x1D697, 'M', 'n'),
    +    (0x1D698, 'M', 'o'),
    +    (0x1D699, 'M', 'p'),
    +    (0x1D69A, 'M', 'q'),
    +    (0x1D69B, 'M', 'r'),
    +    (0x1D69C, 'M', 's'),
    +    (0x1D69D, 'M', 't'),
    +    (0x1D69E, 'M', 'u'),
    +    (0x1D69F, 'M', 'v'),
    +    (0x1D6A0, 'M', 'w'),
    +    (0x1D6A1, 'M', 'x'),
    +    (0x1D6A2, 'M', 'y'),
    +    (0x1D6A3, 'M', 'z'),
    +    (0x1D6A4, 'M', 'ı'),
    +    (0x1D6A5, 'M', 'ȷ'),
    +    (0x1D6A6, 'X'),
    +    (0x1D6A8, 'M', 'α'),
    +    (0x1D6A9, 'M', 'β'),
    +    (0x1D6AA, 'M', 'γ'),
    +    (0x1D6AB, 'M', 'δ'),
    +    (0x1D6AC, 'M', 'ε'),
    +    (0x1D6AD, 'M', 'ζ'),
    +    (0x1D6AE, 'M', 'η'),
    +    (0x1D6AF, 'M', 'θ'),
    +    (0x1D6B0, 'M', 'ι'),
    +    (0x1D6B1, 'M', 'κ'),
    +    (0x1D6B2, 'M', 'λ'),
    +    (0x1D6B3, 'M', 'μ'),
    +    (0x1D6B4, 'M', 'ν'),
    +    (0x1D6B5, 'M', 'ξ'),
    +    (0x1D6B6, 'M', 'ο'),
    +    (0x1D6B7, 'M', 'π'),
    +    (0x1D6B8, 'M', 'ρ'),
    +    (0x1D6B9, 'M', 'θ'),
    +    (0x1D6BA, 'M', 'σ'),
    +    (0x1D6BB, 'M', 'τ'),
    +    (0x1D6BC, 'M', 'υ'),
    +    (0x1D6BD, 'M', 'φ'),
    +    (0x1D6BE, 'M', 'χ'),
    +    (0x1D6BF, 'M', 'ψ'),
    +    (0x1D6C0, 'M', 'ω'),
    +    (0x1D6C1, 'M', '∇'),
    +    (0x1D6C2, 'M', 'α'),
    +    (0x1D6C3, 'M', 'β'),
    +    (0x1D6C4, 'M', 'γ'),
    +    (0x1D6C5, 'M', 'δ'),
    +    (0x1D6C6, 'M', 'ε'),
    +    (0x1D6C7, 'M', 'ζ'),
    +    (0x1D6C8, 'M', 'η'),
    +    (0x1D6C9, 'M', 'θ'),
    +    (0x1D6CA, 'M', 'ι'),
    +    (0x1D6CB, 'M', 'κ'),
    +    (0x1D6CC, 'M', 'λ'),
    +    (0x1D6CD, 'M', 'μ'),
    +    (0x1D6CE, 'M', 'ν'),
    +    (0x1D6CF, 'M', 'ξ'),
    +    (0x1D6D0, 'M', 'ο'),
    +    (0x1D6D1, 'M', 'π'),
    +    (0x1D6D2, 'M', 'ρ'),
    +    (0x1D6D3, 'M', 'σ'),
    +    (0x1D6D5, 'M', 'τ'),
    +    (0x1D6D6, 'M', 'υ'),
    +    (0x1D6D7, 'M', 'φ'),
    +    (0x1D6D8, 'M', 'χ'),
    +    (0x1D6D9, 'M', 'ψ'),
    +    (0x1D6DA, 'M', 'ω'),
    +    (0x1D6DB, 'M', '∂'),
    +    (0x1D6DC, 'M', 'ε'),
    +    (0x1D6DD, 'M', 'θ'),
    +    (0x1D6DE, 'M', 'κ'),
    +    (0x1D6DF, 'M', 'φ'),
    +    (0x1D6E0, 'M', 'ρ'),
    +    (0x1D6E1, 'M', 'π'),
    +    (0x1D6E2, 'M', 'α'),
    +    (0x1D6E3, 'M', 'β'),
    +    (0x1D6E4, 'M', 'γ'),
    +    ]
    +
    +def _seg_68() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1D6E5, 'M', 'δ'),
    +    (0x1D6E6, 'M', 'ε'),
    +    (0x1D6E7, 'M', 'ζ'),
    +    (0x1D6E8, 'M', 'η'),
    +    (0x1D6E9, 'M', 'θ'),
    +    (0x1D6EA, 'M', 'ι'),
    +    (0x1D6EB, 'M', 'κ'),
    +    (0x1D6EC, 'M', 'λ'),
    +    (0x1D6ED, 'M', 'μ'),
    +    (0x1D6EE, 'M', 'ν'),
    +    (0x1D6EF, 'M', 'ξ'),
    +    (0x1D6F0, 'M', 'ο'),
    +    (0x1D6F1, 'M', 'π'),
    +    (0x1D6F2, 'M', 'ρ'),
    +    (0x1D6F3, 'M', 'θ'),
    +    (0x1D6F4, 'M', 'σ'),
    +    (0x1D6F5, 'M', 'τ'),
    +    (0x1D6F6, 'M', 'υ'),
    +    (0x1D6F7, 'M', 'φ'),
    +    (0x1D6F8, 'M', 'χ'),
    +    (0x1D6F9, 'M', 'ψ'),
    +    (0x1D6FA, 'M', 'ω'),
    +    (0x1D6FB, 'M', '∇'),
    +    (0x1D6FC, 'M', 'α'),
    +    (0x1D6FD, 'M', 'β'),
    +    (0x1D6FE, 'M', 'γ'),
    +    (0x1D6FF, 'M', 'δ'),
    +    (0x1D700, 'M', 'ε'),
    +    (0x1D701, 'M', 'ζ'),
    +    (0x1D702, 'M', 'η'),
    +    (0x1D703, 'M', 'θ'),
    +    (0x1D704, 'M', 'ι'),
    +    (0x1D705, 'M', 'κ'),
    +    (0x1D706, 'M', 'λ'),
    +    (0x1D707, 'M', 'μ'),
    +    (0x1D708, 'M', 'ν'),
    +    (0x1D709, 'M', 'ξ'),
    +    (0x1D70A, 'M', 'ο'),
    +    (0x1D70B, 'M', 'π'),
    +    (0x1D70C, 'M', 'ρ'),
    +    (0x1D70D, 'M', 'σ'),
    +    (0x1D70F, 'M', 'τ'),
    +    (0x1D710, 'M', 'υ'),
    +    (0x1D711, 'M', 'φ'),
    +    (0x1D712, 'M', 'χ'),
    +    (0x1D713, 'M', 'ψ'),
    +    (0x1D714, 'M', 'ω'),
    +    (0x1D715, 'M', '∂'),
    +    (0x1D716, 'M', 'ε'),
    +    (0x1D717, 'M', 'θ'),
    +    (0x1D718, 'M', 'κ'),
    +    (0x1D719, 'M', 'φ'),
    +    (0x1D71A, 'M', 'ρ'),
    +    (0x1D71B, 'M', 'π'),
    +    (0x1D71C, 'M', 'α'),
    +    (0x1D71D, 'M', 'β'),
    +    (0x1D71E, 'M', 'γ'),
    +    (0x1D71F, 'M', 'δ'),
    +    (0x1D720, 'M', 'ε'),
    +    (0x1D721, 'M', 'ζ'),
    +    (0x1D722, 'M', 'η'),
    +    (0x1D723, 'M', 'θ'),
    +    (0x1D724, 'M', 'ι'),
    +    (0x1D725, 'M', 'κ'),
    +    (0x1D726, 'M', 'λ'),
    +    (0x1D727, 'M', 'μ'),
    +    (0x1D728, 'M', 'ν'),
    +    (0x1D729, 'M', 'ξ'),
    +    (0x1D72A, 'M', 'ο'),
    +    (0x1D72B, 'M', 'π'),
    +    (0x1D72C, 'M', 'ρ'),
    +    (0x1D72D, 'M', 'θ'),
    +    (0x1D72E, 'M', 'σ'),
    +    (0x1D72F, 'M', 'τ'),
    +    (0x1D730, 'M', 'υ'),
    +    (0x1D731, 'M', 'φ'),
    +    (0x1D732, 'M', 'χ'),
    +    (0x1D733, 'M', 'ψ'),
    +    (0x1D734, 'M', 'ω'),
    +    (0x1D735, 'M', '∇'),
    +    (0x1D736, 'M', 'α'),
    +    (0x1D737, 'M', 'β'),
    +    (0x1D738, 'M', 'γ'),
    +    (0x1D739, 'M', 'δ'),
    +    (0x1D73A, 'M', 'ε'),
    +    (0x1D73B, 'M', 'ζ'),
    +    (0x1D73C, 'M', 'η'),
    +    (0x1D73D, 'M', 'θ'),
    +    (0x1D73E, 'M', 'ι'),
    +    (0x1D73F, 'M', 'κ'),
    +    (0x1D740, 'M', 'λ'),
    +    (0x1D741, 'M', 'μ'),
    +    (0x1D742, 'M', 'ν'),
    +    (0x1D743, 'M', 'ξ'),
    +    (0x1D744, 'M', 'ο'),
    +    (0x1D745, 'M', 'π'),
    +    (0x1D746, 'M', 'ρ'),
    +    (0x1D747, 'M', 'σ'),
    +    (0x1D749, 'M', 'τ'),
    +    (0x1D74A, 'M', 'υ'),
    +    ]
    +
    +def _seg_69() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1D74B, 'M', 'φ'),
    +    (0x1D74C, 'M', 'χ'),
    +    (0x1D74D, 'M', 'ψ'),
    +    (0x1D74E, 'M', 'ω'),
    +    (0x1D74F, 'M', '∂'),
    +    (0x1D750, 'M', 'ε'),
    +    (0x1D751, 'M', 'θ'),
    +    (0x1D752, 'M', 'κ'),
    +    (0x1D753, 'M', 'φ'),
    +    (0x1D754, 'M', 'ρ'),
    +    (0x1D755, 'M', 'π'),
    +    (0x1D756, 'M', 'α'),
    +    (0x1D757, 'M', 'β'),
    +    (0x1D758, 'M', 'γ'),
    +    (0x1D759, 'M', 'δ'),
    +    (0x1D75A, 'M', 'ε'),
    +    (0x1D75B, 'M', 'ζ'),
    +    (0x1D75C, 'M', 'η'),
    +    (0x1D75D, 'M', 'θ'),
    +    (0x1D75E, 'M', 'ι'),
    +    (0x1D75F, 'M', 'κ'),
    +    (0x1D760, 'M', 'λ'),
    +    (0x1D761, 'M', 'μ'),
    +    (0x1D762, 'M', 'ν'),
    +    (0x1D763, 'M', 'ξ'),
    +    (0x1D764, 'M', 'ο'),
    +    (0x1D765, 'M', 'π'),
    +    (0x1D766, 'M', 'ρ'),
    +    (0x1D767, 'M', 'θ'),
    +    (0x1D768, 'M', 'σ'),
    +    (0x1D769, 'M', 'τ'),
    +    (0x1D76A, 'M', 'υ'),
    +    (0x1D76B, 'M', 'φ'),
    +    (0x1D76C, 'M', 'χ'),
    +    (0x1D76D, 'M', 'ψ'),
    +    (0x1D76E, 'M', 'ω'),
    +    (0x1D76F, 'M', '∇'),
    +    (0x1D770, 'M', 'α'),
    +    (0x1D771, 'M', 'β'),
    +    (0x1D772, 'M', 'γ'),
    +    (0x1D773, 'M', 'δ'),
    +    (0x1D774, 'M', 'ε'),
    +    (0x1D775, 'M', 'ζ'),
    +    (0x1D776, 'M', 'η'),
    +    (0x1D777, 'M', 'θ'),
    +    (0x1D778, 'M', 'ι'),
    +    (0x1D779, 'M', 'κ'),
    +    (0x1D77A, 'M', 'λ'),
    +    (0x1D77B, 'M', 'μ'),
    +    (0x1D77C, 'M', 'ν'),
    +    (0x1D77D, 'M', 'ξ'),
    +    (0x1D77E, 'M', 'ο'),
    +    (0x1D77F, 'M', 'π'),
    +    (0x1D780, 'M', 'ρ'),
    +    (0x1D781, 'M', 'σ'),
    +    (0x1D783, 'M', 'τ'),
    +    (0x1D784, 'M', 'υ'),
    +    (0x1D785, 'M', 'φ'),
    +    (0x1D786, 'M', 'χ'),
    +    (0x1D787, 'M', 'ψ'),
    +    (0x1D788, 'M', 'ω'),
    +    (0x1D789, 'M', '∂'),
    +    (0x1D78A, 'M', 'ε'),
    +    (0x1D78B, 'M', 'θ'),
    +    (0x1D78C, 'M', 'κ'),
    +    (0x1D78D, 'M', 'φ'),
    +    (0x1D78E, 'M', 'ρ'),
    +    (0x1D78F, 'M', 'π'),
    +    (0x1D790, 'M', 'α'),
    +    (0x1D791, 'M', 'β'),
    +    (0x1D792, 'M', 'γ'),
    +    (0x1D793, 'M', 'δ'),
    +    (0x1D794, 'M', 'ε'),
    +    (0x1D795, 'M', 'ζ'),
    +    (0x1D796, 'M', 'η'),
    +    (0x1D797, 'M', 'θ'),
    +    (0x1D798, 'M', 'ι'),
    +    (0x1D799, 'M', 'κ'),
    +    (0x1D79A, 'M', 'λ'),
    +    (0x1D79B, 'M', 'μ'),
    +    (0x1D79C, 'M', 'ν'),
    +    (0x1D79D, 'M', 'ξ'),
    +    (0x1D79E, 'M', 'ο'),
    +    (0x1D79F, 'M', 'π'),
    +    (0x1D7A0, 'M', 'ρ'),
    +    (0x1D7A1, 'M', 'θ'),
    +    (0x1D7A2, 'M', 'σ'),
    +    (0x1D7A3, 'M', 'τ'),
    +    (0x1D7A4, 'M', 'υ'),
    +    (0x1D7A5, 'M', 'φ'),
    +    (0x1D7A6, 'M', 'χ'),
    +    (0x1D7A7, 'M', 'ψ'),
    +    (0x1D7A8, 'M', 'ω'),
    +    (0x1D7A9, 'M', '∇'),
    +    (0x1D7AA, 'M', 'α'),
    +    (0x1D7AB, 'M', 'β'),
    +    (0x1D7AC, 'M', 'γ'),
    +    (0x1D7AD, 'M', 'δ'),
    +    (0x1D7AE, 'M', 'ε'),
    +    (0x1D7AF, 'M', 'ζ'),
    +    ]
    +
    +def _seg_70() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1D7B0, 'M', 'η'),
    +    (0x1D7B1, 'M', 'θ'),
    +    (0x1D7B2, 'M', 'ι'),
    +    (0x1D7B3, 'M', 'κ'),
    +    (0x1D7B4, 'M', 'λ'),
    +    (0x1D7B5, 'M', 'μ'),
    +    (0x1D7B6, 'M', 'ν'),
    +    (0x1D7B7, 'M', 'ξ'),
    +    (0x1D7B8, 'M', 'ο'),
    +    (0x1D7B9, 'M', 'π'),
    +    (0x1D7BA, 'M', 'ρ'),
    +    (0x1D7BB, 'M', 'σ'),
    +    (0x1D7BD, 'M', 'τ'),
    +    (0x1D7BE, 'M', 'υ'),
    +    (0x1D7BF, 'M', 'φ'),
    +    (0x1D7C0, 'M', 'χ'),
    +    (0x1D7C1, 'M', 'ψ'),
    +    (0x1D7C2, 'M', 'ω'),
    +    (0x1D7C3, 'M', '∂'),
    +    (0x1D7C4, 'M', 'ε'),
    +    (0x1D7C5, 'M', 'θ'),
    +    (0x1D7C6, 'M', 'κ'),
    +    (0x1D7C7, 'M', 'φ'),
    +    (0x1D7C8, 'M', 'ρ'),
    +    (0x1D7C9, 'M', 'π'),
    +    (0x1D7CA, 'M', 'ϝ'),
    +    (0x1D7CC, 'X'),
    +    (0x1D7CE, 'M', '0'),
    +    (0x1D7CF, 'M', '1'),
    +    (0x1D7D0, 'M', '2'),
    +    (0x1D7D1, 'M', '3'),
    +    (0x1D7D2, 'M', '4'),
    +    (0x1D7D3, 'M', '5'),
    +    (0x1D7D4, 'M', '6'),
    +    (0x1D7D5, 'M', '7'),
    +    (0x1D7D6, 'M', '8'),
    +    (0x1D7D7, 'M', '9'),
    +    (0x1D7D8, 'M', '0'),
    +    (0x1D7D9, 'M', '1'),
    +    (0x1D7DA, 'M', '2'),
    +    (0x1D7DB, 'M', '3'),
    +    (0x1D7DC, 'M', '4'),
    +    (0x1D7DD, 'M', '5'),
    +    (0x1D7DE, 'M', '6'),
    +    (0x1D7DF, 'M', '7'),
    +    (0x1D7E0, 'M', '8'),
    +    (0x1D7E1, 'M', '9'),
    +    (0x1D7E2, 'M', '0'),
    +    (0x1D7E3, 'M', '1'),
    +    (0x1D7E4, 'M', '2'),
    +    (0x1D7E5, 'M', '3'),
    +    (0x1D7E6, 'M', '4'),
    +    (0x1D7E7, 'M', '5'),
    +    (0x1D7E8, 'M', '6'),
    +    (0x1D7E9, 'M', '7'),
    +    (0x1D7EA, 'M', '8'),
    +    (0x1D7EB, 'M', '9'),
    +    (0x1D7EC, 'M', '0'),
    +    (0x1D7ED, 'M', '1'),
    +    (0x1D7EE, 'M', '2'),
    +    (0x1D7EF, 'M', '3'),
    +    (0x1D7F0, 'M', '4'),
    +    (0x1D7F1, 'M', '5'),
    +    (0x1D7F2, 'M', '6'),
    +    (0x1D7F3, 'M', '7'),
    +    (0x1D7F4, 'M', '8'),
    +    (0x1D7F5, 'M', '9'),
    +    (0x1D7F6, 'M', '0'),
    +    (0x1D7F7, 'M', '1'),
    +    (0x1D7F8, 'M', '2'),
    +    (0x1D7F9, 'M', '3'),
    +    (0x1D7FA, 'M', '4'),
    +    (0x1D7FB, 'M', '5'),
    +    (0x1D7FC, 'M', '6'),
    +    (0x1D7FD, 'M', '7'),
    +    (0x1D7FE, 'M', '8'),
    +    (0x1D7FF, 'M', '9'),
    +    (0x1D800, 'V'),
    +    (0x1DA8C, 'X'),
    +    (0x1DA9B, 'V'),
    +    (0x1DAA0, 'X'),
    +    (0x1DAA1, 'V'),
    +    (0x1DAB0, 'X'),
    +    (0x1DF00, 'V'),
    +    (0x1DF1F, 'X'),
    +    (0x1DF25, 'V'),
    +    (0x1DF2B, 'X'),
    +    (0x1E000, 'V'),
    +    (0x1E007, 'X'),
    +    (0x1E008, 'V'),
    +    (0x1E019, 'X'),
    +    (0x1E01B, 'V'),
    +    (0x1E022, 'X'),
    +    (0x1E023, 'V'),
    +    (0x1E025, 'X'),
    +    (0x1E026, 'V'),
    +    (0x1E02B, 'X'),
    +    (0x1E030, 'M', 'а'),
    +    (0x1E031, 'M', 'б'),
    +    (0x1E032, 'M', 'в'),
    +    ]
    +
    +def _seg_71() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1E033, 'M', 'г'),
    +    (0x1E034, 'M', 'д'),
    +    (0x1E035, 'M', 'е'),
    +    (0x1E036, 'M', 'ж'),
    +    (0x1E037, 'M', 'з'),
    +    (0x1E038, 'M', 'и'),
    +    (0x1E039, 'M', 'к'),
    +    (0x1E03A, 'M', 'л'),
    +    (0x1E03B, 'M', 'м'),
    +    (0x1E03C, 'M', 'о'),
    +    (0x1E03D, 'M', 'п'),
    +    (0x1E03E, 'M', 'р'),
    +    (0x1E03F, 'M', 'с'),
    +    (0x1E040, 'M', 'т'),
    +    (0x1E041, 'M', 'у'),
    +    (0x1E042, 'M', 'ф'),
    +    (0x1E043, 'M', 'х'),
    +    (0x1E044, 'M', 'ц'),
    +    (0x1E045, 'M', 'ч'),
    +    (0x1E046, 'M', 'ш'),
    +    (0x1E047, 'M', 'ы'),
    +    (0x1E048, 'M', 'э'),
    +    (0x1E049, 'M', 'ю'),
    +    (0x1E04A, 'M', 'ꚉ'),
    +    (0x1E04B, 'M', 'ә'),
    +    (0x1E04C, 'M', 'і'),
    +    (0x1E04D, 'M', 'ј'),
    +    (0x1E04E, 'M', 'ө'),
    +    (0x1E04F, 'M', 'ү'),
    +    (0x1E050, 'M', 'ӏ'),
    +    (0x1E051, 'M', 'а'),
    +    (0x1E052, 'M', 'б'),
    +    (0x1E053, 'M', 'в'),
    +    (0x1E054, 'M', 'г'),
    +    (0x1E055, 'M', 'д'),
    +    (0x1E056, 'M', 'е'),
    +    (0x1E057, 'M', 'ж'),
    +    (0x1E058, 'M', 'з'),
    +    (0x1E059, 'M', 'и'),
    +    (0x1E05A, 'M', 'к'),
    +    (0x1E05B, 'M', 'л'),
    +    (0x1E05C, 'M', 'о'),
    +    (0x1E05D, 'M', 'п'),
    +    (0x1E05E, 'M', 'с'),
    +    (0x1E05F, 'M', 'у'),
    +    (0x1E060, 'M', 'ф'),
    +    (0x1E061, 'M', 'х'),
    +    (0x1E062, 'M', 'ц'),
    +    (0x1E063, 'M', 'ч'),
    +    (0x1E064, 'M', 'ш'),
    +    (0x1E065, 'M', 'ъ'),
    +    (0x1E066, 'M', 'ы'),
    +    (0x1E067, 'M', 'ґ'),
    +    (0x1E068, 'M', 'і'),
    +    (0x1E069, 'M', 'ѕ'),
    +    (0x1E06A, 'M', 'џ'),
    +    (0x1E06B, 'M', 'ҫ'),
    +    (0x1E06C, 'M', 'ꙑ'),
    +    (0x1E06D, 'M', 'ұ'),
    +    (0x1E06E, 'X'),
    +    (0x1E08F, 'V'),
    +    (0x1E090, 'X'),
    +    (0x1E100, 'V'),
    +    (0x1E12D, 'X'),
    +    (0x1E130, 'V'),
    +    (0x1E13E, 'X'),
    +    (0x1E140, 'V'),
    +    (0x1E14A, 'X'),
    +    (0x1E14E, 'V'),
    +    (0x1E150, 'X'),
    +    (0x1E290, 'V'),
    +    (0x1E2AF, 'X'),
    +    (0x1E2C0, 'V'),
    +    (0x1E2FA, 'X'),
    +    (0x1E2FF, 'V'),
    +    (0x1E300, 'X'),
    +    (0x1E4D0, 'V'),
    +    (0x1E4FA, 'X'),
    +    (0x1E7E0, 'V'),
    +    (0x1E7E7, 'X'),
    +    (0x1E7E8, 'V'),
    +    (0x1E7EC, 'X'),
    +    (0x1E7ED, 'V'),
    +    (0x1E7EF, 'X'),
    +    (0x1E7F0, 'V'),
    +    (0x1E7FF, 'X'),
    +    (0x1E800, 'V'),
    +    (0x1E8C5, 'X'),
    +    (0x1E8C7, 'V'),
    +    (0x1E8D7, 'X'),
    +    (0x1E900, 'M', '𞤢'),
    +    (0x1E901, 'M', '𞤣'),
    +    (0x1E902, 'M', '𞤤'),
    +    (0x1E903, 'M', '𞤥'),
    +    (0x1E904, 'M', '𞤦'),
    +    (0x1E905, 'M', '𞤧'),
    +    (0x1E906, 'M', '𞤨'),
    +    (0x1E907, 'M', '𞤩'),
    +    (0x1E908, 'M', '𞤪'),
    +    (0x1E909, 'M', '𞤫'),
    +    ]
    +
    +def _seg_72() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1E90A, 'M', '𞤬'),
    +    (0x1E90B, 'M', '𞤭'),
    +    (0x1E90C, 'M', '𞤮'),
    +    (0x1E90D, 'M', '𞤯'),
    +    (0x1E90E, 'M', '𞤰'),
    +    (0x1E90F, 'M', '𞤱'),
    +    (0x1E910, 'M', '𞤲'),
    +    (0x1E911, 'M', '𞤳'),
    +    (0x1E912, 'M', '𞤴'),
    +    (0x1E913, 'M', '𞤵'),
    +    (0x1E914, 'M', '𞤶'),
    +    (0x1E915, 'M', '𞤷'),
    +    (0x1E916, 'M', '𞤸'),
    +    (0x1E917, 'M', '𞤹'),
    +    (0x1E918, 'M', '𞤺'),
    +    (0x1E919, 'M', '𞤻'),
    +    (0x1E91A, 'M', '𞤼'),
    +    (0x1E91B, 'M', '𞤽'),
    +    (0x1E91C, 'M', '𞤾'),
    +    (0x1E91D, 'M', '𞤿'),
    +    (0x1E91E, 'M', '𞥀'),
    +    (0x1E91F, 'M', '𞥁'),
    +    (0x1E920, 'M', '𞥂'),
    +    (0x1E921, 'M', '𞥃'),
    +    (0x1E922, 'V'),
    +    (0x1E94C, 'X'),
    +    (0x1E950, 'V'),
    +    (0x1E95A, 'X'),
    +    (0x1E95E, 'V'),
    +    (0x1E960, 'X'),
    +    (0x1EC71, 'V'),
    +    (0x1ECB5, 'X'),
    +    (0x1ED01, 'V'),
    +    (0x1ED3E, 'X'),
    +    (0x1EE00, 'M', 'ا'),
    +    (0x1EE01, 'M', 'ب'),
    +    (0x1EE02, 'M', 'ج'),
    +    (0x1EE03, 'M', 'د'),
    +    (0x1EE04, 'X'),
    +    (0x1EE05, 'M', 'و'),
    +    (0x1EE06, 'M', 'ز'),
    +    (0x1EE07, 'M', 'ح'),
    +    (0x1EE08, 'M', 'ط'),
    +    (0x1EE09, 'M', 'ي'),
    +    (0x1EE0A, 'M', 'ك'),
    +    (0x1EE0B, 'M', 'ل'),
    +    (0x1EE0C, 'M', 'م'),
    +    (0x1EE0D, 'M', 'ن'),
    +    (0x1EE0E, 'M', 'س'),
    +    (0x1EE0F, 'M', 'ع'),
    +    (0x1EE10, 'M', 'ف'),
    +    (0x1EE11, 'M', 'ص'),
    +    (0x1EE12, 'M', 'ق'),
    +    (0x1EE13, 'M', 'ر'),
    +    (0x1EE14, 'M', 'ش'),
    +    (0x1EE15, 'M', 'ت'),
    +    (0x1EE16, 'M', 'ث'),
    +    (0x1EE17, 'M', 'خ'),
    +    (0x1EE18, 'M', 'ذ'),
    +    (0x1EE19, 'M', 'ض'),
    +    (0x1EE1A, 'M', 'ظ'),
    +    (0x1EE1B, 'M', 'غ'),
    +    (0x1EE1C, 'M', 'ٮ'),
    +    (0x1EE1D, 'M', 'ں'),
    +    (0x1EE1E, 'M', 'ڡ'),
    +    (0x1EE1F, 'M', 'ٯ'),
    +    (0x1EE20, 'X'),
    +    (0x1EE21, 'M', 'ب'),
    +    (0x1EE22, 'M', 'ج'),
    +    (0x1EE23, 'X'),
    +    (0x1EE24, 'M', 'ه'),
    +    (0x1EE25, 'X'),
    +    (0x1EE27, 'M', 'ح'),
    +    (0x1EE28, 'X'),
    +    (0x1EE29, 'M', 'ي'),
    +    (0x1EE2A, 'M', 'ك'),
    +    (0x1EE2B, 'M', 'ل'),
    +    (0x1EE2C, 'M', 'م'),
    +    (0x1EE2D, 'M', 'ن'),
    +    (0x1EE2E, 'M', 'س'),
    +    (0x1EE2F, 'M', 'ع'),
    +    (0x1EE30, 'M', 'ف'),
    +    (0x1EE31, 'M', 'ص'),
    +    (0x1EE32, 'M', 'ق'),
    +    (0x1EE33, 'X'),
    +    (0x1EE34, 'M', 'ش'),
    +    (0x1EE35, 'M', 'ت'),
    +    (0x1EE36, 'M', 'ث'),
    +    (0x1EE37, 'M', 'خ'),
    +    (0x1EE38, 'X'),
    +    (0x1EE39, 'M', 'ض'),
    +    (0x1EE3A, 'X'),
    +    (0x1EE3B, 'M', 'غ'),
    +    (0x1EE3C, 'X'),
    +    (0x1EE42, 'M', 'ج'),
    +    (0x1EE43, 'X'),
    +    (0x1EE47, 'M', 'ح'),
    +    (0x1EE48, 'X'),
    +    (0x1EE49, 'M', 'ي'),
    +    (0x1EE4A, 'X'),
    +    ]
    +
    +def _seg_73() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1EE4B, 'M', 'ل'),
    +    (0x1EE4C, 'X'),
    +    (0x1EE4D, 'M', 'ن'),
    +    (0x1EE4E, 'M', 'س'),
    +    (0x1EE4F, 'M', 'ع'),
    +    (0x1EE50, 'X'),
    +    (0x1EE51, 'M', 'ص'),
    +    (0x1EE52, 'M', 'ق'),
    +    (0x1EE53, 'X'),
    +    (0x1EE54, 'M', 'ش'),
    +    (0x1EE55, 'X'),
    +    (0x1EE57, 'M', 'خ'),
    +    (0x1EE58, 'X'),
    +    (0x1EE59, 'M', 'ض'),
    +    (0x1EE5A, 'X'),
    +    (0x1EE5B, 'M', 'غ'),
    +    (0x1EE5C, 'X'),
    +    (0x1EE5D, 'M', 'ں'),
    +    (0x1EE5E, 'X'),
    +    (0x1EE5F, 'M', 'ٯ'),
    +    (0x1EE60, 'X'),
    +    (0x1EE61, 'M', 'ب'),
    +    (0x1EE62, 'M', 'ج'),
    +    (0x1EE63, 'X'),
    +    (0x1EE64, 'M', 'ه'),
    +    (0x1EE65, 'X'),
    +    (0x1EE67, 'M', 'ح'),
    +    (0x1EE68, 'M', 'ط'),
    +    (0x1EE69, 'M', 'ي'),
    +    (0x1EE6A, 'M', 'ك'),
    +    (0x1EE6B, 'X'),
    +    (0x1EE6C, 'M', 'م'),
    +    (0x1EE6D, 'M', 'ن'),
    +    (0x1EE6E, 'M', 'س'),
    +    (0x1EE6F, 'M', 'ع'),
    +    (0x1EE70, 'M', 'ف'),
    +    (0x1EE71, 'M', 'ص'),
    +    (0x1EE72, 'M', 'ق'),
    +    (0x1EE73, 'X'),
    +    (0x1EE74, 'M', 'ش'),
    +    (0x1EE75, 'M', 'ت'),
    +    (0x1EE76, 'M', 'ث'),
    +    (0x1EE77, 'M', 'خ'),
    +    (0x1EE78, 'X'),
    +    (0x1EE79, 'M', 'ض'),
    +    (0x1EE7A, 'M', 'ظ'),
    +    (0x1EE7B, 'M', 'غ'),
    +    (0x1EE7C, 'M', 'ٮ'),
    +    (0x1EE7D, 'X'),
    +    (0x1EE7E, 'M', 'ڡ'),
    +    (0x1EE7F, 'X'),
    +    (0x1EE80, 'M', 'ا'),
    +    (0x1EE81, 'M', 'ب'),
    +    (0x1EE82, 'M', 'ج'),
    +    (0x1EE83, 'M', 'د'),
    +    (0x1EE84, 'M', 'ه'),
    +    (0x1EE85, 'M', 'و'),
    +    (0x1EE86, 'M', 'ز'),
    +    (0x1EE87, 'M', 'ح'),
    +    (0x1EE88, 'M', 'ط'),
    +    (0x1EE89, 'M', 'ي'),
    +    (0x1EE8A, 'X'),
    +    (0x1EE8B, 'M', 'ل'),
    +    (0x1EE8C, 'M', 'م'),
    +    (0x1EE8D, 'M', 'ن'),
    +    (0x1EE8E, 'M', 'س'),
    +    (0x1EE8F, 'M', 'ع'),
    +    (0x1EE90, 'M', 'ف'),
    +    (0x1EE91, 'M', 'ص'),
    +    (0x1EE92, 'M', 'ق'),
    +    (0x1EE93, 'M', 'ر'),
    +    (0x1EE94, 'M', 'ش'),
    +    (0x1EE95, 'M', 'ت'),
    +    (0x1EE96, 'M', 'ث'),
    +    (0x1EE97, 'M', 'خ'),
    +    (0x1EE98, 'M', 'ذ'),
    +    (0x1EE99, 'M', 'ض'),
    +    (0x1EE9A, 'M', 'ظ'),
    +    (0x1EE9B, 'M', 'غ'),
    +    (0x1EE9C, 'X'),
    +    (0x1EEA1, 'M', 'ب'),
    +    (0x1EEA2, 'M', 'ج'),
    +    (0x1EEA3, 'M', 'د'),
    +    (0x1EEA4, 'X'),
    +    (0x1EEA5, 'M', 'و'),
    +    (0x1EEA6, 'M', 'ز'),
    +    (0x1EEA7, 'M', 'ح'),
    +    (0x1EEA8, 'M', 'ط'),
    +    (0x1EEA9, 'M', 'ي'),
    +    (0x1EEAA, 'X'),
    +    (0x1EEAB, 'M', 'ل'),
    +    (0x1EEAC, 'M', 'م'),
    +    (0x1EEAD, 'M', 'ن'),
    +    (0x1EEAE, 'M', 'س'),
    +    (0x1EEAF, 'M', 'ع'),
    +    (0x1EEB0, 'M', 'ف'),
    +    (0x1EEB1, 'M', 'ص'),
    +    (0x1EEB2, 'M', 'ق'),
    +    (0x1EEB3, 'M', 'ر'),
    +    (0x1EEB4, 'M', 'ش'),
    +    ]
    +
    +def _seg_74() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1EEB5, 'M', 'ت'),
    +    (0x1EEB6, 'M', 'ث'),
    +    (0x1EEB7, 'M', 'خ'),
    +    (0x1EEB8, 'M', 'ذ'),
    +    (0x1EEB9, 'M', 'ض'),
    +    (0x1EEBA, 'M', 'ظ'),
    +    (0x1EEBB, 'M', 'غ'),
    +    (0x1EEBC, 'X'),
    +    (0x1EEF0, 'V'),
    +    (0x1EEF2, 'X'),
    +    (0x1F000, 'V'),
    +    (0x1F02C, 'X'),
    +    (0x1F030, 'V'),
    +    (0x1F094, 'X'),
    +    (0x1F0A0, 'V'),
    +    (0x1F0AF, 'X'),
    +    (0x1F0B1, 'V'),
    +    (0x1F0C0, 'X'),
    +    (0x1F0C1, 'V'),
    +    (0x1F0D0, 'X'),
    +    (0x1F0D1, 'V'),
    +    (0x1F0F6, 'X'),
    +    (0x1F101, '3', '0,'),
    +    (0x1F102, '3', '1,'),
    +    (0x1F103, '3', '2,'),
    +    (0x1F104, '3', '3,'),
    +    (0x1F105, '3', '4,'),
    +    (0x1F106, '3', '5,'),
    +    (0x1F107, '3', '6,'),
    +    (0x1F108, '3', '7,'),
    +    (0x1F109, '3', '8,'),
    +    (0x1F10A, '3', '9,'),
    +    (0x1F10B, 'V'),
    +    (0x1F110, '3', '(a)'),
    +    (0x1F111, '3', '(b)'),
    +    (0x1F112, '3', '(c)'),
    +    (0x1F113, '3', '(d)'),
    +    (0x1F114, '3', '(e)'),
    +    (0x1F115, '3', '(f)'),
    +    (0x1F116, '3', '(g)'),
    +    (0x1F117, '3', '(h)'),
    +    (0x1F118, '3', '(i)'),
    +    (0x1F119, '3', '(j)'),
    +    (0x1F11A, '3', '(k)'),
    +    (0x1F11B, '3', '(l)'),
    +    (0x1F11C, '3', '(m)'),
    +    (0x1F11D, '3', '(n)'),
    +    (0x1F11E, '3', '(o)'),
    +    (0x1F11F, '3', '(p)'),
    +    (0x1F120, '3', '(q)'),
    +    (0x1F121, '3', '(r)'),
    +    (0x1F122, '3', '(s)'),
    +    (0x1F123, '3', '(t)'),
    +    (0x1F124, '3', '(u)'),
    +    (0x1F125, '3', '(v)'),
    +    (0x1F126, '3', '(w)'),
    +    (0x1F127, '3', '(x)'),
    +    (0x1F128, '3', '(y)'),
    +    (0x1F129, '3', '(z)'),
    +    (0x1F12A, 'M', '〔s〕'),
    +    (0x1F12B, 'M', 'c'),
    +    (0x1F12C, 'M', 'r'),
    +    (0x1F12D, 'M', 'cd'),
    +    (0x1F12E, 'M', 'wz'),
    +    (0x1F12F, 'V'),
    +    (0x1F130, 'M', 'a'),
    +    (0x1F131, 'M', 'b'),
    +    (0x1F132, 'M', 'c'),
    +    (0x1F133, 'M', 'd'),
    +    (0x1F134, 'M', 'e'),
    +    (0x1F135, 'M', 'f'),
    +    (0x1F136, 'M', 'g'),
    +    (0x1F137, 'M', 'h'),
    +    (0x1F138, 'M', 'i'),
    +    (0x1F139, 'M', 'j'),
    +    (0x1F13A, 'M', 'k'),
    +    (0x1F13B, 'M', 'l'),
    +    (0x1F13C, 'M', 'm'),
    +    (0x1F13D, 'M', 'n'),
    +    (0x1F13E, 'M', 'o'),
    +    (0x1F13F, 'M', 'p'),
    +    (0x1F140, 'M', 'q'),
    +    (0x1F141, 'M', 'r'),
    +    (0x1F142, 'M', 's'),
    +    (0x1F143, 'M', 't'),
    +    (0x1F144, 'M', 'u'),
    +    (0x1F145, 'M', 'v'),
    +    (0x1F146, 'M', 'w'),
    +    (0x1F147, 'M', 'x'),
    +    (0x1F148, 'M', 'y'),
    +    (0x1F149, 'M', 'z'),
    +    (0x1F14A, 'M', 'hv'),
    +    (0x1F14B, 'M', 'mv'),
    +    (0x1F14C, 'M', 'sd'),
    +    (0x1F14D, 'M', 'ss'),
    +    (0x1F14E, 'M', 'ppv'),
    +    (0x1F14F, 'M', 'wc'),
    +    (0x1F150, 'V'),
    +    (0x1F16A, 'M', 'mc'),
    +    (0x1F16B, 'M', 'md'),
    +    ]
    +
    +def _seg_75() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1F16C, 'M', 'mr'),
    +    (0x1F16D, 'V'),
    +    (0x1F190, 'M', 'dj'),
    +    (0x1F191, 'V'),
    +    (0x1F1AE, 'X'),
    +    (0x1F1E6, 'V'),
    +    (0x1F200, 'M', 'ほか'),
    +    (0x1F201, 'M', 'ココ'),
    +    (0x1F202, 'M', 'サ'),
    +    (0x1F203, 'X'),
    +    (0x1F210, 'M', '手'),
    +    (0x1F211, 'M', '字'),
    +    (0x1F212, 'M', '双'),
    +    (0x1F213, 'M', 'デ'),
    +    (0x1F214, 'M', '二'),
    +    (0x1F215, 'M', '多'),
    +    (0x1F216, 'M', '解'),
    +    (0x1F217, 'M', '天'),
    +    (0x1F218, 'M', '交'),
    +    (0x1F219, 'M', '映'),
    +    (0x1F21A, 'M', '無'),
    +    (0x1F21B, 'M', '料'),
    +    (0x1F21C, 'M', '前'),
    +    (0x1F21D, 'M', '後'),
    +    (0x1F21E, 'M', '再'),
    +    (0x1F21F, 'M', '新'),
    +    (0x1F220, 'M', '初'),
    +    (0x1F221, 'M', '終'),
    +    (0x1F222, 'M', '生'),
    +    (0x1F223, 'M', '販'),
    +    (0x1F224, 'M', '声'),
    +    (0x1F225, 'M', '吹'),
    +    (0x1F226, 'M', '演'),
    +    (0x1F227, 'M', '投'),
    +    (0x1F228, 'M', '捕'),
    +    (0x1F229, 'M', '一'),
    +    (0x1F22A, 'M', '三'),
    +    (0x1F22B, 'M', '遊'),
    +    (0x1F22C, 'M', '左'),
    +    (0x1F22D, 'M', '中'),
    +    (0x1F22E, 'M', '右'),
    +    (0x1F22F, 'M', '指'),
    +    (0x1F230, 'M', '走'),
    +    (0x1F231, 'M', '打'),
    +    (0x1F232, 'M', '禁'),
    +    (0x1F233, 'M', '空'),
    +    (0x1F234, 'M', '合'),
    +    (0x1F235, 'M', '満'),
    +    (0x1F236, 'M', '有'),
    +    (0x1F237, 'M', '月'),
    +    (0x1F238, 'M', '申'),
    +    (0x1F239, 'M', '割'),
    +    (0x1F23A, 'M', '営'),
    +    (0x1F23B, 'M', '配'),
    +    (0x1F23C, 'X'),
    +    (0x1F240, 'M', '〔本〕'),
    +    (0x1F241, 'M', '〔三〕'),
    +    (0x1F242, 'M', '〔二〕'),
    +    (0x1F243, 'M', '〔安〕'),
    +    (0x1F244, 'M', '〔点〕'),
    +    (0x1F245, 'M', '〔打〕'),
    +    (0x1F246, 'M', '〔盗〕'),
    +    (0x1F247, 'M', '〔勝〕'),
    +    (0x1F248, 'M', '〔敗〕'),
    +    (0x1F249, 'X'),
    +    (0x1F250, 'M', '得'),
    +    (0x1F251, 'M', '可'),
    +    (0x1F252, 'X'),
    +    (0x1F260, 'V'),
    +    (0x1F266, 'X'),
    +    (0x1F300, 'V'),
    +    (0x1F6D8, 'X'),
    +    (0x1F6DC, 'V'),
    +    (0x1F6ED, 'X'),
    +    (0x1F6F0, 'V'),
    +    (0x1F6FD, 'X'),
    +    (0x1F700, 'V'),
    +    (0x1F777, 'X'),
    +    (0x1F77B, 'V'),
    +    (0x1F7DA, 'X'),
    +    (0x1F7E0, 'V'),
    +    (0x1F7EC, 'X'),
    +    (0x1F7F0, 'V'),
    +    (0x1F7F1, 'X'),
    +    (0x1F800, 'V'),
    +    (0x1F80C, 'X'),
    +    (0x1F810, 'V'),
    +    (0x1F848, 'X'),
    +    (0x1F850, 'V'),
    +    (0x1F85A, 'X'),
    +    (0x1F860, 'V'),
    +    (0x1F888, 'X'),
    +    (0x1F890, 'V'),
    +    (0x1F8AE, 'X'),
    +    (0x1F8B0, 'V'),
    +    (0x1F8B2, 'X'),
    +    (0x1F900, 'V'),
    +    (0x1FA54, 'X'),
    +    (0x1FA60, 'V'),
    +    (0x1FA6E, 'X'),
    +    ]
    +
    +def _seg_76() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x1FA70, 'V'),
    +    (0x1FA7D, 'X'),
    +    (0x1FA80, 'V'),
    +    (0x1FA89, 'X'),
    +    (0x1FA90, 'V'),
    +    (0x1FABE, 'X'),
    +    (0x1FABF, 'V'),
    +    (0x1FAC6, 'X'),
    +    (0x1FACE, 'V'),
    +    (0x1FADC, 'X'),
    +    (0x1FAE0, 'V'),
    +    (0x1FAE9, 'X'),
    +    (0x1FAF0, 'V'),
    +    (0x1FAF9, 'X'),
    +    (0x1FB00, 'V'),
    +    (0x1FB93, 'X'),
    +    (0x1FB94, 'V'),
    +    (0x1FBCB, 'X'),
    +    (0x1FBF0, 'M', '0'),
    +    (0x1FBF1, 'M', '1'),
    +    (0x1FBF2, 'M', '2'),
    +    (0x1FBF3, 'M', '3'),
    +    (0x1FBF4, 'M', '4'),
    +    (0x1FBF5, 'M', '5'),
    +    (0x1FBF6, 'M', '6'),
    +    (0x1FBF7, 'M', '7'),
    +    (0x1FBF8, 'M', '8'),
    +    (0x1FBF9, 'M', '9'),
    +    (0x1FBFA, 'X'),
    +    (0x20000, 'V'),
    +    (0x2A6E0, 'X'),
    +    (0x2A700, 'V'),
    +    (0x2B73A, 'X'),
    +    (0x2B740, 'V'),
    +    (0x2B81E, 'X'),
    +    (0x2B820, 'V'),
    +    (0x2CEA2, 'X'),
    +    (0x2CEB0, 'V'),
    +    (0x2EBE1, 'X'),
    +    (0x2F800, 'M', '丽'),
    +    (0x2F801, 'M', '丸'),
    +    (0x2F802, 'M', '乁'),
    +    (0x2F803, 'M', '𠄢'),
    +    (0x2F804, 'M', '你'),
    +    (0x2F805, 'M', '侮'),
    +    (0x2F806, 'M', '侻'),
    +    (0x2F807, 'M', '倂'),
    +    (0x2F808, 'M', '偺'),
    +    (0x2F809, 'M', '備'),
    +    (0x2F80A, 'M', '僧'),
    +    (0x2F80B, 'M', '像'),
    +    (0x2F80C, 'M', '㒞'),
    +    (0x2F80D, 'M', '𠘺'),
    +    (0x2F80E, 'M', '免'),
    +    (0x2F80F, 'M', '兔'),
    +    (0x2F810, 'M', '兤'),
    +    (0x2F811, 'M', '具'),
    +    (0x2F812, 'M', '𠔜'),
    +    (0x2F813, 'M', '㒹'),
    +    (0x2F814, 'M', '內'),
    +    (0x2F815, 'M', '再'),
    +    (0x2F816, 'M', '𠕋'),
    +    (0x2F817, 'M', '冗'),
    +    (0x2F818, 'M', '冤'),
    +    (0x2F819, 'M', '仌'),
    +    (0x2F81A, 'M', '冬'),
    +    (0x2F81B, 'M', '况'),
    +    (0x2F81C, 'M', '𩇟'),
    +    (0x2F81D, 'M', '凵'),
    +    (0x2F81E, 'M', '刃'),
    +    (0x2F81F, 'M', '㓟'),
    +    (0x2F820, 'M', '刻'),
    +    (0x2F821, 'M', '剆'),
    +    (0x2F822, 'M', '割'),
    +    (0x2F823, 'M', '剷'),
    +    (0x2F824, 'M', '㔕'),
    +    (0x2F825, 'M', '勇'),
    +    (0x2F826, 'M', '勉'),
    +    (0x2F827, 'M', '勤'),
    +    (0x2F828, 'M', '勺'),
    +    (0x2F829, 'M', '包'),
    +    (0x2F82A, 'M', '匆'),
    +    (0x2F82B, 'M', '北'),
    +    (0x2F82C, 'M', '卉'),
    +    (0x2F82D, 'M', '卑'),
    +    (0x2F82E, 'M', '博'),
    +    (0x2F82F, 'M', '即'),
    +    (0x2F830, 'M', '卽'),
    +    (0x2F831, 'M', '卿'),
    +    (0x2F834, 'M', '𠨬'),
    +    (0x2F835, 'M', '灰'),
    +    (0x2F836, 'M', '及'),
    +    (0x2F837, 'M', '叟'),
    +    (0x2F838, 'M', '𠭣'),
    +    (0x2F839, 'M', '叫'),
    +    (0x2F83A, 'M', '叱'),
    +    (0x2F83B, 'M', '吆'),
    +    (0x2F83C, 'M', '咞'),
    +    (0x2F83D, 'M', '吸'),
    +    (0x2F83E, 'M', '呈'),
    +    ]
    +
    +def _seg_77() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x2F83F, 'M', '周'),
    +    (0x2F840, 'M', '咢'),
    +    (0x2F841, 'M', '哶'),
    +    (0x2F842, 'M', '唐'),
    +    (0x2F843, 'M', '啓'),
    +    (0x2F844, 'M', '啣'),
    +    (0x2F845, 'M', '善'),
    +    (0x2F847, 'M', '喙'),
    +    (0x2F848, 'M', '喫'),
    +    (0x2F849, 'M', '喳'),
    +    (0x2F84A, 'M', '嗂'),
    +    (0x2F84B, 'M', '圖'),
    +    (0x2F84C, 'M', '嘆'),
    +    (0x2F84D, 'M', '圗'),
    +    (0x2F84E, 'M', '噑'),
    +    (0x2F84F, 'M', '噴'),
    +    (0x2F850, 'M', '切'),
    +    (0x2F851, 'M', '壮'),
    +    (0x2F852, 'M', '城'),
    +    (0x2F853, 'M', '埴'),
    +    (0x2F854, 'M', '堍'),
    +    (0x2F855, 'M', '型'),
    +    (0x2F856, 'M', '堲'),
    +    (0x2F857, 'M', '報'),
    +    (0x2F858, 'M', '墬'),
    +    (0x2F859, 'M', '𡓤'),
    +    (0x2F85A, 'M', '売'),
    +    (0x2F85B, 'M', '壷'),
    +    (0x2F85C, 'M', '夆'),
    +    (0x2F85D, 'M', '多'),
    +    (0x2F85E, 'M', '夢'),
    +    (0x2F85F, 'M', '奢'),
    +    (0x2F860, 'M', '𡚨'),
    +    (0x2F861, 'M', '𡛪'),
    +    (0x2F862, 'M', '姬'),
    +    (0x2F863, 'M', '娛'),
    +    (0x2F864, 'M', '娧'),
    +    (0x2F865, 'M', '姘'),
    +    (0x2F866, 'M', '婦'),
    +    (0x2F867, 'M', '㛮'),
    +    (0x2F868, 'X'),
    +    (0x2F869, 'M', '嬈'),
    +    (0x2F86A, 'M', '嬾'),
    +    (0x2F86C, 'M', '𡧈'),
    +    (0x2F86D, 'M', '寃'),
    +    (0x2F86E, 'M', '寘'),
    +    (0x2F86F, 'M', '寧'),
    +    (0x2F870, 'M', '寳'),
    +    (0x2F871, 'M', '𡬘'),
    +    (0x2F872, 'M', '寿'),
    +    (0x2F873, 'M', '将'),
    +    (0x2F874, 'X'),
    +    (0x2F875, 'M', '尢'),
    +    (0x2F876, 'M', '㞁'),
    +    (0x2F877, 'M', '屠'),
    +    (0x2F878, 'M', '屮'),
    +    (0x2F879, 'M', '峀'),
    +    (0x2F87A, 'M', '岍'),
    +    (0x2F87B, 'M', '𡷤'),
    +    (0x2F87C, 'M', '嵃'),
    +    (0x2F87D, 'M', '𡷦'),
    +    (0x2F87E, 'M', '嵮'),
    +    (0x2F87F, 'M', '嵫'),
    +    (0x2F880, 'M', '嵼'),
    +    (0x2F881, 'M', '巡'),
    +    (0x2F882, 'M', '巢'),
    +    (0x2F883, 'M', '㠯'),
    +    (0x2F884, 'M', '巽'),
    +    (0x2F885, 'M', '帨'),
    +    (0x2F886, 'M', '帽'),
    +    (0x2F887, 'M', '幩'),
    +    (0x2F888, 'M', '㡢'),
    +    (0x2F889, 'M', '𢆃'),
    +    (0x2F88A, 'M', '㡼'),
    +    (0x2F88B, 'M', '庰'),
    +    (0x2F88C, 'M', '庳'),
    +    (0x2F88D, 'M', '庶'),
    +    (0x2F88E, 'M', '廊'),
    +    (0x2F88F, 'M', '𪎒'),
    +    (0x2F890, 'M', '廾'),
    +    (0x2F891, 'M', '𢌱'),
    +    (0x2F893, 'M', '舁'),
    +    (0x2F894, 'M', '弢'),
    +    (0x2F896, 'M', '㣇'),
    +    (0x2F897, 'M', '𣊸'),
    +    (0x2F898, 'M', '𦇚'),
    +    (0x2F899, 'M', '形'),
    +    (0x2F89A, 'M', '彫'),
    +    (0x2F89B, 'M', '㣣'),
    +    (0x2F89C, 'M', '徚'),
    +    (0x2F89D, 'M', '忍'),
    +    (0x2F89E, 'M', '志'),
    +    (0x2F89F, 'M', '忹'),
    +    (0x2F8A0, 'M', '悁'),
    +    (0x2F8A1, 'M', '㤺'),
    +    (0x2F8A2, 'M', '㤜'),
    +    (0x2F8A3, 'M', '悔'),
    +    (0x2F8A4, 'M', '𢛔'),
    +    (0x2F8A5, 'M', '惇'),
    +    (0x2F8A6, 'M', '慈'),
    +    ]
    +
    +def _seg_78() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x2F8A7, 'M', '慌'),
    +    (0x2F8A8, 'M', '慎'),
    +    (0x2F8A9, 'M', '慌'),
    +    (0x2F8AA, 'M', '慺'),
    +    (0x2F8AB, 'M', '憎'),
    +    (0x2F8AC, 'M', '憲'),
    +    (0x2F8AD, 'M', '憤'),
    +    (0x2F8AE, 'M', '憯'),
    +    (0x2F8AF, 'M', '懞'),
    +    (0x2F8B0, 'M', '懲'),
    +    (0x2F8B1, 'M', '懶'),
    +    (0x2F8B2, 'M', '成'),
    +    (0x2F8B3, 'M', '戛'),
    +    (0x2F8B4, 'M', '扝'),
    +    (0x2F8B5, 'M', '抱'),
    +    (0x2F8B6, 'M', '拔'),
    +    (0x2F8B7, 'M', '捐'),
    +    (0x2F8B8, 'M', '𢬌'),
    +    (0x2F8B9, 'M', '挽'),
    +    (0x2F8BA, 'M', '拼'),
    +    (0x2F8BB, 'M', '捨'),
    +    (0x2F8BC, 'M', '掃'),
    +    (0x2F8BD, 'M', '揤'),
    +    (0x2F8BE, 'M', '𢯱'),
    +    (0x2F8BF, 'M', '搢'),
    +    (0x2F8C0, 'M', '揅'),
    +    (0x2F8C1, 'M', '掩'),
    +    (0x2F8C2, 'M', '㨮'),
    +    (0x2F8C3, 'M', '摩'),
    +    (0x2F8C4, 'M', '摾'),
    +    (0x2F8C5, 'M', '撝'),
    +    (0x2F8C6, 'M', '摷'),
    +    (0x2F8C7, 'M', '㩬'),
    +    (0x2F8C8, 'M', '敏'),
    +    (0x2F8C9, 'M', '敬'),
    +    (0x2F8CA, 'M', '𣀊'),
    +    (0x2F8CB, 'M', '旣'),
    +    (0x2F8CC, 'M', '書'),
    +    (0x2F8CD, 'M', '晉'),
    +    (0x2F8CE, 'M', '㬙'),
    +    (0x2F8CF, 'M', '暑'),
    +    (0x2F8D0, 'M', '㬈'),
    +    (0x2F8D1, 'M', '㫤'),
    +    (0x2F8D2, 'M', '冒'),
    +    (0x2F8D3, 'M', '冕'),
    +    (0x2F8D4, 'M', '最'),
    +    (0x2F8D5, 'M', '暜'),
    +    (0x2F8D6, 'M', '肭'),
    +    (0x2F8D7, 'M', '䏙'),
    +    (0x2F8D8, 'M', '朗'),
    +    (0x2F8D9, 'M', '望'),
    +    (0x2F8DA, 'M', '朡'),
    +    (0x2F8DB, 'M', '杞'),
    +    (0x2F8DC, 'M', '杓'),
    +    (0x2F8DD, 'M', '𣏃'),
    +    (0x2F8DE, 'M', '㭉'),
    +    (0x2F8DF, 'M', '柺'),
    +    (0x2F8E0, 'M', '枅'),
    +    (0x2F8E1, 'M', '桒'),
    +    (0x2F8E2, 'M', '梅'),
    +    (0x2F8E3, 'M', '𣑭'),
    +    (0x2F8E4, 'M', '梎'),
    +    (0x2F8E5, 'M', '栟'),
    +    (0x2F8E6, 'M', '椔'),
    +    (0x2F8E7, 'M', '㮝'),
    +    (0x2F8E8, 'M', '楂'),
    +    (0x2F8E9, 'M', '榣'),
    +    (0x2F8EA, 'M', '槪'),
    +    (0x2F8EB, 'M', '檨'),
    +    (0x2F8EC, 'M', '𣚣'),
    +    (0x2F8ED, 'M', '櫛'),
    +    (0x2F8EE, 'M', '㰘'),
    +    (0x2F8EF, 'M', '次'),
    +    (0x2F8F0, 'M', '𣢧'),
    +    (0x2F8F1, 'M', '歔'),
    +    (0x2F8F2, 'M', '㱎'),
    +    (0x2F8F3, 'M', '歲'),
    +    (0x2F8F4, 'M', '殟'),
    +    (0x2F8F5, 'M', '殺'),
    +    (0x2F8F6, 'M', '殻'),
    +    (0x2F8F7, 'M', '𣪍'),
    +    (0x2F8F8, 'M', '𡴋'),
    +    (0x2F8F9, 'M', '𣫺'),
    +    (0x2F8FA, 'M', '汎'),
    +    (0x2F8FB, 'M', '𣲼'),
    +    (0x2F8FC, 'M', '沿'),
    +    (0x2F8FD, 'M', '泍'),
    +    (0x2F8FE, 'M', '汧'),
    +    (0x2F8FF, 'M', '洖'),
    +    (0x2F900, 'M', '派'),
    +    (0x2F901, 'M', '海'),
    +    (0x2F902, 'M', '流'),
    +    (0x2F903, 'M', '浩'),
    +    (0x2F904, 'M', '浸'),
    +    (0x2F905, 'M', '涅'),
    +    (0x2F906, 'M', '𣴞'),
    +    (0x2F907, 'M', '洴'),
    +    (0x2F908, 'M', '港'),
    +    (0x2F909, 'M', '湮'),
    +    (0x2F90A, 'M', '㴳'),
    +    ]
    +
    +def _seg_79() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x2F90B, 'M', '滋'),
    +    (0x2F90C, 'M', '滇'),
    +    (0x2F90D, 'M', '𣻑'),
    +    (0x2F90E, 'M', '淹'),
    +    (0x2F90F, 'M', '潮'),
    +    (0x2F910, 'M', '𣽞'),
    +    (0x2F911, 'M', '𣾎'),
    +    (0x2F912, 'M', '濆'),
    +    (0x2F913, 'M', '瀹'),
    +    (0x2F914, 'M', '瀞'),
    +    (0x2F915, 'M', '瀛'),
    +    (0x2F916, 'M', '㶖'),
    +    (0x2F917, 'M', '灊'),
    +    (0x2F918, 'M', '災'),
    +    (0x2F919, 'M', '灷'),
    +    (0x2F91A, 'M', '炭'),
    +    (0x2F91B, 'M', '𠔥'),
    +    (0x2F91C, 'M', '煅'),
    +    (0x2F91D, 'M', '𤉣'),
    +    (0x2F91E, 'M', '熜'),
    +    (0x2F91F, 'X'),
    +    (0x2F920, 'M', '爨'),
    +    (0x2F921, 'M', '爵'),
    +    (0x2F922, 'M', '牐'),
    +    (0x2F923, 'M', '𤘈'),
    +    (0x2F924, 'M', '犀'),
    +    (0x2F925, 'M', '犕'),
    +    (0x2F926, 'M', '𤜵'),
    +    (0x2F927, 'M', '𤠔'),
    +    (0x2F928, 'M', '獺'),
    +    (0x2F929, 'M', '王'),
    +    (0x2F92A, 'M', '㺬'),
    +    (0x2F92B, 'M', '玥'),
    +    (0x2F92C, 'M', '㺸'),
    +    (0x2F92E, 'M', '瑇'),
    +    (0x2F92F, 'M', '瑜'),
    +    (0x2F930, 'M', '瑱'),
    +    (0x2F931, 'M', '璅'),
    +    (0x2F932, 'M', '瓊'),
    +    (0x2F933, 'M', '㼛'),
    +    (0x2F934, 'M', '甤'),
    +    (0x2F935, 'M', '𤰶'),
    +    (0x2F936, 'M', '甾'),
    +    (0x2F937, 'M', '𤲒'),
    +    (0x2F938, 'M', '異'),
    +    (0x2F939, 'M', '𢆟'),
    +    (0x2F93A, 'M', '瘐'),
    +    (0x2F93B, 'M', '𤾡'),
    +    (0x2F93C, 'M', '𤾸'),
    +    (0x2F93D, 'M', '𥁄'),
    +    (0x2F93E, 'M', '㿼'),
    +    (0x2F93F, 'M', '䀈'),
    +    (0x2F940, 'M', '直'),
    +    (0x2F941, 'M', '𥃳'),
    +    (0x2F942, 'M', '𥃲'),
    +    (0x2F943, 'M', '𥄙'),
    +    (0x2F944, 'M', '𥄳'),
    +    (0x2F945, 'M', '眞'),
    +    (0x2F946, 'M', '真'),
    +    (0x2F948, 'M', '睊'),
    +    (0x2F949, 'M', '䀹'),
    +    (0x2F94A, 'M', '瞋'),
    +    (0x2F94B, 'M', '䁆'),
    +    (0x2F94C, 'M', '䂖'),
    +    (0x2F94D, 'M', '𥐝'),
    +    (0x2F94E, 'M', '硎'),
    +    (0x2F94F, 'M', '碌'),
    +    (0x2F950, 'M', '磌'),
    +    (0x2F951, 'M', '䃣'),
    +    (0x2F952, 'M', '𥘦'),
    +    (0x2F953, 'M', '祖'),
    +    (0x2F954, 'M', '𥚚'),
    +    (0x2F955, 'M', '𥛅'),
    +    (0x2F956, 'M', '福'),
    +    (0x2F957, 'M', '秫'),
    +    (0x2F958, 'M', '䄯'),
    +    (0x2F959, 'M', '穀'),
    +    (0x2F95A, 'M', '穊'),
    +    (0x2F95B, 'M', '穏'),
    +    (0x2F95C, 'M', '𥥼'),
    +    (0x2F95D, 'M', '𥪧'),
    +    (0x2F95F, 'X'),
    +    (0x2F960, 'M', '䈂'),
    +    (0x2F961, 'M', '𥮫'),
    +    (0x2F962, 'M', '篆'),
    +    (0x2F963, 'M', '築'),
    +    (0x2F964, 'M', '䈧'),
    +    (0x2F965, 'M', '𥲀'),
    +    (0x2F966, 'M', '糒'),
    +    (0x2F967, 'M', '䊠'),
    +    (0x2F968, 'M', '糨'),
    +    (0x2F969, 'M', '糣'),
    +    (0x2F96A, 'M', '紀'),
    +    (0x2F96B, 'M', '𥾆'),
    +    (0x2F96C, 'M', '絣'),
    +    (0x2F96D, 'M', '䌁'),
    +    (0x2F96E, 'M', '緇'),
    +    (0x2F96F, 'M', '縂'),
    +    (0x2F970, 'M', '繅'),
    +    (0x2F971, 'M', '䌴'),
    +    ]
    +
    +def _seg_80() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x2F972, 'M', '𦈨'),
    +    (0x2F973, 'M', '𦉇'),
    +    (0x2F974, 'M', '䍙'),
    +    (0x2F975, 'M', '𦋙'),
    +    (0x2F976, 'M', '罺'),
    +    (0x2F977, 'M', '𦌾'),
    +    (0x2F978, 'M', '羕'),
    +    (0x2F979, 'M', '翺'),
    +    (0x2F97A, 'M', '者'),
    +    (0x2F97B, 'M', '𦓚'),
    +    (0x2F97C, 'M', '𦔣'),
    +    (0x2F97D, 'M', '聠'),
    +    (0x2F97E, 'M', '𦖨'),
    +    (0x2F97F, 'M', '聰'),
    +    (0x2F980, 'M', '𣍟'),
    +    (0x2F981, 'M', '䏕'),
    +    (0x2F982, 'M', '育'),
    +    (0x2F983, 'M', '脃'),
    +    (0x2F984, 'M', '䐋'),
    +    (0x2F985, 'M', '脾'),
    +    (0x2F986, 'M', '媵'),
    +    (0x2F987, 'M', '𦞧'),
    +    (0x2F988, 'M', '𦞵'),
    +    (0x2F989, 'M', '𣎓'),
    +    (0x2F98A, 'M', '𣎜'),
    +    (0x2F98B, 'M', '舁'),
    +    (0x2F98C, 'M', '舄'),
    +    (0x2F98D, 'M', '辞'),
    +    (0x2F98E, 'M', '䑫'),
    +    (0x2F98F, 'M', '芑'),
    +    (0x2F990, 'M', '芋'),
    +    (0x2F991, 'M', '芝'),
    +    (0x2F992, 'M', '劳'),
    +    (0x2F993, 'M', '花'),
    +    (0x2F994, 'M', '芳'),
    +    (0x2F995, 'M', '芽'),
    +    (0x2F996, 'M', '苦'),
    +    (0x2F997, 'M', '𦬼'),
    +    (0x2F998, 'M', '若'),
    +    (0x2F999, 'M', '茝'),
    +    (0x2F99A, 'M', '荣'),
    +    (0x2F99B, 'M', '莭'),
    +    (0x2F99C, 'M', '茣'),
    +    (0x2F99D, 'M', '莽'),
    +    (0x2F99E, 'M', '菧'),
    +    (0x2F99F, 'M', '著'),
    +    (0x2F9A0, 'M', '荓'),
    +    (0x2F9A1, 'M', '菊'),
    +    (0x2F9A2, 'M', '菌'),
    +    (0x2F9A3, 'M', '菜'),
    +    (0x2F9A4, 'M', '𦰶'),
    +    (0x2F9A5, 'M', '𦵫'),
    +    (0x2F9A6, 'M', '𦳕'),
    +    (0x2F9A7, 'M', '䔫'),
    +    (0x2F9A8, 'M', '蓱'),
    +    (0x2F9A9, 'M', '蓳'),
    +    (0x2F9AA, 'M', '蔖'),
    +    (0x2F9AB, 'M', '𧏊'),
    +    (0x2F9AC, 'M', '蕤'),
    +    (0x2F9AD, 'M', '𦼬'),
    +    (0x2F9AE, 'M', '䕝'),
    +    (0x2F9AF, 'M', '䕡'),
    +    (0x2F9B0, 'M', '𦾱'),
    +    (0x2F9B1, 'M', '𧃒'),
    +    (0x2F9B2, 'M', '䕫'),
    +    (0x2F9B3, 'M', '虐'),
    +    (0x2F9B4, 'M', '虜'),
    +    (0x2F9B5, 'M', '虧'),
    +    (0x2F9B6, 'M', '虩'),
    +    (0x2F9B7, 'M', '蚩'),
    +    (0x2F9B8, 'M', '蚈'),
    +    (0x2F9B9, 'M', '蜎'),
    +    (0x2F9BA, 'M', '蛢'),
    +    (0x2F9BB, 'M', '蝹'),
    +    (0x2F9BC, 'M', '蜨'),
    +    (0x2F9BD, 'M', '蝫'),
    +    (0x2F9BE, 'M', '螆'),
    +    (0x2F9BF, 'X'),
    +    (0x2F9C0, 'M', '蟡'),
    +    (0x2F9C1, 'M', '蠁'),
    +    (0x2F9C2, 'M', '䗹'),
    +    (0x2F9C3, 'M', '衠'),
    +    (0x2F9C4, 'M', '衣'),
    +    (0x2F9C5, 'M', '𧙧'),
    +    (0x2F9C6, 'M', '裗'),
    +    (0x2F9C7, 'M', '裞'),
    +    (0x2F9C8, 'M', '䘵'),
    +    (0x2F9C9, 'M', '裺'),
    +    (0x2F9CA, 'M', '㒻'),
    +    (0x2F9CB, 'M', '𧢮'),
    +    (0x2F9CC, 'M', '𧥦'),
    +    (0x2F9CD, 'M', '䚾'),
    +    (0x2F9CE, 'M', '䛇'),
    +    (0x2F9CF, 'M', '誠'),
    +    (0x2F9D0, 'M', '諭'),
    +    (0x2F9D1, 'M', '變'),
    +    (0x2F9D2, 'M', '豕'),
    +    (0x2F9D3, 'M', '𧲨'),
    +    (0x2F9D4, 'M', '貫'),
    +    (0x2F9D5, 'M', '賁'),
    +    ]
    +
    +def _seg_81() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]:
    +    return [
    +    (0x2F9D6, 'M', '贛'),
    +    (0x2F9D7, 'M', '起'),
    +    (0x2F9D8, 'M', '𧼯'),
    +    (0x2F9D9, 'M', '𠠄'),
    +    (0x2F9DA, 'M', '跋'),
    +    (0x2F9DB, 'M', '趼'),
    +    (0x2F9DC, 'M', '跰'),
    +    (0x2F9DD, 'M', '𠣞'),
    +    (0x2F9DE, 'M', '軔'),
    +    (0x2F9DF, 'M', '輸'),
    +    (0x2F9E0, 'M', '𨗒'),
    +    (0x2F9E1, 'M', '𨗭'),
    +    (0x2F9E2, 'M', '邔'),
    +    (0x2F9E3, 'M', '郱'),
    +    (0x2F9E4, 'M', '鄑'),
    +    (0x2F9E5, 'M', '𨜮'),
    +    (0x2F9E6, 'M', '鄛'),
    +    (0x2F9E7, 'M', '鈸'),
    +    (0x2F9E8, 'M', '鋗'),
    +    (0x2F9E9, 'M', '鋘'),
    +    (0x2F9EA, 'M', '鉼'),
    +    (0x2F9EB, 'M', '鏹'),
    +    (0x2F9EC, 'M', '鐕'),
    +    (0x2F9ED, 'M', '𨯺'),
    +    (0x2F9EE, 'M', '開'),
    +    (0x2F9EF, 'M', '䦕'),
    +    (0x2F9F0, 'M', '閷'),
    +    (0x2F9F1, 'M', '𨵷'),
    +    (0x2F9F2, 'M', '䧦'),
    +    (0x2F9F3, 'M', '雃'),
    +    (0x2F9F4, 'M', '嶲'),
    +    (0x2F9F5, 'M', '霣'),
    +    (0x2F9F6, 'M', '𩅅'),
    +    (0x2F9F7, 'M', '𩈚'),
    +    (0x2F9F8, 'M', '䩮'),
    +    (0x2F9F9, 'M', '䩶'),
    +    (0x2F9FA, 'M', '韠'),
    +    (0x2F9FB, 'M', '𩐊'),
    +    (0x2F9FC, 'M', '䪲'),
    +    (0x2F9FD, 'M', '𩒖'),
    +    (0x2F9FE, 'M', '頋'),
    +    (0x2FA00, 'M', '頩'),
    +    (0x2FA01, 'M', '𩖶'),
    +    (0x2FA02, 'M', '飢'),
    +    (0x2FA03, 'M', '䬳'),
    +    (0x2FA04, 'M', '餩'),
    +    (0x2FA05, 'M', '馧'),
    +    (0x2FA06, 'M', '駂'),
    +    (0x2FA07, 'M', '駾'),
    +    (0x2FA08, 'M', '䯎'),
    +    (0x2FA09, 'M', '𩬰'),
    +    (0x2FA0A, 'M', '鬒'),
    +    (0x2FA0B, 'M', '鱀'),
    +    (0x2FA0C, 'M', '鳽'),
    +    (0x2FA0D, 'M', '䳎'),
    +    (0x2FA0E, 'M', '䳭'),
    +    (0x2FA0F, 'M', '鵧'),
    +    (0x2FA10, 'M', '𪃎'),
    +    (0x2FA11, 'M', '䳸'),
    +    (0x2FA12, 'M', '𪄅'),
    +    (0x2FA13, 'M', '𪈎'),
    +    (0x2FA14, 'M', '𪊑'),
    +    (0x2FA15, 'M', '麻'),
    +    (0x2FA16, 'M', '䵖'),
    +    (0x2FA17, 'M', '黹'),
    +    (0x2FA18, 'M', '黾'),
    +    (0x2FA19, 'M', '鼅'),
    +    (0x2FA1A, 'M', '鼏'),
    +    (0x2FA1B, 'M', '鼖'),
    +    (0x2FA1C, 'M', '鼻'),
    +    (0x2FA1D, 'M', '𪘀'),
    +    (0x2FA1E, 'X'),
    +    (0x30000, 'V'),
    +    (0x3134B, 'X'),
    +    (0x31350, 'V'),
    +    (0x323B0, 'X'),
    +    (0xE0100, 'I'),
    +    (0xE01F0, 'X'),
    +    ]
    +
    +uts46data = tuple(
    +    _seg_0()
    +    + _seg_1()
    +    + _seg_2()
    +    + _seg_3()
    +    + _seg_4()
    +    + _seg_5()
    +    + _seg_6()
    +    + _seg_7()
    +    + _seg_8()
    +    + _seg_9()
    +    + _seg_10()
    +    + _seg_11()
    +    + _seg_12()
    +    + _seg_13()
    +    + _seg_14()
    +    + _seg_15()
    +    + _seg_16()
    +    + _seg_17()
    +    + _seg_18()
    +    + _seg_19()
    +    + _seg_20()
    +    + _seg_21()
    +    + _seg_22()
    +    + _seg_23()
    +    + _seg_24()
    +    + _seg_25()
    +    + _seg_26()
    +    + _seg_27()
    +    + _seg_28()
    +    + _seg_29()
    +    + _seg_30()
    +    + _seg_31()
    +    + _seg_32()
    +    + _seg_33()
    +    + _seg_34()
    +    + _seg_35()
    +    + _seg_36()
    +    + _seg_37()
    +    + _seg_38()
    +    + _seg_39()
    +    + _seg_40()
    +    + _seg_41()
    +    + _seg_42()
    +    + _seg_43()
    +    + _seg_44()
    +    + _seg_45()
    +    + _seg_46()
    +    + _seg_47()
    +    + _seg_48()
    +    + _seg_49()
    +    + _seg_50()
    +    + _seg_51()
    +    + _seg_52()
    +    + _seg_53()
    +    + _seg_54()
    +    + _seg_55()
    +    + _seg_56()
    +    + _seg_57()
    +    + _seg_58()
    +    + _seg_59()
    +    + _seg_60()
    +    + _seg_61()
    +    + _seg_62()
    +    + _seg_63()
    +    + _seg_64()
    +    + _seg_65()
    +    + _seg_66()
    +    + _seg_67()
    +    + _seg_68()
    +    + _seg_69()
    +    + _seg_70()
    +    + _seg_71()
    +    + _seg_72()
    +    + _seg_73()
    +    + _seg_74()
    +    + _seg_75()
    +    + _seg_76()
    +    + _seg_77()
    +    + _seg_78()
    +    + _seg_79()
    +    + _seg_80()
    +    + _seg_81()
    +)  # type: Tuple[Union[Tuple[int, str], Tuple[int, str, str]], ...]
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/INSTALLER b/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/INSTALLER
    new file mode 100644
    index 0000000..a1b589e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/INSTALLER
    @@ -0,0 +1 @@
    +pip
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/LICENSE b/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/LICENSE
    new file mode 100644
    index 0000000..67db858
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/LICENSE
    @@ -0,0 +1,175 @@
    +
    +                                 Apache License
    +                           Version 2.0, January 2004
    +                        http://www.apache.org/licenses/
    +
    +   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    +
    +   1. Definitions.
    +
    +      "License" shall mean the terms and conditions for use, reproduction,
    +      and distribution as defined by Sections 1 through 9 of this document.
    +
    +      "Licensor" shall mean the copyright owner or entity authorized by
    +      the copyright owner that is granting the License.
    +
    +      "Legal Entity" shall mean the union of the acting entity and all
    +      other entities that control, are controlled by, or are under common
    +      control with that entity. For the purposes of this definition,
    +      "control" means (i) the power, direct or indirect, to cause the
    +      direction or management of such entity, whether by contract or
    +      otherwise, or (ii) ownership of fifty percent (50%) or more of the
    +      outstanding shares, or (iii) beneficial ownership of such entity.
    +
    +      "You" (or "Your") shall mean an individual or Legal Entity
    +      exercising permissions granted by this License.
    +
    +      "Source" form shall mean the preferred form for making modifications,
    +      including but not limited to software source code, documentation
    +      source, and configuration files.
    +
    +      "Object" form shall mean any form resulting from mechanical
    +      transformation or translation of a Source form, including but
    +      not limited to compiled object code, generated documentation,
    +      and conversions to other media types.
    +
    +      "Work" shall mean the work of authorship, whether in Source or
    +      Object form, made available under the License, as indicated by a
    +      copyright notice that is included in or attached to the work
    +      (an example is provided in the Appendix below).
    +
    +      "Derivative Works" shall mean any work, whether in Source or Object
    +      form, that is based on (or derived from) the Work and for which the
    +      editorial revisions, annotations, elaborations, or other modifications
    +      represent, as a whole, an original work of authorship. For the purposes
    +      of this License, Derivative Works shall not include works that remain
    +      separable from, or merely link (or bind by name) to the interfaces of,
    +      the Work and Derivative Works thereof.
    +
    +      "Contribution" shall mean any work of authorship, including
    +      the original version of the Work and any modifications or additions
    +      to that Work or Derivative Works thereof, that is intentionally
    +      submitted to Licensor for inclusion in the Work by the copyright owner
    +      or by an individual or Legal Entity authorized to submit on behalf of
    +      the copyright owner. For the purposes of this definition, "submitted"
    +      means any form of electronic, verbal, or written communication sent
    +      to the Licensor or its representatives, including but not limited to
    +      communication on electronic mailing lists, source code control systems,
    +      and issue tracking systems that are managed by, or on behalf of, the
    +      Licensor for the purpose of discussing and improving the Work, but
    +      excluding communication that is conspicuously marked or otherwise
    +      designated in writing by the copyright owner as "Not a Contribution."
    +
    +      "Contributor" shall mean Licensor and any individual or Legal Entity
    +      on behalf of whom a Contribution has been received by Licensor and
    +      subsequently incorporated within the Work.
    +
    +   2. Grant of Copyright License. Subject to the terms and conditions of
    +      this License, each Contributor hereby grants to You a perpetual,
    +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    +      copyright license to reproduce, prepare Derivative Works of,
    +      publicly display, publicly perform, sublicense, and distribute the
    +      Work and such Derivative Works in Source or Object form.
    +
    +   3. Grant of Patent License. Subject to the terms and conditions of
    +      this License, each Contributor hereby grants to You a perpetual,
    +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    +      (except as stated in this section) patent license to make, have made,
    +      use, offer to sell, sell, import, and otherwise transfer the Work,
    +      where such license applies only to those patent claims licensable
    +      by such Contributor that are necessarily infringed by their
    +      Contribution(s) alone or by combination of their Contribution(s)
    +      with the Work to which such Contribution(s) was submitted. If You
    +      institute patent litigation against any entity (including a
    +      cross-claim or counterclaim in a lawsuit) alleging that the Work
    +      or a Contribution incorporated within the Work constitutes direct
    +      or contributory patent infringement, then any patent licenses
    +      granted to You under this License for that Work shall terminate
    +      as of the date such litigation is filed.
    +
    +   4. Redistribution. You may reproduce and distribute copies of the
    +      Work or Derivative Works thereof in any medium, with or without
    +      modifications, and in Source or Object form, provided that You
    +      meet the following conditions:
    +
    +      (a) You must give any other recipients of the Work or
    +          Derivative Works a copy of this License; and
    +
    +      (b) You must cause any modified files to carry prominent notices
    +          stating that You changed the files; and
    +
    +      (c) You must retain, in the Source form of any Derivative Works
    +          that You distribute, all copyright, patent, trademark, and
    +          attribution notices from the Source form of the Work,
    +          excluding those notices that do not pertain to any part of
    +          the Derivative Works; and
    +
    +      (d) If the Work includes a "NOTICE" text file as part of its
    +          distribution, then any Derivative Works that You distribute must
    +          include a readable copy of the attribution notices contained
    +          within such NOTICE file, excluding those notices that do not
    +          pertain to any part of the Derivative Works, in at least one
    +          of the following places: within a NOTICE text file distributed
    +          as part of the Derivative Works; within the Source form or
    +          documentation, if provided along with the Derivative Works; or,
    +          within a display generated by the Derivative Works, if and
    +          wherever such third-party notices normally appear. The contents
    +          of the NOTICE file are for informational purposes only and
    +          do not modify the License. You may add Your own attribution
    +          notices within Derivative Works that You distribute, alongside
    +          or as an addendum to the NOTICE text from the Work, provided
    +          that such additional attribution notices cannot be construed
    +          as modifying the License.
    +
    +      You may add Your own copyright statement to Your modifications and
    +      may provide additional or different license terms and conditions
    +      for use, reproduction, or distribution of Your modifications, or
    +      for any such Derivative Works as a whole, provided Your use,
    +      reproduction, and distribution of the Work otherwise complies with
    +      the conditions stated in this License.
    +
    +   5. Submission of Contributions. Unless You explicitly state otherwise,
    +      any Contribution intentionally submitted for inclusion in the Work
    +      by You to the Licensor shall be under the terms and conditions of
    +      this License, without any additional terms or conditions.
    +      Notwithstanding the above, nothing herein shall supersede or modify
    +      the terms of any separate license agreement you may have executed
    +      with Licensor regarding such Contributions.
    +
    +   6. Trademarks. This License does not grant permission to use the trade
    +      names, trademarks, service marks, or product names of the Licensor,
    +      except as required for reasonable and customary use in describing the
    +      origin of the Work and reproducing the content of the NOTICE file.
    +
    +   7. Disclaimer of Warranty. Unless required by applicable law or
    +      agreed to in writing, Licensor provides the Work (and each
    +      Contributor provides its Contributions) on an "AS IS" BASIS,
    +      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    +      implied, including, without limitation, any warranties or conditions
    +      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
    +      PARTICULAR PURPOSE. You are solely responsible for determining the
    +      appropriateness of using or redistributing the Work and assume any
    +      risks associated with Your exercise of permissions under this License.
    +
    +   8. Limitation of Liability. In no event and under no legal theory,
    +      whether in tort (including negligence), contract, or otherwise,
    +      unless required by applicable law (such as deliberate and grossly
    +      negligent acts) or agreed to in writing, shall any Contributor be
    +      liable to You for damages, including any direct, indirect, special,
    +      incidental, or consequential damages of any character arising as a
    +      result of this License or out of the use or inability to use the
    +      Work (including but not limited to damages for loss of goodwill,
    +      work stoppage, computer failure or malfunction, or any and all
    +      other commercial damages or losses), even if such Contributor
    +      has been advised of the possibility of such damages.
    +
    +   9. Accepting Warranty or Additional Liability. While redistributing
    +      the Work or Derivative Works thereof, You may choose to offer,
    +      and charge a fee for, acceptance of support, warranty, indemnity,
    +      or other liability obligations and/or rights consistent with this
    +      License. However, in accepting such obligations, You may act only
    +      on Your own behalf and on Your sole responsibility, not on behalf
    +      of any other Contributor, and only if You agree to indemnify,
    +      defend, and hold each Contributor harmless for any liability
    +      incurred by, or claims asserted against, such Contributor by reason
    +      of your accepting any such warranty or additional liability.
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/METADATA b/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/METADATA
    new file mode 100644
    index 0000000..b1ed44a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/METADATA
    @@ -0,0 +1,121 @@
    +Metadata-Version: 2.1
    +Name: requests
    +Version: 2.28.2
    +Summary: Python HTTP for Humans.
    +Home-page: https://requests.readthedocs.io
    +Author: Kenneth Reitz
    +Author-email: me@kennethreitz.org
    +License: Apache 2.0
    +Project-URL: Documentation, https://requests.readthedocs.io
    +Project-URL: Source, https://github.com/psf/requests
    +Platform: UNKNOWN
    +Classifier: Development Status :: 5 - Production/Stable
    +Classifier: Environment :: Web Environment
    +Classifier: Intended Audience :: Developers
    +Classifier: License :: OSI Approved :: Apache Software License
    +Classifier: Natural Language :: English
    +Classifier: Operating System :: OS Independent
    +Classifier: Programming Language :: Python
    +Classifier: Programming Language :: Python :: 3
    +Classifier: Programming Language :: Python :: 3.7
    +Classifier: Programming Language :: Python :: 3.8
    +Classifier: Programming Language :: Python :: 3.9
    +Classifier: Programming Language :: Python :: 3.10
    +Classifier: Programming Language :: Python :: 3.11
    +Classifier: Programming Language :: Python :: 3 :: Only
    +Classifier: Programming Language :: Python :: Implementation :: CPython
    +Classifier: Programming Language :: Python :: Implementation :: PyPy
    +Classifier: Topic :: Internet :: WWW/HTTP
    +Classifier: Topic :: Software Development :: Libraries
    +Requires-Python: >=3.7, <4
    +Description-Content-Type: text/markdown
    +Requires-Dist: charset-normalizer (<4,>=2)
    +Requires-Dist: idna (<4,>=2.5)
    +Requires-Dist: urllib3 (<1.27,>=1.21.1)
    +Requires-Dist: certifi (>=2017.4.17)
    +Provides-Extra: security
    +Provides-Extra: socks
    +Requires-Dist: PySocks (!=1.5.7,>=1.5.6) ; extra == 'socks'
    +Provides-Extra: use_chardet_on_py3
    +Requires-Dist: chardet (<6,>=3.0.2) ; extra == 'use_chardet_on_py3'
    +
    +# Requests
    +
    +**Requests** is a simple, yet elegant, HTTP library.
    +
    +```python
    +>>> import requests
    +>>> r = requests.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))
    +>>> r.status_code
    +200
    +>>> r.headers['content-type']
    +'application/json; charset=utf8'
    +>>> r.encoding
    +'utf-8'
    +>>> r.text
    +'{"authenticated": true, ...'
    +>>> r.json()
    +{'authenticated': True, ...}
    +```
    +
    +Requests allows you to send HTTP/1.1 requests extremely easily. There’s no need to manually add query strings to your URLs, or to form-encode your `PUT` & `POST` data — but nowadays, just use the `json` method!
    +
    +Requests is one of the most downloaded Python packages today, pulling in around `30M downloads / week`— according to GitHub, Requests is currently [depended upon](https://github.com/psf/requests/network/dependents?package_id=UGFja2FnZS01NzA4OTExNg%3D%3D) by `1,000,000+` repositories. You may certainly put your trust in this code.
    +
    +[![Downloads](https://pepy.tech/badge/requests/month)](https://pepy.tech/project/requests)
    +[![Supported Versions](https://img.shields.io/pypi/pyversions/requests.svg)](https://pypi.org/project/requests)
    +[![Contributors](https://img.shields.io/github/contributors/psf/requests.svg)](https://github.com/psf/requests/graphs/contributors)
    +
    +## Installing Requests and Supported Versions
    +
    +Requests is available on PyPI:
    +
    +```console
    +$ python -m pip install requests
    +```
    +
    +Requests officially supports Python 3.7+.
    +
    +## Supported Features & Best–Practices
    +
    +Requests is ready for the demands of building robust and reliable HTTP–speaking applications, for the needs of today.
    +
    +- Keep-Alive & Connection Pooling
    +- International Domains and URLs
    +- Sessions with Cookie Persistence
    +- Browser-style TLS/SSL Verification
    +- Basic & Digest Authentication
    +- Familiar `dict`–like Cookies
    +- Automatic Content Decompression and Decoding
    +- Multi-part File Uploads
    +- SOCKS Proxy Support
    +- Connection Timeouts
    +- Streaming Downloads
    +- Automatic honoring of `.netrc`
    +- Chunked HTTP Requests
    +
    +## API Reference and User Guide available on [Read the Docs](https://requests.readthedocs.io)
    +
    +[![Read the Docs](https://raw.githubusercontent.com/psf/requests/main/ext/ss.png)](https://requests.readthedocs.io)
    +
    +## Cloning the repository
    +
    +When cloning the Requests repository, you may need to add the `-c
    +fetch.fsck.badTimezone=ignore` flag to avoid an error about a bad commit (see
    +[this issue](https://github.com/psf/requests/issues/2690) for more background):
    +
    +```shell
    +git clone -c fetch.fsck.badTimezone=ignore https://github.com/psf/requests.git
    +```
    +
    +You can also apply this setting to your global Git config:
    +
    +```shell
    +git config --global fetch.fsck.badTimezone ignore
    +```
    +
    +---
    +
    +[![Kenneth Reitz](https://raw.githubusercontent.com/psf/requests/main/ext/kr.png)](https://kennethreitz.org) [![Python Software Foundation](https://raw.githubusercontent.com/psf/requests/main/ext/psf.png)](https://www.python.org/psf)
    +
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/RECORD b/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/RECORD
    new file mode 100644
    index 0000000..29b7f68
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/RECORD
    @@ -0,0 +1,24 @@
    +requests-2.28.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
    +requests-2.28.2.dist-info/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
    +requests-2.28.2.dist-info/METADATA,sha256=7164jsFZN3Llh_nX_oBRqetlTdcULRBjjnQlzrtn6Y0,4619
    +requests-2.28.2.dist-info/RECORD,,
    +requests-2.28.2.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
    +requests-2.28.2.dist-info/top_level.txt,sha256=fMSVmHfb5rbGOo6xv-O_tUX6j-WyixssE-SnwcDRxNQ,9
    +requests/__init__.py,sha256=xX0rLGvoljtzG8oDF-ZYuTlgL_BQgKoxUZ1e3cpNHX8,4972
    +requests/__version__.py,sha256=h48zn-oFukaXrYHocdadp_hIszWyd_PGrS8Eiii6aoc,435
    +requests/_internal_utils.py,sha256=aSPlF4uDhtfKxEayZJJ7KkAxtormeTfpwKSBSwtmAUw,1397
    +requests/adapters.py,sha256=sEnHGl4mJz4QHBT8jG6bU5aPinUtdoH3BIuAIzT-X74,21287
    +requests/api.py,sha256=dyvkDd5itC9z2g0wHl_YfD1yf6YwpGWLO7__8e21nks,6377
    +requests/auth.py,sha256=h-HLlVx9j8rKV5hfSAycP2ApOSglTz77R0tz7qCbbEE,10187
    +requests/certs.py,sha256=Z9Sb410Anv6jUFTyss0jFFhU6xst8ctELqfy8Ev23gw,429
    +requests/compat.py,sha256=yxntVOSEHGMrn7FNr_32EEam1ZNAdPRdSE13_yaHzTk,1451
    +requests/cookies.py,sha256=kD3kNEcCj-mxbtf5fJsSaT86eGoEYpD3X0CSgpzl7BM,18560
    +requests/exceptions.py,sha256=DhveFBclVjTRxhRduVpO-GbMYMID2gmjdLfNEqNpI_U,3811
    +requests/help.py,sha256=gPX5d_H7Xd88aDABejhqGgl9B1VFRTt5BmiYvL3PzIQ,3875
    +requests/hooks.py,sha256=CiuysiHA39V5UfcCBXFIx83IrDpuwfN9RcTUgv28ftQ,733
    +requests/models.py,sha256=-DlKi0or8gFAM6VzutobXvvBW_2wrJuOF5NfndTIddA,35223
    +requests/packages.py,sha256=DXgv-FJIczZITmv0vEBAhWj4W-5CGCIN_ksvgR17Dvs,957
    +requests/sessions.py,sha256=KUqJcRRLovNefUs7ScOXSUVCcfSayTFWtbiJ7gOSlTI,30180
    +requests/status_codes.py,sha256=FvHmT5uH-_uimtRz5hH9VCbt7VV-Nei2J9upbej6j8g,4235
    +requests/structures.py,sha256=-IbmhVz06S-5aPSZuUthZ6-6D9XOjRuTXHOabY041XM,2912
    +requests/utils.py,sha256=5_ws-bsKI9EHl7j27yi-6HFzPBKultPgd7HfPrUToWI,33228
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/WHEEL b/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/WHEEL
    new file mode 100644
    index 0000000..57e3d84
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests-2.28.2.dist-info/WHEEL
    @@ -0,0 +1,5 @@
    +Wheel-Version: 1.0
    +Generator: bdist_wheel (0.38.4)
    +Root-Is-Purelib: true
    +Tag: py3-none-any
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/__init__.py b/deployment-apps/metricator-for-nmon/lib/requests/__init__.py
    new file mode 100644
    index 0000000..22db3c1
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/__init__.py
    @@ -0,0 +1,180 @@
    +#   __
    +#  /__)  _  _     _   _ _/   _
    +# / (   (- (/ (/ (- _)  /  _)
    +#          /
    +
    +"""
    +Requests HTTP Library
    +~~~~~~~~~~~~~~~~~~~~~
    +
    +Requests is an HTTP library, written in Python, for human beings.
    +Basic GET usage:
    +
    +   >>> import requests
    +   >>> r = requests.get('https://www.python.org')
    +   >>> r.status_code
    +   200
    +   >>> b'Python is a programming language' in r.content
    +   True
    +
    +... or POST:
    +
    +   >>> payload = dict(key1='value1', key2='value2')
    +   >>> r = requests.post('https://httpbin.org/post', data=payload)
    +   >>> print(r.text)
    +   {
    +     ...
    +     "form": {
    +       "key1": "value1",
    +       "key2": "value2"
    +     },
    +     ...
    +   }
    +
    +The other HTTP methods are supported - see `requests.api`. Full documentation
    +is at <https://requests.readthedocs.io>.
    +
    +:copyright: (c) 2017 by Kenneth Reitz.
    +:license: Apache 2.0, see LICENSE for more details.
    +"""
    +
    +import warnings
    +
    +import urllib3
    +
    +from .exceptions import RequestsDependencyWarning
    +
    +try:
    +    from charset_normalizer import __version__ as charset_normalizer_version
    +except ImportError:
    +    charset_normalizer_version = None
    +
    +try:
    +    from chardet import __version__ as chardet_version
    +except ImportError:
    +    chardet_version = None
    +
    +
    +def check_compatibility(urllib3_version, chardet_version, charset_normalizer_version):
    +    urllib3_version = urllib3_version.split(".")
    +    assert urllib3_version != ["dev"]  # Verify urllib3 isn't installed from git.
    +
    +    # Sometimes, urllib3 only reports its version as 16.1.
    +    if len(urllib3_version) == 2:
    +        urllib3_version.append("0")
    +
    +    # Check urllib3 for compatibility.
    +    major, minor, patch = urllib3_version  # noqa: F811
    +    major, minor, patch = int(major), int(minor), int(patch)
    +    # urllib3 >= 1.21.1, <= 1.26
    +    assert major == 1
    +    assert minor >= 21
    +    assert minor <= 26
    +
    +    # Check charset_normalizer for compatibility.
    +    if chardet_version:
    +        major, minor, patch = chardet_version.split(".")[:3]
    +        major, minor, patch = int(major), int(minor), int(patch)
    +        # chardet_version >= 3.0.2, < 6.0.0
    +        assert (3, 0, 2) <= (major, minor, patch) < (6, 0, 0)
    +    elif charset_normalizer_version:
    +        major, minor, patch = charset_normalizer_version.split(".")[:3]
    +        major, minor, patch = int(major), int(minor), int(patch)
    +        # charset_normalizer >= 2.0.0 < 4.0.0
    +        assert (2, 0, 0) <= (major, minor, patch) < (4, 0, 0)
    +    else:
    +        raise Exception("You need either charset_normalizer or chardet installed")
    +
    +
    +def _check_cryptography(cryptography_version):
    +    # cryptography < 1.3.4
    +    try:
    +        cryptography_version = list(map(int, cryptography_version.split(".")))
    +    except ValueError:
    +        return
    +
    +    if cryptography_version < [1, 3, 4]:
    +        warning = "Old version of cryptography ({}) may cause slowdown.".format(
    +            cryptography_version
    +        )
    +        warnings.warn(warning, RequestsDependencyWarning)
    +
    +
    +# Check imported dependencies for compatibility.
    +try:
    +    check_compatibility(
    +        urllib3.__version__, chardet_version, charset_normalizer_version
    +    )
    +except (AssertionError, ValueError):
    +    warnings.warn(
    +        "urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported "
    +        "version!".format(
    +            urllib3.__version__, chardet_version, charset_normalizer_version
    +        ),
    +        RequestsDependencyWarning,
    +    )
    +
    +# Attempt to enable urllib3's fallback for SNI support
    +# if the standard library doesn't support SNI or the
    +# 'ssl' library isn't available.
    +try:
    +    try:
    +        import ssl
    +    except ImportError:
    +        ssl = None
    +
    +    if not getattr(ssl, "HAS_SNI", False):
    +        from urllib3.contrib import pyopenssl
    +
    +        pyopenssl.inject_into_urllib3()
    +
    +        # Check cryptography version
    +        from cryptography import __version__ as cryptography_version
    +
    +        _check_cryptography(cryptography_version)
    +except ImportError:
    +    pass
    +
    +# urllib3's DependencyWarnings should be silenced.
    +from urllib3.exceptions import DependencyWarning
    +
    +warnings.simplefilter("ignore", DependencyWarning)
    +
    +# Set default logging handler to avoid "No handler found" warnings.
    +import logging
    +from logging import NullHandler
    +
    +from . import packages, utils
    +from .__version__ import (
    +    __author__,
    +    __author_email__,
    +    __build__,
    +    __cake__,
    +    __copyright__,
    +    __description__,
    +    __license__,
    +    __title__,
    +    __url__,
    +    __version__,
    +)
    +from .api import delete, get, head, options, patch, post, put, request
    +from .exceptions import (
    +    ConnectionError,
    +    ConnectTimeout,
    +    FileModeWarning,
    +    HTTPError,
    +    JSONDecodeError,
    +    ReadTimeout,
    +    RequestException,
    +    Timeout,
    +    TooManyRedirects,
    +    URLRequired,
    +)
    +from .models import PreparedRequest, Request, Response
    +from .sessions import Session, session
    +from .status_codes import codes
    +
    +logging.getLogger(__name__).addHandler(NullHandler())
    +
    +# FileModeWarnings go off per the default.
    +warnings.simplefilter("default", FileModeWarning, append=True)
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/__version__.py b/deployment-apps/metricator-for-nmon/lib/requests/__version__.py
    new file mode 100644
    index 0000000..69be3de
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/__version__.py
    @@ -0,0 +1,14 @@
    +# .-. .-. .-. . . .-. .-. .-. .-.
    +# |(  |-  |.| | | |-  `-.  |  `-.
    +# ' ' `-' `-`.`-' `-' `-'  '  `-'
    +
    +__title__ = "requests"
    +__description__ = "Python HTTP for Humans."
    +__url__ = "https://requests.readthedocs.io"
    +__version__ = "2.28.2"
    +__build__ = 0x022802
    +__author__ = "Kenneth Reitz"
    +__author_email__ = "me@kennethreitz.org"
    +__license__ = "Apache 2.0"
    +__copyright__ = "Copyright Kenneth Reitz"
    +__cake__ = "\u2728 \U0001f370 \u2728"
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/_internal_utils.py b/deployment-apps/metricator-for-nmon/lib/requests/_internal_utils.py
    new file mode 100644
    index 0000000..7dc9bc5
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/_internal_utils.py
    @@ -0,0 +1,48 @@
    +"""
    +requests._internal_utils
    +~~~~~~~~~~~~~~
    +
    +Provides utility functions that are consumed internally by Requests
    +which depend on extremely few external helpers (such as compat)
    +"""
    +import re
    +
    +from .compat import builtin_str
    +
    +_VALID_HEADER_NAME_RE_BYTE = re.compile(rb"^[^:\s][^:\r\n]*$")
    +_VALID_HEADER_NAME_RE_STR = re.compile(r"^[^:\s][^:\r\n]*$")
    +_VALID_HEADER_VALUE_RE_BYTE = re.compile(rb"^\S[^\r\n]*$|^$")
    +_VALID_HEADER_VALUE_RE_STR = re.compile(r"^\S[^\r\n]*$|^$")
    +
    +HEADER_VALIDATORS = {
    +    bytes: (_VALID_HEADER_NAME_RE_BYTE, _VALID_HEADER_VALUE_RE_BYTE),
    +    str: (_VALID_HEADER_NAME_RE_STR, _VALID_HEADER_VALUE_RE_STR),
    +}
    +
    +
    +def to_native_string(string, encoding="ascii"):
    +    """Given a string object, regardless of type, returns a representation of
    +    that string in the native string type, encoding and decoding where
    +    necessary. This assumes ASCII unless told otherwise.
    +    """
    +    if isinstance(string, builtin_str):
    +        out = string
    +    else:
    +        out = string.decode(encoding)
    +
    +    return out
    +
    +
    +def unicode_is_ascii(u_string):
    +    """Determine if unicode string only contains ASCII characters.
    +
    +    :param str u_string: unicode string to check. Must be unicode
    +        and not Python 2 `str`.
    +    :rtype: bool
    +    """
    +    assert isinstance(u_string, str)
    +    try:
    +        u_string.encode("ascii")
    +        return True
    +    except UnicodeEncodeError:
    +        return False
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/adapters.py b/deployment-apps/metricator-for-nmon/lib/requests/adapters.py
    new file mode 100644
    index 0000000..d3b2d5b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/adapters.py
    @@ -0,0 +1,584 @@
    +"""
    +requests.adapters
    +~~~~~~~~~~~~~~~~~
    +
    +This module contains the transport adapters that Requests uses to define
    +and maintain connections.
    +"""
    +
    +import os.path
    +import socket  # noqa: F401
    +
    +from urllib3.exceptions import ClosedPoolError, ConnectTimeoutError
    +from urllib3.exceptions import HTTPError as _HTTPError
    +from urllib3.exceptions import InvalidHeader as _InvalidHeader
    +from urllib3.exceptions import (
    +    LocationValueError,
    +    MaxRetryError,
    +    NewConnectionError,
    +    ProtocolError,
    +)
    +from urllib3.exceptions import ProxyError as _ProxyError
    +from urllib3.exceptions import ReadTimeoutError, ResponseError
    +from urllib3.exceptions import SSLError as _SSLError
    +from urllib3.poolmanager import PoolManager, proxy_from_url
    +from urllib3.response import HTTPResponse
    +from urllib3.util import Timeout as TimeoutSauce
    +from urllib3.util import parse_url
    +from urllib3.util.retry import Retry
    +
    +from .auth import _basic_auth_str
    +from .compat import basestring, urlparse
    +from .cookies import extract_cookies_to_jar
    +from .exceptions import (
    +    ConnectionError,
    +    ConnectTimeout,
    +    InvalidHeader,
    +    InvalidProxyURL,
    +    InvalidSchema,
    +    InvalidURL,
    +    ProxyError,
    +    ReadTimeout,
    +    RetryError,
    +    SSLError,
    +)
    +from .models import Response
    +from .structures import CaseInsensitiveDict
    +from .utils import (
    +    DEFAULT_CA_BUNDLE_PATH,
    +    extract_zipped_paths,
    +    get_auth_from_url,
    +    get_encoding_from_headers,
    +    prepend_scheme_if_needed,
    +    select_proxy,
    +    urldefragauth,
    +)
    +
    +try:
    +    from urllib3.contrib.socks import SOCKSProxyManager
    +except ImportError:
    +
    +    def SOCKSProxyManager(*args, **kwargs):
    +        raise InvalidSchema("Missing dependencies for SOCKS support.")
    +
    +
    +DEFAULT_POOLBLOCK = False
    +DEFAULT_POOLSIZE = 10
    +DEFAULT_RETRIES = 0
    +DEFAULT_POOL_TIMEOUT = None
    +
    +
    +class BaseAdapter:
    +    """The Base Transport Adapter"""
    +
    +    def __init__(self):
    +        super().__init__()
    +
    +    def send(
    +        self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
    +    ):
    +        """Sends PreparedRequest object. Returns Response object.
    +
    +        :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
    +        :param stream: (optional) Whether to stream the request content.
    +        :param timeout: (optional) How long to wait for the server to send
    +            data before giving up, as a float, or a :ref:`(connect timeout,
    +            read timeout) <timeouts>` tuple.
    +        :type timeout: float or tuple
    +        :param verify: (optional) Either a boolean, in which case it controls whether we verify
    +            the server's TLS certificate, or a string, in which case it must be a path
    +            to a CA bundle to use
    +        :param cert: (optional) Any user-provided SSL certificate to be trusted.
    +        :param proxies: (optional) The proxies dictionary to apply to the request.
    +        """
    +        raise NotImplementedError
    +
    +    def close(self):
    +        """Cleans up adapter specific items."""
    +        raise NotImplementedError
    +
    +
    +class HTTPAdapter(BaseAdapter):
    +    """The built-in HTTP Adapter for urllib3.
    +
    +    Provides a general-case interface for Requests sessions to contact HTTP and
    +    HTTPS urls by implementing the Transport Adapter interface. This class will
    +    usually be created by the :class:`Session <Session>` class under the
    +    covers.
    +
    +    :param pool_connections: The number of urllib3 connection pools to cache.
    +    :param pool_maxsize: The maximum number of connections to save in the pool.
    +    :param max_retries: The maximum number of retries each connection
    +        should attempt. Note, this applies only to failed DNS lookups, socket
    +        connections and connection timeouts, never to requests where data has
    +        made it to the server. By default, Requests does not retry failed
    +        connections. If you need granular control over the conditions under
    +        which we retry a request, import urllib3's ``Retry`` class and pass
    +        that instead.
    +    :param pool_block: Whether the connection pool should block for connections.
    +
    +    Usage::
    +
    +      >>> import requests
    +      >>> s = requests.Session()
    +      >>> a = requests.adapters.HTTPAdapter(max_retries=3)
    +      >>> s.mount('http://', a)
    +    """
    +
    +    __attrs__ = [
    +        "max_retries",
    +        "config",
    +        "_pool_connections",
    +        "_pool_maxsize",
    +        "_pool_block",
    +    ]
    +
    +    def __init__(
    +        self,
    +        pool_connections=DEFAULT_POOLSIZE,
    +        pool_maxsize=DEFAULT_POOLSIZE,
    +        max_retries=DEFAULT_RETRIES,
    +        pool_block=DEFAULT_POOLBLOCK,
    +    ):
    +        if max_retries == DEFAULT_RETRIES:
    +            self.max_retries = Retry(0, read=False)
    +        else:
    +            self.max_retries = Retry.from_int(max_retries)
    +        self.config = {}
    +        self.proxy_manager = {}
    +
    +        super().__init__()
    +
    +        self._pool_connections = pool_connections
    +        self._pool_maxsize = pool_maxsize
    +        self._pool_block = pool_block
    +
    +        self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)
    +
    +    def __getstate__(self):
    +        return {attr: getattr(self, attr, None) for attr in self.__attrs__}
    +
    +    def __setstate__(self, state):
    +        # Can't handle by adding 'proxy_manager' to self.__attrs__ because
    +        # self.poolmanager uses a lambda function, which isn't pickleable.
    +        self.proxy_manager = {}
    +        self.config = {}
    +
    +        for attr, value in state.items():
    +            setattr(self, attr, value)
    +
    +        self.init_poolmanager(
    +            self._pool_connections, self._pool_maxsize, block=self._pool_block
    +        )
    +
    +    def init_poolmanager(
    +        self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs
    +    ):
    +        """Initializes a urllib3 PoolManager.
    +
    +        This method should not be called from user code, and is only
    +        exposed for use when subclassing the
    +        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
    +
    +        :param connections: The number of urllib3 connection pools to cache.
    +        :param maxsize: The maximum number of connections to save in the pool.
    +        :param block: Block when no free connections are available.
    +        :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager.
    +        """
    +        # save these values for pickling
    +        self._pool_connections = connections
    +        self._pool_maxsize = maxsize
    +        self._pool_block = block
    +
    +        self.poolmanager = PoolManager(
    +            num_pools=connections,
    +            maxsize=maxsize,
    +            block=block,
    +            strict=True,
    +            **pool_kwargs,
    +        )
    +
    +    def proxy_manager_for(self, proxy, **proxy_kwargs):
    +        """Return urllib3 ProxyManager for the given proxy.
    +
    +        This method should not be called from user code, and is only
    +        exposed for use when subclassing the
    +        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
    +
    +        :param proxy: The proxy to return a urllib3 ProxyManager for.
    +        :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.
    +        :returns: ProxyManager
    +        :rtype: urllib3.ProxyManager
    +        """
    +        if proxy in self.proxy_manager:
    +            manager = self.proxy_manager[proxy]
    +        elif proxy.lower().startswith("socks"):
    +            username, password = get_auth_from_url(proxy)
    +            manager = self.proxy_manager[proxy] = SOCKSProxyManager(
    +                proxy,
    +                username=username,
    +                password=password,
    +                num_pools=self._pool_connections,
    +                maxsize=self._pool_maxsize,
    +                block=self._pool_block,
    +                **proxy_kwargs,
    +            )
    +        else:
    +            proxy_headers = self.proxy_headers(proxy)
    +            manager = self.proxy_manager[proxy] = proxy_from_url(
    +                proxy,
    +                proxy_headers=proxy_headers,
    +                num_pools=self._pool_connections,
    +                maxsize=self._pool_maxsize,
    +                block=self._pool_block,
    +                **proxy_kwargs,
    +            )
    +
    +        return manager
    +
    +    def cert_verify(self, conn, url, verify, cert):
    +        """Verify a SSL certificate. This method should not be called from user
    +        code, and is only exposed for use when subclassing the
    +        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
    +
    +        :param conn: The urllib3 connection object associated with the cert.
    +        :param url: The requested URL.
    +        :param verify: Either a boolean, in which case it controls whether we verify
    +            the server's TLS certificate, or a string, in which case it must be a path
    +            to a CA bundle to use
    +        :param cert: The SSL certificate to verify.
    +        """
    +        if url.lower().startswith("https") and verify:
    +
    +            cert_loc = None
    +
    +            # Allow self-specified cert location.
    +            if verify is not True:
    +                cert_loc = verify
    +
    +            if not cert_loc:
    +                cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH)
    +
    +            if not cert_loc or not os.path.exists(cert_loc):
    +                raise OSError(
    +                    f"Could not find a suitable TLS CA certificate bundle, "
    +                    f"invalid path: {cert_loc}"
    +                )
    +
    +            conn.cert_reqs = "CERT_REQUIRED"
    +
    +            if not os.path.isdir(cert_loc):
    +                conn.ca_certs = cert_loc
    +            else:
    +                conn.ca_cert_dir = cert_loc
    +        else:
    +            conn.cert_reqs = "CERT_NONE"
    +            conn.ca_certs = None
    +            conn.ca_cert_dir = None
    +
    +        if cert:
    +            if not isinstance(cert, basestring):
    +                conn.cert_file = cert[0]
    +                conn.key_file = cert[1]
    +            else:
    +                conn.cert_file = cert
    +                conn.key_file = None
    +            if conn.cert_file and not os.path.exists(conn.cert_file):
    +                raise OSError(
    +                    f"Could not find the TLS certificate file, "
    +                    f"invalid path: {conn.cert_file}"
    +                )
    +            if conn.key_file and not os.path.exists(conn.key_file):
    +                raise OSError(
    +                    f"Could not find the TLS key file, invalid path: {conn.key_file}"
    +                )
    +
    +    def build_response(self, req, resp):
    +        """Builds a :class:`Response <requests.Response>` object from a urllib3
    +        response. This should not be called from user code, and is only exposed
    +        for use when subclassing the
    +        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`
    +
    +        :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response.
    +        :param resp: The urllib3 response object.
    +        :rtype: requests.Response
    +        """
    +        response = Response()
    +
    +        # Fallback to None if there's no status_code, for whatever reason.
    +        response.status_code = getattr(resp, "status", None)
    +
    +        # Make headers case-insensitive.
    +        response.headers = CaseInsensitiveDict(getattr(resp, "headers", {}))
    +
    +        # Set encoding.
    +        response.encoding = get_encoding_from_headers(response.headers)
    +        response.raw = resp
    +        response.reason = response.raw.reason
    +
    +        if isinstance(req.url, bytes):
    +            response.url = req.url.decode("utf-8")
    +        else:
    +            response.url = req.url
    +
    +        # Add new cookies from the server.
    +        extract_cookies_to_jar(response.cookies, req, resp)
    +
    +        # Give the Response some context.
    +        response.request = req
    +        response.connection = self
    +
    +        return response
    +
    +    def get_connection(self, url, proxies=None):
    +        """Returns a urllib3 connection for the given URL. This should not be
    +        called from user code, and is only exposed for use when subclassing the
    +        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
    +
    +        :param url: The URL to connect to.
    +        :param proxies: (optional) A Requests-style dictionary of proxies used on this request.
    +        :rtype: urllib3.ConnectionPool
    +        """
    +        proxy = select_proxy(url, proxies)
    +
    +        if proxy:
    +            proxy = prepend_scheme_if_needed(proxy, "http")
    +            proxy_url = parse_url(proxy)
    +            if not proxy_url.host:
    +                raise InvalidProxyURL(
    +                    "Please check proxy URL. It is malformed "
    +                    "and could be missing the host."
    +                )
    +            proxy_manager = self.proxy_manager_for(proxy)
    +            conn = proxy_manager.connection_from_url(url)
    +        else:
    +            # Only scheme should be lower case
    +            parsed = urlparse(url)
    +            url = parsed.geturl()
    +            conn = self.poolmanager.connection_from_url(url)
    +
    +        return conn
    +
    +    def close(self):
    +        """Disposes of any internal state.
    +
    +        Currently, this closes the PoolManager and any active ProxyManager,
    +        which closes any pooled connections.
    +        """
    +        self.poolmanager.clear()
    +        for proxy in self.proxy_manager.values():
    +            proxy.clear()
    +
    +    def request_url(self, request, proxies):
    +        """Obtain the url to use when making the final request.
    +
    +        If the message is being sent through a HTTP proxy, the full URL has to
    +        be used. Otherwise, we should only use the path portion of the URL.
    +
    +        This should not be called from user code, and is only exposed for use
    +        when subclassing the
    +        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
    +
    +        :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
    +        :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs.
    +        :rtype: str
    +        """
    +        proxy = select_proxy(request.url, proxies)
    +        scheme = urlparse(request.url).scheme
    +
    +        is_proxied_http_request = proxy and scheme != "https"
    +        using_socks_proxy = False
    +        if proxy:
    +            proxy_scheme = urlparse(proxy).scheme.lower()
    +            using_socks_proxy = proxy_scheme.startswith("socks")
    +
    +        url = request.path_url
    +        if is_proxied_http_request and not using_socks_proxy:
    +            url = urldefragauth(request.url)
    +
    +        return url
    +
    +    def add_headers(self, request, **kwargs):
    +        """Add any headers needed by the connection. As of v2.0 this does
    +        nothing by default, but is left for overriding by users that subclass
    +        the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
    +
    +        This should not be called from user code, and is only exposed for use
    +        when subclassing the
    +        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
    +
    +        :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to.
    +        :param kwargs: The keyword arguments from the call to send().
    +        """
    +        pass
    +
    +    def proxy_headers(self, proxy):
    +        """Returns a dictionary of the headers to add to any request sent
    +        through a proxy. This works with urllib3 magic to ensure that they are
    +        correctly sent to the proxy, rather than in a tunnelled request if
    +        CONNECT is being used.
    +
    +        This should not be called from user code, and is only exposed for use
    +        when subclassing the
    +        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
    +
    +        :param proxy: The url of the proxy being used for this request.
    +        :rtype: dict
    +        """
    +        headers = {}
    +        username, password = get_auth_from_url(proxy)
    +
    +        if username:
    +            headers["Proxy-Authorization"] = _basic_auth_str(username, password)
    +
    +        return headers
    +
    +    def send(
    +        self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
    +    ):
    +        """Sends PreparedRequest object. Returns Response object.
    +
    +        :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
    +        :param stream: (optional) Whether to stream the request content.
    +        :param timeout: (optional) How long to wait for the server to send
    +            data before giving up, as a float, or a :ref:`(connect timeout,
    +            read timeout) <timeouts>` tuple.
    +        :type timeout: float or tuple or urllib3 Timeout object
    +        :param verify: (optional) Either a boolean, in which case it controls whether
    +            we verify the server's TLS certificate, or a string, in which case it
    +            must be a path to a CA bundle to use
    +        :param cert: (optional) Any user-provided SSL certificate to be trusted.
    +        :param proxies: (optional) The proxies dictionary to apply to the request.
    +        :rtype: requests.Response
    +        """
    +
    +        try:
    +            conn = self.get_connection(request.url, proxies)
    +        except LocationValueError as e:
    +            raise InvalidURL(e, request=request)
    +
    +        self.cert_verify(conn, request.url, verify, cert)
    +        url = self.request_url(request, proxies)
    +        self.add_headers(
    +            request,
    +            stream=stream,
    +            timeout=timeout,
    +            verify=verify,
    +            cert=cert,
    +            proxies=proxies,
    +        )
    +
    +        chunked = not (request.body is None or "Content-Length" in request.headers)
    +
    +        if isinstance(timeout, tuple):
    +            try:
    +                connect, read = timeout
    +                timeout = TimeoutSauce(connect=connect, read=read)
    +            except ValueError:
    +                raise ValueError(
    +                    f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, "
    +                    f"or a single float to set both timeouts to the same value."
    +                )
    +        elif isinstance(timeout, TimeoutSauce):
    +            pass
    +        else:
    +            timeout = TimeoutSauce(connect=timeout, read=timeout)
    +
    +        try:
    +            if not chunked:
    +                resp = conn.urlopen(
    +                    method=request.method,
    +                    url=url,
    +                    body=request.body,
    +                    headers=request.headers,
    +                    redirect=False,
    +                    assert_same_host=False,
    +                    preload_content=False,
    +                    decode_content=False,
    +                    retries=self.max_retries,
    +                    timeout=timeout,
    +                )
    +
    +            # Send the request.
    +            else:
    +                if hasattr(conn, "proxy_pool"):
    +                    conn = conn.proxy_pool
    +
    +                low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT)
    +
    +                try:
    +                    skip_host = "Host" in request.headers
    +                    low_conn.putrequest(
    +                        request.method,
    +                        url,
    +                        skip_accept_encoding=True,
    +                        skip_host=skip_host,
    +                    )
    +
    +                    for header, value in request.headers.items():
    +                        low_conn.putheader(header, value)
    +
    +                    low_conn.endheaders()
    +
    +                    for i in request.body:
    +                        low_conn.send(hex(len(i))[2:].encode("utf-8"))
    +                        low_conn.send(b"\r\n")
    +                        low_conn.send(i)
    +                        low_conn.send(b"\r\n")
    +                    low_conn.send(b"0\r\n\r\n")
    +
    +                    # Receive the response from the server
    +                    r = low_conn.getresponse()
    +
    +                    resp = HTTPResponse.from_httplib(
    +                        r,
    +                        pool=conn,
    +                        connection=low_conn,
    +                        preload_content=False,
    +                        decode_content=False,
    +                    )
    +                except Exception:
    +                    # If we hit any problems here, clean up the connection.
    +                    # Then, raise so that we can handle the actual exception.
    +                    low_conn.close()
    +                    raise
    +
    +        except (ProtocolError, OSError) as err:
    +            raise ConnectionError(err, request=request)
    +
    +        except MaxRetryError as e:
    +            if isinstance(e.reason, ConnectTimeoutError):
    +                # TODO: Remove this in 3.0.0: see #2811
    +                if not isinstance(e.reason, NewConnectionError):
    +                    raise ConnectTimeout(e, request=request)
    +
    +            if isinstance(e.reason, ResponseError):
    +                raise RetryError(e, request=request)
    +
    +            if isinstance(e.reason, _ProxyError):
    +                raise ProxyError(e, request=request)
    +
    +            if isinstance(e.reason, _SSLError):
    +                # This branch is for urllib3 v1.22 and later.
    +                raise SSLError(e, request=request)
    +
    +            raise ConnectionError(e, request=request)
    +
    +        except ClosedPoolError as e:
    +            raise ConnectionError(e, request=request)
    +
    +        except _ProxyError as e:
    +            raise ProxyError(e)
    +
    +        except (_SSLError, _HTTPError) as e:
    +            if isinstance(e, _SSLError):
    +                # This branch is for urllib3 versions earlier than v1.22
    +                raise SSLError(e, request=request)
    +            elif isinstance(e, ReadTimeoutError):
    +                raise ReadTimeout(e, request=request)
    +            elif isinstance(e, _InvalidHeader):
    +                raise InvalidHeader(e, request=request)
    +            else:
    +                raise
    +
    +        return self.build_response(request, resp)
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/api.py b/deployment-apps/metricator-for-nmon/lib/requests/api.py
    new file mode 100644
    index 0000000..2f71aae
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/api.py
    @@ -0,0 +1,157 @@
    +"""
    +requests.api
    +~~~~~~~~~~~~
    +
    +This module implements the Requests API.
    +
    +:copyright: (c) 2012 by Kenneth Reitz.
    +:license: Apache2, see LICENSE for more details.
    +"""
    +
    +from . import sessions
    +
    +
    +def request(method, url, **kwargs):
    +    """Constructs and sends a :class:`Request <Request>`.
    +
    +    :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
    +    :param url: URL for the new :class:`Request` object.
    +    :param params: (optional) Dictionary, list of tuples or bytes to send
    +        in the query string for the :class:`Request`.
    +    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
    +        object to send in the body of the :class:`Request`.
    +    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
    +    :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
    +    :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
    +    :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
    +        ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
    +        or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
    +        defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
    +        to add for the file.
    +    :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
    +    :param timeout: (optional) How many seconds to wait for the server to send data
    +        before giving up, as a float, or a :ref:`(connect timeout, read
    +        timeout) <timeouts>` tuple.
    +    :type timeout: float or tuple
    +    :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
    +    :type allow_redirects: bool
    +    :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
    +    :param verify: (optional) Either a boolean, in which case it controls whether we verify
    +            the server's TLS certificate, or a string, in which case it must be a path
    +            to a CA bundle to use. Defaults to ``True``.
    +    :param stream: (optional) if ``False``, the response content will be immediately downloaded.
    +    :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
    +    :return: :class:`Response <Response>` object
    +    :rtype: requests.Response
    +
    +    Usage::
    +
    +      >>> import requests
    +      >>> req = requests.request('GET', 'https://httpbin.org/get')
    +      >>> req
    +      <Response [200]>
    +    """
    +
    +    # By using the 'with' statement we are sure the session is closed, thus we
    +    # avoid leaving sockets open which can trigger a ResourceWarning in some
    +    # cases, and look like a memory leak in others.
    +    with sessions.Session() as session:
    +        return session.request(method=method, url=url, **kwargs)
    +
    +
    +def get(url, params=None, **kwargs):
    +    r"""Sends a GET request.
    +
    +    :param url: URL for the new :class:`Request` object.
    +    :param params: (optional) Dictionary, list of tuples or bytes to send
    +        in the query string for the :class:`Request`.
    +    :param \*\*kwargs: Optional arguments that ``request`` takes.
    +    :return: :class:`Response <Response>` object
    +    :rtype: requests.Response
    +    """
    +
    +    return request("get", url, params=params, **kwargs)
    +
    +
    +def options(url, **kwargs):
    +    r"""Sends an OPTIONS request.
    +
    +    :param url: URL for the new :class:`Request` object.
    +    :param \*\*kwargs: Optional arguments that ``request`` takes.
    +    :return: :class:`Response <Response>` object
    +    :rtype: requests.Response
    +    """
    +
    +    return request("options", url, **kwargs)
    +
    +
    +def head(url, **kwargs):
    +    r"""Sends a HEAD request.
    +
    +    :param url: URL for the new :class:`Request` object.
    +    :param \*\*kwargs: Optional arguments that ``request`` takes. If
    +        `allow_redirects` is not provided, it will be set to `False` (as
    +        opposed to the default :meth:`request` behavior).
    +    :return: :class:`Response <Response>` object
    +    :rtype: requests.Response
    +    """
    +
    +    kwargs.setdefault("allow_redirects", False)
    +    return request("head", url, **kwargs)
    +
    +
    +def post(url, data=None, json=None, **kwargs):
    +    r"""Sends a POST request.
    +
    +    :param url: URL for the new :class:`Request` object.
    +    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
    +        object to send in the body of the :class:`Request`.
    +    :param json: (optional) json data to send in the body of the :class:`Request`.
    +    :param \*\*kwargs: Optional arguments that ``request`` takes.
    +    :return: :class:`Response <Response>` object
    +    :rtype: requests.Response
    +    """
    +
    +    return request("post", url, data=data, json=json, **kwargs)
    +
    +
    +def put(url, data=None, **kwargs):
    +    r"""Sends a PUT request.
    +
    +    :param url: URL for the new :class:`Request` object.
    +    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
    +        object to send in the body of the :class:`Request`.
    +    :param json: (optional) json data to send in the body of the :class:`Request`.
    +    :param \*\*kwargs: Optional arguments that ``request`` takes.
    +    :return: :class:`Response <Response>` object
    +    :rtype: requests.Response
    +    """
    +
    +    return request("put", url, data=data, **kwargs)
    +
    +
    +def patch(url, data=None, **kwargs):
    +    r"""Sends a PATCH request.
    +
    +    :param url: URL for the new :class:`Request` object.
    +    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
    +        object to send in the body of the :class:`Request`.
    +    :param json: (optional) json data to send in the body of the :class:`Request`.
    +    :param \*\*kwargs: Optional arguments that ``request`` takes.
    +    :return: :class:`Response <Response>` object
    +    :rtype: requests.Response
    +    """
    +
    +    return request("patch", url, data=data, **kwargs)
    +
    +
    +def delete(url, **kwargs):
    +    r"""Sends a DELETE request.
    +
    +    :param url: URL for the new :class:`Request` object.
    +    :param \*\*kwargs: Optional arguments that ``request`` takes.
    +    :return: :class:`Response <Response>` object
    +    :rtype: requests.Response
    +    """
    +
    +    return request("delete", url, **kwargs)
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/auth.py b/deployment-apps/metricator-for-nmon/lib/requests/auth.py
    new file mode 100644
    index 0000000..9733686
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/auth.py
    @@ -0,0 +1,315 @@
    +"""
    +requests.auth
    +~~~~~~~~~~~~~
    +
    +This module contains the authentication handlers for Requests.
    +"""
    +
    +import hashlib
    +import os
    +import re
    +import threading
    +import time
    +import warnings
    +from base64 import b64encode
    +
    +from ._internal_utils import to_native_string
    +from .compat import basestring, str, urlparse
    +from .cookies import extract_cookies_to_jar
    +from .utils import parse_dict_header
    +
    +CONTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded"
    +CONTENT_TYPE_MULTI_PART = "multipart/form-data"
    +
    +
    +def _basic_auth_str(username, password):
    +    """Returns a Basic Auth string."""
    +
    +    # "I want us to put a big-ol' comment on top of it that
    +    # says that this behaviour is dumb but we need to preserve
    +    # it because people are relying on it."
    +    #    - Lukasa
    +    #
    +    # These are here solely to maintain backwards compatibility
    +    # for things like ints. This will be removed in 3.0.0.
    +    if not isinstance(username, basestring):
    +        warnings.warn(
    +            "Non-string usernames will no longer be supported in Requests "
    +            "3.0.0. Please convert the object you've passed in ({!r}) to "
    +            "a string or bytes object in the near future to avoid "
    +            "problems.".format(username),
    +            category=DeprecationWarning,
    +        )
    +        username = str(username)
    +
    +    if not isinstance(password, basestring):
    +        warnings.warn(
    +            "Non-string passwords will no longer be supported in Requests "
    +            "3.0.0. Please convert the object you've passed in ({!r}) to "
    +            "a string or bytes object in the near future to avoid "
    +            "problems.".format(type(password)),
    +            category=DeprecationWarning,
    +        )
    +        password = str(password)
    +    # -- End Removal --
    +
    +    if isinstance(username, str):
    +        username = username.encode("latin1")
    +
    +    if isinstance(password, str):
    +        password = password.encode("latin1")
    +
    +    authstr = "Basic " + to_native_string(
    +        b64encode(b":".join((username, password))).strip()
    +    )
    +
    +    return authstr
    +
    +
    +class AuthBase:
    +    """Base class that all auth implementations derive from"""
    +
    +    def __call__(self, r):
    +        raise NotImplementedError("Auth hooks must be callable.")
    +
    +
    +class HTTPBasicAuth(AuthBase):
    +    """Attaches HTTP Basic Authentication to the given Request object."""
    +
    +    def __init__(self, username, password):
    +        self.username = username
    +        self.password = password
    +
    +    def __eq__(self, other):
    +        return all(
    +            [
    +                self.username == getattr(other, "username", None),
    +                self.password == getattr(other, "password", None),
    +            ]
    +        )
    +
    +    def __ne__(self, other):
    +        return not self == other
    +
    +    def __call__(self, r):
    +        r.headers["Authorization"] = _basic_auth_str(self.username, self.password)
    +        return r
    +
    +
    +class HTTPProxyAuth(HTTPBasicAuth):
    +    """Attaches HTTP Proxy Authentication to a given Request object."""
    +
    +    def __call__(self, r):
    +        r.headers["Proxy-Authorization"] = _basic_auth_str(self.username, self.password)
    +        return r
    +
    +
    +class HTTPDigestAuth(AuthBase):
    +    """Attaches HTTP Digest Authentication to the given Request object."""
    +
    +    def __init__(self, username, password):
    +        self.username = username
    +        self.password = password
    +        # Keep state in per-thread local storage
    +        self._thread_local = threading.local()
    +
    +    def init_per_thread_state(self):
    +        # Ensure state is initialized just once per-thread
    +        if not hasattr(self._thread_local, "init"):
    +            self._thread_local.init = True
    +            self._thread_local.last_nonce = ""
    +            self._thread_local.nonce_count = 0
    +            self._thread_local.chal = {}
    +            self._thread_local.pos = None
    +            self._thread_local.num_401_calls = None
    +
    +    def build_digest_header(self, method, url):
    +        """
    +        :rtype: str
    +        """
    +
    +        realm = self._thread_local.chal["realm"]
    +        nonce = self._thread_local.chal["nonce"]
    +        qop = self._thread_local.chal.get("qop")
    +        algorithm = self._thread_local.chal.get("algorithm")
    +        opaque = self._thread_local.chal.get("opaque")
    +        hash_utf8 = None
    +
    +        if algorithm is None:
    +            _algorithm = "MD5"
    +        else:
    +            _algorithm = algorithm.upper()
    +        # lambdas assume digest modules are imported at the top level
    +        if _algorithm == "MD5" or _algorithm == "MD5-SESS":
    +
    +            def md5_utf8(x):
    +                if isinstance(x, str):
    +                    x = x.encode("utf-8")
    +                return hashlib.md5(x).hexdigest()
    +
    +            hash_utf8 = md5_utf8
    +        elif _algorithm == "SHA":
    +
    +            def sha_utf8(x):
    +                if isinstance(x, str):
    +                    x = x.encode("utf-8")
    +                return hashlib.sha1(x).hexdigest()
    +
    +            hash_utf8 = sha_utf8
    +        elif _algorithm == "SHA-256":
    +
    +            def sha256_utf8(x):
    +                if isinstance(x, str):
    +                    x = x.encode("utf-8")
    +                return hashlib.sha256(x).hexdigest()
    +
    +            hash_utf8 = sha256_utf8
    +        elif _algorithm == "SHA-512":
    +
    +            def sha512_utf8(x):
    +                if isinstance(x, str):
    +                    x = x.encode("utf-8")
    +                return hashlib.sha512(x).hexdigest()
    +
    +            hash_utf8 = sha512_utf8
    +
    +        KD = lambda s, d: hash_utf8(f"{s}:{d}")  # noqa:E731
    +
    +        if hash_utf8 is None:
    +            return None
    +
    +        # XXX not implemented yet
    +        entdig = None
    +        p_parsed = urlparse(url)
    +        #: path is request-uri defined in RFC 2616 which should not be empty
    +        path = p_parsed.path or "/"
    +        if p_parsed.query:
    +            path += f"?{p_parsed.query}"
    +
    +        A1 = f"{self.username}:{realm}:{self.password}"
    +        A2 = f"{method}:{path}"
    +
    +        HA1 = hash_utf8(A1)
    +        HA2 = hash_utf8(A2)
    +
    +        if nonce == self._thread_local.last_nonce:
    +            self._thread_local.nonce_count += 1
    +        else:
    +            self._thread_local.nonce_count = 1
    +        ncvalue = f"{self._thread_local.nonce_count:08x}"
    +        s = str(self._thread_local.nonce_count).encode("utf-8")
    +        s += nonce.encode("utf-8")
    +        s += time.ctime().encode("utf-8")
    +        s += os.urandom(8)
    +
    +        cnonce = hashlib.sha1(s).hexdigest()[:16]
    +        if _algorithm == "MD5-SESS":
    +            HA1 = hash_utf8(f"{HA1}:{nonce}:{cnonce}")
    +
    +        if not qop:
    +            respdig = KD(HA1, f"{nonce}:{HA2}")
    +        elif qop == "auth" or "auth" in qop.split(","):
    +            noncebit = f"{nonce}:{ncvalue}:{cnonce}:auth:{HA2}"
    +            respdig = KD(HA1, noncebit)
    +        else:
    +            # XXX handle auth-int.
    +            return None
    +
    +        self._thread_local.last_nonce = nonce
    +
    +        # XXX should the partial digests be encoded too?
    +        base = (
    +            f'username="{self.username}", realm="{realm}", nonce="{nonce}", '
    +            f'uri="{path}", response="{respdig}"'
    +        )
    +        if opaque:
    +            base += f', opaque="{opaque}"'
    +        if algorithm:
    +            base += f', algorithm="{algorithm}"'
    +        if entdig:
    +            base += f', digest="{entdig}"'
    +        if qop:
    +            base += f', qop="auth", nc={ncvalue}, cnonce="{cnonce}"'
    +
    +        return f"Digest {base}"
    +
    +    def handle_redirect(self, r, **kwargs):
    +        """Reset num_401_calls counter on redirects."""
    +        if r.is_redirect:
    +            self._thread_local.num_401_calls = 1
    +
    +    def handle_401(self, r, **kwargs):
    +        """
    +        Takes the given response and tries digest-auth, if needed.
    +
    +        :rtype: requests.Response
    +        """
    +
    +        # If response is not 4xx, do not auth
    +        # See https://github.com/psf/requests/issues/3772
    +        if not 400 <= r.status_code < 500:
    +            self._thread_local.num_401_calls = 1
    +            return r
    +
    +        if self._thread_local.pos is not None:
    +            # Rewind the file position indicator of the body to where
    +            # it was to resend the request.
    +            r.request.body.seek(self._thread_local.pos)
    +        s_auth = r.headers.get("www-authenticate", "")
    +
    +        if "digest" in s_auth.lower() and self._thread_local.num_401_calls < 2:
    +
    +            self._thread_local.num_401_calls += 1
    +            pat = re.compile(r"digest ", flags=re.IGNORECASE)
    +            self._thread_local.chal = parse_dict_header(pat.sub("", s_auth, count=1))
    +
    +            # Consume content and release the original connection
    +            # to allow our new request to reuse the same one.
    +            r.content
    +            r.close()
    +            prep = r.request.copy()
    +            extract_cookies_to_jar(prep._cookies, r.request, r.raw)
    +            prep.prepare_cookies(prep._cookies)
    +
    +            prep.headers["Authorization"] = self.build_digest_header(
    +                prep.method, prep.url
    +            )
    +            _r = r.connection.send(prep, **kwargs)
    +            _r.history.append(r)
    +            _r.request = prep
    +
    +            return _r
    +
    +        self._thread_local.num_401_calls = 1
    +        return r
    +
    +    def __call__(self, r):
    +        # Initialize per-thread state, if needed
    +        self.init_per_thread_state()
    +        # If we have a saved nonce, skip the 401
    +        if self._thread_local.last_nonce:
    +            r.headers["Authorization"] = self.build_digest_header(r.method, r.url)
    +        try:
    +            self._thread_local.pos = r.body.tell()
    +        except AttributeError:
    +            # In the case of HTTPDigestAuth being reused and the body of
    +            # the previous request was a file-like object, pos has the
    +            # file position of the previous body. Ensure it's set to
    +            # None.
    +            self._thread_local.pos = None
    +        r.register_hook("response", self.handle_401)
    +        r.register_hook("response", self.handle_redirect)
    +        self._thread_local.num_401_calls = 1
    +
    +        return r
    +
    +    def __eq__(self, other):
    +        return all(
    +            [
    +                self.username == getattr(other, "username", None),
    +                self.password == getattr(other, "password", None),
    +            ]
    +        )
    +
    +    def __ne__(self, other):
    +        return not self == other
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/certs.py b/deployment-apps/metricator-for-nmon/lib/requests/certs.py
    new file mode 100644
    index 0000000..be422c3
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/certs.py
    @@ -0,0 +1,17 @@
    +#!/usr/bin/env python
    +
    +"""
    +requests.certs
    +~~~~~~~~~~~~~~
    +
    +This module returns the preferred default CA certificate bundle. There is
    +only one — the one from the certifi package.
    +
    +If you are packaging Requests, e.g., for a Linux distribution or a managed
    +environment, you can change the definition of where() to return a separately
    +packaged CA bundle.
    +"""
    +from certifi import where
    +
    +if __name__ == "__main__":
    +    print(where())
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/compat.py b/deployment-apps/metricator-for-nmon/lib/requests/compat.py
    new file mode 100644
    index 0000000..6776163
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/compat.py
    @@ -0,0 +1,79 @@
    +"""
    +requests.compat
    +~~~~~~~~~~~~~~~
    +
    +This module previously handled import compatibility issues
    +between Python 2 and Python 3. It remains for backwards
    +compatibility until the next major version.
    +"""
    +
    +try:
    +    import chardet
    +except ImportError:
    +    import charset_normalizer as chardet
    +
    +import sys
    +
    +# -------
    +# Pythons
    +# -------
    +
    +# Syntax sugar.
    +_ver = sys.version_info
    +
    +#: Python 2.x?
    +is_py2 = _ver[0] == 2
    +
    +#: Python 3.x?
    +is_py3 = _ver[0] == 3
    +
    +# json/simplejson module import resolution
    +has_simplejson = False
    +try:
    +    import simplejson as json
    +
    +    has_simplejson = True
    +except ImportError:
    +    import json
    +
    +if has_simplejson:
    +    from simplejson import JSONDecodeError
    +else:
    +    from json import JSONDecodeError
    +
    +# Keep OrderedDict for backwards compatibility.
    +from collections import OrderedDict
    +from collections.abc import Callable, Mapping, MutableMapping
    +from http import cookiejar as cookielib
    +from http.cookies import Morsel
    +from io import StringIO
    +
    +# --------------
    +# Legacy Imports
    +# --------------
    +from urllib.parse import (
    +    quote,
    +    quote_plus,
    +    unquote,
    +    unquote_plus,
    +    urldefrag,
    +    urlencode,
    +    urljoin,
    +    urlparse,
    +    urlsplit,
    +    urlunparse,
    +)
    +from urllib.request import (
    +    getproxies,
    +    getproxies_environment,
    +    parse_http_list,
    +    proxy_bypass,
    +    proxy_bypass_environment,
    +)
    +
    +builtin_str = str
    +str = str
    +bytes = bytes
    +basestring = (str, bytes)
    +numeric_types = (int, float)
    +integer_types = (int,)
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/cookies.py b/deployment-apps/metricator-for-nmon/lib/requests/cookies.py
    new file mode 100644
    index 0000000..bf54ab2
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/cookies.py
    @@ -0,0 +1,561 @@
    +"""
    +requests.cookies
    +~~~~~~~~~~~~~~~~
    +
    +Compatibility code to be able to use `cookielib.CookieJar` with requests.
    +
    +requests.utils imports from here, so be careful with imports.
    +"""
    +
    +import calendar
    +import copy
    +import time
    +
    +from ._internal_utils import to_native_string
    +from .compat import Morsel, MutableMapping, cookielib, urlparse, urlunparse
    +
    +try:
    +    import threading
    +except ImportError:
    +    import dummy_threading as threading
    +
    +
    +class MockRequest:
    +    """Wraps a `requests.Request` to mimic a `urllib2.Request`.
    +
    +    The code in `cookielib.CookieJar` expects this interface in order to correctly
    +    manage cookie policies, i.e., determine whether a cookie can be set, given the
    +    domains of the request and the cookie.
    +
    +    The original request object is read-only. The client is responsible for collecting
    +    the new headers via `get_new_headers()` and interpreting them appropriately. You
    +    probably want `get_cookie_header`, defined below.
    +    """
    +
    +    def __init__(self, request):
    +        self._r = request
    +        self._new_headers = {}
    +        self.type = urlparse(self._r.url).scheme
    +
    +    def get_type(self):
    +        return self.type
    +
    +    def get_host(self):
    +        return urlparse(self._r.url).netloc
    +
    +    def get_origin_req_host(self):
    +        return self.get_host()
    +
    +    def get_full_url(self):
    +        # Only return the response's URL if the user hadn't set the Host
    +        # header
    +        if not self._r.headers.get("Host"):
    +            return self._r.url
    +        # If they did set it, retrieve it and reconstruct the expected domain
    +        host = to_native_string(self._r.headers["Host"], encoding="utf-8")
    +        parsed = urlparse(self._r.url)
    +        # Reconstruct the URL as we expect it
    +        return urlunparse(
    +            [
    +                parsed.scheme,
    +                host,
    +                parsed.path,
    +                parsed.params,
    +                parsed.query,
    +                parsed.fragment,
    +            ]
    +        )
    +
    +    def is_unverifiable(self):
    +        return True
    +
    +    def has_header(self, name):
    +        return name in self._r.headers or name in self._new_headers
    +
    +    def get_header(self, name, default=None):
    +        return self._r.headers.get(name, self._new_headers.get(name, default))
    +
    +    def add_header(self, key, val):
    +        """cookielib has no legitimate use for this method; add it back if you find one."""
    +        raise NotImplementedError(
    +            "Cookie headers should be added with add_unredirected_header()"
    +        )
    +
    +    def add_unredirected_header(self, name, value):
    +        self._new_headers[name] = value
    +
    +    def get_new_headers(self):
    +        return self._new_headers
    +
    +    @property
    +    def unverifiable(self):
    +        return self.is_unverifiable()
    +
    +    @property
    +    def origin_req_host(self):
    +        return self.get_origin_req_host()
    +
    +    @property
    +    def host(self):
    +        return self.get_host()
    +
    +
    +class MockResponse:
    +    """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`.
    +
    +    ...what? Basically, expose the parsed HTTP headers from the server response
    +    the way `cookielib` expects to see them.
    +    """
    +
    +    def __init__(self, headers):
    +        """Make a MockResponse for `cookielib` to read.
    +
    +        :param headers: a httplib.HTTPMessage or analogous carrying the headers
    +        """
    +        self._headers = headers
    +
    +    def info(self):
    +        return self._headers
    +
    +    def getheaders(self, name):
    +        self._headers.getheaders(name)
    +
    +
    +def extract_cookies_to_jar(jar, request, response):
    +    """Extract the cookies from the response into a CookieJar.
    +
    +    :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar)
    +    :param request: our own requests.Request object
    +    :param response: urllib3.HTTPResponse object
    +    """
    +    if not (hasattr(response, "_original_response") and response._original_response):
    +        return
    +    # the _original_response field is the wrapped httplib.HTTPResponse object,
    +    req = MockRequest(request)
    +    # pull out the HTTPMessage with the headers and put it in the mock:
    +    res = MockResponse(response._original_response.msg)
    +    jar.extract_cookies(res, req)
    +
    +
    +def get_cookie_header(jar, request):
    +    """
    +    Produce an appropriate Cookie header string to be sent with `request`, or None.
    +
    +    :rtype: str
    +    """
    +    r = MockRequest(request)
    +    jar.add_cookie_header(r)
    +    return r.get_new_headers().get("Cookie")
    +
    +
    +def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
    +    """Unsets a cookie by name, by default over all domains and paths.
    +
    +    Wraps CookieJar.clear(), is O(n).
    +    """
    +    clearables = []
    +    for cookie in cookiejar:
    +        if cookie.name != name:
    +            continue
    +        if domain is not None and domain != cookie.domain:
    +            continue
    +        if path is not None and path != cookie.path:
    +            continue
    +        clearables.append((cookie.domain, cookie.path, cookie.name))
    +
    +    for domain, path, name in clearables:
    +        cookiejar.clear(domain, path, name)
    +
    +
    +class CookieConflictError(RuntimeError):
    +    """There are two cookies that meet the criteria specified in the cookie jar.
    +    Use .get and .set and include domain and path args in order to be more specific.
    +    """
    +
    +
    +class RequestsCookieJar(cookielib.CookieJar, MutableMapping):
    +    """Compatibility class; is a cookielib.CookieJar, but exposes a dict
    +    interface.
    +
    +    This is the CookieJar we create by default for requests and sessions that
    +    don't specify one, since some clients may expect response.cookies and
    +    session.cookies to support dict operations.
    +
    +    Requests does not use the dict interface internally; it's just for
    +    compatibility with external client code. All requests code should work
    +    out of the box with externally provided instances of ``CookieJar``, e.g.
    +    ``LWPCookieJar`` and ``FileCookieJar``.
    +
    +    Unlike a regular CookieJar, this class is pickleable.
    +
    +    .. warning:: dictionary operations that are normally O(1) may be O(n).
    +    """
    +
    +    def get(self, name, default=None, domain=None, path=None):
    +        """Dict-like get() that also supports optional domain and path args in
    +        order to resolve naming collisions from using one cookie jar over
    +        multiple domains.
    +
    +        .. warning:: operation is O(n), not O(1).
    +        """
    +        try:
    +            return self._find_no_duplicates(name, domain, path)
    +        except KeyError:
    +            return default
    +
    +    def set(self, name, value, **kwargs):
    +        """Dict-like set() that also supports optional domain and path args in
    +        order to resolve naming collisions from using one cookie jar over
    +        multiple domains.
    +        """
    +        # support client code that unsets cookies by assignment of a None value:
    +        if value is None:
    +            remove_cookie_by_name(
    +                self, name, domain=kwargs.get("domain"), path=kwargs.get("path")
    +            )
    +            return
    +
    +        if isinstance(value, Morsel):
    +            c = morsel_to_cookie(value)
    +        else:
    +            c = create_cookie(name, value, **kwargs)
    +        self.set_cookie(c)
    +        return c
    +
    +    def iterkeys(self):
    +        """Dict-like iterkeys() that returns an iterator of names of cookies
    +        from the jar.
    +
    +        .. seealso:: itervalues() and iteritems().
    +        """
    +        for cookie in iter(self):
    +            yield cookie.name
    +
    +    def keys(self):
    +        """Dict-like keys() that returns a list of names of cookies from the
    +        jar.
    +
    +        .. seealso:: values() and items().
    +        """
    +        return list(self.iterkeys())
    +
    +    def itervalues(self):
    +        """Dict-like itervalues() that returns an iterator of values of cookies
    +        from the jar.
    +
    +        .. seealso:: iterkeys() and iteritems().
    +        """
    +        for cookie in iter(self):
    +            yield cookie.value
    +
    +    def values(self):
    +        """Dict-like values() that returns a list of values of cookies from the
    +        jar.
    +
    +        .. seealso:: keys() and items().
    +        """
    +        return list(self.itervalues())
    +
    +    def iteritems(self):
    +        """Dict-like iteritems() that returns an iterator of name-value tuples
    +        from the jar.
    +
    +        .. seealso:: iterkeys() and itervalues().
    +        """
    +        for cookie in iter(self):
    +            yield cookie.name, cookie.value
    +
    +    def items(self):
    +        """Dict-like items() that returns a list of name-value tuples from the
    +        jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a
    +        vanilla python dict of key value pairs.
    +
    +        .. seealso:: keys() and values().
    +        """
    +        return list(self.iteritems())
    +
    +    def list_domains(self):
    +        """Utility method to list all the domains in the jar."""
    +        domains = []
    +        for cookie in iter(self):
    +            if cookie.domain not in domains:
    +                domains.append(cookie.domain)
    +        return domains
    +
    +    def list_paths(self):
    +        """Utility method to list all the paths in the jar."""
    +        paths = []
    +        for cookie in iter(self):
    +            if cookie.path not in paths:
    +                paths.append(cookie.path)
    +        return paths
    +
    +    def multiple_domains(self):
    +        """Returns True if there are multiple domains in the jar.
    +        Returns False otherwise.
    +
    +        :rtype: bool
    +        """
    +        domains = []
    +        for cookie in iter(self):
    +            if cookie.domain is not None and cookie.domain in domains:
    +                return True
    +            domains.append(cookie.domain)
    +        return False  # there is only one domain in jar
    +
    +    def get_dict(self, domain=None, path=None):
    +        """Takes as an argument an optional domain and path and returns a plain
    +        old Python dict of name-value pairs of cookies that meet the
    +        requirements.
    +
    +        :rtype: dict
    +        """
    +        dictionary = {}
    +        for cookie in iter(self):
    +            if (domain is None or cookie.domain == domain) and (
    +                path is None or cookie.path == path
    +            ):
    +                dictionary[cookie.name] = cookie.value
    +        return dictionary
    +
    +    def __contains__(self, name):
    +        try:
    +            return super().__contains__(name)
    +        except CookieConflictError:
    +            return True
    +
    +    def __getitem__(self, name):
    +        """Dict-like __getitem__() for compatibility with client code. Throws
    +        exception if there are more than one cookie with name. In that case,
    +        use the more explicit get() method instead.
    +
    +        .. warning:: operation is O(n), not O(1).
    +        """
    +        return self._find_no_duplicates(name)
    +
    +    def __setitem__(self, name, value):
    +        """Dict-like __setitem__ for compatibility with client code. Throws
    +        exception if there is already a cookie of that name in the jar. In that
    +        case, use the more explicit set() method instead.
    +        """
    +        self.set(name, value)
    +
    +    def __delitem__(self, name):
    +        """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s
    +        ``remove_cookie_by_name()``.
    +        """
    +        remove_cookie_by_name(self, name)
    +
    +    def set_cookie(self, cookie, *args, **kwargs):
    +        if (
    +            hasattr(cookie.value, "startswith")
    +            and cookie.value.startswith('"')
    +            and cookie.value.endswith('"')
    +        ):
    +            cookie.value = cookie.value.replace('\\"', "")
    +        return super().set_cookie(cookie, *args, **kwargs)
    +
    +    def update(self, other):
    +        """Updates this jar with cookies from another CookieJar or dict-like"""
    +        if isinstance(other, cookielib.CookieJar):
    +            for cookie in other:
    +                self.set_cookie(copy.copy(cookie))
    +        else:
    +            super().update(other)
    +
    +    def _find(self, name, domain=None, path=None):
    +        """Requests uses this method internally to get cookie values.
    +
    +        If there are conflicting cookies, _find arbitrarily chooses one.
    +        See _find_no_duplicates if you want an exception thrown if there are
    +        conflicting cookies.
    +
    +        :param name: a string containing name of cookie
    +        :param domain: (optional) string containing domain of cookie
    +        :param path: (optional) string containing path of cookie
    +        :return: cookie.value
    +        """
    +        for cookie in iter(self):
    +            if cookie.name == name:
    +                if domain is None or cookie.domain == domain:
    +                    if path is None or cookie.path == path:
    +                        return cookie.value
    +
    +        raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
    +
    +    def _find_no_duplicates(self, name, domain=None, path=None):
    +        """Both ``__get_item__`` and ``get`` call this function: it's never
    +        used elsewhere in Requests.
    +
    +        :param name: a string containing name of cookie
    +        :param domain: (optional) string containing domain of cookie
    +        :param path: (optional) string containing path of cookie
    +        :raises KeyError: if cookie is not found
    +        :raises CookieConflictError: if there are multiple cookies
    +            that match name and optionally domain and path
    +        :return: cookie.value
    +        """
    +        toReturn = None
    +        for cookie in iter(self):
    +            if cookie.name == name:
    +                if domain is None or cookie.domain == domain:
    +                    if path is None or cookie.path == path:
    +                        if toReturn is not None:
    +                            # if there are multiple cookies that meet passed in criteria
    +                            raise CookieConflictError(
    +                                f"There are multiple cookies with name, {name!r}"
    +                            )
    +                        # we will eventually return this as long as no cookie conflict
    +                        toReturn = cookie.value
    +
    +        if toReturn:
    +            return toReturn
    +        raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
    +
    +    def __getstate__(self):
    +        """Unlike a normal CookieJar, this class is pickleable."""
    +        state = self.__dict__.copy()
    +        # remove the unpickleable RLock object
    +        state.pop("_cookies_lock")
    +        return state
    +
    +    def __setstate__(self, state):
    +        """Unlike a normal CookieJar, this class is pickleable."""
    +        self.__dict__.update(state)
    +        if "_cookies_lock" not in self.__dict__:
    +            self._cookies_lock = threading.RLock()
    +
    +    def copy(self):
    +        """Return a copy of this RequestsCookieJar."""
    +        new_cj = RequestsCookieJar()
    +        new_cj.set_policy(self.get_policy())
    +        new_cj.update(self)
    +        return new_cj
    +
    +    def get_policy(self):
    +        """Return the CookiePolicy instance used."""
    +        return self._policy
    +
    +
    +def _copy_cookie_jar(jar):
    +    if jar is None:
    +        return None
    +
    +    if hasattr(jar, "copy"):
    +        # We're dealing with an instance of RequestsCookieJar
    +        return jar.copy()
    +    # We're dealing with a generic CookieJar instance
    +    new_jar = copy.copy(jar)
    +    new_jar.clear()
    +    for cookie in jar:
    +        new_jar.set_cookie(copy.copy(cookie))
    +    return new_jar
    +
    +
    +def create_cookie(name, value, **kwargs):
    +    """Make a cookie from underspecified parameters.
    +
    +    By default, the pair of `name` and `value` will be set for the domain ''
    +    and sent on every request (this is sometimes called a "supercookie").
    +    """
    +    result = {
    +        "version": 0,
    +        "name": name,
    +        "value": value,
    +        "port": None,
    +        "domain": "",
    +        "path": "/",
    +        "secure": False,
    +        "expires": None,
    +        "discard": True,
    +        "comment": None,
    +        "comment_url": None,
    +        "rest": {"HttpOnly": None},
    +        "rfc2109": False,
    +    }
    +
    +    badargs = set(kwargs) - set(result)
    +    if badargs:
    +        raise TypeError(
    +            f"create_cookie() got unexpected keyword arguments: {list(badargs)}"
    +        )
    +
    +    result.update(kwargs)
    +    result["port_specified"] = bool(result["port"])
    +    result["domain_specified"] = bool(result["domain"])
    +    result["domain_initial_dot"] = result["domain"].startswith(".")
    +    result["path_specified"] = bool(result["path"])
    +
    +    return cookielib.Cookie(**result)
    +
    +
    +def morsel_to_cookie(morsel):
    +    """Convert a Morsel object into a Cookie containing the one k/v pair."""
    +
    +    expires = None
    +    if morsel["max-age"]:
    +        try:
    +            expires = int(time.time() + int(morsel["max-age"]))
    +        except ValueError:
    +            raise TypeError(f"max-age: {morsel['max-age']} must be integer")
    +    elif morsel["expires"]:
    +        time_template = "%a, %d-%b-%Y %H:%M:%S GMT"
    +        expires = calendar.timegm(time.strptime(morsel["expires"], time_template))
    +    return create_cookie(
    +        comment=morsel["comment"],
    +        comment_url=bool(morsel["comment"]),
    +        discard=False,
    +        domain=morsel["domain"],
    +        expires=expires,
    +        name=morsel.key,
    +        path=morsel["path"],
    +        port=None,
    +        rest={"HttpOnly": morsel["httponly"]},
    +        rfc2109=False,
    +        secure=bool(morsel["secure"]),
    +        value=morsel.value,
    +        version=morsel["version"] or 0,
    +    )
    +
    +
    +def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True):
    +    """Returns a CookieJar from a key/value dictionary.
    +
    +    :param cookie_dict: Dict of key/values to insert into CookieJar.
    +    :param cookiejar: (optional) A cookiejar to add the cookies to.
    +    :param overwrite: (optional) If False, will not replace cookies
    +        already in the jar with new ones.
    +    :rtype: CookieJar
    +    """
    +    if cookiejar is None:
    +        cookiejar = RequestsCookieJar()
    +
    +    if cookie_dict is not None:
    +        names_from_jar = [cookie.name for cookie in cookiejar]
    +        for name in cookie_dict:
    +            if overwrite or (name not in names_from_jar):
    +                cookiejar.set_cookie(create_cookie(name, cookie_dict[name]))
    +
    +    return cookiejar
    +
    +
    +def merge_cookies(cookiejar, cookies):
    +    """Add cookies to cookiejar and returns a merged CookieJar.
    +
    +    :param cookiejar: CookieJar object to add the cookies to.
    +    :param cookies: Dictionary or CookieJar object to be added.
    +    :rtype: CookieJar
    +    """
    +    if not isinstance(cookiejar, cookielib.CookieJar):
    +        raise ValueError("You can only merge into CookieJar")
    +
    +    if isinstance(cookies, dict):
    +        cookiejar = cookiejar_from_dict(cookies, cookiejar=cookiejar, overwrite=False)
    +    elif isinstance(cookies, cookielib.CookieJar):
    +        try:
    +            cookiejar.update(cookies)
    +        except AttributeError:
    +            for cookie_in_jar in cookies:
    +                cookiejar.set_cookie(cookie_in_jar)
    +
    +    return cookiejar
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/exceptions.py b/deployment-apps/metricator-for-nmon/lib/requests/exceptions.py
    new file mode 100644
    index 0000000..e1cedf8
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/exceptions.py
    @@ -0,0 +1,141 @@
    +"""
    +requests.exceptions
    +~~~~~~~~~~~~~~~~~~~
    +
    +This module contains the set of Requests' exceptions.
    +"""
    +from urllib3.exceptions import HTTPError as BaseHTTPError
    +
    +from .compat import JSONDecodeError as CompatJSONDecodeError
    +
    +
    +class RequestException(IOError):
    +    """There was an ambiguous exception that occurred while handling your
    +    request.
    +    """
    +
    +    def __init__(self, *args, **kwargs):
    +        """Initialize RequestException with `request` and `response` objects."""
    +        response = kwargs.pop("response", None)
    +        self.response = response
    +        self.request = kwargs.pop("request", None)
    +        if response is not None and not self.request and hasattr(response, "request"):
    +            self.request = self.response.request
    +        super().__init__(*args, **kwargs)
    +
    +
    +class InvalidJSONError(RequestException):
    +    """A JSON error occurred."""
    +
    +
    +class JSONDecodeError(InvalidJSONError, CompatJSONDecodeError):
    +    """Couldn't decode the text into json"""
    +
    +    def __init__(self, *args, **kwargs):
    +        """
    +        Construct the JSONDecodeError instance first with all
    +        args. Then use it's args to construct the IOError so that
    +        the json specific args aren't used as IOError specific args
    +        and the error message from JSONDecodeError is preserved.
    +        """
    +        CompatJSONDecodeError.__init__(self, *args)
    +        InvalidJSONError.__init__(self, *self.args, **kwargs)
    +
    +
    +class HTTPError(RequestException):
    +    """An HTTP error occurred."""
    +
    +
    +class ConnectionError(RequestException):
    +    """A Connection error occurred."""
    +
    +
    +class ProxyError(ConnectionError):
    +    """A proxy error occurred."""
    +
    +
    +class SSLError(ConnectionError):
    +    """An SSL error occurred."""
    +
    +
    +class Timeout(RequestException):
    +    """The request timed out.
    +
    +    Catching this error will catch both
    +    :exc:`~requests.exceptions.ConnectTimeout` and
    +    :exc:`~requests.exceptions.ReadTimeout` errors.
    +    """
    +
    +
    +class ConnectTimeout(ConnectionError, Timeout):
    +    """The request timed out while trying to connect to the remote server.
    +
    +    Requests that produced this error are safe to retry.
    +    """
    +
    +
    +class ReadTimeout(Timeout):
    +    """The server did not send any data in the allotted amount of time."""
    +
    +
    +class URLRequired(RequestException):
    +    """A valid URL is required to make a request."""
    +
    +
    +class TooManyRedirects(RequestException):
    +    """Too many redirects."""
    +
    +
    +class MissingSchema(RequestException, ValueError):
    +    """The URL scheme (e.g. http or https) is missing."""
    +
    +
    +class InvalidSchema(RequestException, ValueError):
    +    """The URL scheme provided is either invalid or unsupported."""
    +
    +
    +class InvalidURL(RequestException, ValueError):
    +    """The URL provided was somehow invalid."""
    +
    +
    +class InvalidHeader(RequestException, ValueError):
    +    """The header value provided was somehow invalid."""
    +
    +
    +class InvalidProxyURL(InvalidURL):
    +    """The proxy URL provided is invalid."""
    +
    +
    +class ChunkedEncodingError(RequestException):
    +    """The server declared chunked encoding but sent an invalid chunk."""
    +
    +
    +class ContentDecodingError(RequestException, BaseHTTPError):
    +    """Failed to decode response content."""
    +
    +
    +class StreamConsumedError(RequestException, TypeError):
    +    """The content for this response was already consumed."""
    +
    +
    +class RetryError(RequestException):
    +    """Custom retries logic failed"""
    +
    +
    +class UnrewindableBodyError(RequestException):
    +    """Requests encountered an error when trying to rewind a body."""
    +
    +
    +# Warnings
    +
    +
    +class RequestsWarning(Warning):
    +    """Base warning for Requests."""
    +
    +
    +class FileModeWarning(RequestsWarning, DeprecationWarning):
    +    """A file was opened in text mode, but Requests determined its binary length."""
    +
    +
    +class RequestsDependencyWarning(RequestsWarning):
    +    """An imported dependency doesn't match the expected version range."""
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/help.py b/deployment-apps/metricator-for-nmon/lib/requests/help.py
    new file mode 100644
    index 0000000..8fbcd65
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/help.py
    @@ -0,0 +1,134 @@
    +"""Module containing bug report helper(s)."""
    +
    +import json
    +import platform
    +import ssl
    +import sys
    +
    +import idna
    +import urllib3
    +
    +from . import __version__ as requests_version
    +
    +try:
    +    import charset_normalizer
    +except ImportError:
    +    charset_normalizer = None
    +
    +try:
    +    import chardet
    +except ImportError:
    +    chardet = None
    +
    +try:
    +    from urllib3.contrib import pyopenssl
    +except ImportError:
    +    pyopenssl = None
    +    OpenSSL = None
    +    cryptography = None
    +else:
    +    import cryptography
    +    import OpenSSL
    +
    +
    +def _implementation():
    +    """Return a dict with the Python implementation and version.
    +
    +    Provide both the name and the version of the Python implementation
    +    currently running. For example, on CPython 3.10.3 it will return
    +    {'name': 'CPython', 'version': '3.10.3'}.
    +
    +    This function works best on CPython and PyPy: in particular, it probably
    +    doesn't work for Jython or IronPython. Future investigation should be done
    +    to work out the correct shape of the code for those platforms.
    +    """
    +    implementation = platform.python_implementation()
    +
    +    if implementation == "CPython":
    +        implementation_version = platform.python_version()
    +    elif implementation == "PyPy":
    +        implementation_version = "{}.{}.{}".format(
    +            sys.pypy_version_info.major,
    +            sys.pypy_version_info.minor,
    +            sys.pypy_version_info.micro,
    +        )
    +        if sys.pypy_version_info.releaselevel != "final":
    +            implementation_version = "".join(
    +                [implementation_version, sys.pypy_version_info.releaselevel]
    +            )
    +    elif implementation == "Jython":
    +        implementation_version = platform.python_version()  # Complete Guess
    +    elif implementation == "IronPython":
    +        implementation_version = platform.python_version()  # Complete Guess
    +    else:
    +        implementation_version = "Unknown"
    +
    +    return {"name": implementation, "version": implementation_version}
    +
    +
    +def info():
    +    """Generate information for a bug report."""
    +    try:
    +        platform_info = {
    +            "system": platform.system(),
    +            "release": platform.release(),
    +        }
    +    except OSError:
    +        platform_info = {
    +            "system": "Unknown",
    +            "release": "Unknown",
    +        }
    +
    +    implementation_info = _implementation()
    +    urllib3_info = {"version": urllib3.__version__}
    +    charset_normalizer_info = {"version": None}
    +    chardet_info = {"version": None}
    +    if charset_normalizer:
    +        charset_normalizer_info = {"version": charset_normalizer.__version__}
    +    if chardet:
    +        chardet_info = {"version": chardet.__version__}
    +
    +    pyopenssl_info = {
    +        "version": None,
    +        "openssl_version": "",
    +    }
    +    if OpenSSL:
    +        pyopenssl_info = {
    +            "version": OpenSSL.__version__,
    +            "openssl_version": f"{OpenSSL.SSL.OPENSSL_VERSION_NUMBER:x}",
    +        }
    +    cryptography_info = {
    +        "version": getattr(cryptography, "__version__", ""),
    +    }
    +    idna_info = {
    +        "version": getattr(idna, "__version__", ""),
    +    }
    +
    +    system_ssl = ssl.OPENSSL_VERSION_NUMBER
    +    system_ssl_info = {"version": f"{system_ssl:x}" if system_ssl is not None else ""}
    +
    +    return {
    +        "platform": platform_info,
    +        "implementation": implementation_info,
    +        "system_ssl": system_ssl_info,
    +        "using_pyopenssl": pyopenssl is not None,
    +        "using_charset_normalizer": chardet is None,
    +        "pyOpenSSL": pyopenssl_info,
    +        "urllib3": urllib3_info,
    +        "chardet": chardet_info,
    +        "charset_normalizer": charset_normalizer_info,
    +        "cryptography": cryptography_info,
    +        "idna": idna_info,
    +        "requests": {
    +            "version": requests_version,
    +        },
    +    }
    +
    +
    +def main():
    +    """Pretty-print the bug information as JSON."""
    +    print(json.dumps(info(), sort_keys=True, indent=2))
    +
    +
    +if __name__ == "__main__":
    +    main()
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/hooks.py b/deployment-apps/metricator-for-nmon/lib/requests/hooks.py
    new file mode 100644
    index 0000000..d181ba2
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/hooks.py
    @@ -0,0 +1,33 @@
    +"""
    +requests.hooks
    +~~~~~~~~~~~~~~
    +
    +This module provides the capabilities for the Requests hooks system.
    +
    +Available hooks:
    +
    +``response``:
    +    The response generated from a Request.
    +"""
    +HOOKS = ["response"]
    +
    +
    +def default_hooks():
    +    return {event: [] for event in HOOKS}
    +
    +
    +# TODO: response is the only one
    +
    +
    +def dispatch_hook(key, hooks, hook_data, **kwargs):
    +    """Dispatches a hook dictionary on a given piece of data."""
    +    hooks = hooks or {}
    +    hooks = hooks.get(key)
    +    if hooks:
    +        if hasattr(hooks, "__call__"):
    +            hooks = [hooks]
    +        for hook in hooks:
    +            _hook_data = hook(hook_data, **kwargs)
    +            if _hook_data is not None:
    +                hook_data = _hook_data
    +    return hook_data
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/models.py b/deployment-apps/metricator-for-nmon/lib/requests/models.py
    new file mode 100644
    index 0000000..617a413
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/models.py
    @@ -0,0 +1,1034 @@
    +"""
    +requests.models
    +~~~~~~~~~~~~~~~
    +
    +This module contains the primary objects that power Requests.
    +"""
    +
    +import datetime
    +
    +# Import encoding now, to avoid implicit import later.
    +# Implicit import within threads may cause LookupError when standard library is in a ZIP,
    +# such as in Embedded Python. See https://github.com/psf/requests/issues/3578.
    +import encodings.idna  # noqa: F401
    +from io import UnsupportedOperation
    +
    +from urllib3.exceptions import (
    +    DecodeError,
    +    LocationParseError,
    +    ProtocolError,
    +    ReadTimeoutError,
    +    SSLError,
    +)
    +from urllib3.fields import RequestField
    +from urllib3.filepost import encode_multipart_formdata
    +from urllib3.util import parse_url
    +
    +from ._internal_utils import to_native_string, unicode_is_ascii
    +from .auth import HTTPBasicAuth
    +from .compat import (
    +    Callable,
    +    JSONDecodeError,
    +    Mapping,
    +    basestring,
    +    builtin_str,
    +    chardet,
    +    cookielib,
    +)
    +from .compat import json as complexjson
    +from .compat import urlencode, urlsplit, urlunparse
    +from .cookies import _copy_cookie_jar, cookiejar_from_dict, get_cookie_header
    +from .exceptions import (
    +    ChunkedEncodingError,
    +    ConnectionError,
    +    ContentDecodingError,
    +    HTTPError,
    +    InvalidJSONError,
    +    InvalidURL,
    +)
    +from .exceptions import JSONDecodeError as RequestsJSONDecodeError
    +from .exceptions import MissingSchema
    +from .exceptions import SSLError as RequestsSSLError
    +from .exceptions import StreamConsumedError
    +from .hooks import default_hooks
    +from .status_codes import codes
    +from .structures import CaseInsensitiveDict
    +from .utils import (
    +    check_header_validity,
    +    get_auth_from_url,
    +    guess_filename,
    +    guess_json_utf,
    +    iter_slices,
    +    parse_header_links,
    +    requote_uri,
    +    stream_decode_response_unicode,
    +    super_len,
    +    to_key_val_list,
    +)
    +
    +#: The set of HTTP status codes that indicate an automatically
    +#: processable redirect.
    +REDIRECT_STATI = (
    +    codes.moved,  # 301
    +    codes.found,  # 302
    +    codes.other,  # 303
    +    codes.temporary_redirect,  # 307
    +    codes.permanent_redirect,  # 308
    +)
    +
    +DEFAULT_REDIRECT_LIMIT = 30
    +CONTENT_CHUNK_SIZE = 10 * 1024
    +ITER_CHUNK_SIZE = 512
    +
    +
    +class RequestEncodingMixin:
    +    @property
    +    def path_url(self):
    +        """Build the path URL to use."""
    +
    +        url = []
    +
    +        p = urlsplit(self.url)
    +
    +        path = p.path
    +        if not path:
    +            path = "/"
    +
    +        url.append(path)
    +
    +        query = p.query
    +        if query:
    +            url.append("?")
    +            url.append(query)
    +
    +        return "".join(url)
    +
    +    @staticmethod
    +    def _encode_params(data):
    +        """Encode parameters in a piece of data.
    +
    +        Will successfully encode parameters when passed as a dict or a list of
    +        2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
    +        if parameters are supplied as a dict.
    +        """
    +
    +        if isinstance(data, (str, bytes)):
    +            return data
    +        elif hasattr(data, "read"):
    +            return data
    +        elif hasattr(data, "__iter__"):
    +            result = []
    +            for k, vs in to_key_val_list(data):
    +                if isinstance(vs, basestring) or not hasattr(vs, "__iter__"):
    +                    vs = [vs]
    +                for v in vs:
    +                    if v is not None:
    +                        result.append(
    +                            (
    +                                k.encode("utf-8") if isinstance(k, str) else k,
    +                                v.encode("utf-8") if isinstance(v, str) else v,
    +                            )
    +                        )
    +            return urlencode(result, doseq=True)
    +        else:
    +            return data
    +
    +    @staticmethod
    +    def _encode_files(files, data):
    +        """Build the body for a multipart/form-data request.
    +
    +        Will successfully encode files when passed as a dict or a list of
    +        tuples. Order is retained if data is a list of tuples but arbitrary
    +        if parameters are supplied as a dict.
    +        The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype)
    +        or 4-tuples (filename, fileobj, contentype, custom_headers).
    +        """
    +        if not files:
    +            raise ValueError("Files must be provided.")
    +        elif isinstance(data, basestring):
    +            raise ValueError("Data must not be a string.")
    +
    +        new_fields = []
    +        fields = to_key_val_list(data or {})
    +        files = to_key_val_list(files or {})
    +
    +        for field, val in fields:
    +            if isinstance(val, basestring) or not hasattr(val, "__iter__"):
    +                val = [val]
    +            for v in val:
    +                if v is not None:
    +                    # Don't call str() on bytestrings: in Py3 it all goes wrong.
    +                    if not isinstance(v, bytes):
    +                        v = str(v)
    +
    +                    new_fields.append(
    +                        (
    +                            field.decode("utf-8")
    +                            if isinstance(field, bytes)
    +                            else field,
    +                            v.encode("utf-8") if isinstance(v, str) else v,
    +                        )
    +                    )
    +
    +        for (k, v) in files:
    +            # support for explicit filename
    +            ft = None
    +            fh = None
    +            if isinstance(v, (tuple, list)):
    +                if len(v) == 2:
    +                    fn, fp = v
    +                elif len(v) == 3:
    +                    fn, fp, ft = v
    +                else:
    +                    fn, fp, ft, fh = v
    +            else:
    +                fn = guess_filename(v) or k
    +                fp = v
    +
    +            if isinstance(fp, (str, bytes, bytearray)):
    +                fdata = fp
    +            elif hasattr(fp, "read"):
    +                fdata = fp.read()
    +            elif fp is None:
    +                continue
    +            else:
    +                fdata = fp
    +
    +            rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
    +            rf.make_multipart(content_type=ft)
    +            new_fields.append(rf)
    +
    +        body, content_type = encode_multipart_formdata(new_fields)
    +
    +        return body, content_type
    +
    +
    +class RequestHooksMixin:
    +    def register_hook(self, event, hook):
    +        """Properly register a hook."""
    +
    +        if event not in self.hooks:
    +            raise ValueError(f'Unsupported event specified, with event name "{event}"')
    +
    +        if isinstance(hook, Callable):
    +            self.hooks[event].append(hook)
    +        elif hasattr(hook, "__iter__"):
    +            self.hooks[event].extend(h for h in hook if isinstance(h, Callable))
    +
    +    def deregister_hook(self, event, hook):
    +        """Deregister a previously registered hook.
    +        Returns True if the hook existed, False if not.
    +        """
    +
    +        try:
    +            self.hooks[event].remove(hook)
    +            return True
    +        except ValueError:
    +            return False
    +
    +
    +class Request(RequestHooksMixin):
    +    """A user-created :class:`Request <Request>` object.
    +
    +    Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server.
    +
    +    :param method: HTTP method to use.
    +    :param url: URL to send.
    +    :param headers: dictionary of headers to send.
    +    :param files: dictionary of {filename: fileobject} files to multipart upload.
    +    :param data: the body to attach to the request. If a dictionary or
    +        list of tuples ``[(key, value)]`` is provided, form-encoding will
    +        take place.
    +    :param json: json for the body to attach to the request (if files or data is not specified).
    +    :param params: URL parameters to append to the URL. If a dictionary or
    +        list of tuples ``[(key, value)]`` is provided, form-encoding will
    +        take place.
    +    :param auth: Auth handler or (user, pass) tuple.
    +    :param cookies: dictionary or CookieJar of cookies to attach to this request.
    +    :param hooks: dictionary of callback hooks, for internal usage.
    +
    +    Usage::
    +
    +      >>> import requests
    +      >>> req = requests.Request('GET', 'https://httpbin.org/get')
    +      >>> req.prepare()
    +      <PreparedRequest [GET]>
    +    """
    +
    +    def __init__(
    +        self,
    +        method=None,
    +        url=None,
    +        headers=None,
    +        files=None,
    +        data=None,
    +        params=None,
    +        auth=None,
    +        cookies=None,
    +        hooks=None,
    +        json=None,
    +    ):
    +
    +        # Default empty dicts for dict params.
    +        data = [] if data is None else data
    +        files = [] if files is None else files
    +        headers = {} if headers is None else headers
    +        params = {} if params is None else params
    +        hooks = {} if hooks is None else hooks
    +
    +        self.hooks = default_hooks()
    +        for (k, v) in list(hooks.items()):
    +            self.register_hook(event=k, hook=v)
    +
    +        self.method = method
    +        self.url = url
    +        self.headers = headers
    +        self.files = files
    +        self.data = data
    +        self.json = json
    +        self.params = params
    +        self.auth = auth
    +        self.cookies = cookies
    +
    +    def __repr__(self):
    +        return f"<Request [{self.method}]>"
    +
    +    def prepare(self):
    +        """Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it."""
    +        p = PreparedRequest()
    +        p.prepare(
    +            method=self.method,
    +            url=self.url,
    +            headers=self.headers,
    +            files=self.files,
    +            data=self.data,
    +            json=self.json,
    +            params=self.params,
    +            auth=self.auth,
    +            cookies=self.cookies,
    +            hooks=self.hooks,
    +        )
    +        return p
    +
    +
    +class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
    +    """The fully mutable :class:`PreparedRequest <PreparedRequest>` object,
    +    containing the exact bytes that will be sent to the server.
    +
    +    Instances are generated from a :class:`Request <Request>` object, and
    +    should not be instantiated manually; doing so may produce undesirable
    +    effects.
    +
    +    Usage::
    +
    +      >>> import requests
    +      >>> req = requests.Request('GET', 'https://httpbin.org/get')
    +      >>> r = req.prepare()
    +      >>> r
    +      <PreparedRequest [GET]>
    +
    +      >>> s = requests.Session()
    +      >>> s.send(r)
    +      <Response [200]>
    +    """
    +
    +    def __init__(self):
    +        #: HTTP verb to send to the server.
    +        self.method = None
    +        #: HTTP URL to send the request to.
    +        self.url = None
    +        #: dictionary of HTTP headers.
    +        self.headers = None
    +        # The `CookieJar` used to create the Cookie header will be stored here
    +        # after prepare_cookies is called
    +        self._cookies = None
    +        #: request body to send to the server.
    +        self.body = None
    +        #: dictionary of callback hooks, for internal usage.
    +        self.hooks = default_hooks()
    +        #: integer denoting starting position of a readable file-like body.
    +        self._body_position = None
    +
    +    def prepare(
    +        self,
    +        method=None,
    +        url=None,
    +        headers=None,
    +        files=None,
    +        data=None,
    +        params=None,
    +        auth=None,
    +        cookies=None,
    +        hooks=None,
    +        json=None,
    +    ):
    +        """Prepares the entire request with the given parameters."""
    +
    +        self.prepare_method(method)
    +        self.prepare_url(url, params)
    +        self.prepare_headers(headers)
    +        self.prepare_cookies(cookies)
    +        self.prepare_body(data, files, json)
    +        self.prepare_auth(auth, url)
    +
    +        # Note that prepare_auth must be last to enable authentication schemes
    +        # such as OAuth to work on a fully prepared request.
    +
    +        # This MUST go after prepare_auth. Authenticators could add a hook
    +        self.prepare_hooks(hooks)
    +
    +    def __repr__(self):
    +        return f"<PreparedRequest [{self.method}]>"
    +
    +    def copy(self):
    +        p = PreparedRequest()
    +        p.method = self.method
    +        p.url = self.url
    +        p.headers = self.headers.copy() if self.headers is not None else None
    +        p._cookies = _copy_cookie_jar(self._cookies)
    +        p.body = self.body
    +        p.hooks = self.hooks
    +        p._body_position = self._body_position
    +        return p
    +
    +    def prepare_method(self, method):
    +        """Prepares the given HTTP method."""
    +        self.method = method
    +        if self.method is not None:
    +            self.method = to_native_string(self.method.upper())
    +
    +    @staticmethod
    +    def _get_idna_encoded_host(host):
    +        import idna
    +
    +        try:
    +            host = idna.encode(host, uts46=True).decode("utf-8")
    +        except idna.IDNAError:
    +            raise UnicodeError
    +        return host
    +
    +    def prepare_url(self, url, params):
    +        """Prepares the given HTTP URL."""
    +        #: Accept objects that have string representations.
    +        #: We're unable to blindly call unicode/str functions
    +        #: as this will include the bytestring indicator (b'')
    +        #: on python 3.x.
    +        #: https://github.com/psf/requests/pull/2238
    +        if isinstance(url, bytes):
    +            url = url.decode("utf8")
    +        else:
    +            url = str(url)
    +
    +        # Remove leading whitespaces from url
    +        url = url.lstrip()
    +
    +        # Don't do any URL preparation for non-HTTP schemes like `mailto`,
    +        # `data` etc to work around exceptions from `url_parse`, which
    +        # handles RFC 3986 only.
    +        if ":" in url and not url.lower().startswith("http"):
    +            self.url = url
    +            return
    +
    +        # Support for unicode domain names and paths.
    +        try:
    +            scheme, auth, host, port, path, query, fragment = parse_url(url)
    +        except LocationParseError as e:
    +            raise InvalidURL(*e.args)
    +
    +        if not scheme:
    +            raise MissingSchema(
    +                f"Invalid URL {url!r}: No scheme supplied. "
    +                f"Perhaps you meant https://{url}?"
    +            )
    +
    +        if not host:
    +            raise InvalidURL(f"Invalid URL {url!r}: No host supplied")
    +
    +        # In general, we want to try IDNA encoding the hostname if the string contains
    +        # non-ASCII characters. This allows users to automatically get the correct IDNA
    +        # behaviour. For strings containing only ASCII characters, we need to also verify
    +        # it doesn't start with a wildcard (*), before allowing the unencoded hostname.
    +        if not unicode_is_ascii(host):
    +            try:
    +                host = self._get_idna_encoded_host(host)
    +            except UnicodeError:
    +                raise InvalidURL("URL has an invalid label.")
    +        elif host.startswith(("*", ".")):
    +            raise InvalidURL("URL has an invalid label.")
    +
    +        # Carefully reconstruct the network location
    +        netloc = auth or ""
    +        if netloc:
    +            netloc += "@"
    +        netloc += host
    +        if port:
    +            netloc += f":{port}"
    +
    +        # Bare domains aren't valid URLs.
    +        if not path:
    +            path = "/"
    +
    +        if isinstance(params, (str, bytes)):
    +            params = to_native_string(params)
    +
    +        enc_params = self._encode_params(params)
    +        if enc_params:
    +            if query:
    +                query = f"{query}&{enc_params}"
    +            else:
    +                query = enc_params
    +
    +        url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment]))
    +        self.url = url
    +
    +    def prepare_headers(self, headers):
    +        """Prepares the given HTTP headers."""
    +
    +        self.headers = CaseInsensitiveDict()
    +        if headers:
    +            for header in headers.items():
    +                # Raise exception on invalid header value.
    +                check_header_validity(header)
    +                name, value = header
    +                self.headers[to_native_string(name)] = value
    +
    +    def prepare_body(self, data, files, json=None):
    +        """Prepares the given HTTP body data."""
    +
    +        # Check if file, fo, generator, iterator.
    +        # If not, run through normal process.
    +
    +        # Nottin' on you.
    +        body = None
    +        content_type = None
    +
    +        if not data and json is not None:
    +            # urllib3 requires a bytes-like body. Python 2's json.dumps
    +            # provides this natively, but Python 3 gives a Unicode string.
    +            content_type = "application/json"
    +
    +            try:
    +                body = complexjson.dumps(json, allow_nan=False)
    +            except ValueError as ve:
    +                raise InvalidJSONError(ve, request=self)
    +
    +            if not isinstance(body, bytes):
    +                body = body.encode("utf-8")
    +
    +        is_stream = all(
    +            [
    +                hasattr(data, "__iter__"),
    +                not isinstance(data, (basestring, list, tuple, Mapping)),
    +            ]
    +        )
    +
    +        if is_stream:
    +            try:
    +                length = super_len(data)
    +            except (TypeError, AttributeError, UnsupportedOperation):
    +                length = None
    +
    +            body = data
    +
    +            if getattr(body, "tell", None) is not None:
    +                # Record the current file position before reading.
    +                # This will allow us to rewind a file in the event
    +                # of a redirect.
    +                try:
    +                    self._body_position = body.tell()
    +                except OSError:
    +                    # This differentiates from None, allowing us to catch
    +                    # a failed `tell()` later when trying to rewind the body
    +                    self._body_position = object()
    +
    +            if files:
    +                raise NotImplementedError(
    +                    "Streamed bodies and files are mutually exclusive."
    +                )
    +
    +            if length:
    +                self.headers["Content-Length"] = builtin_str(length)
    +            else:
    +                self.headers["Transfer-Encoding"] = "chunked"
    +        else:
    +            # Multi-part file uploads.
    +            if files:
    +                (body, content_type) = self._encode_files(files, data)
    +            else:
    +                if data:
    +                    body = self._encode_params(data)
    +                    if isinstance(data, basestring) or hasattr(data, "read"):
    +                        content_type = None
    +                    else:
    +                        content_type = "application/x-www-form-urlencoded"
    +
    +            self.prepare_content_length(body)
    +
    +            # Add content-type if it wasn't explicitly provided.
    +            if content_type and ("content-type" not in self.headers):
    +                self.headers["Content-Type"] = content_type
    +
    +        self.body = body
    +
    +    def prepare_content_length(self, body):
    +        """Prepare Content-Length header based on request method and body"""
    +        if body is not None:
    +            length = super_len(body)
    +            if length:
    +                # If length exists, set it. Otherwise, we fallback
    +                # to Transfer-Encoding: chunked.
    +                self.headers["Content-Length"] = builtin_str(length)
    +        elif (
    +            self.method not in ("GET", "HEAD")
    +            and self.headers.get("Content-Length") is None
    +        ):
    +            # Set Content-Length to 0 for methods that can have a body
    +            # but don't provide one. (i.e. not GET or HEAD)
    +            self.headers["Content-Length"] = "0"
    +
    +    def prepare_auth(self, auth, url=""):
    +        """Prepares the given HTTP auth data."""
    +
    +        # If no Auth is explicitly provided, extract it from the URL first.
    +        if auth is None:
    +            url_auth = get_auth_from_url(self.url)
    +            auth = url_auth if any(url_auth) else None
    +
    +        if auth:
    +            if isinstance(auth, tuple) and len(auth) == 2:
    +                # special-case basic HTTP auth
    +                auth = HTTPBasicAuth(*auth)
    +
    +            # Allow auth to make its changes.
    +            r = auth(self)
    +
    +            # Update self to reflect the auth changes.
    +            self.__dict__.update(r.__dict__)
    +
    +            # Recompute Content-Length
    +            self.prepare_content_length(self.body)
    +
    +    def prepare_cookies(self, cookies):
    +        """Prepares the given HTTP cookie data.
    +
    +        This function eventually generates a ``Cookie`` header from the
    +        given cookies using cookielib. Due to cookielib's design, the header
    +        will not be regenerated if it already exists, meaning this function
    +        can only be called once for the life of the
    +        :class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls
    +        to ``prepare_cookies`` will have no actual effect, unless the "Cookie"
    +        header is removed beforehand.
    +        """
    +        if isinstance(cookies, cookielib.CookieJar):
    +            self._cookies = cookies
    +        else:
    +            self._cookies = cookiejar_from_dict(cookies)
    +
    +        cookie_header = get_cookie_header(self._cookies, self)
    +        if cookie_header is not None:
    +            self.headers["Cookie"] = cookie_header
    +
    +    def prepare_hooks(self, hooks):
    +        """Prepares the given hooks."""
    +        # hooks can be passed as None to the prepare method and to this
    +        # method. To prevent iterating over None, simply use an empty list
    +        # if hooks is False-y
    +        hooks = hooks or []
    +        for event in hooks:
    +            self.register_hook(event, hooks[event])
    +
    +
    +class Response:
    +    """The :class:`Response <Response>` object, which contains a
    +    server's response to an HTTP request.
    +    """
    +
    +    __attrs__ = [
    +        "_content",
    +        "status_code",
    +        "headers",
    +        "url",
    +        "history",
    +        "encoding",
    +        "reason",
    +        "cookies",
    +        "elapsed",
    +        "request",
    +    ]
    +
    +    def __init__(self):
    +        self._content = False
    +        self._content_consumed = False
    +        self._next = None
    +
    +        #: Integer Code of responded HTTP Status, e.g. 404 or 200.
    +        self.status_code = None
    +
    +        #: Case-insensitive Dictionary of Response Headers.
    +        #: For example, ``headers['content-encoding']`` will return the
    +        #: value of a ``'Content-Encoding'`` response header.
    +        self.headers = CaseInsensitiveDict()
    +
    +        #: File-like object representation of response (for advanced usage).
    +        #: Use of ``raw`` requires that ``stream=True`` be set on the request.
    +        #: This requirement does not apply for use internally to Requests.
    +        self.raw = None
    +
    +        #: Final URL location of Response.
    +        self.url = None
    +
    +        #: Encoding to decode with when accessing r.text.
    +        self.encoding = None
    +
    +        #: A list of :class:`Response <Response>` objects from
    +        #: the history of the Request. Any redirect responses will end
    +        #: up here. The list is sorted from the oldest to the most recent request.
    +        self.history = []
    +
    +        #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK".
    +        self.reason = None
    +
    +        #: A CookieJar of Cookies the server sent back.
    +        self.cookies = cookiejar_from_dict({})
    +
    +        #: The amount of time elapsed between sending the request
    +        #: and the arrival of the response (as a timedelta).
    +        #: This property specifically measures the time taken between sending
    +        #: the first byte of the request and finishing parsing the headers. It
    +        #: is therefore unaffected by consuming the response content or the
    +        #: value of the ``stream`` keyword argument.
    +        self.elapsed = datetime.timedelta(0)
    +
    +        #: The :class:`PreparedRequest <PreparedRequest>` object to which this
    +        #: is a response.
    +        self.request = None
    +
    +    def __enter__(self):
    +        return self
    +
    +    def __exit__(self, *args):
    +        self.close()
    +
    +    def __getstate__(self):
    +        # Consume everything; accessing the content attribute makes
    +        # sure the content has been fully read.
    +        if not self._content_consumed:
    +            self.content
    +
    +        return {attr: getattr(self, attr, None) for attr in self.__attrs__}
    +
    +    def __setstate__(self, state):
    +        for name, value in state.items():
    +            setattr(self, name, value)
    +
    +        # pickled objects do not have .raw
    +        setattr(self, "_content_consumed", True)
    +        setattr(self, "raw", None)
    +
    +    def __repr__(self):
    +        return f"<Response [{self.status_code}]>"
    +
    +    def __bool__(self):
    +        """Returns True if :attr:`status_code` is less than 400.
    +
    +        This attribute checks if the status code of the response is between
    +        400 and 600 to see if there was a client error or a server error. If
    +        the status code, is between 200 and 400, this will return True. This
    +        is **not** a check to see if the response code is ``200 OK``.
    +        """
    +        return self.ok
    +
    +    def __nonzero__(self):
    +        """Returns True if :attr:`status_code` is less than 400.
    +
    +        This attribute checks if the status code of the response is between
    +        400 and 600 to see if there was a client error or a server error. If
    +        the status code, is between 200 and 400, this will return True. This
    +        is **not** a check to see if the response code is ``200 OK``.
    +        """
    +        return self.ok
    +
    +    def __iter__(self):
    +        """Allows you to use a response as an iterator."""
    +        return self.iter_content(128)
    +
    +    @property
    +    def ok(self):
    +        """Returns True if :attr:`status_code` is less than 400, False if not.
    +
    +        This attribute checks if the status code of the response is between
    +        400 and 600 to see if there was a client error or a server error. If
    +        the status code is between 200 and 400, this will return True. This
    +        is **not** a check to see if the response code is ``200 OK``.
    +        """
    +        try:
    +            self.raise_for_status()
    +        except HTTPError:
    +            return False
    +        return True
    +
    +    @property
    +    def is_redirect(self):
    +        """True if this Response is a well-formed HTTP redirect that could have
    +        been processed automatically (by :meth:`Session.resolve_redirects`).
    +        """
    +        return "location" in self.headers and self.status_code in REDIRECT_STATI
    +
    +    @property
    +    def is_permanent_redirect(self):
    +        """True if this Response one of the permanent versions of redirect."""
    +        return "location" in self.headers and self.status_code in (
    +            codes.moved_permanently,
    +            codes.permanent_redirect,
    +        )
    +
    +    @property
    +    def next(self):
    +        """Returns a PreparedRequest for the next request in a redirect chain, if there is one."""
    +        return self._next
    +
    +    @property
    +    def apparent_encoding(self):
    +        """The apparent encoding, provided by the charset_normalizer or chardet libraries."""
    +        return chardet.detect(self.content)["encoding"]
    +
    +    def iter_content(self, chunk_size=1, decode_unicode=False):
    +        """Iterates over the response data.  When stream=True is set on the
    +        request, this avoids reading the content at once into memory for
    +        large responses.  The chunk size is the number of bytes it should
    +        read into memory.  This is not necessarily the length of each item
    +        returned as decoding can take place.
    +
    +        chunk_size must be of type int or None. A value of None will
    +        function differently depending on the value of `stream`.
    +        stream=True will read data as it arrives in whatever size the
    +        chunks are received. If stream=False, data is returned as
    +        a single chunk.
    +
    +        If decode_unicode is True, content will be decoded using the best
    +        available encoding based on the response.
    +        """
    +
    +        def generate():
    +            # Special case for urllib3.
    +            if hasattr(self.raw, "stream"):
    +                try:
    +                    yield from self.raw.stream(chunk_size, decode_content=True)
    +                except ProtocolError as e:
    +                    raise ChunkedEncodingError(e)
    +                except DecodeError as e:
    +                    raise ContentDecodingError(e)
    +                except ReadTimeoutError as e:
    +                    raise ConnectionError(e)
    +                except SSLError as e:
    +                    raise RequestsSSLError(e)
    +            else:
    +                # Standard file-like object.
    +                while True:
    +                    chunk = self.raw.read(chunk_size)
    +                    if not chunk:
    +                        break
    +                    yield chunk
    +
    +            self._content_consumed = True
    +
    +        if self._content_consumed and isinstance(self._content, bool):
    +            raise StreamConsumedError()
    +        elif chunk_size is not None and not isinstance(chunk_size, int):
    +            raise TypeError(
    +                f"chunk_size must be an int, it is instead a {type(chunk_size)}."
    +            )
    +        # simulate reading small chunks of the content
    +        reused_chunks = iter_slices(self._content, chunk_size)
    +
    +        stream_chunks = generate()
    +
    +        chunks = reused_chunks if self._content_consumed else stream_chunks
    +
    +        if decode_unicode:
    +            chunks = stream_decode_response_unicode(chunks, self)
    +
    +        return chunks
    +
    +    def iter_lines(
    +        self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, delimiter=None
    +    ):
    +        """Iterates over the response data, one line at a time.  When
    +        stream=True is set on the request, this avoids reading the
    +        content at once into memory for large responses.
    +
    +        .. note:: This method is not reentrant safe.
    +        """
    +
    +        pending = None
    +
    +        for chunk in self.iter_content(
    +            chunk_size=chunk_size, decode_unicode=decode_unicode
    +        ):
    +
    +            if pending is not None:
    +                chunk = pending + chunk
    +
    +            if delimiter:
    +                lines = chunk.split(delimiter)
    +            else:
    +                lines = chunk.splitlines()
    +
    +            if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]:
    +                pending = lines.pop()
    +            else:
    +                pending = None
    +
    +            yield from lines
    +
    +        if pending is not None:
    +            yield pending
    +
    +    @property
    +    def content(self):
    +        """Content of the response, in bytes."""
    +
    +        if self._content is False:
    +            # Read the contents.
    +            if self._content_consumed:
    +                raise RuntimeError("The content for this response was already consumed")
    +
    +            if self.status_code == 0 or self.raw is None:
    +                self._content = None
    +            else:
    +                self._content = b"".join(self.iter_content(CONTENT_CHUNK_SIZE)) or b""
    +
    +        self._content_consumed = True
    +        # don't need to release the connection; that's been handled by urllib3
    +        # since we exhausted the data.
    +        return self._content
    +
    +    @property
    +    def text(self):
    +        """Content of the response, in unicode.
    +
    +        If Response.encoding is None, encoding will be guessed using
    +        ``charset_normalizer`` or ``chardet``.
    +
    +        The encoding of the response content is determined based solely on HTTP
    +        headers, following RFC 2616 to the letter. If you can take advantage of
    +        non-HTTP knowledge to make a better guess at the encoding, you should
    +        set ``r.encoding`` appropriately before accessing this property.
    +        """
    +
    +        # Try charset from content-type
    +        content = None
    +        encoding = self.encoding
    +
    +        if not self.content:
    +            return ""
    +
    +        # Fallback to auto-detected encoding.
    +        if self.encoding is None:
    +            encoding = self.apparent_encoding
    +
    +        # Decode unicode from given encoding.
    +        try:
    +            content = str(self.content, encoding, errors="replace")
    +        except (LookupError, TypeError):
    +            # A LookupError is raised if the encoding was not found which could
    +            # indicate a misspelling or similar mistake.
    +            #
    +            # A TypeError can be raised if encoding is None
    +            #
    +            # So we try blindly encoding.
    +            content = str(self.content, errors="replace")
    +
    +        return content
    +
    +    def json(self, **kwargs):
    +        r"""Returns the json-encoded content of a response, if any.
    +
    +        :param \*\*kwargs: Optional arguments that ``json.loads`` takes.
    +        :raises requests.exceptions.JSONDecodeError: If the response body does not
    +            contain valid json.
    +        """
    +
    +        if not self.encoding and self.content and len(self.content) > 3:
    +            # No encoding set. JSON RFC 4627 section 3 states we should expect
    +            # UTF-8, -16 or -32. Detect which one to use; If the detection or
    +            # decoding fails, fall back to `self.text` (using charset_normalizer to make
    +            # a best guess).
    +            encoding = guess_json_utf(self.content)
    +            if encoding is not None:
    +                try:
    +                    return complexjson.loads(self.content.decode(encoding), **kwargs)
    +                except UnicodeDecodeError:
    +                    # Wrong UTF codec detected; usually because it's not UTF-8
    +                    # but some other 8-bit codec.  This is an RFC violation,
    +                    # and the server didn't bother to tell us what codec *was*
    +                    # used.
    +                    pass
    +                except JSONDecodeError as e:
    +                    raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
    +
    +        try:
    +            return complexjson.loads(self.text, **kwargs)
    +        except JSONDecodeError as e:
    +            # Catch JSON-related errors and raise as requests.JSONDecodeError
    +            # This aliases json.JSONDecodeError and simplejson.JSONDecodeError
    +            raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
    +
    +    @property
    +    def links(self):
    +        """Returns the parsed header links of the response, if any."""
    +
    +        header = self.headers.get("link")
    +
    +        resolved_links = {}
    +
    +        if header:
    +            links = parse_header_links(header)
    +
    +            for link in links:
    +                key = link.get("rel") or link.get("url")
    +                resolved_links[key] = link
    +
    +        return resolved_links
    +
    +    def raise_for_status(self):
    +        """Raises :class:`HTTPError`, if one occurred."""
    +
    +        http_error_msg = ""
    +        if isinstance(self.reason, bytes):
    +            # We attempt to decode utf-8 first because some servers
    +            # choose to localize their reason strings. If the string
    +            # isn't utf-8, we fall back to iso-8859-1 for all other
    +            # encodings. (See PR #3538)
    +            try:
    +                reason = self.reason.decode("utf-8")
    +            except UnicodeDecodeError:
    +                reason = self.reason.decode("iso-8859-1")
    +        else:
    +            reason = self.reason
    +
    +        if 400 <= self.status_code < 500:
    +            http_error_msg = (
    +                f"{self.status_code} Client Error: {reason} for url: {self.url}"
    +            )
    +
    +        elif 500 <= self.status_code < 600:
    +            http_error_msg = (
    +                f"{self.status_code} Server Error: {reason} for url: {self.url}"
    +            )
    +
    +        if http_error_msg:
    +            raise HTTPError(http_error_msg, response=self)
    +
    +    def close(self):
    +        """Releases the connection back to the pool. Once this method has been
    +        called the underlying ``raw`` object must not be accessed again.
    +
    +        *Note: Should not normally need to be called explicitly.*
    +        """
    +        if not self._content_consumed:
    +            self.raw.close()
    +
    +        release_conn = getattr(self.raw, "release_conn", None)
    +        if release_conn is not None:
    +            release_conn()
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/packages.py b/deployment-apps/metricator-for-nmon/lib/requests/packages.py
    new file mode 100644
    index 0000000..77c45c9
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/packages.py
    @@ -0,0 +1,28 @@
    +import sys
    +
    +try:
    +    import chardet
    +except ImportError:
    +    import warnings
    +
    +    import charset_normalizer as chardet
    +
    +    warnings.filterwarnings("ignore", "Trying to detect", module="charset_normalizer")
    +
    +# This code exists for backwards compatibility reasons.
    +# I don't like it either. Just look the other way. :)
    +
    +for package in ("urllib3", "idna"):
    +    locals()[package] = __import__(package)
    +    # This traversal is apparently necessary such that the identities are
    +    # preserved (requests.packages.urllib3.* is urllib3.*)
    +    for mod in list(sys.modules):
    +        if mod == package or mod.startswith(f"{package}."):
    +            sys.modules[f"requests.packages.{mod}"] = sys.modules[mod]
    +
    +target = chardet.__name__
    +for mod in list(sys.modules):
    +    if mod == target or mod.startswith(f"{target}."):
    +        target = target.replace(target, "chardet")
    +        sys.modules[f"requests.packages.{target}"] = sys.modules[mod]
    +# Kinda cool, though, right?
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/sessions.py b/deployment-apps/metricator-for-nmon/lib/requests/sessions.py
    new file mode 100644
    index 0000000..6cb3b4d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/sessions.py
    @@ -0,0 +1,831 @@
    +"""
    +requests.sessions
    +~~~~~~~~~~~~~~~~~
    +
    +This module provides a Session object to manage and persist settings across
    +requests (cookies, auth, proxies).
    +"""
    +import os
    +import sys
    +import time
    +from collections import OrderedDict
    +from datetime import timedelta
    +
    +from ._internal_utils import to_native_string
    +from .adapters import HTTPAdapter
    +from .auth import _basic_auth_str
    +from .compat import Mapping, cookielib, urljoin, urlparse
    +from .cookies import (
    +    RequestsCookieJar,
    +    cookiejar_from_dict,
    +    extract_cookies_to_jar,
    +    merge_cookies,
    +)
    +from .exceptions import (
    +    ChunkedEncodingError,
    +    ContentDecodingError,
    +    InvalidSchema,
    +    TooManyRedirects,
    +)
    +from .hooks import default_hooks, dispatch_hook
    +
    +# formerly defined here, reexposed here for backward compatibility
    +from .models import (  # noqa: F401
    +    DEFAULT_REDIRECT_LIMIT,
    +    REDIRECT_STATI,
    +    PreparedRequest,
    +    Request,
    +)
    +from .status_codes import codes
    +from .structures import CaseInsensitiveDict
    +from .utils import (  # noqa: F401
    +    DEFAULT_PORTS,
    +    default_headers,
    +    get_auth_from_url,
    +    get_environ_proxies,
    +    get_netrc_auth,
    +    requote_uri,
    +    resolve_proxies,
    +    rewind_body,
    +    should_bypass_proxies,
    +    to_key_val_list,
    +)
    +
    +# Preferred clock, based on which one is more accurate on a given system.
    +if sys.platform == "win32":
    +    preferred_clock = time.perf_counter
    +else:
    +    preferred_clock = time.time
    +
    +
    +def merge_setting(request_setting, session_setting, dict_class=OrderedDict):
    +    """Determines appropriate setting for a given request, taking into account
    +    the explicit setting on that request, and the setting in the session. If a
    +    setting is a dictionary, they will be merged together using `dict_class`
    +    """
    +
    +    if session_setting is None:
    +        return request_setting
    +
    +    if request_setting is None:
    +        return session_setting
    +
    +    # Bypass if not a dictionary (e.g. verify)
    +    if not (
    +        isinstance(session_setting, Mapping) and isinstance(request_setting, Mapping)
    +    ):
    +        return request_setting
    +
    +    merged_setting = dict_class(to_key_val_list(session_setting))
    +    merged_setting.update(to_key_val_list(request_setting))
    +
    +    # Remove keys that are set to None. Extract keys first to avoid altering
    +    # the dictionary during iteration.
    +    none_keys = [k for (k, v) in merged_setting.items() if v is None]
    +    for key in none_keys:
    +        del merged_setting[key]
    +
    +    return merged_setting
    +
    +
    +def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict):
    +    """Properly merges both requests and session hooks.
    +
    +    This is necessary because when request_hooks == {'response': []}, the
    +    merge breaks Session hooks entirely.
    +    """
    +    if session_hooks is None or session_hooks.get("response") == []:
    +        return request_hooks
    +
    +    if request_hooks is None or request_hooks.get("response") == []:
    +        return session_hooks
    +
    +    return merge_setting(request_hooks, session_hooks, dict_class)
    +
    +
    +class SessionRedirectMixin:
    +    def get_redirect_target(self, resp):
    +        """Receives a Response. Returns a redirect URI or ``None``"""
    +        # Due to the nature of how requests processes redirects this method will
    +        # be called at least once upon the original response and at least twice
    +        # on each subsequent redirect response (if any).
    +        # If a custom mixin is used to handle this logic, it may be advantageous
    +        # to cache the redirect location onto the response object as a private
    +        # attribute.
    +        if resp.is_redirect:
    +            location = resp.headers["location"]
    +            # Currently the underlying http module on py3 decode headers
    +            # in latin1, but empirical evidence suggests that latin1 is very
    +            # rarely used with non-ASCII characters in HTTP headers.
    +            # It is more likely to get UTF8 header rather than latin1.
    +            # This causes incorrect handling of UTF8 encoded location headers.
    +            # To solve this, we re-encode the location in latin1.
    +            location = location.encode("latin1")
    +            return to_native_string(location, "utf8")
    +        return None
    +
    +    def should_strip_auth(self, old_url, new_url):
    +        """Decide whether Authorization header should be removed when redirecting"""
    +        old_parsed = urlparse(old_url)
    +        new_parsed = urlparse(new_url)
    +        if old_parsed.hostname != new_parsed.hostname:
    +            return True
    +        # Special case: allow http -> https redirect when using the standard
    +        # ports. This isn't specified by RFC 7235, but is kept to avoid
    +        # breaking backwards compatibility with older versions of requests
    +        # that allowed any redirects on the same host.
    +        if (
    +            old_parsed.scheme == "http"
    +            and old_parsed.port in (80, None)
    +            and new_parsed.scheme == "https"
    +            and new_parsed.port in (443, None)
    +        ):
    +            return False
    +
    +        # Handle default port usage corresponding to scheme.
    +        changed_port = old_parsed.port != new_parsed.port
    +        changed_scheme = old_parsed.scheme != new_parsed.scheme
    +        default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None)
    +        if (
    +            not changed_scheme
    +            and old_parsed.port in default_port
    +            and new_parsed.port in default_port
    +        ):
    +            return False
    +
    +        # Standard case: root URI must match
    +        return changed_port or changed_scheme
    +
    +    def resolve_redirects(
    +        self,
    +        resp,
    +        req,
    +        stream=False,
    +        timeout=None,
    +        verify=True,
    +        cert=None,
    +        proxies=None,
    +        yield_requests=False,
    +        **adapter_kwargs,
    +    ):
    +        """Receives a Response. Returns a generator of Responses or Requests."""
    +
    +        hist = []  # keep track of history
    +
    +        url = self.get_redirect_target(resp)
    +        previous_fragment = urlparse(req.url).fragment
    +        while url:
    +            prepared_request = req.copy()
    +
    +            # Update history and keep track of redirects.
    +            # resp.history must ignore the original request in this loop
    +            hist.append(resp)
    +            resp.history = hist[1:]
    +
    +            try:
    +                resp.content  # Consume socket so it can be released
    +            except (ChunkedEncodingError, ContentDecodingError, RuntimeError):
    +                resp.raw.read(decode_content=False)
    +
    +            if len(resp.history) >= self.max_redirects:
    +                raise TooManyRedirects(
    +                    f"Exceeded {self.max_redirects} redirects.", response=resp
    +                )
    +
    +            # Release the connection back into the pool.
    +            resp.close()
    +
    +            # Handle redirection without scheme (see: RFC 1808 Section 4)
    +            if url.startswith("//"):
    +                parsed_rurl = urlparse(resp.url)
    +                url = ":".join([to_native_string(parsed_rurl.scheme), url])
    +
    +            # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2)
    +            parsed = urlparse(url)
    +            if parsed.fragment == "" and previous_fragment:
    +                parsed = parsed._replace(fragment=previous_fragment)
    +            elif parsed.fragment:
    +                previous_fragment = parsed.fragment
    +            url = parsed.geturl()
    +
    +            # Facilitate relative 'location' headers, as allowed by RFC 7231.
    +            # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')
    +            # Compliant with RFC3986, we percent encode the url.
    +            if not parsed.netloc:
    +                url = urljoin(resp.url, requote_uri(url))
    +            else:
    +                url = requote_uri(url)
    +
    +            prepared_request.url = to_native_string(url)
    +
    +            self.rebuild_method(prepared_request, resp)
    +
    +            # https://github.com/psf/requests/issues/1084
    +            if resp.status_code not in (
    +                codes.temporary_redirect,
    +                codes.permanent_redirect,
    +            ):
    +                # https://github.com/psf/requests/issues/3490
    +                purged_headers = ("Content-Length", "Content-Type", "Transfer-Encoding")
    +                for header in purged_headers:
    +                    prepared_request.headers.pop(header, None)
    +                prepared_request.body = None
    +
    +            headers = prepared_request.headers
    +            headers.pop("Cookie", None)
    +
    +            # Extract any cookies sent on the response to the cookiejar
    +            # in the new request. Because we've mutated our copied prepared
    +            # request, use the old one that we haven't yet touched.
    +            extract_cookies_to_jar(prepared_request._cookies, req, resp.raw)
    +            merge_cookies(prepared_request._cookies, self.cookies)
    +            prepared_request.prepare_cookies(prepared_request._cookies)
    +
    +            # Rebuild auth and proxy information.
    +            proxies = self.rebuild_proxies(prepared_request, proxies)
    +            self.rebuild_auth(prepared_request, resp)
    +
    +            # A failed tell() sets `_body_position` to `object()`. This non-None
    +            # value ensures `rewindable` will be True, allowing us to raise an
    +            # UnrewindableBodyError, instead of hanging the connection.
    +            rewindable = prepared_request._body_position is not None and (
    +                "Content-Length" in headers or "Transfer-Encoding" in headers
    +            )
    +
    +            # Attempt to rewind consumed file-like object.
    +            if rewindable:
    +                rewind_body(prepared_request)
    +
    +            # Override the original request.
    +            req = prepared_request
    +
    +            if yield_requests:
    +                yield req
    +            else:
    +
    +                resp = self.send(
    +                    req,
    +                    stream=stream,
    +                    timeout=timeout,
    +                    verify=verify,
    +                    cert=cert,
    +                    proxies=proxies,
    +                    allow_redirects=False,
    +                    **adapter_kwargs,
    +                )
    +
    +                extract_cookies_to_jar(self.cookies, prepared_request, resp.raw)
    +
    +                # extract redirect url, if any, for the next loop
    +                url = self.get_redirect_target(resp)
    +                yield resp
    +
    +    def rebuild_auth(self, prepared_request, response):
    +        """When being redirected we may want to strip authentication from the
    +        request to avoid leaking credentials. This method intelligently removes
    +        and reapplies authentication where possible to avoid credential loss.
    +        """
    +        headers = prepared_request.headers
    +        url = prepared_request.url
    +
    +        if "Authorization" in headers and self.should_strip_auth(
    +            response.request.url, url
    +        ):
    +            # If we get redirected to a new host, we should strip out any
    +            # authentication headers.
    +            del headers["Authorization"]
    +
    +        # .netrc might have more auth for us on our new host.
    +        new_auth = get_netrc_auth(url) if self.trust_env else None
    +        if new_auth is not None:
    +            prepared_request.prepare_auth(new_auth)
    +
    +    def rebuild_proxies(self, prepared_request, proxies):
    +        """This method re-evaluates the proxy configuration by considering the
    +        environment variables. If we are redirected to a URL covered by
    +        NO_PROXY, we strip the proxy configuration. Otherwise, we set missing
    +        proxy keys for this URL (in case they were stripped by a previous
    +        redirect).
    +
    +        This method also replaces the Proxy-Authorization header where
    +        necessary.
    +
    +        :rtype: dict
    +        """
    +        headers = prepared_request.headers
    +        scheme = urlparse(prepared_request.url).scheme
    +        new_proxies = resolve_proxies(prepared_request, proxies, self.trust_env)
    +
    +        if "Proxy-Authorization" in headers:
    +            del headers["Proxy-Authorization"]
    +
    +        try:
    +            username, password = get_auth_from_url(new_proxies[scheme])
    +        except KeyError:
    +            username, password = None, None
    +
    +        if username and password:
    +            headers["Proxy-Authorization"] = _basic_auth_str(username, password)
    +
    +        return new_proxies
    +
    +    def rebuild_method(self, prepared_request, response):
    +        """When being redirected we may want to change the method of the request
    +        based on certain specs or browser behavior.
    +        """
    +        method = prepared_request.method
    +
    +        # https://tools.ietf.org/html/rfc7231#section-6.4.4
    +        if response.status_code == codes.see_other and method != "HEAD":
    +            method = "GET"
    +
    +        # Do what the browsers do, despite standards...
    +        # First, turn 302s into GETs.
    +        if response.status_code == codes.found and method != "HEAD":
    +            method = "GET"
    +
    +        # Second, if a POST is responded to with a 301, turn it into a GET.
    +        # This bizarre behaviour is explained in Issue 1704.
    +        if response.status_code == codes.moved and method == "POST":
    +            method = "GET"
    +
    +        prepared_request.method = method
    +
    +
    +class Session(SessionRedirectMixin):
    +    """A Requests session.
    +
    +    Provides cookie persistence, connection-pooling, and configuration.
    +
    +    Basic Usage::
    +
    +      >>> import requests
    +      >>> s = requests.Session()
    +      >>> s.get('https://httpbin.org/get')
    +      <Response [200]>
    +
    +    Or as a context manager::
    +
    +      >>> with requests.Session() as s:
    +      ...     s.get('https://httpbin.org/get')
    +      <Response [200]>
    +    """
    +
    +    __attrs__ = [
    +        "headers",
    +        "cookies",
    +        "auth",
    +        "proxies",
    +        "hooks",
    +        "params",
    +        "verify",
    +        "cert",
    +        "adapters",
    +        "stream",
    +        "trust_env",
    +        "max_redirects",
    +    ]
    +
    +    def __init__(self):
    +
    +        #: A case-insensitive dictionary of headers to be sent on each
    +        #: :class:`Request <Request>` sent from this
    +        #: :class:`Session <Session>`.
    +        self.headers = default_headers()
    +
    +        #: Default Authentication tuple or object to attach to
    +        #: :class:`Request <Request>`.
    +        self.auth = None
    +
    +        #: Dictionary mapping protocol or protocol and host to the URL of the proxy
    +        #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to
    +        #: be used on each :class:`Request <Request>`.
    +        self.proxies = {}
    +
    +        #: Event-handling hooks.
    +        self.hooks = default_hooks()
    +
    +        #: Dictionary of querystring data to attach to each
    +        #: :class:`Request <Request>`. The dictionary values may be lists for
    +        #: representing multivalued query parameters.
    +        self.params = {}
    +
    +        #: Stream response content default.
    +        self.stream = False
    +
    +        #: SSL Verification default.
    +        #: Defaults to `True`, requiring requests to verify the TLS certificate at the
    +        #: remote end.
    +        #: If verify is set to `False`, requests will accept any TLS certificate
    +        #: presented by the server, and will ignore hostname mismatches and/or
    +        #: expired certificates, which will make your application vulnerable to
    +        #: man-in-the-middle (MitM) attacks.
    +        #: Only set this to `False` for testing.
    +        self.verify = True
    +
    +        #: SSL client certificate default, if String, path to ssl client
    +        #: cert file (.pem). If Tuple, ('cert', 'key') pair.
    +        self.cert = None
    +
    +        #: Maximum number of redirects allowed. If the request exceeds this
    +        #: limit, a :class:`TooManyRedirects` exception is raised.
    +        #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is
    +        #: 30.
    +        self.max_redirects = DEFAULT_REDIRECT_LIMIT
    +
    +        #: Trust environment settings for proxy configuration, default
    +        #: authentication and similar.
    +        self.trust_env = True
    +
    +        #: A CookieJar containing all currently outstanding cookies set on this
    +        #: session. By default it is a
    +        #: :class:`RequestsCookieJar <requests.cookies.RequestsCookieJar>`, but
    +        #: may be any other ``cookielib.CookieJar`` compatible object.
    +        self.cookies = cookiejar_from_dict({})
    +
    +        # Default connection adapters.
    +        self.adapters = OrderedDict()
    +        self.mount("https://", HTTPAdapter())
    +        self.mount("http://", HTTPAdapter())
    +
    +    def __enter__(self):
    +        return self
    +
    +    def __exit__(self, *args):
    +        self.close()
    +
    +    def prepare_request(self, request):
    +        """Constructs a :class:`PreparedRequest <PreparedRequest>` for
    +        transmission and returns it. The :class:`PreparedRequest` has settings
    +        merged from the :class:`Request <Request>` instance and those of the
    +        :class:`Session`.
    +
    +        :param request: :class:`Request` instance to prepare with this
    +            session's settings.
    +        :rtype: requests.PreparedRequest
    +        """
    +        cookies = request.cookies or {}
    +
    +        # Bootstrap CookieJar.
    +        if not isinstance(cookies, cookielib.CookieJar):
    +            cookies = cookiejar_from_dict(cookies)
    +
    +        # Merge with session cookies
    +        merged_cookies = merge_cookies(
    +            merge_cookies(RequestsCookieJar(), self.cookies), cookies
    +        )
    +
    +        # Set environment's basic authentication if not explicitly set.
    +        auth = request.auth
    +        if self.trust_env and not auth and not self.auth:
    +            auth = get_netrc_auth(request.url)
    +
    +        p = PreparedRequest()
    +        p.prepare(
    +            method=request.method.upper(),
    +            url=request.url,
    +            files=request.files,
    +            data=request.data,
    +            json=request.json,
    +            headers=merge_setting(
    +                request.headers, self.headers, dict_class=CaseInsensitiveDict
    +            ),
    +            params=merge_setting(request.params, self.params),
    +            auth=merge_setting(auth, self.auth),
    +            cookies=merged_cookies,
    +            hooks=merge_hooks(request.hooks, self.hooks),
    +        )
    +        return p
    +
    +    def request(
    +        self,
    +        method,
    +        url,
    +        params=None,
    +        data=None,
    +        headers=None,
    +        cookies=None,
    +        files=None,
    +        auth=None,
    +        timeout=None,
    +        allow_redirects=True,
    +        proxies=None,
    +        hooks=None,
    +        stream=None,
    +        verify=None,
    +        cert=None,
    +        json=None,
    +    ):
    +        """Constructs a :class:`Request <Request>`, prepares it and sends it.
    +        Returns :class:`Response <Response>` object.
    +
    +        :param method: method for the new :class:`Request` object.
    +        :param url: URL for the new :class:`Request` object.
    +        :param params: (optional) Dictionary or bytes to be sent in the query
    +            string for the :class:`Request`.
    +        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
    +            object to send in the body of the :class:`Request`.
    +        :param json: (optional) json to send in the body of the
    +            :class:`Request`.
    +        :param headers: (optional) Dictionary of HTTP Headers to send with the
    +            :class:`Request`.
    +        :param cookies: (optional) Dict or CookieJar object to send with the
    +            :class:`Request`.
    +        :param files: (optional) Dictionary of ``'filename': file-like-objects``
    +            for multipart encoding upload.
    +        :param auth: (optional) Auth tuple or callable to enable
    +            Basic/Digest/Custom HTTP Auth.
    +        :param timeout: (optional) How long to wait for the server to send
    +            data before giving up, as a float, or a :ref:`(connect timeout,
    +            read timeout) <timeouts>` tuple.
    +        :type timeout: float or tuple
    +        :param allow_redirects: (optional) Set to True by default.
    +        :type allow_redirects: bool
    +        :param proxies: (optional) Dictionary mapping protocol or protocol and
    +            hostname to the URL of the proxy.
    +        :param stream: (optional) whether to immediately download the response
    +            content. Defaults to ``False``.
    +        :param verify: (optional) Either a boolean, in which case it controls whether we verify
    +            the server's TLS certificate, or a string, in which case it must be a path
    +            to a CA bundle to use. Defaults to ``True``. When set to
    +            ``False``, requests will accept any TLS certificate presented by
    +            the server, and will ignore hostname mismatches and/or expired
    +            certificates, which will make your application vulnerable to
    +            man-in-the-middle (MitM) attacks. Setting verify to ``False``
    +            may be useful during local development or testing.
    +        :param cert: (optional) if String, path to ssl client cert file (.pem).
    +            If Tuple, ('cert', 'key') pair.
    +        :rtype: requests.Response
    +        """
    +        # Create the Request.
    +        req = Request(
    +            method=method.upper(),
    +            url=url,
    +            headers=headers,
    +            files=files,
    +            data=data or {},
    +            json=json,
    +            params=params or {},
    +            auth=auth,
    +            cookies=cookies,
    +            hooks=hooks,
    +        )
    +        prep = self.prepare_request(req)
    +
    +        proxies = proxies or {}
    +
    +        settings = self.merge_environment_settings(
    +            prep.url, proxies, stream, verify, cert
    +        )
    +
    +        # Send the request.
    +        send_kwargs = {
    +            "timeout": timeout,
    +            "allow_redirects": allow_redirects,
    +        }
    +        send_kwargs.update(settings)
    +        resp = self.send(prep, **send_kwargs)
    +
    +        return resp
    +
    +    def get(self, url, **kwargs):
    +        r"""Sends a GET request. Returns :class:`Response` object.
    +
    +        :param url: URL for the new :class:`Request` object.
    +        :param \*\*kwargs: Optional arguments that ``request`` takes.
    +        :rtype: requests.Response
    +        """
    +
    +        kwargs.setdefault("allow_redirects", True)
    +        return self.request("GET", url, **kwargs)
    +
    +    def options(self, url, **kwargs):
    +        r"""Sends a OPTIONS request. Returns :class:`Response` object.
    +
    +        :param url: URL for the new :class:`Request` object.
    +        :param \*\*kwargs: Optional arguments that ``request`` takes.
    +        :rtype: requests.Response
    +        """
    +
    +        kwargs.setdefault("allow_redirects", True)
    +        return self.request("OPTIONS", url, **kwargs)
    +
    +    def head(self, url, **kwargs):
    +        r"""Sends a HEAD request. Returns :class:`Response` object.
    +
    +        :param url: URL for the new :class:`Request` object.
    +        :param \*\*kwargs: Optional arguments that ``request`` takes.
    +        :rtype: requests.Response
    +        """
    +
    +        kwargs.setdefault("allow_redirects", False)
    +        return self.request("HEAD", url, **kwargs)
    +
    +    def post(self, url, data=None, json=None, **kwargs):
    +        r"""Sends a POST request. Returns :class:`Response` object.
    +
    +        :param url: URL for the new :class:`Request` object.
    +        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
    +            object to send in the body of the :class:`Request`.
    +        :param json: (optional) json to send in the body of the :class:`Request`.
    +        :param \*\*kwargs: Optional arguments that ``request`` takes.
    +        :rtype: requests.Response
    +        """
    +
    +        return self.request("POST", url, data=data, json=json, **kwargs)
    +
    +    def put(self, url, data=None, **kwargs):
    +        r"""Sends a PUT request. Returns :class:`Response` object.
    +
    +        :param url: URL for the new :class:`Request` object.
    +        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
    +            object to send in the body of the :class:`Request`.
    +        :param \*\*kwargs: Optional arguments that ``request`` takes.
    +        :rtype: requests.Response
    +        """
    +
    +        return self.request("PUT", url, data=data, **kwargs)
    +
    +    def patch(self, url, data=None, **kwargs):
    +        r"""Sends a PATCH request. Returns :class:`Response` object.
    +
    +        :param url: URL for the new :class:`Request` object.
    +        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
    +            object to send in the body of the :class:`Request`.
    +        :param \*\*kwargs: Optional arguments that ``request`` takes.
    +        :rtype: requests.Response
    +        """
    +
    +        return self.request("PATCH", url, data=data, **kwargs)
    +
    +    def delete(self, url, **kwargs):
    +        r"""Sends a DELETE request. Returns :class:`Response` object.
    +
    +        :param url: URL for the new :class:`Request` object.
    +        :param \*\*kwargs: Optional arguments that ``request`` takes.
    +        :rtype: requests.Response
    +        """
    +
    +        return self.request("DELETE", url, **kwargs)
    +
    +    def send(self, request, **kwargs):
    +        """Send a given PreparedRequest.
    +
    +        :rtype: requests.Response
    +        """
    +        # Set defaults that the hooks can utilize to ensure they always have
    +        # the correct parameters to reproduce the previous request.
    +        kwargs.setdefault("stream", self.stream)
    +        kwargs.setdefault("verify", self.verify)
    +        kwargs.setdefault("cert", self.cert)
    +        if "proxies" not in kwargs:
    +            kwargs["proxies"] = resolve_proxies(request, self.proxies, self.trust_env)
    +
    +        # It's possible that users might accidentally send a Request object.
    +        # Guard against that specific failure case.
    +        if isinstance(request, Request):
    +            raise ValueError("You can only send PreparedRequests.")
    +
    +        # Set up variables needed for resolve_redirects and dispatching of hooks
    +        allow_redirects = kwargs.pop("allow_redirects", True)
    +        stream = kwargs.get("stream")
    +        hooks = request.hooks
    +
    +        # Get the appropriate adapter to use
    +        adapter = self.get_adapter(url=request.url)
    +
    +        # Start time (approximately) of the request
    +        start = preferred_clock()
    +
    +        # Send the request
    +        r = adapter.send(request, **kwargs)
    +
    +        # Total elapsed time of the request (approximately)
    +        elapsed = preferred_clock() - start
    +        r.elapsed = timedelta(seconds=elapsed)
    +
    +        # Response manipulation hooks
    +        r = dispatch_hook("response", hooks, r, **kwargs)
    +
    +        # Persist cookies
    +        if r.history:
    +
    +            # If the hooks create history then we want those cookies too
    +            for resp in r.history:
    +                extract_cookies_to_jar(self.cookies, resp.request, resp.raw)
    +
    +        extract_cookies_to_jar(self.cookies, request, r.raw)
    +
    +        # Resolve redirects if allowed.
    +        if allow_redirects:
    +            # Redirect resolving generator.
    +            gen = self.resolve_redirects(r, request, **kwargs)
    +            history = [resp for resp in gen]
    +        else:
    +            history = []
    +
    +        # Shuffle things around if there's history.
    +        if history:
    +            # Insert the first (original) request at the start
    +            history.insert(0, r)
    +            # Get the last request made
    +            r = history.pop()
    +            r.history = history
    +
    +        # If redirects aren't being followed, store the response on the Request for Response.next().
    +        if not allow_redirects:
    +            try:
    +                r._next = next(
    +                    self.resolve_redirects(r, request, yield_requests=True, **kwargs)
    +                )
    +            except StopIteration:
    +                pass
    +
    +        if not stream:
    +            r.content
    +
    +        return r
    +
    +    def merge_environment_settings(self, url, proxies, stream, verify, cert):
    +        """
    +        Check the environment and merge it with some settings.
    +
    +        :rtype: dict
    +        """
    +        # Gather clues from the surrounding environment.
    +        if self.trust_env:
    +            # Set environment's proxies.
    +            no_proxy = proxies.get("no_proxy") if proxies is not None else None
    +            env_proxies = get_environ_proxies(url, no_proxy=no_proxy)
    +            for (k, v) in env_proxies.items():
    +                proxies.setdefault(k, v)
    +
    +            # Look for requests environment configuration
    +            # and be compatible with cURL.
    +            if verify is True or verify is None:
    +                verify = (
    +                    os.environ.get("REQUESTS_CA_BUNDLE")
    +                    or os.environ.get("CURL_CA_BUNDLE")
    +                    or verify
    +                )
    +
    +        # Merge all the kwargs.
    +        proxies = merge_setting(proxies, self.proxies)
    +        stream = merge_setting(stream, self.stream)
    +        verify = merge_setting(verify, self.verify)
    +        cert = merge_setting(cert, self.cert)
    +
    +        return {"proxies": proxies, "stream": stream, "verify": verify, "cert": cert}
    +
    +    def get_adapter(self, url):
    +        """
    +        Returns the appropriate connection adapter for the given URL.
    +
    +        :rtype: requests.adapters.BaseAdapter
    +        """
    +        for (prefix, adapter) in self.adapters.items():
    +
    +            if url.lower().startswith(prefix.lower()):
    +                return adapter
    +
    +        # Nothing matches :-/
    +        raise InvalidSchema(f"No connection adapters were found for {url!r}")
    +
    +    def close(self):
    +        """Closes all adapters and as such the session"""
    +        for v in self.adapters.values():
    +            v.close()
    +
    +    def mount(self, prefix, adapter):
    +        """Registers a connection adapter to a prefix.
    +
    +        Adapters are sorted in descending order by prefix length.
    +        """
    +        self.adapters[prefix] = adapter
    +        keys_to_move = [k for k in self.adapters if len(k) < len(prefix)]
    +
    +        for key in keys_to_move:
    +            self.adapters[key] = self.adapters.pop(key)
    +
    +    def __getstate__(self):
    +        state = {attr: getattr(self, attr, None) for attr in self.__attrs__}
    +        return state
    +
    +    def __setstate__(self, state):
    +        for attr, value in state.items():
    +            setattr(self, attr, value)
    +
    +
    +def session():
    +    """
    +    Returns a :class:`Session` for context-management.
    +
    +    .. deprecated:: 1.0.0
    +
    +        This method has been deprecated since version 1.0.0 and is only kept for
    +        backwards compatibility. New code should use :class:`~requests.sessions.Session`
    +        to create a session. This may be removed at a future date.
    +
    +    :rtype: Session
    +    """
    +    return Session()
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/status_codes.py b/deployment-apps/metricator-for-nmon/lib/requests/status_codes.py
    new file mode 100644
    index 0000000..4bd072b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/status_codes.py
    @@ -0,0 +1,128 @@
    +r"""
    +The ``codes`` object defines a mapping from common names for HTTP statuses
    +to their numerical codes, accessible either as attributes or as dictionary
    +items.
    +
    +Example::
    +
    +    >>> import requests
    +    >>> requests.codes['temporary_redirect']
    +    307
    +    >>> requests.codes.teapot
    +    418
    +    >>> requests.codes['\o/']
    +    200
    +
    +Some codes have multiple names, and both upper- and lower-case versions of
    +the names are allowed. For example, ``codes.ok``, ``codes.OK``, and
    +``codes.okay`` all correspond to the HTTP status code 200.
    +"""
    +
    +from .structures import LookupDict
    +
    +_codes = {
    +    # Informational.
    +    100: ("continue",),
    +    101: ("switching_protocols",),
    +    102: ("processing",),
    +    103: ("checkpoint",),
    +    122: ("uri_too_long", "request_uri_too_long"),
    +    200: ("ok", "okay", "all_ok", "all_okay", "all_good", "\\o/", "✓"),
    +    201: ("created",),
    +    202: ("accepted",),
    +    203: ("non_authoritative_info", "non_authoritative_information"),
    +    204: ("no_content",),
    +    205: ("reset_content", "reset"),
    +    206: ("partial_content", "partial"),
    +    207: ("multi_status", "multiple_status", "multi_stati", "multiple_stati"),
    +    208: ("already_reported",),
    +    226: ("im_used",),
    +    # Redirection.
    +    300: ("multiple_choices",),
    +    301: ("moved_permanently", "moved", "\\o-"),
    +    302: ("found",),
    +    303: ("see_other", "other"),
    +    304: ("not_modified",),
    +    305: ("use_proxy",),
    +    306: ("switch_proxy",),
    +    307: ("temporary_redirect", "temporary_moved", "temporary"),
    +    308: (
    +        "permanent_redirect",
    +        "resume_incomplete",
    +        "resume",
    +    ),  # "resume" and "resume_incomplete" to be removed in 3.0
    +    # Client Error.
    +    400: ("bad_request", "bad"),
    +    401: ("unauthorized",),
    +    402: ("payment_required", "payment"),
    +    403: ("forbidden",),
    +    404: ("not_found", "-o-"),
    +    405: ("method_not_allowed", "not_allowed"),
    +    406: ("not_acceptable",),
    +    407: ("proxy_authentication_required", "proxy_auth", "proxy_authentication"),
    +    408: ("request_timeout", "timeout"),
    +    409: ("conflict",),
    +    410: ("gone",),
    +    411: ("length_required",),
    +    412: ("precondition_failed", "precondition"),
    +    413: ("request_entity_too_large",),
    +    414: ("request_uri_too_large",),
    +    415: ("unsupported_media_type", "unsupported_media", "media_type"),
    +    416: (
    +        "requested_range_not_satisfiable",
    +        "requested_range",
    +        "range_not_satisfiable",
    +    ),
    +    417: ("expectation_failed",),
    +    418: ("im_a_teapot", "teapot", "i_am_a_teapot"),
    +    421: ("misdirected_request",),
    +    422: ("unprocessable_entity", "unprocessable"),
    +    423: ("locked",),
    +    424: ("failed_dependency", "dependency"),
    +    425: ("unordered_collection", "unordered"),
    +    426: ("upgrade_required", "upgrade"),
    +    428: ("precondition_required", "precondition"),
    +    429: ("too_many_requests", "too_many"),
    +    431: ("header_fields_too_large", "fields_too_large"),
    +    444: ("no_response", "none"),
    +    449: ("retry_with", "retry"),
    +    450: ("blocked_by_windows_parental_controls", "parental_controls"),
    +    451: ("unavailable_for_legal_reasons", "legal_reasons"),
    +    499: ("client_closed_request",),
    +    # Server Error.
    +    500: ("internal_server_error", "server_error", "/o\\", "✗"),
    +    501: ("not_implemented",),
    +    502: ("bad_gateway",),
    +    503: ("service_unavailable", "unavailable"),
    +    504: ("gateway_timeout",),
    +    505: ("http_version_not_supported", "http_version"),
    +    506: ("variant_also_negotiates",),
    +    507: ("insufficient_storage",),
    +    509: ("bandwidth_limit_exceeded", "bandwidth"),
    +    510: ("not_extended",),
    +    511: ("network_authentication_required", "network_auth", "network_authentication"),
    +}
    +
    +codes = LookupDict(name="status_codes")
    +
    +
    +def _init():
    +    for code, titles in _codes.items():
    +        for title in titles:
    +            setattr(codes, title, code)
    +            if not title.startswith(("\\", "/")):
    +                setattr(codes, title.upper(), code)
    +
    +    def doc(code):
    +        names = ", ".join(f"``{n}``" for n in _codes[code])
    +        return "* %d: %s" % (code, names)
    +
    +    global __doc__
    +    __doc__ = (
    +        __doc__ + "\n" + "\n".join(doc(code) for code in sorted(_codes))
    +        if __doc__ is not None
    +        else None
    +    )
    +
    +
    +_init()
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/structures.py b/deployment-apps/metricator-for-nmon/lib/requests/structures.py
    new file mode 100644
    index 0000000..188e13e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/structures.py
    @@ -0,0 +1,99 @@
    +"""
    +requests.structures
    +~~~~~~~~~~~~~~~~~~~
    +
    +Data structures that power Requests.
    +"""
    +
    +from collections import OrderedDict
    +
    +from .compat import Mapping, MutableMapping
    +
    +
    +class CaseInsensitiveDict(MutableMapping):
    +    """A case-insensitive ``dict``-like object.
    +
    +    Implements all methods and operations of
    +    ``MutableMapping`` as well as dict's ``copy``. Also
    +    provides ``lower_items``.
    +
    +    All keys are expected to be strings. The structure remembers the
    +    case of the last key to be set, and ``iter(instance)``,
    +    ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
    +    will contain case-sensitive keys. However, querying and contains
    +    testing is case insensitive::
    +
    +        cid = CaseInsensitiveDict()
    +        cid['Accept'] = 'application/json'
    +        cid['aCCEPT'] == 'application/json'  # True
    +        list(cid) == ['Accept']  # True
    +
    +    For example, ``headers['content-encoding']`` will return the
    +    value of a ``'Content-Encoding'`` response header, regardless
    +    of how the header name was originally stored.
    +
    +    If the constructor, ``.update``, or equality comparison
    +    operations are given keys that have equal ``.lower()``s, the
    +    behavior is undefined.
    +    """
    +
    +    def __init__(self, data=None, **kwargs):
    +        self._store = OrderedDict()
    +        if data is None:
    +            data = {}
    +        self.update(data, **kwargs)
    +
    +    def __setitem__(self, key, value):
    +        # Use the lowercased key for lookups, but store the actual
    +        # key alongside the value.
    +        self._store[key.lower()] = (key, value)
    +
    +    def __getitem__(self, key):
    +        return self._store[key.lower()][1]
    +
    +    def __delitem__(self, key):
    +        del self._store[key.lower()]
    +
    +    def __iter__(self):
    +        return (casedkey for casedkey, mappedvalue in self._store.values())
    +
    +    def __len__(self):
    +        return len(self._store)
    +
    +    def lower_items(self):
    +        """Like iteritems(), but with all lowercase keys."""
    +        return ((lowerkey, keyval[1]) for (lowerkey, keyval) in self._store.items())
    +
    +    def __eq__(self, other):
    +        if isinstance(other, Mapping):
    +            other = CaseInsensitiveDict(other)
    +        else:
    +            return NotImplemented
    +        # Compare insensitively
    +        return dict(self.lower_items()) == dict(other.lower_items())
    +
    +    # Copy is required
    +    def copy(self):
    +        return CaseInsensitiveDict(self._store.values())
    +
    +    def __repr__(self):
    +        return str(dict(self.items()))
    +
    +
    +class LookupDict(dict):
    +    """Dictionary lookup object."""
    +
    +    def __init__(self, name=None):
    +        self.name = name
    +        super().__init__()
    +
    +    def __repr__(self):
    +        return f"<lookup '{self.name}'>"
    +
    +    def __getitem__(self, key):
    +        # We allow fall-through here, so values default to None
    +
    +        return self.__dict__.get(key, None)
    +
    +    def get(self, key, default=None):
    +        return self.__dict__.get(key, default)
    diff --git a/deployment-apps/metricator-for-nmon/lib/requests/utils.py b/deployment-apps/metricator-for-nmon/lib/requests/utils.py
    new file mode 100644
    index 0000000..ad53583
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/requests/utils.py
    @@ -0,0 +1,1086 @@
    +"""
    +requests.utils
    +~~~~~~~~~~~~~~
    +
    +This module provides utility functions that are used within Requests
    +that are also useful for external consumption.
    +"""
    +
    +import codecs
    +import contextlib
    +import io
    +import os
    +import re
    +import socket
    +import struct
    +import sys
    +import tempfile
    +import warnings
    +import zipfile
    +from collections import OrderedDict
    +
    +from urllib3.util import make_headers, parse_url
    +
    +from . import certs
    +from .__version__ import __version__
    +
    +# to_native_string is unused here, but imported here for backwards compatibility
    +from ._internal_utils import HEADER_VALIDATORS, to_native_string  # noqa: F401
    +from .compat import (
    +    Mapping,
    +    basestring,
    +    bytes,
    +    getproxies,
    +    getproxies_environment,
    +    integer_types,
    +)
    +from .compat import parse_http_list as _parse_list_header
    +from .compat import (
    +    proxy_bypass,
    +    proxy_bypass_environment,
    +    quote,
    +    str,
    +    unquote,
    +    urlparse,
    +    urlunparse,
    +)
    +from .cookies import cookiejar_from_dict
    +from .exceptions import (
    +    FileModeWarning,
    +    InvalidHeader,
    +    InvalidURL,
    +    UnrewindableBodyError,
    +)
    +from .structures import CaseInsensitiveDict
    +
    +NETRC_FILES = (".netrc", "_netrc")
    +
    +DEFAULT_CA_BUNDLE_PATH = certs.where()
    +
    +DEFAULT_PORTS = {"http": 80, "https": 443}
    +
    +# Ensure that ', ' is used to preserve previous delimiter behavior.
    +DEFAULT_ACCEPT_ENCODING = ", ".join(
    +    re.split(r",\s*", make_headers(accept_encoding=True)["accept-encoding"])
    +)
    +
    +
    +if sys.platform == "win32":
    +    # provide a proxy_bypass version on Windows without DNS lookups
    +
    +    def proxy_bypass_registry(host):
    +        try:
    +            import winreg
    +        except ImportError:
    +            return False
    +
    +        try:
    +            internetSettings = winreg.OpenKey(
    +                winreg.HKEY_CURRENT_USER,
    +                r"Software\Microsoft\Windows\CurrentVersion\Internet Settings",
    +            )
    +            # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it
    +            proxyEnable = int(winreg.QueryValueEx(internetSettings, "ProxyEnable")[0])
    +            # ProxyOverride is almost always a string
    +            proxyOverride = winreg.QueryValueEx(internetSettings, "ProxyOverride")[0]
    +        except (OSError, ValueError):
    +            return False
    +        if not proxyEnable or not proxyOverride:
    +            return False
    +
    +        # make a check value list from the registry entry: replace the
    +        # '<local>' string by the localhost entry and the corresponding
    +        # canonical entry.
    +        proxyOverride = proxyOverride.split(";")
    +        # now check if we match one of the registry values.
    +        for test in proxyOverride:
    +            if test == "<local>":
    +                if "." not in host:
    +                    return True
    +            test = test.replace(".", r"\.")  # mask dots
    +            test = test.replace("*", r".*")  # change glob sequence
    +            test = test.replace("?", r".")  # change glob char
    +            if re.match(test, host, re.I):
    +                return True
    +        return False
    +
    +    def proxy_bypass(host):  # noqa
    +        """Return True, if the host should be bypassed.
    +
    +        Checks proxy settings gathered from the environment, if specified,
    +        or the registry.
    +        """
    +        if getproxies_environment():
    +            return proxy_bypass_environment(host)
    +        else:
    +            return proxy_bypass_registry(host)
    +
    +
    +def dict_to_sequence(d):
    +    """Returns an internal sequence dictionary update."""
    +
    +    if hasattr(d, "items"):
    +        d = d.items()
    +
    +    return d
    +
    +
    +def super_len(o):
    +    total_length = None
    +    current_position = 0
    +
    +    if hasattr(o, "__len__"):
    +        total_length = len(o)
    +
    +    elif hasattr(o, "len"):
    +        total_length = o.len
    +
    +    elif hasattr(o, "fileno"):
    +        try:
    +            fileno = o.fileno()
    +        except (io.UnsupportedOperation, AttributeError):
    +            # AttributeError is a surprising exception, seeing as how we've just checked
    +            # that `hasattr(o, 'fileno')`.  It happens for objects obtained via
    +            # `Tarfile.extractfile()`, per issue 5229.
    +            pass
    +        else:
    +            total_length = os.fstat(fileno).st_size
    +
    +            # Having used fstat to determine the file length, we need to
    +            # confirm that this file was opened up in binary mode.
    +            if "b" not in o.mode:
    +                warnings.warn(
    +                    (
    +                        "Requests has determined the content-length for this "
    +                        "request using the binary size of the file: however, the "
    +                        "file has been opened in text mode (i.e. without the 'b' "
    +                        "flag in the mode). This may lead to an incorrect "
    +                        "content-length. In Requests 3.0, support will be removed "
    +                        "for files in text mode."
    +                    ),
    +                    FileModeWarning,
    +                )
    +
    +    if hasattr(o, "tell"):
    +        try:
    +            current_position = o.tell()
    +        except OSError:
    +            # This can happen in some weird situations, such as when the file
    +            # is actually a special file descriptor like stdin. In this
    +            # instance, we don't know what the length is, so set it to zero and
    +            # let requests chunk it instead.
    +            if total_length is not None:
    +                current_position = total_length
    +        else:
    +            if hasattr(o, "seek") and total_length is None:
    +                # StringIO and BytesIO have seek but no usable fileno
    +                try:
    +                    # seek to end of file
    +                    o.seek(0, 2)
    +                    total_length = o.tell()
    +
    +                    # seek back to current position to support
    +                    # partially read file-like objects
    +                    o.seek(current_position or 0)
    +                except OSError:
    +                    total_length = 0
    +
    +    if total_length is None:
    +        total_length = 0
    +
    +    return max(0, total_length - current_position)
    +
    +
    +def get_netrc_auth(url, raise_errors=False):
    +    """Returns the Requests tuple auth for a given url from netrc."""
    +
    +    netrc_file = os.environ.get("NETRC")
    +    if netrc_file is not None:
    +        netrc_locations = (netrc_file,)
    +    else:
    +        netrc_locations = (f"~/{f}" for f in NETRC_FILES)
    +
    +    try:
    +        from netrc import NetrcParseError, netrc
    +
    +        netrc_path = None
    +
    +        for f in netrc_locations:
    +            try:
    +                loc = os.path.expanduser(f)
    +            except KeyError:
    +                # os.path.expanduser can fail when $HOME is undefined and
    +                # getpwuid fails. See https://bugs.python.org/issue20164 &
    +                # https://github.com/psf/requests/issues/1846
    +                return
    +
    +            if os.path.exists(loc):
    +                netrc_path = loc
    +                break
    +
    +        # Abort early if there isn't one.
    +        if netrc_path is None:
    +            return
    +
    +        ri = urlparse(url)
    +
    +        # Strip port numbers from netloc. This weird `if...encode`` dance is
    +        # used for Python 3.2, which doesn't support unicode literals.
    +        splitstr = b":"
    +        if isinstance(url, str):
    +            splitstr = splitstr.decode("ascii")
    +        host = ri.netloc.split(splitstr)[0]
    +
    +        try:
    +            _netrc = netrc(netrc_path).authenticators(host)
    +            if _netrc:
    +                # Return with login / password
    +                login_i = 0 if _netrc[0] else 1
    +                return (_netrc[login_i], _netrc[2])
    +        except (NetrcParseError, OSError):
    +            # If there was a parsing error or a permissions issue reading the file,
    +            # we'll just skip netrc auth unless explicitly asked to raise errors.
    +            if raise_errors:
    +                raise
    +
    +    # App Engine hackiness.
    +    except (ImportError, AttributeError):
    +        pass
    +
    +
    +def guess_filename(obj):
    +    """Tries to guess the filename of the given object."""
    +    name = getattr(obj, "name", None)
    +    if name and isinstance(name, basestring) and name[0] != "<" and name[-1] != ">":
    +        return os.path.basename(name)
    +
    +
    +def extract_zipped_paths(path):
    +    """Replace nonexistent paths that look like they refer to a member of a zip
    +    archive with the location of an extracted copy of the target, or else
    +    just return the provided path unchanged.
    +    """
    +    if os.path.exists(path):
    +        # this is already a valid path, no need to do anything further
    +        return path
    +
    +    # find the first valid part of the provided path and treat that as a zip archive
    +    # assume the rest of the path is the name of a member in the archive
    +    archive, member = os.path.split(path)
    +    while archive and not os.path.exists(archive):
    +        archive, prefix = os.path.split(archive)
    +        if not prefix:
    +            # If we don't check for an empty prefix after the split (in other words, archive remains unchanged after the split),
    +            # we _can_ end up in an infinite loop on a rare corner case affecting a small number of users
    +            break
    +        member = "/".join([prefix, member])
    +
    +    if not zipfile.is_zipfile(archive):
    +        return path
    +
    +    zip_file = zipfile.ZipFile(archive)
    +    if member not in zip_file.namelist():
    +        return path
    +
    +    # we have a valid zip archive and a valid member of that archive
    +    tmp = tempfile.gettempdir()
    +    extracted_path = os.path.join(tmp, member.split("/")[-1])
    +    if not os.path.exists(extracted_path):
    +        # use read + write to avoid the creating nested folders, we only want the file, avoids mkdir racing condition
    +        with atomic_open(extracted_path) as file_handler:
    +            file_handler.write(zip_file.read(member))
    +    return extracted_path
    +
    +
    +@contextlib.contextmanager
    +def atomic_open(filename):
    +    """Write a file to the disk in an atomic fashion"""
    +    tmp_descriptor, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename))
    +    try:
    +        with os.fdopen(tmp_descriptor, "wb") as tmp_handler:
    +            yield tmp_handler
    +        os.replace(tmp_name, filename)
    +    except BaseException:
    +        os.remove(tmp_name)
    +        raise
    +
    +
    +def from_key_val_list(value):
    +    """Take an object and test to see if it can be represented as a
    +    dictionary. Unless it can not be represented as such, return an
    +    OrderedDict, e.g.,
    +
    +    ::
    +
    +        >>> from_key_val_list([('key', 'val')])
    +        OrderedDict([('key', 'val')])
    +        >>> from_key_val_list('string')
    +        Traceback (most recent call last):
    +        ...
    +        ValueError: cannot encode objects that are not 2-tuples
    +        >>> from_key_val_list({'key': 'val'})
    +        OrderedDict([('key', 'val')])
    +
    +    :rtype: OrderedDict
    +    """
    +    if value is None:
    +        return None
    +
    +    if isinstance(value, (str, bytes, bool, int)):
    +        raise ValueError("cannot encode objects that are not 2-tuples")
    +
    +    return OrderedDict(value)
    +
    +
    +def to_key_val_list(value):
    +    """Take an object and test to see if it can be represented as a
    +    dictionary. If it can be, return a list of tuples, e.g.,
    +
    +    ::
    +
    +        >>> to_key_val_list([('key', 'val')])
    +        [('key', 'val')]
    +        >>> to_key_val_list({'key': 'val'})
    +        [('key', 'val')]
    +        >>> to_key_val_list('string')
    +        Traceback (most recent call last):
    +        ...
    +        ValueError: cannot encode objects that are not 2-tuples
    +
    +    :rtype: list
    +    """
    +    if value is None:
    +        return None
    +
    +    if isinstance(value, (str, bytes, bool, int)):
    +        raise ValueError("cannot encode objects that are not 2-tuples")
    +
    +    if isinstance(value, Mapping):
    +        value = value.items()
    +
    +    return list(value)
    +
    +
    +# From mitsuhiko/werkzeug (used with permission).
    +def parse_list_header(value):
    +    """Parse lists as described by RFC 2068 Section 2.
    +
    +    In particular, parse comma-separated lists where the elements of
    +    the list may include quoted-strings.  A quoted-string could
    +    contain a comma.  A non-quoted string could have quotes in the
    +    middle.  Quotes are removed automatically after parsing.
    +
    +    It basically works like :func:`parse_set_header` just that items
    +    may appear multiple times and case sensitivity is preserved.
    +
    +    The return value is a standard :class:`list`:
    +
    +    >>> parse_list_header('token, "quoted value"')
    +    ['token', 'quoted value']
    +
    +    To create a header from the :class:`list` again, use the
    +    :func:`dump_header` function.
    +
    +    :param value: a string with a list header.
    +    :return: :class:`list`
    +    :rtype: list
    +    """
    +    result = []
    +    for item in _parse_list_header(value):
    +        if item[:1] == item[-1:] == '"':
    +            item = unquote_header_value(item[1:-1])
    +        result.append(item)
    +    return result
    +
    +
    +# From mitsuhiko/werkzeug (used with permission).
    +def parse_dict_header(value):
    +    """Parse lists of key, value pairs as described by RFC 2068 Section 2 and
    +    convert them into a python dict:
    +
    +    >>> d = parse_dict_header('foo="is a fish", bar="as well"')
    +    >>> type(d) is dict
    +    True
    +    >>> sorted(d.items())
    +    [('bar', 'as well'), ('foo', 'is a fish')]
    +
    +    If there is no value for a key it will be `None`:
    +
    +    >>> parse_dict_header('key_without_value')
    +    {'key_without_value': None}
    +
    +    To create a header from the :class:`dict` again, use the
    +    :func:`dump_header` function.
    +
    +    :param value: a string with a dict header.
    +    :return: :class:`dict`
    +    :rtype: dict
    +    """
    +    result = {}
    +    for item in _parse_list_header(value):
    +        if "=" not in item:
    +            result[item] = None
    +            continue
    +        name, value = item.split("=", 1)
    +        if value[:1] == value[-1:] == '"':
    +            value = unquote_header_value(value[1:-1])
    +        result[name] = value
    +    return result
    +
    +
    +# From mitsuhiko/werkzeug (used with permission).
    +def unquote_header_value(value, is_filename=False):
    +    r"""Unquotes a header value.  (Reversal of :func:`quote_header_value`).
    +    This does not use the real unquoting but what browsers are actually
    +    using for quoting.
    +
    +    :param value: the header value to unquote.
    +    :rtype: str
    +    """
    +    if value and value[0] == value[-1] == '"':
    +        # this is not the real unquoting, but fixing this so that the
    +        # RFC is met will result in bugs with internet explorer and
    +        # probably some other browsers as well.  IE for example is
    +        # uploading files with "C:\foo\bar.txt" as filename
    +        value = value[1:-1]
    +
    +        # if this is a filename and the starting characters look like
    +        # a UNC path, then just return the value without quotes.  Using the
    +        # replace sequence below on a UNC path has the effect of turning
    +        # the leading double slash into a single slash and then
    +        # _fix_ie_filename() doesn't work correctly.  See #458.
    +        if not is_filename or value[:2] != "\\\\":
    +            return value.replace("\\\\", "\\").replace('\\"', '"')
    +    return value
    +
    +
    +def dict_from_cookiejar(cj):
    +    """Returns a key/value dictionary from a CookieJar.
    +
    +    :param cj: CookieJar object to extract cookies from.
    +    :rtype: dict
    +    """
    +
    +    cookie_dict = {}
    +
    +    for cookie in cj:
    +        cookie_dict[cookie.name] = cookie.value
    +
    +    return cookie_dict
    +
    +
    +def add_dict_to_cookiejar(cj, cookie_dict):
    +    """Returns a CookieJar from a key/value dictionary.
    +
    +    :param cj: CookieJar to insert cookies into.
    +    :param cookie_dict: Dict of key/values to insert into CookieJar.
    +    :rtype: CookieJar
    +    """
    +
    +    return cookiejar_from_dict(cookie_dict, cj)
    +
    +
    +def get_encodings_from_content(content):
    +    """Returns encodings from given content string.
    +
    +    :param content: bytestring to extract encodings from.
    +    """
    +    warnings.warn(
    +        (
    +            "In requests 3.0, get_encodings_from_content will be removed. For "
    +            "more information, please see the discussion on issue #2266. (This"
    +            " warning should only appear once.)"
    +        ),
    +        DeprecationWarning,
    +    )
    +
    +    charset_re = re.compile(r'<meta.*?charset=["\']*(.+?)["\'>]', flags=re.I)
    +    pragma_re = re.compile(r'<meta.*?content=["\']*;?charset=(.+?)["\'>]', flags=re.I)
    +    xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]')
    +
    +    return (
    +        charset_re.findall(content)
    +        + pragma_re.findall(content)
    +        + xml_re.findall(content)
    +    )
    +
    +
    +def _parse_content_type_header(header):
    +    """Returns content type and parameters from given header
    +
    +    :param header: string
    +    :return: tuple containing content type and dictionary of
    +         parameters
    +    """
    +
    +    tokens = header.split(";")
    +    content_type, params = tokens[0].strip(), tokens[1:]
    +    params_dict = {}
    +    items_to_strip = "\"' "
    +
    +    for param in params:
    +        param = param.strip()
    +        if param:
    +            key, value = param, True
    +            index_of_equals = param.find("=")
    +            if index_of_equals != -1:
    +                key = param[:index_of_equals].strip(items_to_strip)
    +                value = param[index_of_equals + 1 :].strip(items_to_strip)
    +            params_dict[key.lower()] = value
    +    return content_type, params_dict
    +
    +
    +def get_encoding_from_headers(headers):
    +    """Returns encodings from given HTTP Header Dict.
    +
    +    :param headers: dictionary to extract encoding from.
    +    :rtype: str
    +    """
    +
    +    content_type = headers.get("content-type")
    +
    +    if not content_type:
    +        return None
    +
    +    content_type, params = _parse_content_type_header(content_type)
    +
    +    if "charset" in params:
    +        return params["charset"].strip("'\"")
    +
    +    if "text" in content_type:
    +        return "ISO-8859-1"
    +
    +    if "application/json" in content_type:
    +        # Assume UTF-8 based on RFC 4627: https://www.ietf.org/rfc/rfc4627.txt since the charset was unset
    +        return "utf-8"
    +
    +
    +def stream_decode_response_unicode(iterator, r):
    +    """Stream decodes an iterator."""
    +
    +    if r.encoding is None:
    +        yield from iterator
    +        return
    +
    +    decoder = codecs.getincrementaldecoder(r.encoding)(errors="replace")
    +    for chunk in iterator:
    +        rv = decoder.decode(chunk)
    +        if rv:
    +            yield rv
    +    rv = decoder.decode(b"", final=True)
    +    if rv:
    +        yield rv
    +
    +
    +def iter_slices(string, slice_length):
    +    """Iterate over slices of a string."""
    +    pos = 0
    +    if slice_length is None or slice_length <= 0:
    +        slice_length = len(string)
    +    while pos < len(string):
    +        yield string[pos : pos + slice_length]
    +        pos += slice_length
    +
    +
    +def get_unicode_from_response(r):
    +    """Returns the requested content back in unicode.
    +
    +    :param r: Response object to get unicode content from.
    +
    +    Tried:
    +
    +    1. charset from content-type
    +    2. fall back and replace all unicode characters
    +
    +    :rtype: str
    +    """
    +    warnings.warn(
    +        (
    +            "In requests 3.0, get_unicode_from_response will be removed. For "
    +            "more information, please see the discussion on issue #2266. (This"
    +            " warning should only appear once.)"
    +        ),
    +        DeprecationWarning,
    +    )
    +
    +    tried_encodings = []
    +
    +    # Try charset from content-type
    +    encoding = get_encoding_from_headers(r.headers)
    +
    +    if encoding:
    +        try:
    +            return str(r.content, encoding)
    +        except UnicodeError:
    +            tried_encodings.append(encoding)
    +
    +    # Fall back:
    +    try:
    +        return str(r.content, encoding, errors="replace")
    +    except TypeError:
    +        return r.content
    +
    +
    +# The unreserved URI characters (RFC 3986)
    +UNRESERVED_SET = frozenset(
    +    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~"
    +)
    +
    +
    +def unquote_unreserved(uri):
    +    """Un-escape any percent-escape sequences in a URI that are unreserved
    +    characters. This leaves all reserved, illegal and non-ASCII bytes encoded.
    +
    +    :rtype: str
    +    """
    +    parts = uri.split("%")
    +    for i in range(1, len(parts)):
    +        h = parts[i][0:2]
    +        if len(h) == 2 and h.isalnum():
    +            try:
    +                c = chr(int(h, 16))
    +            except ValueError:
    +                raise InvalidURL(f"Invalid percent-escape sequence: '{h}'")
    +
    +            if c in UNRESERVED_SET:
    +                parts[i] = c + parts[i][2:]
    +            else:
    +                parts[i] = f"%{parts[i]}"
    +        else:
    +            parts[i] = f"%{parts[i]}"
    +    return "".join(parts)
    +
    +
    +def requote_uri(uri):
    +    """Re-quote the given URI.
    +
    +    This function passes the given URI through an unquote/quote cycle to
    +    ensure that it is fully and consistently quoted.
    +
    +    :rtype: str
    +    """
    +    safe_with_percent = "!#$%&'()*+,/:;=?@[]~"
    +    safe_without_percent = "!#$&'()*+,/:;=?@[]~"
    +    try:
    +        # Unquote only the unreserved characters
    +        # Then quote only illegal characters (do not quote reserved,
    +        # unreserved, or '%')
    +        return quote(unquote_unreserved(uri), safe=safe_with_percent)
    +    except InvalidURL:
    +        # We couldn't unquote the given URI, so let's try quoting it, but
    +        # there may be unquoted '%'s in the URI. We need to make sure they're
    +        # properly quoted so they do not cause issues elsewhere.
    +        return quote(uri, safe=safe_without_percent)
    +
    +
    +def address_in_network(ip, net):
    +    """This function allows you to check if an IP belongs to a network subnet
    +
    +    Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24
    +             returns False if ip = 192.168.1.1 and net = 192.168.100.0/24
    +
    +    :rtype: bool
    +    """
    +    ipaddr = struct.unpack("=L", socket.inet_aton(ip))[0]
    +    netaddr, bits = net.split("/")
    +    netmask = struct.unpack("=L", socket.inet_aton(dotted_netmask(int(bits))))[0]
    +    network = struct.unpack("=L", socket.inet_aton(netaddr))[0] & netmask
    +    return (ipaddr & netmask) == (network & netmask)
    +
    +
    +def dotted_netmask(mask):
    +    """Converts mask from /xx format to xxx.xxx.xxx.xxx
    +
    +    Example: if mask is 24 function returns 255.255.255.0
    +
    +    :rtype: str
    +    """
    +    bits = 0xFFFFFFFF ^ (1 << 32 - mask) - 1
    +    return socket.inet_ntoa(struct.pack(">I", bits))
    +
    +
    +def is_ipv4_address(string_ip):
    +    """
    +    :rtype: bool
    +    """
    +    try:
    +        socket.inet_aton(string_ip)
    +    except OSError:
    +        return False
    +    return True
    +
    +
    +def is_valid_cidr(string_network):
    +    """
    +    Very simple check of the cidr format in no_proxy variable.
    +
    +    :rtype: bool
    +    """
    +    if string_network.count("/") == 1:
    +        try:
    +            mask = int(string_network.split("/")[1])
    +        except ValueError:
    +            return False
    +
    +        if mask < 1 or mask > 32:
    +            return False
    +
    +        try:
    +            socket.inet_aton(string_network.split("/")[0])
    +        except OSError:
    +            return False
    +    else:
    +        return False
    +    return True
    +
    +
    +@contextlib.contextmanager
    +def set_environ(env_name, value):
    +    """Set the environment variable 'env_name' to 'value'
    +
    +    Save previous value, yield, and then restore the previous value stored in
    +    the environment variable 'env_name'.
    +
    +    If 'value' is None, do nothing"""
    +    value_changed = value is not None
    +    if value_changed:
    +        old_value = os.environ.get(env_name)
    +        os.environ[env_name] = value
    +    try:
    +        yield
    +    finally:
    +        if value_changed:
    +            if old_value is None:
    +                del os.environ[env_name]
    +            else:
    +                os.environ[env_name] = old_value
    +
    +
    +def should_bypass_proxies(url, no_proxy):
    +    """
    +    Returns whether we should bypass proxies or not.
    +
    +    :rtype: bool
    +    """
    +    # Prioritize lowercase environment variables over uppercase
    +    # to keep a consistent behaviour with other http projects (curl, wget).
    +    def get_proxy(key):
    +        return os.environ.get(key) or os.environ.get(key.upper())
    +
    +    # First check whether no_proxy is defined. If it is, check that the URL
    +    # we're getting isn't in the no_proxy list.
    +    no_proxy_arg = no_proxy
    +    if no_proxy is None:
    +        no_proxy = get_proxy("no_proxy")
    +    parsed = urlparse(url)
    +
    +    if parsed.hostname is None:
    +        # URLs don't always have hostnames, e.g. file:/// urls.
    +        return True
    +
    +    if no_proxy:
    +        # We need to check whether we match here. We need to see if we match
    +        # the end of the hostname, both with and without the port.
    +        no_proxy = (host for host in no_proxy.replace(" ", "").split(",") if host)
    +
    +        if is_ipv4_address(parsed.hostname):
    +            for proxy_ip in no_proxy:
    +                if is_valid_cidr(proxy_ip):
    +                    if address_in_network(parsed.hostname, proxy_ip):
    +                        return True
    +                elif parsed.hostname == proxy_ip:
    +                    # If no_proxy ip was defined in plain IP notation instead of cidr notation &
    +                    # matches the IP of the index
    +                    return True
    +        else:
    +            host_with_port = parsed.hostname
    +            if parsed.port:
    +                host_with_port += f":{parsed.port}"
    +
    +            for host in no_proxy:
    +                if parsed.hostname.endswith(host) or host_with_port.endswith(host):
    +                    # The URL does match something in no_proxy, so we don't want
    +                    # to apply the proxies on this URL.
    +                    return True
    +
    +    with set_environ("no_proxy", no_proxy_arg):
    +        # parsed.hostname can be `None` in cases such as a file URI.
    +        try:
    +            bypass = proxy_bypass(parsed.hostname)
    +        except (TypeError, socket.gaierror):
    +            bypass = False
    +
    +    if bypass:
    +        return True
    +
    +    return False
    +
    +
    +def get_environ_proxies(url, no_proxy=None):
    +    """
    +    Return a dict of environment proxies.
    +
    +    :rtype: dict
    +    """
    +    if should_bypass_proxies(url, no_proxy=no_proxy):
    +        return {}
    +    else:
    +        return getproxies()
    +
    +
    +def select_proxy(url, proxies):
    +    """Select a proxy for the url, if applicable.
    +
    +    :param url: The url being for the request
    +    :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
    +    """
    +    proxies = proxies or {}
    +    urlparts = urlparse(url)
    +    if urlparts.hostname is None:
    +        return proxies.get(urlparts.scheme, proxies.get("all"))
    +
    +    proxy_keys = [
    +        urlparts.scheme + "://" + urlparts.hostname,
    +        urlparts.scheme,
    +        "all://" + urlparts.hostname,
    +        "all",
    +    ]
    +    proxy = None
    +    for proxy_key in proxy_keys:
    +        if proxy_key in proxies:
    +            proxy = proxies[proxy_key]
    +            break
    +
    +    return proxy
    +
    +
    +def resolve_proxies(request, proxies, trust_env=True):
    +    """This method takes proxy information from a request and configuration
    +    input to resolve a mapping of target proxies. This will consider settings
    +    such a NO_PROXY to strip proxy configurations.
    +
    +    :param request: Request or PreparedRequest
    +    :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
    +    :param trust_env: Boolean declaring whether to trust environment configs
    +
    +    :rtype: dict
    +    """
    +    proxies = proxies if proxies is not None else {}
    +    url = request.url
    +    scheme = urlparse(url).scheme
    +    no_proxy = proxies.get("no_proxy")
    +    new_proxies = proxies.copy()
    +
    +    if trust_env and not should_bypass_proxies(url, no_proxy=no_proxy):
    +        environ_proxies = get_environ_proxies(url, no_proxy=no_proxy)
    +
    +        proxy = environ_proxies.get(scheme, environ_proxies.get("all"))
    +
    +        if proxy:
    +            new_proxies.setdefault(scheme, proxy)
    +    return new_proxies
    +
    +
    +def default_user_agent(name="python-requests"):
    +    """
    +    Return a string representing the default user agent.
    +
    +    :rtype: str
    +    """
    +    return f"{name}/{__version__}"
    +
    +
    +def default_headers():
    +    """
    +    :rtype: requests.structures.CaseInsensitiveDict
    +    """
    +    return CaseInsensitiveDict(
    +        {
    +            "User-Agent": default_user_agent(),
    +            "Accept-Encoding": DEFAULT_ACCEPT_ENCODING,
    +            "Accept": "*/*",
    +            "Connection": "keep-alive",
    +        }
    +    )
    +
    +
    +def parse_header_links(value):
    +    """Return a list of parsed link headers proxies.
    +
    +    i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg"
    +
    +    :rtype: list
    +    """
    +
    +    links = []
    +
    +    replace_chars = " '\""
    +
    +    value = value.strip(replace_chars)
    +    if not value:
    +        return links
    +
    +    for val in re.split(", *<", value):
    +        try:
    +            url, params = val.split(";", 1)
    +        except ValueError:
    +            url, params = val, ""
    +
    +        link = {"url": url.strip("<> '\"")}
    +
    +        for param in params.split(";"):
    +            try:
    +                key, value = param.split("=")
    +            except ValueError:
    +                break
    +
    +            link[key.strip(replace_chars)] = value.strip(replace_chars)
    +
    +        links.append(link)
    +
    +    return links
    +
    +
    +# Null bytes; no need to recreate these on each call to guess_json_utf
    +_null = "\x00".encode("ascii")  # encoding to ASCII for Python 3
    +_null2 = _null * 2
    +_null3 = _null * 3
    +
    +
    +def guess_json_utf(data):
    +    """
    +    :rtype: str
    +    """
    +    # JSON always starts with two ASCII characters, so detection is as
    +    # easy as counting the nulls and from their location and count
    +    # determine the encoding. Also detect a BOM, if present.
    +    sample = data[:4]
    +    if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE):
    +        return "utf-32"  # BOM included
    +    if sample[:3] == codecs.BOM_UTF8:
    +        return "utf-8-sig"  # BOM included, MS style (discouraged)
    +    if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE):
    +        return "utf-16"  # BOM included
    +    nullcount = sample.count(_null)
    +    if nullcount == 0:
    +        return "utf-8"
    +    if nullcount == 2:
    +        if sample[::2] == _null2:  # 1st and 3rd are null
    +            return "utf-16-be"
    +        if sample[1::2] == _null2:  # 2nd and 4th are null
    +            return "utf-16-le"
    +        # Did not detect 2 valid UTF-16 ascii-range characters
    +    if nullcount == 3:
    +        if sample[:3] == _null3:
    +            return "utf-32-be"
    +        if sample[1:] == _null3:
    +            return "utf-32-le"
    +        # Did not detect a valid UTF-32 ascii-range character
    +    return None
    +
    +
    +def prepend_scheme_if_needed(url, new_scheme):
    +    """Given a URL that may or may not have a scheme, prepend the given scheme.
    +    Does not replace a present scheme with the one provided as an argument.
    +
    +    :rtype: str
    +    """
    +    parsed = parse_url(url)
    +    scheme, auth, host, port, path, query, fragment = parsed
    +
    +    # A defect in urlparse determines that there isn't a netloc present in some
    +    # urls. We previously assumed parsing was overly cautious, and swapped the
    +    # netloc and path. Due to a lack of tests on the original defect, this is
    +    # maintained with parse_url for backwards compatibility.
    +    netloc = parsed.netloc
    +    if not netloc:
    +        netloc, path = path, netloc
    +
    +    if auth:
    +        # parse_url doesn't provide the netloc with auth
    +        # so we'll add it ourselves.
    +        netloc = "@".join([auth, netloc])
    +    if scheme is None:
    +        scheme = new_scheme
    +    if path is None:
    +        path = ""
    +
    +    return urlunparse((scheme, netloc, path, "", query, fragment))
    +
    +
    +def get_auth_from_url(url):
    +    """Given a url with authentication components, extract them into a tuple of
    +    username,password.
    +
    +    :rtype: (str,str)
    +    """
    +    parsed = urlparse(url)
    +
    +    try:
    +        auth = (unquote(parsed.username), unquote(parsed.password))
    +    except (AttributeError, TypeError):
    +        auth = ("", "")
    +
    +    return auth
    +
    +
    +def check_header_validity(header):
    +    """Verifies that header parts don't contain leading whitespace
    +    reserved characters, or return characters.
    +
    +    :param header: tuple, in the format (name, value).
    +    """
    +    name, value = header
    +
    +    for part in header:
    +        if type(part) not in HEADER_VALIDATORS:
    +            raise InvalidHeader(
    +                f"Header part ({part!r}) from {{{name!r}: {value!r}}} must be "
    +                f"of type str or bytes, not {type(part)}"
    +            )
    +
    +    _validate_header_part(name, "name", HEADER_VALIDATORS[type(name)][0])
    +    _validate_header_part(value, "value", HEADER_VALIDATORS[type(value)][1])
    +
    +
    +def _validate_header_part(header_part, header_kind, validator):
    +    if not validator.match(header_part):
    +        raise InvalidHeader(
    +            f"Invalid leading whitespace, reserved character(s), or return"
    +            f"character(s) in header {header_kind}: {header_part!r}"
    +        )
    +
    +
    +def urldefragauth(url):
    +    """
    +    Given a url remove the fragment and the authentication part.
    +
    +    :rtype: str
    +    """
    +    scheme, netloc, path, params, query, fragment = urlparse(url)
    +
    +    # see func:`prepend_scheme_if_needed`
    +    if not netloc:
    +        netloc, path = path, netloc
    +
    +    netloc = netloc.rsplit("@", 1)[-1]
    +
    +    return urlunparse((scheme, netloc, path, params, query, ""))
    +
    +
    +def rewind_body(prepared_request):
    +    """Move file pointer back to its recorded starting position
    +    so it can be read again on redirect.
    +    """
    +    body_seek = getattr(prepared_request.body, "seek", None)
    +    if body_seek is not None and isinstance(
    +        prepared_request._body_position, integer_types
    +    ):
    +        try:
    +            body_seek(prepared_request._body_position)
    +        except OSError:
    +            raise UnrewindableBodyError(
    +                "An error occurred when rewinding request body for redirect."
    +            )
    +    else:
    +        raise UnrewindableBodyError("Unable to rewind request body for redirect.")
    diff --git a/deployment-apps/metricator-for-nmon/lib/socks.py b/deployment-apps/metricator-for-nmon/lib/socks.py
    new file mode 100644
    index 0000000..83b1435
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/socks.py
    @@ -0,0 +1,847 @@
    +from base64 import b64encode
    +try:
    +    from collections.abc import Callable
    +except ImportError:
    +    from collections import Callable
    +from errno import EOPNOTSUPP, EINVAL, EAGAIN
    +import functools
    +from io import BytesIO
    +import logging
    +import os
    +from os import SEEK_CUR
    +import socket
    +import struct
    +import sys
    +
    +__version__ = "1.7.1"
    +
    +
    +if os.name == "nt" and sys.version_info < (3, 0):
    +    try:
    +        import win_inet_pton
    +    except ImportError:
    +        raise ImportError(
    +            "To run PySocks on Windows you must install win_inet_pton")
    +
    +log = logging.getLogger(__name__)
    +
    +PROXY_TYPE_SOCKS4 = SOCKS4 = 1
    +PROXY_TYPE_SOCKS5 = SOCKS5 = 2
    +PROXY_TYPE_HTTP = HTTP = 3
    +
    +PROXY_TYPES = {"SOCKS4": SOCKS4, "SOCKS5": SOCKS5, "HTTP": HTTP}
    +PRINTABLE_PROXY_TYPES = dict(zip(PROXY_TYPES.values(), PROXY_TYPES.keys()))
    +
    +_orgsocket = _orig_socket = socket.socket
    +
    +
    +def set_self_blocking(function):
    +
    +    @functools.wraps(function)
    +    def wrapper(*args, **kwargs):
    +        self = args[0]
    +        try:
    +            _is_blocking = self.gettimeout()
    +            if _is_blocking == 0:
    +                self.setblocking(True)
    +            return function(*args, **kwargs)
    +        except Exception as e:
    +            raise
    +        finally:
    +            # set orgin blocking
    +            if _is_blocking == 0:
    +                self.setblocking(False)
    +    return wrapper
    +
    +
    +class ProxyError(IOError):
    +    """Socket_err contains original socket.error exception."""
    +    def __init__(self, msg, socket_err=None):
    +        self.msg = msg
    +        self.socket_err = socket_err
    +
    +        if socket_err:
    +            self.msg += ": {}".format(socket_err)
    +
    +    def __str__(self):
    +        return self.msg
    +
    +
    +class GeneralProxyError(ProxyError):
    +    pass
    +
    +
    +class ProxyConnectionError(ProxyError):
    +    pass
    +
    +
    +class SOCKS5AuthError(ProxyError):
    +    pass
    +
    +
    +class SOCKS5Error(ProxyError):
    +    pass
    +
    +
    +class SOCKS4Error(ProxyError):
    +    pass
    +
    +
    +class HTTPError(ProxyError):
    +    pass
    +
    +SOCKS4_ERRORS = {
    +    0x5B: "Request rejected or failed",
    +    0x5C: ("Request rejected because SOCKS server cannot connect to identd on"
    +           " the client"),
    +    0x5D: ("Request rejected because the client program and identd report"
    +           " different user-ids")
    +}
    +
    +SOCKS5_ERRORS = {
    +    0x01: "General SOCKS server failure",
    +    0x02: "Connection not allowed by ruleset",
    +    0x03: "Network unreachable",
    +    0x04: "Host unreachable",
    +    0x05: "Connection refused",
    +    0x06: "TTL expired",
    +    0x07: "Command not supported, or protocol error",
    +    0x08: "Address type not supported"
    +}
    +
    +DEFAULT_PORTS = {SOCKS4: 1080, SOCKS5: 1080, HTTP: 8080}
    +
    +
    +def set_default_proxy(proxy_type=None, addr=None, port=None, rdns=True,
    +                      username=None, password=None):
    +    """Sets a default proxy.
    +
    +    All further socksocket objects will use the default unless explicitly
    +    changed. All parameters are as for socket.set_proxy()."""
    +    socksocket.default_proxy = (proxy_type, addr, port, rdns,
    +                                username.encode() if username else None,
    +                                password.encode() if password else None)
    +
    +
    +def setdefaultproxy(*args, **kwargs):
    +    if "proxytype" in kwargs:
    +        kwargs["proxy_type"] = kwargs.pop("proxytype")
    +    return set_default_proxy(*args, **kwargs)
    +
    +
    +def get_default_proxy():
    +    """Returns the default proxy, set by set_default_proxy."""
    +    return socksocket.default_proxy
    +
    +getdefaultproxy = get_default_proxy
    +
    +
    +def wrap_module(module):
    +    """Attempts to replace a module's socket library with a SOCKS socket.
    +
    +    Must set a default proxy using set_default_proxy(...) first. This will
    +    only work on modules that import socket directly into the namespace;
    +    most of the Python Standard Library falls into this category."""
    +    if socksocket.default_proxy:
    +        module.socket.socket = socksocket
    +    else:
    +        raise GeneralProxyError("No default proxy specified")
    +
    +wrapmodule = wrap_module
    +
    +
    +def create_connection(dest_pair,
    +                      timeout=None, source_address=None,
    +                      proxy_type=None, proxy_addr=None,
    +                      proxy_port=None, proxy_rdns=True,
    +                      proxy_username=None, proxy_password=None,
    +                      socket_options=None):
    +    """create_connection(dest_pair, *[, timeout], **proxy_args) -> socket object
    +
    +    Like socket.create_connection(), but connects to proxy
    +    before returning the socket object.
    +
    +    dest_pair - 2-tuple of (IP/hostname, port).
    +    **proxy_args - Same args passed to socksocket.set_proxy() if present.
    +    timeout - Optional socket timeout value, in seconds.
    +    source_address - tuple (host, port) for the socket to bind to as its source
    +    address before connecting (only for compatibility)
    +    """
    +    # Remove IPv6 brackets on the remote address and proxy address.
    +    remote_host, remote_port = dest_pair
    +    if remote_host.startswith("["):
    +        remote_host = remote_host.strip("[]")
    +    if proxy_addr and proxy_addr.startswith("["):
    +        proxy_addr = proxy_addr.strip("[]")
    +
    +    err = None
    +
    +    # Allow the SOCKS proxy to be on IPv4 or IPv6 addresses.
    +    for r in socket.getaddrinfo(proxy_addr, proxy_port, 0, socket.SOCK_STREAM):
    +        family, socket_type, proto, canonname, sa = r
    +        sock = None
    +        try:
    +            sock = socksocket(family, socket_type, proto)
    +
    +            if socket_options:
    +                for opt in socket_options:
    +                    sock.setsockopt(*opt)
    +
    +            if isinstance(timeout, (int, float)):
    +                sock.settimeout(timeout)
    +
    +            if proxy_type:
    +                sock.set_proxy(proxy_type, proxy_addr, proxy_port, proxy_rdns,
    +                               proxy_username, proxy_password)
    +            if source_address:
    +                sock.bind(source_address)
    +
    +            sock.connect((remote_host, remote_port))
    +            return sock
    +
    +        except (socket.error, ProxyError) as e:
    +            err = e
    +            if sock:
    +                sock.close()
    +                sock = None
    +
    +    if err:
    +        raise err
    +
    +    raise socket.error("gai returned empty list.")
    +
    +
    +class _BaseSocket(socket.socket):
    +    """Allows Python 2 delegated methods such as send() to be overridden."""
    +    def __init__(self, *pos, **kw):
    +        _orig_socket.__init__(self, *pos, **kw)
    +
    +        self._savedmethods = dict()
    +        for name in self._savenames:
    +            self._savedmethods[name] = getattr(self, name)
    +            delattr(self, name)  # Allows normal overriding mechanism to work
    +
    +    _savenames = list()
    +
    +
    +def _makemethod(name):
    +    return lambda self, *pos, **kw: self._savedmethods[name](*pos, **kw)
    +for name in ("sendto", "send", "recvfrom", "recv"):
    +    method = getattr(_BaseSocket, name, None)
    +
    +    # Determine if the method is not defined the usual way
    +    # as a function in the class.
    +    # Python 2 uses __slots__, so there are descriptors for each method,
    +    # but they are not functions.
    +    if not isinstance(method, Callable):
    +        _BaseSocket._savenames.append(name)
    +        setattr(_BaseSocket, name, _makemethod(name))
    +
    +
    +class socksocket(_BaseSocket):
    +    """socksocket([family[, type[, proto]]]) -> socket object
    +
    +    Open a SOCKS enabled socket. The parameters are the same as
    +    those of the standard socket init. In order for SOCKS to work,
    +    you must specify family=AF_INET and proto=0.
    +    The "type" argument must be either SOCK_STREAM or SOCK_DGRAM.
    +    """
    +
    +    default_proxy = None
    +
    +    def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM,
    +                 proto=0, *args, **kwargs):
    +        if type not in (socket.SOCK_STREAM, socket.SOCK_DGRAM):
    +            msg = "Socket type must be stream or datagram, not {!r}"
    +            raise ValueError(msg.format(type))
    +
    +        super(socksocket, self).__init__(family, type, proto, *args, **kwargs)
    +        self._proxyconn = None  # TCP connection to keep UDP relay alive
    +
    +        if self.default_proxy:
    +            self.proxy = self.default_proxy
    +        else:
    +            self.proxy = (None, None, None, None, None, None)
    +        self.proxy_sockname = None
    +        self.proxy_peername = None
    +
    +        self._timeout = None
    +
    +    def _readall(self, file, count):
    +        """Receive EXACTLY the number of bytes requested from the file object.
    +
    +        Blocks until the required number of bytes have been received."""
    +        data = b""
    +        while len(data) < count:
    +            d = file.read(count - len(data))
    +            if not d:
    +                raise GeneralProxyError("Connection closed unexpectedly")
    +            data += d
    +        return data
    +
    +    def settimeout(self, timeout):
    +        self._timeout = timeout
    +        try:
    +            # test if we're connected, if so apply timeout
    +            peer = self.get_proxy_peername()
    +            super(socksocket, self).settimeout(self._timeout)
    +        except socket.error:
    +            pass
    +
    +    def gettimeout(self):
    +        return self._timeout
    +
    +    def setblocking(self, v):
    +        if v:
    +            self.settimeout(None)
    +        else:
    +            self.settimeout(0.0)
    +
    +    def set_proxy(self, proxy_type=None, addr=None, port=None, rdns=True,
    +                  username=None, password=None):
    +        """ Sets the proxy to be used.
    +
    +        proxy_type -  The type of the proxy to be used. Three types
    +                        are supported: PROXY_TYPE_SOCKS4 (including socks4a),
    +                        PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP
    +        addr -        The address of the server (IP or DNS).
    +        port -        The port of the server. Defaults to 1080 for SOCKS
    +                        servers and 8080 for HTTP proxy servers.
    +        rdns -        Should DNS queries be performed on the remote side
    +                       (rather than the local side). The default is True.
    +                       Note: This has no effect with SOCKS4 servers.
    +        username -    Username to authenticate with to the server.
    +                       The default is no authentication.
    +        password -    Password to authenticate with to the server.
    +                       Only relevant when username is also provided."""
    +        self.proxy = (proxy_type, addr, port, rdns,
    +                      username.encode() if username else None,
    +                      password.encode() if password else None)
    +
    +    def setproxy(self, *args, **kwargs):
    +        if "proxytype" in kwargs:
    +            kwargs["proxy_type"] = kwargs.pop("proxytype")
    +        return self.set_proxy(*args, **kwargs)
    +
    +    def bind(self, *pos, **kw):
    +        """Implements proxy connection for UDP sockets.
    +
    +        Happens during the bind() phase."""
    +        (proxy_type, proxy_addr, proxy_port, rdns, username,
    +         password) = self.proxy
    +        if not proxy_type or self.type != socket.SOCK_DGRAM:
    +            return _orig_socket.bind(self, *pos, **kw)
    +
    +        if self._proxyconn:
    +            raise socket.error(EINVAL, "Socket already bound to an address")
    +        if proxy_type != SOCKS5:
    +            msg = "UDP only supported by SOCKS5 proxy type"
    +            raise socket.error(EOPNOTSUPP, msg)
    +        super(socksocket, self).bind(*pos, **kw)
    +
    +        # Need to specify actual local port because
    +        # some relays drop packets if a port of zero is specified.
    +        # Avoid specifying host address in case of NAT though.
    +        _, port = self.getsockname()
    +        dst = ("0", port)
    +
    +        self._proxyconn = _orig_socket()
    +        proxy = self._proxy_addr()
    +        self._proxyconn.connect(proxy)
    +
    +        UDP_ASSOCIATE = b"\x03"
    +        _, relay = self._SOCKS5_request(self._proxyconn, UDP_ASSOCIATE, dst)
    +
    +        # The relay is most likely on the same host as the SOCKS proxy,
    +        # but some proxies return a private IP address (10.x.y.z)
    +        host, _ = proxy
    +        _, port = relay
    +        super(socksocket, self).connect((host, port))
    +        super(socksocket, self).settimeout(self._timeout)
    +        self.proxy_sockname = ("0.0.0.0", 0)  # Unknown
    +
    +    def sendto(self, bytes, *args, **kwargs):
    +        if self.type != socket.SOCK_DGRAM:
    +            return super(socksocket, self).sendto(bytes, *args, **kwargs)
    +        if not self._proxyconn:
    +            self.bind(("", 0))
    +
    +        address = args[-1]
    +        flags = args[:-1]
    +
    +        header = BytesIO()
    +        RSV = b"\x00\x00"
    +        header.write(RSV)
    +        STANDALONE = b"\x00"
    +        header.write(STANDALONE)
    +        self._write_SOCKS5_address(address, header)
    +
    +        sent = super(socksocket, self).send(header.getvalue() + bytes, *flags,
    +                                            **kwargs)
    +        return sent - header.tell()
    +
    +    def send(self, bytes, flags=0, **kwargs):
    +        if self.type == socket.SOCK_DGRAM:
    +            return self.sendto(bytes, flags, self.proxy_peername, **kwargs)
    +        else:
    +            return super(socksocket, self).send(bytes, flags, **kwargs)
    +
    +    def recvfrom(self, bufsize, flags=0):
    +        if self.type != socket.SOCK_DGRAM:
    +            return super(socksocket, self).recvfrom(bufsize, flags)
    +        if not self._proxyconn:
    +            self.bind(("", 0))
    +
    +        buf = BytesIO(super(socksocket, self).recv(bufsize + 1024, flags))
    +        buf.seek(2, SEEK_CUR)
    +        frag = buf.read(1)
    +        if ord(frag):
    +            raise NotImplementedError("Received UDP packet fragment")
    +        fromhost, fromport = self._read_SOCKS5_address(buf)
    +
    +        if self.proxy_peername:
    +            peerhost, peerport = self.proxy_peername
    +            if fromhost != peerhost or peerport not in (0, fromport):
    +                raise socket.error(EAGAIN, "Packet filtered")
    +
    +        return (buf.read(bufsize), (fromhost, fromport))
    +
    +    def recv(self, *pos, **kw):
    +        bytes, _ = self.recvfrom(*pos, **kw)
    +        return bytes
    +
    +    def close(self):
    +        if self._proxyconn:
    +            self._proxyconn.close()
    +        return super(socksocket, self).close()
    +
    +    def get_proxy_sockname(self):
    +        """Returns the bound IP address and port number at the proxy."""
    +        return self.proxy_sockname
    +
    +    getproxysockname = get_proxy_sockname
    +
    +    def get_proxy_peername(self):
    +        """
    +        Returns the IP and port number of the proxy.
    +        """
    +        return self.getpeername()
    +
    +    getproxypeername = get_proxy_peername
    +
    +    def get_peername(self):
    +        """Returns the IP address and port number of the destination machine.
    +
    +        Note: get_proxy_peername returns the proxy."""
    +        return self.proxy_peername
    +
    +    getpeername = get_peername
    +
    +    def _negotiate_SOCKS5(self, *dest_addr):
    +        """Negotiates a stream connection through a SOCKS5 server."""
    +        CONNECT = b"\x01"
    +        self.proxy_peername, self.proxy_sockname = self._SOCKS5_request(
    +            self, CONNECT, dest_addr)
    +
    +    def _SOCKS5_request(self, conn, cmd, dst):
    +        """
    +        Send SOCKS5 request with given command (CMD field) and
    +        address (DST field). Returns resolved DST address that was used.
    +        """
    +        proxy_type, addr, port, rdns, username, password = self.proxy
    +
    +        writer = conn.makefile("wb")
    +        reader = conn.makefile("rb", 0)  # buffering=0 renamed in Python 3
    +        try:
    +            # First we'll send the authentication packages we support.
    +            if username and password:
    +                # The username/password details were supplied to the
    +                # set_proxy method so we support the USERNAME/PASSWORD
    +                # authentication (in addition to the standard none).
    +                writer.write(b"\x05\x02\x00\x02")
    +            else:
    +                # No username/password were entered, therefore we
    +                # only support connections with no authentication.
    +                writer.write(b"\x05\x01\x00")
    +
    +            # We'll receive the server's response to determine which
    +            # method was selected
    +            writer.flush()
    +            chosen_auth = self._readall(reader, 2)
    +
    +            if chosen_auth[0:1] != b"\x05":
    +                # Note: string[i:i+1] is used because indexing of a bytestring
    +                # via bytestring[i] yields an integer in Python 3
    +                raise GeneralProxyError(
    +                    "SOCKS5 proxy server sent invalid data")
    +
    +            # Check the chosen authentication method
    +
    +            if chosen_auth[1:2] == b"\x02":
    +                # Okay, we need to perform a basic username/password
    +                # authentication.
    +                if not (username and password):
    +                    # Although we said we don't support authentication, the
    +                    # server may still request basic username/password
    +                    # authentication
    +                    raise SOCKS5AuthError("No username/password supplied. "
    +                                          "Server requested username/password"
    +                                          " authentication")
    +
    +                writer.write(b"\x01" + chr(len(username)).encode()
    +                             + username
    +                             + chr(len(password)).encode()
    +                             + password)
    +                writer.flush()
    +                auth_status = self._readall(reader, 2)
    +                if auth_status[0:1] != b"\x01":
    +                    # Bad response
    +                    raise GeneralProxyError(
    +                        "SOCKS5 proxy server sent invalid data")
    +                if auth_status[1:2] != b"\x00":
    +                    # Authentication failed
    +                    raise SOCKS5AuthError("SOCKS5 authentication failed")
    +
    +                # Otherwise, authentication succeeded
    +
    +            # No authentication is required if 0x00
    +            elif chosen_auth[1:2] != b"\x00":
    +                # Reaching here is always bad
    +                if chosen_auth[1:2] == b"\xFF":
    +                    raise SOCKS5AuthError(
    +                        "All offered SOCKS5 authentication methods were"
    +                        " rejected")
    +                else:
    +                    raise GeneralProxyError(
    +                        "SOCKS5 proxy server sent invalid data")
    +
    +            # Now we can request the actual connection
    +            writer.write(b"\x05" + cmd + b"\x00")
    +            resolved = self._write_SOCKS5_address(dst, writer)
    +            writer.flush()
    +
    +            # Get the response
    +            resp = self._readall(reader, 3)
    +            if resp[0:1] != b"\x05":
    +                raise GeneralProxyError(
    +                    "SOCKS5 proxy server sent invalid data")
    +
    +            status = ord(resp[1:2])
    +            if status != 0x00:
    +                # Connection failed: server returned an error
    +                error = SOCKS5_ERRORS.get(status, "Unknown error")
    +                raise SOCKS5Error("{:#04x}: {}".format(status, error))
    +
    +            # Get the bound address/port
    +            bnd = self._read_SOCKS5_address(reader)
    +
    +            super(socksocket, self).settimeout(self._timeout)
    +            return (resolved, bnd)
    +        finally:
    +            reader.close()
    +            writer.close()
    +
    +    def _write_SOCKS5_address(self, addr, file):
    +        """
    +        Return the host and port packed for the SOCKS5 protocol,
    +        and the resolved address as a tuple object.
    +        """
    +        host, port = addr
    +        proxy_type, _, _, rdns, username, password = self.proxy
    +        family_to_byte = {socket.AF_INET: b"\x01", socket.AF_INET6: b"\x04"}
    +
    +        # If the given destination address is an IP address, we'll
    +        # use the IP address request even if remote resolving was specified.
    +        # Detect whether the address is IPv4/6 directly.
    +        for family in (socket.AF_INET, socket.AF_INET6):
    +            try:
    +                addr_bytes = socket.inet_pton(family, host)
    +                file.write(family_to_byte[family] + addr_bytes)
    +                host = socket.inet_ntop(family, addr_bytes)
    +                file.write(struct.pack(">H", port))
    +                return host, port
    +            except socket.error:
    +                continue
    +
    +        # Well it's not an IP number, so it's probably a DNS name.
    +        if rdns:
    +            # Resolve remotely
    +            host_bytes = host.encode("idna")
    +            file.write(b"\x03" + chr(len(host_bytes)).encode() + host_bytes)
    +        else:
    +            # Resolve locally
    +            addresses = socket.getaddrinfo(host, port, socket.AF_UNSPEC,
    +                                           socket.SOCK_STREAM,
    +                                           socket.IPPROTO_TCP,
    +                                           socket.AI_ADDRCONFIG)
    +            # We can't really work out what IP is reachable, so just pick the
    +            # first.
    +            target_addr = addresses[0]
    +            family = target_addr[0]
    +            host = target_addr[4][0]
    +
    +            addr_bytes = socket.inet_pton(family, host)
    +            file.write(family_to_byte[family] + addr_bytes)
    +            host = socket.inet_ntop(family, addr_bytes)
    +        file.write(struct.pack(">H", port))
    +        return host, port
    +
    +    def _read_SOCKS5_address(self, file):
    +        atyp = self._readall(file, 1)
    +        if atyp == b"\x01":
    +            addr = socket.inet_ntoa(self._readall(file, 4))
    +        elif atyp == b"\x03":
    +            length = self._readall(file, 1)
    +            addr = self._readall(file, ord(length))
    +        elif atyp == b"\x04":
    +            addr = socket.inet_ntop(socket.AF_INET6, self._readall(file, 16))
    +        else:
    +            raise GeneralProxyError("SOCKS5 proxy server sent invalid data")
    +
    +        port = struct.unpack(">H", self._readall(file, 2))[0]
    +        return addr, port
    +
    +    def _negotiate_SOCKS4(self, dest_addr, dest_port):
    +        """Negotiates a connection through a SOCKS4 server."""
    +        proxy_type, addr, port, rdns, username, password = self.proxy
    +
    +        writer = self.makefile("wb")
    +        reader = self.makefile("rb", 0)  # buffering=0 renamed in Python 3
    +        try:
    +            # Check if the destination address provided is an IP address
    +            remote_resolve = False
    +            try:
    +                addr_bytes = socket.inet_aton(dest_addr)
    +            except socket.error:
    +                # It's a DNS name. Check where it should be resolved.
    +                if rdns:
    +                    addr_bytes = b"\x00\x00\x00\x01"
    +                    remote_resolve = True
    +                else:
    +                    addr_bytes = socket.inet_aton(
    +                        socket.gethostbyname(dest_addr))
    +
    +            # Construct the request packet
    +            writer.write(struct.pack(">BBH", 0x04, 0x01, dest_port))
    +            writer.write(addr_bytes)
    +
    +            # The username parameter is considered userid for SOCKS4
    +            if username:
    +                writer.write(username)
    +            writer.write(b"\x00")
    +
    +            # DNS name if remote resolving is required
    +            # NOTE: This is actually an extension to the SOCKS4 protocol
    +            # called SOCKS4A and may not be supported in all cases.
    +            if remote_resolve:
    +                writer.write(dest_addr.encode("idna") + b"\x00")
    +            writer.flush()
    +
    +            # Get the response from the server
    +            resp = self._readall(reader, 8)
    +            if resp[0:1] != b"\x00":
    +                # Bad data
    +                raise GeneralProxyError(
    +                    "SOCKS4 proxy server sent invalid data")
    +
    +            status = ord(resp[1:2])
    +            if status != 0x5A:
    +                # Connection failed: server returned an error
    +                error = SOCKS4_ERRORS.get(status, "Unknown error")
    +                raise SOCKS4Error("{:#04x}: {}".format(status, error))
    +
    +            # Get the bound address/port
    +            self.proxy_sockname = (socket.inet_ntoa(resp[4:]),
    +                                   struct.unpack(">H", resp[2:4])[0])
    +            if remote_resolve:
    +                self.proxy_peername = socket.inet_ntoa(addr_bytes), dest_port
    +            else:
    +                self.proxy_peername = dest_addr, dest_port
    +        finally:
    +            reader.close()
    +            writer.close()
    +
    +    def _negotiate_HTTP(self, dest_addr, dest_port):
    +        """Negotiates a connection through an HTTP server.
    +
    +        NOTE: This currently only supports HTTP CONNECT-style proxies."""
    +        proxy_type, addr, port, rdns, username, password = self.proxy
    +
    +        # If we need to resolve locally, we do this now
    +        addr = dest_addr if rdns else socket.gethostbyname(dest_addr)
    +
    +        http_headers = [
    +            (b"CONNECT " + addr.encode("idna") + b":"
    +             + str(dest_port).encode() + b" HTTP/1.1"),
    +            b"Host: " + dest_addr.encode("idna")
    +        ]
    +
    +        if username and password:
    +            http_headers.append(b"Proxy-Authorization: basic "
    +                                + b64encode(username + b":" + password))
    +
    +        http_headers.append(b"\r\n")
    +
    +        self.sendall(b"\r\n".join(http_headers))
    +
    +        # We just need the first line to check if the connection was successful
    +        fobj = self.makefile()
    +        status_line = fobj.readline()
    +        fobj.close()
    +
    +        if not status_line:
    +            raise GeneralProxyError("Connection closed unexpectedly")
    +
    +        try:
    +            proto, status_code, status_msg = status_line.split(" ", 2)
    +        except ValueError:
    +            raise GeneralProxyError("HTTP proxy server sent invalid response")
    +
    +        if not proto.startswith("HTTP/"):
    +            raise GeneralProxyError(
    +                "Proxy server does not appear to be an HTTP proxy")
    +
    +        try:
    +            status_code = int(status_code)
    +        except ValueError:
    +            raise HTTPError(
    +                "HTTP proxy server did not return a valid HTTP status")
    +
    +        if status_code != 200:
    +            error = "{}: {}".format(status_code, status_msg)
    +            if status_code in (400, 403, 405):
    +                # It's likely that the HTTP proxy server does not support the
    +                # CONNECT tunneling method
    +                error += ("\n[*] Note: The HTTP proxy server may not be"
    +                          " supported by PySocks (must be a CONNECT tunnel"
    +                          " proxy)")
    +            raise HTTPError(error)
    +
    +        self.proxy_sockname = (b"0.0.0.0", 0)
    +        self.proxy_peername = addr, dest_port
    +
    +    _proxy_negotiators = {
    +                           SOCKS4: _negotiate_SOCKS4,
    +                           SOCKS5: _negotiate_SOCKS5,
    +                           HTTP: _negotiate_HTTP
    +                         }
    +
    +    @set_self_blocking
    +    def connect(self, dest_pair, catch_errors=None):
    +        """
    +        Connects to the specified destination through a proxy.
    +        Uses the same API as socket's connect().
    +        To select the proxy server, use set_proxy().
    +
    +        dest_pair - 2-tuple of (IP/hostname, port).
    +        """
    +        if len(dest_pair) != 2 or dest_pair[0].startswith("["):
    +            # Probably IPv6, not supported -- raise an error, and hope
    +            # Happy Eyeballs (RFC6555) makes sure at least the IPv4
    +            # connection works...
    +            raise socket.error("PySocks doesn't support IPv6: %s"
    +                               % str(dest_pair))
    +
    +        dest_addr, dest_port = dest_pair
    +
    +        if self.type == socket.SOCK_DGRAM:
    +            if not self._proxyconn:
    +                self.bind(("", 0))
    +            dest_addr = socket.gethostbyname(dest_addr)
    +
    +            # If the host address is INADDR_ANY or similar, reset the peer
    +            # address so that packets are received from any peer
    +            if dest_addr == "0.0.0.0" and not dest_port:
    +                self.proxy_peername = None
    +            else:
    +                self.proxy_peername = (dest_addr, dest_port)
    +            return
    +
    +        (proxy_type, proxy_addr, proxy_port, rdns, username,
    +         password) = self.proxy
    +
    +        # Do a minimal input check first
    +        if (not isinstance(dest_pair, (list, tuple))
    +                or len(dest_pair) != 2
    +                or not dest_addr
    +                or not isinstance(dest_port, int)):
    +            # Inputs failed, raise an error
    +            raise GeneralProxyError(
    +                "Invalid destination-connection (host, port) pair")
    +
    +        # We set the timeout here so that we don't hang in connection or during
    +        # negotiation.
    +        super(socksocket, self).settimeout(self._timeout)
    +
    +        if proxy_type is None:
    +            # Treat like regular socket object
    +            self.proxy_peername = dest_pair
    +            super(socksocket, self).settimeout(self._timeout)
    +            super(socksocket, self).connect((dest_addr, dest_port))
    +            return
    +
    +        proxy_addr = self._proxy_addr()
    +
    +        try:
    +            # Initial connection to proxy server.
    +            super(socksocket, self).connect(proxy_addr)
    +
    +        except socket.error as error:
    +            # Error while connecting to proxy
    +            self.close()
    +            if not catch_errors:
    +                proxy_addr, proxy_port = proxy_addr
    +                proxy_server = "{}:{}".format(proxy_addr, proxy_port)
    +                printable_type = PRINTABLE_PROXY_TYPES[proxy_type]
    +
    +                msg = "Error connecting to {} proxy {}".format(printable_type,
    +                                                                    proxy_server)
    +                log.debug("%s due to: %s", msg, error)
    +                raise ProxyConnectionError(msg, error)
    +            else:
    +                raise error
    +
    +        else:
    +            # Connected to proxy server, now negotiate
    +            try:
    +                # Calls negotiate_{SOCKS4, SOCKS5, HTTP}
    +                negotiate = self._proxy_negotiators[proxy_type]
    +                negotiate(self, dest_addr, dest_port)
    +            except socket.error as error:
    +                if not catch_errors:
    +                    # Wrap socket errors
    +                    self.close()
    +                    raise GeneralProxyError("Socket error", error)
    +                else:
    +                    raise error
    +            except ProxyError:
    +                # Protocol error while negotiating with proxy
    +                self.close()
    +                raise
    +                
    +    @set_self_blocking
    +    def connect_ex(self, dest_pair):
    +        """ https://docs.python.org/3/library/socket.html#socket.socket.connect_ex
    +        Like connect(address), but return an error indicator instead of raising an exception for errors returned by the C-level connect() call (other problems, such as "host not found" can still raise exceptions).
    +        """
    +        try:
    +            self.connect(dest_pair, catch_errors=True)
    +            return 0
    +        except OSError as e:
    +            # If the error is numeric (socket errors are numeric), then return number as 
    +            # connect_ex expects. Otherwise raise the error again (socket timeout for example)
    +            if e.errno:
    +                return e.errno
    +            else:
    +                raise
    +
    +    def _proxy_addr(self):
    +        """
    +        Return proxy address to connect to as tuple object
    +        """
    +        (proxy_type, proxy_addr, proxy_port, rdns, username,
    +         password) = self.proxy
    +        proxy_port = proxy_port or DEFAULT_PORTS.get(proxy_type)
    +        if not proxy_port:
    +            raise GeneralProxyError("Invalid proxy type")
    +        return proxy_addr, proxy_port
    diff --git a/deployment-apps/metricator-for-nmon/lib/sockshandler.py b/deployment-apps/metricator-for-nmon/lib/sockshandler.py
    new file mode 100644
    index 0000000..6a2ed81
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/sockshandler.py
    @@ -0,0 +1,111 @@
    +#!/usr/bin/env python
    +"""
    +SocksiPy + urllib2 handler
    +
    +version: 0.3
    +author: e<e@tr0ll.in>
    +
    +This module provides a Handler which you can use with urllib2 to allow it to tunnel your connection through a socks.sockssocket socket, with out monkey patching the original socket...
    +"""
    +import socket
    +import ssl
    +
    +try:
    +    import urllib2
    +    import httplib
    +except ImportError: # Python 3
    +    import urllib.request as urllib2
    +    import http.client as httplib
    +
    +import socks # $ pip install PySocks
    +
    +def merge_dict(a, b):
    +    d = a.copy()
    +    d.update(b)
    +    return d
    +
    +def is_ip(s):
    +    try:
    +        if ':' in s:
    +            socket.inet_pton(socket.AF_INET6, s)
    +        elif '.' in s:
    +            socket.inet_aton(s)
    +        else:
    +            return False
    +    except:
    +        return False
    +    else:
    +        return True
    +
    +socks4_no_rdns = set()
    +
    +class SocksiPyConnection(httplib.HTTPConnection):
    +    def __init__(self, proxytype, proxyaddr, proxyport=None, rdns=True, username=None, password=None, *args, **kwargs):
    +        self.proxyargs = (proxytype, proxyaddr, proxyport, rdns, username, password)
    +        httplib.HTTPConnection.__init__(self, *args, **kwargs)
    +
    +    def connect(self):
    +        (proxytype, proxyaddr, proxyport, rdns, username, password) = self.proxyargs
    +        rdns = rdns and proxyaddr not in socks4_no_rdns
    +        while True:
    +            try:
    +                sock = socks.create_connection(
    +                    (self.host, self.port), self.timeout, None,
    +                    proxytype, proxyaddr, proxyport, rdns, username, password,
    +                    ((socket.IPPROTO_TCP, socket.TCP_NODELAY, 1),))
    +                break
    +            except socks.SOCKS4Error as e:
    +                if rdns and "0x5b" in str(e) and not is_ip(self.host):
    +                    # Maybe a SOCKS4 server that doesn't support remote resolving
    +                    # Let's try again
    +                    rdns = False
    +                    socks4_no_rdns.add(proxyaddr)
    +                else:
    +                    raise
    +        self.sock = sock
    +
    +class SocksiPyConnectionS(httplib.HTTPSConnection):
    +    def __init__(self, proxytype, proxyaddr, proxyport=None, rdns=True, username=None, password=None, *args, **kwargs):
    +        self.proxyargs = (proxytype, proxyaddr, proxyport, rdns, username, password)
    +        httplib.HTTPSConnection.__init__(self, *args, **kwargs)
    +
    +    def connect(self):
    +        SocksiPyConnection.connect(self)
    +        self.sock = self._context.wrap_socket(self.sock, server_hostname=self.host)
    +        if not self._context.check_hostname and self._check_hostname:
    +            try:
    +                ssl.match_hostname(self.sock.getpeercert(), self.host)
    +            except Exception:
    +                self.sock.shutdown(socket.SHUT_RDWR)
    +                self.sock.close()
    +                raise
    +
    +class SocksiPyHandler(urllib2.HTTPHandler, urllib2.HTTPSHandler):
    +    def __init__(self, *args, **kwargs):
    +        self.args = args
    +        self.kw = kwargs
    +        urllib2.HTTPHandler.__init__(self)
    +
    +    def http_open(self, req):
    +        def build(host, port=None, timeout=0, **kwargs):
    +            kw = merge_dict(self.kw, kwargs)
    +            conn = SocksiPyConnection(*self.args, host=host, port=port, timeout=timeout, **kw)
    +            return conn
    +        return self.do_open(build, req)
    +
    +    def https_open(self, req):
    +        def build(host, port=None, timeout=0, **kwargs):
    +            kw = merge_dict(self.kw, kwargs)
    +            conn = SocksiPyConnectionS(*self.args, host=host, port=port, timeout=timeout, **kw)
    +            return conn
    +        return self.do_open(build, req)
    +
    +if __name__ == "__main__":
    +    import sys
    +    try:
    +        port = int(sys.argv[1])
    +    except (ValueError, IndexError):
    +        port = 9050
    +    opener = urllib2.build_opener(SocksiPyHandler(socks.PROXY_TYPE_SOCKS5, "localhost", port))
    +    print("HTTP: " + opener.open("http://httpbin.org/ip").read().decode())
    +    print("HTTPS: " + opener.open("https://httpbin.org/ip").read().decode())
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/INSTALLER b/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/INSTALLER
    new file mode 100644
    index 0000000..a1b589e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/INSTALLER
    @@ -0,0 +1 @@
    +pip
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/LICENSE b/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/LICENSE
    new file mode 100644
    index 0000000..d13065d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/LICENSE
    @@ -0,0 +1,201 @@
    +                                 Apache License
    +                           Version 2.0, January 2004
    +                        http://www.apache.org/licenses/
    +
    +   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    +
    +   1. Definitions.
    +
    +      "License" shall mean the terms and conditions for use, reproduction,
    +      and distribution as defined by Sections 1 through 9 of this document.
    +
    +      "Licensor" shall mean the copyright owner or entity authorized by
    +      the copyright owner that is granting the License.
    +
    +      "Legal Entity" shall mean the union of the acting entity and all
    +      other entities that control, are controlled by, or are under common
    +      control with that entity. For the purposes of this definition,
    +      "control" means (i) the power, direct or indirect, to cause the
    +      direction or management of such entity, whether by contract or
    +      otherwise, or (ii) ownership of fifty percent (50%) or more of the
    +      outstanding shares, or (iii) beneficial ownership of such entity.
    +
    +      "You" (or "Your") shall mean an individual or Legal Entity
    +      exercising permissions granted by this License.
    +
    +      "Source" form shall mean the preferred form for making modifications,
    +      including but not limited to software source code, documentation
    +      source, and configuration files.
    +
    +      "Object" form shall mean any form resulting from mechanical
    +      transformation or translation of a Source form, including but
    +      not limited to compiled object code, generated documentation,
    +      and conversions to other media types.
    +
    +      "Work" shall mean the work of authorship, whether in Source or
    +      Object form, made available under the License, as indicated by a
    +      copyright notice that is included in or attached to the work
    +      (an example is provided in the Appendix below).
    +
    +      "Derivative Works" shall mean any work, whether in Source or Object
    +      form, that is based on (or derived from) the Work and for which the
    +      editorial revisions, annotations, elaborations, or other modifications
    +      represent, as a whole, an original work of authorship. For the purposes
    +      of this License, Derivative Works shall not include works that remain
    +      separable from, or merely link (or bind by name) to the interfaces of,
    +      the Work and Derivative Works thereof.
    +
    +      "Contribution" shall mean any work of authorship, including
    +      the original version of the Work and any modifications or additions
    +      to that Work or Derivative Works thereof, that is intentionally
    +      submitted to Licensor for inclusion in the Work by the copyright owner
    +      or by an individual or Legal Entity authorized to submit on behalf of
    +      the copyright owner. For the purposes of this definition, "submitted"
    +      means any form of electronic, verbal, or written communication sent
    +      to the Licensor or its representatives, including but not limited to
    +      communication on electronic mailing lists, source code control systems,
    +      and issue tracking systems that are managed by, or on behalf of, the
    +      Licensor for the purpose of discussing and improving the Work, but
    +      excluding communication that is conspicuously marked or otherwise
    +      designated in writing by the copyright owner as "Not a Contribution."
    +
    +      "Contributor" shall mean Licensor and any individual or Legal Entity
    +      on behalf of whom a Contribution has been received by Licensor and
    +      subsequently incorporated within the Work.
    +
    +   2. Grant of Copyright License. Subject to the terms and conditions of
    +      this License, each Contributor hereby grants to You a perpetual,
    +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    +      copyright license to reproduce, prepare Derivative Works of,
    +      publicly display, publicly perform, sublicense, and distribute the
    +      Work and such Derivative Works in Source or Object form.
    +
    +   3. Grant of Patent License. Subject to the terms and conditions of
    +      this License, each Contributor hereby grants to You a perpetual,
    +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    +      (except as stated in this section) patent license to make, have made,
    +      use, offer to sell, sell, import, and otherwise transfer the Work,
    +      where such license applies only to those patent claims licensable
    +      by such Contributor that are necessarily infringed by their
    +      Contribution(s) alone or by combination of their Contribution(s)
    +      with the Work to which such Contribution(s) was submitted. If You
    +      institute patent litigation against any entity (including a
    +      cross-claim or counterclaim in a lawsuit) alleging that the Work
    +      or a Contribution incorporated within the Work constitutes direct
    +      or contributory patent infringement, then any patent licenses
    +      granted to You under this License for that Work shall terminate
    +      as of the date such litigation is filed.
    +
    +   4. Redistribution. You may reproduce and distribute copies of the
    +      Work or Derivative Works thereof in any medium, with or without
    +      modifications, and in Source or Object form, provided that You
    +      meet the following conditions:
    +
    +      (a) You must give any other recipients of the Work or
    +          Derivative Works a copy of this License; and
    +
    +      (b) You must cause any modified files to carry prominent notices
    +          stating that You changed the files; and
    +
    +      (c) You must retain, in the Source form of any Derivative Works
    +          that You distribute, all copyright, patent, trademark, and
    +          attribution notices from the Source form of the Work,
    +          excluding those notices that do not pertain to any part of
    +          the Derivative Works; and
    +
    +      (d) If the Work includes a "NOTICE" text file as part of its
    +          distribution, then any Derivative Works that You distribute must
    +          include a readable copy of the attribution notices contained
    +          within such NOTICE file, excluding those notices that do not
    +          pertain to any part of the Derivative Works, in at least one
    +          of the following places: within a NOTICE text file distributed
    +          as part of the Derivative Works; within the Source form or
    +          documentation, if provided along with the Derivative Works; or,
    +          within a display generated by the Derivative Works, if and
    +          wherever such third-party notices normally appear. The contents
    +          of the NOTICE file are for informational purposes only and
    +          do not modify the License. You may add Your own attribution
    +          notices within Derivative Works that You distribute, alongside
    +          or as an addendum to the NOTICE text from the Work, provided
    +          that such additional attribution notices cannot be construed
    +          as modifying the License.
    +
    +      You may add Your own copyright statement to Your modifications and
    +      may provide additional or different license terms and conditions
    +      for use, reproduction, or distribution of Your modifications, or
    +      for any such Derivative Works as a whole, provided Your use,
    +      reproduction, and distribution of the Work otherwise complies with
    +      the conditions stated in this License.
    +
    +   5. Submission of Contributions. Unless You explicitly state otherwise,
    +      any Contribution intentionally submitted for inclusion in the Work
    +      by You to the Licensor shall be under the terms and conditions of
    +      this License, without any additional terms or conditions.
    +      Notwithstanding the above, nothing herein shall supersede or modify
    +      the terms of any separate license agreement you may have executed
    +      with Licensor regarding such Contributions.
    +
    +   6. Trademarks. This License does not grant permission to use the trade
    +      names, trademarks, service marks, or product names of the Licensor,
    +      except as required for reasonable and customary use in describing the
    +      origin of the Work and reproducing the content of the NOTICE file.
    +
    +   7. Disclaimer of Warranty. Unless required by applicable law or
    +      agreed to in writing, Licensor provides the Work (and each
    +      Contributor provides its Contributions) on an "AS IS" BASIS,
    +      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    +      implied, including, without limitation, any warranties or conditions
    +      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
    +      PARTICULAR PURPOSE. You are solely responsible for determining the
    +      appropriateness of using or redistributing the Work and assume any
    +      risks associated with Your exercise of permissions under this License.
    +
    +   8. Limitation of Liability. In no event and under no legal theory,
    +      whether in tort (including negligence), contract, or otherwise,
    +      unless required by applicable law (such as deliberate and grossly
    +      negligent acts) or agreed to in writing, shall any Contributor be
    +      liable to You for damages, including any direct, indirect, special,
    +      incidental, or consequential damages of any character arising as a
    +      result of this License or out of the use or inability to use the
    +      Work (including but not limited to damages for loss of goodwill,
    +      work stoppage, computer failure or malfunction, or any and all
    +      other commercial damages or losses), even if such Contributor
    +      has been advised of the possibility of such damages.
    +
    +   9. Accepting Warranty or Additional Liability. While redistributing
    +      the Work or Derivative Works thereof, You may choose to offer,
    +      and charge a fee for, acceptance of support, warranty, indemnity,
    +      or other liability obligations and/or rights consistent with this
    +      License. However, in accepting such obligations, You may act only
    +      on Your own behalf and on Your sole responsibility, not on behalf
    +      of any other Contributor, and only if You agree to indemnify,
    +      defend, and hold each Contributor harmless for any liability
    +      incurred by, or claims asserted against, such Contributor by reason
    +      of your accepting any such warranty or additional liability.
    +
    +   END OF TERMS AND CONDITIONS
    +
    +   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 "{}"
    +      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
    +      file or class name and description of purpose be included on the
    +      same "printed page" as the copyright notice for easier
    +      identification within third-party archives.
    +
    +   Copyright 2021 Splunk Inc.
    +
    +   Licensed 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.
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/METADATA b/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/METADATA
    new file mode 100644
    index 0000000..0e2ff5b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/METADATA
    @@ -0,0 +1,21 @@
    +Metadata-Version: 2.1
    +Name: solnlib
    +Version: 4.9.1
    +Summary: The Splunk Software Development Kit for Splunk Solutions
    +Home-page: https://github.com/splunk/addonfactory-solutions-library-python
    +License: Apache-2.0
    +Author: Splunk
    +Author-email: addonfactory@splunk.com
    +Requires-Python: >=3.7,<4.0
    +Classifier: License :: OSI Approved :: Apache Software License
    +Classifier: Programming Language :: Python :: 3
    +Classifier: Programming Language :: Python :: 3.7
    +Classifier: Programming Language :: Python :: 3.8
    +Classifier: Programming Language :: Python :: 3.9
    +Classifier: Programming Language :: Python :: 3.10
    +Classifier: Programming Language :: Python :: 3.11
    +Requires-Dist: defusedxml (>=0.7.1,<0.8.0)
    +Requires-Dist: requests (>=2.28.0,<3.0.0)
    +Requires-Dist: sortedcontainers (>=2.2,<3.0)
    +Requires-Dist: splunk-sdk (>=1.6.18)
    +Project-URL: Repository, https://github.com/splunk/addonfactory-solutions-library-python
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/RECORD b/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/RECORD
    new file mode 100644
    index 0000000..7665ca8
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/RECORD
    @@ -0,0 +1,28 @@
    +solnlib-4.9.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
    +solnlib-4.9.1.dist-info/LICENSE,sha256=Xvvd894DEl8lUHPEeFU-Ya18RW7Hc2IlPTZS_bE3Hgs,11341
    +solnlib-4.9.1.dist-info/METADATA,sha256=SBFRcIVQKSvJY1MppPVWeKUIOpWD1sBaVHiZmCVkOH8,912
    +solnlib-4.9.1.dist-info/RECORD,,
    +solnlib-4.9.1.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
    +solnlib/__init__.py,sha256=JwDxIsRqigHS3p3zkvhoXV2Snb3yDZn0D4aRpI8g8iU,1244
    +solnlib/_utils.py,sha256=g8c5sLcKYtsdJDf8xfufQxeEf153hFXA83mqw17eNrg,2735
    +solnlib/acl.py,sha256=WLe7X7lBiaGRtUSqOmUKq38Z0kMnZL9_fPx5XnXd_I4,5901
    +solnlib/conf_manager.py,sha256=zpzNSE1ocXrBXPhd-_Zipr2mLf7My2ix6e9ItMsd08o,16897
    +solnlib/credentials.py,sha256=8mr0t_bxz8wKt_ZIiFkqKxckDaxRhkZKP2Q48BHahD8,13862
    +solnlib/file_monitor.py,sha256=LRDNOtFxz83AIcWrhmorPOv1JoWvjpd6AtuM5_ynem0,3974
    +solnlib/hec_config.py,sha256=1QuFfOmpIAofVVC2NvCo4Hvre8YER7RhAriDjMv0sDI,5050
    +solnlib/log.py,sha256=10Ro9RfhTDrDd36t_tefH9NXUNugRx5qO_l-EDbOP50,7269
    +solnlib/modular_input/__init__.py,sha256=ln0Lqf55KfIZUDYy7vzQOvC6Y5_J1vSS7N1KzbO04QM,1186
    +solnlib/modular_input/checkpointer.py,sha256=-X22d3kqYrqiyefw3kQtc_IeQTDqaTw0iKc9ZRicLiY,8688
    +solnlib/modular_input/event.py,sha256=XgklQPwPmJTRn1JyOQ6Kx1OAIf6ZZfcA8NmtqFLWRSs,7869
    +solnlib/modular_input/event_writer.py,sha256=I61SBDZjTXhDMBlCpcy2HSWE07zwDwzTB1hiFxvDBzs,15634
    +solnlib/modular_input/modular_input.py,sha256=uOzxAuBSGZM2dzsqZvD6pzPGe2WPMtIssrSAyTm2EfU,17930
    +solnlib/net_utils.py,sha256=gFapFKL2rrn_UDajm76NWa_dfAYoKjF2yUqv3LvB5AQ,4059
    +solnlib/orphan_process_monitor.py,sha256=evo8yPH6vdoKjllN-cB6kZhkwMkCvhr-drl85zUXALY,3214
    +solnlib/pattern.py,sha256=oBahtj7xVlWOaaLPeqdrpud6vVUl05fhx6r2YUk9IdI,1158
    +solnlib/server_info.py,sha256=xgQh_ZNtHm9knCXJQMPZVemuGzRK-hXOjrtV8WVbfVM,7856
    +solnlib/splunk_rest_client.py,sha256=WnmZPIKy1POU4NrPXT379tYQO2jhn_znzUsOXtv5iwg,7235
    +solnlib/splunkenv.py,sha256=ExL6F04bAYkSTnVTp-l0kE1yGUizyw_Q8BgyaTjrxpk,7887
    +solnlib/time_parser.py,sha256=XQkw5eWo4nz5KmaIv5zw8dQdtsqTiT3RljDYw2aYLa4,4664
    +solnlib/timer_queue.py,sha256=wzqZXJ2_2uKX4RPpkrie7QZyKU4XuoEv_UBVfl9puHw,9968
    +solnlib/user_access.py,sha256=sUmYArPRhPAkMls4AUbBHD0Kniz3VEFaNY6NOoRNpUc,29171
    +solnlib/utils.py,sha256=E4EFu0LYHME6YYMDbfiHRnWSlNptqGNsvG2P7YEncTc,5251
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/WHEEL b/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/WHEEL
    new file mode 100644
    index 0000000..4ba7671
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib-4.9.1.dist-info/WHEEL
    @@ -0,0 +1,4 @@
    +Wheel-Version: 1.0
    +Generator: poetry-core 1.4.0
    +Root-Is-Purelib: true
    +Tag: py3-none-any
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/__init__.py b/deployment-apps/metricator-for-nmon/lib/solnlib/__init__.py
    new file mode 100644
    index 0000000..18acf47
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/__init__.py
    @@ -0,0 +1,57 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""The Splunk Software Development Kit for Solutions."""
    +
    +from . import (
    +    acl,
    +    conf_manager,
    +    credentials,
    +    file_monitor,
    +    hec_config,
    +    log,
    +    net_utils,
    +    orphan_process_monitor,
    +    pattern,
    +    server_info,
    +    splunk_rest_client,
    +    splunkenv,
    +    time_parser,
    +    timer_queue,
    +    user_access,
    +    utils,
    +)
    +
    +__all__ = [
    +    "acl",
    +    "conf_manager",
    +    "credentials",
    +    "file_monitor",
    +    "hec_config",
    +    "log",
    +    "net_utils",
    +    "orphan_process_monitor",
    +    "pattern",
    +    "server_info",
    +    "splunk_rest_client",
    +    "splunkenv",
    +    "time_parser",
    +    "timer_queue",
    +    "user_access",
    +    "utils",
    +]
    +
    +__version__ = "4.9.1"
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/_utils.py b/deployment-apps/metricator-for-nmon/lib/solnlib/_utils.py
    new file mode 100644
    index 0000000..b557623
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/_utils.py
    @@ -0,0 +1,79 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +"""This module provide utils that are private to solnlib."""
    +
    +import re
    +from typing import Any, Dict, Optional, Union
    +
    +from splunklib import binding, client
    +
    +from solnlib import splunk_rest_client
    +from solnlib.utils import retry
    +
    +
    +@retry(exceptions=[binding.HTTPError])
    +def get_collection_data(
    +    collection_name: str,
    +    session_key: str,
    +    app: str,
    +    owner: Optional[str] = None,
    +    scheme: Optional[str] = None,
    +    host: Optional[str] = None,
    +    port: Optional[Union[str, int]] = None,
    +    fields: Optional[Dict] = None,
    +    **context: Any,
    +) -> client.KVStoreCollectionData:
    +    """Get collection data, if there is no such collection - creates one.
    +
    +    Arguments:
    +        collection_name: Collection name of KV Store checkpointer.
    +        session_key: Splunk access token.
    +        app: App name of namespace.
    +        owner: Owner of namespace, default is `nobody`.
    +        scheme: The access scheme, default is None.
    +        host: The host name, default is None.
    +        port: The port number, default is None.
    +        fields: Fields used to initialize the collection if it's missing.
    +        context: Other configurations for Splunk rest client.
    +
    +    Raises:
    +        binding.HTTPError: HTTP error different from 404, for example 503 when
    +            KV Store is initializing and not ready to serve requests.
    +        KeyError: KV Store did not get collection_name.
    +
    +    Returns:
    +        KV Store collections data instance.
    +    """
    +    kvstore = splunk_rest_client.SplunkRestClient(
    +        session_key, app, owner=owner, scheme=scheme, host=host, port=port, **context
    +    ).kvstore
    +
    +    collection_name = re.sub(r"[^\w]+", "_", collection_name)
    +    try:
    +        kvstore.get(name=collection_name)
    +    except binding.HTTPError as e:
    +        if e.status != 404:
    +            raise
    +
    +        fields = fields if fields is not None else {}
    +        kvstore.create(collection_name, fields=fields)
    +
    +    collections = kvstore.list(search=collection_name)
    +    for collection in collections:
    +        if collection.name == collection_name:
    +            return collection.data
    +    else:
    +        raise KeyError(f"Get collection data: {collection_name} failed.")
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/acl.py b/deployment-apps/metricator-for-nmon/lib/solnlib/acl.py
    new file mode 100644
    index 0000000..6a918ce
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/acl.py
    @@ -0,0 +1,182 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module contains interfaces that support CRUD operations on ACL."""
    +
    +import json
    +from typing import List
    +
    +from splunklib import binding
    +
    +from . import splunk_rest_client as rest_client
    +from .utils import retry
    +
    +__all__ = ["ACLException", "ACLManager"]
    +
    +
    +class ACLException(Exception):
    +    """Exception raised by ACLManager."""
    +
    +    pass
    +
    +
    +class ACLManager:
    +    """ACL manager.
    +
    +    Examples:
    +       >>> import solnlib.acl as sacl
    +       >>> saclm = sacl.ACLManager(session_key, 'Splunk_TA_test')
    +       >>> saclm.get('data/transforms/extractions')
    +       >>> saclm.update('data/transforms/extractions/_acl',
    +                        perms_read=['*'], perms_write=['*'])
    +    """
    +
    +    def __init__(
    +        self,
    +        session_key: str,
    +        app: str,
    +        owner: str = "nobody",
    +        scheme: str = None,
    +        host: str = None,
    +        port: int = None,
    +        **context: dict
    +    ):
    +        """Initializes ACLManager.
    +
    +        Arguments:
    +            session_key: Splunk access token.
    +            app: App name of namespace.
    +            owner: (optional) Owner of namespace, default is `nobody`.
    +            scheme: (optional) The access scheme, default is None.
    +            host: (optional) The host name, default is None.
    +            port: (optional) The port number, default is None.
    +            context: Other configurations for Splunk rest client.
    +        """
    +        self._rest_client = rest_client.SplunkRestClient(
    +            session_key,
    +            app,
    +            owner=owner,
    +            scheme=scheme,
    +            host=host,
    +            port=port,
    +            **context
    +        )
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def get(self, path: str) -> dict:
    +        """Get ACL of  /servicesNS/{`owner`}/{`app`}/{`path`}.
    +
    +        Arguments:
    +            path: Path of ACL relative to /servicesNS/{`owner`}/{`app`}
    +
    +        Returns:
    +            A dict contains ACL.
    +
    +        Raises:
    +            ACLException: If `path` is invalid.
    +
    +        Examples:
    +           >>> aclm = acl.ACLManager(session_key, 'Splunk_TA_test')
    +           >>> perms = aclm.get('data/transforms/extractions/_acl')
    +        """
    +
    +        try:
    +            content = self._rest_client.get(path, output_mode="json").body.read()
    +        except binding.HTTPError as e:
    +            if e.status != 404:
    +                raise
    +
    +            raise ACLException("Invalid endpoint: %s.", path)
    +
    +        return json.loads(content)["entry"][0]["acl"]
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def update(
    +        self,
    +        path: str,
    +        owner: str = None,
    +        perms_read: List = None,
    +        perms_write: List = None,
    +    ) -> dict:
    +        """Update ACL of /servicesNS/{`owner`}/{`app`}/{`path`}.
    +
    +        If the ACL is per-entity (ends in /acl), owner can be reassigned. If
    +        the acl is endpoint-level (ends in _acl), owner will be ignored. The
    +        'sharing' setting is always retrieved from the current.
    +
    +        Arguments:
    +            path: Path of ACL relative to /servicesNS/{owner}/{app}. MUST
    +                end with /acl or /_acl indicating whether the permission is applied
    +                at the per-entity level or endpoint level respectively.
    +            owner: (optional) New owner of ACL, default is `nobody`.
    +            perms_read: (optional) List of roles (['*'] for all roles). If
    +                unspecified we will POST with current (if available) perms.read,
    +                default is None.
    +            perms_write: (optional) List of roles (['*'] for all roles). If
    +                unspecified we will POST with current (if available) perms.write,
    +                default is None.
    +
    +        Returns:
    +            A dict contains ACL after update.
    +
    +        Raises:
    +            ACLException: If `path` is invalid.
    +
    +        Examples:
    +           >>> aclm = acl.ACLManager(session_key, 'Splunk_TA_test')
    +           >>> perms = aclm.update('data/transforms/extractions/_acl',
    +                                   perms_read=['admin'], perms_write=['admin'])
    +        """
    +
    +        if not path.endswith("/acl") and not path.endswith("/_acl"):
    +            raise ACLException(
    +                "Invalid endpoint: %s, must end with /acl or /_acl." % path
    +            )
    +
    +        curr_acl = self.get(path)
    +
    +        postargs = {}
    +        if perms_read:
    +            postargs["perms.read"] = ",".join(perms_read)
    +        else:
    +            curr_read = curr_acl["perms"].get("read", [])
    +            if curr_read:
    +                postargs["perms.read"] = ",".join(curr_read)
    +
    +        if perms_write:
    +            postargs["perms.write"] = ",".join(perms_write)
    +        else:
    +            curr_write = curr_acl["perms"].get("write", [])
    +            if curr_write:
    +                postargs["perms.write"] = ",".join(curr_write)
    +
    +        if path.endswith("/acl"):
    +            # Allow ownership to be reset only at entity level.
    +            postargs["owner"] = owner or curr_acl["owner"]
    +
    +        postargs["sharing"] = curr_acl["sharing"]
    +
    +        try:
    +            content = self._rest_client.post(
    +                path, body=binding._encode(**postargs), output_mode="json"
    +            ).body.read()
    +        except binding.HTTPError as e:
    +            if e.status != 404:
    +                raise
    +
    +            raise ACLException("Invalid endpoint: %s.", path)
    +
    +        return json.loads(content)["entry"][0]["acl"]
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/conf_manager.py b/deployment-apps/metricator-for-nmon/lib/solnlib/conf_manager.py
    new file mode 100644
    index 0000000..3e38337
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/conf_manager.py
    @@ -0,0 +1,557 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module contains simple interfaces for Splunk config file management,
    +you can update/get/delete stanzas and encrypt/decrypt some fields of stanza
    +automatically."""
    +
    +import json
    +import logging
    +import traceback
    +from typing import List
    +
    +from splunklib import binding, client
    +
    +from . import splunk_rest_client as rest_client
    +from .credentials import CredentialManager, CredentialNotExistException
    +from .utils import retry
    +
    +__all__ = [
    +    "ConfStanzaNotExistException",
    +    "ConfFile",
    +    "ConfManagerException",
    +    "ConfManager",
    +]
    +
    +
    +class ConfStanzaNotExistException(Exception):
    +    """Exception raised by ConfFile class."""
    +
    +    pass
    +
    +
    +class ConfFile:
    +    """Configuration file."""
    +
    +    ENCRYPTED_TOKEN = "******"
    +
    +    reserved_keys = ("userName", "appName")
    +
    +    def __init__(
    +        self,
    +        name: str,
    +        conf: client.ConfigurationFile,
    +        session_key: str,
    +        app: str,
    +        owner: str = "nobody",
    +        scheme: str = None,
    +        host: str = None,
    +        port: int = None,
    +        realm: str = None,
    +        **context: dict,
    +    ):
    +        """Initializes ConfFile.
    +
    +        Arguments:
    +            name: Configuration file name.
    +            conf: Configuration file object.
    +            session_key: Splunk access token.
    +            app: App name of namespace.
    +            owner: (optional) Owner of namespace, default is `nobody`.
    +            scheme: (optional) The access scheme, default is None.
    +            host: (optional) The host name, default is None.
    +            port: (optional) The port number, default is None.
    +            realm: (optional) Realm of credential, default is None.
    +            context: Other configurations for Splunk rest client.
    +        """
    +        self._name = name
    +        self._conf = conf
    +        self._session_key = session_key
    +        self._app = app
    +        self._owner = owner
    +        self._scheme = scheme
    +        self._host = host
    +        self._port = port
    +        self._context = context
    +        self._cred_manager = None
    +        # 'realm' is set to provided 'realm' argument otherwise as default
    +        # behaviour it is set to 'APP_NAME'.
    +        if realm is None:
    +            self._realm = self._app
    +        else:
    +            self._realm = realm
    +
    +    @property
    +    @retry(exceptions=[binding.HTTPError])
    +    def _cred_mgr(self):
    +        if self._cred_manager is None:
    +            self._cred_manager = CredentialManager(
    +                self._session_key,
    +                self._app,
    +                owner=self._owner,
    +                realm=self._realm,
    +                scheme=self._scheme,
    +                host=self._host,
    +                port=self._port,
    +                **self._context,
    +            )
    +
    +        return self._cred_manager
    +
    +    def _filter_stanza(self, stanza):
    +        for k in self.reserved_keys:
    +            if k in stanza:
    +                del stanza[k]
    +
    +        return stanza
    +
    +    def _encrypt_stanza(self, stanza_name, stanza, encrypt_keys):
    +        if not encrypt_keys:
    +            return stanza
    +
    +        encrypt_stanza_keys = [k for k in encrypt_keys if k in stanza]
    +        encrypt_fields = {key: stanza[key] for key in encrypt_stanza_keys}
    +        if not encrypt_fields:
    +            return stanza
    +        self._cred_mgr.set_password(stanza_name, json.dumps(encrypt_fields))
    +
    +        for key in encrypt_stanza_keys:
    +            stanza[key] = self.ENCRYPTED_TOKEN
    +
    +        return stanza
    +
    +    def _decrypt_stanza(self, stanza_name, encrypted_stanza):
    +        encrypted_keys = [
    +            key
    +            for key in encrypted_stanza
    +            if encrypted_stanza[key] == self.ENCRYPTED_TOKEN
    +        ]
    +        if encrypted_keys:
    +            encrypted_fields = json.loads(self._cred_mgr.get_password(stanza_name))
    +            for key in encrypted_keys:
    +                encrypted_stanza[key] = encrypted_fields[key]
    +
    +        return encrypted_stanza
    +
    +    def _delete_stanza_creds(self, stanza_name):
    +        self._cred_mgr.delete_password(stanza_name)
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def stanza_exist(self, stanza_name: str) -> bool:
    +        """Check whether stanza exists.
    +
    +        Arguments:
    +            stanza_name: Stanza name.
    +
    +        Returns:
    +            True if stanza exists else False.
    +
    +        Examples:
    +           >>> from solnlib import conf_manager
    +           >>> cfm = conf_manager.ConfManager(session_key,
    +                                              'Splunk_TA_test')
    +           >>> conf = cfm.get_conf('test')
    +           >>> conf.stanza_exist('test_stanza')
    +        """
    +
    +        try:
    +            self._conf.list(name=stanza_name)[0]
    +        except binding.HTTPError as e:
    +            if e.status != 404:
    +                raise
    +
    +            return False
    +
    +        return True
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def get(self, stanza_name: str, only_current_app: bool = False) -> dict:
    +        """Get stanza from configuration file.
    +
    +        Result is like:
    +
    +            {
    +                'disabled': '0',
    +                'eai:appName': 'solnlib_demo',
    +                'eai:userName': 'nobody',
    +                'k1': '1',
    +                'k2': '2'
    +            }
    +
    +        Arguments:
    +            stanza_name: Stanza name.
    +            only_current_app: Only include current app.
    +
    +        Returns:
    +            Stanza.
    +
    +        Raises:
    +            ConfStanzaNotExistException: If stanza does not exist.
    +
    +        Examples:
    +           >>> from solnlib import conf_manager
    +           >>> cfm = conf_manager.ConfManager(session_key,
    +                                              'Splunk_TA_test')
    +           >>> conf = cfm.get_conf('test')
    +           >>> conf.get('test_stanza')
    +        """
    +
    +        try:
    +            if only_current_app:
    +                stanza_mgrs = self._conf.list(
    +                    search="eai:acl.app={} name={}".format(
    +                        self._app, stanza_name.replace("=", r"\=")
    +                    )
    +                )
    +            else:
    +                stanza_mgrs = self._conf.list(name=stanza_name)
    +        except binding.HTTPError as e:
    +            if e.status != 404:
    +                raise
    +
    +            raise ConfStanzaNotExistException(
    +                f"Stanza: {stanza_name} does not exist in {self._name}.conf"
    +            )
    +
    +        if len(stanza_mgrs) == 0:
    +            raise ConfStanzaNotExistException(
    +                f"Stanza: {stanza_name} does not exist in {self._name}.conf"
    +            )
    +
    +        stanza = self._decrypt_stanza(stanza_mgrs[0].name, stanza_mgrs[0].content)
    +        stanza["eai:access"] = stanza_mgrs[0].access
    +        stanza["eai:appName"] = stanza_mgrs[0].access.app
    +        return stanza
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def get_all(self, only_current_app: bool = False) -> dict:
    +        """Get all stanzas from configuration file.
    +
    +        Result is like:
    +
    +            {
    +                'test':
    +                    {
    +                        'disabled': '0',
    +                        'eai:appName': 'solnlib_demo',
    +                        'eai:userName': 'nobody',
    +                        'k1': '1',
    +                        'k2': '2'
    +                    }
    +            }
    +
    +        Arguments:
    +            only_current_app: Only include current app.
    +
    +        Returns:
    +            Dict of stanzas.
    +
    +        Examples:
    +           >>> from solnlib import conf_manager
    +           >>> cfm = conf_manager.ConfManager(session_key,
    +                                              'Splunk_TA_test')
    +           >>> conf = cfm.get_conf('test')
    +           >>> conf.get_all()
    +        """
    +
    +        if only_current_app:
    +            stanza_mgrs = self._conf.list(search=f"eai:acl.app={self._app}")
    +        else:
    +            stanza_mgrs = self._conf.list()
    +        res = {}
    +        for stanza_mgr in stanza_mgrs:
    +            name = stanza_mgr.name
    +            key_values = self._decrypt_stanza(name, stanza_mgr.content)
    +            key_values["eai:access"] = stanza_mgr.access
    +            key_values["eai:appName"] = stanza_mgr.access.app
    +            res[name] = key_values
    +        return res
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def update(self, stanza_name: str, stanza: dict, encrypt_keys: List[str] = None):
    +        """Update stanza.
    +
    +        It will try to encrypt the credential automatically fist if
    +        encrypt_keys are not None else keep stanza untouched.
    +
    +        Arguments:
    +            stanza_name: Stanza name.
    +            stanza: Stanza to update.
    +            encrypt_keys: Field names to encrypt.
    +
    +        Examples:
    +           >>> from solnlib import conf_manager
    +           >>> cfm = conf_manager.ConfManager(session_key,
    +                                              'Splunk_TA_test')
    +           >>> conf = cfm.get_conf('test')
    +           >>> conf.update('test_stanza', {'k1': 1, 'k2': 2}, ['k1'])
    +        """
    +
    +        stanza = self._filter_stanza(stanza)
    +        encrypted_stanza = self._encrypt_stanza(stanza_name, stanza, encrypt_keys)
    +
    +        try:
    +            stanza_mgr = self._conf.list(name=stanza_name)[0]
    +        except binding.HTTPError as e:
    +            if e.status != 404:
    +                raise
    +
    +            stanza_mgr = self._conf.create(stanza_name)
    +
    +        stanza_mgr.submit(encrypted_stanza)
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def delete(self, stanza_name: str):
    +        """Delete stanza.
    +
    +        Arguments:
    +            stanza_name: Stanza name to delete.
    +
    +        Raises:
    +            ConfStanzaNotExistException: If stanza does not exist.
    +
    +        Examples:
    +           >>> from solnlib import conf_manager
    +           >>> cfm = conf_manager.ConfManager(session_key,
    +                                              'Splunk_TA_test')
    +           >>> conf = cfm.get_conf('test')
    +           >>> conf.delete('test_stanza')
    +        """
    +
    +        try:
    +            self._cred_mgr.delete_password(stanza_name)
    +        except CredentialNotExistException:
    +            pass
    +
    +        try:
    +            self._conf.delete(stanza_name)
    +        except KeyError:
    +            logging.error(
    +                "Delete stanza: %s error: %s.", stanza_name, traceback.format_exc()
    +            )
    +            raise ConfStanzaNotExistException(
    +                f"Stanza: {stanza_name} does not exist in {self._name}.conf"
    +            )
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def reload(self):
    +        """Reload configuration file.
    +
    +        Examples:
    +           >>> from solnlib import conf_manager
    +           >>> cfm = conf_manager.ConfManager(session_key,
    +                                              'Splunk_TA_test')
    +           >>> conf = cfm.get_conf('test')
    +           >>> conf.reload()
    +        """
    +
    +        self._conf.get("_reload")
    +
    +
    +class ConfManagerException(Exception):
    +    """Exception raised by ConfManager class."""
    +
    +    pass
    +
    +
    +class ConfManager:
    +    """Configuration file manager.
    +
    +    Examples:
    +
    +        >>> from solnlib import conf_manager
    +        >>> cfm = conf_manager.ConfManager(session_key,
    +                                          'Splunk_TA_test')
    +
    +    Examples:
    +        If stanza in passwords.conf is formatted as below:
    +
    +        `credential:__REST_CREDENTIAL__#Splunk_TA_test#configs/conf-CONF_FILENAME:STANZA_NAME``splunk_cred_sep``1:`
    +
    +        >>> from solnlib import conf_manager
    +        >>> cfm = conf_manager.ConfManager(
    +                session_key,
    +                'Splunk_TA_test',
    +                realm='__REST_CREDENTIAL__#Splunk_TA_test#configs/conf-CONF_FILENAME'
    +            )
    +    """
    +
    +    def __init__(
    +        self,
    +        session_key: str,
    +        app: str,
    +        owner: str = "nobody",
    +        scheme: str = None,
    +        host: str = None,
    +        port: int = None,
    +        realm: str = None,
    +        **context: dict,
    +    ):
    +        """Initializes ConfManager.
    +
    +        Arguments:
    +            session_key: Splunk access token.
    +            app: App name of namespace.
    +            owner: (optional) Owner of namespace, default is `nobody`.
    +            scheme: (optional) The access scheme, default is None.
    +            host: (optional) The host name, default is None.
    +            port: (optional) The port number, default is None.
    +            realm: (optional) Realm of credential, default is None.
    +            context: Other configurations for Splunk rest client.
    +        """
    +        self._session_key = session_key
    +        self._app = app
    +        self._owner = owner
    +        self._scheme = scheme
    +        self._host = host
    +        self._port = port
    +        self._context = context
    +        self._rest_client = rest_client.SplunkRestClient(
    +            self._session_key,
    +            self._app,
    +            owner=self._owner,
    +            scheme=self._scheme,
    +            host=self._host,
    +            port=self._port,
    +            **self._context,
    +        )
    +        self._confs = None
    +        self._realm = realm
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def get_conf(self, name: str, refresh: bool = False) -> ConfFile:
    +        """Get conf file.
    +
    +        Arguments:
    +            name: Conf file name.
    +            refresh: (optional) Flag to refresh conf file list, default is False.
    +
    +        Returns:
    +            Conf file object.
    +
    +        Raises:
    +            ConfManagerException: If `conf_file` does not exist.
    +        """
    +
    +        if self._confs is None or refresh:
    +            # Fix bug that can't pass `-` as app name.
    +            curr_app = self._rest_client.namespace.app
    +            self._rest_client.namespace.app = "dummy"
    +            self._confs = self._rest_client.confs
    +            self._rest_client.namespace.app = curr_app
    +
    +        try:
    +            conf = self._confs[name]
    +        except KeyError:
    +            raise ConfManagerException(f"Config file: {name} does not exist.")
    +
    +        return ConfFile(
    +            name,
    +            conf,
    +            self._session_key,
    +            self._app,
    +            self._owner,
    +            self._scheme,
    +            self._host,
    +            self._port,
    +            self._realm,
    +            **self._context,
    +        )
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def create_conf(self, name: str) -> ConfFile:
    +        """Create conf file.
    +
    +        Arguments:
    +            name: Conf file name.
    +
    +        Returns:
    +            Conf file object.
    +        """
    +
    +        if self._confs is None:
    +            self._confs = self._rest_client.confs
    +
    +        conf = self._confs.create(name)
    +        return ConfFile(
    +            name,
    +            conf,
    +            self._session_key,
    +            self._app,
    +            self._owner,
    +            self._scheme,
    +            self._host,
    +            self._port,
    +            self._realm,
    +            **self._context,
    +        )
    +
    +
    +def get_log_level(
    +    *,
    +    logger: logging.Logger,
    +    session_key: str,
    +    app_name: str,
    +    conf_name: str,
    +    log_level_field: str = "loglevel",
    +    default_log_level: str = "INFO",
    +) -> str:
    +    """This function returns the log level for the addon from configuration
    +    file.
    +
    +    Arguments:
    +        logger: Logger.
    +        session_key: Splunk access token.
    +        app_name: Add-on name.
    +        conf_name: Configuration file name where logging stanza is.
    +        log_level_field: Logging level field name under logging stanza.
    +        default_log_level: Default log level to return in case of errors.
    +
    +    Returns:
    +        Log level defined under `logging.log_level_field` field in `conf_name`
    +        file. In case of any error, `default_log_level` will be returned.
    +
    +    Examples:
    +        >>> from solnlib import conf_manager
    +        >>> log_level = conf_manager.get_log_level(
    +        >>>     logger,
    +        >>>     "session_key",
    +        >>>     "ADDON_NAME",
    +        >>>     "splunk_ta_addon_settings",
    +        >>> )
    +    """
    +    try:
    +        cfm = ConfManager(
    +            session_key,
    +            app_name,
    +            realm=f"__REST_CREDENTIAL__#{app_name}#configs/conf-{conf_name}",
    +        )
    +        conf = cfm.get_conf(conf_name)
    +    except ConfManagerException:
    +        logger.error(
    +            f"Failed to fetch configuration file {conf_name}, "
    +            f"taking {default_log_level} as log level."
    +        )
    +        return default_log_level
    +    try:
    +        logging_details = conf.get("logging")
    +        return logging_details.get(log_level_field, default_log_level)
    +    except ConfStanzaNotExistException:
    +        logger.error(
    +            f'"logging" stanza does not exist under {conf_name}, '
    +            f"taking {default_log_level} as log level."
    +        )
    +        return default_log_level
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/credentials.py b/deployment-apps/metricator-for-nmon/lib/solnlib/credentials.py
    new file mode 100644
    index 0000000..53f0237
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/credentials.py
    @@ -0,0 +1,394 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module contains Splunk credential related interfaces."""
    +
    +import json
    +import re
    +import warnings
    +from typing import Dict, List
    +
    +from splunklib import binding, client
    +
    +from . import splunk_rest_client as rest_client
    +from .net_utils import validate_scheme_host_port
    +from .splunkenv import get_splunkd_access_info
    +from .utils import retry
    +
    +__all__ = [
    +    "CredentialException",
    +    "CredentialNotExistException",
    +    "CredentialManager",
    +    "get_session_key",
    +]
    +
    +
    +class CredentialException(Exception):
    +    """General exception regarding credentials."""
    +
    +    pass
    +
    +
    +class CredentialNotExistException(Exception):
    +    """Exception is raised when credentials do not exist."""
    +
    +    pass
    +
    +
    +class CredentialManager:
    +    """Credential manager.
    +
    +    Examples:
    +       >>> from solnlib import credentials
    +       >>> cm = credentials.CredentialManager(session_key,
    +                                              'Splunk_TA_test',
    +                                              realm='realm_test')
    +    """
    +
    +    # Splunk can only encrypt string with length <=255
    +    SPLUNK_CRED_LEN_LIMIT = 255
    +
    +    # Splunk credential separator
    +    SEP = "``splunk_cred_sep``"
    +
    +    # Splunk credential end mark
    +    END_MARK = (
    +        "``splunk_cred_sep``S``splunk_cred_sep``P``splunk_cred_sep``L``splunk_cred_sep``"
    +        "U``splunk_cred_sep``N``splunk_cred_sep``K``splunk_cred_sep``"
    +    )
    +
    +    def __init__(
    +        self,
    +        session_key: str,
    +        app: str,
    +        owner: str = "nobody",
    +        realm: str = None,
    +        scheme: str = None,
    +        host: str = None,
    +        port: int = None,
    +        **context: dict,
    +    ):
    +        """Initializes CredentialManager.
    +
    +        Arguments:
    +            session_key: Splunk access token.
    +            app: App name of namespace.
    +            owner: (optional) Owner of namespace, default is `nobody`.
    +            realm: (optional) Realm of credential, default is None.
    +            scheme: (optional) The access scheme, default is None.
    +            host: (optional) The host name, default is None.
    +            port: (optional) The port number, default is None.
    +            context: Other configurations for Splunk rest client.
    +        """
    +        self._realm = realm
    +        self.service = rest_client.SplunkRestClient(
    +            session_key,
    +            app,
    +            owner=owner,
    +            scheme=scheme,
    +            host=host,
    +            port=port,
    +            **context,
    +        )
    +        self._storage_passwords = self.service.storage_passwords
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def get_password(self, user: str) -> str:
    +        """Get password.
    +
    +        Arguments:
    +            user: User name.
    +
    +        Returns:
    +            Clear user password.
    +
    +        Raises:
    +            CredentialNotExistException: If password for 'realm:user' doesn't exist.
    +
    +        Examples:
    +           >>> from solnlib import credentials
    +           >>> cm = credentials.CredentialManager(session_key,
    +                                                  'Splunk_TA_test',
    +                                                  realm='realm_test')
    +           >>> cm.get_password('testuser2')
    +        """
    +        if self._realm is not None:
    +            passwords = self.get_clear_passwords_in_realm()
    +        else:
    +            passwords = self.get_clear_passwords()
    +        for password in passwords:
    +            if password["username"] == user and password["realm"] == self._realm:
    +                return password["clear_password"]
    +
    +        raise CredentialNotExistException(
    +            f"Failed to get password of realm={self._realm}, user={user}."
    +        )
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def set_password(self, user: str, password: str):
    +        """Set password.
    +
    +        Arguments:
    +            user: User name.
    +            password: User password.
    +
    +        Examples:
    +           >>> from solnlib import credentials
    +           >>> cm = credentials.CredentialManager(session_key,
    +                                                  'Splunk_TA_test',
    +                                                  realm='realm_test')
    +           >>> cm.set_password('testuser1', 'password1')
    +        """
    +        length = 0
    +        index = 1
    +        while length < len(password):
    +            curr_str = password[
    +                length : length + self.SPLUNK_CRED_LEN_LIMIT  # noqa: E203
    +            ]
    +            partial_user = self.SEP.join([user, str(index)])
    +            self._update_password(partial_user, curr_str)
    +            length += self.SPLUNK_CRED_LEN_LIMIT
    +            index += 1
    +
    +        # Append another stanza to mark the end of the password
    +        partial_user = self.SEP.join([user, str(index)])
    +        self._update_password(partial_user, self.END_MARK)
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def _update_password(self, user: str, password: str):
    +        """Update password.
    +
    +        Arguments:
    +            user: User name.
    +            password: User password.
    +
    +        Examples:
    +           >>> from solnlib import credentials
    +           >>> cm = credentials.CredentialManager(session_key,
    +                                                  'Splunk_TA_test',
    +                                                  realm='realm_test')
    +           >>> cm._update_password('testuser1', 'password1')
    +        """
    +        try:
    +            self._storage_passwords.create(password, user, self._realm)
    +        except binding.HTTPError as ex:
    +            if ex.status == 409:
    +                if self._realm is not None:
    +                    passwords = self.get_raw_passwords_in_realm()
    +                else:
    +                    passwords = self.get_raw_passwords()
    +                for pwd_stanza in passwords:
    +                    if pwd_stanza.realm == self._realm and pwd_stanza.username == user:
    +                        pwd_stanza.update(password=password)
    +                        return
    +                raise ValueError(
    +                    f"Can not get the password object for realm: {self._realm} user: {user}"
    +                )
    +            else:
    +                raise ex
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def delete_password(self, user: str):
    +        """Delete password.
    +
    +        Arguments:
    +            user: User name.
    +
    +        Raises:
    +             CredentialNotExistException: If password of realm:user doesn't exist.
    +
    +        Examples:
    +           >>> from solnlib import credentials
    +           >>> cm = credentials.CredentialManager(session_key,
    +                                                  'Splunk_TA_test',
    +                                                  realm='realm_test')
    +           >>> cm.delete_password('testuser1')
    +        """
    +        if self._realm is not None:
    +            passwords = self.get_raw_passwords_in_realm()
    +        else:
    +            passwords = self.get_raw_passwords()
    +        deleted = False
    +        ent_pattern = re.compile(
    +            r"({}{}\d+)".format(user.replace("\\", "\\\\"), self.SEP)
    +        )
    +        for password in passwords:
    +            match = (user == password.username) or ent_pattern.match(password.username)
    +            if match and password.realm == self._realm:
    +                password.delete()
    +                deleted = True
    +
    +        if not deleted:
    +            raise CredentialNotExistException(
    +                f"Failed to delete password of realm={self._realm}, user={user}"
    +            )
    +
    +    def get_raw_passwords(self) -> List[client.StoragePassword]:
    +        """Returns all passwords in the "raw" format."""
    +        warnings.warn(
    +            "Please pass realm to the CredentialManager, "
    +            "so it can utilize get_raw_passwords_in_realm method instead."
    +        )
    +        return self._storage_passwords.list(count=-1)
    +
    +    def get_raw_passwords_in_realm(self) -> List[client.StoragePassword]:
    +        """Returns all passwords within the realm in the "raw" format."""
    +        if self._realm is None:
    +            raise ValueError("No realm was specified")
    +        return self._storage_passwords.list(count=-1, search=f"realm={self._realm}")
    +
    +    def get_clear_passwords(self) -> List[Dict[str, str]]:
    +        """Returns all passwords in the "clear" format."""
    +        warnings.warn(
    +            "Please pass realm to the CredentialManager, "
    +            "so it can utilize get_clear_passwords_in_realm method instead."
    +        )
    +        raw_passwords = self.get_raw_passwords()
    +        return self._get_clear_passwords(raw_passwords)
    +
    +    def get_clear_passwords_in_realm(self) -> List[Dict[str, str]]:
    +        """Returns all passwords within the realm in the "clear" format."""
    +        if self._realm is None:
    +            raise ValueError("No realm was specified")
    +        raw_passwords = self.get_raw_passwords_in_realm()
    +        return self._get_clear_passwords(raw_passwords)
    +
    +    def _get_all_passwords_in_realm(self) -> List[client.StoragePassword]:
    +        warnings.warn(
    +            "_get_all_passwords_in_realm is deprecated, "
    +            "please use get_raw_passwords_in_realm instead.",
    +            stacklevel=2,
    +        )
    +        if self._realm:
    +            all_passwords = self._storage_passwords.list(
    +                count=-1, search=f"realm={self._realm}"
    +            )
    +        else:
    +            all_passwords = self._storage_passwords.list(count=-1, search="")
    +        return all_passwords
    +
    +    def _get_clear_passwords(
    +        self, passwords: List[client.StoragePassword]
    +    ) -> List[Dict[str, str]]:
    +        results = {}
    +        ptn = re.compile(rf"(.+){self.SEP}(\d+)")
    +        for password in passwords:
    +            match = ptn.match(password.name)
    +            if match:
    +                actual_name = match.group(1) + ":"
    +                index = int(match.group(2))
    +                if actual_name in results:
    +                    exist_stanza = results[actual_name]
    +                else:
    +                    exist_stanza = {}
    +                    exist_stanza["name"] = actual_name
    +                    exist_stanza["realm"] = password.realm
    +                    exist_stanza["username"] = password.username.split(self.SEP)[0]
    +                    exist_stanza["clears"] = {}
    +                    results[actual_name] = exist_stanza
    +
    +                exist_stanza["clears"][index] = password.clear_password
    +
    +        # Backward compatibility
    +        # To deal with the password with only one stanza which is generated by the old version.
    +        for password in passwords:
    +            match = ptn.match(password.name)
    +            if (not match) and (password.name not in results):
    +                results[password.name] = {
    +                    "name": password.name,
    +                    "realm": password.realm,
    +                    "username": password.username,
    +                    "clear_password": password.clear_password,
    +                }
    +
    +        # Merge password by index
    +        for name, values in list(results.items()):
    +            field_clear = values.get("clears")
    +            if field_clear:
    +                clear_password = ""
    +                for index in sorted(field_clear.keys()):
    +                    if field_clear[index] != self.END_MARK:
    +                        clear_password += field_clear[index]
    +                    else:
    +                        break
    +                values["clear_password"] = clear_password
    +
    +                del values["clears"]
    +
    +        return list(results.values())
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def _get_all_passwords(self) -> List[Dict[str, str]]:
    +        warnings.warn(
    +            "_get_all_passwords is deprecated, "
    +            "please use get_all_passwords_in_realm instead.",
    +            stacklevel=2,
    +        )
    +        passwords = self._storage_passwords.list(count=-1)
    +        return self._get_clear_passwords(passwords)
    +
    +
    +@retry(exceptions=[binding.HTTPError])
    +def get_session_key(
    +    username: str,
    +    password: str,
    +    scheme: str = None,
    +    host: str = None,
    +    port: int = None,
    +    **context: dict,
    +) -> str:
    +    """Get splunkd access token.
    +
    +    Arguments:
    +        username: The Splunk account username, which is used to authenticate the Splunk instance.
    +        password: The Splunk account password.
    +        scheme: (optional) The access scheme, default is None.
    +        host: (optional) The host name, default is None.
    +        port: (optional) The port number, default is None.
    +        context: Other configurations for Splunk rest client.
    +
    +    Returns:
    +        Splunk session key.
    +
    +    Raises:
    +        CredentialException: If username/password are invalid.
    +        ValueError: if scheme, host or port are invalid.
    +
    +    Examples:
    +       >>> get_session_key('user', 'password')
    +    """
    +    validate_scheme_host_port(scheme, host, port)
    +
    +    if any([scheme is None, host is None, port is None]):
    +        scheme, host, port = get_splunkd_access_info()
    +
    +    uri = "{scheme}://{host}:{port}/{endpoint}".format(
    +        scheme=scheme, host=host, port=port, endpoint="services/auth/login"
    +    )
    +    _rest_client = rest_client.SplunkRestClient(
    +        None, "-", "nobody", scheme, host, port, **context
    +    )
    +    try:
    +        response = _rest_client.http.post(
    +            uri, username=username, password=password, output_mode="json"
    +        )
    +    except binding.HTTPError as e:
    +        if e.status != 401:
    +            raise
    +
    +        raise CredentialException("Invalid username/password.")
    +
    +    return json.loads(response.body.read())["sessionKey"]
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/file_monitor.py b/deployment-apps/metricator-for-nmon/lib/solnlib/file_monitor.py
    new file mode 100644
    index 0000000..65fd655
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/file_monitor.py
    @@ -0,0 +1,133 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module contains file monitoring class that can be used to check files
    +change periodically and call callback function to handle properly when
    +detecting files change."""
    +import logging
    +import os.path as op
    +import threading
    +import time
    +import traceback
    +from typing import Any, Callable, List
    +
    +__all__ = ["FileChangesChecker", "FileMonitor"]
    +
    +
    +class FileChangesChecker:
    +    """Files change checker."""
    +
    +    def __init__(self, callback: Callable[[List[str]], Any], files: List):
    +        """Initializes FileChangesChecker.
    +
    +        Arguments:
    +            callback: Callback function for files change.
    +            files: Files to be monitored with full path.
    +        """
    +        self._callback = callback
    +        self._files = files
    +
    +        self.file_mtimes = {file_name: None for file_name in self._files}
    +        for k in self.file_mtimes:
    +            try:
    +                self.file_mtimes[k] = op.getmtime(k)
    +            except OSError:
    +                logging.debug(f"Getmtime for {k}, failed: {traceback.format_exc()}")
    +
    +    def check_changes(self) -> bool:
    +        """Check files change.
    +
    +        If some files are changed and callback function is not None, call
    +        callback function to handle files change.
    +
    +        Returns:
    +            True if files changed else False
    +        """
    +        logging.debug(f"Checking files={self._files}")
    +        file_mtimes = self.file_mtimes
    +        changed_files = []
    +        for f, last_mtime in list(file_mtimes.items()):
    +            try:
    +                current_mtime = op.getmtime(f)
    +                if current_mtime != last_mtime:
    +                    file_mtimes[f] = current_mtime
    +                    changed_files.append(f)
    +                    logging.info(f"Detect {f} has changed", f)
    +            except OSError:
    +                pass
    +        if changed_files:
    +            if self._callback:
    +                self._callback(changed_files)
    +            return True
    +        return False
    +
    +
    +class FileMonitor:
    +    """Files change monitor.
    +
    +    Monitor files change in a separated thread and call callback
    +    when there is files change.
    +
    +    Examples:
    +      >>> import solnlib.file_monitor as fm
    +      >>> fm = fm.FileMonitor(fm_callback, files_list, 5)
    +      >>> fm.start()
    +    """
    +
    +    def __init__(
    +        self, callback: Callable[[List[str]], Any], files: List, interval: int = 1
    +    ):
    +        """Initializes FileMonitor.
    +
    +        Arguments:
    +            callback: Callback for handling files change.
    +            files: Files to monitor.
    +            interval: Interval to check files change.
    +        """
    +        self._checker = FileChangesChecker(callback, files)
    +        self._thr = threading.Thread(target=self._do_monitor)
    +        self._thr.daemon = True
    +        self._interval = interval
    +        self._started = False
    +
    +    def start(self):
    +        """Start file monitor.
    +
    +        Start a background thread to monitor files change.
    +        """
    +
    +        if self._started:
    +            return
    +        self._started = True
    +
    +        self._thr.start()
    +
    +    def stop(self):
    +        """Stop file monitor.
    +
    +        Stop the background thread to monitor files change.
    +        """
    +
    +        self._started = False
    +
    +    def _do_monitor(self):
    +        while self._started:
    +            self._checker.check_changes()
    +
    +            for _ in range(self._interval):
    +                if not self._started:
    +                    break
    +                time.sleep(1)
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/hec_config.py b/deployment-apps/metricator-for-nmon/lib/solnlib/hec_config.py
    new file mode 100644
    index 0000000..42cb7e5
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/hec_config.py
    @@ -0,0 +1,182 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +from splunklib import binding
    +
    +from . import splunk_rest_client as rest_client
    +from .utils import retry
    +
    +__all__ = ["HECConfig"]
    +
    +
    +class HECConfig:
    +    """HTTP Event Collector configuration."""
    +
    +    input_type = "http"
    +
    +    def __init__(
    +        self,
    +        session_key: str,
    +        scheme: str = None,
    +        host: str = None,
    +        port: int = None,
    +        **context: dict
    +    ):
    +        """Initializes HECConfig.
    +
    +        Arguments:
    +            session_key: Splunk access token.
    +            scheme: (optional) The access scheme, default is None.
    +            host: (optional) The host name, default is None.
    +            port: (optional) The port number, default is None.
    +            context: Other configurations for Splunk rest client.
    +        """
    +        self._rest_client = rest_client.SplunkRestClient(
    +            session_key,
    +            "splunk_httpinput",
    +            scheme=scheme,
    +            host=host,
    +            port=port,
    +            **context
    +        )
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def get_settings(self) -> dict:
    +        """Get http data input global settings.
    +
    +        Returns:
    +            HTTP global settings, for example:
    +
    +                {
    +                    'enableSSL': 1,
    +                    'disabled': 0,
    +                    'useDeploymentServer': 0,
    +                    'port': 8088
    +                }
    +        """
    +
    +        return self._do_get_input(self.input_type).content
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def update_settings(self, settings: dict):
    +        """Update http data input global settings.
    +
    +        Arguments:
    +            settings: HTTP global settings.
    +        """
    +
    +        res = self._do_get_input(self.input_type)
    +        res.update(**settings)
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def create_input(self, name: str, stanza: dict) -> dict:
    +        """Create http data input.
    +
    +        Arguments:
    +            name: HTTP data input name.
    +            stanza: Data input stanza content.
    +
    +        Returns:
    +            Created input.
    +
    +        Examples:
    +           >>> from solnlib.hec_config import HECConfig
    +           >>> hec = HECConfig(session_key)
    +           >>> hec.create_input('my_hec_data_input',
    +                                {'index': 'main', 'sourcetype': 'hec'})
    +        """
    +
    +        res = self._rest_client.inputs.create(name, self.input_type, **stanza)
    +        return res.content
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def update_input(self, name: str, stanza: dict):
    +        """Update http data input.
    +
    +        It will create if the data input doesn't exist.
    +
    +        Arguments:
    +            name: HTTP data input name.
    +            stanza: Data input stanza.
    +
    +        Examples:
    +           >>> from solnlib import HEConfig
    +           >>> hec = HECConfig(session_key)
    +           >>> hec.update_input('my_hec_data_input',
    +                                {'index': 'main', 'sourcetype': 'hec2'})
    +        """
    +
    +        res = self._do_get_input(name)
    +        if res is None:
    +            return self.create_input(name, stanza)
    +        res.update(**stanza)
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def delete_input(self, name: str):
    +        """Delete http data input.
    +
    +        Arguments:
    +            name: HTTP data input name.
    +        """
    +
    +        try:
    +            self._rest_client.inputs.delete(name, self.input_type)
    +        except KeyError:
    +            pass
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def get_input(self, name: str) -> dict:
    +        """Get http data input.
    +
    +        Arguments:
    +            name: HTTP event collector data input name.
    +
    +        Returns:
    +            HTTP event collector data input config dict.
    +        """
    +
    +        res = self._do_get_input(name)
    +        if res:
    +            return res.content
    +        else:
    +            return None
    +
    +    def _do_get_input(self, name):
    +        try:
    +            return self._rest_client.inputs[(name, self.input_type)]
    +        except KeyError:
    +            return None
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def get_limits(self) -> dict:
    +        """Get HTTP input limits.
    +
    +        Returns:
    +            HTTP input limits.
    +        """
    +
    +        return self._rest_client.confs["limits"]["http_input"].content
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def set_limits(self, limits: dict):
    +        """Set HTTP input limits.
    +
    +        Arguments:
    +            limits: HTTP input limits.
    +        """
    +
    +        res = self._rest_client.confs["limits"]["http_input"]
    +        res.submit(limits)
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/log.py b/deployment-apps/metricator-for-nmon/lib/solnlib/log.py
    new file mode 100644
    index 0000000..5ad17b6
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/log.py
    @@ -0,0 +1,219 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module provides log functionalities."""
    +
    +import logging
    +import logging.handlers
    +import os.path as op
    +from threading import Lock
    +
    +from .pattern import Singleton
    +from .splunkenv import make_splunkhome_path
    +
    +__all__ = ["log_enter_exit", "LogException", "Logs"]
    +
    +
    +def log_enter_exit(logger: logging.Logger):
    +    """Decorator for logger to log function enter and exit.
    +
    +    This decorator will generate a lot of debug log, please add this
    +    only when it is required.
    +
    +    Arguments:
    +        logger: Logger to decorate.
    +
    +    Examples:
    +        >>> @log_enter_exit
    +        >>> def myfunc():
    +        >>>     doSomething()
    +    """
    +
    +    def log_decorator(func):
    +        def wrapper(*args, **kwargs):
    +            logger.debug("%s entered", func.__name__)
    +            result = func(*args, **kwargs)
    +            logger.debug("%s exited", func.__name__)
    +            return result
    +
    +        return wrapper
    +
    +    return log_decorator
    +
    +
    +class LogException(Exception):
    +    """Exception raised by Logs class."""
    +
    +    pass
    +
    +
    +class Logs(metaclass=Singleton):
    +    """A singleton class that manage all kinds of logger.
    +
    +    Examples:
    +      >>> from solnlib.import log
    +      >>> log.Logs.set_context(directory='/var/log/test',
    +                               namespace='test')
    +      >>> logger = log.Logs().get_logger('mymodule')
    +      >>> logger.set_level(logging.DEBUG)
    +      >>> logger.debug('a debug log')
    +    """
    +
    +    # Normal logger settings
    +    _default_directory = None
    +    _default_namespace = None
    +    _default_log_format = (
    +        "%(asctime)s %(levelname)s pid=%(process)d tid=%(threadName)s "
    +        "file=%(filename)s:%(funcName)s:%(lineno)d | %(message)s"
    +    )
    +    _default_log_level = logging.INFO
    +    _default_max_bytes = 25000000
    +    _default_backup_count = 5
    +
    +    # Default root logger settings
    +    _default_root_logger_log_file = "solnlib"
    +
    +    @classmethod
    +    def set_context(cls, **context: dict):
    +        """Set log context.
    +
    +        List of keyword arguments:
    +
    +            directory: Log directory, default is splunk log root directory.
    +            namespace: Logger namespace, default is None.
    +            log_format: Log format, default is `_default_log_format`.
    +            log_level: Log level, default is logging.INFO.
    +            max_bytes: The maximum log file size before rollover, default is 25000000.
    +            backup_count: The number of log files to retain,default is 5.
    +            root_logger_log_file: Root logger log file name, default is 'solnlib'   .
    +
    +        Arguments:
    +            context: Keyword arguments. See list of arguments above.
    +        """
    +        if "directory" in context:
    +            cls._default_directory = context["directory"]
    +        if "namespace" in context:
    +            cls._default_namespace = context["namespace"]
    +        if "log_format" in context:
    +            cls._default_log_format = context["log_format"]
    +        if "log_level" in context:
    +            cls._default_log_level = context["log_level"]
    +        if "max_bytes" in context:
    +            cls._default_max_bytes = context["max_bytes"]
    +        if "backup_count" in context:
    +            cls._default_backup_count = context["backup_count"]
    +        if "root_logger_log_file" in context:
    +            cls._default_root_logger_log_file = context["root_logger_log_file"]
    +            cls._reset_root_logger()
    +
    +    @classmethod
    +    def _reset_root_logger(cls):
    +        logger = logging.getLogger()
    +        log_file = cls._get_log_file(cls._default_root_logger_log_file)
    +        file_handler = logging.handlers.RotatingFileHandler(
    +            log_file,
    +            mode="a",
    +            maxBytes=cls._default_max_bytes,
    +            backupCount=cls._default_backup_count,
    +        )
    +        file_handler.setFormatter(logging.Formatter(cls._default_log_format))
    +        logger.addHandler(file_handler)
    +        logger.setLevel(cls._default_log_level)
    +
    +    @classmethod
    +    def _get_log_file(cls, name):
    +        if cls._default_namespace:
    +            name = f"{cls._default_namespace}_{name}.log"
    +        else:
    +            name = f"{name}.log"
    +
    +        if cls._default_directory:
    +            directory = cls._default_directory
    +        else:
    +            try:
    +                directory = make_splunkhome_path(["var", "log", "splunk"])
    +            except KeyError:
    +                raise LogException(
    +                    "Log directory is empty, please set log directory "
    +                    'by calling Logs.set_context(directory="/var/log/...").'
    +                )
    +        log_file = op.sep.join([directory, name])
    +
    +        return log_file
    +
    +    def __init__(self):
    +        self._lock = Lock()
    +        self._loggers = {}
    +
    +    def get_logger(self, name: str) -> logging.Logger:
    +        """Get logger with the name of `name`.
    +
    +        If logger with the name of `name` exists just return else create a new
    +        logger with the name of `name`.
    +
    +        Arguments:
    +            name: Logger name, it will be used as log file name too.
    +
    +        Returns:
    +            A named logger.
    +        """
    +
    +        with self._lock:
    +            log_file = self._get_log_file(name)
    +            if log_file in self._loggers:
    +                return self._loggers[log_file]
    +
    +            logger = logging.getLogger(log_file)
    +            handler_exists = any(
    +                [True for h in logger.handlers if h.baseFilename == log_file]
    +            )
    +            if not handler_exists:
    +                file_handler = logging.handlers.RotatingFileHandler(
    +                    log_file,
    +                    mode="a",
    +                    maxBytes=self._default_max_bytes,
    +                    backupCount=self._default_backup_count,
    +                )
    +                file_handler.setFormatter(logging.Formatter(self._default_log_format))
    +                logger.addHandler(file_handler)
    +                logger.setLevel(self._default_log_level)
    +                logger.propagate = False
    +
    +            self._loggers[log_file] = logger
    +            return logger
    +
    +    def set_level(self, level: int, name: str = None):
    +        """Set log level of logger.
    +
    +        Set log level of all logger if `name` is None else of
    +        logger with the name of `name`.
    +
    +        Arguments:
    +            level: Log level to set.
    +            name: The name of logger, default is None.
    +        """
    +
    +        with self._lock:
    +            if name:
    +                log_file = self._get_log_file(name)
    +                logger = self._loggers.get(log_file)
    +                if logger:
    +                    logger.setLevel(level)
    +            else:
    +                self._default_log_level = level
    +                for logger in list(self._loggers.values()):
    +                    logger.setLevel(level)
    +                logging.getLogger().setLevel(level)
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/__init__.py b/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/__init__.py
    new file mode 100644
    index 0000000..73684b2
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/__init__.py
    @@ -0,0 +1,38 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""Splunk modular input."""
    +
    +from splunklib.modularinput.argument import Argument
    +
    +from .checkpointer import CheckpointerException, FileCheckpointer, KVStoreCheckpointer
    +from .event import EventException, HECEvent, XMLEvent
    +from .event_writer import ClassicEventWriter, HECEventWriter
    +from .modular_input import ModularInput, ModularInputException
    +
    +__all__ = [
    +    "EventException",
    +    "XMLEvent",
    +    "HECEvent",
    +    "ClassicEventWriter",
    +    "HECEventWriter",
    +    "CheckpointerException",
    +    "KVStoreCheckpointer",
    +    "FileCheckpointer",
    +    "Argument",
    +    "ModularInputException",
    +    "ModularInput",
    +]
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/checkpointer.py b/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/checkpointer.py
    new file mode 100644
    index 0000000..2a6c80d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/checkpointer.py
    @@ -0,0 +1,263 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module provides two kinds of checkpointer: KVStoreCheckpointer,
    +FileCheckpointer for modular input to save checkpoint."""
    +
    +import base64
    +import json
    +import logging
    +import os
    +import os.path as op
    +import traceback
    +import warnings
    +from abc import ABCMeta, abstractmethod
    +from typing import Any, Dict, Iterable, Optional
    +
    +from splunklib import binding
    +
    +from solnlib import _utils, utils
    +
    +__all__ = ["CheckpointerException", "KVStoreCheckpointer", "FileCheckpointer"]
    +
    +
    +class CheckpointerException(Exception):
    +    pass
    +
    +
    +class Checkpointer(metaclass=ABCMeta):
    +    """Base class of checkpointer."""
    +
    +    @abstractmethod
    +    def update(self, key: str, state: Any):
    +        """Updates document with an id that equals to `key` and `state` as
    +        document data."""
    +
    +    @abstractmethod
    +    def batch_update(self, states: Iterable[Dict[str, Any]]):
    +        """Updates multiple documents."""
    +
    +    @abstractmethod
    +    def get(self, key: str) -> dict:
    +        """Gets document with an id that equals to `key`."""
    +
    +    @abstractmethod
    +    def delete(self, key: str):
    +        """Deletes document with an id that equals to `key`."""
    +
    +
    +class KVStoreCheckpointer(Checkpointer):
    +    """KVStore checkpointer.
    +
    +    Use KVStore to save modular input checkpoint.
    +
    +    More information about KV Store in Splunk is
    +    [here](https://dev.splunk.com/enterprise/docs/developapps/manageknowledge/kvstore/aboutkvstorecollections).
    +
    +    Examples:
    +        >>> from solnlib.modular_input import checkpointer
    +        >>> checkpoint = checkpointer.KVStoreCheckpointer(
    +                "unique_addon_checkpoints",
    +                "session_key",
    +                "unique_addon"
    +            )
    +        >>> checkpoint.update("input_1", {"timestamp": 1638043093})
    +        >>> checkpoint.get("input_1")
    +        >>> # returns {"timestamp": 1638043093}
    +    """
    +
    +    def __init__(
    +        self,
    +        collection_name: str,
    +        session_key: str,
    +        app: str,
    +        owner: Optional[str] = "nobody",
    +        scheme: Optional[str] = None,
    +        host: Optional[str] = None,
    +        port: Optional[int] = None,
    +        **context: Any,
    +    ):
    +        """Initializes KVStoreCheckpointer.
    +
    +        Arguments:
    +            collection_name: Collection name of kvstore checkpointer.
    +            session_key: Splunk access token.
    +            app: App name of namespace.
    +            owner: (optional) Owner of namespace, default is `nobody`.
    +            scheme: (optional) The access scheme, default is None.
    +            host: (optional) The host name, default is None.
    +            port: (optional) The port number, default is None.
    +            context: Other configurations for Splunk rest client.
    +
    +        Raises:
    +            binding.HTTPError: HTTP error different from 404, for example 503
    +                when KV Store is initializing and not ready to serve requests.
    +            CheckpointerException: If init KV Store checkpointer failed.
    +        """
    +        try:
    +            if not context.get("pool_connections"):
    +                context["pool_connections"] = 5
    +            if not context.get("pool_maxsize"):
    +                context["pool_maxsize"] = 5
    +            self._collection_data = _utils.get_collection_data(
    +                collection_name,
    +                session_key,
    +                app,
    +                owner,
    +                scheme,
    +                host,
    +                port,
    +                {"state": "string"},
    +                **context,
    +            )
    +        except KeyError:
    +            raise CheckpointerException("Get KV Store checkpointer failed.")
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def update(self, key: str, state: Any) -> None:
    +        """Updates document with an id that equals to `key` and `state` as
    +        document data.
    +
    +        Arguments:
    +            key: `id` of the document to update.
    +            state: Document data to update. It can be integer, string,
    +                or a dict, or anything that can be an argument to `json.dumps`.
    +
    +        Raises:
    +            binding.HTTPError: when an error occurred in Splunk, for example,
    +                when Splunk is restarting and KV Store is not yet initialized.
    +        """
    +        record = {"_key": key, "state": json.dumps(state)}
    +        self._collection_data.batch_save(record)
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def batch_update(self, states: Iterable[Dict[str, Any]]) -> None:
    +        """Updates multiple documents.
    +
    +        Arguments:
    +            states: Iterable that contains documents to update. Document should
    +                be a dict with at least "state" key.
    +
    +        Raises:
    +            binding.HTTPError: when an error occurred in Splunk, for example,
    +                when Splunk is restarting and KV Store is not yet initialized.
    +        """
    +        for state in states:
    +            state["state"] = json.dumps(state["state"])
    +        self._collection_data.batch_save(*states)
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def get(self, key: str) -> Optional[Any]:
    +        """Gets document with an id that equals to `key`.
    +
    +        Arguments:
    +            key: `id` of the document to get.
    +
    +        Raises:
    +            binding.HTTPError: When an error occurred in Splunk (not 404 code),
    +                can be 503 code, when Splunk is restarting and KV Store is not
    +                yet initialized.
    +
    +        Returns:
    +            Document data under `key` or `None` in case of no data.
    +        """
    +        try:
    +            record = self._collection_data.query_by_id(key)
    +        except binding.HTTPError as e:
    +            if e.status != 404:
    +                logging.error(f"Get checkpoint failed: {traceback.format_exc()}.")
    +                raise
    +            return None
    +        return json.loads(record["state"])
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def delete(self, key: str) -> None:
    +        """Deletes document with an id that equals to `key`.
    +
    +        Arguments:
    +            key: `id` of the document to delete.
    +
    +        Raises:
    +            binding.HTTPError: When an error occurred in Splunk (not 404 code),
    +                can be 503 code, when Splunk is restarting and KV Store is not
    +                yet initialized.
    +        """
    +        try:
    +            self._collection_data.delete_by_id(key)
    +        except binding.HTTPError as e:
    +            if e.status != 404:
    +                logging.error(f"Delete checkpoint failed: {traceback.format_exc()}.")
    +                raise
    +
    +
    +class FileCheckpointer(Checkpointer):
    +    """File checkpointer.
    +
    +    Use file to save modular input checkpoint.
    +
    +    Examples:
    +        >>> from solnlib.modular_input import checkpointer
    +        >>> ck = checkpointer.FileCheckpointer('/opt/splunk/var/...')
    +        >>> ck.update(...)
    +        >>> ck.get(...)
    +    """
    +
    +    def __init__(self, checkpoint_dir: str):
    +        """Initializes FileCheckpointer.
    +
    +        Arguments:
    +            checkpoint_dir: Checkpoint directory.
    +        """
    +        warnings.warn(
    +            "FileCheckpointer is deprecated, please use KVStoreCheckpointer",
    +            stacklevel=2,
    +        )
    +        self._checkpoint_dir = checkpoint_dir
    +
    +    def encode_key(self, key):
    +        return base64.b64encode(key.encode()).decode()
    +
    +    def update(self, key, state):
    +        file_name = op.join(self._checkpoint_dir, self.encode_key(key))
    +        with open(file_name + "_new", "w") as fp:
    +            json.dump(state, fp)
    +
    +        if op.exists(file_name):
    +            try:
    +                os.remove(file_name)
    +            except OSError:
    +                pass
    +
    +        os.rename(file_name + "_new", file_name)
    +
    +    def batch_update(self, states):
    +        for state in states:
    +            self.update(state["_key"], state["state"])
    +
    +    def get(self, key):
    +        file_name = op.join(self._checkpoint_dir, self.encode_key(key))
    +        try:
    +            with open(file_name) as fp:
    +                return json.load(fp)
    +        except (OSError, ValueError):
    +            return None
    +
    +    def delete(self, key):
    +        file_name = op.join(self._checkpoint_dir, self.encode_key(key))
    +        try:
    +            os.remove(file_name)
    +        except OSError:
    +            pass
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/event.py b/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/event.py
    new file mode 100644
    index 0000000..fbffa0d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/event.py
    @@ -0,0 +1,255 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module provides Splunk modular input event encapsulation."""
    +
    +import json
    +from typing import List
    +from xml.etree import ElementTree as ET  # nosemgrep
    +
    +import defusedxml.ElementTree as defused_et
    +
    +__all__ = ["EventException", "XMLEvent", "HECEvent"]
    +
    +
    +class EventException(Exception):
    +    pass
    +
    +
    +class Event:
    +    """Base class of modular input event."""
    +
    +    def __init__(
    +        self,
    +        data: dict,
    +        time: float = None,
    +        index: str = None,
    +        host: str = None,
    +        source: str = None,
    +        sourcetype: str = None,
    +        fields: dict = None,
    +        stanza: str = None,
    +        unbroken: bool = False,
    +        done: bool = False,
    +    ):
    +        """Modular input event.
    +
    +        Arguments:
    +            data: Event data.
    +            time: (optional) Event timestamp, default is None.
    +            index: (optional) The index event will be written to, default is None.
    +            host: (optional) Event host, default is None.
    +            source: (optional) Event source, default is None.
    +            sourcetype: (optional) Event sourcetype, default is None.
    +            fields: (optional) Event fields, default is None.
    +            stanza: (optional) Event stanza name, default is None.
    +            unbroken: (optional) Event unbroken flag, default is False.
    +            done: (optional) The last unbroken event, default is False.
    +
    +        Examples:
    +           >>> event = Event(
    +           >>>     data='This is a test data.',
    +           >>>     time=1372274622.493,
    +           >>>     index='main',
    +           >>>     host='localhost',
    +           >>>     source='Splunk',
    +           >>>     sourcetype='misc',
    +           >>>     fields= {'Cloud':'AWS','region': 'us-west-1'},
    +           >>>     stanza='test_scheme://test',
    +           >>>     unbroken=True,
    +           >>>     done=True)
    +        """
    +
    +        self._data = data
    +        self._time = "%.3f" % time if time else None
    +        self._index = index
    +        self._host = host
    +        self._source = source
    +        self._sourcetype = sourcetype
    +        if fields:
    +            self._fields = fields
    +        self._stanza = stanza
    +        if not unbroken and done:
    +            raise EventException('Invalid combination of "unbroken" and "done".')
    +        self._unbroken = unbroken
    +        self._done = done
    +
    +    def __str__(self):
    +        event = {
    +            "data": self._data,
    +            "time": float(self._time) if self._time else self._time,
    +            "index": self._index,
    +            "host": self._host,
    +            "source": self._source,
    +            "sourcetype": self._sourcetype,
    +            "stanza": self._stanza,
    +            "unbroken": self._unbroken,
    +            "done": self._done,
    +        }
    +
    +        if hasattr(self, "_fields"):
    +            event["fields"] = self._fields
    +
    +        return json.dumps(event)
    +
    +    @classmethod
    +    def format_events(cls, events: List) -> List:
    +        """Format events to list of string.
    +
    +        Arguments:
    +            events: List of events to format.
    +
    +        Returns:
    +            List of formatted events string.
    +        """
    +
    +        raise EventException('Unimplemented "format_events".')
    +
    +
    +class XMLEvent(Event):
    +    """XML event."""
    +
    +    def _to_xml(self):
    +        _event = ET.Element("event")
    +        if self._stanza:
    +            _event.set("stanza", self._stanza)
    +        if self._unbroken:
    +            _event.set("unbroken", str(int(self._unbroken)))
    +
    +        if self._time:
    +            ET.SubElement(_event, "time").text = self._time
    +
    +        sub_elements = [
    +            ("index", self._index),
    +            ("host", self._host),
    +            ("source", self._source),
    +            ("sourcetype", self._sourcetype),
    +        ]
    +        for node, value in sub_elements:
    +            if value:
    +                ET.SubElement(_event, node).text = value
    +
    +        if isinstance(self._data, str):
    +            ET.SubElement(_event, "data").text = self._data
    +        else:
    +            ET.SubElement(_event, "data").text = json.dumps(self._data)
    +
    +        if self._done:
    +            ET.SubElement(_event, "done")
    +
    +        return _event
    +
    +    @classmethod
    +    def format_events(cls, events: List) -> List:
    +        """Format events to list of string.
    +
    +        Arguments:
    +            events: List of events to format.
    +
    +        Returns:
    +            List of formatted events string, example::
    +
    +                [
    +                    '<stream>
    +                    <event stanza="test_scheme://test" unbroken="1">
    +                    <time>1459919070.994</time>
    +                    <index>main</index>
    +                    <host>localhost</host>
    +                    <source>test</source>
    +                    <sourcetype>test</sourcetype>
    +                    <data>{"kk": [1, 2, 3]}</data>
    +                    <done />
    +                    </event>
    +                    <event stanza="test_scheme://test" unbroken="1">
    +                    <time>1459919082.961</time>
    +                    <index>main</index>
    +                    <host>localhost</host>
    +                    <source>test</source>
    +                    <sourcetype>test</sourcetype>
    +                    <data>{"kk": [3, 2, 3]}</data>
    +                    <done />
    +                    </event>
    +                    </stream>'
    +                ]
    +        """
    +
    +        stream = ET.Element("stream")
    +        for event in events:
    +            stream.append(event._to_xml())
    +
    +        return [
    +            defused_et.tostring(stream, encoding="utf-8", method="xml").decode("utf-8")
    +        ]
    +
    +
    +class HECEvent(Event):
    +    """HEC event."""
    +
    +    max_hec_event_length = 1000000
    +
    +    def _to_hec(self, event_field):
    +        event = {}
    +        event[event_field] = self._data
    +        if self._time:
    +            event["time"] = float(self._time)
    +        if self._index:
    +            event["index"] = self._index
    +        if self._host:
    +            event["host"] = self._host
    +        if self._source:
    +            event["source"] = self._source
    +        if self._sourcetype:
    +            event["sourcetype"] = self._sourcetype
    +        if hasattr(self, "_fields"):
    +            event["fields"] = self._fields
    +
    +        return json.dumps(event, ensure_ascii=False)
    +
    +    @classmethod
    +    def format_events(cls, events: List, event_field: str = "event") -> List:
    +        """Format events to list of string.
    +
    +        Arguments:
    +            events: List of events to format.
    +            event_field: Event field.
    +
    +        Returns:
    +            List of formatted events string, example::
    +
    +                [
    +                    '{"index": "main", ... "event": {"kk": [1, 2, 3]}}\\n
    +                    {"index": "main", ... "event": {"kk": [3, 2, 3]}}',
    +                '...'
    +                ]
    +        """
    +
    +        size = 0
    +        new_events, batched_events = [], []
    +        events = [event._to_hec(event_field) for event in events]
    +        for event in events:
    +            new_length = size + len(event) + len(batched_events) - 1
    +            if new_length >= cls.max_hec_event_length:
    +                if batched_events:
    +                    new_events.append("\n".join(batched_events))
    +                del batched_events[:]
    +                size = 0
    +
    +            batched_events.append(event)
    +            size = size + len(event)
    +        if batched_events:
    +            new_events.append("\n".join(batched_events))
    +
    +        return new_events
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/event_writer.py b/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/event_writer.py
    new file mode 100644
    index 0000000..8c1d9ce
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/event_writer.py
    @@ -0,0 +1,471 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module provides two kinds of event writers (ClassicEventWriter,
    +HECEventWriter) to write Splunk modular input events."""
    +
    +import logging
    +import multiprocessing
    +import sys
    +import threading
    +import time
    +import traceback
    +from abc import ABCMeta, abstractmethod
    +from random import randint
    +from typing import List, Union
    +
    +from splunklib import binding
    +
    +from .. import splunk_rest_client as rest_client
    +from .. import utils
    +from ..hec_config import HECConfig
    +from ..splunkenv import get_splunkd_access_info
    +from ..utils import retry
    +from .event import HECEvent, XMLEvent
    +
    +__all__ = ["ClassicEventWriter", "HECEventWriter"]
    +
    +
    +class EventWriter(metaclass=ABCMeta):
    +    """Base class of event writer."""
    +
    +    description = "EventWriter"
    +
    +    @abstractmethod
    +    def create_event(
    +        self,
    +        data: dict,
    +        time: float = None,
    +        index: str = None,
    +        host: str = None,
    +        source: str = None,
    +        sourcetype: str = None,
    +        fields: dict = None,
    +        stanza: str = None,
    +        unbroken: bool = False,
    +        done: bool = False,
    +    ) -> Union[XMLEvent, HECEvent]:
    +        """Create a new event.
    +
    +        Arguments:
    +            data: Event data.
    +            time: (optional) Event timestamp, default is None.
    +            index: (optional) The index event will be written to, default is None.
    +            host: (optional) Event host, default is None.
    +            source: (optional) Event source, default is None.
    +            sourcetype: (optional) Event sourcetype, default is None.
    +            fields: (optional) Event fields, default is None.
    +            stanza: (optional) Event stanza name, default is None.
    +            unbroken: (optional) Event unbroken flag, default is False.
    +                It is only meaningful when for XMLEvent when using ClassicEventWriter.
    +            done: (optional) The last unbroken event, default is False.
    +                It is only meaningful when for XMLEvent when using ClassicEventWriter.
    +
    +        Examples:
    +           >>> ew = event_writer.HECEventWriter(...)
    +           >>> event = ew.create_event(
    +           >>>     data='This is a test data.',
    +           >>>     time='%.3f' % 1372274622.493,
    +           >>>     index='main',
    +           >>>     host='localhost',
    +           >>>     source='Splunk',
    +           >>>     sourcetype='misc',
    +           >>>     fields={'accountid': '603514901691', 'Cloud': u'AWS'},
    +           >>>     stanza='test_scheme://test',
    +           >>>     unbroken=True,
    +           >>>     done=True)
    +        """
    +
    +        pass
    +
    +    @abstractmethod
    +    def write_events(self, events: List):
    +        """Write events.
    +
    +        Arguments:
    +            events: List of events to write.
    +
    +        Examples:
    +           >>> from solnlib.modular_input import event_writer
    +           >>> ew = event_writer.EventWriter(...)
    +           >>> ew.write_events([event1, event2])
    +        """
    +
    +        pass
    +
    +
    +class ClassicEventWriter(EventWriter):
    +    """Classic event writer.
    +
    +    Use sys.stdout as the output.
    +
    +    Examples:
    +        >>> from solnlib.modular_input import event_writer
    +        >>> ew = event_writer.ClassicEventWriter()
    +        >>> ew.write_events([event1, event2])
    +    """
    +
    +    description = "ClassicEventWriter"
    +
    +    def __init__(self, lock: Union[threading.Lock, multiprocessing.Lock] = None):
    +        """Initializes ClassicEventWriter.
    +
    +        Arguments:
    +            lock: (optional) lock to exclusively access stdout.
    +                by default, it is None and it will use threading safe lock.
    +                if user would like to make the lock multiple-process safe, user should
    +                pass in multiprocessing.Lock() instead
    +        """
    +        if lock is None:
    +            self._lock = threading.Lock()
    +        else:
    +            self._lock = lock
    +
    +    def create_event(
    +        self,
    +        data: dict,
    +        time: float = None,
    +        index: str = None,
    +        host: str = None,
    +        source: str = None,
    +        sourcetype: str = None,
    +        fields: dict = None,
    +        stanza: str = None,
    +        unbroken: bool = False,
    +        done: bool = False,
    +    ):
    +        """Create a new XMLEvent object."""
    +
    +        return XMLEvent(
    +            data,
    +            time=time,
    +            index=index,
    +            host=host,
    +            source=source,
    +            sourcetype=sourcetype,
    +            stanza=stanza,
    +            unbroken=unbroken,
    +            done=done,
    +        )
    +
    +    def write_events(self, events):
    +        if not events:
    +            return
    +
    +        stdout = sys.stdout
    +
    +        data = "".join([event for event in XMLEvent.format_events(events)])
    +        with self._lock:
    +            stdout.write(data)
    +            stdout.flush()
    +
    +
    +class HECEventWriter(EventWriter):
    +    """HEC event writer.
    +
    +    Use Splunk HEC as the output.
    +
    +    Examples:
    +        >>> from solnlib.modular_input import event_writer
    +        >>> ew = event_writer.HECEventWriter(hec_input_name, session_key)
    +        >>> ew.write_events([event1, event2])
    +    """
    +
    +    WRITE_EVENT_RETRIES = 5
    +    HTTP_INPUT_CONFIG_ENDPOINT = "/servicesNS/nobody/splunk_httpinput/data/inputs/http"
    +    HTTP_EVENT_COLLECTOR_ENDPOINT = "/services/collector"
    +    TOO_MANY_REQUESTS = 429  # we exceeded rate limit
    +    SERVICE_UNAVAILABLE = 503  # remote service is temporary unavailable
    +
    +    description = "HECEventWriter"
    +
    +    headers = [("Content-Type", "application/json")]
    +
    +    def __init__(
    +        self,
    +        hec_input_name: str,
    +        session_key: str,
    +        scheme: str = None,
    +        host: str = None,
    +        port: int = None,
    +        hec_uri: str = None,
    +        hec_token: str = None,
    +        logger: logging.Logger = None,
    +        **context: dict
    +    ):
    +        """Initializes HECEventWriter.
    +
    +        Arguments:
    +            hec_input_name: Splunk HEC input name.
    +            session_key: Splunk access token.
    +            scheme: (optional) The access scheme, default is None.
    +            host: (optional) The host name, default is None.
    +            port: (optional) The port number, default is None.
    +            hec_uri: (optional) If hec_uri and hec_token are provided, they will
    +                higher precedence than hec_input_name.
    +            hec_token: (optional) HEC token.
    +            logger: Logger object.
    +            context: Other configurations for Splunk rest client.
    +        """
    +        super().__init__()
    +        self._session_key = session_key
    +        if logger:
    +            self.logger = logger
    +        else:
    +            self.logger = logging
    +
    +        if not all([scheme, host, port]):
    +            scheme, host, port = get_splunkd_access_info()
    +
    +        if hec_uri and hec_token:
    +            scheme, host, hec_port = utils.extract_http_scheme_host_port(hec_uri)
    +        else:
    +            hec_port, hec_token = self._get_hec_config(
    +                hec_input_name, session_key, scheme, host, port, **context
    +            )
    +
    +        if not context.get("pool_connections"):
    +            context["pool_connections"] = 10
    +
    +        if not context.get("pool_maxsize"):
    +            context["pool_maxsize"] = 10
    +
    +        self._rest_client = rest_client.SplunkRestClient(
    +            hec_token, app="-", scheme=scheme, host=host, port=hec_port, **context
    +        )
    +
    +    @staticmethod
    +    def create_from_token(
    +        hec_uri: str, hec_token: str, **context: dict
    +    ) -> "HECEventWriter":
    +        """Given HEC URI and HEC token, create HECEventWriter object. This
    +        function simplifies the standalone mode HECEventWriter usage (not in a
    +        modinput).
    +
    +        Arguments:
    +            hec_uri: HTTP Event Collector URI, like https://localhost:8088.
    +            hec_token: HTTP Event Collector token.
    +            context: Other configurations.
    +
    +        Returns:
    +            Created HECEventWriter.
    +        """
    +
    +        return HECEventWriter(
    +            None,
    +            None,
    +            None,
    +            None,
    +            None,
    +            hec_uri=hec_uri,
    +            hec_token=hec_token,
    +            **context
    +        )
    +
    +    @staticmethod
    +    def create_from_input(
    +        hec_input_name: str, splunkd_uri: str, session_key: str, **context: dict
    +    ) -> "HECEventWriter":
    +        """Given HEC input stanza name, splunkd URI and splunkd session key,
    +        create HECEventWriter object. HEC URI and token etc will be discovered
    +        from HEC input stanza. When hitting HEC event limit, the underlying
    +        code will increase the HEC event limit automatically by calling
    +        corresponding REST API against splunkd_uri by using session_key.
    +
    +        Arguments:
    +            hec_input_name: Splunk HEC input name.
    +            splunkd_uri: Splunkd URI, like https://localhost:8089
    +            session_key: Splunkd access token.
    +            context: Other configurations.
    +
    +        Returns:
    +            Created HECEventWriter.
    +        """
    +
    +        scheme, host, port = utils.extract_http_scheme_host_port(splunkd_uri)
    +        return HECEventWriter(
    +            hec_input_name, session_key, scheme, host, port, **context
    +        )
    +
    +    @staticmethod
    +    def create_from_token_with_session_key(
    +        splunkd_uri: str,
    +        session_key: str,
    +        hec_uri: str,
    +        hec_token: str,
    +        **context: dict
    +    ) -> "HECEventWriter":
    +        """Given Splunkd URI, Splunkd session key, HEC URI and HEC token,
    +        create HECEventWriter object. When hitting HEC event limit, the event
    +        writer will increase the HEC event limit automatically by calling
    +        corresponding REST API against splunkd_uri by using session_key.
    +
    +        Arguments:
    +            splunkd_uri: Splunkd URI, like https://localhost:8089.
    +            session_key: Splunkd access token.
    +            hec_uri: Http Event Collector URI, like https://localhost:8088.
    +            hec_token: Http Event Collector token.
    +            context: Other configurations.
    +
    +        Returns:
    +            Created HECEventWriter.
    +        """
    +
    +        scheme, host, port = utils.extract_http_scheme_host_port(splunkd_uri)
    +        return HECEventWriter(
    +            None,
    +            session_key,
    +            scheme,
    +            host,
    +            port,
    +            hec_uri=hec_uri,
    +            hec_token=hec_token,
    +            **context
    +        )
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def _get_hec_config(
    +        self, hec_input_name, session_key, scheme, host, port, **context
    +    ):
    +        hc = HECConfig(session_key, scheme=scheme, host=host, port=port, **context)
    +        settings = hc.get_settings()
    +        if utils.is_true(settings.get("disabled")):
    +            # Enable HEC input
    +            self.logger.info("Enabling HEC")
    +            settings["disabled"] = "0"
    +            settings["enableSSL"] = context.get("hec_enablessl", "1")
    +            settings["port"] = context.get("hec_port", "8088")
    +            hc.update_settings(settings)
    +
    +        hec_input = hc.get_input(hec_input_name)
    +        if not hec_input:
    +            # Create HEC input
    +            self.logger.info("Create HEC datainput, name=%s", hec_input_name)
    +            hinput = {
    +                "index": context.get("index", "main"),
    +            }
    +
    +            if context.get("sourcetype"):
    +                hinput["sourcetype"] = context["sourcetype"]
    +
    +            if context.get("token"):
    +                hinput["token"] = context["token"]
    +
    +            if context.get("source"):
    +                hinput["source"] = context["source"]
    +
    +            if context.get("host"):
    +                hinput["host"] = context["host"]
    +
    +            hec_input = hc.create_input(hec_input_name, hinput)
    +
    +        limits = hc.get_limits()
    +        HECEvent.max_hec_event_length = int(limits.get("max_content_length", 1000000))
    +
    +        return settings["port"], hec_input["token"]
    +
    +    def create_event(
    +        self,
    +        data: dict,
    +        time: float = None,
    +        index: str = None,
    +        host: str = None,
    +        source: str = None,
    +        sourcetype: str = None,
    +        fields: dict = None,
    +        stanza: str = None,
    +        unbroken: bool = False,
    +        done: bool = False,
    +    ) -> HECEvent:
    +        """Create a new HECEvent object.
    +
    +        Arguments:
    +            data: Event data.
    +            time: (optional) Event timestamp, default is None.
    +            index: (optional) The index event will be written to, default is None.
    +            host: (optional) Event host, default is None.
    +            source: (optional) Event source, default is None.
    +            sourcetype: (optional) Event sourcetype, default is None.
    +            fields: (optional) Event fields, default is None.
    +            stanza: (optional) Event stanza name, default is None.
    +            unbroken: (optional) Event unbroken flag, default is False.
    +                It is only meaningful when for XMLEvent when using ClassicEventWriter.
    +            done: (optional) The last unbroken event, default is False.
    +                It is only meaningful when for XMLEvent when using ClassicEventWriter.
    +
    +        Returns:
    +            Created HECEvent.
    +        """
    +
    +        return HECEvent(
    +            data,
    +            time=time,
    +            index=index,
    +            host=host,
    +            source=source,
    +            sourcetype=sourcetype,
    +            fields=fields,
    +        )
    +
    +    def write_events(
    +        self,
    +        events: List,
    +        retries: int = WRITE_EVENT_RETRIES,
    +        event_field: str = "event",
    +    ):
    +        """Write events to index in bulk.
    +
    +        Arguments:
    +            events: List of events.
    +            retries: Number of retries for writing events to index.
    +            event_field: Event field.
    +        """
    +        if not events:
    +            return
    +
    +        last_ex = None
    +        for event in HECEvent.format_events(events, event_field):
    +            for i in range(retries):
    +                try:
    +                    self._rest_client.post(
    +                        self.HTTP_EVENT_COLLECTOR_ENDPOINT,
    +                        body=event.encode("utf-8"),
    +                        headers=self.headers,
    +                    )
    +                except binding.HTTPError as e:
    +                    self.logger.warn(
    +                        "Write events through HEC failed. Status=%s", e.status
    +                    )
    +                    last_ex = e
    +                    if e.status in [self.TOO_MANY_REQUESTS, self.SERVICE_UNAVAILABLE]:
    +                        # wait time for n retries: 10, 20, 40, 80, 80, 80, 80, ....
    +                        sleep_time = min(((2 ** (i + 1)) * 5), 80)
    +                        if i < retries - 1:
    +                            random_millisecond = randint(0, 1000) / 1000.0
    +                            time.sleep(sleep_time + random_millisecond)
    +                    else:
    +                        raise last_ex
    +                else:
    +                    break
    +            else:
    +                # When failed after retry, we reraise the exception
    +                # to exit the function to let client handle this situation
    +                self.logger.error(
    +                    "Write events through HEC failed: %s. status=%s",
    +                    traceback.format_exc(),
    +                    last_ex.status,
    +                )
    +                raise last_ex
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/modular_input.py b/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/modular_input.py
    new file mode 100644
    index 0000000..b2256b1
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/modular_input/modular_input.py
    @@ -0,0 +1,507 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module provides a base class of Splunk modular input."""
    +
    +import logging
    +import sys
    +import traceback
    +from abc import ABCMeta, abstractmethod
    +from typing import Callable, List
    +from urllib import parse as urlparse
    +from xml.etree import ElementTree as ET  # nosemgrep
    +
    +import defusedxml.ElementTree as defused_et
    +from splunklib import binding
    +from splunklib.modularinput.argument import Argument
    +from splunklib.modularinput.input_definition import InputDefinition
    +from splunklib.modularinput.scheme import Scheme
    +from splunklib.modularinput.validation_definition import ValidationDefinition
    +
    +from .. import utils
    +from ..orphan_process_monitor import OrphanProcessMonitor
    +from . import checkpointer, event_writer
    +
    +__all__ = ["ModularInputException", "ModularInput"]
    +
    +
    +class ModularInputException(Exception):
    +    """Exception for ModularInput class."""
    +
    +    pass
    +
    +
    +class ModularInput(metaclass=ABCMeta):
    +    """Base class of Splunk modular input.
    +
    +    It's a base modular input, it should be inherited by sub modular input. For
    +    sub modular input, properties: 'app', 'name', 'title' and 'description' must
    +    be overriden, also there are some other optional properties can be overriden
    +    like: 'use_external_validation', 'use_single_instance', 'use_kvstore_checkpointer'
    +    and 'use_hec_event_writer'.
    +
    +    Notes: If you set 'KVStoreCheckpointer' or 'use_hec_event_writer' to True,
    +    you must override the corresponding 'kvstore_checkpointer_collection_name'
    +    and 'hec_input_name'.
    +
    +    Examples:
    +
    +       >>> Class TestModularInput(ModularInput):
    +       >>>     app = 'TestApp'
    +       >>>     name = 'test_modular_input'
    +       >>>     title = 'Test modular input'
    +       >>>     description = 'This is a test modular input'
    +       >>>     use_external_validation = True
    +       >>>     use_single_instance = False
    +       >>>     use_kvstore_checkpointer = True
    +       >>>     kvstore_checkpointer_collection_name = 'TestCheckpoint'
    +       >>>     use_hec_event_writer = True
    +       >>>     hec_input_name = 'TestEventWriter'
    +       >>>
    +       >>>     def extra_arguments(self):
    +       >>>         ... .. .
    +       >>>
    +       >>>     def do_validation(self, parameters):
    +       >>>         ... .. .
    +       >>>
    +       >>>     def do_run(self, inputs):
    +       >>>         ... .. .
    +       >>>
    +       >>> if __name__ == '__main__':
    +       >>>     md = TestModularInput()
    +       >>>     md.execute()
    +    """
    +
    +    # App name, must be overridden
    +    app = None
    +    # Modular input name, must be overridden
    +    name = None
    +    # Modular input scheme title, must be overridden
    +    title = None
    +    # Modular input scheme description, must be overridden
    +    description = None
    +    # Modular input scheme use external validation, default is False
    +    use_external_validation = False
    +    # Modular input scheme use single instance mode, default is False
    +    use_single_instance = False
    +    # Use kvstore as checkpointer, default is True
    +    use_kvstore_checkpointer = True
    +    # Collection name of kvstore checkpointer, must be overridden if
    +    # use_kvstore_checkpointer is True
    +    kvstore_checkpointer_collection_name = None
    +    # Use hec event writer
    +    use_hec_event_writer = True
    +    # Input name of Splunk HEC, must be overridden if use_hec_event_writer
    +    # is True
    +    hec_input_name = None
    +
    +    def __init__(self):
    +        # Validate properties
    +        self._validate_properties()
    +        # Modular input state
    +        self.should_exit = False
    +        # Metadata
    +        self.server_host_name = None
    +        self.server_uri = None
    +        self.server_scheme = None
    +        self.server_host = None
    +        self.server_port = None
    +        self.session_key = None
    +        # Modular input config name
    +        self.config_name = None
    +        # Checkpoint dir
    +        self._checkpoint_dir = None
    +        # Checkpointer
    +        self._checkpointer = None
    +        # Orphan process monitor
    +        self._orphan_monitor = None
    +        # Event writer
    +        self._event_writer = None
    +
    +    def _validate_properties(self):
    +        if not all([self.app, self.name, self.title, self.description]):
    +            raise ModularInputException(
    +                'Attributes: "app", "name", "title", "description" must '
    +                "be overriden."
    +            )
    +
    +        if self.use_kvstore_checkpointer:
    +            if self.kvstore_checkpointer_collection_name is None:
    +                raise ModularInputException(
    +                    'Attribute: "kvstore_checkpointer_collection_name" must'
    +                    'be overriden if "use_kvstore_checkpointer" is True".'
    +                )
    +            elif self.kvstore_checkpointer_collection_name.strip() == "":
    +                raise ModularInputException(
    +                    'Attribute: "kvstore_checkpointer_collection_name" can'
    +                    " not be empty."
    +                )
    +
    +        if self.use_hec_event_writer:
    +            if self.hec_input_name is None:
    +                raise ModularInputException(
    +                    'Attribute: "hec_input_name" must be overriden '
    +                    'if "use_hec_event_writer" is True.'
    +                )
    +            elif self.hec_input_name.strip() == "":
    +                raise ModularInputException(
    +                    'Attribute: "hec_input_name" can not be empty.'
    +                )
    +
    +    @property
    +    def checkpointer(self) -> checkpointer.Checkpointer:
    +        """Get checkpointer object.
    +
    +        The checkpointer returned depends on use_kvstore_checkpointer flag,
    +        if use_kvstore_checkpointer is true will return an KVStoreCheckpointer
    +        object else an FileCheckpointer object.
    +
    +        Returns:
    +            A checkpointer object.
    +        """
    +
    +        if self._checkpointer is not None:
    +            return self._checkpointer
    +
    +        self._checkpointer = self._create_checkpointer()
    +        return self._checkpointer
    +
    +    def _create_checkpointer(self):
    +        if self.use_kvstore_checkpointer:
    +            checkpointer_name = ":".join(
    +                [self.app, self.config_name, self.kvstore_checkpointer_collection_name]
    +            )
    +            try:
    +                return checkpointer.KVStoreCheckpointer(
    +                    checkpointer_name,
    +                    self.session_key,
    +                    self.app,
    +                    owner="nobody",
    +                    scheme=self.server_scheme,
    +                    host=self.server_host,
    +                    port=self.server_port,
    +                )
    +            except binding.HTTPError:
    +                logging.error(
    +                    "Failed to init kvstore checkpointer: %s.", traceback.format_exc()
    +                )
    +                raise
    +        else:
    +            return checkpointer.FileCheckpointer(self._checkpoint_dir)
    +
    +    @property
    +    def event_writer(self) -> event_writer.EventWriter:
    +        """Get event writer object.
    +
    +        The event writer returned depends on use_hec_event_writer flag,
    +        if use_hec_event_writer is true will return an HECEventWriter
    +        object else an ClassicEventWriter object.
    +
    +        Returns:
    +            Event writer object.
    +        """
    +
    +        if self._event_writer is not None:
    +            return self._event_writer
    +
    +        self._event_writer = self._create_event_writer()
    +        return self._event_writer
    +
    +    def _create_event_writer(self):
    +        if self.use_hec_event_writer:
    +            hec_input_name = ":".join([self.app, self.hec_input_name])
    +            try:
    +                return event_writer.HECEventWriter(
    +                    hec_input_name,
    +                    self.session_key,
    +                    scheme=self.server_scheme,
    +                    host=self.server_host,
    +                    port=self.server_port,
    +                )
    +            except binding.HTTPError:
    +                logging.error(
    +                    "Failed to init HECEventWriter: %s.", traceback.format_exc()
    +                )
    +                raise
    +        else:
    +            return event_writer.ClassicEventWriter()
    +
    +    def _update_metadata(self, metadata):
    +        self.server_host_name = metadata["server_host"]
    +        splunkd = urlparse.urlsplit(metadata["server_uri"])
    +        self.server_uri = splunkd.geturl()
    +        self.server_scheme = splunkd.scheme
    +        self.server_host = splunkd.hostname
    +        self.server_port = splunkd.port
    +        self.session_key = metadata["session_key"]
    +        self._checkpoint_dir = metadata["checkpoint_dir"]
    +
    +    def _do_scheme(self):
    +        scheme = Scheme(self.title)
    +        scheme.description = self.description
    +        scheme.use_external_validation = self.use_external_validation
    +        scheme.streaming_mode = Scheme.streaming_mode_xml
    +        scheme.use_single_instance = self.use_single_instance
    +
    +        for argument in self.extra_arguments():
    +            name = argument["name"]
    +            title = argument.get("title", None)
    +            description = argument.get("description", None)
    +            validation = argument.get("validation", None)
    +            data_type = argument.get("data_type", Argument.data_type_string)
    +            required_on_edit = argument.get("required_on_edit", False)
    +            required_on_create = argument.get("required_on_create", False)
    +
    +            scheme.add_argument(
    +                Argument(
    +                    name,
    +                    title=title,
    +                    description=description,
    +                    validation=validation,
    +                    data_type=data_type,
    +                    required_on_edit=required_on_edit,
    +                    required_on_create=required_on_create,
    +                )
    +            )
    +
    +        return defused_et.tostring(scheme.to_xml(), encoding="unicode")
    +
    +    def extra_arguments(self) -> List:
    +        """Extra arguments for modular input.
    +
    +        Default implementation is returning an empty list.
    +
    +        Returns:
    +            List of arguments like::
    +
    +                [
    +                    {
    +                        'name': 'arg1',
    +                        'title': 'arg1 title',
    +                        'description': 'arg1 description',
    +                        'validation': 'arg1 validation statement',
    +                        'data_type': Argument.data_type_string,
    +                        'required_on_edit': False,
    +                        'required_on_create': False
    +                    },
    +                    {...},
    +                    {...}
    +                ]
    +        """
    +
    +        return []
    +
    +    def do_validation(self, parameters):
    +        """Handles external validation for modular input kinds.
    +
    +        When Splunk calls a modular input script in validation mode, it will
    +        pass in an XML document giving information about the Splunk instance
    +        (so you can call back into it if needed) and the name and parameters
    +        of the proposed input. If this function does not throw an exception,
    +        the validation is assumed to succeed. Otherwise any errors thrown will
    +        be turned into a string and logged back to Splunk.
    +
    +        Arguments:
    +            parameters: The parameters of input passed by splunkd.
    +
    +        Raises:
    +            Exception: If validation is failed.
    +        """
    +
    +        pass
    +
    +    @abstractmethod
    +    def do_run(self, inputs: dict):
    +        """Runs this modular input.
    +
    +        Arguments:
    +            inputs: Command line arguments passed to this modular input.
    +                For single instance mode, inputs like::
    +
    +                    {
    +                    'stanza_name1': {'arg1': 'arg1_value', 'arg2': 'arg2_value', ...}
    +                    'stanza_name2': {'arg1': 'arg1_value', 'arg2': 'arg2_value', ...}
    +                    'stanza_name3': {'arg1': 'arg1_value', 'arg2': 'arg2_value', ...}
    +                    }
    +
    +                For multiple instance mode, inputs like::
    +
    +                    {
    +                    'stanza_name1': {'arg1': 'arg1_value', 'arg2': 'arg2_value', ...}
    +                    }
    +        """
    +
    +        pass
    +
    +    def register_teardown_handler(self, handler: Callable, *args):
    +        """Register teardown signal handler.
    +
    +        Arguments:
    +            handler: Teardown signal handler.
    +            args: Arguments to the handler.
    +
    +        Examples:
    +           >>> mi = ModularInput(...)
    +           >>> def teardown_handler(arg1, arg2, ...):
    +           >>>     ...
    +           >>> mi.register_teardown_handler(teardown_handler, arg1, arg2, ...)
    +        """
    +
    +        def _teardown_handler(signum, frame):
    +            handler(*args)
    +
    +        utils.handle_teardown_signals(_teardown_handler)
    +
    +    def register_orphan_handler(self, handler: Callable, *args):
    +        """Register orphan process handler.
    +
    +        Arguments:
    +            handler: Teardown signal handler.
    +            args: Arguments to the handler.
    +
    +        Examples:
    +           >>> mi = ModularInput(...)
    +           >>> def orphan_handler(arg1, arg2, ...):
    +           >>>     ...
    +           >>> mi.register_orphan_handler(orphan_handler, arg1, arg2, ...)
    +        """
    +
    +        def _orphan_handler():
    +            handler(*args)
    +
    +        if self._orphan_monitor is None:
    +            self._orphan_monitor = OrphanProcessMonitor(_orphan_handler)
    +            self._orphan_monitor.start()
    +
    +    def get_validation_definition(self) -> dict:
    +        """Get validation definition.
    +
    +        This method can be overwritten to get validation definition from
    +        other input instead `stdin`.
    +
    +        Returns:
    +            A dict object must contains `metadata` and `parameters`::
    +
    +                example: {
    +                    'metadata': {
    +                    'session_key': 'iCKPS0cvmpyeJk...sdaf',
    +                    'server_host': 'test-test.com',
    +                    'server_uri': 'https://127.0.0.1:8089',
    +                    'checkpoint_dir': '/tmp'
    +                    },
    +                    parameters: {'args1': value1, 'args2': value2}
    +                }
    +        """
    +
    +        validation_definition = ValidationDefinition.parse(sys.stdin)
    +        return {
    +            "metadata": validation_definition.metadata,
    +            "parameters": validation_definition.parameters,
    +        }
    +
    +    def get_input_definition(self) -> dict:
    +        """Get input definition.
    +
    +        This method can be overwritten to get input definition from
    +        other input instead `stdin`.
    +
    +        Returns:
    +            A dict object must contains `metadata` and `inputs`::
    +
    +                example: {
    +                    'metadata': {
    +                    'session_key': 'iCKPS0cvmpyeJk...sdaf',
    +                    'server_host': 'test-test.com',
    +                    'server_uri': 'https://127.0.0.1:8089',
    +                    'checkpoint_dir': '/tmp'
    +                    },
    +                    inputs: {
    +                    'stanza1': {'arg1': value1, 'arg2': value2},
    +                    'stanza2': {'arg1': value1, 'arg2': value2}
    +                    }
    +                }
    +        """
    +
    +        input_definition = InputDefinition.parse(sys.stdin)
    +        return {
    +            "metadata": input_definition.metadata,
    +            "inputs": input_definition.inputs,
    +        }
    +
    +    def execute(self):
    +        """Modular input entry.
    +
    +        Examples:
    +           >>> Class TestModularInput(ModularInput):
    +           >>>         ... .. .
    +           >>>
    +           >>> if __name__ == '__main__':
    +           >>>     md = TestModularInput()
    +           >>>     md.execute()
    +        """
    +
    +        if len(sys.argv) == 1:
    +            try:
    +                input_definition = self.get_input_definition()
    +                self._update_metadata(input_definition["metadata"])
    +                if self.use_single_instance:
    +                    self.config_name = self.name
    +                else:
    +                    self.config_name = list(input_definition["inputs"].keys())[0]
    +                self.do_run(input_definition["inputs"])
    +                logging.info("Modular input: %s exit normally.", self.name)
    +                return 0
    +            except Exception:
    +                logging.error(
    +                    "Modular input: %s exit with exception: %s.",
    +                    self.name,
    +                    traceback.format_exc(),
    +                )
    +                return 1
    +            finally:
    +                # Stop orphan monitor if any
    +                if self._orphan_monitor:
    +                    self._orphan_monitor.stop()
    +
    +        elif str(sys.argv[1]).lower() == "--scheme":
    +            sys.stdout.write(self._do_scheme())
    +            sys.stdout.flush()
    +            return 0
    +
    +        elif sys.argv[1].lower() == "--validate-arguments":
    +            try:
    +                validation_definition = self.get_validation_definition()
    +                self._update_metadata(validation_definition["metadata"])
    +                self.do_validation(validation_definition["parameters"])
    +                return 0
    +            except Exception as e:
    +                logging.error(
    +                    "Modular input: %s validate arguments with exception: %s.",
    +                    self.name,
    +                    traceback.format_exc(),
    +                )
    +                root = ET.Element("error")
    +                ET.SubElement(root, "message").text = str(e)
    +                sys.stderr.write(defused_et.tostring(root))
    +                sys.stderr.flush()
    +                return 1
    +        else:
    +            logging.error(
    +                'Modular input: %s run with invalid arguments: "%s".',
    +                self.name,
    +                " ".join(sys.argv[1:]),
    +            )
    +            return 1
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/net_utils.py b/deployment-apps/metricator-for-nmon/lib/solnlib/net_utils.py
    new file mode 100644
    index 0000000..06cc285
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/net_utils.py
    @@ -0,0 +1,155 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""Net utilities."""
    +import re
    +import socket
    +
    +__all__ = ["resolve_hostname", "validate_scheme_host_port"]
    +
    +from typing import Optional, Union
    +
    +
    +def resolve_hostname(addr: str) -> Optional[str]:
    +    """Try to resolve an IP to a host name and returns None on common failures.
    +
    +    Arguments:
    +        addr: IP address to resolve.
    +
    +    Returns:
    +        Host name if success else None.
    +
    +    Raises:
    +        ValueError: If `addr` is not a valid address.
    +    """
    +
    +    if is_valid_ip(addr):
    +        try:
    +            name, _, _ = socket.gethostbyaddr(addr)
    +            return name
    +        except socket.gaierror:
    +            # [Errno 8] nodename nor servname provided, or not known
    +            pass
    +        except socket.herror:
    +            # [Errno 1] Unknown host
    +            pass
    +        except socket.timeout:
    +            # Timeout.
    +            pass
    +
    +        return None
    +    else:
    +        raise ValueError("Invalid ip address.")
    +
    +
    +def is_valid_ip(addr: str) -> bool:
    +    """Validate an IPV4 address.
    +
    +    Arguments:
    +        addr: IP address to validate.
    +
    +    Returns:
    +        True if is valid else False.
    +    """
    +
    +    ip_rx = re.compile(
    +        r"""
    +        ^(((
    +              [0-1]\d{2}                  # matches 000-199
    +            | 2[0-4]\d                    # matches 200-249
    +            | 25[0-5]                     # matches 250-255
    +            | \d{1,2}                     # matches 0-9, 00-99
    +        )\.){3})                          # 3 of the preceding stanzas
    +        ([0-1]\d{2}|2[0-4]\d|25[0-5]|\d{1,2})$     # final octet
    +    """,
    +        re.VERBOSE,
    +    )
    +
    +    try:
    +        return ip_rx.match(addr.strip())
    +    except AttributeError:
    +        # Value was not a string
    +        return False
    +
    +
    +def is_valid_hostname(hostname: str) -> bool:
    +    """Validate a host name.
    +
    +    Arguments:
    +        hostname: host name to validate.
    +
    +    Returns:
    +        True if is valid else False.
    +    """
    +    # Splunk IPv6 support.
    +    # https://docs.splunk.com/Documentation/Splunk/9.0.0/Admin/ConfigureSplunkforIPv6#Change_the_prioritization_of_IPv4_and_IPv6_communications
    +    if hostname == "[::1]":
    +        return True
    +
    +    if len(hostname) > 255:
    +        return False
    +    if hostname[-1:] == ".":
    +        hostname = hostname[:-1]
    +    allowed = re.compile(r"(?!-)(::)?[A-Z\d-]{1,63}(?<!-)$", re.IGNORECASE)
    +    return all(allowed.match(x) for x in hostname.split("."))
    +
    +
    +def is_valid_port(port: Union[str, int]) -> bool:
    +    """Validate a port.
    +
    +    Arguments:
    +        port: port to validate.
    +
    +    Returns:
    +        True if is valid else False.
    +    """
    +
    +    try:
    +        return 0 < int(port) <= 65535
    +    except ValueError:
    +        return False
    +
    +
    +def is_valid_scheme(scheme: str) -> bool:
    +    """Validate a scheme.
    +
    +    Arguments:
    +        scheme: scheme to validate.
    +
    +    Returns:
    +        True if is valid else False.
    +    """
    +
    +    return scheme.lower() in ("http", "https")
    +
    +
    +def validate_scheme_host_port(scheme: str, host: str, port: Union[str, int]):
    +    """Validates scheme, host and port.
    +
    +    Arguments:
    +        scheme: scheme to validate.
    +        host: hostname to validate.
    +        port: port to validate.
    +
    +    Raises:
    +        ValueError: if scheme, host or port are invalid.
    +    """
    +    if scheme is not None and not is_valid_scheme(scheme):
    +        raise ValueError("Invalid scheme")
    +    if host is not None and not is_valid_hostname(host):
    +        raise ValueError("Invalid host")
    +    if port is not None and not is_valid_port(port):
    +        raise ValueError("Invalid port")
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/orphan_process_monitor.py b/deployment-apps/metricator-for-nmon/lib/solnlib/orphan_process_monitor.py
    new file mode 100644
    index 0000000..348fa3d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/orphan_process_monitor.py
    @@ -0,0 +1,120 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""Orphan process monitor."""
    +
    +import os
    +import threading
    +import time
    +from typing import Callable
    +
    +__all__ = ["OrphanProcessChecker", "OrphanProcessMonitor"]
    +
    +
    +class OrphanProcessChecker:
    +    """Orphan process checker.
    +
    +    Only work for Linux platform. On Windows platform, is_orphan is
    +    always False and there is no need to do this monitoring on Windows.
    +    """
    +
    +    def __init__(self, callback: Callable = None):
    +        """Initializes OrphanProcessChecker.
    +
    +        Arguments:
    +            callback: (optional) Callback for orphan process.
    +        """
    +        if os.name == "nt":
    +            self._ppid = 0
    +        else:
    +            self._ppid = os.getppid()
    +        self._callback = callback
    +
    +    def is_orphan(self) -> bool:
    +        """Check process is orphan.
    +
    +        For windows platform just return False.
    +
    +        Returns:
    +            True for orphan process else False.
    +        """
    +
    +        if os.name == "nt":
    +            return False
    +        return self._ppid != os.getppid()
    +
    +    def check_orphan(self) -> bool:
    +        """Check if the process becomes orphan.
    +
    +        If the process becomes orphan then call callback function
    +        to handle properly.
    +
    +        Returns:
    +            True for orphan process else False.
    +        """
    +
    +        res = self.is_orphan()
    +        if res and self._callback:
    +            self._callback()
    +        return res
    +
    +
    +class OrphanProcessMonitor:
    +    """Orphan process monitor.
    +
    +    Check if process become orphan in background thread per interval and
    +    call callback if process become orphan.
    +    """
    +
    +    def __init__(self, callback: Callable, interval: int = 1):
    +        """Initializes OrphanProcessMonitor.
    +
    +        Arguments:
    +            callback: Callback for orphan process monitor.
    +            interval: (optional) Interval to monitor.
    +        """
    +        self._checker = OrphanProcessChecker(callback)
    +        self._thr = threading.Thread(target=self._do_monitor)
    +        self._thr.daemon = True
    +        self._started = False
    +        self._interval = interval
    +
    +    def start(self):
    +        """Start orphan process monitor."""
    +
    +        if self._started:
    +            return
    +        self._started = True
    +
    +        self._thr.start()
    +
    +    def stop(self):
    +        """Stop orphan process monitor."""
    +
    +        joinable = self._started
    +        self._started = False
    +        if joinable:
    +            self._thr.join(timeout=1)
    +
    +    def _do_monitor(self):
    +        while self._started:
    +            if self._checker.check_orphan():
    +                break
    +
    +            for _ in range(self._interval):
    +                if not self._started:
    +                    break
    +                time.sleep(1)
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/pattern.py b/deployment-apps/metricator-for-nmon/lib/solnlib/pattern.py
    new file mode 100644
    index 0000000..1e16492
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/pattern.py
    @@ -0,0 +1,40 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module provides some common used patterns."""
    +
    +__all__ = ["Singleton"]
    +
    +
    +class Singleton(type):
    +    """Singleton meta class.
    +
    +    Examples:
    +       >>> class Test(object):
    +       >>>     __metaclass__ = Singleton
    +       >>>
    +       >>>     def __init__(self):
    +       >>>         pass
    +    """
    +
    +    def __init__(cls, name, bases, attrs):
    +        super().__init__(name, bases, attrs)
    +        cls._instance = None
    +
    +    def __call__(cls, *args, **kwargs):
    +        if cls._instance is None:
    +            cls._instance = super().__call__(*args, **kwargs)
    +        return cls._instance
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/server_info.py b/deployment-apps/metricator-for-nmon/lib/solnlib/server_info.py
    new file mode 100644
    index 0000000..b0e3633
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/server_info.py
    @@ -0,0 +1,265 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module contains Splunk server info related functionalities."""
    +
    +import json
    +from typing import Any, Dict, Optional
    +
    +from splunklib import binding
    +
    +from solnlib import splunk_rest_client as rest_client
    +from solnlib import utils
    +
    +__all__ = ["ServerInfo", "ServerInfoException"]
    +
    +
    +class ServerInfoException(Exception):
    +    """Exception raised by ServerInfo class."""
    +
    +    pass
    +
    +
    +class ServerInfo:
    +    """This class is a wrapper of Splunk server info."""
    +
    +    SHC_MEMBER_ENDPOINT = "/services/shcluster/member/members"
    +    SHC_CAPTAIN_INFO_ENDPOINT = "/services/shcluster/captain/info"
    +
    +    def __init__(
    +        self,
    +        session_key: str,
    +        scheme: Optional[str] = None,
    +        host: Optional[str] = None,
    +        port: Optional[int] = None,
    +        **context: Any
    +    ):
    +        """Initializes ServerInfo.
    +
    +        Arguments:
    +            session_key: Splunk access token.
    +            scheme: The access scheme, default is None.
    +            host: The host name, default is None.
    +            port: The port number, default is None.
    +            context: Other configurations for Splunk rest client.
    +        """
    +        self._rest_client = rest_client.SplunkRestClient(
    +            session_key, "-", scheme=scheme, host=host, port=port, **context
    +        )
    +
    +    @classmethod
    +    def from_server_uri(
    +        cls, server_uri: str, session_key: str, **context: Any
    +    ) -> "ServerInfo":
    +        """Creates ServerInfo class using server_uri and session_key.
    +
    +        Note: splunktalib uses these parameters to create it's ServerInfo class,
    +        so this method should ease the transition from splunktalib to solnlib.
    +
    +        Arguments:
    +            server_uri: splunkd URI.
    +            session_key: Splunk access token.
    +            context: Other configurations for Splunk rest client.
    +
    +        Returns:
    +            An instance of `ServerInfo`.
    +
    +        Raises:
    +            ValueError: server_uri is in the wrong format.
    +        """
    +        scheme, host, port = utils.extract_http_scheme_host_port(server_uri)
    +        return ServerInfo(
    +            session_key,
    +            scheme=scheme,
    +            host=host,
    +            port=port,
    +            **context,
    +        )
    +
    +    def to_dict(self) -> Dict:
    +        """Returns server information in a form dictionary.
    +
    +        Note: This method is implemented here to have compatibility with splunktalib's
    +        analogue.
    +
    +        Returns:
    +            Server information in a dictionary format.
    +        """
    +        return self._server_info()
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def _server_info(self):
    +        return self._rest_client.info
    +
    +    @property
    +    def server_name(self) -> str:
    +        """Get server name.
    +
    +        Returns:
    +            Server name.
    +        """
    +        return self._server_info()["serverName"]
    +
    +    @property
    +    def guid(self) -> str:
    +        """Get guid for the server.
    +
    +        Returns:
    +            Server GUID.
    +        """
    +        return self._server_info()["guid"]
    +
    +    @property
    +    def version(self) -> str:
    +        """Get Splunk server version.
    +
    +        Returns:
    +            Splunk version.
    +        """
    +        return self._server_info()["version"]
    +
    +    def is_captain(self) -> bool:
    +        """Check if this server is SHC captain.
    +
    +        Note during a rolling start of SH members, the captain may be changed
    +        from machine to machine. To avoid the race condition, client may need
    +        do necessary sleep and then poll `is_captain_ready() == True` and then
    +        check `is_captain()`. See `is_captain_ready()` for more details.
    +
    +        Returns:
    +            True if this server is SHC captain else False.
    +        """
    +
    +        return "shc_captain" in self._server_info()["server_roles"]
    +
    +    def is_cloud_instance(self) -> bool:
    +        """Check if this server is a cloud instance.
    +
    +        Returns:
    +            True if this server is a cloud instance else False.
    +        """
    +
    +        try:
    +            return self._server_info()["instance_type"] == "cloud"
    +        except KeyError:
    +            return False
    +
    +    def is_search_head(self) -> bool:
    +        """Check if this server is a search head.
    +
    +        Returns:
    +            True if this server is a search head else False.
    +        """
    +
    +        server_info = self._server_info()
    +        for sh in ("search_head", "cluster_search_head"):
    +            if sh in server_info["server_roles"]:
    +                return True
    +
    +        return False
    +
    +    def is_shc_member(self) -> bool:
    +        """Check if this server is a SHC member.
    +
    +        Returns:
    +            True if this server is a SHC member else False.
    +        """
    +
    +        server_info = self._server_info()
    +        for sh in ("shc_member", "shc_captain"):
    +            if sh in server_info["server_roles"]:
    +                return True
    +
    +        return False
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def get_shc_members(self) -> list:
    +        """Get SHC members.
    +
    +        Raises:
    +            ServerInfoException: If this server has no SHC members.
    +
    +        Returns:
    +            List of SHC members [(label, peer_scheme_host_port) ...].
    +        """
    +        try:
    +            content = self._rest_client.get(
    +                self.SHC_MEMBER_ENDPOINT, output_mode="json"
    +            ).body.read()
    +        except binding.HTTPError as e:
    +            if e.status != 404 and e.status != 503:
    +                raise
    +
    +            raise ServerInfoException(
    +                "This server is not a SHC member and has no SHC members."
    +            )
    +
    +        members = []
    +        for member in json.loads(content)["entry"]:
    +            content = member["content"]
    +            members.append((content["label"], content["peer_scheme_host_port"]))
    +
    +        return members
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def is_captain_ready(self) -> bool:
    +        """Check if captain is ready.
    +
    +        Client usually first polls this function until captain is ready
    +        and then call is_captain to detect current captain machine
    +
    +        Returns:
    +            True if captain is ready else False.
    +
    +        Examples:
    +            >>> from solnlib import server_info
    +            >>> serverinfo = server_info.ServerInfo(session_key)
    +            >>> while 1:
    +            >>>    if serverinfo.is_captain_ready():
    +            >>>        break
    +            >>>    time.sleep(2)
    +            >>>
    +            >>> # If do_stuff can only be executed in SH captain
    +            >>> if serverinfo.is_captain():
    +            >>>    do_stuff()
    +        """
    +
    +        cap_info = self.captain_info()
    +        return utils.is_true(cap_info["service_ready_flag"]) and utils.is_false(
    +            cap_info["maintenance_mode"]
    +        )
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def captain_info(self) -> dict:
    +        """Get captain information.
    +
    +        Raises:
    +            ServerInfoException: If there is SHC is not enabled.
    +
    +        Returns:
    +            Captain information.
    +        """
    +
    +        try:
    +            content = self._rest_client.get(
    +                self.SHC_CAPTAIN_INFO_ENDPOINT, output_mode="json"
    +            ).body.read()
    +        except binding.HTTPError as e:
    +            if e.status == 503 and "not available" in str(e):
    +                raise ServerInfoException(str(e))
    +            raise
    +
    +        return json.loads(content)["entry"][0]["content"]
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/splunk_rest_client.py b/deployment-apps/metricator-for-nmon/lib/solnlib/splunk_rest_client.py
    new file mode 100644
    index 0000000..0ed6fa0
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/splunk_rest_client.py
    @@ -0,0 +1,230 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module proxy all REST call to splunklib SDK, it handles proxy, certs
    +etc in this centralized location.
    +
    +All clients should use SplunkRestProxy to do REST call instead of
    +calling splunklib SDK directly in business logic code.
    +"""
    +
    +import logging
    +import os
    +import traceback
    +from io import BytesIO
    +from urllib.parse import quote
    +
    +from splunklib import binding, client
    +
    +from .net_utils import validate_scheme_host_port
    +from .splunkenv import get_splunkd_access_info
    +
    +__all__ = ["SplunkRestClient"]
    +
    +
    +def _get_proxy_info(context):
    +    if not context.get("proxy_hostname") or not context.get("proxy_port"):
    +        return None
    +
    +    user_pass = ""
    +    if context.get("proxy_username") and context.get("proxy_password"):
    +        username = quote(context["proxy_username"], safe="")
    +        password = quote(context["proxy_password"], safe="")
    +        user_pass = f"{username}:{password}@"
    +
    +    proxy = "http://{user_pass}{host}:{port}".format(
    +        user_pass=user_pass, host=context["proxy_hostname"], port=context["proxy_port"]
    +    )
    +    proxies = {
    +        "http": proxy,
    +        "https": proxy,
    +    }
    +    return proxies
    +
    +
    +def _request_handler(context):
    +    """
    +    :param context: Http connection context can contain the following
    +        key/values: {
    +        'proxy_hostname': string,
    +        'proxy_port': int,
    +        'proxy_username': string,
    +        'proxy_password': string,
    +        'key_file': string,
    +        'cert_file': string
    +        'pool_connections', int,
    +        'pool_maxsize', int,
    +        }
    +    :type content: dict
    +    """
    +
    +    try:
    +        import requests
    +    except ImportError:
    +        # FIXME proxy ?
    +        return binding.handler(
    +            key_file=context.get("key_file"), cert_file=context.get("cert_file")
    +        )
    +
    +    try:
    +        requests.urllib3.disable_warnings()
    +    except AttributeError:
    +        pass
    +
    +    proxies = _get_proxy_info(context)
    +    verify = context.get("verify", False)
    +
    +    if context.get("key_file") and context.get("cert_file"):
    +        # cert = ('/path/client.cert', '/path/client.key')
    +        cert = context["key_file"], context["cert_file"]
    +    elif context.get("cert_file"):
    +        cert = context["cert_file"]
    +    else:
    +        cert = None
    +
    +    if context.get("pool_connections", 0):
    +        logging.info("Use HTTP connection pooling")
    +        session = requests.Session()
    +        adapter = requests.adapters.HTTPAdapter(
    +            pool_connections=context.get("pool_connections", 10),
    +            pool_maxsize=context.get("pool_maxsize", 10),
    +        )
    +        session.mount("https://", adapter)
    +        req_func = session.request
    +    else:
    +        req_func = requests.request
    +
    +    def request(url, message, **kwargs):
    +        """
    +        :param url: URL
    +        :type url: string
    +        :param message: Can contain following key/values: {
    +            'method': 'GET' or 'DELETE', or 'PUT' or 'POST'
    +            'headers': [[key, value], [key, value], ...],
    +            'body': string
    +            }
    +        :type message: dict
    +        """
    +
    +        body = message.get("body")
    +        headers = {
    +            "User-Agent": "curl",
    +            "Accept": "*/*",
    +            "Connection": "Keep-Alive",
    +        }
    +
    +        if body:
    +            headers["Content-Length"] = str(len(body))
    +
    +        for key, value in message["headers"]:
    +            headers[key] = value
    +
    +        method = message.get("method", "GET")
    +
    +        try:
    +            resp = req_func(
    +                method,
    +                url,
    +                data=body,
    +                headers=headers,
    +                stream=False,
    +                verify=verify,
    +                proxies=proxies,
    +                cert=cert,
    +                **kwargs,
    +            )
    +        except Exception:
    +            logging.error(
    +                "Failed to issue http request=%s to url=%s, error=%s",
    +                method,
    +                url,
    +                traceback.format_exc(),
    +            )
    +            raise
    +
    +        return {
    +            "status": resp.status_code,
    +            "reason": resp.reason,
    +            "headers": dict(resp.headers),
    +            "body": BytesIO(resp.content),
    +        }
    +
    +    return request
    +
    +
    +class SplunkRestClient(client.Service):
    +    """Splunk REST client."""
    +
    +    def __init__(
    +        self,
    +        session_key: str,
    +        app: str,
    +        owner: str = "nobody",
    +        scheme: str = None,
    +        host: str = None,
    +        port: int = None,
    +        **context: dict,
    +    ):
    +        """Initializes SplunkRestClient.
    +
    +        Arguments `scheme`, `host` and `port` are optional in the Splunk
    +        environment (when environment variable SPLUNK_HOME is set). In this
    +        situation `get_splunkd_access_info` will be used to set `scheme`,
    +        `host` and `port`. In case of using `SplunkRestClient` outside of
    +        Splunk environment - `scheme`, `host` and `port` should be provided.
    +
    +        Arguments:
    +            session_key: Splunk access token.
    +            app: App name of namespace.
    +            owner: Owner of namespace, default is `nobody`.
    +            scheme: The access scheme, default is None.
    +            host: The host name, default is None.
    +            port: The port number, default is None.
    +            context: Other configurations, it can contain `proxy_hostname`,
    +                `proxy_port`, `proxy_username`, `proxy_password`, then proxy will
    +                be accounted and setup, all REST APIs to splunkd will be through
    +                the proxy. If `context` contains `key_file`, `cert_file`, then
    +                certification will be accounted and setup, all REST APIs to splunkd
    +                will use certification. If `context` contains `pool_connections`,
    +                `pool_maxsize`, then HTTP connection will be pooled.
    +
    +        Raises:
    +            ValueError: if scheme, host or port are invalid.
    +        """
    +        # Only do splunkd URI discovery in SPLUNK env (SPLUNK_HOME is set).
    +        if not all([scheme, host, port]) and os.environ.get("SPLUNK_HOME"):
    +            scheme, host, port = get_splunkd_access_info()
    +        if os.environ.get("SPLUNK_HOME") is None:
    +            if not all([scheme, host, port]):
    +                raise ValueError(
    +                    "scheme, host, port should be provided outside of Splunk environment"
    +                )
    +
    +        validate_scheme_host_port(scheme, host, port)
    +        if host == "[::1]":
    +            host = "::1"
    +
    +        handler = _request_handler(context)
    +        super().__init__(
    +            handler=handler,
    +            scheme=scheme,
    +            host=host,
    +            port=port,
    +            token=session_key,
    +            app=app,
    +            owner=owner,
    +            autologin=True,
    +        )
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/splunkenv.py b/deployment-apps/metricator-for-nmon/lib/solnlib/splunkenv.py
    new file mode 100644
    index 0000000..78ba582
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/splunkenv.py
    @@ -0,0 +1,292 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""Splunk platform related utilities."""
    +
    +import os
    +import os.path as op
    +import socket
    +import subprocess
    +from configparser import ConfigParser
    +from io import StringIO
    +from typing import List, Optional, Tuple, Union
    +
    +from .utils import is_true
    +
    +__all__ = [
    +    "make_splunkhome_path",
    +    "get_splunk_host_info",
    +    "get_splunk_bin",
    +    "get_splunkd_access_info",
    +    "get_splunkd_uri",
    +    "get_conf_key_value",
    +    "get_conf_stanza",
    +    "get_conf_stanzas",
    +]
    +
    +ETC_LEAF = "etc"
    +
    +# See validateSearchHeadPooling() in src/libbundle/ConfSettings.cpp
    +on_shared_storage = [
    +    os.path.join(ETC_LEAF, "apps"),
    +    os.path.join(ETC_LEAF, "users"),
    +    os.path.join("var", "run", "splunk", "dispatch"),
    +    os.path.join("var", "run", "splunk", "srtemp"),
    +    os.path.join("var", "run", "splunk", "rss"),
    +    os.path.join("var", "run", "splunk", "scheduler"),
    +    os.path.join("var", "run", "splunk", "lookup_tmp"),
    +]
    +
    +
    +def _splunk_home():
    +    return os.path.normpath(os.environ["SPLUNK_HOME"])
    +
    +
    +def _splunk_etc():
    +    try:
    +        result = os.environ["SPLUNK_ETC"]
    +    except KeyError:
    +        result = op.join(_splunk_home(), ETC_LEAF)
    +
    +    return os.path.normpath(result)
    +
    +
    +def _get_shared_storage() -> Optional[str]:
    +    """Get splunk shared storage name.
    +
    +    Returns:
    +        Splunk shared storage name.
    +    """
    +
    +    try:
    +        state = get_conf_key_value("server", "pooling", "state")
    +        storage = get_conf_key_value("server", "pooling", "storage")
    +    except KeyError:
    +        state = "disabled"
    +        storage = None
    +
    +    if state == "enabled" and storage:
    +        return storage
    +
    +    return None
    +
    +
    +# Verify path prefix and return true if both paths have drives
    +def _verify_path_prefix(path, start):
    +    path_drive = os.path.splitdrive(path)[0]
    +    start_drive = os.path.splitdrive(start)[0]
    +    return len(path_drive) == len(start_drive)
    +
    +
    +def make_splunkhome_path(parts: Union[List, Tuple]) -> str:
    +    """Construct absolute path by $SPLUNK_HOME and `parts`.
    +
    +    Concatenate $SPLUNK_HOME and `parts` to an absolute path.
    +    For example, `parts` is ['etc', 'apps', 'Splunk_TA_test'],
    +    the return path will be $SPLUNK_HOME/etc/apps/Splunk_TA_test.
    +    Note: this function assumed SPLUNK_HOME is in environment varialbes.
    +
    +    Arguments:
    +        parts: Path parts.
    +
    +    Returns:
    +        Absolute path.
    +
    +    Raises:
    +        ValueError: Escape from intended parent directories.
    +    """
    +
    +    relpath = os.path.normpath(os.path.join(*parts))
    +
    +    basepath = None
    +    shared_storage = _get_shared_storage()
    +    if shared_storage:
    +        for candidate in on_shared_storage:
    +            # SPL-100508 On windows if the path is missing the drive letter,
    +            # construct fullpath manually and call relpath
    +            if os.name == "nt" and not _verify_path_prefix(relpath, candidate):
    +                break
    +
    +            if os.path.relpath(relpath, candidate)[0:2] != "..":
    +                basepath = shared_storage
    +                break
    +
    +    if basepath is None:
    +        etc_with_trailing_sep = os.path.join(ETC_LEAF, "")
    +        if relpath == ETC_LEAF or relpath.startswith(etc_with_trailing_sep):
    +            # Redirect $SPLUNK_HOME/etc to $SPLUNK_ETC.
    +            basepath = _splunk_etc()
    +            # Remove leading etc (and path separator, if present). Note: when
    +            # emitting $SPLUNK_ETC exactly, with no additional path parts, we
    +            # set <relpath> to the empty string.
    +            relpath = relpath[4:]
    +        else:
    +            basepath = _splunk_home()
    +
    +    fullpath = os.path.normpath(os.path.join(basepath, relpath))
    +
    +    # Check that we haven't escaped from intended parent directories.
    +    if os.path.relpath(fullpath, basepath)[0:2] == "..":
    +        raise ValueError(
    +            f'Illegal escape from parent directory "{basepath}": {fullpath}'
    +        )
    +    return fullpath
    +
    +
    +def get_splunk_host_info() -> Tuple:
    +    """Get splunk host info.
    +
    +    Returns:
    +        Tuple of (server_name, host_name).
    +    """
    +
    +    server_name = get_conf_key_value("server", "general", "serverName")
    +    host_name = socket.gethostname()
    +    return server_name, host_name
    +
    +
    +def get_splunk_bin() -> str:
    +    """Get absolute path of splunk CLI.
    +
    +    Returns:
    +        Absolute path of splunk CLI.
    +    """
    +
    +    if os.name == "nt":
    +        splunk_bin = "splunk.exe"
    +    else:
    +        splunk_bin = "splunk"
    +    return make_splunkhome_path(("bin", splunk_bin))
    +
    +
    +def get_splunkd_access_info() -> Tuple[str, str, int]:
    +    """Get splunkd server access info.
    +
    +    Returns:
    +        Tuple of (scheme, host, port).
    +    """
    +
    +    if is_true(get_conf_key_value("server", "sslConfig", "enableSplunkdSSL")):
    +        scheme = "https"
    +    else:
    +        scheme = "http"
    +
    +    host_port = get_conf_key_value("web", "settings", "mgmtHostPort")
    +    host_port = host_port.strip()
    +    host_port_split_parts = host_port.split(":")
    +    host = ":".join(host_port_split_parts[:-1])
    +    port = int(host_port_split_parts[-1])
    +
    +    if "SPLUNK_BINDIP" in os.environ:
    +        bindip = os.environ["SPLUNK_BINDIP"]
    +        port_idx = bindip.rfind(":")
    +        host = bindip[:port_idx] if port_idx > 0 else bindip
    +
    +    return scheme, host, port
    +
    +
    +def get_splunkd_uri() -> str:
    +    """Get splunkd uri.
    +
    +    Returns:
    +        Splunkd uri.
    +    """
    +
    +    if os.environ.get("SPLUNKD_URI"):
    +        return os.environ["SPLUNKD_URI"]
    +
    +    scheme, host, port = get_splunkd_access_info()
    +    return f"{scheme}://{host}:{port}"
    +
    +
    +def get_conf_key_value(conf_name: str, stanza: str, key: str) -> Union[str, List, dict]:
    +    """Get value of `key` of `stanza` in `conf_name`.
    +
    +    Arguments:
    +        conf_name: Config file.
    +        stanza: Stanza name.
    +        key: Key name.
    +
    +    Returns:
    +        Config value.
    +
    +    Raises:
    +        KeyError: If `stanza` or `key` doesn't exist.
    +    """
    +
    +    stanzas = get_conf_stanzas(conf_name)
    +    return stanzas[stanza][key]
    +
    +
    +def get_conf_stanza(conf_name: str, stanza: str) -> dict:
    +    """Get `stanza` in `conf_name`.
    +
    +    Arguments:
    +        conf_name: Config file.
    +        stanza: Stanza name.
    +
    +    Returns:
    +        Config stanza.
    +
    +    Raises:
    +         KeyError: If stanza doesn't exist.
    +    """
    +
    +    stanzas = get_conf_stanzas(conf_name)
    +    return stanzas[stanza]
    +
    +
    +def get_conf_stanzas(conf_name: str) -> dict:
    +    """Get stanzas of `conf_name`
    +
    +    Arguments:
    +        conf_name: Config file.
    +
    +    Returns:
    +        Config stanzas.
    +
    +    Examples:
    +       >>> stanzas = get_conf_stanzas('server')
    +       >>> return: {'serverName': 'testServer', 'sessionTimeout': '1h', ...}
    +    """
    +
    +    if conf_name.endswith(".conf"):
    +        conf_name = conf_name[:-5]
    +
    +    # TODO: dynamically calculate SPLUNK_HOME
    +    btool_cli = [
    +        op.join(os.environ["SPLUNK_HOME"], "bin", "splunk"),
    +        "cmd",
    +        "btool",
    +        conf_name,
    +        "list",
    +    ]
    +    p = subprocess.Popen(  # nosemgrep: python.lang.security.audit.dangerous-subprocess-use.dangerous-subprocess-use
    +        btool_cli, stdout=subprocess.PIPE, stderr=subprocess.PIPE
    +    )
    +    out, _ = p.communicate()
    +
    +    if isinstance(out, bytes):
    +        out = out.decode()
    +
    +    parser = ConfigParser(**{"strict": False})
    +    parser.optionxform = str
    +    parser.readfp(StringIO(out))
    +
    +    out = {}
    +    for section in parser.sections():
    +        out[section] = {item[0]: item[1] for item in parser.items(section, raw=True)}
    +    return out
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/time_parser.py b/deployment-apps/metricator-for-nmon/lib/solnlib/time_parser.py
    new file mode 100644
    index 0000000..760d30b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/time_parser.py
    @@ -0,0 +1,151 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""This module provides interfaces to parse and convert timestamp."""
    +
    +import datetime
    +import json
    +from typing import Any
    +
    +from splunklib import binding
    +
    +from . import splunk_rest_client as rest_client
    +from .utils import retry
    +
    +__all__ = ["TimeParser"]
    +
    +
    +class InvalidTimeFormatException(Exception):
    +    """Exception for invalid time format."""
    +
    +    pass
    +
    +
    +class TimeParser:
    +    """Datetime parser.
    +
    +    Use splunkd rest to parse datetime.
    +
    +    Examples:
    +       >>> from solnlib import time_parser
    +       >>> tp = time_parser.TimeParser(session_key)
    +       >>> tp.to_seconds('2011-07-06T21:54:23.000-07:00')
    +       >>> tp.to_utc('2011-07-06T21:54:23.000-07:00')
    +       >>> tp.to_local('2011-07-06T21:54:23.000-07:00')
    +    """
    +
    +    URL = "/services/search/timeparser"
    +
    +    def __init__(
    +        self,
    +        session_key: str,
    +        scheme: str = None,
    +        host: str = None,
    +        port: int = None,
    +        **context: Any,
    +    ):
    +        """Initializes TimeParser.
    +
    +        Arguments:
    +            session_key: Splunk access token.
    +            scheme: (optional) The access scheme, default is None.
    +            host: (optional) The host name, default is None.
    +            port: (optional) The port number, default is None.
    +            context: Other configurations for Splunk rest client.
    +
    +        Raises:
    +            ValueError: if scheme, host or port are invalid.
    +        """
    +        self._rest_client = rest_client.SplunkRestClient(
    +            session_key, "-", scheme=scheme, host=host, port=port, **context
    +        )
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def to_seconds(self, time_str: str) -> float:
    +        """Parse `time_str` and convert to seconds since epoch.
    +
    +        Arguments:
    +            time_str: ISO8601 format timestamp, example: 2011-07-06T21:54:23.000-07:00.
    +
    +        Raises:
    +            binding.HTTPError: rest client returns an exception (everything
    +                else than 400 code).
    +            InvalidTimeFormatException: when time format is invalid (rest
    +                client returns 400 code).
    +
    +        Returns:
    +            Seconds since epoch.
    +        """
    +
    +        try:
    +            response = self._rest_client.get(
    +                self.URL, output_mode="json", time=time_str, output_time_format="%s"
    +            ).body.read()
    +        except binding.HTTPError as e:
    +            if e.status != 400:
    +                raise
    +
    +            raise InvalidTimeFormatException(f"Invalid time format: {time_str}.")
    +
    +        seconds = json.loads(response)[time_str]
    +        return float(seconds)
    +
    +    def to_utc(self, time_str: str) -> datetime.datetime:
    +        """Parse `time_str` and convert to UTC timestamp.
    +
    +        Arguments:
    +            time_str: ISO8601 format timestamp, example: 2011-07-06T21:54:23.000-07:00.
    +
    +        Raises:
    +            binding.HTTPError: rest client returns an exception (everything
    +                else than 400 code).
    +            InvalidTimeFormatException: when time format is invalid (rest
    +                client returns 400 code).
    +
    +        Returns:
    +            UTC timestamp.
    +        """
    +
    +        return datetime.datetime.utcfromtimestamp(self.to_seconds(time_str))
    +
    +    @retry(exceptions=[binding.HTTPError])
    +    def to_local(self, time_str: str) -> str:
    +        """Parse `time_str` and convert to local timestamp.
    +
    +        Arguments:
    +            time_str: ISO8601 format timestamp, example: 2011-07-06T21:54:23.000-07:00.
    +
    +        Raises:
    +            binding.HTTPError: rest client returns an exception (everything
    +                else than 400 code).
    +            InvalidTimeFormatException: when time format is invalid (rest
    +                client returns 400 code).
    +
    +        Returns:
    +            Local timestamp in ISO8601 format.
    +        """
    +
    +        try:
    +            response = self._rest_client.get(
    +                self.URL, output_mode="json", time=time_str
    +            ).body.read()
    +        except binding.HTTPError as e:
    +            if e.status != 400:
    +                raise
    +
    +            raise InvalidTimeFormatException(f"Invalid time format: {time_str}.")
    +
    +        return json.loads(response)[time_str]
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/timer_queue.py b/deployment-apps/metricator-for-nmon/lib/solnlib/timer_queue.py
    new file mode 100644
    index 0000000..68103bf
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/timer_queue.py
    @@ -0,0 +1,324 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""A simple thread safe timer queue implementation which has O(logn) time
    +complexity."""
    +import logging
    +import queue as Queue
    +import threading
    +import traceback
    +from time import time
    +from typing import Callable, List, Tuple
    +
    +import sortedcontainers as sc
    +
    +__all__ = ["Timer", "TimerQueueStruct", "TimerQueue"]
    +
    +
    +class Timer:
    +    """Timer wraps the callback and timestamp related attributes."""
    +
    +    _ident = 0
    +    _lock = threading.Lock()
    +
    +    def __init__(self, callback: Callable, when: int, interval: int, ident: int = None):
    +        """Initializes Timer.
    +
    +        Arguments:
    +            callback: Arbitrary callable object.
    +            when: The first expiration time, seconds since epoch.
    +            interval: Timer interval, if equals 0, one time timer, otherwise
    +                the timer will be periodically executed.
    +            ident: (optional) Timer identity.
    +        """
    +        self._callback = callback
    +        self.when = when
    +        self.interval = interval
    +
    +        if ident is not None:
    +            self.ident = ident
    +        else:
    +            with Timer._lock:
    +                self.ident = Timer._ident + 1
    +                Timer._ident = Timer._ident + 1
    +
    +    def update_expiration(self):
    +        self.when += self.interval
    +
    +    def __hash__(self):
    +        return hash(self.ident)
    +
    +    def __eq__(self, other):
    +        return isinstance(other, Timer) and (self.ident == other.ident)
    +
    +    def __lt__(self, other):
    +        return (self.when, self.ident) < (other.when, other.ident)
    +
    +    def __le__(self, other):
    +        return (self.when, self.ident) <= (other.when, other.ident)
    +
    +    def __gt__(self, other):
    +        return (self.when, self.ident) > (other.when, other.ident)
    +
    +    def __ge__(self, other):
    +        return (self.when, self.ident) >= (other.when, other.ident)
    +
    +    def __call__(self):
    +        self._callback()
    +
    +
    +TEARDOWN_SENTINEL = None
    +
    +
    +class TimerQueueStruct:
    +    """The underlying data structure for TimerQueue."""
    +
    +    def __init__(self):
    +        self._timers = sc.SortedSet()
    +        self._cancelling_timers = {}
    +
    +    def add_timer(
    +        self, callback: Callable, when: int, interval: int, ident: int
    +    ) -> Timer:
    +        """Add timer to the data structure.
    +
    +        Arguments:
    +            callback: Arbitrary callable object.
    +            when: The first expiration time, seconds since epoch.
    +            interval: Timer interval, if equals 0, one time timer, otherwise
    +                the timer will be periodically executed
    +            ident: (optional) Timer identity.
    +
    +        Returns:
    +            A timer object which should not be manipulated directly by
    +                clients. Used to delete/update the timer.
    +        """
    +
    +        timer = Timer(callback, when, interval, ident)
    +        self._timers.add(timer)
    +        return timer
    +
    +    def remove_timer(self, timer: Timer):
    +        """Remove timer from data structure.
    +
    +        Arguments:
    +            timer: Timer object which is returned by ``TimerQueueStruct.add_timer``.
    +        """
    +
    +        try:
    +            self._timers.remove(timer)
    +        except ValueError:
    +            logging.info(
    +                "Timer=%s is not in queue, move it to cancelling " "list", timer.ident
    +            )
    +        else:
    +            self._cancelling_timers[timer.ident] = timer
    +
    +    def get_expired_timers(self) -> Tuple:
    +        """Get a list of expired timers.
    +
    +        Returns:
    +            A tuple of ``Timer``, empty list if there is no expired timers.
    +        """
    +
    +        next_expired_time = 0
    +        now = time()
    +        expired_timers = []
    +        for timer in self._timers:
    +            if timer.when <= now:
    +                expired_timers.append(timer)
    +
    +        if expired_timers:
    +            del self._timers[: len(expired_timers)]
    +
    +        if self._timers:
    +            next_expired_time = self._timers[0].when
    +        return next_expired_time, expired_timers
    +
    +    def reset_timers(self, expired_timers: List[Timer]) -> bool:
    +        """Re-add the expired periodical timers to data structure for next
    +        round scheduling.
    +
    +        Arguments:
    +            expired_timers: List of expired timers.
    +
    +        Returns:
    +            True if there are timers added, False otherwise.
    +        """
    +
    +        has_new_timer = False
    +        cancelling_timers = self._cancelling_timers
    +        for timer in expired_timers:
    +            if timer.ident in cancelling_timers:
    +                continue
    +            elif timer.interval:
    +                # Repeated timer
    +                timer.update_expiration()
    +                self._timers.add(timer)
    +                has_new_timer = True
    +        cancelling_timers.clear()
    +        return has_new_timer
    +
    +    def check_and_execute(self) -> float:
    +        """Get expired timers and execute callbacks for the timers.
    +
    +        Returns:
    +            Duration of next expired timer.
    +        """
    +
    +        (next_expired_time, expired_timers) = self.get_expired_timers()
    +        for timer in expired_timers:
    +            try:
    +                timer()
    +            except Exception:
    +                logging.error(traceback.format_exc())
    +
    +        self.reset_timers(expired_timers)
    +        return _calc_sleep_time(next_expired_time)
    +
    +
    +class TimerQueue:
    +    r"""A simple timer queue implementation.
    +
    +    It runs a separate thread to handle timers Note: to effectively use this
    +    timer queue, the timer callback should be short, otherwise it will cause
    +    other timers's delay execution. A typical use scenario in production is
    +    that the timers are just a simple functions which inject themselvies to
    +    a task queue and then they are picked up by a threading/process pool to
    +    execute, as shows below:
    +
    +        Timers --enqueue---> TimerQueue --------expiration-----------
    +                                                                    |
    +                                                                    |
    +                                                                   \|/
    +        Threading/Process Pool <---- TaskQueue <--enqueue-- Timers' callback (nonblocking)
    +
    +    Examples:
    +           >>> from solnlib import timer_queue
    +           >>> tq = timer_queue.TimerQueue()
    +           >>> tq.start()
    +           >>> t = tq.add_timer(my_func, time.time(), 10)
    +           >>> # do other stuff
    +           >>> tq.stop()
    +    """
    +
    +    def __init__(self):
    +        self._timers = TimerQueueStruct()
    +        self._lock = threading.Lock()
    +        self._wakeup_queue = Queue.Queue()
    +        self._thr = threading.Thread(target=self._check_and_execute)
    +        self._thr.daemon = True
    +        self._started = False
    +
    +    def start(self):
    +        """Start the timer queue."""
    +
    +        if self._started:
    +            return
    +        self._started = True
    +
    +        self._thr.start()
    +        logging.info("TimerQueue started.")
    +
    +    def stop(self):
    +        """Stop the timer queue."""
    +
    +        if not self._started:
    +            return
    +        self._started = True
    +
    +        self._wakeup(TEARDOWN_SENTINEL)
    +        self._thr.join()
    +
    +    def add_timer(
    +        self, callback: Callable, when: int, interval: int, ident: int = None
    +    ) -> Timer:
    +        """Add timer to the queue.
    +
    +        Arguments:
    +            callback: Arbitrary callable object.
    +            when: The first expiration time, seconds since epoch.
    +            interval: Timer interval, if equals 0, one time timer, otherwise
    +                the timer will be periodically executed
    +            ident: (optional) Timer identity.
    +
    +        Returns:
    +            A timer object which should not be manipulated directly by
    +                clients. Used to delete/update the timer.
    +        """
    +
    +        with self._lock:
    +            timer = self._timers.add_timer(callback, when, interval, ident)
    +        self._wakeup()
    +        return timer
    +
    +    def remove_timer(self, timer: Timer):
    +        """Remove timer from the queue.
    +
    +        Arguments:
    +            timer: Timer object to remove.
    +        """
    +
    +        with self._lock:
    +            self._timers.remove_timer(timer)
    +
    +    def _check_and_execute(self):
    +        wakeup_queue = self._wakeup_queue
    +        while 1:
    +            (next_expired_time, expired_timers) = self._get_expired_timers()
    +            for timer in expired_timers:
    +                try:
    +                    # Note, please make timer callback effective/short
    +                    timer()
    +                except Exception:
    +                    logging.error(traceback.format_exc())
    +
    +            self._reset_timers(expired_timers)
    +
    +            sleep_time = _calc_sleep_time(next_expired_time)
    +            try:
    +                wakeup = wakeup_queue.get(timeout=sleep_time)
    +                if wakeup is TEARDOWN_SENTINEL:
    +                    break
    +            except Queue.Empty:
    +                pass
    +        logging.info("TimerQueue stopped.")
    +
    +    def _get_expired_timers(self):
    +        with self._lock:
    +            return self._timers.get_expired_timers()
    +
    +    def _reset_timers(self, expired_timers):
    +        with self._lock:
    +            has_new_timer = self._timers.reset_timers(expired_timers)
    +
    +        if has_new_timer:
    +            self._wakeup()
    +
    +    def _wakeup(self, something="not_None"):
    +        self._wakeup_queue.put(something)
    +
    +
    +def _calc_sleep_time(next_expired_time):
    +    if next_expired_time:
    +        now = time()
    +        if now < next_expired_time:
    +            sleep_time = next_expired_time - now
    +        else:
    +            sleep_time = 0.1
    +    else:
    +        sleep_time = 1
    +    return sleep_time
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/user_access.py b/deployment-apps/metricator-for-nmon/lib/solnlib/user_access.py
    new file mode 100644
    index 0000000..61c1803
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/user_access.py
    @@ -0,0 +1,949 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""Splunk user access control related utilities."""
    +
    +import json
    +from typing import List, Optional
    +
    +from splunklib import binding
    +
    +from solnlib import _utils
    +from solnlib import splunk_rest_client as rest_client
    +from solnlib import utils
    +
    +__all__ = [
    +    "ObjectACLException",
    +    "ObjectACL",
    +    "ObjectACLManagerException",
    +    "ObjectACLManager",
    +    "AppCapabilityManagerException",
    +    "AppCapabilityManager",
    +    "UserAccessException",
    +    "check_user_access",
    +    "InvalidSessionKeyException",
    +    "get_current_username",
    +    "UserNotExistException",
    +    "get_user_capabilities",
    +    "user_is_capable",
    +    "get_user_roles",
    +]
    +
    +
    +class ObjectACLException(Exception):
    +    pass
    +
    +
    +class ObjectACL:
    +    """Object ACL record.
    +
    +    Examples:
    +       >>> from solnlib import user_access
    +       >>> obj_acl = user_access.ObjectACL(
    +       >>>    'test_collection',
    +       >>>    '9defa6f510d711e6be16a45e60e34295',
    +       >>>    'test_object',
    +       >>>    'Splunk_TA_test',
    +       >>>    'admin',
    +       >>>    {'read': ['*'], 'write': ['admin'], 'delete': ['admin']},
    +       >>>    False)
    +    """
    +
    +    OBJ_COLLECTION_KEY = "obj_collection"
    +    OBJ_ID_KEY = "obj_id"
    +    OBJ_TYPE_KEY = "obj_type"
    +    OBJ_APP_KEY = "obj_app"
    +    OBJ_OWNER_KEY = "obj_owner"
    +    OBJ_PERMS_KEY = "obj_perms"
    +    OBJ_PERMS_READ_KEY = "read"
    +    OBJ_PERMS_WRITE_KEY = "write"
    +    OBJ_PERMS_DELETE_KEY = "delete"
    +    OBJ_PERMS_ALLOW_ALL = "*"
    +    OBJ_SHARED_BY_INCLUSION_KEY = "obj_shared_by_inclusion"
    +
    +    def __init__(
    +        self,
    +        obj_collection: str,
    +        obj_id: str,
    +        obj_type: str,
    +        obj_app: str,
    +        obj_owner: str,
    +        obj_perms: dict,
    +        obj_shared_by_inclusion: bool,
    +    ):
    +        """Initializes ObjectACL.
    +
    +        Arguments:
    +            obj_collection: Collection where object currently stored.
    +            obj_id: ID of this object.
    +            obj_type: Type of this object.
    +            obj_app: App of this object.
    +            obj_owner: Owner of this object.
    +            obj_perms: Object perms, like: {'read': ['*'], 'write': ['admin'], 'delete': ['admin']}.
    +            obj_shared_by_inclusion: Flag of object is shared by inclusion.
    +        """
    +        self.obj_collection = obj_collection
    +        self.obj_id = obj_id
    +        self.obj_type = obj_type
    +        self.obj_app = obj_app
    +        self.obj_owner = obj_owner
    +        self._check_perms(obj_perms)
    +        self._obj_perms = obj_perms
    +        self.obj_shared_by_inclusion = obj_shared_by_inclusion
    +
    +    @classmethod
    +    def _check_perms(cls, obj_perms):
    +        if not isinstance(obj_perms, dict):
    +            raise ObjectACLException(
    +                "Invalid object acl perms type: %s, should be a dict." % type(obj_perms)
    +            )
    +
    +        if not (
    +            cls.OBJ_PERMS_READ_KEY in obj_perms
    +            and cls.OBJ_PERMS_WRITE_KEY in obj_perms
    +            and cls.OBJ_PERMS_DELETE_KEY in obj_perms
    +        ):
    +            raise ObjectACLException(
    +                "Invalid object acl perms: %s, "
    +                "should include read, write and delete perms." % obj_perms
    +            )
    +
    +    @property
    +    def obj_perms(self):
    +        return self._obj_perms
    +
    +    @obj_perms.setter
    +    def obj_perms(self, obj_perms):
    +        self._check_perms(obj_perms)
    +        self._obj_perms = obj_perms
    +
    +    @property
    +    def record(self) -> dict:
    +        """Get object acl record.
    +
    +        Returns: Object acl record, like:
    +
    +            {
    +                '_key': 'test_collection-1234',
    +                'obj_collection': 'test_collection',
    +                'obj_id': '1234',
    +                'obj_type': 'test_object',
    +                'obj_app': 'Splunk_TA_test',
    +                'obj_owner': 'admin',
    +                'obj_perms': {'read': ['*'], 'write': ['admin'], 'delete': ['admin']},
    +                'obj_shared_by_inclusion': True
    +            }
    +        """
    +
    +        return {
    +            "_key": self.generate_key(self.obj_collection, self.obj_id),
    +            self.OBJ_COLLECTION_KEY: self.obj_collection,
    +            self.OBJ_ID_KEY: self.obj_id,
    +            self.OBJ_TYPE_KEY: self.obj_type,
    +            self.OBJ_APP_KEY: self.obj_app,
    +            self.OBJ_OWNER_KEY: self.obj_owner,
    +            self.OBJ_PERMS_KEY: self._obj_perms,
    +            self.OBJ_SHARED_BY_INCLUSION_KEY: self.obj_shared_by_inclusion,
    +        }
    +
    +    @staticmethod
    +    def generate_key(obj_collection: str, obj_id: str) -> str:
    +        """Generate object acl record key.
    +
    +        Arguments:
    +            obj_collection: Collection where object currently stored.
    +            obj_id: ID of this object.
    +
    +        Returns:
    +            Object acl record key.
    +        """
    +
    +        return "{obj_collection}_{obj_id}".format(
    +            obj_collection=obj_collection, obj_id=obj_id
    +        )
    +
    +    @staticmethod
    +    def parse(obj_acl_record: dict) -> "ObjectACL":
    +        """Parse object acl record and construct a new `ObjectACL` object from
    +        it.
    +
    +        Arguments:
    +            obj_acl_record: Object acl record.
    +
    +        Returns:
    +            New `ObjectACL` object.
    +        """
    +
    +        return ObjectACL(
    +            obj_acl_record[ObjectACL.OBJ_COLLECTION_KEY],
    +            obj_acl_record[ObjectACL.OBJ_ID_KEY],
    +            obj_acl_record[ObjectACL.OBJ_TYPE_KEY],
    +            obj_acl_record[ObjectACL.OBJ_APP_KEY],
    +            obj_acl_record[ObjectACL.OBJ_OWNER_KEY],
    +            obj_acl_record[ObjectACL.OBJ_PERMS_KEY],
    +            obj_acl_record[ObjectACL.OBJ_SHARED_BY_INCLUSION_KEY],
    +        )
    +
    +    def merge(self, obj_acl: "ObjectACL"):
    +        """Merge current object perms with perms of `obj_acl`.
    +
    +        Arguments:
    +            obj_acl: Object acl to merge.
    +        """
    +
    +        for perm_key in self._obj_perms:
    +            self._obj_perms[perm_key] = list(
    +                set.union(
    +                    set(self._obj_perms[perm_key]), set(obj_acl._obj_perms[perm_key])
    +                )
    +            )
    +            if self.OBJ_PERMS_ALLOW_ALL in self._obj_perms[perm_key]:
    +                self._obj_perms[perm_key] = [self.OBJ_PERMS_ALLOW_ALL]
    +
    +    def __str__(self):
    +        return json.dumps(self.record)
    +
    +
    +class ObjectACLManagerException(Exception):
    +    """Exception for ObjectACLManager."""
    +
    +    pass
    +
    +
    +class ObjectACLNotExistException(Exception):
    +    """Exception for the situation when ACL does not exist."""
    +
    +    pass
    +
    +
    +class ObjectACLManager:
    +    """Object ACL manager.
    +
    +    Examples:
    +       >>> from solnlib import user_access
    +       >>> oaclm = user_access.ObjectACLManager(session_key,
    +                                                'Splunk_TA_test')
    +    """
    +
    +    def __init__(
    +        self,
    +        collection_name: str,
    +        session_key: str,
    +        app: str,
    +        owner: Optional[str] = "nobody",
    +        scheme: Optional[str] = None,
    +        host: Optional[str] = None,
    +        port: Optional[int] = None,
    +        **context: dict,
    +    ):
    +        """Initializes ObjectACLManager.
    +
    +        Arguments:
    +            collection_name: Collection name to store object ACL info.
    +            session_key: Splunk access token.
    +            app: App name of namespace.
    +            owner: (optional) Owner of namespace, default is `nobody`.
    +            scheme: (optional) The access scheme, default is None.
    +            host: (optional) The host name, default is None.
    +            port: (optional) The port number, default is None.
    +            context: Other configurations for Splunk rest client.
    +
    +        Raises:
    +            ObjectACLManagerException: If init ObjectACLManager failed.
    +        """
    +        collection_name = "{app}_{collection_name}".format(
    +            app=app, collection_name=collection_name
    +        )
    +        try:
    +            self._collection_data = _utils.get_collection_data(
    +                collection_name,
    +                session_key,
    +                app,
    +                owner,
    +                scheme,
    +                host,
    +                port,
    +                None,
    +                **context,
    +            )
    +        except KeyError:
    +            raise ObjectACLManagerException(
    +                f"Get object acl collection: {collection_name} fail."
    +            )
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def update_acl(
    +        self,
    +        obj_collection: str,
    +        obj_id: str,
    +        obj_type: str,
    +        obj_app: str,
    +        obj_owner: str,
    +        obj_perms: dict,
    +        obj_shared_by_inclusion: bool = True,
    +        replace_existing: bool = True,
    +    ):
    +        """Update acl info of object.
    +
    +        Construct a new object acl info first, if `replace_existing` is True
    +        then replace existing acl info else merge new object acl info with the
    +        old one and replace the old acl info with merged acl info.
    +
    +        Arguments:
    +            obj_collection: Collection where object currently stored.
    +            obj_id: ID of this object.
    +            obj_type: Type of this object.
    +            obj_app: App of this object.
    +            obj_owner: Owner of this object.
    +            obj_perms: Object perms, like:
    +
    +                {
    +                    'read': ['*'],
    +                    'write': ['admin'],
    +                    'delete': ['admin']
    +                }.
    +            obj_shared_by_inclusion: (optional) Flag of object is shared by
    +                inclusion, default is True.
    +            replace_existing: (optional) Replace existing acl info flag, True
    +                indicates replace old acl info with new one else merge with old
    +                acl info, default is True.
    +        """
    +
    +        obj_acl = ObjectACL(
    +            obj_collection,
    +            obj_id,
    +            obj_type,
    +            obj_app,
    +            obj_owner,
    +            obj_perms,
    +            obj_shared_by_inclusion,
    +        )
    +
    +        if not replace_existing:
    +            try:
    +                old_obj_acl = self.get_acl(obj_collection, obj_id)
    +            except ObjectACLNotExistException:
    +                old_obj_acl = None
    +
    +            if old_obj_acl:
    +                obj_acl.merge(old_obj_acl)
    +
    +        self._collection_data.batch_save(obj_acl.record)
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def update_acls(
    +        self,
    +        obj_collection: str,
    +        obj_ids: List[str],
    +        obj_type: str,
    +        obj_app: str,
    +        obj_owner: str,
    +        obj_perms: dict,
    +        obj_shared_by_inclusion: bool = True,
    +        replace_existing: bool = True,
    +    ):
    +        """Batch update object acl info to all provided `obj_ids`.
    +
    +        Arguments:
    +            obj_collection: Collection where objects currently stored.
    +            obj_ids: IDs list of objects.
    +            obj_type: Type of this object.
    +            obj_app: App of this object.
    +            obj_owner: Owner of this object.
    +            obj_perms: Object perms, like:
    +
    +                {
    +                    'read': ['*'],
    +                    'write': ['admin'],
    +                    'delete': ['admin']
    +                }.
    +            obj_shared_by_inclusion: (optional) Flag of object is shared by
    +                inclusion, default is True.
    +            replace_existing: (optional) Replace existing acl info flag, True
    +                indicates replace old acl info with new one else merge with old acl
    +                info, default is True.
    +        """
    +
    +        obj_acl_records = []
    +        for obj_id in obj_ids:
    +            obj_acl = ObjectACL(
    +                obj_collection,
    +                obj_id,
    +                obj_type,
    +                obj_app,
    +                obj_owner,
    +                obj_perms,
    +                obj_shared_by_inclusion,
    +            )
    +
    +            if not replace_existing:
    +                try:
    +                    old_obj_acl = self.get_acl(obj_collection, obj_id)
    +                except ObjectACLNotExistException:
    +                    old_obj_acl = None
    +
    +                if old_obj_acl:
    +                    obj_acl.merge(old_obj_acl)
    +
    +            obj_acl_records.append(obj_acl.record)
    +
    +        self._collection_data.batch_save(*obj_acl_records)
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def get_acl(self, obj_collection: str, obj_id: str) -> "ObjectACL":
    +        """Get acl info.
    +
    +        Query object acl info with parameter of the combination of
    +        `obj_collection` and `obj_id` from `self.collection_name` and
    +        return it.
    +
    +        Arguments:
    +            obj_collection: Collection where object currently stored.
    +            obj_id: ID of this object.
    +
    +        Returns:
    +            Object acl info if success else None.
    +
    +        Raises:
    +            ObjectACLNotExistException: If object ACL info does not exist.
    +        """
    +
    +        key = ObjectACL.generate_key(obj_collection, obj_id)
    +        try:
    +            obj_acl = self._collection_data.query_by_id(key)
    +        except binding.HTTPError as e:
    +            if e.status != 404:
    +                raise
    +
    +            raise ObjectACLNotExistException(
    +                "Object ACL info of {}_{} does not exist.".format(
    +                    obj_collection, obj_id
    +                )
    +            )
    +
    +        return ObjectACL.parse(obj_acl)
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def get_acls(self, obj_collection: str, obj_ids: List[str]) -> List[ObjectACL]:
    +        """Batch get acl info.
    +
    +        Query objects acl info with parameter of the combination of
    +        `obj_collection` and `obj_ids` from KVStore and return them.
    +
    +        Arguments:
    +            obj_collection: Collection where object currently stored.
    +            obj_ids: IDs of objects.
    +
    +        Returns:
    +            List of `ObjectACL` instances.
    +        """
    +
    +        query = json.dumps(
    +            {
    +                "$or": [
    +                    {"_key": ObjectACL.generate_key(obj_collection, obj_id)}
    +                    for obj_id in obj_ids
    +                ]
    +            }
    +        )
    +        obj_acls = self._collection_data.query(query=query)
    +
    +        return [ObjectACL.parse(obj_acl) for obj_acl in obj_acls]
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def delete_acl(self, obj_collection: str, obj_id: str):
    +        """Delete acl info.
    +
    +        Query object acl info with parameter of the combination of
    +        `obj_collection` and `obj_ids` from KVStore and delete it.
    +
    +        Arguments:
    +            obj_collection: Collection where object currently stored.
    +            obj_id: ID of this object.
    +
    +        Raises:
    +            ObjectACLNotExistException: If object ACL info does not exist.
    +        """
    +
    +        key = ObjectACL.generate_key(obj_collection, obj_id)
    +        try:
    +            self._collection_data.delete_by_id(key)
    +        except binding.HTTPError as e:
    +            if e.status != 404:
    +                raise
    +
    +            raise ObjectACLNotExistException(
    +                "Object ACL info of {}_{} does not exist.".format(
    +                    obj_collection, obj_id
    +                )
    +            )
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def delete_acls(self, obj_collection: str, obj_ids: List[str]):
    +        """Batch delete acl info.
    +
    +        Query objects acl info with parameter of the combination of
    +        `obj_collection` and `obj_ids` from KVStore and delete them.
    +
    +        Arguments:
    +            obj_collection: Collection where object currently stored.
    +            obj_ids: IDs of objects.
    +        """
    +
    +        query = json.dumps(
    +            {
    +                "$or": [
    +                    {"_key": ObjectACL.generate_key(obj_collection, obj_id)}
    +                    for obj_id in obj_ids
    +                ]
    +            }
    +        )
    +        self._collection_data.delete(query=query)
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def get_accessible_object_ids(
    +        self, user: str, operation: str, obj_collection: str, obj_ids: List[str]
    +    ) -> List[str]:
    +        """Get accessible IDs of objects from `obj_acls`.
    +
    +        Arguments:
    +            user: User name of current `operation`.
    +            operation: User operation, possible option: (read/write/delete).
    +            obj_collection: Collection where object currently stored.
    +            obj_ids: IDs of objects.
    +
    +        Returns:
    +            List of IDs of accessible objects.
    +        """
    +
    +        obj_acls = self.get_acls(obj_collection, obj_ids)
    +        accessible_obj_ids = []
    +        for obj_acl in obj_acls:
    +            perms = obj_acl.obj_perms[operation]
    +            if ObjectACL.OBJ_PERMS_ALLOW_ALL in perms or user in perms:
    +                accessible_obj_ids.append(obj_acl.obj_id)
    +
    +        return accessible_obj_ids
    +
    +
    +class AppCapabilityManagerException(Exception):
    +    """Exception for AppCapabilityManager."""
    +
    +    pass
    +
    +
    +class AppCapabilityNotExistException(Exception):
    +    """Exception for the situation when AppCapability does not exist for a
    +    specific app."""
    +
    +    pass
    +
    +
    +class AppCapabilityManager:
    +    """App capability manager.
    +
    +    Examples:
    +       >>> from solnlib import user_access
    +       >>> acm = user_access.AppCapabilityManager('test_collection',
    +                                                  session_key,
    +                                                  'Splunk_TA_test')
    +       >>> acm.register_capabilities(...)
    +       >>> acm.unregister_capabilities(...)
    +    """
    +
    +    def __init__(
    +        self,
    +        collection_name: str,
    +        session_key: str,
    +        app: str,
    +        owner: str = "nobody",
    +        scheme: str = None,
    +        host: str = None,
    +        port: int = None,
    +        **context: dict,
    +    ):
    +        """Initializes AppCapabilityManager.
    +
    +        Arguments:
    +            collection_name: Collection name to store capabilities.
    +            session_key: Splunk access token.
    +            app: App name of namespace.
    +            owner: (optional) Owner of namespace, default is `nobody`.
    +            scheme: (optional) The access scheme, default is None.
    +            host: (optional) The host name, default is None.
    +            port: (optional) The port number, default is None.
    +            context: Other configurations for Splunk rest client.
    +
    +        Raises:
    +            AppCapabilityManagerException: If init AppCapabilityManager failed.
    +        """
    +        self._app = app
    +
    +        collection_name = f"{app}_{collection_name}"
    +        try:
    +            self._collection_data = _utils.get_collection_data(
    +                collection_name,
    +                session_key,
    +                app,
    +                owner,
    +                scheme,
    +                host,
    +                port,
    +                None,
    +                **context,
    +            )
    +        except KeyError:
    +            raise AppCapabilityManagerException(
    +                f"Get app capabilities collection: {collection_name} failed."
    +            )
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def register_capabilities(self, capabilities: dict):
    +        """Register app capabilities.
    +
    +        Arguments:
    +            capabilities: App capabilities, example:
    +
    +                {
    +                    'object_type1': {
    +                        'read': 'read_app_object_type1',
    +                        'write': 'write_app_object_type1',
    +                        'delete': 'delete_app_object_type1'},
    +                        'object_type2': {
    +                        'read': 'read_app_object_type2',
    +                        'write': 'write_app_object_type2',
    +                        'delete': 'delete_app_object_type2'
    +                    },
    +                    ...
    +                }
    +        """
    +
    +        record = {"_key": self._app, "capabilities": capabilities}
    +        self._collection_data.batch_save(record)
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def unregister_capabilities(self):
    +        """Unregister app capabilities.
    +
    +        Raises:
    +            AppCapabilityNotExistException: If app capabilities are not registered.
    +        """
    +
    +        try:
    +            self._collection_data.delete_by_id(self._app)
    +        except binding.HTTPError as e:
    +            if e.status != 404:
    +                raise
    +
    +            raise AppCapabilityNotExistException(
    +                "App capabilities for %s have not been registered." % self._app
    +            )
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def capabilities_are_registered(self) -> bool:
    +        """Check if app capabilities are registered.
    +
    +        Returns:
    +            True if app capabilities are registered else False.
    +        """
    +
    +        try:
    +            self._collection_data.query_by_id(self._app)
    +        except binding.HTTPError as e:
    +            if e.status != 404:
    +                raise
    +
    +            return False
    +
    +        return True
    +
    +    @utils.retry(exceptions=[binding.HTTPError])
    +    def get_capabilities(self) -> dict:
    +        """Get app capabilities.
    +
    +        Returns:
    +            App capabilities.
    +
    +        Raises:
    +             AppCapabilityNotExistException: If app capabilities are not registered.
    +        """
    +
    +        try:
    +            record = self._collection_data.query_by_id(self._app)
    +        except binding.HTTPError as e:
    +            if e.status != 404:
    +                raise
    +
    +            raise AppCapabilityNotExistException(
    +                "App capabilities for %s have not been registered." % self._app
    +            )
    +
    +        return record["capabilities"]
    +
    +
    +class UserAccessException(Exception):
    +    """Exception for the situation when there is user access exception."""
    +
    +    pass
    +
    +
    +def check_user_access(
    +    session_key: str,
    +    capabilities: dict,
    +    obj_type: str,
    +    operation: str,
    +    scheme: str = None,
    +    host: str = None,
    +    port: int = None,
    +    **context: dict,
    +):
    +    """User access checker.
    +
    +    It will fetch user capabilities from given `session_key` and check if
    +    the capability extracted from `capabilities`, `obj_type` and `operation`
    +    is contained, if user capabilities include the extracted capability user
    +    access is ok else fail.
    +
    +    Arguments:
    +        session_key: Splunk access token.
    +        capabilities: App capabilities, example:
    +
    +            {
    +                'object_type1': {
    +                    'read': 'read_app_object_type1',
    +                    'write': 'write_app_object_type1',
    +                    'delete': 'delete_app_object_type1'},
    +                    'object_type2': {
    +                    'read': 'read_app_object_type2',
    +                    'write': 'write_app_object_type2',
    +                    'delete': 'delete_app_object_type2'
    +                },
    +                ...
    +            }
    +        obj_type: Object type.
    +        operation: User operation, possible option: (read/write/delete).
    +        scheme: (optional) The access scheme, default is None.
    +        host: (optional) The host name, default is None.
    +        port: (optional) The port number, default is None.
    +        context: Other configurations for Splunk rest client.
    +
    +    Raises:
    +        UserAccessException: If user access permission is denied.
    +
    +    Examples:
    +       >>> from solnlib.user_access import check_user_access
    +       >>> def fun():
    +       >>>     check_user_access(
    +       >>>         session_key, capabilities, 'test_object', 'read')
    +       >>>     ...
    +    """
    +
    +    username = get_current_username(
    +        session_key, scheme=scheme, host=host, port=port, **context
    +    )
    +    capability = capabilities[obj_type][operation]
    +    if not user_is_capable(
    +        session_key,
    +        username,
    +        capability,
    +        scheme=scheme,
    +        host=host,
    +        port=port,
    +        **context,
    +    ):
    +        raise UserAccessException(
    +            "Permission denied, %s does not have the capability: %s."
    +            % (username, capability)
    +        )
    +
    +
    +class InvalidSessionKeyException(Exception):
    +    """Exception when Splunk session key is invalid."""
    +
    +    pass
    +
    +
    +@utils.retry(exceptions=[binding.HTTPError])
    +def get_current_username(
    +    session_key: str,
    +    scheme: str = None,
    +    host: str = None,
    +    port: int = None,
    +    **context: dict,
    +) -> str:
    +    """Get current user name from `session_key`.
    +
    +    Arguments:
    +        session_key: Splunk access token.
    +        scheme: (optional) The access scheme, default is None.
    +        host: (optional) The host name, default is None.
    +        port: (optional) The port number, default is None.
    +        context: Other configurations for Splunk rest client.
    +
    +    Returns:
    +        Current user name.
    +
    +    Raises:
    +        InvalidSessionKeyException: If `session_key` is invalid.
    +
    +    Examples:
    +       >>> from solnlib import user_access
    +       >>> user_name = user_access.get_current_username(session_key)
    +    """
    +
    +    _rest_client = rest_client.SplunkRestClient(
    +        session_key, "-", scheme=scheme, host=host, port=port, **context
    +    )
    +    try:
    +        response = _rest_client.get(
    +            "/services/authentication/current-context", output_mode="json"
    +        ).body.read()
    +    except binding.HTTPError as e:
    +        if e.status != 401:
    +            raise
    +
    +        raise InvalidSessionKeyException("Invalid session key.")
    +
    +    return json.loads(response)["entry"][0]["content"]["username"]
    +
    +
    +class UserNotExistException(Exception):
    +    """Exception when user does not exist."""
    +
    +    pass
    +
    +
    +@utils.retry(exceptions=[binding.HTTPError])
    +def get_user_capabilities(
    +    session_key: str,
    +    username: str,
    +    scheme: str = None,
    +    host: str = None,
    +    port: int = None,
    +    **context: dict,
    +) -> List[dict]:
    +    """Get user capabilities.
    +
    +    Arguments:
    +        session_key: Splunk access token.
    +        scheme: (optional) The access scheme, default is None.
    +        host: (optional) The host name, default is None.
    +        port: (optional) The port number, default is None.
    +        context: Other configurations for Splunk rest client.
    +
    +    Returns:
    +        User capabilities.
    +
    +    Raises:
    +        UserNotExistException: If `username` does not exist.
    +
    +    Examples:
    +       >>> from solnlib import user_access
    +       >>> user_capabilities = user_access.get_user_capabilities(
    +       >>>     session_key, 'test_user')
    +    """
    +
    +    _rest_client = rest_client.SplunkRestClient(
    +        session_key, "-", scheme=scheme, host=host, port=port, **context
    +    )
    +    url = f"/services/authentication/users/{username}"
    +    try:
    +        response = _rest_client.get(url, output_mode="json").body.read()
    +    except binding.HTTPError as e:
    +        if e.status != 404:
    +            raise
    +
    +        raise UserNotExistException("User: %s does not exist." % username)
    +
    +    return json.loads(response)["entry"][0]["content"]["capabilities"]
    +
    +
    +def user_is_capable(
    +    session_key: str,
    +    username: str,
    +    capability: str,
    +    scheme: str = None,
    +    host: str = None,
    +    port: int = None,
    +    **context: dict,
    +) -> bool:
    +    """Check if user is capable for given `capability`.
    +
    +    Arguments:
    +        session_key: Splunk access token.
    +        username: (optional) User name of roles to get.
    +        capability: The capability we wish to check for.
    +        scheme: (optional) The access scheme, default is None.
    +        host: (optional) The host name, default is None.
    +        port: (optional) The port number, default is None.
    +        context: Other configurations for Splunk rest client.
    +
    +    Returns:
    +        True if user is capable else False.
    +
    +    Raises:
    +        UserNotExistException: If `username` does not exist.
    +
    +    Examples:
    +       >>> from solnlib import user_access
    +       >>> is_capable = user_access.user_is_capable(
    +       >>>     session_key, 'test_user', 'object_read_capability')
    +    """
    +
    +    capabilities = get_user_capabilities(
    +        session_key, username, scheme=scheme, host=host, port=port, **context
    +    )
    +    return capability in capabilities
    +
    +
    +@utils.retry(exceptions=[binding.HTTPError])
    +def get_user_roles(
    +    session_key: str, username: str, scheme=None, host=None, port=None, **context
    +) -> List:
    +    """Get user roles.
    +
    +    Arguments:
    +        session_key: Splunk access token.
    +        username: (optional) User name of roles to get.
    +        scheme: (optional) The access scheme, default is None.
    +        host: (optional) The host name, default is None.
    +        port: (optional) The port number, default is None.
    +        context: Other configurations for Splunk rest client.
    +
    +    Returns:
    +        User roles.
    +
    +    Raises:
    +        UserNotExistException: If `username` does not exist.
    +
    +    Examples:
    +       >>> from solnlib import user_access
    +       >>> user_roles = user_access.get_user_roles(session_key, 'test_user')
    +    """
    +
    +    _rest_client = rest_client.SplunkRestClient(
    +        session_key, "-", scheme=scheme, host=host, port=port, **context
    +    )
    +    url = f"/services/authentication/users/{username}"
    +    try:
    +        response = _rest_client.get(url, output_mode="json").body.read()
    +    except binding.HTTPError as e:
    +        if e.status != 404:
    +            raise
    +
    +        raise UserNotExistException("User: %s does not exist." % username)
    +
    +    return json.loads(response)["entry"][0]["content"]["roles"]
    diff --git a/deployment-apps/metricator-for-nmon/lib/solnlib/utils.py b/deployment-apps/metricator-for-nmon/lib/solnlib/utils.py
    new file mode 100644
    index 0000000..fda4264
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/solnlib/utils.py
    @@ -0,0 +1,195 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""Common utilities."""
    +
    +import datetime
    +import logging
    +import os
    +import signal
    +import time
    +import traceback
    +from functools import wraps
    +from typing import Any, Callable, List, Tuple, Union
    +from urllib import parse as urlparse
    +
    +__all__ = [
    +    "handle_teardown_signals",
    +    "datetime_to_seconds",
    +    "is_true",
    +    "is_false",
    +    "retry",
    +    "extract_http_scheme_host_port",
    +    "remove_http_proxy_env_vars",
    +]
    +
    +
    +def remove_http_proxy_env_vars() -> None:
    +    """Removes HTTP(s) proxies from environment variables.
    +
    +    Removes the following environment variables:
    +        * http_proxy
    +        * https_proxy
    +        * HTTP_PROXY
    +        * HTTPS_PROXY
    +
    +    This function can be used in Splunk modular inputs code before starting the
    +    ingestion to ensure that no proxy is going to be used when doing requests.
    +    In case of proxy is needed, it can be defined in the modular inputs code.
    +    """
    +    env_vars_to_remove = (
    +        "http_proxy",
    +        "https_proxy",
    +        "HTTP_PROXY",
    +        "HTTPS_PROXY",
    +    )
    +    for env_var in env_vars_to_remove:
    +        if env_var in os.environ:
    +            del os.environ[env_var]
    +
    +
    +def handle_teardown_signals(callback: Callable):
    +    """Register handler for SIGTERM/SIGINT/SIGBREAK signal.
    +
    +    Catch SIGTERM/SIGINT/SIGBREAK signals, and invoke callback
    +    Note: this should be called in main thread since Python only catches
    +    signals in main thread.
    +
    +    Arguments:
    +        callback: Callback for tear down signals.
    +    """
    +
    +    signal.signal(signal.SIGTERM, callback)
    +    signal.signal(signal.SIGINT, callback)
    +
    +    if os.name == "nt":
    +        signal.signal(signal.SIGBREAK, callback)
    +
    +
    +def datetime_to_seconds(dt: datetime.datetime) -> float:
    +    """Convert UTC datetime to seconds since epoch.
    +
    +    Arguments:
    +        dt: Date time.
    +
    +    Returns:
    +        Seconds since epoch.
    +    """
    +
    +    epoch_time = datetime.datetime.utcfromtimestamp(0)
    +    return (dt - epoch_time).total_seconds()
    +
    +
    +def is_true(val: Union[str, int]) -> bool:
    +    """Decide if `val` is true.
    +
    +    Arguments:
    +        val: Value to check.
    +
    +    Returns:
    +        True or False.
    +    """
    +
    +    value = str(val).strip().upper()
    +    if value in ("1", "TRUE", "T", "Y", "YES"):
    +        return True
    +    return False
    +
    +
    +def is_false(val: Union[str, int]) -> bool:
    +    """Decide if `val` is false.
    +
    +    Arguments:
    +        val: Value to check.
    +
    +    Returns:
    +        True or False.
    +    """
    +
    +    value = str(val).strip().upper()
    +    if value in ("0", "FALSE", "F", "N", "NO", "NONE", ""):
    +        return True
    +    return False
    +
    +
    +def retry(
    +    retries: int = 3,
    +    reraise: bool = True,
    +    default_return: Any = None,
    +    exceptions: List = None,
    +):
    +    """A decorator to run function with max `retries` times if there is
    +    exception.
    +
    +    Arguments:
    +        retries: (optional) Max retries times, default is 3.
    +        reraise: Whether exception should be reraised, default is True.
    +        default_return: (optional) Default return value for function
    +            run after max retries and reraise is False.
    +        exceptions: (optional) List of exceptions that should retry.
    +    """
    +
    +    max_tries = max(retries, 0) + 1
    +
    +    def do_retry(func):
    +        @wraps(func)
    +        def wrapper(*args, **kwargs):
    +            last_ex = None
    +            for i in range(max_tries):
    +                try:
    +                    return func(*args, **kwargs)
    +                except Exception as e:
    +                    logging.warning(
    +                        "Run function: %s failed: %s.",
    +                        func.__name__,
    +                        traceback.format_exc(),
    +                    )
    +                    if not exceptions or any(
    +                        isinstance(e, exception) for exception in exceptions
    +                    ):
    +                        last_ex = e
    +                        if i < max_tries - 1:
    +                            time.sleep(2**i)
    +                    else:
    +                        raise
    +
    +            if reraise:
    +                raise last_ex
    +            else:
    +                return default_return
    +
    +        return wrapper
    +
    +    return do_retry
    +
    +
    +def extract_http_scheme_host_port(http_url: str) -> Tuple:
    +    """Extract scheme, host and port from a HTTP URL.
    +
    +    Arguments:
    +        http_url: HTTP URL to extract.
    +
    +    Returns:
    +        A tuple of scheme, host and port
    +
    +    Raises:
    +        ValueError: If `http_url` is not in http(s)://hostname:port format.
    +    """
    +
    +    http_info = urlparse.urlparse(http_url)
    +    if not http_info.scheme or not http_info.hostname or not http_info.port:
    +        raise ValueError(http_url + " is not in http(s)://hostname:port format")
    +    return http_info.scheme, http_info.hostname, http_info.port
    diff --git a/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/INSTALLER b/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/INSTALLER
    new file mode 100644
    index 0000000..a1b589e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/INSTALLER
    @@ -0,0 +1 @@
    +pip
    diff --git a/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/LICENSE b/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/LICENSE
    new file mode 100644
    index 0000000..668d8ec
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/LICENSE
    @@ -0,0 +1,13 @@
    +Copyright 2014-2019 Grant Jenks
    +
    +Licensed 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.
    diff --git a/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/METADATA b/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/METADATA
    new file mode 100644
    index 0000000..dd28af4
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/METADATA
    @@ -0,0 +1,264 @@
    +Metadata-Version: 2.1
    +Name: sortedcontainers
    +Version: 2.4.0
    +Summary: Sorted Containers -- Sorted List, Sorted Dict, Sorted Set
    +Home-page: http://www.grantjenks.com/docs/sortedcontainers/
    +Author: Grant Jenks
    +Author-email: contact@grantjenks.com
    +License: Apache 2.0
    +Platform: UNKNOWN
    +Classifier: Development Status :: 5 - Production/Stable
    +Classifier: Intended Audience :: Developers
    +Classifier: License :: OSI Approved :: Apache Software License
    +Classifier: Natural Language :: English
    +Classifier: Programming Language :: Python
    +Classifier: Programming Language :: Python :: 2
    +Classifier: Programming Language :: Python :: 2.7
    +Classifier: Programming Language :: Python :: 3
    +Classifier: Programming Language :: Python :: 3.2
    +Classifier: Programming Language :: Python :: 3.3
    +Classifier: Programming Language :: Python :: 3.4
    +Classifier: Programming Language :: Python :: 3.5
    +Classifier: Programming Language :: Python :: 3.6
    +Classifier: Programming Language :: Python :: 3.7
    +Classifier: Programming Language :: Python :: Implementation :: CPython
    +Classifier: Programming Language :: Python :: Implementation :: PyPy
    +
    +Python Sorted Containers
    +========================
    +
    +`Sorted Containers`_ is an Apache2 licensed `sorted collections library`_,
    +written in pure-Python, and fast as C-extensions.
    +
    +Python's standard library is great until you need a sorted collections
    +type. Many will attest that you can get really far without one, but the moment
    +you **really need** a sorted list, sorted dict, or sorted set, you're faced
    +with a dozen different implementations, most using C-extensions without great
    +documentation and benchmarking.
    +
    +In Python, we can do better. And we can do it in pure-Python!
    +
    +.. code-block:: python
    +
    +    >>> from sortedcontainers import SortedList
    +    >>> sl = SortedList(['e', 'a', 'c', 'd', 'b'])
    +    >>> sl
    +    SortedList(['a', 'b', 'c', 'd', 'e'])
    +    >>> sl *= 10_000_000
    +    >>> sl.count('c')
    +    10000000
    +    >>> sl[-3:]
    +    ['e', 'e', 'e']
    +    >>> from sortedcontainers import SortedDict
    +    >>> sd = SortedDict({'c': 3, 'a': 1, 'b': 2})
    +    >>> sd
    +    SortedDict({'a': 1, 'b': 2, 'c': 3})
    +    >>> sd.popitem(index=-1)
    +    ('c', 3)
    +    >>> from sortedcontainers import SortedSet
    +    >>> ss = SortedSet('abracadabra')
    +    >>> ss
    +    SortedSet(['a', 'b', 'c', 'd', 'r'])
    +    >>> ss.bisect_left('c')
    +    2
    +
    +All of the operations shown above run in faster than linear time. The above
    +demo also takes nearly a gigabyte of memory to run. When the sorted list is
    +multiplied by ten million, it stores ten million references to each of "a"
    +through "e". Each reference requires eight bytes in the sorted
    +container. That's pretty hard to beat as it's the cost of a pointer to each
    +object. It's also 66% less overhead than a typical binary tree implementation
    +(e.g. Red-Black Tree, AVL-Tree, AA-Tree, Splay-Tree, Treap, etc.) for which
    +every node must also store two pointers to children nodes.
    +
    +`Sorted Containers`_ takes all of the work out of Python sorted collections -
    +making your deployment and use of Python easy. There's no need to install a C
    +compiler or pre-build and distribute custom extensions. Performance is a
    +feature and testing has 100% coverage with unit tests and hours of stress.
    +
    +.. _`Sorted Containers`: http://www.grantjenks.com/docs/sortedcontainers/
    +.. _`sorted collections library`: http://www.grantjenks.com/docs/sortedcontainers/
    +
    +Testimonials
    +------------
    +
    +**Alex Martelli**, `Fellow of the Python Software Foundation`_
    +
    +"Good stuff! ... I like the `simple, effective implementation`_ idea of
    +splitting the sorted containers into smaller "fragments" to avoid the O(N)
    +insertion costs."
    +
    +**Jeff Knupp**, `author of Writing Idiomatic Python and Python Trainer`_
    +
    +"That last part, "fast as C-extensions," was difficult to believe. I would need
    +some sort of `Performance Comparison`_ to be convinced this is true. The author
    +includes this in the docs. It is."
    +
    +**Kevin Samuel**, `Python and Django Trainer`_
    +
    +I'm quite amazed, not just by the code quality (it's incredibly readable and
    +has more comment than code, wow), but the actual amount of work you put at
    +stuff that is *not* code: documentation, benchmarking, implementation
    +explanations. Even the git log is clean and the unit tests run out of the box
    +on Python 2 and 3.
    +
    +**Mark Summerfield**, a short plea for `Python Sorted Collections`_
    +
    +Python's "batteries included" standard library seems to have a battery
    +missing. And the argument that "we never had it before" has worn thin. It is
    +time that Python offered a full range of collection classes out of the box,
    +including sorted ones.
    +
    +`Sorted Containers`_ is used in popular open source projects such as:
    +`Zipline`_, an algorithmic trading library from Quantopian; `Angr`_, a binary
    +analysis platform from UC Santa Barbara; `Trio`_, an async I/O library; and
    +`Dask Distributed`_, a distributed computation library supported by Continuum
    +Analytics.
    +
    +.. _`Fellow of the Python Software Foundation`: https://en.wikipedia.org/wiki/Alex_Martelli
    +.. _`simple, effective implementation`: http://www.grantjenks.com/docs/sortedcontainers/implementation.html
    +.. _`author of Writing Idiomatic Python and Python Trainer`: https://jeffknupp.com/
    +.. _`Python and Django Trainer`: https://www.elephorm.com/formateur/kevin-samuel
    +.. _`Python Sorted Collections`: http://www.qtrac.eu/pysorted.html
    +.. _`Zipline`: https://github.com/quantopian/zipline
    +.. _`Angr`: https://github.com/angr/angr
    +.. _`Trio`: https://github.com/python-trio/trio
    +.. _`Dask Distributed`: https://github.com/dask/distributed
    +
    +Features
    +--------
    +
    +- Pure-Python
    +- Fully documented
    +- Benchmark comparison (alternatives, runtimes, load-factors)
    +- 100% test coverage
    +- Hours of stress testing
    +- Performance matters (often faster than C implementations)
    +- Compatible API (nearly identical to older blist and bintrees modules)
    +- Feature-rich (e.g. get the five largest keys in a sorted dict: d.keys()[-5:])
    +- Pragmatic design (e.g. SortedSet is a Python set with a SortedList index)
    +- Developed on Python 3.7
    +- Tested on CPython 2.7, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7 and PyPy, PyPy3
    +
    +.. image:: https://api.travis-ci.org/grantjenks/python-sortedcontainers.svg?branch=master
    +   :target: http://www.grantjenks.com/docs/sortedcontainers/
    +
    +.. image:: https://ci.appveyor.com/api/projects/status/github/grantjenks/python-sortedcontainers?branch=master&svg=true
    +   :target: http://www.grantjenks.com/docs/sortedcontainers/
    +
    +Quickstart
    +----------
    +
    +Installing `Sorted Containers`_ is simple with `pip
    +<https://pypi.org/project/pip/>`_::
    +
    +    $ pip install sortedcontainers
    +
    +You can access documentation in the interpreter with Python's built-in `help`
    +function. The `help` works on modules, classes and methods in `Sorted
    +Containers`_.
    +
    +.. code-block:: python
    +
    +    >>> import sortedcontainers
    +    >>> help(sortedcontainers)
    +    >>> from sortedcontainers import SortedDict
    +    >>> help(SortedDict)
    +    >>> help(SortedDict.popitem)
    +
    +Documentation
    +-------------
    +
    +Complete documentation for `Sorted Containers`_ is available at
    +http://www.grantjenks.com/docs/sortedcontainers/
    +
    +User Guide
    +..........
    +
    +The user guide provides an introduction to `Sorted Containers`_ and extensive
    +performance comparisons and analysis.
    +
    +- `Introduction`_
    +- `Performance Comparison`_
    +- `Load Factor Performance Comparison`_
    +- `Runtime Performance Comparison`_
    +- `Simulated Workload Performance Comparison`_
    +- `Performance at Scale`_
    +
    +.. _`Introduction`: http://www.grantjenks.com/docs/sortedcontainers/introduction.html
    +.. _`Performance Comparison`: http://www.grantjenks.com/docs/sortedcontainers/performance.html
    +.. _`Load Factor Performance Comparison`: http://www.grantjenks.com/docs/sortedcontainers/performance-load.html
    +.. _`Runtime Performance Comparison`: http://www.grantjenks.com/docs/sortedcontainers/performance-runtime.html
    +.. _`Simulated Workload Performance Comparison`: http://www.grantjenks.com/docs/sortedcontainers/performance-workload.html
    +.. _`Performance at Scale`: http://www.grantjenks.com/docs/sortedcontainers/performance-scale.html
    +
    +Community Guide
    +...............
    +
    +The community guide provides information on the development of `Sorted
    +Containers`_ along with support, implementation, and history details.
    +
    +- `Development and Support`_
    +- `Implementation Details`_
    +- `Release History`_
    +
    +.. _`Development and Support`: http://www.grantjenks.com/docs/sortedcontainers/development.html
    +.. _`Implementation Details`: http://www.grantjenks.com/docs/sortedcontainers/implementation.html
    +.. _`Release History`: http://www.grantjenks.com/docs/sortedcontainers/history.html
    +
    +API Documentation
    +.................
    +
    +The API documentation provides information on specific functions, classes, and
    +modules in the `Sorted Containers`_ package.
    +
    +- `Sorted List`_
    +- `Sorted Dict`_
    +- `Sorted Set`_
    +
    +.. _`Sorted List`: http://www.grantjenks.com/docs/sortedcontainers/sortedlist.html
    +.. _`Sorted Dict`: http://www.grantjenks.com/docs/sortedcontainers/sorteddict.html
    +.. _`Sorted Set`: http://www.grantjenks.com/docs/sortedcontainers/sortedset.html
    +
    +Talks
    +-----
    +
    +- `Python Sorted Collections | PyCon 2016 Talk`_
    +- `SF Python Holiday Party 2015 Lightning Talk`_
    +- `DjangoCon 2015 Lightning Talk`_
    +
    +.. _`Python Sorted Collections | PyCon 2016 Talk`: http://www.grantjenks.com/docs/sortedcontainers/pycon-2016-talk.html
    +.. _`SF Python Holiday Party 2015 Lightning Talk`: http://www.grantjenks.com/docs/sortedcontainers/sf-python-2015-lightning-talk.html
    +.. _`DjangoCon 2015 Lightning Talk`: http://www.grantjenks.com/docs/sortedcontainers/djangocon-2015-lightning-talk.html
    +
    +Resources
    +---------
    +
    +- `Sorted Containers Documentation`_
    +- `Sorted Containers at PyPI`_
    +- `Sorted Containers at Github`_
    +- `Sorted Containers Issue Tracker`_
    +
    +.. _`Sorted Containers Documentation`: http://www.grantjenks.com/docs/sortedcontainers/
    +.. _`Sorted Containers at PyPI`: https://pypi.org/project/sortedcontainers/
    +.. _`Sorted Containers at Github`: https://github.com/grantjenks/python-sortedcontainers
    +.. _`Sorted Containers Issue Tracker`: https://github.com/grantjenks/python-sortedcontainers/issues
    +
    +Sorted Containers License
    +-------------------------
    +
    +Copyright 2014-2019 Grant Jenks
    +
    +Licensed 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.
    +
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/RECORD b/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/RECORD
    new file mode 100644
    index 0000000..965aa00
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/RECORD
    @@ -0,0 +1,10 @@
    +sortedcontainers-2.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
    +sortedcontainers-2.4.0.dist-info/LICENSE,sha256=HbfK5_zmRS4uYI5AGg-VPgEz5MLXXbafuK6FHSCG9bY,557
    +sortedcontainers-2.4.0.dist-info/METADATA,sha256=7t8RUQniFQAekE2giChRvq5QsDwLAWGouedLfP1nlHM,10666
    +sortedcontainers-2.4.0.dist-info/RECORD,,
    +sortedcontainers-2.4.0.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110
    +sortedcontainers-2.4.0.dist-info/top_level.txt,sha256=AVs0q-qf-10gs1tkVhfALdebJo4uPuVVBX7YT91riQU,17
    +sortedcontainers/__init__.py,sha256=X_X5LuRjve77KwuJQrDUSu0T8559YcoowQbAnjuM7TE,2131
    +sortedcontainers/sorteddict.py,sha256=za5LnENZMGPIn_JZEr0S0tDXfEsxJsfEnanh6lLlTZM,22712
    +sortedcontainers/sortedlist.py,sha256=rwA1dM8ce09eb2DMjLOfHoikhCx_Rfk5nuE_NSsfr3I,76331
    +sortedcontainers/sortedset.py,sha256=5RI2CUJGMm1ig3-dhbOrzDl8aPqDePkoJPQoq0ROS7M,19825
    diff --git a/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/WHEEL b/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/WHEEL
    new file mode 100644
    index 0000000..ef99c6c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/sortedcontainers-2.4.0.dist-info/WHEEL
    @@ -0,0 +1,6 @@
    +Wheel-Version: 1.0
    +Generator: bdist_wheel (0.34.2)
    +Root-Is-Purelib: true
    +Tag: py2-none-any
    +Tag: py3-none-any
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/sortedcontainers/__init__.py b/deployment-apps/metricator-for-nmon/lib/sortedcontainers/__init__.py
    new file mode 100644
    index 0000000..a141dd1
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/sortedcontainers/__init__.py
    @@ -0,0 +1,74 @@
    +"""Sorted Containers -- Sorted List, Sorted Dict, Sorted Set
    +
    +Sorted Containers is an Apache2 licensed containers library, written in
    +pure-Python, and fast as C-extensions.
    +
    +Python's standard library is great until you need a sorted collections
    +type. Many will attest that you can get really far without one, but the moment
    +you **really need** a sorted list, dict, or set, you're faced with a dozen
    +different implementations, most using C-extensions without great documentation
    +and benchmarking.
    +
    +In Python, we can do better. And we can do it in pure-Python!
    +
    +::
    +
    +    >>> from sortedcontainers import SortedList
    +    >>> sl = SortedList(['e', 'a', 'c', 'd', 'b'])
    +    >>> sl
    +    SortedList(['a', 'b', 'c', 'd', 'e'])
    +    >>> sl *= 1000000
    +    >>> sl.count('c')
    +    1000000
    +    >>> sl[-3:]
    +    ['e', 'e', 'e']
    +    >>> from sortedcontainers import SortedDict
    +    >>> sd = SortedDict({'c': 3, 'a': 1, 'b': 2})
    +    >>> sd
    +    SortedDict({'a': 1, 'b': 2, 'c': 3})
    +    >>> sd.popitem(index=-1)
    +    ('c', 3)
    +    >>> from sortedcontainers import SortedSet
    +    >>> ss = SortedSet('abracadabra')
    +    >>> ss
    +    SortedSet(['a', 'b', 'c', 'd', 'r'])
    +    >>> ss.bisect_left('c')
    +    2
    +
    +Sorted Containers takes all of the work out of Python sorted types - making
    +your deployment and use of Python easy. There's no need to install a C compiler
    +or pre-build and distribute custom extensions. Performance is a feature and
    +testing has 100% coverage with unit tests and hours of stress.
    +
    +:copyright: (c) 2014-2019 by Grant Jenks.
    +:license: Apache 2.0, see LICENSE for more details.
    +
    +"""
    +
    +
    +from .sortedlist import SortedList, SortedKeyList, SortedListWithKey
    +from .sortedset import SortedSet
    +from .sorteddict import (
    +    SortedDict,
    +    SortedKeysView,
    +    SortedItemsView,
    +    SortedValuesView,
    +)
    +
    +__all__ = [
    +    'SortedList',
    +    'SortedKeyList',
    +    'SortedListWithKey',
    +    'SortedDict',
    +    'SortedKeysView',
    +    'SortedItemsView',
    +    'SortedValuesView',
    +    'SortedSet',
    +]
    +
    +__title__ = 'sortedcontainers'
    +__version__ = '2.4.0'
    +__build__ = 0x020400
    +__author__ = 'Grant Jenks'
    +__license__ = 'Apache 2.0'
    +__copyright__ = '2014-2019, Grant Jenks'
    diff --git a/deployment-apps/metricator-for-nmon/lib/sortedcontainers/sorteddict.py b/deployment-apps/metricator-for-nmon/lib/sortedcontainers/sorteddict.py
    new file mode 100644
    index 0000000..910f260
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/sortedcontainers/sorteddict.py
    @@ -0,0 +1,812 @@
    +"""Sorted Dict
    +==============
    +
    +:doc:`Sorted Containers<index>` is an Apache2 licensed Python sorted
    +collections library, written in pure-Python, and fast as C-extensions. The
    +:doc:`introduction<introduction>` is the best way to get started.
    +
    +Sorted dict implementations:
    +
    +.. currentmodule:: sortedcontainers
    +
    +* :class:`SortedDict`
    +* :class:`SortedKeysView`
    +* :class:`SortedItemsView`
    +* :class:`SortedValuesView`
    +
    +"""
    +
    +import sys
    +import warnings
    +
    +from itertools import chain
    +
    +from .sortedlist import SortedList, recursive_repr
    +from .sortedset import SortedSet
    +
    +###############################################################################
    +# BEGIN Python 2/3 Shims
    +###############################################################################
    +
    +try:
    +    from collections.abc import (
    +        ItemsView, KeysView, Mapping, ValuesView, Sequence
    +    )
    +except ImportError:
    +    from collections import ItemsView, KeysView, Mapping, ValuesView, Sequence
    +
    +###############################################################################
    +# END Python 2/3 Shims
    +###############################################################################
    +
    +
    +class SortedDict(dict):
    +    """Sorted dict is a sorted mutable mapping.
    +
    +    Sorted dict keys are maintained in sorted order. The design of sorted dict
    +    is simple: sorted dict inherits from dict to store items and maintains a
    +    sorted list of keys.
    +
    +    Sorted dict keys must be hashable and comparable. The hash and total
    +    ordering of keys must not change while they are stored in the sorted dict.
    +
    +    Mutable mapping methods:
    +
    +    * :func:`SortedDict.__getitem__` (inherited from dict)
    +    * :func:`SortedDict.__setitem__`
    +    * :func:`SortedDict.__delitem__`
    +    * :func:`SortedDict.__iter__`
    +    * :func:`SortedDict.__len__` (inherited from dict)
    +
    +    Methods for adding items:
    +
    +    * :func:`SortedDict.setdefault`
    +    * :func:`SortedDict.update`
    +
    +    Methods for removing items:
    +
    +    * :func:`SortedDict.clear`
    +    * :func:`SortedDict.pop`
    +    * :func:`SortedDict.popitem`
    +
    +    Methods for looking up items:
    +
    +    * :func:`SortedDict.__contains__` (inherited from dict)
    +    * :func:`SortedDict.get` (inherited from dict)
    +    * :func:`SortedDict.peekitem`
    +
    +    Methods for views:
    +
    +    * :func:`SortedDict.keys`
    +    * :func:`SortedDict.items`
    +    * :func:`SortedDict.values`
    +
    +    Methods for miscellany:
    +
    +    * :func:`SortedDict.copy`
    +    * :func:`SortedDict.fromkeys`
    +    * :func:`SortedDict.__reversed__`
    +    * :func:`SortedDict.__eq__` (inherited from dict)
    +    * :func:`SortedDict.__ne__` (inherited from dict)
    +    * :func:`SortedDict.__repr__`
    +    * :func:`SortedDict._check`
    +
    +    Sorted list methods available (applies to keys):
    +
    +    * :func:`SortedList.bisect_left`
    +    * :func:`SortedList.bisect_right`
    +    * :func:`SortedList.count`
    +    * :func:`SortedList.index`
    +    * :func:`SortedList.irange`
    +    * :func:`SortedList.islice`
    +    * :func:`SortedList._reset`
    +
    +    Additional sorted list methods available, if key-function used:
    +
    +    * :func:`SortedKeyList.bisect_key_left`
    +    * :func:`SortedKeyList.bisect_key_right`
    +    * :func:`SortedKeyList.irange_key`
    +
    +    Sorted dicts may only be compared for equality and inequality.
    +
    +    """
    +    def __init__(self, *args, **kwargs):
    +        """Initialize sorted dict instance.
    +
    +        Optional key-function argument defines a callable that, like the `key`
    +        argument to the built-in `sorted` function, extracts a comparison key
    +        from each dictionary key. If no function is specified, the default
    +        compares the dictionary keys directly. The key-function argument must
    +        be provided as a positional argument and must come before all other
    +        arguments.
    +
    +        Optional iterable argument provides an initial sequence of pairs to
    +        initialize the sorted dict. Each pair in the sequence defines the key
    +        and corresponding value. If a key is seen more than once, the last
    +        value associated with it is stored in the new sorted dict.
    +
    +        Optional mapping argument provides an initial mapping of items to
    +        initialize the sorted dict.
    +
    +        If keyword arguments are given, the keywords themselves, with their
    +        associated values, are added as items to the dictionary. If a key is
    +        specified both in the positional argument and as a keyword argument,
    +        the value associated with the keyword is stored in the
    +        sorted dict.
    +
    +        Sorted dict keys must be hashable, per the requirement for Python's
    +        dictionaries. Keys (or the result of the key-function) must also be
    +        comparable, per the requirement for sorted lists.
    +
    +        >>> d = {'alpha': 1, 'beta': 2}
    +        >>> SortedDict([('alpha', 1), ('beta', 2)]) == d
    +        True
    +        >>> SortedDict({'alpha': 1, 'beta': 2}) == d
    +        True
    +        >>> SortedDict(alpha=1, beta=2) == d
    +        True
    +
    +        """
    +        if args and (args[0] is None or callable(args[0])):
    +            _key = self._key = args[0]
    +            args = args[1:]
    +        else:
    +            _key = self._key = None
    +
    +        self._list = SortedList(key=_key)
    +
    +        # Reaching through ``self._list`` repeatedly adds unnecessary overhead
    +        # so cache references to sorted list methods.
    +
    +        _list = self._list
    +        self._list_add = _list.add
    +        self._list_clear = _list.clear
    +        self._list_iter = _list.__iter__
    +        self._list_reversed = _list.__reversed__
    +        self._list_pop = _list.pop
    +        self._list_remove = _list.remove
    +        self._list_update = _list.update
    +
    +        # Expose some sorted list methods publicly.
    +
    +        self.bisect_left = _list.bisect_left
    +        self.bisect = _list.bisect_right
    +        self.bisect_right = _list.bisect_right
    +        self.index = _list.index
    +        self.irange = _list.irange
    +        self.islice = _list.islice
    +        self._reset = _list._reset
    +
    +        if _key is not None:
    +            self.bisect_key_left = _list.bisect_key_left
    +            self.bisect_key_right = _list.bisect_key_right
    +            self.bisect_key = _list.bisect_key
    +            self.irange_key = _list.irange_key
    +
    +        self._update(*args, **kwargs)
    +
    +
    +    @property
    +    def key(self):
    +        """Function used to extract comparison key from keys.
    +
    +        Sorted dict compares keys directly when the key function is none.
    +
    +        """
    +        return self._key
    +
    +
    +    @property
    +    def iloc(self):
    +        """Cached reference of sorted keys view.
    +
    +        Deprecated in version 2 of Sorted Containers. Use
    +        :func:`SortedDict.keys` instead.
    +
    +        """
    +        # pylint: disable=attribute-defined-outside-init
    +        try:
    +            return self._iloc
    +        except AttributeError:
    +            warnings.warn(
    +                'sorted_dict.iloc is deprecated.'
    +                ' Use SortedDict.keys() instead.',
    +                DeprecationWarning,
    +                stacklevel=2,
    +            )
    +            _iloc = self._iloc = SortedKeysView(self)
    +            return _iloc
    +
    +
    +    def clear(self):
    +
    +        """Remove all items from sorted dict.
    +
    +        Runtime complexity: `O(n)`
    +
    +        """
    +        dict.clear(self)
    +        self._list_clear()
    +
    +
    +    def __delitem__(self, key):
    +        """Remove item from sorted dict identified by `key`.
    +
    +        ``sd.__delitem__(key)`` <==> ``del sd[key]``
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sd = SortedDict({'a': 1, 'b': 2, 'c': 3})
    +        >>> del sd['b']
    +        >>> sd
    +        SortedDict({'a': 1, 'c': 3})
    +        >>> del sd['z']
    +        Traceback (most recent call last):
    +          ...
    +        KeyError: 'z'
    +
    +        :param key: `key` for item lookup
    +        :raises KeyError: if key not found
    +
    +        """
    +        dict.__delitem__(self, key)
    +        self._list_remove(key)
    +
    +
    +    def __iter__(self):
    +        """Return an iterator over the keys of the sorted dict.
    +
    +        ``sd.__iter__()`` <==> ``iter(sd)``
    +
    +        Iterating the sorted dict while adding or deleting items may raise a
    +        :exc:`RuntimeError` or fail to iterate over all keys.
    +
    +        """
    +        return self._list_iter()
    +
    +
    +    def __reversed__(self):
    +        """Return a reverse iterator over the keys of the sorted dict.
    +
    +        ``sd.__reversed__()`` <==> ``reversed(sd)``
    +
    +        Iterating the sorted dict while adding or deleting items may raise a
    +        :exc:`RuntimeError` or fail to iterate over all keys.
    +
    +        """
    +        return self._list_reversed()
    +
    +
    +    def __setitem__(self, key, value):
    +        """Store item in sorted dict with `key` and corresponding `value`.
    +
    +        ``sd.__setitem__(key, value)`` <==> ``sd[key] = value``
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sd = SortedDict()
    +        >>> sd['c'] = 3
    +        >>> sd['a'] = 1
    +        >>> sd['b'] = 2
    +        >>> sd
    +        SortedDict({'a': 1, 'b': 2, 'c': 3})
    +
    +        :param key: key for item
    +        :param value: value for item
    +
    +        """
    +        if key not in self:
    +            self._list_add(key)
    +        dict.__setitem__(self, key, value)
    +
    +    _setitem = __setitem__
    +
    +
    +    def __or__(self, other):
    +        if not isinstance(other, Mapping):
    +            return NotImplemented
    +        items = chain(self.items(), other.items())
    +        return self.__class__(self._key, items)
    +
    +
    +    def __ror__(self, other):
    +        if not isinstance(other, Mapping):
    +            return NotImplemented
    +        items = chain(other.items(), self.items())
    +        return self.__class__(self._key, items)
    +
    +
    +    def __ior__(self, other):
    +        self._update(other)
    +        return self
    +
    +
    +    def copy(self):
    +        """Return a shallow copy of the sorted dict.
    +
    +        Runtime complexity: `O(n)`
    +
    +        :return: new sorted dict
    +
    +        """
    +        return self.__class__(self._key, self.items())
    +
    +    __copy__ = copy
    +
    +
    +    @classmethod
    +    def fromkeys(cls, iterable, value=None):
    +        """Return a new sorted dict initailized from `iterable` and `value`.
    +
    +        Items in the sorted dict have keys from `iterable` and values equal to
    +        `value`.
    +
    +        Runtime complexity: `O(n*log(n))`
    +
    +        :return: new sorted dict
    +
    +        """
    +        return cls((key, value) for key in iterable)
    +
    +
    +    def keys(self):
    +        """Return new sorted keys view of the sorted dict's keys.
    +
    +        See :class:`SortedKeysView` for details.
    +
    +        :return: new sorted keys view
    +
    +        """
    +        return SortedKeysView(self)
    +
    +
    +    def items(self):
    +        """Return new sorted items view of the sorted dict's items.
    +
    +        See :class:`SortedItemsView` for details.
    +
    +        :return: new sorted items view
    +
    +        """
    +        return SortedItemsView(self)
    +
    +
    +    def values(self):
    +        """Return new sorted values view of the sorted dict's values.
    +
    +        See :class:`SortedValuesView` for details.
    +
    +        :return: new sorted values view
    +
    +        """
    +        return SortedValuesView(self)
    +
    +
    +    if sys.hexversion < 0x03000000:
    +        def __make_raise_attributeerror(original, alternate):
    +            # pylint: disable=no-self-argument
    +            message = (
    +                'SortedDict.{original}() is not implemented.'
    +                ' Use SortedDict.{alternate}() instead.'
    +            ).format(original=original, alternate=alternate)
    +            def method(self):
    +                # pylint: disable=missing-docstring,unused-argument
    +                raise AttributeError(message)
    +            method.__name__ = original  # pylint: disable=non-str-assignment-to-dunder-name
    +            method.__doc__ = message
    +            return property(method)
    +
    +        iteritems = __make_raise_attributeerror('iteritems', 'items')
    +        iterkeys = __make_raise_attributeerror('iterkeys', 'keys')
    +        itervalues = __make_raise_attributeerror('itervalues', 'values')
    +        viewitems = __make_raise_attributeerror('viewitems', 'items')
    +        viewkeys = __make_raise_attributeerror('viewkeys', 'keys')
    +        viewvalues = __make_raise_attributeerror('viewvalues', 'values')
    +
    +
    +    class _NotGiven(object):
    +        # pylint: disable=too-few-public-methods
    +        def __repr__(self):
    +            return '<not-given>'
    +
    +    __not_given = _NotGiven()
    +
    +    def pop(self, key, default=__not_given):
    +        """Remove and return value for item identified by `key`.
    +
    +        If the `key` is not found then return `default` if given. If `default`
    +        is not given then raise :exc:`KeyError`.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sd = SortedDict({'a': 1, 'b': 2, 'c': 3})
    +        >>> sd.pop('c')
    +        3
    +        >>> sd.pop('z', 26)
    +        26
    +        >>> sd.pop('y')
    +        Traceback (most recent call last):
    +          ...
    +        KeyError: 'y'
    +
    +        :param key: `key` for item
    +        :param default: `default` value if key not found (optional)
    +        :return: value for item
    +        :raises KeyError: if `key` not found and `default` not given
    +
    +        """
    +        if key in self:
    +            self._list_remove(key)
    +            return dict.pop(self, key)
    +        else:
    +            if default is self.__not_given:
    +                raise KeyError(key)
    +            return default
    +
    +
    +    def popitem(self, index=-1):
    +        """Remove and return ``(key, value)`` pair at `index` from sorted dict.
    +
    +        Optional argument `index` defaults to -1, the last item in the sorted
    +        dict. Specify ``index=0`` for the first item in the sorted dict.
    +
    +        If the sorted dict is empty, raises :exc:`KeyError`.
    +
    +        If the `index` is out of range, raises :exc:`IndexError`.
    +
    +        Runtime complexity: `O(log(n))`
    +
    +        >>> sd = SortedDict({'a': 1, 'b': 2, 'c': 3})
    +        >>> sd.popitem()
    +        ('c', 3)
    +        >>> sd.popitem(0)
    +        ('a', 1)
    +        >>> sd.popitem(100)
    +        Traceback (most recent call last):
    +          ...
    +        IndexError: list index out of range
    +
    +        :param int index: `index` of item (default -1)
    +        :return: key and value pair
    +        :raises KeyError: if sorted dict is empty
    +        :raises IndexError: if `index` out of range
    +
    +        """
    +        if not self:
    +            raise KeyError('popitem(): dictionary is empty')
    +
    +        key = self._list_pop(index)
    +        value = dict.pop(self, key)
    +        return (key, value)
    +
    +
    +    def peekitem(self, index=-1):
    +        """Return ``(key, value)`` pair at `index` in sorted dict.
    +
    +        Optional argument `index` defaults to -1, the last item in the sorted
    +        dict. Specify ``index=0`` for the first item in the sorted dict.
    +
    +        Unlike :func:`SortedDict.popitem`, the sorted dict is not modified.
    +
    +        If the `index` is out of range, raises :exc:`IndexError`.
    +
    +        Runtime complexity: `O(log(n))`
    +
    +        >>> sd = SortedDict({'a': 1, 'b': 2, 'c': 3})
    +        >>> sd.peekitem()
    +        ('c', 3)
    +        >>> sd.peekitem(0)
    +        ('a', 1)
    +        >>> sd.peekitem(100)
    +        Traceback (most recent call last):
    +          ...
    +        IndexError: list index out of range
    +
    +        :param int index: index of item (default -1)
    +        :return: key and value pair
    +        :raises IndexError: if `index` out of range
    +
    +        """
    +        key = self._list[index]
    +        return key, self[key]
    +
    +
    +    def setdefault(self, key, default=None):
    +        """Return value for item identified by `key` in sorted dict.
    +
    +        If `key` is in the sorted dict then return its value. If `key` is not
    +        in the sorted dict then insert `key` with value `default` and return
    +        `default`.
    +
    +        Optional argument `default` defaults to none.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sd = SortedDict()
    +        >>> sd.setdefault('a', 1)
    +        1
    +        >>> sd.setdefault('a', 10)
    +        1
    +        >>> sd
    +        SortedDict({'a': 1})
    +
    +        :param key: key for item
    +        :param default: value for item (default None)
    +        :return: value for item identified by `key`
    +
    +        """
    +        if key in self:
    +            return self[key]
    +        dict.__setitem__(self, key, default)
    +        self._list_add(key)
    +        return default
    +
    +
    +    def update(self, *args, **kwargs):
    +        """Update sorted dict with items from `args` and `kwargs`.
    +
    +        Overwrites existing items.
    +
    +        Optional arguments `args` and `kwargs` may be a mapping, an iterable of
    +        pairs or keyword arguments. See :func:`SortedDict.__init__` for
    +        details.
    +
    +        :param args: mapping or iterable of pairs
    +        :param kwargs: keyword arguments mapping
    +
    +        """
    +        if not self:
    +            dict.update(self, *args, **kwargs)
    +            self._list_update(dict.__iter__(self))
    +            return
    +
    +        if not kwargs and len(args) == 1 and isinstance(args[0], dict):
    +            pairs = args[0]
    +        else:
    +            pairs = dict(*args, **kwargs)
    +
    +        if (10 * len(pairs)) > len(self):
    +            dict.update(self, pairs)
    +            self._list_clear()
    +            self._list_update(dict.__iter__(self))
    +        else:
    +            for key in pairs:
    +                self._setitem(key, pairs[key])
    +
    +    _update = update
    +
    +
    +    def __reduce__(self):
    +        """Support for pickle.
    +
    +        The tricks played with caching references in
    +        :func:`SortedDict.__init__` confuse pickle so customize the reducer.
    +
    +        """
    +        items = dict.copy(self)
    +        return (type(self), (self._key, items))
    +
    +
    +    @recursive_repr()
    +    def __repr__(self):
    +        """Return string representation of sorted dict.
    +
    +        ``sd.__repr__()`` <==> ``repr(sd)``
    +
    +        :return: string representation
    +
    +        """
    +        _key = self._key
    +        type_name = type(self).__name__
    +        key_arg = '' if _key is None else '{0!r}, '.format(_key)
    +        item_format = '{0!r}: {1!r}'.format
    +        items = ', '.join(item_format(key, self[key]) for key in self._list)
    +        return '{0}({1}{{{2}}})'.format(type_name, key_arg, items)
    +
    +
    +    def _check(self):
    +        """Check invariants of sorted dict.
    +
    +        Runtime complexity: `O(n)`
    +
    +        """
    +        _list = self._list
    +        _list._check()
    +        assert len(self) == len(_list)
    +        assert all(key in self for key in _list)
    +
    +
    +def _view_delitem(self, index):
    +    """Remove item at `index` from sorted dict.
    +
    +    ``view.__delitem__(index)`` <==> ``del view[index]``
    +
    +    Supports slicing.
    +
    +    Runtime complexity: `O(log(n))` -- approximate.
    +
    +    >>> sd = SortedDict({'a': 1, 'b': 2, 'c': 3})
    +    >>> view = sd.keys()
    +    >>> del view[0]
    +    >>> sd
    +    SortedDict({'b': 2, 'c': 3})
    +    >>> del view[-1]
    +    >>> sd
    +    SortedDict({'b': 2})
    +    >>> del view[:]
    +    >>> sd
    +    SortedDict({})
    +
    +    :param index: integer or slice for indexing
    +    :raises IndexError: if index out of range
    +
    +    """
    +    _mapping = self._mapping
    +    _list = _mapping._list
    +    dict_delitem = dict.__delitem__
    +    if isinstance(index, slice):
    +        keys = _list[index]
    +        del _list[index]
    +        for key in keys:
    +            dict_delitem(_mapping, key)
    +    else:
    +        key = _list.pop(index)
    +        dict_delitem(_mapping, key)
    +
    +
    +class SortedKeysView(KeysView, Sequence):
    +    """Sorted keys view is a dynamic view of the sorted dict's keys.
    +
    +    When the sorted dict's keys change, the view reflects those changes.
    +
    +    The keys view implements the set and sequence abstract base classes.
    +
    +    """
    +    __slots__ = ()
    +
    +
    +    @classmethod
    +    def _from_iterable(cls, it):
    +        return SortedSet(it)
    +
    +
    +    def __getitem__(self, index):
    +        """Lookup key at `index` in sorted keys views.
    +
    +        ``skv.__getitem__(index)`` <==> ``skv[index]``
    +
    +        Supports slicing.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sd = SortedDict({'a': 1, 'b': 2, 'c': 3})
    +        >>> skv = sd.keys()
    +        >>> skv[0]
    +        'a'
    +        >>> skv[-1]
    +        'c'
    +        >>> skv[:]
    +        ['a', 'b', 'c']
    +        >>> skv[100]
    +        Traceback (most recent call last):
    +          ...
    +        IndexError: list index out of range
    +
    +        :param index: integer or slice for indexing
    +        :return: key or list of keys
    +        :raises IndexError: if index out of range
    +
    +        """
    +        return self._mapping._list[index]
    +
    +
    +    __delitem__ = _view_delitem
    +
    +
    +class SortedItemsView(ItemsView, Sequence):
    +    """Sorted items view is a dynamic view of the sorted dict's items.
    +
    +    When the sorted dict's items change, the view reflects those changes.
    +
    +    The items view implements the set and sequence abstract base classes.
    +
    +    """
    +    __slots__ = ()
    +
    +
    +    @classmethod
    +    def _from_iterable(cls, it):
    +        return SortedSet(it)
    +
    +
    +    def __getitem__(self, index):
    +        """Lookup item at `index` in sorted items view.
    +
    +        ``siv.__getitem__(index)`` <==> ``siv[index]``
    +
    +        Supports slicing.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sd = SortedDict({'a': 1, 'b': 2, 'c': 3})
    +        >>> siv = sd.items()
    +        >>> siv[0]
    +        ('a', 1)
    +        >>> siv[-1]
    +        ('c', 3)
    +        >>> siv[:]
    +        [('a', 1), ('b', 2), ('c', 3)]
    +        >>> siv[100]
    +        Traceback (most recent call last):
    +          ...
    +        IndexError: list index out of range
    +
    +        :param index: integer or slice for indexing
    +        :return: item or list of items
    +        :raises IndexError: if index out of range
    +
    +        """
    +        _mapping = self._mapping
    +        _mapping_list = _mapping._list
    +
    +        if isinstance(index, slice):
    +            keys = _mapping_list[index]
    +            return [(key, _mapping[key]) for key in keys]
    +
    +        key = _mapping_list[index]
    +        return key, _mapping[key]
    +
    +
    +    __delitem__ = _view_delitem
    +
    +
    +class SortedValuesView(ValuesView, Sequence):
    +    """Sorted values view is a dynamic view of the sorted dict's values.
    +
    +    When the sorted dict's values change, the view reflects those changes.
    +
    +    The values view implements the sequence abstract base class.
    +
    +    """
    +    __slots__ = ()
    +
    +
    +    def __getitem__(self, index):
    +        """Lookup value at `index` in sorted values view.
    +
    +        ``siv.__getitem__(index)`` <==> ``siv[index]``
    +
    +        Supports slicing.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sd = SortedDict({'a': 1, 'b': 2, 'c': 3})
    +        >>> svv = sd.values()
    +        >>> svv[0]
    +        1
    +        >>> svv[-1]
    +        3
    +        >>> svv[:]
    +        [1, 2, 3]
    +        >>> svv[100]
    +        Traceback (most recent call last):
    +          ...
    +        IndexError: list index out of range
    +
    +        :param index: integer or slice for indexing
    +        :return: value or list of values
    +        :raises IndexError: if index out of range
    +
    +        """
    +        _mapping = self._mapping
    +        _mapping_list = _mapping._list
    +
    +        if isinstance(index, slice):
    +            keys = _mapping_list[index]
    +            return [_mapping[key] for key in keys]
    +
    +        key = _mapping_list[index]
    +        return _mapping[key]
    +
    +
    +    __delitem__ = _view_delitem
    diff --git a/deployment-apps/metricator-for-nmon/lib/sortedcontainers/sortedlist.py b/deployment-apps/metricator-for-nmon/lib/sortedcontainers/sortedlist.py
    new file mode 100644
    index 0000000..e3b58eb
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/sortedcontainers/sortedlist.py
    @@ -0,0 +1,2646 @@
    +"""Sorted List
    +==============
    +
    +:doc:`Sorted Containers<index>` is an Apache2 licensed Python sorted
    +collections library, written in pure-Python, and fast as C-extensions. The
    +:doc:`introduction<introduction>` is the best way to get started.
    +
    +Sorted list implementations:
    +
    +.. currentmodule:: sortedcontainers
    +
    +* :class:`SortedList`
    +* :class:`SortedKeyList`
    +
    +"""
    +# pylint: disable=too-many-lines
    +from __future__ import print_function
    +
    +import sys
    +import traceback
    +
    +from bisect import bisect_left, bisect_right, insort
    +from itertools import chain, repeat, starmap
    +from math import log
    +from operator import add, eq, ne, gt, ge, lt, le, iadd
    +from textwrap import dedent
    +
    +###############################################################################
    +# BEGIN Python 2/3 Shims
    +###############################################################################
    +
    +try:
    +    from collections.abc import Sequence, MutableSequence
    +except ImportError:
    +    from collections import Sequence, MutableSequence
    +
    +from functools import wraps
    +from sys import hexversion
    +
    +if hexversion < 0x03000000:
    +    from itertools import imap as map  # pylint: disable=redefined-builtin
    +    from itertools import izip as zip  # pylint: disable=redefined-builtin
    +    try:
    +        from thread import get_ident
    +    except ImportError:
    +        from dummy_thread import get_ident
    +else:
    +    from functools import reduce
    +    try:
    +        from _thread import get_ident
    +    except ImportError:
    +        from _dummy_thread import get_ident
    +
    +
    +def recursive_repr(fillvalue='...'):
    +    "Decorator to make a repr function return fillvalue for a recursive call."
    +    # pylint: disable=missing-docstring
    +    # Copied from reprlib in Python 3
    +    # https://hg.python.org/cpython/file/3.6/Lib/reprlib.py
    +
    +    def decorating_function(user_function):
    +        repr_running = set()
    +
    +        @wraps(user_function)
    +        def wrapper(self):
    +            key = id(self), get_ident()
    +            if key in repr_running:
    +                return fillvalue
    +            repr_running.add(key)
    +            try:
    +                result = user_function(self)
    +            finally:
    +                repr_running.discard(key)
    +            return result
    +
    +        return wrapper
    +
    +    return decorating_function
    +
    +###############################################################################
    +# END Python 2/3 Shims
    +###############################################################################
    +
    +
    +class SortedList(MutableSequence):
    +    """Sorted list is a sorted mutable sequence.
    +
    +    Sorted list values are maintained in sorted order.
    +
    +    Sorted list values must be comparable. The total ordering of values must
    +    not change while they are stored in the sorted list.
    +
    +    Methods for adding values:
    +
    +    * :func:`SortedList.add`
    +    * :func:`SortedList.update`
    +    * :func:`SortedList.__add__`
    +    * :func:`SortedList.__iadd__`
    +    * :func:`SortedList.__mul__`
    +    * :func:`SortedList.__imul__`
    +
    +    Methods for removing values:
    +
    +    * :func:`SortedList.clear`
    +    * :func:`SortedList.discard`
    +    * :func:`SortedList.remove`
    +    * :func:`SortedList.pop`
    +    * :func:`SortedList.__delitem__`
    +
    +    Methods for looking up values:
    +
    +    * :func:`SortedList.bisect_left`
    +    * :func:`SortedList.bisect_right`
    +    * :func:`SortedList.count`
    +    * :func:`SortedList.index`
    +    * :func:`SortedList.__contains__`
    +    * :func:`SortedList.__getitem__`
    +
    +    Methods for iterating values:
    +
    +    * :func:`SortedList.irange`
    +    * :func:`SortedList.islice`
    +    * :func:`SortedList.__iter__`
    +    * :func:`SortedList.__reversed__`
    +
    +    Methods for miscellany:
    +
    +    * :func:`SortedList.copy`
    +    * :func:`SortedList.__len__`
    +    * :func:`SortedList.__repr__`
    +    * :func:`SortedList._check`
    +    * :func:`SortedList._reset`
    +
    +    Sorted lists use lexicographical ordering semantics when compared to other
    +    sequences.
    +
    +    Some methods of mutable sequences are not supported and will raise
    +    not-implemented error.
    +
    +    """
    +    DEFAULT_LOAD_FACTOR = 1000
    +
    +
    +    def __init__(self, iterable=None, key=None):
    +        """Initialize sorted list instance.
    +
    +        Optional `iterable` argument provides an initial iterable of values to
    +        initialize the sorted list.
    +
    +        Runtime complexity: `O(n*log(n))`
    +
    +        >>> sl = SortedList()
    +        >>> sl
    +        SortedList([])
    +        >>> sl = SortedList([3, 1, 2, 5, 4])
    +        >>> sl
    +        SortedList([1, 2, 3, 4, 5])
    +
    +        :param iterable: initial values (optional)
    +
    +        """
    +        assert key is None
    +        self._len = 0
    +        self._load = self.DEFAULT_LOAD_FACTOR
    +        self._lists = []
    +        self._maxes = []
    +        self._index = []
    +        self._offset = 0
    +
    +        if iterable is not None:
    +            self._update(iterable)
    +
    +
    +    def __new__(cls, iterable=None, key=None):
    +        """Create new sorted list or sorted-key list instance.
    +
    +        Optional `key`-function argument will return an instance of subtype
    +        :class:`SortedKeyList`.
    +
    +        >>> sl = SortedList()
    +        >>> isinstance(sl, SortedList)
    +        True
    +        >>> sl = SortedList(key=lambda x: -x)
    +        >>> isinstance(sl, SortedList)
    +        True
    +        >>> isinstance(sl, SortedKeyList)
    +        True
    +
    +        :param iterable: initial values (optional)
    +        :param key: function used to extract comparison key (optional)
    +        :return: sorted list or sorted-key list instance
    +
    +        """
    +        # pylint: disable=unused-argument
    +        if key is None:
    +            return object.__new__(cls)
    +        else:
    +            if cls is SortedList:
    +                return object.__new__(SortedKeyList)
    +            else:
    +                raise TypeError('inherit SortedKeyList for key argument')
    +
    +
    +    @property
    +    def key(self):  # pylint: disable=useless-return
    +        """Function used to extract comparison key from values.
    +
    +        Sorted list compares values directly so the key function is none.
    +
    +        """
    +        return None
    +
    +
    +    def _reset(self, load):
    +        """Reset sorted list load factor.
    +
    +        The `load` specifies the load-factor of the list. The default load
    +        factor of 1000 works well for lists from tens to tens-of-millions of
    +        values. Good practice is to use a value that is the cube root of the
    +        list size. With billions of elements, the best load factor depends on
    +        your usage. It's best to leave the load factor at the default until you
    +        start benchmarking.
    +
    +        See :doc:`implementation` and :doc:`performance-scale` for more
    +        information.
    +
    +        Runtime complexity: `O(n)`
    +
    +        :param int load: load-factor for sorted list sublists
    +
    +        """
    +        values = reduce(iadd, self._lists, [])
    +        self._clear()
    +        self._load = load
    +        self._update(values)
    +
    +
    +    def clear(self):
    +        """Remove all values from sorted list.
    +
    +        Runtime complexity: `O(n)`
    +
    +        """
    +        self._len = 0
    +        del self._lists[:]
    +        del self._maxes[:]
    +        del self._index[:]
    +        self._offset = 0
    +
    +    _clear = clear
    +
    +
    +    def add(self, value):
    +        """Add `value` to sorted list.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sl = SortedList()
    +        >>> sl.add(3)
    +        >>> sl.add(1)
    +        >>> sl.add(2)
    +        >>> sl
    +        SortedList([1, 2, 3])
    +
    +        :param value: value to add to sorted list
    +
    +        """
    +        _lists = self._lists
    +        _maxes = self._maxes
    +
    +        if _maxes:
    +            pos = bisect_right(_maxes, value)
    +
    +            if pos == len(_maxes):
    +                pos -= 1
    +                _lists[pos].append(value)
    +                _maxes[pos] = value
    +            else:
    +                insort(_lists[pos], value)
    +
    +            self._expand(pos)
    +        else:
    +            _lists.append([value])
    +            _maxes.append(value)
    +
    +        self._len += 1
    +
    +
    +    def _expand(self, pos):
    +        """Split sublists with length greater than double the load-factor.
    +
    +        Updates the index when the sublist length is less than double the load
    +        level. This requires incrementing the nodes in a traversal from the
    +        leaf node to the root. For an example traversal see
    +        ``SortedList._loc``.
    +
    +        """
    +        _load = self._load
    +        _lists = self._lists
    +        _index = self._index
    +
    +        if len(_lists[pos]) > (_load << 1):
    +            _maxes = self._maxes
    +
    +            _lists_pos = _lists[pos]
    +            half = _lists_pos[_load:]
    +            del _lists_pos[_load:]
    +            _maxes[pos] = _lists_pos[-1]
    +
    +            _lists.insert(pos + 1, half)
    +            _maxes.insert(pos + 1, half[-1])
    +
    +            del _index[:]
    +        else:
    +            if _index:
    +                child = self._offset + pos
    +                while child:
    +                    _index[child] += 1
    +                    child = (child - 1) >> 1
    +                _index[0] += 1
    +
    +
    +    def update(self, iterable):
    +        """Update sorted list by adding all values from `iterable`.
    +
    +        Runtime complexity: `O(k*log(n))` -- approximate.
    +
    +        >>> sl = SortedList()
    +        >>> sl.update([3, 1, 2])
    +        >>> sl
    +        SortedList([1, 2, 3])
    +
    +        :param iterable: iterable of values to add
    +
    +        """
    +        _lists = self._lists
    +        _maxes = self._maxes
    +        values = sorted(iterable)
    +
    +        if _maxes:
    +            if len(values) * 4 >= self._len:
    +                _lists.append(values)
    +                values = reduce(iadd, _lists, [])
    +                values.sort()
    +                self._clear()
    +            else:
    +                _add = self.add
    +                for val in values:
    +                    _add(val)
    +                return
    +
    +        _load = self._load
    +        _lists.extend(values[pos:(pos + _load)]
    +                      for pos in range(0, len(values), _load))
    +        _maxes.extend(sublist[-1] for sublist in _lists)
    +        self._len = len(values)
    +        del self._index[:]
    +
    +    _update = update
    +
    +
    +    def __contains__(self, value):
    +        """Return true if `value` is an element of the sorted list.
    +
    +        ``sl.__contains__(value)`` <==> ``value in sl``
    +
    +        Runtime complexity: `O(log(n))`
    +
    +        >>> sl = SortedList([1, 2, 3, 4, 5])
    +        >>> 3 in sl
    +        True
    +
    +        :param value: search for value in sorted list
    +        :return: true if `value` in sorted list
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            return False
    +
    +        pos = bisect_left(_maxes, value)
    +
    +        if pos == len(_maxes):
    +            return False
    +
    +        _lists = self._lists
    +        idx = bisect_left(_lists[pos], value)
    +
    +        return _lists[pos][idx] == value
    +
    +
    +    def discard(self, value):
    +        """Remove `value` from sorted list if it is a member.
    +
    +        If `value` is not a member, do nothing.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sl = SortedList([1, 2, 3, 4, 5])
    +        >>> sl.discard(5)
    +        >>> sl.discard(0)
    +        >>> sl == [1, 2, 3, 4]
    +        True
    +
    +        :param value: `value` to discard from sorted list
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            return
    +
    +        pos = bisect_left(_maxes, value)
    +
    +        if pos == len(_maxes):
    +            return
    +
    +        _lists = self._lists
    +        idx = bisect_left(_lists[pos], value)
    +
    +        if _lists[pos][idx] == value:
    +            self._delete(pos, idx)
    +
    +
    +    def remove(self, value):
    +        """Remove `value` from sorted list; `value` must be a member.
    +
    +        If `value` is not a member, raise ValueError.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sl = SortedList([1, 2, 3, 4, 5])
    +        >>> sl.remove(5)
    +        >>> sl == [1, 2, 3, 4]
    +        True
    +        >>> sl.remove(0)
    +        Traceback (most recent call last):
    +          ...
    +        ValueError: 0 not in list
    +
    +        :param value: `value` to remove from sorted list
    +        :raises ValueError: if `value` is not in sorted list
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            raise ValueError('{0!r} not in list'.format(value))
    +
    +        pos = bisect_left(_maxes, value)
    +
    +        if pos == len(_maxes):
    +            raise ValueError('{0!r} not in list'.format(value))
    +
    +        _lists = self._lists
    +        idx = bisect_left(_lists[pos], value)
    +
    +        if _lists[pos][idx] == value:
    +            self._delete(pos, idx)
    +        else:
    +            raise ValueError('{0!r} not in list'.format(value))
    +
    +
    +    def _delete(self, pos, idx):
    +        """Delete value at the given `(pos, idx)`.
    +
    +        Combines lists that are less than half the load level.
    +
    +        Updates the index when the sublist length is more than half the load
    +        level. This requires decrementing the nodes in a traversal from the
    +        leaf node to the root. For an example traversal see
    +        ``SortedList._loc``.
    +
    +        :param int pos: lists index
    +        :param int idx: sublist index
    +
    +        """
    +        _lists = self._lists
    +        _maxes = self._maxes
    +        _index = self._index
    +
    +        _lists_pos = _lists[pos]
    +
    +        del _lists_pos[idx]
    +        self._len -= 1
    +
    +        len_lists_pos = len(_lists_pos)
    +
    +        if len_lists_pos > (self._load >> 1):
    +            _maxes[pos] = _lists_pos[-1]
    +
    +            if _index:
    +                child = self._offset + pos
    +                while child > 0:
    +                    _index[child] -= 1
    +                    child = (child - 1) >> 1
    +                _index[0] -= 1
    +        elif len(_lists) > 1:
    +            if not pos:
    +                pos += 1
    +
    +            prev = pos - 1
    +            _lists[prev].extend(_lists[pos])
    +            _maxes[prev] = _lists[prev][-1]
    +
    +            del _lists[pos]
    +            del _maxes[pos]
    +            del _index[:]
    +
    +            self._expand(prev)
    +        elif len_lists_pos:
    +            _maxes[pos] = _lists_pos[-1]
    +        else:
    +            del _lists[pos]
    +            del _maxes[pos]
    +            del _index[:]
    +
    +
    +    def _loc(self, pos, idx):
    +        """Convert an index pair (lists index, sublist index) into a single
    +        index number that corresponds to the position of the value in the
    +        sorted list.
    +
    +        Many queries require the index be built. Details of the index are
    +        described in ``SortedList._build_index``.
    +
    +        Indexing requires traversing the tree from a leaf node to the root. The
    +        parent of each node is easily computable at ``(pos - 1) // 2``.
    +
    +        Left-child nodes are always at odd indices and right-child nodes are
    +        always at even indices.
    +
    +        When traversing up from a right-child node, increment the total by the
    +        left-child node.
    +
    +        The final index is the sum from traversal and the index in the sublist.
    +
    +        For example, using the index from ``SortedList._build_index``::
    +
    +            _index = 14 5 9 3 2 4 5
    +            _offset = 3
    +
    +        Tree::
    +
    +                 14
    +              5      9
    +            3   2  4   5
    +
    +        Converting an index pair (2, 3) into a single index involves iterating
    +        like so:
    +
    +        1. Starting at the leaf node: offset + alpha = 3 + 2 = 5. We identify
    +           the node as a left-child node. At such nodes, we simply traverse to
    +           the parent.
    +
    +        2. At node 9, position 2, we recognize the node as a right-child node
    +           and accumulate the left-child in our total. Total is now 5 and we
    +           traverse to the parent at position 0.
    +
    +        3. Iteration ends at the root.
    +
    +        The index is then the sum of the total and sublist index: 5 + 3 = 8.
    +
    +        :param int pos: lists index
    +        :param int idx: sublist index
    +        :return: index in sorted list
    +
    +        """
    +        if not pos:
    +            return idx
    +
    +        _index = self._index
    +
    +        if not _index:
    +            self._build_index()
    +
    +        total = 0
    +
    +        # Increment pos to point in the index to len(self._lists[pos]).
    +
    +        pos += self._offset
    +
    +        # Iterate until reaching the root of the index tree at pos = 0.
    +
    +        while pos:
    +
    +            # Right-child nodes are at odd indices. At such indices
    +            # account the total below the left child node.
    +
    +            if not pos & 1:
    +                total += _index[pos - 1]
    +
    +            # Advance pos to the parent node.
    +
    +            pos = (pos - 1) >> 1
    +
    +        return total + idx
    +
    +
    +    def _pos(self, idx):
    +        """Convert an index into an index pair (lists index, sublist index)
    +        that can be used to access the corresponding lists position.
    +
    +        Many queries require the index be built. Details of the index are
    +        described in ``SortedList._build_index``.
    +
    +        Indexing requires traversing the tree to a leaf node. Each node has two
    +        children which are easily computable. Given an index, pos, the
    +        left-child is at ``pos * 2 + 1`` and the right-child is at ``pos * 2 +
    +        2``.
    +
    +        When the index is less than the left-child, traversal moves to the
    +        left sub-tree. Otherwise, the index is decremented by the left-child
    +        and traversal moves to the right sub-tree.
    +
    +        At a child node, the indexing pair is computed from the relative
    +        position of the child node as compared with the offset and the remaining
    +        index.
    +
    +        For example, using the index from ``SortedList._build_index``::
    +
    +            _index = 14 5 9 3 2 4 5
    +            _offset = 3
    +
    +        Tree::
    +
    +                 14
    +              5      9
    +            3   2  4   5
    +
    +        Indexing position 8 involves iterating like so:
    +
    +        1. Starting at the root, position 0, 8 is compared with the left-child
    +           node (5) which it is greater than. When greater the index is
    +           decremented and the position is updated to the right child node.
    +
    +        2. At node 9 with index 3, we again compare the index to the left-child
    +           node with value 4. Because the index is the less than the left-child
    +           node, we simply traverse to the left.
    +
    +        3. At node 4 with index 3, we recognize that we are at a leaf node and
    +           stop iterating.
    +
    +        4. To compute the sublist index, we subtract the offset from the index
    +           of the leaf node: 5 - 3 = 2. To compute the index in the sublist, we
    +           simply use the index remaining from iteration. In this case, 3.
    +
    +        The final index pair from our example is (2, 3) which corresponds to
    +        index 8 in the sorted list.
    +
    +        :param int idx: index in sorted list
    +        :return: (lists index, sublist index) pair
    +
    +        """
    +        if idx < 0:
    +            last_len = len(self._lists[-1])
    +
    +            if (-idx) <= last_len:
    +                return len(self._lists) - 1, last_len + idx
    +
    +            idx += self._len
    +
    +            if idx < 0:
    +                raise IndexError('list index out of range')
    +        elif idx >= self._len:
    +            raise IndexError('list index out of range')
    +
    +        if idx < len(self._lists[0]):
    +            return 0, idx
    +
    +        _index = self._index
    +
    +        if not _index:
    +            self._build_index()
    +
    +        pos = 0
    +        child = 1
    +        len_index = len(_index)
    +
    +        while child < len_index:
    +            index_child = _index[child]
    +
    +            if idx < index_child:
    +                pos = child
    +            else:
    +                idx -= index_child
    +                pos = child + 1
    +
    +            child = (pos << 1) + 1
    +
    +        return (pos - self._offset, idx)
    +
    +
    +    def _build_index(self):
    +        """Build a positional index for indexing the sorted list.
    +
    +        Indexes are represented as binary trees in a dense array notation
    +        similar to a binary heap.
    +
    +        For example, given a lists representation storing integers::
    +
    +            0: [1, 2, 3]
    +            1: [4, 5]
    +            2: [6, 7, 8, 9]
    +            3: [10, 11, 12, 13, 14]
    +
    +        The first transformation maps the sub-lists by their length. The
    +        first row of the index is the length of the sub-lists::
    +
    +            0: [3, 2, 4, 5]
    +
    +        Each row after that is the sum of consecutive pairs of the previous
    +        row::
    +
    +            1: [5, 9]
    +            2: [14]
    +
    +        Finally, the index is built by concatenating these lists together::
    +
    +            _index = [14, 5, 9, 3, 2, 4, 5]
    +
    +        An offset storing the start of the first row is also stored::
    +
    +            _offset = 3
    +
    +        When built, the index can be used for efficient indexing into the list.
    +        See the comment and notes on ``SortedList._pos`` for details.
    +
    +        """
    +        row0 = list(map(len, self._lists))
    +
    +        if len(row0) == 1:
    +            self._index[:] = row0
    +            self._offset = 0
    +            return
    +
    +        head = iter(row0)
    +        tail = iter(head)
    +        row1 = list(starmap(add, zip(head, tail)))
    +
    +        if len(row0) & 1:
    +            row1.append(row0[-1])
    +
    +        if len(row1) == 1:
    +            self._index[:] = row1 + row0
    +            self._offset = 1
    +            return
    +
    +        size = 2 ** (int(log(len(row1) - 1, 2)) + 1)
    +        row1.extend(repeat(0, size - len(row1)))
    +        tree = [row0, row1]
    +
    +        while len(tree[-1]) > 1:
    +            head = iter(tree[-1])
    +            tail = iter(head)
    +            row = list(starmap(add, zip(head, tail)))
    +            tree.append(row)
    +
    +        reduce(iadd, reversed(tree), self._index)
    +        self._offset = size * 2 - 1
    +
    +
    +    def __delitem__(self, index):
    +        """Remove value at `index` from sorted list.
    +
    +        ``sl.__delitem__(index)`` <==> ``del sl[index]``
    +
    +        Supports slicing.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sl = SortedList('abcde')
    +        >>> del sl[2]
    +        >>> sl
    +        SortedList(['a', 'b', 'd', 'e'])
    +        >>> del sl[:2]
    +        >>> sl
    +        SortedList(['d', 'e'])
    +
    +        :param index: integer or slice for indexing
    +        :raises IndexError: if index out of range
    +
    +        """
    +        if isinstance(index, slice):
    +            start, stop, step = index.indices(self._len)
    +
    +            if step == 1 and start < stop:
    +                if start == 0 and stop == self._len:
    +                    return self._clear()
    +                elif self._len <= 8 * (stop - start):
    +                    values = self._getitem(slice(None, start))
    +                    if stop < self._len:
    +                        values += self._getitem(slice(stop, None))
    +                    self._clear()
    +                    return self._update(values)
    +
    +            indices = range(start, stop, step)
    +
    +            # Delete items from greatest index to least so
    +            # that the indices remain valid throughout iteration.
    +
    +            if step > 0:
    +                indices = reversed(indices)
    +
    +            _pos, _delete = self._pos, self._delete
    +
    +            for index in indices:
    +                pos, idx = _pos(index)
    +                _delete(pos, idx)
    +        else:
    +            pos, idx = self._pos(index)
    +            self._delete(pos, idx)
    +
    +
    +    def __getitem__(self, index):
    +        """Lookup value at `index` in sorted list.
    +
    +        ``sl.__getitem__(index)`` <==> ``sl[index]``
    +
    +        Supports slicing.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sl = SortedList('abcde')
    +        >>> sl[1]
    +        'b'
    +        >>> sl[-1]
    +        'e'
    +        >>> sl[2:5]
    +        ['c', 'd', 'e']
    +
    +        :param index: integer or slice for indexing
    +        :return: value or list of values
    +        :raises IndexError: if index out of range
    +
    +        """
    +        _lists = self._lists
    +
    +        if isinstance(index, slice):
    +            start, stop, step = index.indices(self._len)
    +
    +            if step == 1 and start < stop:
    +                # Whole slice optimization: start to stop slices the whole
    +                # sorted list.
    +
    +                if start == 0 and stop == self._len:
    +                    return reduce(iadd, self._lists, [])
    +
    +                start_pos, start_idx = self._pos(start)
    +                start_list = _lists[start_pos]
    +                stop_idx = start_idx + stop - start
    +
    +                # Small slice optimization: start index and stop index are
    +                # within the start list.
    +
    +                if len(start_list) >= stop_idx:
    +                    return start_list[start_idx:stop_idx]
    +
    +                if stop == self._len:
    +                    stop_pos = len(_lists) - 1
    +                    stop_idx = len(_lists[stop_pos])
    +                else:
    +                    stop_pos, stop_idx = self._pos(stop)
    +
    +                prefix = _lists[start_pos][start_idx:]
    +                middle = _lists[(start_pos + 1):stop_pos]
    +                result = reduce(iadd, middle, prefix)
    +                result += _lists[stop_pos][:stop_idx]
    +
    +                return result
    +
    +            if step == -1 and start > stop:
    +                result = self._getitem(slice(stop + 1, start + 1))
    +                result.reverse()
    +                return result
    +
    +            # Return a list because a negative step could
    +            # reverse the order of the items and this could
    +            # be the desired behavior.
    +
    +            indices = range(start, stop, step)
    +            return list(self._getitem(index) for index in indices)
    +        else:
    +            if self._len:
    +                if index == 0:
    +                    return _lists[0][0]
    +                elif index == -1:
    +                    return _lists[-1][-1]
    +            else:
    +                raise IndexError('list index out of range')
    +
    +            if 0 <= index < len(_lists[0]):
    +                return _lists[0][index]
    +
    +            len_last = len(_lists[-1])
    +
    +            if -len_last < index < 0:
    +                return _lists[-1][len_last + index]
    +
    +            pos, idx = self._pos(index)
    +            return _lists[pos][idx]
    +
    +    _getitem = __getitem__
    +
    +
    +    def __setitem__(self, index, value):
    +        """Raise not-implemented error.
    +
    +        ``sl.__setitem__(index, value)`` <==> ``sl[index] = value``
    +
    +        :raises NotImplementedError: use ``del sl[index]`` and
    +            ``sl.add(value)`` instead
    +
    +        """
    +        message = 'use ``del sl[index]`` and ``sl.add(value)`` instead'
    +        raise NotImplementedError(message)
    +
    +
    +    def __iter__(self):
    +        """Return an iterator over the sorted list.
    +
    +        ``sl.__iter__()`` <==> ``iter(sl)``
    +
    +        Iterating the sorted list while adding or deleting values may raise a
    +        :exc:`RuntimeError` or fail to iterate over all values.
    +
    +        """
    +        return chain.from_iterable(self._lists)
    +
    +
    +    def __reversed__(self):
    +        """Return a reverse iterator over the sorted list.
    +
    +        ``sl.__reversed__()`` <==> ``reversed(sl)``
    +
    +        Iterating the sorted list while adding or deleting values may raise a
    +        :exc:`RuntimeError` or fail to iterate over all values.
    +
    +        """
    +        return chain.from_iterable(map(reversed, reversed(self._lists)))
    +
    +
    +    def reverse(self):
    +        """Raise not-implemented error.
    +
    +        Sorted list maintains values in ascending sort order. Values may not be
    +        reversed in-place.
    +
    +        Use ``reversed(sl)`` for an iterator over values in descending sort
    +        order.
    +
    +        Implemented to override `MutableSequence.reverse` which provides an
    +        erroneous default implementation.
    +
    +        :raises NotImplementedError: use ``reversed(sl)`` instead
    +
    +        """
    +        raise NotImplementedError('use ``reversed(sl)`` instead')
    +
    +
    +    def islice(self, start=None, stop=None, reverse=False):
    +        """Return an iterator that slices sorted list from `start` to `stop`.
    +
    +        The `start` and `stop` index are treated inclusive and exclusive,
    +        respectively.
    +
    +        Both `start` and `stop` default to `None` which is automatically
    +        inclusive of the beginning and end of the sorted list.
    +
    +        When `reverse` is `True` the values are yielded from the iterator in
    +        reverse order; `reverse` defaults to `False`.
    +
    +        >>> sl = SortedList('abcdefghij')
    +        >>> it = sl.islice(2, 6)
    +        >>> list(it)
    +        ['c', 'd', 'e', 'f']
    +
    +        :param int start: start index (inclusive)
    +        :param int stop: stop index (exclusive)
    +        :param bool reverse: yield values in reverse order
    +        :return: iterator
    +
    +        """
    +        _len = self._len
    +
    +        if not _len:
    +            return iter(())
    +
    +        start, stop, _ = slice(start, stop).indices(self._len)
    +
    +        if start >= stop:
    +            return iter(())
    +
    +        _pos = self._pos
    +
    +        min_pos, min_idx = _pos(start)
    +
    +        if stop == _len:
    +            max_pos = len(self._lists) - 1
    +            max_idx = len(self._lists[-1])
    +        else:
    +            max_pos, max_idx = _pos(stop)
    +
    +        return self._islice(min_pos, min_idx, max_pos, max_idx, reverse)
    +
    +
    +    def _islice(self, min_pos, min_idx, max_pos, max_idx, reverse):
    +        """Return an iterator that slices sorted list using two index pairs.
    +
    +        The index pairs are (min_pos, min_idx) and (max_pos, max_idx), the
    +        first inclusive and the latter exclusive. See `_pos` for details on how
    +        an index is converted to an index pair.
    +
    +        When `reverse` is `True`, values are yielded from the iterator in
    +        reverse order.
    +
    +        """
    +        _lists = self._lists
    +
    +        if min_pos > max_pos:
    +            return iter(())
    +
    +        if min_pos == max_pos:
    +            if reverse:
    +                indices = reversed(range(min_idx, max_idx))
    +                return map(_lists[min_pos].__getitem__, indices)
    +
    +            indices = range(min_idx, max_idx)
    +            return map(_lists[min_pos].__getitem__, indices)
    +
    +        next_pos = min_pos + 1
    +
    +        if next_pos == max_pos:
    +            if reverse:
    +                min_indices = range(min_idx, len(_lists[min_pos]))
    +                max_indices = range(max_idx)
    +                return chain(
    +                    map(_lists[max_pos].__getitem__, reversed(max_indices)),
    +                    map(_lists[min_pos].__getitem__, reversed(min_indices)),
    +                )
    +
    +            min_indices = range(min_idx, len(_lists[min_pos]))
    +            max_indices = range(max_idx)
    +            return chain(
    +                map(_lists[min_pos].__getitem__, min_indices),
    +                map(_lists[max_pos].__getitem__, max_indices),
    +            )
    +
    +        if reverse:
    +            min_indices = range(min_idx, len(_lists[min_pos]))
    +            sublist_indices = range(next_pos, max_pos)
    +            sublists = map(_lists.__getitem__, reversed(sublist_indices))
    +            max_indices = range(max_idx)
    +            return chain(
    +                map(_lists[max_pos].__getitem__, reversed(max_indices)),
    +                chain.from_iterable(map(reversed, sublists)),
    +                map(_lists[min_pos].__getitem__, reversed(min_indices)),
    +            )
    +
    +        min_indices = range(min_idx, len(_lists[min_pos]))
    +        sublist_indices = range(next_pos, max_pos)
    +        sublists = map(_lists.__getitem__, sublist_indices)
    +        max_indices = range(max_idx)
    +        return chain(
    +            map(_lists[min_pos].__getitem__, min_indices),
    +            chain.from_iterable(sublists),
    +            map(_lists[max_pos].__getitem__, max_indices),
    +        )
    +
    +
    +    def irange(self, minimum=None, maximum=None, inclusive=(True, True),
    +               reverse=False):
    +        """Create an iterator of values between `minimum` and `maximum`.
    +
    +        Both `minimum` and `maximum` default to `None` which is automatically
    +        inclusive of the beginning and end of the sorted list.
    +
    +        The argument `inclusive` is a pair of booleans that indicates whether
    +        the minimum and maximum ought to be included in the range,
    +        respectively. The default is ``(True, True)`` such that the range is
    +        inclusive of both minimum and maximum.
    +
    +        When `reverse` is `True` the values are yielded from the iterator in
    +        reverse order; `reverse` defaults to `False`.
    +
    +        >>> sl = SortedList('abcdefghij')
    +        >>> it = sl.irange('c', 'f')
    +        >>> list(it)
    +        ['c', 'd', 'e', 'f']
    +
    +        :param minimum: minimum value to start iterating
    +        :param maximum: maximum value to stop iterating
    +        :param inclusive: pair of booleans
    +        :param bool reverse: yield values in reverse order
    +        :return: iterator
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            return iter(())
    +
    +        _lists = self._lists
    +
    +        # Calculate the minimum (pos, idx) pair. By default this location
    +        # will be inclusive in our calculation.
    +
    +        if minimum is None:
    +            min_pos = 0
    +            min_idx = 0
    +        else:
    +            if inclusive[0]:
    +                min_pos = bisect_left(_maxes, minimum)
    +
    +                if min_pos == len(_maxes):
    +                    return iter(())
    +
    +                min_idx = bisect_left(_lists[min_pos], minimum)
    +            else:
    +                min_pos = bisect_right(_maxes, minimum)
    +
    +                if min_pos == len(_maxes):
    +                    return iter(())
    +
    +                min_idx = bisect_right(_lists[min_pos], minimum)
    +
    +        # Calculate the maximum (pos, idx) pair. By default this location
    +        # will be exclusive in our calculation.
    +
    +        if maximum is None:
    +            max_pos = len(_maxes) - 1
    +            max_idx = len(_lists[max_pos])
    +        else:
    +            if inclusive[1]:
    +                max_pos = bisect_right(_maxes, maximum)
    +
    +                if max_pos == len(_maxes):
    +                    max_pos -= 1
    +                    max_idx = len(_lists[max_pos])
    +                else:
    +                    max_idx = bisect_right(_lists[max_pos], maximum)
    +            else:
    +                max_pos = bisect_left(_maxes, maximum)
    +
    +                if max_pos == len(_maxes):
    +                    max_pos -= 1
    +                    max_idx = len(_lists[max_pos])
    +                else:
    +                    max_idx = bisect_left(_lists[max_pos], maximum)
    +
    +        return self._islice(min_pos, min_idx, max_pos, max_idx, reverse)
    +
    +
    +    def __len__(self):
    +        """Return the size of the sorted list.
    +
    +        ``sl.__len__()`` <==> ``len(sl)``
    +
    +        :return: size of sorted list
    +
    +        """
    +        return self._len
    +
    +
    +    def bisect_left(self, value):
    +        """Return an index to insert `value` in the sorted list.
    +
    +        If the `value` is already present, the insertion point will be before
    +        (to the left of) any existing values.
    +
    +        Similar to the `bisect` module in the standard library.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sl = SortedList([10, 11, 12, 13, 14])
    +        >>> sl.bisect_left(12)
    +        2
    +
    +        :param value: insertion index of value in sorted list
    +        :return: index
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            return 0
    +
    +        pos = bisect_left(_maxes, value)
    +
    +        if pos == len(_maxes):
    +            return self._len
    +
    +        idx = bisect_left(self._lists[pos], value)
    +        return self._loc(pos, idx)
    +
    +
    +    def bisect_right(self, value):
    +        """Return an index to insert `value` in the sorted list.
    +
    +        Similar to `bisect_left`, but if `value` is already present, the
    +        insertion point will be after (to the right of) any existing values.
    +
    +        Similar to the `bisect` module in the standard library.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sl = SortedList([10, 11, 12, 13, 14])
    +        >>> sl.bisect_right(12)
    +        3
    +
    +        :param value: insertion index of value in sorted list
    +        :return: index
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            return 0
    +
    +        pos = bisect_right(_maxes, value)
    +
    +        if pos == len(_maxes):
    +            return self._len
    +
    +        idx = bisect_right(self._lists[pos], value)
    +        return self._loc(pos, idx)
    +
    +    bisect = bisect_right
    +    _bisect_right = bisect_right
    +
    +
    +    def count(self, value):
    +        """Return number of occurrences of `value` in the sorted list.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sl = SortedList([1, 2, 2, 3, 3, 3, 4, 4, 4, 4])
    +        >>> sl.count(3)
    +        3
    +
    +        :param value: value to count in sorted list
    +        :return: count
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            return 0
    +
    +        pos_left = bisect_left(_maxes, value)
    +
    +        if pos_left == len(_maxes):
    +            return 0
    +
    +        _lists = self._lists
    +        idx_left = bisect_left(_lists[pos_left], value)
    +        pos_right = bisect_right(_maxes, value)
    +
    +        if pos_right == len(_maxes):
    +            return self._len - self._loc(pos_left, idx_left)
    +
    +        idx_right = bisect_right(_lists[pos_right], value)
    +
    +        if pos_left == pos_right:
    +            return idx_right - idx_left
    +
    +        right = self._loc(pos_right, idx_right)
    +        left = self._loc(pos_left, idx_left)
    +        return right - left
    +
    +
    +    def copy(self):
    +        """Return a shallow copy of the sorted list.
    +
    +        Runtime complexity: `O(n)`
    +
    +        :return: new sorted list
    +
    +        """
    +        return self.__class__(self)
    +
    +    __copy__ = copy
    +
    +
    +    def append(self, value):
    +        """Raise not-implemented error.
    +
    +        Implemented to override `MutableSequence.append` which provides an
    +        erroneous default implementation.
    +
    +        :raises NotImplementedError: use ``sl.add(value)`` instead
    +
    +        """
    +        raise NotImplementedError('use ``sl.add(value)`` instead')
    +
    +
    +    def extend(self, values):
    +        """Raise not-implemented error.
    +
    +        Implemented to override `MutableSequence.extend` which provides an
    +        erroneous default implementation.
    +
    +        :raises NotImplementedError: use ``sl.update(values)`` instead
    +
    +        """
    +        raise NotImplementedError('use ``sl.update(values)`` instead')
    +
    +
    +    def insert(self, index, value):
    +        """Raise not-implemented error.
    +
    +        :raises NotImplementedError: use ``sl.add(value)`` instead
    +
    +        """
    +        raise NotImplementedError('use ``sl.add(value)`` instead')
    +
    +
    +    def pop(self, index=-1):
    +        """Remove and return value at `index` in sorted list.
    +
    +        Raise :exc:`IndexError` if the sorted list is empty or index is out of
    +        range.
    +
    +        Negative indices are supported.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sl = SortedList('abcde')
    +        >>> sl.pop()
    +        'e'
    +        >>> sl.pop(2)
    +        'c'
    +        >>> sl
    +        SortedList(['a', 'b', 'd'])
    +
    +        :param int index: index of value (default -1)
    +        :return: value
    +        :raises IndexError: if index is out of range
    +
    +        """
    +        if not self._len:
    +            raise IndexError('pop index out of range')
    +
    +        _lists = self._lists
    +
    +        if index == 0:
    +            val = _lists[0][0]
    +            self._delete(0, 0)
    +            return val
    +
    +        if index == -1:
    +            pos = len(_lists) - 1
    +            loc = len(_lists[pos]) - 1
    +            val = _lists[pos][loc]
    +            self._delete(pos, loc)
    +            return val
    +
    +        if 0 <= index < len(_lists[0]):
    +            val = _lists[0][index]
    +            self._delete(0, index)
    +            return val
    +
    +        len_last = len(_lists[-1])
    +
    +        if -len_last < index < 0:
    +            pos = len(_lists) - 1
    +            loc = len_last + index
    +            val = _lists[pos][loc]
    +            self._delete(pos, loc)
    +            return val
    +
    +        pos, idx = self._pos(index)
    +        val = _lists[pos][idx]
    +        self._delete(pos, idx)
    +        return val
    +
    +
    +    def index(self, value, start=None, stop=None):
    +        """Return first index of value in sorted list.
    +
    +        Raise ValueError if `value` is not present.
    +
    +        Index must be between `start` and `stop` for the `value` to be
    +        considered present. The default value, None, for `start` and `stop`
    +        indicate the beginning and end of the sorted list.
    +
    +        Negative indices are supported.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> sl = SortedList('abcde')
    +        >>> sl.index('d')
    +        3
    +        >>> sl.index('z')
    +        Traceback (most recent call last):
    +          ...
    +        ValueError: 'z' is not in list
    +
    +        :param value: value in sorted list
    +        :param int start: start index (default None, start of sorted list)
    +        :param int stop: stop index (default None, end of sorted list)
    +        :return: index of value
    +        :raises ValueError: if value is not present
    +
    +        """
    +        _len = self._len
    +
    +        if not _len:
    +            raise ValueError('{0!r} is not in list'.format(value))
    +
    +        if start is None:
    +            start = 0
    +        if start < 0:
    +            start += _len
    +        if start < 0:
    +            start = 0
    +
    +        if stop is None:
    +            stop = _len
    +        if stop < 0:
    +            stop += _len
    +        if stop > _len:
    +            stop = _len
    +
    +        if stop <= start:
    +            raise ValueError('{0!r} is not in list'.format(value))
    +
    +        _maxes = self._maxes
    +        pos_left = bisect_left(_maxes, value)
    +
    +        if pos_left == len(_maxes):
    +            raise ValueError('{0!r} is not in list'.format(value))
    +
    +        _lists = self._lists
    +        idx_left = bisect_left(_lists[pos_left], value)
    +
    +        if _lists[pos_left][idx_left] != value:
    +            raise ValueError('{0!r} is not in list'.format(value))
    +
    +        stop -= 1
    +        left = self._loc(pos_left, idx_left)
    +
    +        if start <= left:
    +            if left <= stop:
    +                return left
    +        else:
    +            right = self._bisect_right(value) - 1
    +
    +            if start <= right:
    +                return start
    +
    +        raise ValueError('{0!r} is not in list'.format(value))
    +
    +
    +    def __add__(self, other):
    +        """Return new sorted list containing all values in both sequences.
    +
    +        ``sl.__add__(other)`` <==> ``sl + other``
    +
    +        Values in `other` do not need to be in sorted order.
    +
    +        Runtime complexity: `O(n*log(n))`
    +
    +        >>> sl1 = SortedList('bat')
    +        >>> sl2 = SortedList('cat')
    +        >>> sl1 + sl2
    +        SortedList(['a', 'a', 'b', 'c', 't', 't'])
    +
    +        :param other: other iterable
    +        :return: new sorted list
    +
    +        """
    +        values = reduce(iadd, self._lists, [])
    +        values.extend(other)
    +        return self.__class__(values)
    +
    +    __radd__ = __add__
    +
    +
    +    def __iadd__(self, other):
    +        """Update sorted list with values from `other`.
    +
    +        ``sl.__iadd__(other)`` <==> ``sl += other``
    +
    +        Values in `other` do not need to be in sorted order.
    +
    +        Runtime complexity: `O(k*log(n))` -- approximate.
    +
    +        >>> sl = SortedList('bat')
    +        >>> sl += 'cat'
    +        >>> sl
    +        SortedList(['a', 'a', 'b', 'c', 't', 't'])
    +
    +        :param other: other iterable
    +        :return: existing sorted list
    +
    +        """
    +        self._update(other)
    +        return self
    +
    +
    +    def __mul__(self, num):
    +        """Return new sorted list with `num` shallow copies of values.
    +
    +        ``sl.__mul__(num)`` <==> ``sl * num``
    +
    +        Runtime complexity: `O(n*log(n))`
    +
    +        >>> sl = SortedList('abc')
    +        >>> sl * 3
    +        SortedList(['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c'])
    +
    +        :param int num: count of shallow copies
    +        :return: new sorted list
    +
    +        """
    +        values = reduce(iadd, self._lists, []) * num
    +        return self.__class__(values)
    +
    +    __rmul__ = __mul__
    +
    +
    +    def __imul__(self, num):
    +        """Update the sorted list with `num` shallow copies of values.
    +
    +        ``sl.__imul__(num)`` <==> ``sl *= num``
    +
    +        Runtime complexity: `O(n*log(n))`
    +
    +        >>> sl = SortedList('abc')
    +        >>> sl *= 3
    +        >>> sl
    +        SortedList(['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c'])
    +
    +        :param int num: count of shallow copies
    +        :return: existing sorted list
    +
    +        """
    +        values = reduce(iadd, self._lists, []) * num
    +        self._clear()
    +        self._update(values)
    +        return self
    +
    +
    +    def __make_cmp(seq_op, symbol, doc):
    +        "Make comparator method."
    +        def comparer(self, other):
    +            "Compare method for sorted list and sequence."
    +            if not isinstance(other, Sequence):
    +                return NotImplemented
    +
    +            self_len = self._len
    +            len_other = len(other)
    +
    +            if self_len != len_other:
    +                if seq_op is eq:
    +                    return False
    +                if seq_op is ne:
    +                    return True
    +
    +            for alpha, beta in zip(self, other):
    +                if alpha != beta:
    +                    return seq_op(alpha, beta)
    +
    +            return seq_op(self_len, len_other)
    +
    +        seq_op_name = seq_op.__name__
    +        comparer.__name__ = '__{0}__'.format(seq_op_name)
    +        doc_str = """Return true if and only if sorted list is {0} `other`.
    +
    +        ``sl.__{1}__(other)`` <==> ``sl {2} other``
    +
    +        Comparisons use lexicographical order as with sequences.
    +
    +        Runtime complexity: `O(n)`
    +
    +        :param other: `other` sequence
    +        :return: true if sorted list is {0} `other`
    +
    +        """
    +        comparer.__doc__ = dedent(doc_str.format(doc, seq_op_name, symbol))
    +        return comparer
    +
    +
    +    __eq__ = __make_cmp(eq, '==', 'equal to')
    +    __ne__ = __make_cmp(ne, '!=', 'not equal to')
    +    __lt__ = __make_cmp(lt, '<', 'less than')
    +    __gt__ = __make_cmp(gt, '>', 'greater than')
    +    __le__ = __make_cmp(le, '<=', 'less than or equal to')
    +    __ge__ = __make_cmp(ge, '>=', 'greater than or equal to')
    +    __make_cmp = staticmethod(__make_cmp)
    +
    +
    +    def __reduce__(self):
    +        values = reduce(iadd, self._lists, [])
    +        return (type(self), (values,))
    +
    +
    +    @recursive_repr()
    +    def __repr__(self):
    +        """Return string representation of sorted list.
    +
    +        ``sl.__repr__()`` <==> ``repr(sl)``
    +
    +        :return: string representation
    +
    +        """
    +        return '{0}({1!r})'.format(type(self).__name__, list(self))
    +
    +
    +    def _check(self):
    +        """Check invariants of sorted list.
    +
    +        Runtime complexity: `O(n)`
    +
    +        """
    +        try:
    +            assert self._load >= 4
    +            assert len(self._maxes) == len(self._lists)
    +            assert self._len == sum(len(sublist) for sublist in self._lists)
    +
    +            # Check all sublists are sorted.
    +
    +            for sublist in self._lists:
    +                for pos in range(1, len(sublist)):
    +                    assert sublist[pos - 1] <= sublist[pos]
    +
    +            # Check beginning/end of sublists are sorted.
    +
    +            for pos in range(1, len(self._lists)):
    +                assert self._lists[pos - 1][-1] <= self._lists[pos][0]
    +
    +            # Check _maxes index is the last value of each sublist.
    +
    +            for pos in range(len(self._maxes)):
    +                assert self._maxes[pos] == self._lists[pos][-1]
    +
    +            # Check sublist lengths are less than double load-factor.
    +
    +            double = self._load << 1
    +            assert all(len(sublist) <= double for sublist in self._lists)
    +
    +            # Check sublist lengths are greater than half load-factor for all
    +            # but the last sublist.
    +
    +            half = self._load >> 1
    +            for pos in range(0, len(self._lists) - 1):
    +                assert len(self._lists[pos]) >= half
    +
    +            if self._index:
    +                assert self._len == self._index[0]
    +                assert len(self._index) == self._offset + len(self._lists)
    +
    +                # Check index leaf nodes equal length of sublists.
    +
    +                for pos in range(len(self._lists)):
    +                    leaf = self._index[self._offset + pos]
    +                    assert leaf == len(self._lists[pos])
    +
    +                # Check index branch nodes are the sum of their children.
    +
    +                for pos in range(self._offset):
    +                    child = (pos << 1) + 1
    +                    if child >= len(self._index):
    +                        assert self._index[pos] == 0
    +                    elif child + 1 == len(self._index):
    +                        assert self._index[pos] == self._index[child]
    +                    else:
    +                        child_sum = self._index[child] + self._index[child + 1]
    +                        assert child_sum == self._index[pos]
    +        except:
    +            traceback.print_exc(file=sys.stdout)
    +            print('len', self._len)
    +            print('load', self._load)
    +            print('offset', self._offset)
    +            print('len_index', len(self._index))
    +            print('index', self._index)
    +            print('len_maxes', len(self._maxes))
    +            print('maxes', self._maxes)
    +            print('len_lists', len(self._lists))
    +            print('lists', self._lists)
    +            raise
    +
    +
    +def identity(value):
    +    "Identity function."
    +    return value
    +
    +
    +class SortedKeyList(SortedList):
    +    """Sorted-key list is a subtype of sorted list.
    +
    +    The sorted-key list maintains values in comparison order based on the
    +    result of a key function applied to every value.
    +
    +    All the same methods that are available in :class:`SortedList` are also
    +    available in :class:`SortedKeyList`.
    +
    +    Additional methods provided:
    +
    +    * :attr:`SortedKeyList.key`
    +    * :func:`SortedKeyList.bisect_key_left`
    +    * :func:`SortedKeyList.bisect_key_right`
    +    * :func:`SortedKeyList.irange_key`
    +
    +    Some examples below use:
    +
    +    >>> from operator import neg
    +    >>> neg
    +    <built-in function neg>
    +    >>> neg(1)
    +    -1
    +
    +    """
    +    def __init__(self, iterable=None, key=identity):
    +        """Initialize sorted-key list instance.
    +
    +        Optional `iterable` argument provides an initial iterable of values to
    +        initialize the sorted-key list.
    +
    +        Optional `key` argument defines a callable that, like the `key`
    +        argument to Python's `sorted` function, extracts a comparison key from
    +        each value. The default is the identity function.
    +
    +        Runtime complexity: `O(n*log(n))`
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList(key=neg)
    +        >>> skl
    +        SortedKeyList([], key=<built-in function neg>)
    +        >>> skl = SortedKeyList([3, 1, 2], key=neg)
    +        >>> skl
    +        SortedKeyList([3, 2, 1], key=<built-in function neg>)
    +
    +        :param iterable: initial values (optional)
    +        :param key: function used to extract comparison key (optional)
    +
    +        """
    +        self._key = key
    +        self._len = 0
    +        self._load = self.DEFAULT_LOAD_FACTOR
    +        self._lists = []
    +        self._keys = []
    +        self._maxes = []
    +        self._index = []
    +        self._offset = 0
    +
    +        if iterable is not None:
    +            self._update(iterable)
    +
    +
    +    def __new__(cls, iterable=None, key=identity):
    +        return object.__new__(cls)
    +
    +
    +    @property
    +    def key(self):
    +        "Function used to extract comparison key from values."
    +        return self._key
    +
    +
    +    def clear(self):
    +        """Remove all values from sorted-key list.
    +
    +        Runtime complexity: `O(n)`
    +
    +        """
    +        self._len = 0
    +        del self._lists[:]
    +        del self._keys[:]
    +        del self._maxes[:]
    +        del self._index[:]
    +
    +    _clear = clear
    +
    +
    +    def add(self, value):
    +        """Add `value` to sorted-key list.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList(key=neg)
    +        >>> skl.add(3)
    +        >>> skl.add(1)
    +        >>> skl.add(2)
    +        >>> skl
    +        SortedKeyList([3, 2, 1], key=<built-in function neg>)
    +
    +        :param value: value to add to sorted-key list
    +
    +        """
    +        _lists = self._lists
    +        _keys = self._keys
    +        _maxes = self._maxes
    +
    +        key = self._key(value)
    +
    +        if _maxes:
    +            pos = bisect_right(_maxes, key)
    +
    +            if pos == len(_maxes):
    +                pos -= 1
    +                _lists[pos].append(value)
    +                _keys[pos].append(key)
    +                _maxes[pos] = key
    +            else:
    +                idx = bisect_right(_keys[pos], key)
    +                _lists[pos].insert(idx, value)
    +                _keys[pos].insert(idx, key)
    +
    +            self._expand(pos)
    +        else:
    +            _lists.append([value])
    +            _keys.append([key])
    +            _maxes.append(key)
    +
    +        self._len += 1
    +
    +
    +    def _expand(self, pos):
    +        """Split sublists with length greater than double the load-factor.
    +
    +        Updates the index when the sublist length is less than double the load
    +        level. This requires incrementing the nodes in a traversal from the
    +        leaf node to the root. For an example traversal see
    +        ``SortedList._loc``.
    +
    +        """
    +        _lists = self._lists
    +        _keys = self._keys
    +        _index = self._index
    +
    +        if len(_keys[pos]) > (self._load << 1):
    +            _maxes = self._maxes
    +            _load = self._load
    +
    +            _lists_pos = _lists[pos]
    +            _keys_pos = _keys[pos]
    +            half = _lists_pos[_load:]
    +            half_keys = _keys_pos[_load:]
    +            del _lists_pos[_load:]
    +            del _keys_pos[_load:]
    +            _maxes[pos] = _keys_pos[-1]
    +
    +            _lists.insert(pos + 1, half)
    +            _keys.insert(pos + 1, half_keys)
    +            _maxes.insert(pos + 1, half_keys[-1])
    +
    +            del _index[:]
    +        else:
    +            if _index:
    +                child = self._offset + pos
    +                while child:
    +                    _index[child] += 1
    +                    child = (child - 1) >> 1
    +                _index[0] += 1
    +
    +
    +    def update(self, iterable):
    +        """Update sorted-key list by adding all values from `iterable`.
    +
    +        Runtime complexity: `O(k*log(n))` -- approximate.
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList(key=neg)
    +        >>> skl.update([3, 1, 2])
    +        >>> skl
    +        SortedKeyList([3, 2, 1], key=<built-in function neg>)
    +
    +        :param iterable: iterable of values to add
    +
    +        """
    +        _lists = self._lists
    +        _keys = self._keys
    +        _maxes = self._maxes
    +        values = sorted(iterable, key=self._key)
    +
    +        if _maxes:
    +            if len(values) * 4 >= self._len:
    +                _lists.append(values)
    +                values = reduce(iadd, _lists, [])
    +                values.sort(key=self._key)
    +                self._clear()
    +            else:
    +                _add = self.add
    +                for val in values:
    +                    _add(val)
    +                return
    +
    +        _load = self._load
    +        _lists.extend(values[pos:(pos + _load)]
    +                      for pos in range(0, len(values), _load))
    +        _keys.extend(list(map(self._key, _list)) for _list in _lists)
    +        _maxes.extend(sublist[-1] for sublist in _keys)
    +        self._len = len(values)
    +        del self._index[:]
    +
    +    _update = update
    +
    +
    +    def __contains__(self, value):
    +        """Return true if `value` is an element of the sorted-key list.
    +
    +        ``skl.__contains__(value)`` <==> ``value in skl``
    +
    +        Runtime complexity: `O(log(n))`
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList([1, 2, 3, 4, 5], key=neg)
    +        >>> 3 in skl
    +        True
    +
    +        :param value: search for value in sorted-key list
    +        :return: true if `value` in sorted-key list
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            return False
    +
    +        key = self._key(value)
    +        pos = bisect_left(_maxes, key)
    +
    +        if pos == len(_maxes):
    +            return False
    +
    +        _lists = self._lists
    +        _keys = self._keys
    +
    +        idx = bisect_left(_keys[pos], key)
    +
    +        len_keys = len(_keys)
    +        len_sublist = len(_keys[pos])
    +
    +        while True:
    +            if _keys[pos][idx] != key:
    +                return False
    +            if _lists[pos][idx] == value:
    +                return True
    +            idx += 1
    +            if idx == len_sublist:
    +                pos += 1
    +                if pos == len_keys:
    +                    return False
    +                len_sublist = len(_keys[pos])
    +                idx = 0
    +
    +
    +    def discard(self, value):
    +        """Remove `value` from sorted-key list if it is a member.
    +
    +        If `value` is not a member, do nothing.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList([5, 4, 3, 2, 1], key=neg)
    +        >>> skl.discard(1)
    +        >>> skl.discard(0)
    +        >>> skl == [5, 4, 3, 2]
    +        True
    +
    +        :param value: `value` to discard from sorted-key list
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            return
    +
    +        key = self._key(value)
    +        pos = bisect_left(_maxes, key)
    +
    +        if pos == len(_maxes):
    +            return
    +
    +        _lists = self._lists
    +        _keys = self._keys
    +        idx = bisect_left(_keys[pos], key)
    +        len_keys = len(_keys)
    +        len_sublist = len(_keys[pos])
    +
    +        while True:
    +            if _keys[pos][idx] != key:
    +                return
    +            if _lists[pos][idx] == value:
    +                self._delete(pos, idx)
    +                return
    +            idx += 1
    +            if idx == len_sublist:
    +                pos += 1
    +                if pos == len_keys:
    +                    return
    +                len_sublist = len(_keys[pos])
    +                idx = 0
    +
    +
    +    def remove(self, value):
    +        """Remove `value` from sorted-key list; `value` must be a member.
    +
    +        If `value` is not a member, raise ValueError.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList([1, 2, 3, 4, 5], key=neg)
    +        >>> skl.remove(5)
    +        >>> skl == [4, 3, 2, 1]
    +        True
    +        >>> skl.remove(0)
    +        Traceback (most recent call last):
    +          ...
    +        ValueError: 0 not in list
    +
    +        :param value: `value` to remove from sorted-key list
    +        :raises ValueError: if `value` is not in sorted-key list
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            raise ValueError('{0!r} not in list'.format(value))
    +
    +        key = self._key(value)
    +        pos = bisect_left(_maxes, key)
    +
    +        if pos == len(_maxes):
    +            raise ValueError('{0!r} not in list'.format(value))
    +
    +        _lists = self._lists
    +        _keys = self._keys
    +        idx = bisect_left(_keys[pos], key)
    +        len_keys = len(_keys)
    +        len_sublist = len(_keys[pos])
    +
    +        while True:
    +            if _keys[pos][idx] != key:
    +                raise ValueError('{0!r} not in list'.format(value))
    +            if _lists[pos][idx] == value:
    +                self._delete(pos, idx)
    +                return
    +            idx += 1
    +            if idx == len_sublist:
    +                pos += 1
    +                if pos == len_keys:
    +                    raise ValueError('{0!r} not in list'.format(value))
    +                len_sublist = len(_keys[pos])
    +                idx = 0
    +
    +
    +    def _delete(self, pos, idx):
    +        """Delete value at the given `(pos, idx)`.
    +
    +        Combines lists that are less than half the load level.
    +
    +        Updates the index when the sublist length is more than half the load
    +        level. This requires decrementing the nodes in a traversal from the
    +        leaf node to the root. For an example traversal see
    +        ``SortedList._loc``.
    +
    +        :param int pos: lists index
    +        :param int idx: sublist index
    +
    +        """
    +        _lists = self._lists
    +        _keys = self._keys
    +        _maxes = self._maxes
    +        _index = self._index
    +        keys_pos = _keys[pos]
    +        lists_pos = _lists[pos]
    +
    +        del keys_pos[idx]
    +        del lists_pos[idx]
    +        self._len -= 1
    +
    +        len_keys_pos = len(keys_pos)
    +
    +        if len_keys_pos > (self._load >> 1):
    +            _maxes[pos] = keys_pos[-1]
    +
    +            if _index:
    +                child = self._offset + pos
    +                while child > 0:
    +                    _index[child] -= 1
    +                    child = (child - 1) >> 1
    +                _index[0] -= 1
    +        elif len(_keys) > 1:
    +            if not pos:
    +                pos += 1
    +
    +            prev = pos - 1
    +            _keys[prev].extend(_keys[pos])
    +            _lists[prev].extend(_lists[pos])
    +            _maxes[prev] = _keys[prev][-1]
    +
    +            del _lists[pos]
    +            del _keys[pos]
    +            del _maxes[pos]
    +            del _index[:]
    +
    +            self._expand(prev)
    +        elif len_keys_pos:
    +            _maxes[pos] = keys_pos[-1]
    +        else:
    +            del _lists[pos]
    +            del _keys[pos]
    +            del _maxes[pos]
    +            del _index[:]
    +
    +
    +    def irange(self, minimum=None, maximum=None, inclusive=(True, True),
    +               reverse=False):
    +        """Create an iterator of values between `minimum` and `maximum`.
    +
    +        Both `minimum` and `maximum` default to `None` which is automatically
    +        inclusive of the beginning and end of the sorted-key list.
    +
    +        The argument `inclusive` is a pair of booleans that indicates whether
    +        the minimum and maximum ought to be included in the range,
    +        respectively. The default is ``(True, True)`` such that the range is
    +        inclusive of both minimum and maximum.
    +
    +        When `reverse` is `True` the values are yielded from the iterator in
    +        reverse order; `reverse` defaults to `False`.
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList([11, 12, 13, 14, 15], key=neg)
    +        >>> it = skl.irange(14.5, 11.5)
    +        >>> list(it)
    +        [14, 13, 12]
    +
    +        :param minimum: minimum value to start iterating
    +        :param maximum: maximum value to stop iterating
    +        :param inclusive: pair of booleans
    +        :param bool reverse: yield values in reverse order
    +        :return: iterator
    +
    +        """
    +        min_key = self._key(minimum) if minimum is not None else None
    +        max_key = self._key(maximum) if maximum is not None else None
    +        return self._irange_key(
    +            min_key=min_key, max_key=max_key,
    +            inclusive=inclusive, reverse=reverse,
    +        )
    +
    +
    +    def irange_key(self, min_key=None, max_key=None, inclusive=(True, True),
    +                   reverse=False):
    +        """Create an iterator of values between `min_key` and `max_key`.
    +
    +        Both `min_key` and `max_key` default to `None` which is automatically
    +        inclusive of the beginning and end of the sorted-key list.
    +
    +        The argument `inclusive` is a pair of booleans that indicates whether
    +        the minimum and maximum ought to be included in the range,
    +        respectively. The default is ``(True, True)`` such that the range is
    +        inclusive of both minimum and maximum.
    +
    +        When `reverse` is `True` the values are yielded from the iterator in
    +        reverse order; `reverse` defaults to `False`.
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList([11, 12, 13, 14, 15], key=neg)
    +        >>> it = skl.irange_key(-14, -12)
    +        >>> list(it)
    +        [14, 13, 12]
    +
    +        :param min_key: minimum key to start iterating
    +        :param max_key: maximum key to stop iterating
    +        :param inclusive: pair of booleans
    +        :param bool reverse: yield values in reverse order
    +        :return: iterator
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            return iter(())
    +
    +        _keys = self._keys
    +
    +        # Calculate the minimum (pos, idx) pair. By default this location
    +        # will be inclusive in our calculation.
    +
    +        if min_key is None:
    +            min_pos = 0
    +            min_idx = 0
    +        else:
    +            if inclusive[0]:
    +                min_pos = bisect_left(_maxes, min_key)
    +
    +                if min_pos == len(_maxes):
    +                    return iter(())
    +
    +                min_idx = bisect_left(_keys[min_pos], min_key)
    +            else:
    +                min_pos = bisect_right(_maxes, min_key)
    +
    +                if min_pos == len(_maxes):
    +                    return iter(())
    +
    +                min_idx = bisect_right(_keys[min_pos], min_key)
    +
    +        # Calculate the maximum (pos, idx) pair. By default this location
    +        # will be exclusive in our calculation.
    +
    +        if max_key is None:
    +            max_pos = len(_maxes) - 1
    +            max_idx = len(_keys[max_pos])
    +        else:
    +            if inclusive[1]:
    +                max_pos = bisect_right(_maxes, max_key)
    +
    +                if max_pos == len(_maxes):
    +                    max_pos -= 1
    +                    max_idx = len(_keys[max_pos])
    +                else:
    +                    max_idx = bisect_right(_keys[max_pos], max_key)
    +            else:
    +                max_pos = bisect_left(_maxes, max_key)
    +
    +                if max_pos == len(_maxes):
    +                    max_pos -= 1
    +                    max_idx = len(_keys[max_pos])
    +                else:
    +                    max_idx = bisect_left(_keys[max_pos], max_key)
    +
    +        return self._islice(min_pos, min_idx, max_pos, max_idx, reverse)
    +
    +    _irange_key = irange_key
    +
    +
    +    def bisect_left(self, value):
    +        """Return an index to insert `value` in the sorted-key list.
    +
    +        If the `value` is already present, the insertion point will be before
    +        (to the left of) any existing values.
    +
    +        Similar to the `bisect` module in the standard library.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList([5, 4, 3, 2, 1], key=neg)
    +        >>> skl.bisect_left(1)
    +        4
    +
    +        :param value: insertion index of value in sorted-key list
    +        :return: index
    +
    +        """
    +        return self._bisect_key_left(self._key(value))
    +
    +
    +    def bisect_right(self, value):
    +        """Return an index to insert `value` in the sorted-key list.
    +
    +        Similar to `bisect_left`, but if `value` is already present, the
    +        insertion point will be after (to the right of) any existing values.
    +
    +        Similar to the `bisect` module in the standard library.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> from operator import neg
    +        >>> skl = SortedList([5, 4, 3, 2, 1], key=neg)
    +        >>> skl.bisect_right(1)
    +        5
    +
    +        :param value: insertion index of value in sorted-key list
    +        :return: index
    +
    +        """
    +        return self._bisect_key_right(self._key(value))
    +
    +    bisect = bisect_right
    +
    +
    +    def bisect_key_left(self, key):
    +        """Return an index to insert `key` in the sorted-key list.
    +
    +        If the `key` is already present, the insertion point will be before (to
    +        the left of) any existing keys.
    +
    +        Similar to the `bisect` module in the standard library.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList([5, 4, 3, 2, 1], key=neg)
    +        >>> skl.bisect_key_left(-1)
    +        4
    +
    +        :param key: insertion index of key in sorted-key list
    +        :return: index
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            return 0
    +
    +        pos = bisect_left(_maxes, key)
    +
    +        if pos == len(_maxes):
    +            return self._len
    +
    +        idx = bisect_left(self._keys[pos], key)
    +
    +        return self._loc(pos, idx)
    +
    +    _bisect_key_left = bisect_key_left
    +
    +
    +    def bisect_key_right(self, key):
    +        """Return an index to insert `key` in the sorted-key list.
    +
    +        Similar to `bisect_key_left`, but if `key` is already present, the
    +        insertion point will be after (to the right of) any existing keys.
    +
    +        Similar to the `bisect` module in the standard library.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> from operator import neg
    +        >>> skl = SortedList([5, 4, 3, 2, 1], key=neg)
    +        >>> skl.bisect_key_right(-1)
    +        5
    +
    +        :param key: insertion index of key in sorted-key list
    +        :return: index
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            return 0
    +
    +        pos = bisect_right(_maxes, key)
    +
    +        if pos == len(_maxes):
    +            return self._len
    +
    +        idx = bisect_right(self._keys[pos], key)
    +
    +        return self._loc(pos, idx)
    +
    +    bisect_key = bisect_key_right
    +    _bisect_key_right = bisect_key_right
    +
    +
    +    def count(self, value):
    +        """Return number of occurrences of `value` in the sorted-key list.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList([4, 4, 4, 4, 3, 3, 3, 2, 2, 1], key=neg)
    +        >>> skl.count(2)
    +        2
    +
    +        :param value: value to count in sorted-key list
    +        :return: count
    +
    +        """
    +        _maxes = self._maxes
    +
    +        if not _maxes:
    +            return 0
    +
    +        key = self._key(value)
    +        pos = bisect_left(_maxes, key)
    +
    +        if pos == len(_maxes):
    +            return 0
    +
    +        _lists = self._lists
    +        _keys = self._keys
    +        idx = bisect_left(_keys[pos], key)
    +        total = 0
    +        len_keys = len(_keys)
    +        len_sublist = len(_keys[pos])
    +
    +        while True:
    +            if _keys[pos][idx] != key:
    +                return total
    +            if _lists[pos][idx] == value:
    +                total += 1
    +            idx += 1
    +            if idx == len_sublist:
    +                pos += 1
    +                if pos == len_keys:
    +                    return total
    +                len_sublist = len(_keys[pos])
    +                idx = 0
    +
    +
    +    def copy(self):
    +        """Return a shallow copy of the sorted-key list.
    +
    +        Runtime complexity: `O(n)`
    +
    +        :return: new sorted-key list
    +
    +        """
    +        return self.__class__(self, key=self._key)
    +
    +    __copy__ = copy
    +
    +
    +    def index(self, value, start=None, stop=None):
    +        """Return first index of value in sorted-key list.
    +
    +        Raise ValueError if `value` is not present.
    +
    +        Index must be between `start` and `stop` for the `value` to be
    +        considered present. The default value, None, for `start` and `stop`
    +        indicate the beginning and end of the sorted-key list.
    +
    +        Negative indices are supported.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList([5, 4, 3, 2, 1], key=neg)
    +        >>> skl.index(2)
    +        3
    +        >>> skl.index(0)
    +        Traceback (most recent call last):
    +          ...
    +        ValueError: 0 is not in list
    +
    +        :param value: value in sorted-key list
    +        :param int start: start index (default None, start of sorted-key list)
    +        :param int stop: stop index (default None, end of sorted-key list)
    +        :return: index of value
    +        :raises ValueError: if value is not present
    +
    +        """
    +        _len = self._len
    +
    +        if not _len:
    +            raise ValueError('{0!r} is not in list'.format(value))
    +
    +        if start is None:
    +            start = 0
    +        if start < 0:
    +            start += _len
    +        if start < 0:
    +            start = 0
    +
    +        if stop is None:
    +            stop = _len
    +        if stop < 0:
    +            stop += _len
    +        if stop > _len:
    +            stop = _len
    +
    +        if stop <= start:
    +            raise ValueError('{0!r} is not in list'.format(value))
    +
    +        _maxes = self._maxes
    +        key = self._key(value)
    +        pos = bisect_left(_maxes, key)
    +
    +        if pos == len(_maxes):
    +            raise ValueError('{0!r} is not in list'.format(value))
    +
    +        stop -= 1
    +        _lists = self._lists
    +        _keys = self._keys
    +        idx = bisect_left(_keys[pos], key)
    +        len_keys = len(_keys)
    +        len_sublist = len(_keys[pos])
    +
    +        while True:
    +            if _keys[pos][idx] != key:
    +                raise ValueError('{0!r} is not in list'.format(value))
    +            if _lists[pos][idx] == value:
    +                loc = self._loc(pos, idx)
    +                if start <= loc <= stop:
    +                    return loc
    +                elif loc > stop:
    +                    break
    +            idx += 1
    +            if idx == len_sublist:
    +                pos += 1
    +                if pos == len_keys:
    +                    raise ValueError('{0!r} is not in list'.format(value))
    +                len_sublist = len(_keys[pos])
    +                idx = 0
    +
    +        raise ValueError('{0!r} is not in list'.format(value))
    +
    +
    +    def __add__(self, other):
    +        """Return new sorted-key list containing all values in both sequences.
    +
    +        ``skl.__add__(other)`` <==> ``skl + other``
    +
    +        Values in `other` do not need to be in sorted-key order.
    +
    +        Runtime complexity: `O(n*log(n))`
    +
    +        >>> from operator import neg
    +        >>> skl1 = SortedKeyList([5, 4, 3], key=neg)
    +        >>> skl2 = SortedKeyList([2, 1, 0], key=neg)
    +        >>> skl1 + skl2
    +        SortedKeyList([5, 4, 3, 2, 1, 0], key=<built-in function neg>)
    +
    +        :param other: other iterable
    +        :return: new sorted-key list
    +
    +        """
    +        values = reduce(iadd, self._lists, [])
    +        values.extend(other)
    +        return self.__class__(values, key=self._key)
    +
    +    __radd__ = __add__
    +
    +
    +    def __mul__(self, num):
    +        """Return new sorted-key list with `num` shallow copies of values.
    +
    +        ``skl.__mul__(num)`` <==> ``skl * num``
    +
    +        Runtime complexity: `O(n*log(n))`
    +
    +        >>> from operator import neg
    +        >>> skl = SortedKeyList([3, 2, 1], key=neg)
    +        >>> skl * 2
    +        SortedKeyList([3, 3, 2, 2, 1, 1], key=<built-in function neg>)
    +
    +        :param int num: count of shallow copies
    +        :return: new sorted-key list
    +
    +        """
    +        values = reduce(iadd, self._lists, []) * num
    +        return self.__class__(values, key=self._key)
    +
    +
    +    def __reduce__(self):
    +        values = reduce(iadd, self._lists, [])
    +        return (type(self), (values, self.key))
    +
    +
    +    @recursive_repr()
    +    def __repr__(self):
    +        """Return string representation of sorted-key list.
    +
    +        ``skl.__repr__()`` <==> ``repr(skl)``
    +
    +        :return: string representation
    +
    +        """
    +        type_name = type(self).__name__
    +        return '{0}({1!r}, key={2!r})'.format(type_name, list(self), self._key)
    +
    +
    +    def _check(self):
    +        """Check invariants of sorted-key list.
    +
    +        Runtime complexity: `O(n)`
    +
    +        """
    +        try:
    +            assert self._load >= 4
    +            assert len(self._maxes) == len(self._lists) == len(self._keys)
    +            assert self._len == sum(len(sublist) for sublist in self._lists)
    +
    +            # Check all sublists are sorted.
    +
    +            for sublist in self._keys:
    +                for pos in range(1, len(sublist)):
    +                    assert sublist[pos - 1] <= sublist[pos]
    +
    +            # Check beginning/end of sublists are sorted.
    +
    +            for pos in range(1, len(self._keys)):
    +                assert self._keys[pos - 1][-1] <= self._keys[pos][0]
    +
    +            # Check _keys matches _key mapped to _lists.
    +
    +            for val_sublist, key_sublist in zip(self._lists, self._keys):
    +                assert len(val_sublist) == len(key_sublist)
    +                for val, key in zip(val_sublist, key_sublist):
    +                    assert self._key(val) == key
    +
    +            # Check _maxes index is the last value of each sublist.
    +
    +            for pos in range(len(self._maxes)):
    +                assert self._maxes[pos] == self._keys[pos][-1]
    +
    +            # Check sublist lengths are less than double load-factor.
    +
    +            double = self._load << 1
    +            assert all(len(sublist) <= double for sublist in self._lists)
    +
    +            # Check sublist lengths are greater than half load-factor for all
    +            # but the last sublist.
    +
    +            half = self._load >> 1
    +            for pos in range(0, len(self._lists) - 1):
    +                assert len(self._lists[pos]) >= half
    +
    +            if self._index:
    +                assert self._len == self._index[0]
    +                assert len(self._index) == self._offset + len(self._lists)
    +
    +                # Check index leaf nodes equal length of sublists.
    +
    +                for pos in range(len(self._lists)):
    +                    leaf = self._index[self._offset + pos]
    +                    assert leaf == len(self._lists[pos])
    +
    +                # Check index branch nodes are the sum of their children.
    +
    +                for pos in range(self._offset):
    +                    child = (pos << 1) + 1
    +                    if child >= len(self._index):
    +                        assert self._index[pos] == 0
    +                    elif child + 1 == len(self._index):
    +                        assert self._index[pos] == self._index[child]
    +                    else:
    +                        child_sum = self._index[child] + self._index[child + 1]
    +                        assert child_sum == self._index[pos]
    +        except:
    +            traceback.print_exc(file=sys.stdout)
    +            print('len', self._len)
    +            print('load', self._load)
    +            print('offset', self._offset)
    +            print('len_index', len(self._index))
    +            print('index', self._index)
    +            print('len_maxes', len(self._maxes))
    +            print('maxes', self._maxes)
    +            print('len_keys', len(self._keys))
    +            print('keys', self._keys)
    +            print('len_lists', len(self._lists))
    +            print('lists', self._lists)
    +            raise
    +
    +
    +SortedListWithKey = SortedKeyList
    diff --git a/deployment-apps/metricator-for-nmon/lib/sortedcontainers/sortedset.py b/deployment-apps/metricator-for-nmon/lib/sortedcontainers/sortedset.py
    new file mode 100644
    index 0000000..be2b899
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/sortedcontainers/sortedset.py
    @@ -0,0 +1,733 @@
    +"""Sorted Set
    +=============
    +
    +:doc:`Sorted Containers<index>` is an Apache2 licensed Python sorted
    +collections library, written in pure-Python, and fast as C-extensions. The
    +:doc:`introduction<introduction>` is the best way to get started.
    +
    +Sorted set implementations:
    +
    +.. currentmodule:: sortedcontainers
    +
    +* :class:`SortedSet`
    +
    +"""
    +
    +from itertools import chain
    +from operator import eq, ne, gt, ge, lt, le
    +from textwrap import dedent
    +
    +from .sortedlist import SortedList, recursive_repr
    +
    +###############################################################################
    +# BEGIN Python 2/3 Shims
    +###############################################################################
    +
    +try:
    +    from collections.abc import MutableSet, Sequence, Set
    +except ImportError:
    +    from collections import MutableSet, Sequence, Set
    +
    +###############################################################################
    +# END Python 2/3 Shims
    +###############################################################################
    +
    +
    +class SortedSet(MutableSet, Sequence):
    +    """Sorted set is a sorted mutable set.
    +
    +    Sorted set values are maintained in sorted order. The design of sorted set
    +    is simple: sorted set uses a set for set-operations and maintains a sorted
    +    list of values.
    +
    +    Sorted set values must be hashable and comparable. The hash and total
    +    ordering of values must not change while they are stored in the sorted set.
    +
    +    Mutable set methods:
    +
    +    * :func:`SortedSet.__contains__`
    +    * :func:`SortedSet.__iter__`
    +    * :func:`SortedSet.__len__`
    +    * :func:`SortedSet.add`
    +    * :func:`SortedSet.discard`
    +
    +    Sequence methods:
    +
    +    * :func:`SortedSet.__getitem__`
    +    * :func:`SortedSet.__delitem__`
    +    * :func:`SortedSet.__reversed__`
    +
    +    Methods for removing values:
    +
    +    * :func:`SortedSet.clear`
    +    * :func:`SortedSet.pop`
    +    * :func:`SortedSet.remove`
    +
    +    Set-operation methods:
    +
    +    * :func:`SortedSet.difference`
    +    * :func:`SortedSet.difference_update`
    +    * :func:`SortedSet.intersection`
    +    * :func:`SortedSet.intersection_update`
    +    * :func:`SortedSet.symmetric_difference`
    +    * :func:`SortedSet.symmetric_difference_update`
    +    * :func:`SortedSet.union`
    +    * :func:`SortedSet.update`
    +
    +    Methods for miscellany:
    +
    +    * :func:`SortedSet.copy`
    +    * :func:`SortedSet.count`
    +    * :func:`SortedSet.__repr__`
    +    * :func:`SortedSet._check`
    +
    +    Sorted list methods available:
    +
    +    * :func:`SortedList.bisect_left`
    +    * :func:`SortedList.bisect_right`
    +    * :func:`SortedList.index`
    +    * :func:`SortedList.irange`
    +    * :func:`SortedList.islice`
    +    * :func:`SortedList._reset`
    +
    +    Additional sorted list methods available, if key-function used:
    +
    +    * :func:`SortedKeyList.bisect_key_left`
    +    * :func:`SortedKeyList.bisect_key_right`
    +    * :func:`SortedKeyList.irange_key`
    +
    +    Sorted set comparisons use subset and superset relations. Two sorted sets
    +    are equal if and only if every element of each sorted set is contained in
    +    the other (each is a subset of the other). A sorted set is less than
    +    another sorted set if and only if the first sorted set is a proper subset
    +    of the second sorted set (is a subset, but is not equal). A sorted set is
    +    greater than another sorted set if and only if the first sorted set is a
    +    proper superset of the second sorted set (is a superset, but is not equal).
    +
    +    """
    +    def __init__(self, iterable=None, key=None):
    +        """Initialize sorted set instance.
    +
    +        Optional `iterable` argument provides an initial iterable of values to
    +        initialize the sorted set.
    +
    +        Optional `key` argument defines a callable that, like the `key`
    +        argument to Python's `sorted` function, extracts a comparison key from
    +        each value. The default, none, compares values directly.
    +
    +        Runtime complexity: `O(n*log(n))`
    +
    +        >>> ss = SortedSet([3, 1, 2, 5, 4])
    +        >>> ss
    +        SortedSet([1, 2, 3, 4, 5])
    +        >>> from operator import neg
    +        >>> ss = SortedSet([3, 1, 2, 5, 4], neg)
    +        >>> ss
    +        SortedSet([5, 4, 3, 2, 1], key=<built-in function neg>)
    +
    +        :param iterable: initial values (optional)
    +        :param key: function used to extract comparison key (optional)
    +
    +        """
    +        self._key = key
    +
    +        # SortedSet._fromset calls SortedSet.__init__ after initializing the
    +        # _set attribute. So only create a new set if the _set attribute is not
    +        # already present.
    +
    +        if not hasattr(self, '_set'):
    +            self._set = set()
    +
    +        self._list = SortedList(self._set, key=key)
    +
    +        # Expose some set methods publicly.
    +
    +        _set = self._set
    +        self.isdisjoint = _set.isdisjoint
    +        self.issubset = _set.issubset
    +        self.issuperset = _set.issuperset
    +
    +        # Expose some sorted list methods publicly.
    +
    +        _list = self._list
    +        self.bisect_left = _list.bisect_left
    +        self.bisect = _list.bisect
    +        self.bisect_right = _list.bisect_right
    +        self.index = _list.index
    +        self.irange = _list.irange
    +        self.islice = _list.islice
    +        self._reset = _list._reset
    +
    +        if key is not None:
    +            self.bisect_key_left = _list.bisect_key_left
    +            self.bisect_key_right = _list.bisect_key_right
    +            self.bisect_key = _list.bisect_key
    +            self.irange_key = _list.irange_key
    +
    +        if iterable is not None:
    +            self._update(iterable)
    +
    +
    +    @classmethod
    +    def _fromset(cls, values, key=None):
    +        """Initialize sorted set from existing set.
    +
    +        Used internally by set operations that return a new set.
    +
    +        """
    +        sorted_set = object.__new__(cls)
    +        sorted_set._set = values
    +        sorted_set.__init__(key=key)
    +        return sorted_set
    +
    +
    +    @property
    +    def key(self):
    +        """Function used to extract comparison key from values.
    +
    +        Sorted set compares values directly when the key function is none.
    +
    +        """
    +        return self._key
    +
    +
    +    def __contains__(self, value):
    +        """Return true if `value` is an element of the sorted set.
    +
    +        ``ss.__contains__(value)`` <==> ``value in ss``
    +
    +        Runtime complexity: `O(1)`
    +
    +        >>> ss = SortedSet([1, 2, 3, 4, 5])
    +        >>> 3 in ss
    +        True
    +
    +        :param value: search for value in sorted set
    +        :return: true if `value` in sorted set
    +
    +        """
    +        return value in self._set
    +
    +
    +    def __getitem__(self, index):
    +        """Lookup value at `index` in sorted set.
    +
    +        ``ss.__getitem__(index)`` <==> ``ss[index]``
    +
    +        Supports slicing.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> ss = SortedSet('abcde')
    +        >>> ss[2]
    +        'c'
    +        >>> ss[-1]
    +        'e'
    +        >>> ss[2:5]
    +        ['c', 'd', 'e']
    +
    +        :param index: integer or slice for indexing
    +        :return: value or list of values
    +        :raises IndexError: if index out of range
    +
    +        """
    +        return self._list[index]
    +
    +
    +    def __delitem__(self, index):
    +        """Remove value at `index` from sorted set.
    +
    +        ``ss.__delitem__(index)`` <==> ``del ss[index]``
    +
    +        Supports slicing.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> ss = SortedSet('abcde')
    +        >>> del ss[2]
    +        >>> ss
    +        SortedSet(['a', 'b', 'd', 'e'])
    +        >>> del ss[:2]
    +        >>> ss
    +        SortedSet(['d', 'e'])
    +
    +        :param index: integer or slice for indexing
    +        :raises IndexError: if index out of range
    +
    +        """
    +        _set = self._set
    +        _list = self._list
    +        if isinstance(index, slice):
    +            values = _list[index]
    +            _set.difference_update(values)
    +        else:
    +            value = _list[index]
    +            _set.remove(value)
    +        del _list[index]
    +
    +
    +    def __make_cmp(set_op, symbol, doc):
    +        "Make comparator method."
    +        def comparer(self, other):
    +            "Compare method for sorted set and set."
    +            if isinstance(other, SortedSet):
    +                return set_op(self._set, other._set)
    +            elif isinstance(other, Set):
    +                return set_op(self._set, other)
    +            return NotImplemented
    +
    +        set_op_name = set_op.__name__
    +        comparer.__name__ = '__{0}__'.format(set_op_name)
    +        doc_str = """Return true if and only if sorted set is {0} `other`.
    +
    +        ``ss.__{1}__(other)`` <==> ``ss {2} other``
    +
    +        Comparisons use subset and superset semantics as with sets.
    +
    +        Runtime complexity: `O(n)`
    +
    +        :param other: `other` set
    +        :return: true if sorted set is {0} `other`
    +
    +        """
    +        comparer.__doc__ = dedent(doc_str.format(doc, set_op_name, symbol))
    +        return comparer
    +
    +
    +    __eq__ = __make_cmp(eq, '==', 'equal to')
    +    __ne__ = __make_cmp(ne, '!=', 'not equal to')
    +    __lt__ = __make_cmp(lt, '<', 'a proper subset of')
    +    __gt__ = __make_cmp(gt, '>', 'a proper superset of')
    +    __le__ = __make_cmp(le, '<=', 'a subset of')
    +    __ge__ = __make_cmp(ge, '>=', 'a superset of')
    +    __make_cmp = staticmethod(__make_cmp)
    +
    +
    +    def __len__(self):
    +        """Return the size of the sorted set.
    +
    +        ``ss.__len__()`` <==> ``len(ss)``
    +
    +        :return: size of sorted set
    +
    +        """
    +        return len(self._set)
    +
    +
    +    def __iter__(self):
    +        """Return an iterator over the sorted set.
    +
    +        ``ss.__iter__()`` <==> ``iter(ss)``
    +
    +        Iterating the sorted set while adding or deleting values may raise a
    +        :exc:`RuntimeError` or fail to iterate over all values.
    +
    +        """
    +        return iter(self._list)
    +
    +
    +    def __reversed__(self):
    +        """Return a reverse iterator over the sorted set.
    +
    +        ``ss.__reversed__()`` <==> ``reversed(ss)``
    +
    +        Iterating the sorted set while adding or deleting values may raise a
    +        :exc:`RuntimeError` or fail to iterate over all values.
    +
    +        """
    +        return reversed(self._list)
    +
    +
    +    def add(self, value):
    +        """Add `value` to sorted set.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> ss = SortedSet()
    +        >>> ss.add(3)
    +        >>> ss.add(1)
    +        >>> ss.add(2)
    +        >>> ss
    +        SortedSet([1, 2, 3])
    +
    +        :param value: value to add to sorted set
    +
    +        """
    +        _set = self._set
    +        if value not in _set:
    +            _set.add(value)
    +            self._list.add(value)
    +
    +    _add = add
    +
    +
    +    def clear(self):
    +        """Remove all values from sorted set.
    +
    +        Runtime complexity: `O(n)`
    +
    +        """
    +        self._set.clear()
    +        self._list.clear()
    +
    +
    +    def copy(self):
    +        """Return a shallow copy of the sorted set.
    +
    +        Runtime complexity: `O(n)`
    +
    +        :return: new sorted set
    +
    +        """
    +        return self._fromset(set(self._set), key=self._key)
    +
    +    __copy__ = copy
    +
    +
    +    def count(self, value):
    +        """Return number of occurrences of `value` in the sorted set.
    +
    +        Runtime complexity: `O(1)`
    +
    +        >>> ss = SortedSet([1, 2, 3, 4, 5])
    +        >>> ss.count(3)
    +        1
    +
    +        :param value: value to count in sorted set
    +        :return: count
    +
    +        """
    +        return 1 if value in self._set else 0
    +
    +
    +    def discard(self, value):
    +        """Remove `value` from sorted set if it is a member.
    +
    +        If `value` is not a member, do nothing.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> ss = SortedSet([1, 2, 3, 4, 5])
    +        >>> ss.discard(5)
    +        >>> ss.discard(0)
    +        >>> ss == set([1, 2, 3, 4])
    +        True
    +
    +        :param value: `value` to discard from sorted set
    +
    +        """
    +        _set = self._set
    +        if value in _set:
    +            _set.remove(value)
    +            self._list.remove(value)
    +
    +    _discard = discard
    +
    +
    +    def pop(self, index=-1):
    +        """Remove and return value at `index` in sorted set.
    +
    +        Raise :exc:`IndexError` if the sorted set is empty or index is out of
    +        range.
    +
    +        Negative indices are supported.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> ss = SortedSet('abcde')
    +        >>> ss.pop()
    +        'e'
    +        >>> ss.pop(2)
    +        'c'
    +        >>> ss
    +        SortedSet(['a', 'b', 'd'])
    +
    +        :param int index: index of value (default -1)
    +        :return: value
    +        :raises IndexError: if index is out of range
    +
    +        """
    +        # pylint: disable=arguments-differ
    +        value = self._list.pop(index)
    +        self._set.remove(value)
    +        return value
    +
    +
    +    def remove(self, value):
    +        """Remove `value` from sorted set; `value` must be a member.
    +
    +        If `value` is not a member, raise :exc:`KeyError`.
    +
    +        Runtime complexity: `O(log(n))` -- approximate.
    +
    +        >>> ss = SortedSet([1, 2, 3, 4, 5])
    +        >>> ss.remove(5)
    +        >>> ss == set([1, 2, 3, 4])
    +        True
    +        >>> ss.remove(0)
    +        Traceback (most recent call last):
    +          ...
    +        KeyError: 0
    +
    +        :param value: `value` to remove from sorted set
    +        :raises KeyError: if `value` is not in sorted set
    +
    +        """
    +        self._set.remove(value)
    +        self._list.remove(value)
    +
    +
    +    def difference(self, *iterables):
    +        """Return the difference of two or more sets as a new sorted set.
    +
    +        The `difference` method also corresponds to operator ``-``.
    +
    +        ``ss.__sub__(iterable)`` <==> ``ss - iterable``
    +
    +        The difference is all values that are in this sorted set but not the
    +        other `iterables`.
    +
    +        >>> ss = SortedSet([1, 2, 3, 4, 5])
    +        >>> ss.difference([4, 5, 6, 7])
    +        SortedSet([1, 2, 3])
    +
    +        :param iterables: iterable arguments
    +        :return: new sorted set
    +
    +        """
    +        diff = self._set.difference(*iterables)
    +        return self._fromset(diff, key=self._key)
    +
    +    __sub__ = difference
    +
    +
    +    def difference_update(self, *iterables):
    +        """Remove all values of `iterables` from this sorted set.
    +
    +        The `difference_update` method also corresponds to operator ``-=``.
    +
    +        ``ss.__isub__(iterable)`` <==> ``ss -= iterable``
    +
    +        >>> ss = SortedSet([1, 2, 3, 4, 5])
    +        >>> _ = ss.difference_update([4, 5, 6, 7])
    +        >>> ss
    +        SortedSet([1, 2, 3])
    +
    +        :param iterables: iterable arguments
    +        :return: itself
    +
    +        """
    +        _set = self._set
    +        _list = self._list
    +        values = set(chain(*iterables))
    +        if (4 * len(values)) > len(_set):
    +            _set.difference_update(values)
    +            _list.clear()
    +            _list.update(_set)
    +        else:
    +            _discard = self._discard
    +            for value in values:
    +                _discard(value)
    +        return self
    +
    +    __isub__ = difference_update
    +
    +
    +    def intersection(self, *iterables):
    +        """Return the intersection of two or more sets as a new sorted set.
    +
    +        The `intersection` method also corresponds to operator ``&``.
    +
    +        ``ss.__and__(iterable)`` <==> ``ss & iterable``
    +
    +        The intersection is all values that are in this sorted set and each of
    +        the other `iterables`.
    +
    +        >>> ss = SortedSet([1, 2, 3, 4, 5])
    +        >>> ss.intersection([4, 5, 6, 7])
    +        SortedSet([4, 5])
    +
    +        :param iterables: iterable arguments
    +        :return: new sorted set
    +
    +        """
    +        intersect = self._set.intersection(*iterables)
    +        return self._fromset(intersect, key=self._key)
    +
    +    __and__ = intersection
    +    __rand__ = __and__
    +
    +
    +    def intersection_update(self, *iterables):
    +        """Update the sorted set with the intersection of `iterables`.
    +
    +        The `intersection_update` method also corresponds to operator ``&=``.
    +
    +        ``ss.__iand__(iterable)`` <==> ``ss &= iterable``
    +
    +        Keep only values found in itself and all `iterables`.
    +
    +        >>> ss = SortedSet([1, 2, 3, 4, 5])
    +        >>> _ = ss.intersection_update([4, 5, 6, 7])
    +        >>> ss
    +        SortedSet([4, 5])
    +
    +        :param iterables: iterable arguments
    +        :return: itself
    +
    +        """
    +        _set = self._set
    +        _list = self._list
    +        _set.intersection_update(*iterables)
    +        _list.clear()
    +        _list.update(_set)
    +        return self
    +
    +    __iand__ = intersection_update
    +
    +
    +    def symmetric_difference(self, other):
    +        """Return the symmetric difference with `other` as a new sorted set.
    +
    +        The `symmetric_difference` method also corresponds to operator ``^``.
    +
    +        ``ss.__xor__(other)`` <==> ``ss ^ other``
    +
    +        The symmetric difference is all values tha are in exactly one of the
    +        sets.
    +
    +        >>> ss = SortedSet([1, 2, 3, 4, 5])
    +        >>> ss.symmetric_difference([4, 5, 6, 7])
    +        SortedSet([1, 2, 3, 6, 7])
    +
    +        :param other: `other` iterable
    +        :return: new sorted set
    +
    +        """
    +        diff = self._set.symmetric_difference(other)
    +        return self._fromset(diff, key=self._key)
    +
    +    __xor__ = symmetric_difference
    +    __rxor__ = __xor__
    +
    +
    +    def symmetric_difference_update(self, other):
    +        """Update the sorted set with the symmetric difference with `other`.
    +
    +        The `symmetric_difference_update` method also corresponds to operator
    +        ``^=``.
    +
    +        ``ss.__ixor__(other)`` <==> ``ss ^= other``
    +
    +        Keep only values found in exactly one of itself and `other`.
    +
    +        >>> ss = SortedSet([1, 2, 3, 4, 5])
    +        >>> _ = ss.symmetric_difference_update([4, 5, 6, 7])
    +        >>> ss
    +        SortedSet([1, 2, 3, 6, 7])
    +
    +        :param other: `other` iterable
    +        :return: itself
    +
    +        """
    +        _set = self._set
    +        _list = self._list
    +        _set.symmetric_difference_update(other)
    +        _list.clear()
    +        _list.update(_set)
    +        return self
    +
    +    __ixor__ = symmetric_difference_update
    +
    +
    +    def union(self, *iterables):
    +        """Return new sorted set with values from itself and all `iterables`.
    +
    +        The `union` method also corresponds to operator ``|``.
    +
    +        ``ss.__or__(iterable)`` <==> ``ss | iterable``
    +
    +        >>> ss = SortedSet([1, 2, 3, 4, 5])
    +        >>> ss.union([4, 5, 6, 7])
    +        SortedSet([1, 2, 3, 4, 5, 6, 7])
    +
    +        :param iterables: iterable arguments
    +        :return: new sorted set
    +
    +        """
    +        return self.__class__(chain(iter(self), *iterables), key=self._key)
    +
    +    __or__ = union
    +    __ror__ = __or__
    +
    +
    +    def update(self, *iterables):
    +        """Update the sorted set adding values from all `iterables`.
    +
    +        The `update` method also corresponds to operator ``|=``.
    +
    +        ``ss.__ior__(iterable)`` <==> ``ss |= iterable``
    +
    +        >>> ss = SortedSet([1, 2, 3, 4, 5])
    +        >>> _ = ss.update([4, 5, 6, 7])
    +        >>> ss
    +        SortedSet([1, 2, 3, 4, 5, 6, 7])
    +
    +        :param iterables: iterable arguments
    +        :return: itself
    +
    +        """
    +        _set = self._set
    +        _list = self._list
    +        values = set(chain(*iterables))
    +        if (4 * len(values)) > len(_set):
    +            _list = self._list
    +            _set.update(values)
    +            _list.clear()
    +            _list.update(_set)
    +        else:
    +            _add = self._add
    +            for value in values:
    +                _add(value)
    +        return self
    +
    +    __ior__ = update
    +    _update = update
    +
    +
    +    def __reduce__(self):
    +        """Support for pickle.
    +
    +        The tricks played with exposing methods in :func:`SortedSet.__init__`
    +        confuse pickle so customize the reducer.
    +
    +        """
    +        return (type(self), (self._set, self._key))
    +
    +
    +    @recursive_repr()
    +    def __repr__(self):
    +        """Return string representation of sorted set.
    +
    +        ``ss.__repr__()`` <==> ``repr(ss)``
    +
    +        :return: string representation
    +
    +        """
    +        _key = self._key
    +        key = '' if _key is None else ', key={0!r}'.format(_key)
    +        type_name = type(self).__name__
    +        return '{0}({1!r}{2})'.format(type_name, list(self), key)
    +
    +
    +    def _check(self):
    +        """Check invariants of sorted set.
    +
    +        Runtime complexity: `O(n)`
    +
    +        """
    +        _set = self._set
    +        _list = self._list
    +        _list._check()
    +        assert len(_set) == len(_list)
    +        assert all(value in _set for value in _list)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunk_sdk-1.7.3.dist-info/INSTALLER b/deployment-apps/metricator-for-nmon/lib/splunk_sdk-1.7.3.dist-info/INSTALLER
    new file mode 100644
    index 0000000..a1b589e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunk_sdk-1.7.3.dist-info/INSTALLER
    @@ -0,0 +1 @@
    +pip
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunk_sdk-1.7.3.dist-info/METADATA b/deployment-apps/metricator-for-nmon/lib/splunk_sdk-1.7.3.dist-info/METADATA
    new file mode 100644
    index 0000000..ade4962
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunk_sdk-1.7.3.dist-info/METADATA
    @@ -0,0 +1,20 @@
    +Metadata-Version: 2.1
    +Name: splunk-sdk
    +Version: 1.7.3
    +Summary: The Splunk Software Development Kit for Python.
    +Home-page: http://github.com/splunk/splunk-sdk-python
    +Author: Splunk, Inc.
    +Author-email: devinfo@splunk.com
    +License: http://www.apache.org/licenses/LICENSE-2.0
    +Platform: UNKNOWN
    +Classifier: Programming Language :: Python
    +Classifier: Development Status :: 6 - Mature
    +Classifier: Environment :: Other Environment
    +Classifier: Intended Audience :: Developers
    +Classifier: License :: OSI Approved :: Apache Software License
    +Classifier: Operating System :: OS Independent
    +Classifier: Topic :: Software Development :: Libraries :: Python Modules
    +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
    +
    +UNKNOWN
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunk_sdk-1.7.3.dist-info/RECORD b/deployment-apps/metricator-for-nmon/lib/splunk_sdk-1.7.3.dist-info/RECORD
    new file mode 100644
    index 0000000..4c5b457
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunk_sdk-1.7.3.dist-info/RECORD
    @@ -0,0 +1,31 @@
    +splunk_sdk-1.7.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
    +splunk_sdk-1.7.3.dist-info/METADATA,sha256=-x8OqcGsa14GvunXMWfZ1KWebc8-_TDV9MotMeCDS-A,740
    +splunk_sdk-1.7.3.dist-info/RECORD,,
    +splunk_sdk-1.7.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
    +splunk_sdk-1.7.3.dist-info/top_level.txt,sha256=taq2YYfOB31tNefwW73s54xytiB_sy8bpbyBAfn0kr8,10
    +splunklib/__init__.py,sha256=NWAu71AAMnezREUKbU1hWbufwNA0ws1R9JO0IlgWXow,1371
    +splunklib/binding.py,sha256=PaLlm-s_UKg6ttrZK4DAg-40e2u55FlBc8I51zDAxZw,60209
    +splunklib/client.py,sha256=xNqWmqclO3DWn8kLRDtGoY1K1valYv3jZfmnM1287uI,150652
    +splunklib/data.py,sha256=TksFc2trF2_UOXosQu9mdgq8y7sG2-_ZWmFldnRU-K4,8508
    +splunklib/modularinput/__init__.py,sha256=bHyI0p3GtBoAjbFCEbuUibEFKwnHDyZzZOwS4Fvt0zs,400
    +splunklib/modularinput/argument.py,sha256=OGYDCW1Fw7PsMygxetwzTH2YGm1fdzErZXxUYyB-WNU,4219
    +splunklib/modularinput/event.py,sha256=xV-n38M4xFU8OB3vcT_u8cllWGBo5BHGWNYXTcfJOIk,4456
    +splunklib/modularinput/event_writer.py,sha256=RL38U9PdkMD1hLrR3XSl5ndZFvgyZeSFiZjDvwf1BrA,2878
    +splunklib/modularinput/input_definition.py,sha256=RE_QnfBLXA2JhdEshvclVzTBKcppY_ktQ0lOAlGUPNc,1888
    +splunklib/modularinput/scheme.py,sha256=wllFtEnV90MY9FNrPR3OoIhdzVU4blaF7ONaEcL3ekQ,3073
    +splunklib/modularinput/script.py,sha256=YZM7UKIFuLkkNldlGAtk8HfbwzZ11uev0Ig8vsMVGWo,6597
    +splunklib/modularinput/utils.py,sha256=Y0-gfqtaOphQa7LJTPOmBwtWwaR_2G2XZZemlkQpwWE,2729
    +splunklib/modularinput/validation_definition.py,sha256=orD4V_hYmpxtuHsv_GhcPnhcGDoHnKMSU-KShTmUCwI,2775
    +splunklib/results.py,sha256=Ju4ZWbxLv_fOGtjns7WcGkQu_CwslamnyiOej4AGIak,13892
    +splunklib/searchcommands/__init__.py,sha256=Vh4ANhCUpiCtmZOxluTwJn3NgXr9sbK_mMqw-N9IB-I,6330
    +splunklib/searchcommands/decorators.py,sha256=x2TFIJuyx8_rFi4K2Wf6YKjG8tZuD3lZ1X45TaRyB40,15657
    +splunklib/searchcommands/environment.py,sha256=mX52tmJigBDnguIrzvzMHFu9XysDkGi6WNl5GuUKKTs,4683
    +splunklib/searchcommands/eventing_command.py,sha256=Rxy88uB95xFQ2Gq4U7e45Roc-zGRM1X2zdfIIbRNh-I,5432
    +splunklib/searchcommands/external_search_command.py,sha256=ml-_4qMBZx_M0OYiCevAdpRZBLG_ih7pTRsmElbn2a0,7872
    +splunklib/searchcommands/generating_command.py,sha256=93xwHtQIRUIlxdG2uhJvxk6omp4SELefM8wqsfKpXNE,18949
    +splunklib/searchcommands/internals.py,sha256=CWJ3nv5a6wWVoI6xn50YMs1LGS0BszNtKv0-A3sfMI8,28820
    +splunklib/searchcommands/reporting_command.py,sha256=QFNyGO-EQlW01BxEEw5c7JWh4IAfhm29SlAKgjftuyY,9697
    +splunklib/searchcommands/search_command.py,sha256=cMsf_uUyS-uTwicANN-Wp4FfOhBMt8LlRj4fUWsG47Q,40702
    +splunklib/searchcommands/streaming_command.py,sha256=qkVpXsNKQSWoTE1ZLKJvK7aPFHQydPFj9TP_x7wLntc,6778
    +splunklib/searchcommands/validators.py,sha256=B0vwQ9rYluApMlNrcQmajdHxam-cXg0KCWt9q3urX-4,13226
    +splunklib/six.py,sha256=kZ-1CgvQf-HDGdmKqxzWn9UUCkPkK1Cgel5ckcj-xoc,34536
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunk_sdk-1.7.3.dist-info/WHEEL b/deployment-apps/metricator-for-nmon/lib/splunk_sdk-1.7.3.dist-info/WHEEL
    new file mode 100644
    index 0000000..becc9a6
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunk_sdk-1.7.3.dist-info/WHEEL
    @@ -0,0 +1,5 @@
    +Wheel-Version: 1.0
    +Generator: bdist_wheel (0.37.1)
    +Root-Is-Purelib: true
    +Tag: py3-none-any
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunklib/__init__.py
    new file mode 100644
    index 0000000..31787bd
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/__init__.py
    @@ -0,0 +1,35 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +"""Python library for Splunk."""
    +
    +from __future__ import absolute_import
    +from splunklib.six.moves import map
    +import logging
    +
    +DEFAULT_LOG_FORMAT = '%(asctime)s, Level=%(levelname)s, Pid=%(process)s, Logger=%(name)s, File=%(filename)s, ' \
    +                 'Line=%(lineno)s, %(message)s'
    +DEFAULT_DATE_FORMAT = '%Y-%m-%d %H:%M:%S %Z'
    +
    +
    +# To set the logging level of splunklib
    +# ex. To enable debug logs, call this method with parameter 'logging.DEBUG'
    +# default logging level is set to 'WARNING'
    +def setup_logging(level, log_format=DEFAULT_LOG_FORMAT, date_format=DEFAULT_DATE_FORMAT):
    +    logging.basicConfig(level=level,
    +                        format=log_format,
    +                        datefmt=date_format)
    +
    +__version_info__ = (1, 7, 3)
    +__version__ = ".".join(map(str, __version_info__))
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/binding.py b/deployment-apps/metricator-for-nmon/lib/splunklib/binding.py
    new file mode 100644
    index 0000000..85cb8d1
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/binding.py
    @@ -0,0 +1,1466 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +"""The **splunklib.binding** module provides a low-level binding interface to the
    +`Splunk REST API <http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTcontents>`_.
    +
    +This module handles the wire details of calling the REST API, such as
    +authentication tokens, prefix paths, URL encoding, and so on. Actual path
    +segments, ``GET`` and ``POST`` arguments, and the parsing of responses is left
    +to the user.
    +
    +If you want a friendlier interface to the Splunk REST API, use the
    +:mod:`splunklib.client` module.
    +"""
    +
    +from __future__ import absolute_import
    +
    +import io
    +import logging
    +import socket
    +import ssl
    +import sys
    +import time
    +from base64 import b64encode
    +from contextlib import contextmanager
    +from datetime import datetime
    +from functools import wraps
    +from io import BytesIO
    +from xml.etree.ElementTree import XML
    +
    +from splunklib import __version__
    +from splunklib import six
    +from splunklib.six.moves import urllib
    +
    +from .data import record
    +
    +try:
    +    from xml.etree.ElementTree import ParseError
    +except ImportError as e:
    +    from xml.parsers.expat import ExpatError as ParseError
    +
    +logger = logging.getLogger(__name__)
    +
    +__all__ = [
    +    "AuthenticationError",
    +    "connect",
    +    "Context",
    +    "handler",
    +    "HTTPError"
    +]
    +
    +# If you change these, update the docstring
    +# on _authority as well.
    +DEFAULT_HOST = "localhost"
    +DEFAULT_PORT = "8089"
    +DEFAULT_SCHEME = "https"
    +
    +def _log_duration(f):
    +    @wraps(f)
    +    def new_f(*args, **kwargs):
    +        start_time = datetime.now()
    +        val = f(*args, **kwargs)
    +        end_time = datetime.now()
    +        logger.debug("Operation took %s", end_time-start_time)
    +        return val
    +    return new_f
    +
    +
    +def _parse_cookies(cookie_str, dictionary):
    +    """Tries to parse any key-value pairs of cookies in a string,
    +    then updates the the dictionary with any key-value pairs found.
    +
    +    **Example**::
    +
    +        dictionary = {}
    +        _parse_cookies('my=value', dictionary)
    +        # Now the following is True
    +        dictionary['my'] == 'value'
    +
    +    :param cookie_str: A string containing "key=value" pairs from an HTTP "Set-Cookie" header.
    +    :type cookie_str: ``str``
    +    :param dictionary: A dictionary to update with any found key-value pairs.
    +    :type dictionary: ``dict``
    +    """
    +    parsed_cookie = six.moves.http_cookies.SimpleCookie(cookie_str)
    +    for cookie in parsed_cookie.values():
    +        dictionary[cookie.key] = cookie.coded_value
    +
    +
    +def _make_cookie_header(cookies):
    +    """
    +    Takes a list of 2-tuples of key-value pairs of
    +    cookies, and returns a valid HTTP ``Cookie``
    +    header.
    +
    +    **Example**::
    +
    +        header = _make_cookie_header([("key", "value"), ("key_2", "value_2")])
    +        # Now the following is True
    +        header == "key=value; key_2=value_2"
    +
    +    :param cookies: A list of 2-tuples of cookie key-value pairs.
    +    :type cookies: ``list`` of 2-tuples
    +    :return: ``str` An HTTP header cookie string.
    +    :rtype: ``str``
    +    """
    +    return "; ".join("%s=%s" % (key, value) for key, value in cookies)
    +
    +# Singleton values to eschew None
    +class _NoAuthenticationToken(object):
    +    """The value stored in a :class:`Context` or :class:`splunklib.client.Service`
    +    class that is not logged in.
    +
    +    If a ``Context`` or ``Service`` object is created without an authentication
    +    token, and there has not yet been a call to the ``login`` method, the token
    +    field of the ``Context`` or ``Service`` object is set to
    +    ``_NoAuthenticationToken``.
    +
    +    Likewise, after a ``Context`` or ``Service`` object has been logged out, the
    +    token is set to this value again.
    +    """
    +    pass
    +
    +
    +class UrlEncoded(str):
    +    """This class marks URL-encoded strings.
    +    It should be considered an SDK-private implementation detail.
    +
    +    Manually tracking whether strings are URL encoded can be difficult. Avoid
    +    calling ``urllib.quote`` to replace special characters with escapes. When
    +    you receive a URL-encoded string, *do* use ``urllib.unquote`` to replace
    +    escapes with single characters. Then, wrap any string you want to use as a
    +    URL in ``UrlEncoded``. Note that because the ``UrlEncoded`` class is
    +    idempotent, making multiple calls to it is OK.
    +
    +    ``UrlEncoded`` objects are identical to ``str`` objects (including being
    +    equal if their contents are equal) except when passed to ``UrlEncoded``
    +    again.
    +
    +    ``UrlEncoded`` removes the ``str`` type support for interpolating values
    +    with ``%`` (doing that raises a ``TypeError``). There is no reliable way to
    +    encode values this way, so instead, interpolate into a string, quoting by
    +    hand, and call ``UrlEncode`` with ``skip_encode=True``.
    +
    +    **Example**::
    +
    +        import urllib
    +        UrlEncoded('%s://%s' % (scheme, urllib.quote(host)), skip_encode=True)
    +
    +    If you append ``str`` strings and ``UrlEncoded`` strings, the result is also
    +    URL encoded.
    +
    +    **Example**::
    +
    +        UrlEncoded('ab c') + 'de f' == UrlEncoded('ab cde f')
    +        'ab c' + UrlEncoded('de f') == UrlEncoded('ab cde f')
    +    """
    +    def __new__(self, val='', skip_encode=False, encode_slash=False):
    +        if isinstance(val, UrlEncoded):
    +            # Don't urllib.quote something already URL encoded.
    +            return val
    +        elif skip_encode:
    +            return str.__new__(self, val)
    +        elif encode_slash:
    +            return str.__new__(self, urllib.parse.quote_plus(val))
    +        else:
    +            # When subclassing str, just call str's __new__ method
    +            # with your class and the value you want to have in the
    +            # new string.
    +            return str.__new__(self, urllib.parse.quote(val))
    +
    +    def __add__(self, other):
    +        """self + other
    +
    +        If *other* is not a ``UrlEncoded``, URL encode it before
    +        adding it.
    +        """
    +        if isinstance(other, UrlEncoded):
    +            return UrlEncoded(str.__add__(self, other), skip_encode=True)
    +        else:
    +            return UrlEncoded(str.__add__(self, urllib.parse.quote(other)), skip_encode=True)
    +
    +    def __radd__(self, other):
    +        """other + self
    +
    +        If *other* is not a ``UrlEncoded``, URL _encode it before
    +        adding it.
    +        """
    +        if isinstance(other, UrlEncoded):
    +            return UrlEncoded(str.__radd__(self, other), skip_encode=True)
    +        else:
    +            return UrlEncoded(str.__add__(urllib.parse.quote(other), self), skip_encode=True)
    +
    +    def __mod__(self, fields):
    +        """Interpolation into ``UrlEncoded``s is disabled.
    +
    +        If you try to write ``UrlEncoded("%s") % "abc", will get a
    +        ``TypeError``.
    +        """
    +        raise TypeError("Cannot interpolate into a UrlEncoded object.")
    +    def __repr__(self):
    +        return "UrlEncoded(%s)" % repr(urllib.parse.unquote(str(self)))
    +
    +@contextmanager
    +def _handle_auth_error(msg):
    +    """Handle reraising HTTP authentication errors as something clearer.
    +
    +    If an ``HTTPError`` is raised with status 401 (access denied) in
    +    the body of this context manager, reraise it as an
    +    ``AuthenticationError`` instead, with *msg* as its message.
    +
    +    This function adds no round trips to the server.
    +
    +    :param msg: The message to be raised in ``AuthenticationError``.
    +    :type msg: ``str``
    +
    +    **Example**::
    +
    +        with _handle_auth_error("Your login failed."):
    +             ... # make an HTTP request
    +    """
    +    try:
    +        yield
    +    except HTTPError as he:
    +        if he.status == 401:
    +            raise AuthenticationError(msg, he)
    +        else:
    +            raise
    +
    +def _authentication(request_fun):
    +    """Decorator to handle autologin and authentication errors.
    +
    +    *request_fun* is a function taking no arguments that needs to
    +    be run with this ``Context`` logged into Splunk.
    +
    +    ``_authentication``'s behavior depends on whether the
    +    ``autologin`` field of ``Context`` is set to ``True`` or
    +    ``False``. If it's ``False``, then ``_authentication``
    +    aborts if the ``Context`` is not logged in, and raises an
    +    ``AuthenticationError`` if an ``HTTPError`` of status 401 is
    +    raised in *request_fun*. If it's ``True``, then
    +    ``_authentication`` will try at all sensible places to
    +    log in before issuing the request.
    +
    +    If ``autologin`` is ``False``, ``_authentication`` makes
    +    one roundtrip to the server if the ``Context`` is logged in,
    +    or zero if it is not. If ``autologin`` is ``True``, it's less
    +    deterministic, and may make at most three roundtrips (though
    +    that would be a truly pathological case).
    +
    +    :param request_fun: A function of no arguments encapsulating
    +                        the request to make to the server.
    +
    +    **Example**::
    +
    +        import splunklib.binding as binding
    +        c = binding.connect(..., autologin=True)
    +        c.logout()
    +        def f():
    +            c.get("/services")
    +            return 42
    +        print _authentication(f)
    +    """
    +    @wraps(request_fun)
    +    def wrapper(self, *args, **kwargs):
    +        if self.token is _NoAuthenticationToken and \
    +                not self.has_cookies():
    +            # Not yet logged in.
    +            if self.autologin and self.username and self.password:
    +                # This will throw an uncaught
    +                # AuthenticationError if it fails.
    +                self.login()
    +            else:
    +                # Try the request anyway without authentication.
    +                # Most requests will fail. Some will succeed, such as
    +                # 'GET server/info'.
    +                with _handle_auth_error("Request aborted: not logged in."):
    +                    return request_fun(self, *args, **kwargs)
    +        try:
    +            # Issue the request
    +            return request_fun(self, *args, **kwargs)
    +        except HTTPError as he:
    +            if he.status == 401 and self.autologin:
    +                # Authentication failed. Try logging in, and then
    +                # rerunning the request. If either step fails, throw
    +                # an AuthenticationError and give up.
    +                with _handle_auth_error("Autologin failed."):
    +                    self.login()
    +                with _handle_auth_error(
    +                        "Authentication Failed! If session token is used, it seems to have been expired."):
    +                    return request_fun(self, *args, **kwargs)
    +            elif he.status == 401 and not self.autologin:
    +                raise AuthenticationError(
    +                    "Request failed: Session is not logged in.", he)
    +            else:
    +                raise
    +
    +    return wrapper
    +
    +
    +def _authority(scheme=DEFAULT_SCHEME, host=DEFAULT_HOST, port=DEFAULT_PORT):
    +    """Construct a URL authority from the given *scheme*, *host*, and *port*.
    +
    +    Named in accordance with RFC2396_, which defines URLs as::
    +
    +        <scheme>://<authority><path>?<query>
    +
    +    .. _RFC2396: http://www.ietf.org/rfc/rfc2396.txt
    +
    +    So ``https://localhost:8000/a/b/b?boris=hilda`` would be parsed as::
    +
    +        scheme := https
    +        authority := localhost:8000
    +        path := /a/b/c
    +        query := boris=hilda
    +
    +    :param scheme: URL scheme (the default is "https")
    +    :type scheme: "http" or "https"
    +    :param host: The host name (the default is "localhost")
    +    :type host: string
    +    :param port: The port number (the default is 8089)
    +    :type port: integer
    +    :return: The URL authority.
    +    :rtype: UrlEncoded (subclass of ``str``)
    +
    +    **Example**::
    +
    +        _authority() == "https://localhost:8089"
    +
    +        _authority(host="splunk.utopia.net") == "https://splunk.utopia.net:8089"
    +
    +        _authority(host="2001:0db8:85a3:0000:0000:8a2e:0370:7334") == \
    +            "https://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8089"
    +
    +        _authority(scheme="http", host="splunk.utopia.net", port="471") == \
    +            "http://splunk.utopia.net:471"
    +
    +    """
    +    # check if host is an IPv6 address and not enclosed in [ ]
    +    if ':' in host and not (host.startswith('[') and host.endswith(']')):
    +        # IPv6 addresses must be enclosed in [ ] in order to be well
    +        # formed.
    +        host = '[' + host + ']'
    +    return UrlEncoded("%s://%s:%s" % (scheme, host, port), skip_encode=True)
    +
    +# kwargs: sharing, owner, app
    +def namespace(sharing=None, owner=None, app=None, **kwargs):
    +    """This function constructs a Splunk namespace.
    +
    +    Every Splunk resource belongs to a namespace. The namespace is specified by
    +    the pair of values ``owner`` and ``app`` and is governed by a ``sharing`` mode.
    +    The possible values for ``sharing`` are: "user", "app", "global" and "system",
    +    which map to the following combinations of ``owner`` and ``app`` values:
    +
    +        "user"   => {owner}, {app}
    +
    +        "app"    => nobody, {app}
    +
    +        "global" => nobody, {app}
    +
    +        "system" => nobody, system
    +
    +    "nobody" is a special user name that basically means no user, and "system"
    +    is the name reserved for system resources.
    +
    +    "-" is a wildcard that can be used for both ``owner`` and ``app`` values and
    +    refers to all users and all apps, respectively.
    +
    +    In general, when you specify a namespace you can specify any combination of
    +    these three values and the library will reconcile the triple, overriding the
    +    provided values as appropriate.
    +
    +    Finally, if no namespacing is specified the library will make use of the
    +    ``/services`` branch of the REST API, which provides a namespaced view of
    +    Splunk resources equivelent to using ``owner={currentUser}`` and
    +    ``app={defaultApp}``.
    +
    +    The ``namespace`` function returns a representation of the namespace from
    +    reconciling the values you provide. It ignores any keyword arguments other
    +    than ``owner``, ``app``, and ``sharing``, so you can provide ``dicts`` of
    +    configuration information without first having to extract individual keys.
    +
    +    :param sharing: The sharing mode (the default is "user").
    +    :type sharing: "system", "global", "app", or "user"
    +    :param owner: The owner context (the default is "None").
    +    :type owner: ``string``
    +    :param app: The app context (the default is "None").
    +    :type app: ``string``
    +    :returns: A :class:`splunklib.data.Record` containing the reconciled
    +        namespace.
    +
    +    **Example**::
    +
    +        import splunklib.binding as binding
    +        n = binding.namespace(sharing="user", owner="boris", app="search")
    +        n = binding.namespace(sharing="global", app="search")
    +    """
    +    if sharing in ["system"]:
    +        return record({'sharing': sharing, 'owner': "nobody", 'app': "system" })
    +    if sharing in ["global", "app"]:
    +        return record({'sharing': sharing, 'owner': "nobody", 'app': app})
    +    if sharing in ["user", None]:
    +        return record({'sharing': sharing, 'owner': owner, 'app': app})
    +    raise ValueError("Invalid value for argument: 'sharing'")
    +
    +
    +class Context(object):
    +    """This class represents a context that encapsulates a splunkd connection.
    +
    +    The ``Context`` class encapsulates the details of HTTP requests,
    +    authentication, a default namespace, and URL prefixes to simplify access to
    +    the REST API.
    +
    +    After creating a ``Context`` object, you must call its :meth:`login`
    +    method before you can issue requests to splunkd. Or, use the :func:`connect`
    +    function to create an already-authenticated ``Context`` object. You can
    +    provide a session token explicitly (the same token can be shared by multiple
    +    ``Context`` objects) to provide authentication.
    +
    +    :param host: The host name (the default is "localhost").
    +    :type host: ``string``
    +    :param port: The port number (the default is 8089).
    +    :type port: ``integer``
    +    :param scheme: The scheme for accessing the service (the default is "https").
    +    :type scheme: "https" or "http"
    +    :param verify: Enable (True) or disable (False) SSL verrification for https connections.
    +    :type verify: ``Boolean``
    +    :param sharing: The sharing mode for the namespace (the default is "user").
    +    :type sharing: "global", "system", "app", or "user"
    +    :param owner: The owner context of the namespace (optional, the default is "None").
    +    :type owner: ``string``
    +    :param app: The app context of the namespace (optional, the default is "None").
    +    :type app: ``string``
    +    :param token: A session token. When provided, you don't need to call :meth:`login`.
    +    :type token: ``string``
    +    :param cookie: A session cookie. When provided, you don't need to call :meth:`login`.
    +        This parameter is only supported for Splunk 6.2+.
    +    :type cookie: ``string``
    +    :param username: The Splunk account username, which is used to
    +        authenticate the Splunk instance.
    +    :type username: ``string``
    +    :param password: The password for the Splunk account.
    +    :type password: ``string``
    +    :param splunkToken: Splunk authentication token
    +    :type splunkToken: ``string``
    +    :param headers: List of extra HTTP headers to send (optional).
    +    :type headers: ``list`` of 2-tuples.
    +    :param retires: Number of retries for each HTTP connection (optional, the default is 0).
    +                    NOTE THAT THIS MAY INCREASE THE NUMBER OF ROUND TRIP CONNECTIONS TO THE SPLUNK SERVER AND BLOCK THE
    +                    CURRENT THREAD WHILE RETRYING.
    +    :type retries: ``int``
    +    :param retryDelay: How long to wait between connection attempts if `retries` > 0 (optional, defaults to 10s).
    +    :type retryDelay: ``int`` (in seconds)
    +    :param handler: The HTTP request handler (optional).
    +    :returns: A ``Context`` instance.
    +
    +    **Example**::
    +
    +        import splunklib.binding as binding
    +        c = binding.Context(username="boris", password="natasha", ...)
    +        c.login()
    +        # Or equivalently
    +        c = binding.connect(username="boris", password="natasha")
    +        # Or if you already have a session token
    +        c = binding.Context(token="atg232342aa34324a")
    +        # Or if you already have a valid cookie
    +        c = binding.Context(cookie="splunkd_8089=...")
    +    """
    +    def __init__(self, handler=None, **kwargs):
    +        self.http = HttpLib(handler, kwargs.get("verify", False), key_file=kwargs.get("key_file"),
    +                            cert_file=kwargs.get("cert_file"),  context=kwargs.get("context"), # Default to False for backward compat
    +                            retries=kwargs.get("retries", 0), retryDelay=kwargs.get("retryDelay", 10))
    +        self.token = kwargs.get("token", _NoAuthenticationToken)
    +        if self.token is None: # In case someone explicitly passes token=None
    +            self.token = _NoAuthenticationToken
    +        self.scheme = kwargs.get("scheme", DEFAULT_SCHEME)
    +        self.host = kwargs.get("host", DEFAULT_HOST)
    +        self.port = int(kwargs.get("port", DEFAULT_PORT))
    +        self.authority = _authority(self.scheme, self.host, self.port)
    +        self.namespace = namespace(**kwargs)
    +        self.username = kwargs.get("username", "")
    +        self.password = kwargs.get("password", "")
    +        self.basic = kwargs.get("basic", False)
    +        self.bearerToken = kwargs.get("splunkToken", "")
    +        self.autologin = kwargs.get("autologin", False)
    +        self.additional_headers = kwargs.get("headers", [])
    +
    +        # Store any cookies in the self.http._cookies dict
    +        if "cookie" in kwargs and kwargs['cookie'] not in [None, _NoAuthenticationToken]:
    +            _parse_cookies(kwargs["cookie"], self.http._cookies)
    +
    +    def get_cookies(self):
    +        """Gets the dictionary of cookies from the ``HttpLib`` member of this instance.
    +
    +        :return: Dictionary of cookies stored on the ``self.http``.
    +        :rtype: ``dict``
    +        """
    +        return self.http._cookies
    +
    +    def has_cookies(self):
    +        """Returns true if the ``HttpLib`` member of this instance has auth token stored.
    +
    +        :return: ``True`` if there is auth token present, else ``False``
    +        :rtype: ``bool``
    +        """
    +        auth_token_key = "splunkd_"
    +        return any(auth_token_key in key for key in self.get_cookies().keys())
    +
    +    # Shared per-context request headers
    +    @property
    +    def _auth_headers(self):
    +        """Headers required to authenticate a request.
    +
    +        Assumes your ``Context`` already has a authentication token or
    +        cookie, either provided explicitly or obtained by logging
    +        into the Splunk instance.
    +
    +        :returns: A list of 2-tuples containing key and value
    +        """
    +        header = []
    +        if self.has_cookies():
    +            return [("Cookie", _make_cookie_header(list(self.get_cookies().items())))]
    +        elif self.basic and (self.username and self.password):
    +            token = 'Basic %s' % b64encode(("%s:%s" % (self.username, self.password)).encode('utf-8')).decode('ascii')
    +        elif self.bearerToken:
    +            token = 'Bearer %s' % self.bearerToken
    +        elif self.token is _NoAuthenticationToken:
    +            token = []
    +        else:
    +            # Ensure the token is properly formatted
    +            if self.token.startswith('Splunk '):
    +                token = self.token
    +            else:
    +                token = 'Splunk %s' % self.token
    +        if token:
    +            header.append(("Authorization", token))
    +        if self.get_cookies():
    +            header.append(("Cookie", _make_cookie_header(list(self.get_cookies().items()))))
    +
    +        return header
    +
    +    def connect(self):
    +        """Returns an open connection (socket) to the Splunk instance.
    +
    +        This method is used for writing bulk events to an index or similar tasks
    +        where the overhead of opening a connection multiple times would be
    +        prohibitive.
    +
    +        :returns: A socket.
    +
    +        **Example**::
    +
    +            import splunklib.binding as binding
    +            c = binding.connect(...)
    +            socket = c.connect()
    +            socket.write("POST %s HTTP/1.1\\r\\n" % "some/path/to/post/to")
    +            socket.write("Host: %s:%s\\r\\n" % (c.host, c.port))
    +            socket.write("Accept-Encoding: identity\\r\\n")
    +            socket.write("Authorization: %s\\r\\n" % c.token)
    +            socket.write("X-Splunk-Input-Mode: Streaming\\r\\n")
    +            socket.write("\\r\\n")
    +        """
    +        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    +        if self.scheme == "https":
    +            sock = ssl.wrap_socket(sock)
    +        sock.connect((socket.gethostbyname(self.host), self.port))
    +        return sock
    +
    +    @_authentication
    +    @_log_duration
    +    def delete(self, path_segment, owner=None, app=None, sharing=None, **query):
    +        """Performs a DELETE operation at the REST path segment with the given
    +        namespace and query.
    +
    +        This method is named to match the HTTP method. ``delete`` makes at least
    +        one round trip to the server, one additional round trip for each 303
    +        status returned, and at most two additional round trips if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        If *owner*, *app*, and *sharing* are omitted, this method uses the
    +        default :class:`Context` namespace. All other keyword arguments are
    +        included in the URL as query parameters.
    +
    +        :raises AuthenticationError: Raised when the ``Context`` object is not
    +             logged in.
    +        :raises HTTPError: Raised when an error occurred in a GET operation from
    +             *path_segment*.
    +        :param path_segment: A REST path segment.
    +        :type path_segment: ``string``
    +        :param owner: The owner context of the namespace (optional).
    +        :type owner: ``string``
    +        :param app: The app context of the namespace (optional).
    +        :type app: ``string``
    +        :param sharing: The sharing mode of the namespace (optional).
    +        :type sharing: ``string``
    +        :param query: All other keyword arguments, which are used as query
    +            parameters.
    +        :type query: ``string``
    +        :return: The response from the server.
    +        :rtype: ``dict`` with keys ``body``, ``headers``, ``reason``,
    +                and ``status``
    +
    +        **Example**::
    +
    +            c = binding.connect(...)
    +            c.delete('saved/searches/boris') == \\
    +                {'body': ...a response reader object...,
    +                 'headers': [('content-length', '1786'),
    +                             ('expires', 'Fri, 30 Oct 1998 00:00:00 GMT'),
    +                             ('server', 'Splunkd'),
    +                             ('connection', 'close'),
    +                             ('cache-control', 'no-store, max-age=0, must-revalidate, no-cache'),
    +                             ('date', 'Fri, 11 May 2012 16:53:06 GMT'),
    +                             ('content-type', 'text/xml; charset=utf-8')],
    +                 'reason': 'OK',
    +                 'status': 200}
    +            c.delete('nonexistant/path') # raises HTTPError
    +            c.logout()
    +            c.delete('apps/local') # raises AuthenticationError
    +        """
    +        path = self.authority + self._abspath(path_segment, owner=owner,
    +                                              app=app, sharing=sharing)
    +        logger.debug("DELETE request to %s (body: %s)", path, repr(query))
    +        response = self.http.delete(path, self._auth_headers, **query)
    +        return response
    +
    +    @_authentication
    +    @_log_duration
    +    def get(self, path_segment, owner=None, app=None, headers=None, sharing=None, **query):
    +        """Performs a GET operation from the REST path segment with the given
    +        namespace and query.
    +
    +        This method is named to match the HTTP method. ``get`` makes at least
    +        one round trip to the server, one additional round trip for each 303
    +        status returned, and at most two additional round trips if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        If *owner*, *app*, and *sharing* are omitted, this method uses the
    +        default :class:`Context` namespace. All other keyword arguments are
    +        included in the URL as query parameters.
    +
    +        :raises AuthenticationError: Raised when the ``Context`` object is not
    +             logged in.
    +        :raises HTTPError: Raised when an error occurred in a GET operation from
    +             *path_segment*.
    +        :param path_segment: A REST path segment.
    +        :type path_segment: ``string``
    +        :param owner: The owner context of the namespace (optional).
    +        :type owner: ``string``
    +        :param app: The app context of the namespace (optional).
    +        :type app: ``string``
    +        :param headers: List of extra HTTP headers to send (optional).
    +        :type headers: ``list`` of 2-tuples.
    +        :param sharing: The sharing mode of the namespace (optional).
    +        :type sharing: ``string``
    +        :param query: All other keyword arguments, which are used as query
    +            parameters.
    +        :type query: ``string``
    +        :return: The response from the server.
    +        :rtype: ``dict`` with keys ``body``, ``headers``, ``reason``,
    +                and ``status``
    +
    +        **Example**::
    +
    +            c = binding.connect(...)
    +            c.get('apps/local') == \\
    +                {'body': ...a response reader object...,
    +                 'headers': [('content-length', '26208'),
    +                             ('expires', 'Fri, 30 Oct 1998 00:00:00 GMT'),
    +                             ('server', 'Splunkd'),
    +                             ('connection', 'close'),
    +                             ('cache-control', 'no-store, max-age=0, must-revalidate, no-cache'),
    +                             ('date', 'Fri, 11 May 2012 16:30:35 GMT'),
    +                             ('content-type', 'text/xml; charset=utf-8')],
    +                 'reason': 'OK',
    +                 'status': 200}
    +            c.get('nonexistant/path') # raises HTTPError
    +            c.logout()
    +            c.get('apps/local') # raises AuthenticationError
    +        """
    +        if headers is None:
    +            headers = []
    +
    +        path = self.authority + self._abspath(path_segment, owner=owner,
    +                                              app=app, sharing=sharing)
    +        logger.debug("GET request to %s (body: %s)", path, repr(query))
    +        all_headers = headers + self.additional_headers + self._auth_headers
    +        response = self.http.get(path, all_headers, **query)
    +        return response
    +
    +    @_authentication
    +    @_log_duration
    +    def post(self, path_segment, owner=None, app=None, sharing=None, headers=None, **query):
    +        """Performs a POST operation from the REST path segment with the given
    +        namespace and query.
    +
    +        This method is named to match the HTTP method. ``post`` makes at least
    +        one round trip to the server, one additional round trip for each 303
    +        status returned, and at most two additional round trips if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        If *owner*, *app*, and *sharing* are omitted, this method uses the
    +        default :class:`Context` namespace. All other keyword arguments are
    +        included in the URL as query parameters.
    +
    +        Some of Splunk's endpoints, such as ``receivers/simple`` and
    +        ``receivers/stream``, require unstructured data in the POST body
    +        and all metadata passed as GET-style arguments. If you provide
    +        a ``body`` argument to ``post``, it will be used as the POST
    +        body, and all other keyword arguments will be passed as
    +        GET-style arguments in the URL.
    +
    +        :raises AuthenticationError: Raised when the ``Context`` object is not
    +             logged in.
    +        :raises HTTPError: Raised when an error occurred in a GET operation from
    +             *path_segment*.
    +        :param path_segment: A REST path segment.
    +        :type path_segment: ``string``
    +        :param owner: The owner context of the namespace (optional).
    +        :type owner: ``string``
    +        :param app: The app context of the namespace (optional).
    +        :type app: ``string``
    +        :param sharing: The sharing mode of the namespace (optional).
    +        :type sharing: ``string``
    +        :param headers: List of extra HTTP headers to send (optional).
    +        :type headers: ``list`` of 2-tuples.
    +        :param query: All other keyword arguments, which are used as query
    +            parameters.
    +        :param body: Parameters to be used in the post body. If specified,
    +            any parameters in the query will be applied to the URL instead of
    +            the body. If a dict is supplied, the key-value pairs will be form
    +            encoded. If a string is supplied, the body will be passed through
    +            in the request unchanged.
    +        :type body: ``dict`` or ``str``
    +        :return: The response from the server.
    +        :rtype: ``dict`` with keys ``body``, ``headers``, ``reason``,
    +                and ``status``
    +
    +        **Example**::
    +
    +            c = binding.connect(...)
    +            c.post('saved/searches', name='boris',
    +                   search='search * earliest=-1m | head 1') == \\
    +                {'body': ...a response reader object...,
    +                 'headers': [('content-length', '10455'),
    +                             ('expires', 'Fri, 30 Oct 1998 00:00:00 GMT'),
    +                             ('server', 'Splunkd'),
    +                             ('connection', 'close'),
    +                             ('cache-control', 'no-store, max-age=0, must-revalidate, no-cache'),
    +                             ('date', 'Fri, 11 May 2012 16:46:06 GMT'),
    +                             ('content-type', 'text/xml; charset=utf-8')],
    +                 'reason': 'Created',
    +                 'status': 201}
    +            c.post('nonexistant/path') # raises HTTPError
    +            c.logout()
    +            # raises AuthenticationError:
    +            c.post('saved/searches', name='boris',
    +                   search='search * earliest=-1m | head 1')
    +        """
    +        if headers is None:
    +            headers = []
    +
    +        path = self.authority + self._abspath(path_segment, owner=owner, app=app, sharing=sharing)
    +
    +        # To avoid writing sensitive data in debug logs
    +        endpoint_having_sensitive_data = ["/storage/passwords"]
    +        if any(endpoint in path for endpoint in endpoint_having_sensitive_data):
    +            logger.debug("POST request to %s ", path)
    +        else:
    +            logger.debug("POST request to %s (body: %s)", path, repr(query))
    +        all_headers = headers + self.additional_headers + self._auth_headers
    +        response = self.http.post(path, all_headers, **query)
    +        return response
    +
    +    @_authentication
    +    @_log_duration
    +    def request(self, path_segment, method="GET", headers=None, body={},
    +                owner=None, app=None, sharing=None):
    +        """Issues an arbitrary HTTP request to the REST path segment.
    +
    +        This method is named to match ``httplib.request``. This function
    +        makes a single round trip to the server.
    +
    +        If *owner*, *app*, and *sharing* are omitted, this method uses the
    +        default :class:`Context` namespace. All other keyword arguments are
    +        included in the URL as query parameters.
    +
    +        :raises AuthenticationError: Raised when the ``Context`` object is not
    +             logged in.
    +        :raises HTTPError: Raised when an error occurred in a GET operation from
    +             *path_segment*.
    +        :param path_segment: A REST path segment.
    +        :type path_segment: ``string``
    +        :param method: The HTTP method to use (optional).
    +        :type method: ``string``
    +        :param headers: List of extra HTTP headers to send (optional).
    +        :type headers: ``list`` of 2-tuples.
    +        :param body: Content of the HTTP request (optional).
    +        :type body: ``string``
    +        :param owner: The owner context of the namespace (optional).
    +        :type owner: ``string``
    +        :param app: The app context of the namespace (optional).
    +        :type app: ``string``
    +        :param sharing: The sharing mode of the namespace (optional).
    +        :type sharing: ``string``
    +        :return: The response from the server.
    +        :rtype: ``dict`` with keys ``body``, ``headers``, ``reason``,
    +                and ``status``
    +
    +        **Example**::
    +
    +            c = binding.connect(...)
    +            c.request('saved/searches', method='GET') == \\
    +                {'body': ...a response reader object...,
    +                 'headers': [('content-length', '46722'),
    +                             ('expires', 'Fri, 30 Oct 1998 00:00:00 GMT'),
    +                             ('server', 'Splunkd'),
    +                             ('connection', 'close'),
    +                             ('cache-control', 'no-store, max-age=0, must-revalidate, no-cache'),
    +                             ('date', 'Fri, 11 May 2012 17:24:19 GMT'),
    +                             ('content-type', 'text/xml; charset=utf-8')],
    +                 'reason': 'OK',
    +                 'status': 200}
    +            c.request('nonexistant/path', method='GET') # raises HTTPError
    +            c.logout()
    +            c.get('apps/local') # raises AuthenticationError
    +        """
    +        if headers is None:
    +            headers = []
    +
    +        path = self.authority \
    +            + self._abspath(path_segment, owner=owner,
    +                            app=app, sharing=sharing)
    +
    +        all_headers = headers + self.additional_headers + self._auth_headers
    +        logger.debug("%s request to %s (headers: %s, body: %s)",
    +                      method, path, str(all_headers), repr(body))
    +
    +        if body:
    +            body = _encode(**body)
    +
    +            if method == "GET":
    +                path = path + UrlEncoded('?' + body, skip_encode=True)
    +                message = {'method': method,
    +                           'headers': all_headers}
    +            else:
    +                message = {'method': method,
    +                           'headers': all_headers,
    +                           'body': body}
    +        else:
    +            message = {'method': method,
    +                       'headers': all_headers}
    +
    +        response = self.http.request(path, message)
    +
    +        return response
    +
    +    def login(self):
    +        """Logs into the Splunk instance referred to by the :class:`Context`
    +        object.
    +
    +        Unless a ``Context`` is created with an explicit authentication token
    +        (probably obtained by logging in from a different ``Context`` object)
    +        you must call :meth:`login` before you can issue requests.
    +        The authentication token obtained from the server is stored in the
    +        ``token`` field of the ``Context`` object.
    +
    +        :raises AuthenticationError: Raised when login fails.
    +        :returns: The ``Context`` object, so you can chain calls.
    +
    +        **Example**::
    +
    +            import splunklib.binding as binding
    +            c = binding.Context(...).login()
    +            # Then issue requests...
    +        """
    +
    +        if self.has_cookies() and \
    +                (not self.username and not self.password):
    +            # If we were passed session cookie(s), but no username or
    +            # password, then login is a nop, since we're automatically
    +            # logged in.
    +            return
    +
    +        if self.token is not _NoAuthenticationToken and \
    +                (not self.username and not self.password):
    +            # If we were passed a session token, but no username or
    +            # password, then login is a nop, since we're automatically
    +            # logged in.
    +            return
    +
    +        if self.basic and (self.username and self.password):
    +            # Basic auth mode requested, so this method is a nop as long
    +            # as credentials were passed in.
    +            return
    +
    +        if self.bearerToken:
    +            # Bearer auth mode requested, so this method is a nop as long
    +            # as authentication token was passed in.
    +            return
    +        # Only try to get a token and updated cookie if username & password are specified
    +        try:
    +            response = self.http.post(
    +                self.authority + self._abspath("/services/auth/login"),
    +                username=self.username,
    +                password=self.password,
    +                headers=self.additional_headers,
    +                cookie="1") # In Splunk 6.2+, passing "cookie=1" will return the "set-cookie" header
    +
    +            body = response.body.read()
    +            session = XML(body).findtext("./sessionKey")
    +            self.token = "Splunk %s" % session
    +            return self
    +        except HTTPError as he:
    +            if he.status == 401:
    +                raise AuthenticationError("Login failed.", he)
    +            else:
    +                raise
    +
    +    def logout(self):
    +        """Forgets the current session token, and cookies."""
    +        self.token = _NoAuthenticationToken
    +        self.http._cookies = {}
    +        return self
    +
    +    def _abspath(self, path_segment,
    +                owner=None, app=None, sharing=None):
    +        """Qualifies *path_segment* into an absolute path for a URL.
    +
    +        If *path_segment* is already absolute, returns it unchanged.
    +        If *path_segment* is relative, then qualifies it with either
    +        the provided namespace arguments or the ``Context``'s default
    +        namespace. Any forbidden characters in *path_segment* are URL
    +        encoded. This function has no network activity.
    +
    +        Named to be consistent with RFC2396_.
    +
    +        .. _RFC2396: http://www.ietf.org/rfc/rfc2396.txt
    +
    +        :param path_segment: A relative or absolute URL path segment.
    +        :type path_segment: ``string``
    +        :param owner, app, sharing: Components of a namespace (defaults
    +                                    to the ``Context``'s namespace if all
    +                                    three are omitted)
    +        :type owner, app, sharing: ``string``
    +        :return: A ``UrlEncoded`` (a subclass of ``str``).
    +        :rtype: ``string``
    +
    +        **Example**::
    +
    +            import splunklib.binding as binding
    +            c = binding.connect(owner='boris', app='search', sharing='user')
    +            c._abspath('/a/b/c') == '/a/b/c'
    +            c._abspath('/a/b c/d') == '/a/b%20c/d'
    +            c._abspath('apps/local/search') == \
    +                '/servicesNS/boris/search/apps/local/search'
    +            c._abspath('apps/local/search', sharing='system') == \
    +                '/servicesNS/nobody/system/apps/local/search'
    +            url = c.authority + c._abspath('apps/local/sharing')
    +        """
    +        skip_encode = isinstance(path_segment, UrlEncoded)
    +        # If path_segment is absolute, escape all forbidden characters
    +        # in it and return it.
    +        if path_segment.startswith('/'):
    +            return UrlEncoded(path_segment, skip_encode=skip_encode)
    +
    +        # path_segment is relative, so we need a namespace to build an
    +        # absolute path.
    +        if owner or app or sharing:
    +            ns = namespace(owner=owner, app=app, sharing=sharing)
    +        else:
    +            ns = self.namespace
    +
    +        # If no app or owner are specified, then use the /services
    +        # endpoint. Otherwise, use /servicesNS with the specified
    +        # namespace. If only one of app and owner is specified, use
    +        # '-' for the other.
    +        if ns.app is None and ns.owner is None:
    +            return UrlEncoded("/services/%s" % path_segment, skip_encode=skip_encode)
    +
    +        oname = "nobody" if ns.owner is None else ns.owner
    +        aname = "system" if ns.app is None else ns.app
    +        path = UrlEncoded("/servicesNS/%s/%s/%s" % (oname, aname, path_segment),
    +                          skip_encode=skip_encode)
    +        return path
    +
    +
    +def connect(**kwargs):
    +    """This function returns an authenticated :class:`Context` object.
    +
    +    This function is a shorthand for calling :meth:`Context.login`.
    +
    +    This function makes one round trip to the server.
    +
    +    :param host: The host name (the default is "localhost").
    +    :type host: ``string``
    +    :param port: The port number (the default is 8089).
    +    :type port: ``integer``
    +    :param scheme: The scheme for accessing the service (the default is "https").
    +    :type scheme: "https" or "http"
    +    :param owner: The owner context of the namespace (the default is "None").
    +    :type owner: ``string``
    +    :param app: The app context of the namespace (the default is "None").
    +    :type app: ``string``
    +    :param sharing: The sharing mode for the namespace (the default is "user").
    +    :type sharing: "global", "system", "app", or "user"
    +    :param token: The current session token (optional). Session tokens can be
    +        shared across multiple service instances.
    +    :type token: ``string``
    +    :param cookie: A session cookie. When provided, you don't need to call :meth:`login`.
    +        This parameter is only supported for Splunk 6.2+.
    +    :type cookie: ``string``
    +    :param username: The Splunk account username, which is used to
    +        authenticate the Splunk instance.
    +    :type username: ``string``
    +    :param password: The password for the Splunk account.
    +    :type password: ``string``
    +    :param headers: List of extra HTTP headers to send (optional).
    +    :type headers: ``list`` of 2-tuples.
    +    :param autologin: When ``True``, automatically tries to log in again if the
    +        session terminates.
    +    :type autologin: ``Boolean``
    +    :return: An initialized :class:`Context` instance.
    +
    +    **Example**::
    +
    +        import splunklib.binding as binding
    +        c = binding.connect(...)
    +        response = c.get("apps/local")
    +    """
    +    c = Context(**kwargs)
    +    c.login()
    +    return c
    +
    +# Note: the error response schema supports multiple messages but we only
    +# return the first, although we do return the body so that an exception
    +# handler that wants to read multiple messages can do so.
    +class HTTPError(Exception):
    +    """This exception is raised for HTTP responses that return an error."""
    +    def __init__(self, response, _message=None):
    +        status = response.status
    +        reason = response.reason
    +        body = response.body.read()
    +        try:
    +            detail = XML(body).findtext("./messages/msg")
    +        except ParseError as err:
    +            detail = body
    +        message = "HTTP %d %s%s" % (
    +            status, reason, "" if detail is None else " -- %s" % detail)
    +        Exception.__init__(self, _message or message)
    +        self.status = status
    +        self.reason = reason
    +        self.headers = response.headers
    +        self.body = body
    +        self._response = response
    +
    +class AuthenticationError(HTTPError):
    +    """Raised when a login request to Splunk fails.
    +
    +    If your username was unknown or you provided an incorrect password
    +    in a call to :meth:`Context.login` or :meth:`splunklib.client.Service.login`,
    +    this exception is raised.
    +    """
    +    def __init__(self, message, cause):
    +        # Put the body back in the response so that HTTPError's constructor can
    +        # read it again.
    +        cause._response.body = BytesIO(cause.body)
    +
    +        HTTPError.__init__(self, cause._response, message)
    +
    +#
    +# The HTTP interface used by the Splunk binding layer abstracts the underlying
    +# HTTP library using request & response 'messages' which are implemented as
    +# dictionaries with the following structure:
    +#
    +#   # HTTP request message (only method required)
    +#   request {
    +#       method : str,
    +#       headers? : [(str, str)*],
    +#       body? : str,
    +#   }
    +#
    +#   # HTTP response message (all keys present)
    +#   response {
    +#       status : int,
    +#       reason : str,
    +#       headers : [(str, str)*],
    +#       body : file,
    +#   }
    +#
    +
    +# Encode the given kwargs as a query string. This wrapper will also _encode
    +# a list value as a sequence of assignments to the corresponding arg name,
    +# for example an argument such as 'foo=[1,2,3]' will be encoded as
    +# 'foo=1&foo=2&foo=3'.
    +def _encode(**kwargs):
    +    items = []
    +    for key, value in six.iteritems(kwargs):
    +        if isinstance(value, list):
    +            items.extend([(key, item) for item in value])
    +        else:
    +            items.append((key, value))
    +    return urllib.parse.urlencode(items)
    +
    +# Crack the given url into (scheme, host, port, path)
    +def _spliturl(url):
    +    parsed_url = urllib.parse.urlparse(url)
    +    host = parsed_url.hostname
    +    port = parsed_url.port
    +    path = '?'.join((parsed_url.path, parsed_url.query)) if parsed_url.query else parsed_url.path
    +    # Strip brackets if its an IPv6 address
    +    if host.startswith('[') and host.endswith(']'): host = host[1:-1]
    +    if port is None: port = DEFAULT_PORT
    +    return parsed_url.scheme, host, port, path
    +
    +# Given an HTTP request handler, this wrapper objects provides a related
    +# family of convenience methods built using that handler.
    +class HttpLib(object):
    +    """A set of convenient methods for making HTTP calls.
    +
    +    ``HttpLib`` provides a general :meth:`request` method, and :meth:`delete`,
    +    :meth:`post`, and :meth:`get` methods for the three HTTP methods that Splunk
    +    uses.
    +
    +    By default, ``HttpLib`` uses Python's built-in ``httplib`` library,
    +    but you can replace it by passing your own handling function to the
    +    constructor for ``HttpLib``.
    +
    +    The handling function should have the type:
    +
    +        ``handler(`url`, `request_dict`) -> response_dict``
    +
    +    where `url` is the URL to make the request to (including any query and
    +    fragment sections) as a dictionary with the following keys:
    +
    +        - method: The method for the request, typically ``GET``, ``POST``, or ``DELETE``.
    +
    +        - headers: A list of pairs specifying the HTTP headers (for example: ``[('key': value), ...]``).
    +
    +        - body: A string containing the body to send with the request (this string
    +          should default to '').
    +
    +    and ``response_dict`` is a dictionary with the following keys:
    +
    +        - status: An integer containing the HTTP status code (such as 200 or 404).
    +
    +        - reason: The reason phrase, if any, returned by the server.
    +
    +        - headers: A list of pairs containing the response headers (for example, ``[('key': value), ...]``).
    +
    +        - body: A stream-like object supporting ``read(size=None)`` and ``close()``
    +          methods to get the body of the response.
    +
    +    The response dictionary is returned directly by ``HttpLib``'s methods with
    +    no further processing. By default, ``HttpLib`` calls the :func:`handler` function
    +    to get a handler function.
    +
    +    If using the default handler, SSL verification can be disabled by passing verify=False.
    +    """
    +    def __init__(self, custom_handler=None, verify=False, key_file=None, cert_file=None, context=None, retries=0, retryDelay=10):
    +        if custom_handler is None:
    +            self.handler = handler(verify=verify, key_file=key_file, cert_file=cert_file, context=context)
    +        else:
    +            self.handler = custom_handler
    +        self._cookies = {}
    +        self.retries = retries
    +        self.retryDelay = retryDelay
    +
    +    def delete(self, url, headers=None, **kwargs):
    +        """Sends a DELETE request to a URL.
    +
    +        :param url: The URL.
    +        :type url: ``string``
    +        :param headers: A list of pairs specifying the headers for the HTTP
    +            response (for example, ``[('Content-Type': 'text/cthulhu'), ('Token': 'boris')]``).
    +        :type headers: ``list``
    +        :param kwargs: Additional keyword arguments (optional). These arguments
    +            are interpreted as the query part of the URL. The order of keyword
    +            arguments is not preserved in the request, but the keywords and
    +            their arguments will be URL encoded.
    +        :type kwargs: ``dict``
    +        :returns: A dictionary describing the response (see :class:`HttpLib` for
    +            its structure).
    +        :rtype: ``dict``
    +        """
    +        if headers is None: headers = []
    +        if kwargs:
    +            # url is already a UrlEncoded. We have to manually declare
    +            # the query to be encoded or it will get automatically URL
    +            # encoded by being appended to url.
    +            url = url + UrlEncoded('?' + _encode(**kwargs), skip_encode=True)
    +        message = {
    +            'method': "DELETE",
    +            'headers': headers,
    +        }
    +        return self.request(url, message)
    +
    +    def get(self, url, headers=None, **kwargs):
    +        """Sends a GET request to a URL.
    +
    +        :param url: The URL.
    +        :type url: ``string``
    +        :param headers: A list of pairs specifying the headers for the HTTP
    +            response (for example, ``[('Content-Type': 'text/cthulhu'), ('Token': 'boris')]``).
    +        :type headers: ``list``
    +        :param kwargs: Additional keyword arguments (optional). These arguments
    +            are interpreted as the query part of the URL. The order of keyword
    +            arguments is not preserved in the request, but the keywords and
    +            their arguments will be URL encoded.
    +        :type kwargs: ``dict``
    +        :returns: A dictionary describing the response (see :class:`HttpLib` for
    +            its structure).
    +        :rtype: ``dict``
    +        """
    +        if headers is None: headers = []
    +        if kwargs:
    +            # url is already a UrlEncoded. We have to manually declare
    +            # the query to be encoded or it will get automatically URL
    +            # encoded by being appended to url.
    +            url = url + UrlEncoded('?' + _encode(**kwargs), skip_encode=True)
    +        return self.request(url, { 'method': "GET", 'headers': headers })
    +
    +    def post(self, url, headers=None, **kwargs):
    +        """Sends a POST request to a URL.
    +
    +        :param url: The URL.
    +        :type url: ``string``
    +        :param headers: A list of pairs specifying the headers for the HTTP
    +            response (for example, ``[('Content-Type': 'text/cthulhu'), ('Token': 'boris')]``).
    +        :type headers: ``list``
    +        :param kwargs: Additional keyword arguments (optional). If the argument
    +            is ``body``, the value is used as the body for the request, and the
    +            keywords and their arguments will be URL encoded. If there is no
    +            ``body`` keyword argument, all the keyword arguments are encoded
    +            into the body of the request in the format ``x-www-form-urlencoded``.
    +        :type kwargs: ``dict``
    +        :returns: A dictionary describing the response (see :class:`HttpLib` for
    +            its structure).
    +        :rtype: ``dict``
    +        """
    +        if headers is None: headers = []
    +
    +        # We handle GET-style arguments and an unstructured body. This is here
    +        # to support the receivers/stream endpoint.
    +        if 'body' in kwargs:
    +            # We only use application/x-www-form-urlencoded if there is no other
    +            # Content-Type header present. This can happen in cases where we
    +            # send requests as application/json, e.g. for KV Store.
    +            if len([x for x in headers if x[0].lower() == "content-type"]) == 0:
    +                headers.append(("Content-Type", "application/x-www-form-urlencoded"))
    +
    +            body = kwargs.pop('body')
    +            if isinstance(body, dict):
    +                body = _encode(**body).encode('utf-8')
    +            if len(kwargs) > 0:
    +                url = url + UrlEncoded('?' + _encode(**kwargs), skip_encode=True)
    +        else:
    +            body = _encode(**kwargs).encode('utf-8')
    +        message = {
    +            'method': "POST",
    +            'headers': headers,
    +            'body': body
    +        }
    +        return self.request(url, message)
    +
    +    def request(self, url, message, **kwargs):
    +        """Issues an HTTP request to a URL.
    +
    +        :param url: The URL.
    +        :type url: ``string``
    +        :param message: A dictionary with the format as described in
    +            :class:`HttpLib`.
    +        :type message: ``dict``
    +        :param kwargs: Additional keyword arguments (optional). These arguments
    +            are passed unchanged to the handler.
    +        :type kwargs: ``dict``
    +        :returns: A dictionary describing the response (see :class:`HttpLib` for
    +            its structure).
    +        :rtype: ``dict``
    +        """
    +        while True:
    +            try:
    +                response = self.handler(url, message, **kwargs)
    +                break
    +            except Exception:
    +                if self.retries <= 0:
    +                    raise
    +                else:
    +                    time.sleep(self.retryDelay)
    +                    self.retries -= 1
    +        response = record(response)
    +        if 400 <= response.status:
    +            raise HTTPError(response)
    +
    +        # Update the cookie with any HTTP request
    +        # Initially, assume list of 2-tuples
    +        key_value_tuples = response.headers
    +        # If response.headers is a dict, get the key-value pairs as 2-tuples
    +        # this is the case when using urllib2
    +        if isinstance(response.headers, dict):
    +            key_value_tuples = list(response.headers.items())
    +        for key, value in key_value_tuples:
    +            if key.lower() == "set-cookie":
    +                _parse_cookies(value, self._cookies)
    +
    +        return response
    +
    +
    +# Converts an httplib response into a file-like object.
    +class ResponseReader(io.RawIOBase):
    +    """This class provides a file-like interface for :class:`httplib` responses.
    +
    +    The ``ResponseReader`` class is intended to be a layer to unify the different
    +    types of HTTP libraries used with this SDK. This class also provides a
    +    preview of the stream and a few useful predicates.
    +    """
    +    # For testing, you can use a StringIO as the argument to
    +    # ``ResponseReader`` instead of an ``httplib.HTTPResponse``. It
    +    # will work equally well.
    +    def __init__(self, response, connection=None):
    +        self._response = response
    +        self._connection = connection
    +        self._buffer = b''
    +
    +    def __str__(self):
    +        if six.PY2:
    +            return self.read()
    +        else:
    +            return str(self.read(), 'UTF-8')
    +
    +    @property
    +    def empty(self):
    +        """Indicates whether there is any more data in the response."""
    +        return self.peek(1) == b""
    +
    +    def peek(self, size):
    +        """Nondestructively retrieves a given number of characters.
    +
    +        The next :meth:`read` operation behaves as though this method was never
    +        called.
    +
    +        :param size: The number of characters to retrieve.
    +        :type size: ``integer``
    +        """
    +        c = self.read(size)
    +        self._buffer = self._buffer + c
    +        return c
    +
    +    def close(self):
    +        """Closes this response."""
    +        if self._connection:
    +            self._connection.close()
    +        self._response.close()
    +
    +    def read(self, size = None):
    +        """Reads a given number of characters from the response.
    +
    +        :param size: The number of characters to read, or "None" to read the
    +            entire response.
    +        :type size: ``integer`` or "None"
    +
    +        """
    +        r = self._buffer
    +        self._buffer = b''
    +        if size is not None:
    +            size -= len(r)
    +        r = r + self._response.read(size)
    +        return r
    +
    +    def readable(self):
    +        """ Indicates that the response reader is readable."""
    +        return True
    +
    +    def readinto(self, byte_array):
    +        """ Read data into a byte array, upto the size of the byte array.
    +
    +        :param byte_array: A byte array/memory view to pour bytes into.
    +        :type byte_array: ``bytearray`` or ``memoryview``
    +
    +        """
    +        max_size = len(byte_array)
    +        data = self.read(max_size)
    +        bytes_read = len(data)
    +        byte_array[:bytes_read] = data
    +        return bytes_read
    +
    +
    +def handler(key_file=None, cert_file=None, timeout=None, verify=False, context=None):
    +    """This class returns an instance of the default HTTP request handler using
    +    the values you provide.
    +
    +    :param `key_file`: A path to a PEM (Privacy Enhanced Mail) formatted file containing your private key (optional).
    +    :type key_file: ``string``
    +    :param `cert_file`: A path to a PEM (Privacy Enhanced Mail) formatted file containing a certificate chain file (optional).
    +    :type cert_file: ``string``
    +    :param `timeout`: The request time-out period, in seconds (optional).
    +    :type timeout: ``integer`` or "None"
    +    :param `verify`: Set to False to disable SSL verification on https connections.
    +    :type verify: ``Boolean``
    +    :param `context`: The SSLContext that can is used with the HTTPSConnection when verify=True is enabled and context is specified
    +    :type context: ``SSLContext`
    +    """
    +
    +    def connect(scheme, host, port):
    +        kwargs = {}
    +        if timeout is not None: kwargs['timeout'] = timeout
    +        if scheme == "http":
    +            return six.moves.http_client.HTTPConnection(host, port, **kwargs)
    +        if scheme == "https":
    +            if key_file is not None: kwargs['key_file'] = key_file
    +            if cert_file is not None: kwargs['cert_file'] = cert_file
    +
    +            if not verify:
    +                kwargs['context'] = ssl._create_unverified_context()
    +            elif context:
    +                # verify is True in elif branch and context is not None
    +                kwargs['context'] = context
    +
    +            return six.moves.http_client.HTTPSConnection(host, port, **kwargs)
    +        raise ValueError("unsupported scheme: %s" % scheme)
    +
    +    def request(url, message, **kwargs):
    +        scheme, host, port, path = _spliturl(url)
    +        body = message.get("body", "")
    +        head = {
    +            "Content-Length": str(len(body)),
    +            "Host": host,
    +            "User-Agent": "splunk-sdk-python/%s" % __version__,
    +            "Accept": "*/*",
    +            "Connection": "Close",
    +        } # defaults
    +        for key, value in message["headers"]:
    +            head[key] = value
    +        method = message.get("method", "GET")
    +
    +        connection = connect(scheme, host, port)
    +        is_keepalive = False
    +        try:
    +            connection.request(method, path, body, head)
    +            if timeout is not None:
    +                connection.sock.settimeout(timeout)
    +            response = connection.getresponse()
    +            is_keepalive = "keep-alive" in response.getheader("connection", default="close").lower()
    +        finally:
    +            if not is_keepalive:
    +                connection.close()
    +
    +        return {
    +            "status": response.status,
    +            "reason": response.reason,
    +            "headers": response.getheaders(),
    +            "body": ResponseReader(response, connection if is_keepalive else None),
    +        }
    +
    +    return request
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/client.py b/deployment-apps/metricator-for-nmon/lib/splunklib/client.py
    new file mode 100644
    index 0000000..33156bb
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/client.py
    @@ -0,0 +1,3915 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +#
    +# The purpose of this module is to provide a friendlier domain interface to
    +# various Splunk endpoints. The approach here is to leverage the binding
    +# layer to capture endpoint context and provide objects and methods that
    +# offer simplified access their corresponding endpoints. The design avoids
    +# caching resource state. From the perspective of this module, the 'policy'
    +# for caching resource state belongs in the application or a higher level
    +# framework, and its the purpose of this module to provide simplified
    +# access to that resource state.
    +#
    +# A side note, the objects below that provide helper methods for updating eg:
    +# Entity state, are written so that they may be used in a fluent style.
    +#
    +
    +"""The **splunklib.client** module provides a Pythonic interface to the
    +`Splunk REST API <http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTcontents>`_,
    +allowing you programmatically access Splunk's resources.
    +
    +**splunklib.client** wraps a Pythonic layer around the wire-level
    +binding of the **splunklib.binding** module. The core of the library is the
    +:class:`Service` class, which encapsulates a connection to the server, and
    +provides access to the various aspects of Splunk's functionality, which are
    +exposed via the REST API. Typically you connect to a running Splunk instance
    +with the :func:`connect` function::
    +
    +    import splunklib.client as client
    +    service = client.connect(host='localhost', port=8089,
    +                       username='admin', password='...')
    +    assert isinstance(service, client.Service)
    +
    +:class:`Service` objects have fields for the various Splunk resources (such as apps,
    +jobs, saved searches, inputs, and indexes). All of these fields are
    +:class:`Collection` objects::
    +
    +    appcollection = service.apps
    +    my_app = appcollection.create('my_app')
    +    my_app = appcollection['my_app']
    +    appcollection.delete('my_app')
    +
    +The individual elements of the collection, in this case *applications*,
    +are subclasses of :class:`Entity`. An ``Entity`` object has fields for its
    +attributes, and methods that are specific to each kind of entity. For example::
    +
    +    print my_app['author']  # Or: print my_app.author
    +    my_app.package()  # Creates a compressed package of this application
    +"""
    +
    +import contextlib
    +import datetime
    +import json
    +import logging
    +import re
    +import socket
    +from datetime import datetime, timedelta
    +from time import sleep
    +
    +from splunklib import six
    +from splunklib.six.moves import urllib
    +
    +from . import data
    +from .binding import (AuthenticationError, Context, HTTPError, UrlEncoded,
    +                      _encode, _make_cookie_header, _NoAuthenticationToken,
    +                      namespace)
    +from .data import record
    +
    +logger = logging.getLogger(__name__)
    +
    +__all__ = [
    +    "connect",
    +    "NotSupportedError",
    +    "OperationError",
    +    "IncomparableException",
    +    "Service",
    +    "namespace"
    +]
    +
    +PATH_APPS = "apps/local/"
    +PATH_CAPABILITIES = "authorization/capabilities/"
    +PATH_CONF = "configs/conf-%s/"
    +PATH_PROPERTIES = "properties/"
    +PATH_DEPLOYMENT_CLIENTS = "deployment/client/"
    +PATH_DEPLOYMENT_TENANTS = "deployment/tenants/"
    +PATH_DEPLOYMENT_SERVERS = "deployment/server/"
    +PATH_DEPLOYMENT_SERVERCLASSES = "deployment/serverclass/"
    +PATH_EVENT_TYPES = "saved/eventtypes/"
    +PATH_FIRED_ALERTS = "alerts/fired_alerts/"
    +PATH_INDEXES = "data/indexes/"
    +PATH_INPUTS = "data/inputs/"
    +PATH_JOBS = "search/jobs/"
    +PATH_JOBS_V2 = "search/v2/jobs/"
    +PATH_LOGGER = "/services/server/logger/"
    +PATH_MESSAGES = "messages/"
    +PATH_MODULAR_INPUTS = "data/modular-inputs"
    +PATH_ROLES = "authorization/roles/"
    +PATH_SAVED_SEARCHES = "saved/searches/"
    +PATH_STANZA = "configs/conf-%s/%s" # (file, stanza)
    +PATH_USERS = "authentication/users/"
    +PATH_RECEIVERS_STREAM = "/services/receivers/stream"
    +PATH_RECEIVERS_SIMPLE = "/services/receivers/simple"
    +PATH_STORAGE_PASSWORDS = "storage/passwords"
    +
    +XNAMEF_ATOM = "{http://www.w3.org/2005/Atom}%s"
    +XNAME_ENTRY = XNAMEF_ATOM % "entry"
    +XNAME_CONTENT = XNAMEF_ATOM % "content"
    +
    +MATCH_ENTRY_CONTENT = "%s/%s/*" % (XNAME_ENTRY, XNAME_CONTENT)
    +
    +
    +class IllegalOperationException(Exception):
    +    """Thrown when an operation is not possible on the Splunk instance that a
    +    :class:`Service` object is connected to."""
    +    pass
    +
    +
    +class IncomparableException(Exception):
    +    """Thrown when trying to compare objects (using ``==``, ``<``, ``>``, and
    +    so on) of a type that doesn't support it."""
    +    pass
    +
    +
    +class AmbiguousReferenceException(ValueError):
    +    """Thrown when the name used to fetch an entity matches more than one entity."""
    +    pass
    +
    +
    +class InvalidNameException(Exception):
    +    """Thrown when the specified name contains characters that are not allowed
    +    in Splunk entity names."""
    +    pass
    +
    +
    +class NoSuchCapability(Exception):
    +    """Thrown when the capability that has been referred to doesn't exist."""
    +    pass
    +
    +
    +class OperationError(Exception):
    +    """Raised for a failed operation, such as a time out."""
    +    pass
    +
    +
    +class NotSupportedError(Exception):
    +    """Raised for operations that are not supported on a given object."""
    +    pass
    +
    +
    +def _trailing(template, *targets):
    +    """Substring of *template* following all *targets*.
    +
    +    **Example**::
    +
    +        template = "this is a test of the bunnies."
    +        _trailing(template, "is", "est", "the") == " bunnies"
    +
    +    Each target is matched successively in the string, and the string
    +    remaining after the last target is returned. If one of the targets
    +    fails to match, a ValueError is raised.
    +
    +    :param template: Template to extract a trailing string from.
    +    :type template: ``string``
    +    :param targets: Strings to successively match in *template*.
    +    :type targets: list of ``string``s
    +    :return: Trailing string after all targets are matched.
    +    :rtype: ``string``
    +    :raises ValueError: Raised when one of the targets does not match.
    +    """
    +    s = template
    +    for t in targets:
    +        n = s.find(t)
    +        if n == -1:
    +            raise ValueError("Target " + t + " not found in template.")
    +        s = s[n + len(t):]
    +    return s
    +
    +
    +# Filter the given state content record according to the given arg list.
    +def _filter_content(content, *args):
    +    if len(args) > 0:
    +        return record((k, content[k]) for k in args)
    +    return record((k, v) for k, v in six.iteritems(content)
    +        if k not in ['eai:acl', 'eai:attributes', 'type'])
    +
    +# Construct a resource path from the given base path + resource name
    +def _path(base, name):
    +    if not base.endswith('/'): base = base + '/'
    +    return base + name
    +
    +
    +# Load an atom record from the body of the given response
    +# this will ultimately be sent to an xml ElementTree so we
    +# should use the xmlcharrefreplace option
    +def _load_atom(response, match=None):
    +    return data.load(response.body.read()
    +                     .decode('utf-8', 'xmlcharrefreplace'), match)
    +
    +
    +# Load an array of atom entries from the body of the given response
    +def _load_atom_entries(response):
    +    r = _load_atom(response)
    +    if 'feed' in r:
    +        # Need this to handle a random case in the REST API
    +        if r.feed.get('totalResults') in [0, '0']:
    +            return []
    +        entries = r.feed.get('entry', None)
    +        if entries is None: return None
    +        return entries if isinstance(entries, list) else [entries]
    +    # Unlike most other endpoints, the jobs endpoint does not return
    +    # its state wrapped in another element, but at the top level.
    +    # For example, in XML, it returns <entry>...</entry> instead of
    +    # <feed><entry>...</entry></feed>.
    +    else:
    +        entries = r.get('entry', None)
    +        if entries is None: return None
    +        return entries if isinstance(entries, list) else [entries]
    +
    +
    +# Load the sid from the body of the given response
    +def _load_sid(response, output_mode):
    +    if output_mode == "json":
    +        json_obj = json.loads(response.body.read())
    +        return json_obj.get('sid')
    +    return _load_atom(response).response.sid
    +
    +
    +# Parse the given atom entry record into a generic entity state record
    +def _parse_atom_entry(entry):
    +    title = entry.get('title', None)
    +
    +    elink = entry.get('link', [])
    +    elink = elink if isinstance(elink, list) else [elink]
    +    links = record((link.rel, link.href) for link in elink)
    +
    +    # Retrieve entity content values
    +    content = entry.get('content', {})
    +
    +    # Host entry metadata
    +    metadata = _parse_atom_metadata(content)
    +
    +    # Filter some of the noise out of the content record
    +    content = record((k, v) for k, v in six.iteritems(content)
    +                     if k not in ['eai:acl', 'eai:attributes'])
    +
    +    if 'type' in content:
    +        if isinstance(content['type'], list):
    +            content['type'] = [t for t in content['type'] if t != 'text/xml']
    +            # Unset type if it was only 'text/xml'
    +            if len(content['type']) == 0:
    +                content.pop('type', None)
    +            # Flatten 1 element list
    +            if len(content['type']) == 1:
    +                content['type'] = content['type'][0]
    +        else:
    +            content.pop('type', None)
    +
    +    return record({
    +        'title': title,
    +        'links': links,
    +        'access': metadata.access,
    +        'fields': metadata.fields,
    +        'content': content,
    +        'updated': entry.get("updated")
    +    })
    +
    +
    +# Parse the metadata fields out of the given atom entry content record
    +def _parse_atom_metadata(content):
    +    # Hoist access metadata
    +    access = content.get('eai:acl', None)
    +
    +    # Hoist content metadata (and cleanup some naming)
    +    attributes = content.get('eai:attributes', {})
    +    fields = record({
    +        'required': attributes.get('requiredFields', []),
    +        'optional': attributes.get('optionalFields', []),
    +        'wildcard': attributes.get('wildcardFields', [])})
    +
    +    return record({'access': access, 'fields': fields})
    +
    +# kwargs: scheme, host, port, app, owner, username, password
    +def connect(**kwargs):
    +    """This function connects and logs in to a Splunk instance.
    +
    +    This function is a shorthand for :meth:`Service.login`.
    +    The ``connect`` function makes one round trip to the server (for logging in).
    +
    +    :param host: The host name (the default is "localhost").
    +    :type host: ``string``
    +    :param port: The port number (the default is 8089).
    +    :type port: ``integer``
    +    :param scheme: The scheme for accessing the service (the default is "https").
    +    :type scheme: "https" or "http"
    +    :param verify: Enable (True) or disable (False) SSL verification for
    +                   https connections. (optional, the default is True)
    +    :type verify: ``Boolean``
    +    :param `owner`: The owner context of the namespace (optional).
    +    :type owner: ``string``
    +    :param `app`: The app context of the namespace (optional).
    +    :type app: ``string``
    +    :param sharing: The sharing mode for the namespace (the default is "user").
    +    :type sharing: "global", "system", "app", or "user"
    +    :param `token`: The current session token (optional). Session tokens can be
    +                    shared across multiple service instances.
    +    :type token: ``string``
    +    :param cookie: A session cookie. When provided, you don't need to call :meth:`login`.
    +        This parameter is only supported for Splunk 6.2+.
    +    :type cookie: ``string``
    +    :param autologin: When ``True``, automatically tries to log in again if the
    +        session terminates.
    +    :type autologin: ``boolean``
    +    :param `username`: The Splunk account username, which is used to
    +                       authenticate the Splunk instance.
    +    :type username: ``string``
    +    :param `password`: The password for the Splunk account.
    +    :type password: ``string``
    +    :param retires: Number of retries for each HTTP connection (optional, the default is 0).
    +                    NOTE THAT THIS MAY INCREASE THE NUMBER OF ROUND TRIP CONNECTIONS TO THE SPLUNK SERVER.
    +    :type retries: ``int``
    +    :param retryDelay: How long to wait between connection attempts if `retries` > 0 (optional, defaults to 10s).
    +    :type retryDelay: ``int`` (in seconds)
    +    :param `context`: The SSLContext that can be used when setting verify=True (optional)
    +    :type context: ``SSLContext``
    +    :return: An initialized :class:`Service` connection.
    +
    +    **Example**::
    +
    +        import splunklib.client as client
    +        s = client.connect(...)
    +        a = s.apps["my_app"]
    +        ...
    +    """
    +    s = Service(**kwargs)
    +    s.login()
    +    return s
    +
    +
    +# In preparation for adding Storm support, we added an
    +# intermediary class between Service and Context. Storm's
    +# API is not going to be the same as enterprise Splunk's
    +# API, so we will derive both Service (for enterprise Splunk)
    +# and StormService for (Splunk Storm) from _BaseService, and
    +# put any shared behavior on it.
    +class _BaseService(Context):
    +    pass
    +
    +
    +class Service(_BaseService):
    +    """A Pythonic binding to Splunk instances.
    +
    +    A :class:`Service` represents a binding to a Splunk instance on an
    +    HTTP or HTTPS port. It handles the details of authentication, wire
    +    formats, and wraps the REST API endpoints into something more
    +    Pythonic. All of the low-level operations on the instance from
    +    :class:`splunklib.binding.Context` are also available in case you need
    +    to do something beyond what is provided by this class.
    +
    +    After creating a ``Service`` object, you must call its :meth:`login`
    +    method before you can issue requests to Splunk.
    +    Alternately, use the :func:`connect` function to create an already
    +    authenticated :class:`Service` object, or provide a session token
    +    when creating the :class:`Service` object explicitly (the same
    +    token may be shared by multiple :class:`Service` objects).
    +
    +    :param host: The host name (the default is "localhost").
    +    :type host: ``string``
    +    :param port: The port number (the default is 8089).
    +    :type port: ``integer``
    +    :param scheme: The scheme for accessing the service (the default is "https").
    +    :type scheme: "https" or "http"
    +    :param verify: Enable (True) or disable (False) SSL verification for
    +                   https connections. (optional, the default is True)
    +    :type verify: ``Boolean``
    +    :param `owner`: The owner context of the namespace (optional; use "-" for wildcard).
    +    :type owner: ``string``
    +    :param `app`: The app context of the namespace (optional; use "-" for wildcard).
    +    :type app: ``string``
    +    :param `token`: The current session token (optional). Session tokens can be
    +                    shared across multiple service instances.
    +    :type token: ``string``
    +    :param cookie: A session cookie. When provided, you don't need to call :meth:`login`.
    +        This parameter is only supported for Splunk 6.2+.
    +    :type cookie: ``string``
    +    :param `username`: The Splunk account username, which is used to
    +                       authenticate the Splunk instance.
    +    :type username: ``string``
    +    :param `password`: The password, which is used to authenticate the Splunk
    +                       instance.
    +    :type password: ``string``
    +    :param retires: Number of retries for each HTTP connection (optional, the default is 0).
    +                    NOTE THAT THIS MAY INCREASE THE NUMBER OF ROUND TRIP CONNECTIONS TO THE SPLUNK SERVER.
    +    :type retries: ``int``
    +    :param retryDelay: How long to wait between connection attempts if `retries` > 0 (optional, defaults to 10s).
    +    :type retryDelay: ``int`` (in seconds)
    +    :return: A :class:`Service` instance.
    +
    +    **Example**::
    +
    +        import splunklib.client as client
    +        s = client.Service(username="boris", password="natasha", ...)
    +        s.login()
    +        # Or equivalently
    +        s = client.connect(username="boris", password="natasha")
    +        # Or if you already have a session token
    +        s = client.Service(token="atg232342aa34324a")
    +        # Or if you already have a valid cookie
    +        s = client.Service(cookie="splunkd_8089=...")
    +    """
    +    def __init__(self, **kwargs):
    +        super(Service, self).__init__(**kwargs)
    +        self._splunk_version = None
    +        self._kvstore_owner = None
    +        self._instance_type = None
    +
    +    @property
    +    def apps(self):
    +        """Returns the collection of applications that are installed on this instance of Splunk.
    +
    +        :return: A :class:`Collection` of :class:`Application` entities.
    +        """
    +        return Collection(self, PATH_APPS, item=Application)
    +
    +    @property
    +    def confs(self):
    +        """Returns the collection of configuration files for this Splunk instance.
    +
    +        :return: A :class:`Configurations` collection of
    +            :class:`ConfigurationFile` entities.
    +        """
    +        return Configurations(self)
    +
    +    @property
    +    def capabilities(self):
    +        """Returns the list of system capabilities.
    +
    +        :return: A ``list`` of capabilities.
    +        """
    +        response = self.get(PATH_CAPABILITIES)
    +        return _load_atom(response, MATCH_ENTRY_CONTENT).capabilities
    +
    +    @property
    +    def event_types(self):
    +        """Returns the collection of event types defined in this Splunk instance.
    +
    +        :return: An :class:`Entity` containing the event types.
    +        """
    +        return Collection(self, PATH_EVENT_TYPES)
    +
    +    @property
    +    def fired_alerts(self):
    +        """Returns the collection of alerts that have been fired on the Splunk
    +        instance, grouped by saved search.
    +
    +        :return: A :class:`Collection` of :class:`AlertGroup` entities.
    +        """
    +        return Collection(self, PATH_FIRED_ALERTS, item=AlertGroup)
    +
    +    @property
    +    def indexes(self):
    +        """Returns the collection of indexes for this Splunk instance.
    +
    +        :return: An :class:`Indexes` collection of :class:`Index` entities.
    +        """
    +        return Indexes(self, PATH_INDEXES, item=Index)
    +
    +    @property
    +    def info(self):
    +        """Returns the information about this instance of Splunk.
    +
    +        :return: The system information, as key-value pairs.
    +        :rtype: ``dict``
    +        """
    +        response = self.get("/services/server/info")
    +        return _filter_content(_load_atom(response, MATCH_ENTRY_CONTENT))
    +
    +    def input(self, path, kind=None):
    +        """Retrieves an input by path, and optionally kind.
    +
    +        :return: A :class:`Input` object.
    +        """
    +        return Input(self, path, kind=kind).refresh()
    +
    +    @property
    +    def inputs(self):
    +        """Returns the collection of inputs configured on this Splunk instance.
    +
    +        :return: An :class:`Inputs` collection of :class:`Input` entities.
    +        """
    +        return Inputs(self)
    +
    +    def job(self, sid):
    +        """Retrieves a search job by sid.
    +
    +        :return: A :class:`Job` object.
    +        """
    +        return Job(self, sid).refresh()
    +
    +    @property
    +    def jobs(self):
    +        """Returns the collection of current search jobs.
    +
    +        :return: A :class:`Jobs` collection of :class:`Job` entities.
    +        """
    +        return Jobs(self)
    +
    +    @property
    +    def loggers(self):
    +        """Returns the collection of logging level categories and their status.
    +
    +        :return: A :class:`Loggers` collection of logging levels.
    +        """
    +        return Loggers(self)
    +
    +    @property
    +    def messages(self):
    +        """Returns the collection of service messages.
    +
    +        :return: A :class:`Collection` of :class:`Message` entities.
    +        """
    +        return Collection(self, PATH_MESSAGES, item=Message)
    +
    +    @property
    +    def modular_input_kinds(self):
    +        """Returns the collection of the modular input kinds on this Splunk instance.
    +
    +        :return: A :class:`ReadOnlyCollection` of :class:`ModularInputKind` entities.
    +        """
    +        if self.splunk_version >= (5,):
    +            return ReadOnlyCollection(self, PATH_MODULAR_INPUTS, item=ModularInputKind)
    +        else:
    +            raise IllegalOperationException("Modular inputs are not supported before Splunk version 5.")
    +
    +    @property
    +    def storage_passwords(self):
    +        """Returns the collection of the storage passwords on this Splunk instance.
    +
    +        :return: A :class:`ReadOnlyCollection` of :class:`StoragePasswords` entities.
    +        """
    +        return StoragePasswords(self)
    +
    +    # kwargs: enable_lookups, reload_macros, parse_only, output_mode
    +    def parse(self, query, **kwargs):
    +        """Parses a search query and returns a semantic map of the search.
    +
    +        :param query: The search query to parse.
    +        :type query: ``string``
    +        :param kwargs: Arguments to pass to the ``search/parser`` endpoint
    +            (optional). Valid arguments are:
    +
    +            * "enable_lookups" (``boolean``): If ``True``, performs reverse lookups
    +              to expand the search expression.
    +
    +            * "output_mode" (``string``): The output format (XML or JSON).
    +
    +            * "parse_only" (``boolean``): If ``True``, disables the expansion of
    +              search due to evaluation of subsearches, time term expansion,
    +              lookups, tags, eventtypes, and sourcetype alias.
    +
    +            * "reload_macros" (``boolean``): If ``True``, reloads macro
    +              definitions from macros.conf.
    +
    +        :type kwargs: ``dict``
    +        :return: A semantic map of the parsed search query.
    +        """
    +        if not self.disable_v2_api:
    +            return self.post("search/v2/parser", q=query, **kwargs)
    +        return self.get("search/parser", q=query, **kwargs)
    +
    +    def restart(self, timeout=None):
    +        """Restarts this Splunk instance.
    +
    +        The service is unavailable until it has successfully restarted.
    +
    +        If a *timeout* value is specified, ``restart`` blocks until the service
    +        resumes or the timeout period has been exceeded. Otherwise, ``restart`` returns
    +        immediately.
    +
    +        :param timeout: A timeout period, in seconds.
    +        :type timeout: ``integer``
    +        """
    +        msg = { "value": "Restart requested by " + self.username + "via the Splunk SDK for Python"}
    +        # This message will be deleted once the server actually restarts.
    +        self.messages.create(name="restart_required", **msg)
    +        result = self.post("/services/server/control/restart")
    +        if timeout is None:
    +            return result
    +        start = datetime.now()
    +        diff = timedelta(seconds=timeout)
    +        while datetime.now() - start < diff:
    +            try:
    +                self.login()
    +                if not self.restart_required:
    +                    return result
    +            except Exception as e:
    +                sleep(1)
    +        raise Exception("Operation time out.")
    +
    +    @property
    +    def restart_required(self):
    +        """Indicates whether splunkd is in a state that requires a restart.
    +
    +        :return: A ``boolean`` that indicates whether a restart is required.
    +
    +        """
    +        response = self.get("messages").body.read()
    +        messages = data.load(response)['feed']
    +        if 'entry' not in messages:
    +            result = False
    +        else:
    +            if isinstance(messages['entry'], dict):
    +                titles = [messages['entry']['title']]
    +            else:
    +                titles = [x['title'] for x in messages['entry']]
    +            result = 'restart_required' in titles
    +        return result
    +
    +    @property
    +    def roles(self):
    +        """Returns the collection of user roles.
    +
    +        :return: A :class:`Roles` collection of :class:`Role` entities.
    +        """
    +        return Roles(self)
    +
    +    def search(self, query, **kwargs):
    +        """Runs a search using a search query and any optional arguments you
    +        provide, and returns a `Job` object representing the search.
    +
    +        :param query: A search query.
    +        :type query: ``string``
    +        :param kwargs: Arguments for the search (optional):
    +
    +            * "output_mode" (``string``): Specifies the output format of the
    +              results.
    +
    +            * "earliest_time" (``string``): Specifies the earliest time in the
    +              time range to
    +              search. The time string can be a UTC time (with fractional
    +              seconds), a relative time specifier (to now), or a formatted
    +              time string.
    +
    +            * "latest_time" (``string``): Specifies the latest time in the time
    +              range to
    +              search. The time string can be a UTC time (with fractional
    +              seconds), a relative time specifier (to now), or a formatted
    +              time string.
    +
    +            * "rf" (``string``): Specifies one or more fields to add to the
    +              search.
    +
    +        :type kwargs: ``dict``
    +        :rtype: class:`Job`
    +        :returns: An object representing the created job.
    +        """
    +        return self.jobs.create(query, **kwargs)
    +
    +    @property
    +    def saved_searches(self):
    +        """Returns the collection of saved searches.
    +
    +        :return: A :class:`SavedSearches` collection of :class:`SavedSearch`
    +            entities.
    +        """
    +        return SavedSearches(self)
    +
    +    @property
    +    def settings(self):
    +        """Returns the configuration settings for this instance of Splunk.
    +
    +        :return: A :class:`Settings` object containing configuration settings.
    +        """
    +        return Settings(self)
    +
    +    @property
    +    def splunk_version(self):
    +        """Returns the version of the splunkd instance this object is attached
    +        to.
    +
    +        The version is returned as a tuple of the version components as
    +        integers (for example, `(4,3,3)` or `(5,)`).
    +
    +        :return: A ``tuple`` of ``integers``.
    +        """
    +        if self._splunk_version is None:
    +            self._splunk_version = tuple([int(p) for p in self.info['version'].split('.')])
    +        return self._splunk_version
    +
    +    @property
    +    def splunk_instance(self):
    +        if self._instance_type is None :
    +            splunk_info = self.info;
    +            if hasattr(splunk_info, 'instance_type') :
    +                self._instance_type = splunk_info['instance_type']
    +            else:
    +                self._instance_type = ''
    +        return self._instance_type
    +
    +    @property
    +    def disable_v2_api(self):
    +        if self.splunk_instance.lower() == 'cloud':
    +            return self.splunk_version < (9,0,2209)
    +        return self.splunk_version < (9,0,2)
    +
    +    @property
    +    def kvstore_owner(self):
    +        """Returns the KVStore owner for this instance of Splunk.
    +
    +        By default is the kvstore owner is not set, it will return "nobody"
    +        :return: A string with the KVStore owner.
    +        """
    +        if self._kvstore_owner is None:
    +            self._kvstore_owner = "nobody"
    +        return self._kvstore_owner
    +
    +    @kvstore_owner.setter
    +    def kvstore_owner(self, value):
    +        """
    +        kvstore is refreshed, when the owner value is changed
    +        """
    +        self._kvstore_owner = value
    +        self.kvstore
    +
    +    @property
    +    def kvstore(self):
    +        """Returns the collection of KV Store collections.
    +
    +        sets the owner for the namespace, before retrieving the KVStore Collection
    +
    +        :return: A :class:`KVStoreCollections` collection of :class:`KVStoreCollection` entities.
    +        """
    +        self.namespace['owner'] = self.kvstore_owner
    +        return KVStoreCollections(self)
    +
    +    @property
    +    def users(self):
    +        """Returns the collection of users.
    +
    +        :return: A :class:`Users` collection of :class:`User` entities.
    +        """
    +        return Users(self)
    +
    +
    +class Endpoint(object):
    +    """This class represents individual Splunk resources in the Splunk REST API.
    +
    +    An ``Endpoint`` object represents a URI, such as ``/services/saved/searches``.
    +    This class provides the common functionality of :class:`Collection` and
    +    :class:`Entity` (essentially HTTP GET and POST methods).
    +    """
    +    def __init__(self, service, path):
    +        self.service = service
    +        self.path = path
    +
    +    def get_api_version(self, path):
    +        """Return the API version of the service used in the provided path.
    +
    +        Args:
    +            path (str): A fully-qualified endpoint path (for example, "/services/search/jobs").
    +
    +        Returns:
    +            int: Version of the API (for example, 1)
    +        """
    +        # Default to v1 if undefined in the path
    +        # For example, "/services/search/jobs" is using API v1
    +        api_version = 1
    +        
    +        versionSearch = re.search('(?:servicesNS\/[^/]+\/[^/]+|services)\/[^/]+\/v(\d+)\/', path)
    +        if versionSearch:
    +            api_version = int(versionSearch.group(1))
    +    
    +        return api_version
    +
    +    def get(self, path_segment="", owner=None, app=None, sharing=None, **query):
    +        """Performs a GET operation on the path segment relative to this endpoint.
    +
    +        This method is named to match the HTTP method. This method makes at least
    +        one roundtrip to the server, one additional round trip for
    +        each 303 status returned, plus at most two additional round
    +        trips if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        If *owner*, *app*, and *sharing* are omitted, this method takes a
    +        default namespace from the :class:`Service` object for this :class:`Endpoint`.
    +        All other keyword arguments are included in the URL as query parameters.
    +
    +        :raises AuthenticationError: Raised when the ``Service`` is not logged in.
    +        :raises HTTPError: Raised when an error in the request occurs.
    +        :param path_segment: A path segment relative to this endpoint.
    +        :type path_segment: ``string``
    +        :param owner: The owner context of the namespace (optional).
    +        :type owner: ``string``
    +        :param app: The app context of the namespace (optional).
    +        :type app: ``string``
    +        :param sharing: The sharing mode for the namespace (optional).
    +        :type sharing: "global", "system", "app", or "user"
    +        :param query: All other keyword arguments, which are used as query
    +            parameters.
    +        :type query: ``string``
    +        :return: The response from the server.
    +        :rtype: ``dict`` with keys ``body``, ``headers``, ``reason``,
    +                and ``status``
    +
    +        **Example**::
    +
    +            import splunklib.client
    +            s = client.service(...)
    +            apps = s.apps
    +            apps.get() == \\
    +                {'body': ...a response reader object...,
    +                 'headers': [('content-length', '26208'),
    +                             ('expires', 'Fri, 30 Oct 1998 00:00:00 GMT'),
    +                             ('server', 'Splunkd'),
    +                             ('connection', 'close'),
    +                             ('cache-control', 'no-store, max-age=0, must-revalidate, no-cache'),
    +                             ('date', 'Fri, 11 May 2012 16:30:35 GMT'),
    +                             ('content-type', 'text/xml; charset=utf-8')],
    +                 'reason': 'OK',
    +                 'status': 200}
    +            apps.get('nonexistant/path') # raises HTTPError
    +            s.logout()
    +            apps.get() # raises AuthenticationError
    +        """
    +        # self.path to the Endpoint is relative in the SDK, so passing
    +        # owner, app, sharing, etc. along will produce the correct
    +        # namespace in the final request.
    +        if path_segment.startswith('/'):
    +            path = path_segment
    +        else:
    +            if not self.path.endswith('/') and path_segment != "":
    +                self.path = self.path + '/'
    +            path = self.service._abspath(self.path + path_segment, owner=owner,
    +                                         app=app, sharing=sharing)
    +        # ^-- This was "%s%s" % (self.path, path_segment).
    +        # That doesn't work, because self.path may be UrlEncoded.
    +
    +        # Get the API version from the path
    +        api_version = self.get_api_version(path)
    +
    +        # Search API v2+ fallback to v1:
    +        #   - In v2+, /results_preview, /events and /results do not support search params.
    +        #   - Fallback from v2+ to v1 if Splunk Version is < 9.
    +        # if api_version >= 2 and ('search' in query and path.endswith(tuple(["results_preview", "events", "results"])) or self.service.splunk_version < (9,)):
    +        #     path = path.replace(PATH_JOBS_V2, PATH_JOBS)
    +        
    +        if api_version == 1:
    +            if isinstance(path, UrlEncoded):
    +                path = UrlEncoded(path.replace(PATH_JOBS_V2, PATH_JOBS), skip_encode=True)
    +            else:
    +                path = path.replace(PATH_JOBS_V2, PATH_JOBS)
    +
    +        return self.service.get(path,
    +                                owner=owner, app=app, sharing=sharing,
    +                                **query)
    +
    +    def post(self, path_segment="", owner=None, app=None, sharing=None, **query):
    +        """Performs a POST operation on the path segment relative to this endpoint.
    +
    +        This method is named to match the HTTP method. This method makes at least
    +        one roundtrip to the server, one additional round trip for
    +        each 303 status returned, plus at most two additional round trips if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        If *owner*, *app*, and *sharing* are omitted, this method takes a
    +        default namespace from the :class:`Service` object for this :class:`Endpoint`.
    +        All other keyword arguments are included in the URL as query parameters.
    +
    +        :raises AuthenticationError: Raised when the ``Service`` is not logged in.
    +        :raises HTTPError: Raised when an error in the request occurs.
    +        :param path_segment: A path segment relative to this endpoint.
    +        :type path_segment: ``string``
    +        :param owner: The owner context of the namespace (optional).
    +        :type owner: ``string``
    +        :param app: The app context of the namespace (optional).
    +        :type app: ``string``
    +        :param sharing: The sharing mode of the namespace (optional).
    +        :type sharing: ``string``
    +        :param query: All other keyword arguments, which are used as query
    +            parameters.
    +        :type query: ``string``
    +        :return: The response from the server.
    +        :rtype: ``dict`` with keys ``body``, ``headers``, ``reason``,
    +                and ``status``
    +
    +        **Example**::
    +
    +            import splunklib.client
    +            s = client.service(...)
    +            apps = s.apps
    +            apps.post(name='boris') == \\
    +                {'body': ...a response reader object...,
    +                 'headers': [('content-length', '2908'),
    +                             ('expires', 'Fri, 30 Oct 1998 00:00:00 GMT'),
    +                             ('server', 'Splunkd'),
    +                             ('connection', 'close'),
    +                             ('cache-control', 'no-store, max-age=0, must-revalidate, no-cache'),
    +                             ('date', 'Fri, 11 May 2012 18:34:50 GMT'),
    +                             ('content-type', 'text/xml; charset=utf-8')],
    +                 'reason': 'Created',
    +                 'status': 201}
    +            apps.get('nonexistant/path') # raises HTTPError
    +            s.logout()
    +            apps.get() # raises AuthenticationError
    +        """       
    +        if path_segment.startswith('/'):
    +            path = path_segment
    +        else:
    +            if not self.path.endswith('/') and path_segment != "":
    +                self.path = self.path + '/'
    +            path = self.service._abspath(self.path + path_segment, owner=owner, app=app, sharing=sharing)
    +            
    +        # Get the API version from the path
    +        api_version = self.get_api_version(path)
    +
    +        # Search API v2+ fallback to v1:
    +        #   - In v2+, /results_preview, /events and /results do not support search params.
    +        #   - Fallback from v2+ to v1 if Splunk Version is < 9.
    +        # if api_version >= 2 and ('search' in query and path.endswith(tuple(["results_preview", "events", "results"])) or self.service.splunk_version < (9,)):
    +        #     path = path.replace(PATH_JOBS_V2, PATH_JOBS)
    +        
    +        if api_version == 1:
    +            if isinstance(path, UrlEncoded):
    +                path = UrlEncoded(path.replace(PATH_JOBS_V2, PATH_JOBS), skip_encode=True)
    +            else:
    +                path = path.replace(PATH_JOBS_V2, PATH_JOBS)
    +
    +        return self.service.post(path, owner=owner, app=app, sharing=sharing, **query)
    +
    +
    +# kwargs: path, app, owner, sharing, state
    +class Entity(Endpoint):
    +    """This class is a base class for Splunk entities in the REST API, such as
    +    saved searches, jobs, indexes, and inputs.
    +
    +    ``Entity`` provides the majority of functionality required by entities.
    +    Subclasses only implement the special cases for individual entities.
    +    For example for saved searches, the subclass makes fields like ``action.email``,
    +    ``alert_type``, and ``search`` available.
    +
    +    An ``Entity`` is addressed like a dictionary, with a few extensions,
    +    so the following all work, for example in saved searches::
    +
    +        ent['action.email']
    +        ent['alert_type']
    +        ent['search']
    +
    +    You can also access the fields as though they were the fields of a Python
    +    object, as in::
    +
    +        ent.alert_type
    +        ent.search
    +
    +    However, because some of the field names are not valid Python identifiers,
    +    the dictionary-like syntax is preferable.
    +
    +    The state of an :class:`Entity` object is cached, so accessing a field
    +    does not contact the server. If you think the values on the
    +    server have changed, call the :meth:`Entity.refresh` method.
    +    """
    +    # Not every endpoint in the API is an Entity or a Collection. For
    +    # example, a saved search at saved/searches/{name} has an additional
    +    # method saved/searches/{name}/scheduled_times, but this isn't an
    +    # entity in its own right. In these cases, subclasses should
    +    # implement a method that uses the get and post methods inherited
    +    # from Endpoint, calls the _load_atom function (it's elsewhere in
    +    # client.py, but not a method of any object) to read the
    +    # information, and returns the extracted data in a Pythonesque form.
    +    #
    +    # The primary use of subclasses of Entity is to handle specially
    +    # named fields in the Entity. If you only need to provide a default
    +    # value for an optional field, subclass Entity and define a
    +    # dictionary ``defaults``. For instance,::
    +    #
    +    #     class Hypothetical(Entity):
    +    #         defaults = {'anOptionalField': 'foo',
    +    #                     'anotherField': 'bar'}
    +    #
    +    # If you have to do more than provide a default, such as rename or
    +    # actually process values, then define a new method with the
    +    # ``@property`` decorator.
    +    #
    +    #     class Hypothetical(Entity):
    +    #         @property
    +    #         def foobar(self):
    +    #             return self.content['foo'] + "-" + self.content["bar"]
    +
    +    # Subclasses can override defaults the default values for
    +    # optional fields. See above.
    +    defaults = {}
    +
    +    def __init__(self, service, path, **kwargs):
    +        Endpoint.__init__(self, service, path)
    +        self._state = None
    +        if not kwargs.get('skip_refresh', False):
    +            self.refresh(kwargs.get('state', None))  # "Prefresh"
    +        return
    +
    +    def __contains__(self, item):
    +        try:
    +            self[item]
    +            return True
    +        except (KeyError, AttributeError):
    +            return False
    +
    +    def __eq__(self, other):
    +        """Raises IncomparableException.
    +
    +        Since Entity objects are snapshots of times on the server, no
    +        simple definition of equality will suffice beyond instance
    +        equality, and instance equality leads to strange situations
    +        such as::
    +
    +            import splunklib.client as client
    +            c = client.connect(...)
    +            saved_searches = c.saved_searches
    +            x = saved_searches['asearch']
    +
    +        but then ``x != saved_searches['asearch']``.
    +
    +        whether or not there was a change on the server. Rather than
    +        try to do something fancy, we simple declare that equality is
    +        undefined for Entities.
    +
    +        Makes no roundtrips to the server.
    +        """
    +        raise IncomparableException(
    +            "Equality is undefined for objects of class %s" % \
    +                self.__class__.__name__)
    +
    +    def __getattr__(self, key):
    +        # Called when an attribute was not found by the normal method. In this
    +        # case we try to find it in self.content and then self.defaults.
    +        if key in self.state.content:
    +            return self.state.content[key]
    +        elif key in self.defaults:
    +            return self.defaults[key]
    +        else:
    +            raise AttributeError(key)
    +
    +    def __getitem__(self, key):
    +        # getattr attempts to find a field on the object in the normal way,
    +        # then calls __getattr__ if it cannot.
    +        return getattr(self, key)
    +
    +    # Load the Atom entry record from the given response - this is a method
    +    # because the "entry" record varies slightly by entity and this allows
    +    # for a subclass to override and handle any special cases.
    +    def _load_atom_entry(self, response):
    +        elem = _load_atom(response, XNAME_ENTRY)
    +        if isinstance(elem, list):
    +            apps = [ele.entry.content.get('eai:appName') for ele in elem]
    +
    +            raise AmbiguousReferenceException(
    +                "Fetch from server returned multiple entries for name '%s' in apps %s." % (elem[0].entry.title, apps))
    +        else:
    +            return elem.entry
    +
    +    # Load the entity state record from the given response
    +    def _load_state(self, response):
    +        entry = self._load_atom_entry(response)
    +        return _parse_atom_entry(entry)
    +
    +    def _run_action(self, path_segment, **kwargs):
    +        """Run a method and return the content Record from the returned XML.
    +
    +        A method is a relative path from an Entity that is not itself
    +        an Entity. _run_action assumes that the returned XML is an
    +        Atom field containing one Entry, and the contents of Entry is
    +        what should be the return value. This is right in enough cases
    +        to make this method useful.
    +        """
    +        response = self.get(path_segment, **kwargs)
    +        data = self._load_atom_entry(response)
    +        rec = _parse_atom_entry(data)
    +        return rec.content
    +
    +    def _proper_namespace(self, owner=None, app=None, sharing=None):
    +        """Produce a namespace sans wildcards for use in entity requests.
    +
    +        This method tries to fill in the fields of the namespace which are `None`
    +        or wildcard (`'-'`) from the entity's namespace. If that fails, it uses
    +        the service's namespace.
    +
    +        :param owner:
    +        :param app:
    +        :param sharing:
    +        :return:
    +        """
    +        if owner is None and app is None and sharing is None: # No namespace provided
    +            if self._state is not None and 'access' in self._state:
    +                return (self._state.access.owner,
    +                        self._state.access.app,
    +                        self._state.access.sharing)
    +            else:
    +                return (self.service.namespace['owner'],
    +                        self.service.namespace['app'],
    +                        self.service.namespace['sharing'])
    +        else:
    +            return (owner,app,sharing)
    +
    +    def delete(self):
    +        owner, app, sharing = self._proper_namespace()
    +        return self.service.delete(self.path, owner=owner, app=app, sharing=sharing)
    +
    +    def get(self, path_segment="", owner=None, app=None, sharing=None, **query):
    +        owner, app, sharing = self._proper_namespace(owner, app, sharing)
    +        return super(Entity, self).get(path_segment, owner=owner, app=app, sharing=sharing, **query)
    +
    +    def post(self, path_segment="", owner=None, app=None, sharing=None, **query):
    +        owner, app, sharing = self._proper_namespace(owner, app, sharing)
    +        return super(Entity, self).post(path_segment, owner=owner, app=app, sharing=sharing, **query)
    +
    +    def refresh(self, state=None):
    +        """Refreshes the state of this entity.
    +
    +        If *state* is provided, load it as the new state for this
    +        entity. Otherwise, make a roundtrip to the server (by calling
    +        the :meth:`read` method of ``self``) to fetch an updated state,
    +        plus at most two additional round trips if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        :param state: Entity-specific arguments (optional).
    +        :type state: ``dict``
    +        :raises EntityDeletedException: Raised if the entity no longer exists on
    +            the server.
    +
    +        **Example**::
    +
    +            import splunklib.client as client
    +            s = client.connect(...)
    +            search = s.apps['search']
    +            search.refresh()
    +        """
    +        if state is not None:
    +            self._state = state
    +        else:
    +            self._state = self.read(self.get())
    +        return self
    +
    +    @property
    +    def access(self):
    +        """Returns the access metadata for this entity.
    +
    +        :return: A :class:`splunklib.data.Record` object with three keys:
    +            ``owner``, ``app``, and ``sharing``.
    +        """
    +        return self.state.access
    +
    +    @property
    +    def content(self):
    +        """Returns the contents of the entity.
    +
    +        :return: A ``dict`` containing values.
    +        """
    +        return self.state.content
    +
    +    def disable(self):
    +        """Disables the entity at this endpoint."""
    +        self.post("disable")
    +        return self
    +
    +    def enable(self):
    +        """Enables the entity at this endpoint."""
    +        self.post("enable")
    +        return self
    +
    +    @property
    +    def fields(self):
    +        """Returns the content metadata for this entity.
    +
    +        :return: A :class:`splunklib.data.Record` object with three keys:
    +            ``required``, ``optional``, and ``wildcard``.
    +        """
    +        return self.state.fields
    +
    +    @property
    +    def links(self):
    +        """Returns a dictionary of related resources.
    +
    +        :return: A ``dict`` with keys and corresponding URLs.
    +        """
    +        return self.state.links
    +
    +    @property
    +    def name(self):
    +        """Returns the entity name.
    +
    +        :return: The entity name.
    +        :rtype: ``string``
    +        """
    +        return self.state.title
    +
    +    def read(self, response):
    +        """ Reads the current state of the entity from the server. """
    +        results = self._load_state(response)
    +        # In lower layers of the SDK, we end up trying to URL encode
    +        # text to be dispatched via HTTP. However, these links are already
    +        # URL encoded when they arrive, and we need to mark them as such.
    +        unquoted_links = dict([(k, UrlEncoded(v, skip_encode=True))
    +                               for k,v in six.iteritems(results['links'])])
    +        results['links'] = unquoted_links
    +        return results
    +
    +    def reload(self):
    +        """Reloads the entity."""
    +        self.post("_reload")
    +        return self
    +
    +    def acl_update(self, **kwargs):
    +        """To update Access Control List (ACL) properties for an endpoint.
    +
    +        :param kwargs: Additional entity-specific arguments (required).
    +
    +            - "owner" (``string``): The Splunk username, such as "admin". A value of "nobody" means no specific user (required).
    +
    +            - "sharing" (``string``): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system" (required).
    +
    +        :type kwargs: ``dict``
    +
    +        **Example**::
    +
    +            import splunklib.client as client
    +            service = client.connect(...)
    +            saved_search = service.saved_searches["name"]
    +            saved_search.acl_update(sharing="app", owner="nobody", app="search", **{"perms.read": "admin, nobody"})
    +        """
    +        if "body" not in kwargs:
    +            kwargs = {"body": kwargs}
    +
    +        if "sharing" not in kwargs["body"]:
    +            raise ValueError("Required argument 'sharing' is missing.")
    +        if "owner" not in kwargs["body"]:
    +            raise ValueError("Required argument 'owner' is missing.")
    +
    +        self.post("acl", **kwargs)
    +        self.refresh()
    +        return self
    +
    +    @property
    +    def state(self):
    +        """Returns the entity's state record.
    +
    +        :return: A ``dict`` containing fields and metadata for the entity.
    +        """
    +        if self._state is None: self.refresh()
    +        return self._state
    +
    +    def update(self, **kwargs):
    +        """Updates the server with any changes you've made to the current entity
    +        along with any additional arguments you specify.
    +
    +            **Note**: You cannot update the ``name`` field of an entity.
    +
    +        Many of the fields in the REST API are not valid Python
    +        identifiers, which means you cannot pass them as keyword
    +        arguments. That is, Python will fail to parse the following::
    +
    +            # This fails
    +            x.update(check-new=False, email.to='boris@utopia.net')
    +
    +        However, you can always explicitly use a dictionary to pass
    +        such keys::
    +
    +            # This works
    +            x.update(**{'check-new': False, 'email.to': 'boris@utopia.net'})
    +
    +        :param kwargs: Additional entity-specific arguments (optional).
    +        :type kwargs: ``dict``
    +
    +        :return: The entity this method is called on.
    +        :rtype: class:`Entity`
    +        """
    +        # The peculiarity in question: the REST API creates a new
    +        # Entity if we pass name in the dictionary, instead of the
    +        # expected behavior of updating this Entity. Therefore we
    +        # check for 'name' in kwargs and throw an error if it is
    +        # there.
    +        if 'name' in kwargs:
    +            raise IllegalOperationException('Cannot update the name of an Entity via the REST API.')
    +        self.post(**kwargs)
    +        return self
    +
    +
    +class ReadOnlyCollection(Endpoint):
    +    """This class represents a read-only collection of entities in the Splunk
    +    instance.
    +    """
    +    def __init__(self, service, path, item=Entity):
    +        Endpoint.__init__(self, service, path)
    +        self.item = item # Item accessor
    +        self.null_count = -1
    +
    +    def __contains__(self, name):
    +        """Is there at least one entry called *name* in this collection?
    +
    +        Makes a single roundtrip to the server, plus at most two more
    +        if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +        """
    +        try:
    +            self[name]
    +            return True
    +        except KeyError:
    +            return False
    +        except AmbiguousReferenceException:
    +            return True
    +
    +    def __getitem__(self, key):
    +        """Fetch an item named *key* from this collection.
    +
    +        A name is not a unique identifier in a collection. The unique
    +        identifier is a name plus a namespace. For example, there can
    +        be a saved search named ``'mysearch'`` with sharing ``'app'``
    +        in application ``'search'``, and another with sharing
    +        ``'user'`` with owner ``'boris'`` and application
    +        ``'search'``. If the ``Collection`` is attached to a
    +        ``Service`` that has ``'-'`` (wildcard) as user and app in its
    +        namespace, then both of these may be visible under the same
    +        name.
    +
    +        Where there is no conflict, ``__getitem__`` will fetch the
    +        entity given just the name. If there is a conflict and you
    +        pass just a name, it will raise a ``ValueError``. In that
    +        case, add the namespace as a second argument.
    +
    +        This function makes a single roundtrip to the server, plus at
    +        most two additional round trips if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        :param key: The name to fetch, or a tuple (name, namespace).
    +        :return: An :class:`Entity` object.
    +        :raises KeyError: Raised if *key* does not exist.
    +        :raises ValueError: Raised if no namespace is specified and *key*
    +                            does not refer to a unique name.
    +
    +        **Example**::
    +
    +            s = client.connect(...)
    +            saved_searches = s.saved_searches
    +            x1 = saved_searches.create(
    +                'mysearch', 'search * | head 1',
    +                owner='admin', app='search', sharing='app')
    +            x2 = saved_searches.create(
    +                'mysearch', 'search * | head 1',
    +                owner='admin', app='search', sharing='user')
    +            # Raises ValueError:
    +            saved_searches['mysearch']
    +            # Fetches x1
    +            saved_searches[
    +                'mysearch',
    +                client.namespace(sharing='app', app='search')]
    +            # Fetches x2
    +            saved_searches[
    +                'mysearch',
    +                client.namespace(sharing='user', owner='boris', app='search')]
    +        """
    +        try:
    +            if isinstance(key, tuple) and len(key) == 2:
    +                # x[a,b] is translated to x.__getitem__( (a,b) ), so we
    +                # have to extract values out.
    +                key, ns = key
    +                key = UrlEncoded(key, encode_slash=True)
    +                response = self.get(key, owner=ns.owner, app=ns.app)
    +            else:
    +                key = UrlEncoded(key, encode_slash=True)
    +                response = self.get(key)
    +            entries = self._load_list(response)
    +            if len(entries) > 1:
    +                raise AmbiguousReferenceException("Found multiple entities named '%s'; please specify a namespace." % key)
    +            elif len(entries) == 0:
    +                raise KeyError(key)
    +            else:
    +                return entries[0]
    +        except HTTPError as he:
    +            if he.status == 404: # No entity matching key and namespace.
    +                raise KeyError(key)
    +            else:
    +                raise
    +
    +    def __iter__(self, **kwargs):
    +        """Iterate over the entities in the collection.
    +
    +        :param kwargs: Additional arguments.
    +        :type kwargs: ``dict``
    +        :rtype: iterator over entities.
    +
    +        Implemented to give Collection a listish interface. This
    +        function always makes a roundtrip to the server, plus at most
    +        two additional round trips if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        **Example**::
    +
    +            import splunklib.client as client
    +            c = client.connect(...)
    +            saved_searches = c.saved_searches
    +            for entity in saved_searches:
    +                print "Saved search named %s" % entity.name
    +        """
    +
    +        for item in self.iter(**kwargs):
    +            yield item
    +
    +    def __len__(self):
    +        """Enable ``len(...)`` for ``Collection`` objects.
    +
    +        Implemented for consistency with a listish interface. No
    +        further failure modes beyond those possible for any method on
    +        an Endpoint.
    +
    +        This function always makes a round trip to the server, plus at
    +        most two additional round trips if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        **Example**::
    +
    +            import splunklib.client as client
    +            c = client.connect(...)
    +            saved_searches = c.saved_searches
    +            n = len(saved_searches)
    +        """
    +        return len(self.list())
    +
    +    def _entity_path(self, state):
    +        """Calculate the path to an entity to be returned.
    +
    +        *state* should be the dictionary returned by
    +        :func:`_parse_atom_entry`. :func:`_entity_path` extracts the
    +        link to this entity from *state*, and strips all the namespace
    +        prefixes from it to leave only the relative path of the entity
    +        itself, sans namespace.
    +
    +        :rtype: ``string``
    +        :return: an absolute path
    +        """
    +        # This has been factored out so that it can be easily
    +        # overloaded by Configurations, which has to switch its
    +        # entities' endpoints from its own properties/ to configs/.
    +        raw_path = urllib.parse.unquote(state.links.alternate)
    +        if 'servicesNS/' in raw_path:
    +            return _trailing(raw_path, 'servicesNS/', '/', '/')
    +        elif 'services/' in raw_path:
    +            return _trailing(raw_path, 'services/')
    +        else:
    +            return raw_path
    +
    +    def _load_list(self, response):
    +        """Converts *response* to a list of entities.
    +
    +        *response* is assumed to be a :class:`Record` containing an
    +        HTTP response, of the form::
    +
    +            {'status': 200,
    +             'headers': [('content-length', '232642'),
    +                         ('expires', 'Fri, 30 Oct 1998 00:00:00 GMT'),
    +                         ('server', 'Splunkd'),
    +                         ('connection', 'close'),
    +                         ('cache-control', 'no-store, max-age=0, must-revalidate, no-cache'),
    +                         ('date', 'Tue, 29 May 2012 15:27:08 GMT'),
    +                         ('content-type', 'text/xml; charset=utf-8')],
    +             'reason': 'OK',
    +             'body': ...a stream implementing .read()...}
    +
    +        The ``'body'`` key refers to a stream containing an Atom feed,
    +        that is, an XML document with a toplevel element ``<feed>``,
    +        and within that element one or more ``<entry>`` elements.
    +        """
    +        # Some subclasses of Collection have to override this because
    +        # splunkd returns something that doesn't match
    +        # <feed><entry></entry><feed>.
    +        entries = _load_atom_entries(response)
    +        if entries is None: return []
    +        entities = []
    +        for entry in entries:
    +            state = _parse_atom_entry(entry)
    +            entity = self.item(
    +                self.service,
    +                self._entity_path(state),
    +                state=state)
    +            entities.append(entity)
    +
    +        return entities
    +
    +    def itemmeta(self):
    +        """Returns metadata for members of the collection.
    +
    +        Makes a single roundtrip to the server, plus two more at most if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        :return: A :class:`splunklib.data.Record` object containing the metadata.
    +
    +        **Example**::
    +
    +            import splunklib.client as client
    +            import pprint
    +            s = client.connect(...)
    +            pprint.pprint(s.apps.itemmeta())
    +            {'access': {'app': 'search',
    +                                    'can_change_perms': '1',
    +                                    'can_list': '1',
    +                                    'can_share_app': '1',
    +                                    'can_share_global': '1',
    +                                    'can_share_user': '1',
    +                                    'can_write': '1',
    +                                    'modifiable': '1',
    +                                    'owner': 'admin',
    +                                    'perms': {'read': ['*'], 'write': ['admin']},
    +                                    'removable': '0',
    +                                    'sharing': 'user'},
    +             'fields': {'optional': ['author',
    +                                        'configured',
    +                                        'description',
    +                                        'label',
    +                                        'manageable',
    +                                        'template',
    +                                        'visible'],
    +                                        'required': ['name'], 'wildcard': []}}
    +        """
    +        response = self.get("_new")
    +        content = _load_atom(response, MATCH_ENTRY_CONTENT)
    +        return _parse_atom_metadata(content)
    +
    +    def iter(self, offset=0, count=None, pagesize=None, **kwargs):
    +        """Iterates over the collection.
    +
    +        This method is equivalent to the :meth:`list` method, but
    +        it returns an iterator and can load a certain number of entities at a
    +        time from the server.
    +
    +        :param offset: The index of the first entity to return (optional).
    +        :type offset: ``integer``
    +        :param count: The maximum number of entities to return (optional).
    +        :type count: ``integer``
    +        :param pagesize: The number of entities to load (optional).
    +        :type pagesize: ``integer``
    +        :param kwargs: Additional arguments (optional):
    +
    +            - "search" (``string``): The search query to filter responses.
    +
    +            - "sort_dir" (``string``): The direction to sort returned items:
    +              "asc" or "desc".
    +
    +            - "sort_key" (``string``): The field to use for sorting (optional).
    +
    +            - "sort_mode" (``string``): The collating sequence for sorting
    +              returned items: "auto", "alpha", "alpha_case", or "num".
    +
    +        :type kwargs: ``dict``
    +
    +        **Example**::
    +
    +            import splunklib.client as client
    +            s = client.connect(...)
    +            for saved_search in s.saved_searches.iter(pagesize=10):
    +                # Loads 10 saved searches at a time from the
    +                # server.
    +                ...
    +        """
    +        assert pagesize is None or pagesize > 0
    +        if count is None:
    +            count = self.null_count
    +        fetched = 0
    +        while count == self.null_count or fetched < count:
    +            response = self.get(count=pagesize or count, offset=offset, **kwargs)
    +            items = self._load_list(response)
    +            N = len(items)
    +            fetched += N
    +            for item in items:
    +                yield item
    +            if pagesize is None or N < pagesize:
    +                break
    +            offset += N
    +            logger.debug("pagesize=%d, fetched=%d, offset=%d, N=%d, kwargs=%s", pagesize, fetched, offset, N, kwargs)
    +
    +    # kwargs: count, offset, search, sort_dir, sort_key, sort_mode
    +    def list(self, count=None, **kwargs):
    +        """Retrieves a list of entities in this collection.
    +
    +        The entire collection is loaded at once and is returned as a list. This
    +        function makes a single roundtrip to the server, plus at most two more if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +        There is no caching--every call makes at least one round trip.
    +
    +        :param count: The maximum number of entities to return (optional).
    +        :type count: ``integer``
    +        :param kwargs: Additional arguments (optional):
    +
    +            - "offset" (``integer``): The offset of the first item to return.
    +
    +            - "search" (``string``): The search query to filter responses.
    +
    +            - "sort_dir" (``string``): The direction to sort returned items:
    +              "asc" or "desc".
    +
    +            - "sort_key" (``string``): The field to use for sorting (optional).
    +
    +            - "sort_mode" (``string``): The collating sequence for sorting
    +              returned items: "auto", "alpha", "alpha_case", or "num".
    +
    +        :type kwargs: ``dict``
    +        :return: A ``list`` of entities.
    +        """
    +        # response = self.get(count=count, **kwargs)
    +        # return self._load_list(response)
    +        return list(self.iter(count=count, **kwargs))
    +
    +
    +
    +
    +class Collection(ReadOnlyCollection):
    +    """A collection of entities.
    +
    +    Splunk provides a number of different collections of distinct
    +    entity types: applications, saved searches, fired alerts, and a
    +    number of others. Each particular type is available separately
    +    from the Splunk instance, and the entities of that type are
    +    returned in a :class:`Collection`.
    +
    +    The interface for :class:`Collection` does not quite match either
    +    ``list`` or ``dict`` in Python, because there are enough semantic
    +    mismatches with either to make its behavior surprising. A unique
    +    element in a :class:`Collection` is defined by a string giving its
    +    name plus namespace (although the namespace is optional if the name is
    +    unique).
    +
    +    **Example**::
    +
    +        import splunklib.client as client
    +        service = client.connect(...)
    +        mycollection = service.saved_searches
    +        mysearch = mycollection['my_search', client.namespace(owner='boris', app='natasha', sharing='user')]
    +        # Or if there is only one search visible named 'my_search'
    +        mysearch = mycollection['my_search']
    +
    +    Similarly, ``name`` in ``mycollection`` works as you might expect (though
    +    you cannot currently pass a namespace to the ``in`` operator), as does
    +    ``len(mycollection)``.
    +
    +    However, as an aggregate, :class:`Collection` behaves more like a
    +    list. If you iterate over a :class:`Collection`, you get an
    +    iterator over the entities, not the names and namespaces.
    +
    +    **Example**::
    +
    +        for entity in mycollection:
    +            assert isinstance(entity, client.Entity)
    +
    +    Use the :meth:`create` and :meth:`delete` methods to create and delete
    +    entities in this collection. To view the access control list and other
    +    metadata of the collection, use the :meth:`ReadOnlyCollection.itemmeta` method.
    +
    +    :class:`Collection` does no caching. Each call makes at least one
    +    round trip to the server to fetch data.
    +    """
    +
    +    def create(self, name, **params):
    +        """Creates a new entity in this collection.
    +
    +        This function makes either one or two roundtrips to the
    +        server, depending on the type of entities in this
    +        collection, plus at most two more if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        :param name: The name of the entity to create.
    +        :type name: ``string``
    +        :param namespace: A namespace, as created by the :func:`splunklib.binding.namespace`
    +            function (optional).  You can also set ``owner``, ``app``, and
    +            ``sharing`` in ``params``.
    +        :type namespace: A :class:`splunklib.data.Record` object with keys ``owner``, ``app``,
    +            and ``sharing``.
    +        :param params: Additional entity-specific arguments (optional).
    +        :type params: ``dict``
    +        :return: The new entity.
    +        :rtype: A subclass of :class:`Entity`, chosen by :meth:`Collection.self.item`.
    +
    +        **Example**::
    +
    +            import splunklib.client as client
    +            s = client.connect(...)
    +            applications = s.apps
    +            new_app = applications.create("my_fake_app")
    +        """
    +        if not isinstance(name, six.string_types):
    +            raise InvalidNameException("%s is not a valid name for an entity." % name)
    +        if 'namespace' in params:
    +            namespace = params.pop('namespace')
    +            params['owner'] = namespace.owner
    +            params['app'] = namespace.app
    +            params['sharing'] = namespace.sharing
    +        response = self.post(name=name, **params)
    +        atom = _load_atom(response, XNAME_ENTRY)
    +        if atom is None:
    +            # This endpoint doesn't return the content of the new
    +            # item. We have to go fetch it ourselves.
    +            return self[name]
    +        else:
    +            entry = atom.entry
    +            state = _parse_atom_entry(entry)
    +            entity = self.item(
    +                self.service,
    +                self._entity_path(state),
    +                state=state)
    +            return entity
    +
    +    def delete(self, name, **params):
    +        """Deletes a specified entity from the collection.
    +
    +        :param name: The name of the entity to delete.
    +        :type name: ``string``
    +        :return: The collection.
    +        :rtype: ``self``
    +
    +        This method is implemented for consistency with the REST API's DELETE
    +        method.
    +
    +        If there is no *name* entity on the server, a ``KeyError`` is
    +        thrown. This function always makes a roundtrip to the server.
    +
    +        **Example**::
    +
    +            import splunklib.client as client
    +            c = client.connect(...)
    +            saved_searches = c.saved_searches
    +            saved_searches.create('my_saved_search',
    +                                  'search * | head 1')
    +            assert 'my_saved_search' in saved_searches
    +            saved_searches.delete('my_saved_search')
    +            assert 'my_saved_search' not in saved_searches
    +        """
    +        name = UrlEncoded(name, encode_slash=True)
    +        if 'namespace' in params:
    +            namespace = params.pop('namespace')
    +            params['owner'] = namespace.owner
    +            params['app'] = namespace.app
    +            params['sharing'] = namespace.sharing
    +        try:
    +            self.service.delete(_path(self.path, name), **params)
    +        except HTTPError as he:
    +            # An HTTPError with status code 404 means that the entity
    +            # has already been deleted, and we reraise it as a
    +            # KeyError.
    +            if he.status == 404:
    +                raise KeyError("No such entity %s" % name)
    +            else:
    +                raise
    +        return self
    +
    +    def get(self, name="", owner=None, app=None, sharing=None, **query):
    +        """Performs a GET request to the server on the collection.
    +
    +        If *owner*, *app*, and *sharing* are omitted, this method takes a
    +        default namespace from the :class:`Service` object for this :class:`Endpoint`.
    +        All other keyword arguments are included in the URL as query parameters.
    +
    +        :raises AuthenticationError: Raised when the ``Service`` is not logged in.
    +        :raises HTTPError: Raised when an error in the request occurs.
    +        :param path_segment: A path segment relative to this endpoint.
    +        :type path_segment: ``string``
    +        :param owner: The owner context of the namespace (optional).
    +        :type owner: ``string``
    +        :param app: The app context of the namespace (optional).
    +        :type app: ``string``
    +        :param sharing: The sharing mode for the namespace (optional).
    +        :type sharing: "global", "system", "app", or "user"
    +        :param query: All other keyword arguments, which are used as query
    +            parameters.
    +        :type query: ``string``
    +        :return: The response from the server.
    +        :rtype: ``dict`` with keys ``body``, ``headers``, ``reason``,
    +                and ``status``
    +
    +        **Example**::
    +
    +            import splunklib.client
    +            s = client.service(...)
    +            saved_searches = s.saved_searches
    +            saved_searches.get("my/saved/search") == \\
    +                {'body': ...a response reader object...,
    +                 'headers': [('content-length', '26208'),
    +                             ('expires', 'Fri, 30 Oct 1998 00:00:00 GMT'),
    +                             ('server', 'Splunkd'),
    +                             ('connection', 'close'),
    +                             ('cache-control', 'no-store, max-age=0, must-revalidate, no-cache'),
    +                             ('date', 'Fri, 11 May 2012 16:30:35 GMT'),
    +                             ('content-type', 'text/xml; charset=utf-8')],
    +                 'reason': 'OK',
    +                 'status': 200}
    +            saved_searches.get('nonexistant/search') # raises HTTPError
    +            s.logout()
    +            saved_searches.get() # raises AuthenticationError
    +
    +        """
    +        name = UrlEncoded(name, encode_slash=True)
    +        return super(Collection, self).get(name, owner, app, sharing, **query)
    +
    +
    +
    +
    +class ConfigurationFile(Collection):
    +    """This class contains all of the stanzas from one configuration file.
    +    """
    +    # __init__'s arguments must match those of an Entity, not a
    +    # Collection, since it is being created as the elements of a
    +    # Configurations, which is a Collection subclass.
    +    def __init__(self, service, path, **kwargs):
    +        Collection.__init__(self, service, path, item=Stanza)
    +        self.name = kwargs['state']['title']
    +
    +
    +class Configurations(Collection):
    +    """This class provides access to the configuration files from this Splunk
    +    instance. Retrieve this collection using :meth:`Service.confs`.
    +
    +    Splunk's configuration is divided into files, and each file into
    +    stanzas. This collection is unusual in that the values in it are
    +    themselves collections of :class:`ConfigurationFile` objects.
    +    """
    +    def __init__(self, service):
    +        Collection.__init__(self, service, PATH_PROPERTIES, item=ConfigurationFile)
    +        if self.service.namespace.owner == '-' or self.service.namespace.app == '-':
    +            raise ValueError("Configurations cannot have wildcards in namespace.")
    +
    +    def __getitem__(self, key):
    +        # The superclass implementation is designed for collections that contain
    +        # entities. This collection (Configurations) contains collections
    +        # (ConfigurationFile).
    +        #
    +        # The configurations endpoint returns multiple entities when we ask for a single file.
    +        # This screws up the default implementation of __getitem__ from Collection, which thinks
    +        # that multiple entities means a name collision, so we have to override it here.
    +        try:
    +            response = self.get(key)
    +            return ConfigurationFile(self.service, PATH_CONF % key, state={'title': key})
    +        except HTTPError as he:
    +            if he.status == 404: # No entity matching key
    +                raise KeyError(key)
    +            else:
    +                raise
    +
    +    def __contains__(self, key):
    +        # configs/conf-{name} never returns a 404. We have to post to properties/{name}
    +        # in order to find out if a configuration exists.
    +        try:
    +            response = self.get(key)
    +            return True
    +        except HTTPError as he:
    +            if he.status == 404: # No entity matching key
    +                return False
    +            else:
    +                raise
    +
    +    def create(self, name):
    +        """ Creates a configuration file named *name*.
    +
    +        If there is already a configuration file with that name,
    +        the existing file is returned.
    +
    +        :param name: The name of the configuration file.
    +        :type name: ``string``
    +
    +        :return: The :class:`ConfigurationFile` object.
    +        """
    +        # This has to be overridden to handle the plumbing of creating
    +        # a ConfigurationFile (which is a Collection) instead of some
    +        # Entity.
    +        if not isinstance(name, six.string_types):
    +            raise ValueError("Invalid name: %s" % repr(name))
    +        response = self.post(__conf=name)
    +        if response.status == 303:
    +            return self[name]
    +        elif response.status == 201:
    +            return ConfigurationFile(self.service, PATH_CONF % name, item=Stanza, state={'title': name})
    +        else:
    +            raise ValueError("Unexpected status code %s returned from creating a stanza" % response.status)
    +
    +    def delete(self, key):
    +        """Raises `IllegalOperationException`."""
    +        raise IllegalOperationException("Cannot delete configuration files from the REST API.")
    +
    +    def _entity_path(self, state):
    +        # Overridden to make all the ConfigurationFile objects
    +        # returned refer to the configs/ path instead of the
    +        # properties/ path used by Configrations.
    +        return PATH_CONF % state['title']
    +
    +
    +class Stanza(Entity):
    +    """This class contains a single configuration stanza."""
    +
    +    def submit(self, stanza):
    +        """Adds keys to the current configuration stanza as a
    +        dictionary of key-value pairs.
    +
    +        :param stanza: A dictionary of key-value pairs for the stanza.
    +        :type stanza: ``dict``
    +        :return: The :class:`Stanza` object.
    +        """
    +        body = _encode(**stanza)
    +        self.service.post(self.path, body=body)
    +        return self
    +
    +    def __len__(self):
    +        # The stanza endpoint returns all the keys at the same level in the XML as the eai information
    +        # and 'disabled', so to get an accurate length, we have to filter those out and have just
    +        # the stanza keys.
    +        return len([x for x in self._state.content.keys()
    +                    if not x.startswith('eai') and x != 'disabled'])
    +
    +
    +class StoragePassword(Entity):
    +    """This class contains a storage password.
    +    """
    +    def __init__(self, service, path, **kwargs):
    +        state = kwargs.get('state', None)
    +        kwargs['skip_refresh'] = kwargs.get('skip_refresh', state is not None)
    +        super(StoragePassword, self).__init__(service, path, **kwargs)
    +        self._state = state
    +
    +    @property
    +    def clear_password(self):
    +        return self.content.get('clear_password')
    +
    +    @property
    +    def encrypted_password(self):
    +        return self.content.get('encr_password')
    +
    +    @property
    +    def realm(self):
    +        return self.content.get('realm')
    +
    +    @property
    +    def username(self):
    +        return self.content.get('username')
    +
    +
    +class StoragePasswords(Collection):
    +    """This class provides access to the storage passwords from this Splunk
    +    instance. Retrieve this collection using :meth:`Service.storage_passwords`.
    +    """
    +    def __init__(self, service):
    +        super(StoragePasswords, self).__init__(service, PATH_STORAGE_PASSWORDS, item=StoragePassword)
    +
    +    def create(self, password, username, realm=None):
    +        """ Creates a storage password.
    +
    +        A `StoragePassword` can be identified by <username>, or by <realm>:<username> if the
    +        optional realm parameter is also provided.
    +
    +        :param password: The password for the credentials - this is the only part of the credentials that will be stored securely.
    +        :type name: ``string``
    +        :param username: The username for the credentials.
    +        :type name: ``string``
    +        :param realm: The credential realm. (optional)
    +        :type name: ``string``
    +
    +        :return: The :class:`StoragePassword` object created.
    +        """
    +        if self.service.namespace.owner == '-' or self.service.namespace.app == '-':
    +            raise ValueError("While creating StoragePasswords, namespace cannot have wildcards.")
    +
    +        if not isinstance(username, six.string_types):
    +            raise ValueError("Invalid name: %s" % repr(username))
    +
    +        if realm is None:
    +            response = self.post(password=password, name=username)
    +        else:
    +            response = self.post(password=password, realm=realm, name=username)
    +
    +        if response.status != 201:
    +            raise ValueError("Unexpected status code %s returned from creating a stanza" % response.status)
    +
    +        entries = _load_atom_entries(response)
    +        state = _parse_atom_entry(entries[0])
    +        storage_password = StoragePassword(self.service, self._entity_path(state), state=state, skip_refresh=True)
    +
    +        return storage_password
    +
    +    def delete(self, username, realm=None):
    +        """Delete a storage password by username and/or realm.
    +
    +        The identifier can be passed in through the username parameter as
    +        <username> or <realm>:<username>, but the preferred way is by
    +        passing in the username and realm parameters.
    +
    +        :param username: The username for the credentials, or <realm>:<username> if the realm parameter is omitted.
    +        :type name: ``string``
    +        :param realm: The credential realm. (optional)
    +        :type name: ``string``
    +        :return: The `StoragePassword` collection.
    +        :rtype: ``self``
    +        """
    +        if self.service.namespace.owner == '-' or self.service.namespace.app == '-':
    +            raise ValueError("app context must be specified when removing a password.")
    +
    +        if realm is None:
    +            # This case makes the username optional, so
    +            # the full name can be passed in as realm.
    +            # Assume it's already encoded.
    +            name = username
    +        else:
    +            # Encode each component separately
    +            name = UrlEncoded(realm, encode_slash=True) + ":" + UrlEncoded(username, encode_slash=True)
    +
    +        # Append the : expected at the end of the name
    +        if name[-1] != ":":
    +            name = name + ":"
    +        return Collection.delete(self, name)
    +
    +
    +class AlertGroup(Entity):
    +    """This class represents a group of fired alerts for a saved search. Access
    +    it using the :meth:`alerts` property."""
    +    def __init__(self, service, path, **kwargs):
    +        Entity.__init__(self, service, path, **kwargs)
    +
    +    def __len__(self):
    +        return self.count
    +
    +    @property
    +    def alerts(self):
    +        """Returns a collection of triggered alerts.
    +
    +        :return: A :class:`Collection` of triggered alerts.
    +        """
    +        return Collection(self.service, self.path)
    +
    +    @property
    +    def count(self):
    +        """Returns the count of triggered alerts.
    +
    +        :return: The triggered alert count.
    +        :rtype: ``integer``
    +        """
    +        return int(self.content.get('triggered_alert_count', 0))
    +
    +
    +class Indexes(Collection):
    +    """This class contains the collection of indexes in this Splunk instance.
    +    Retrieve this collection using :meth:`Service.indexes`.
    +    """
    +    def get_default(self):
    +        """ Returns the name of the default index.
    +
    +        :return: The name of the default index.
    +
    +        """
    +        index = self['_audit']
    +        return index['defaultDatabase']
    +
    +    def delete(self, name):
    +        """ Deletes a given index.
    +
    +        **Note**: This method is only supported in Splunk 5.0 and later.
    +
    +        :param name: The name of the index to delete.
    +        :type name: ``string``
    +        """
    +        if self.service.splunk_version >= (5,):
    +            Collection.delete(self, name)
    +        else:
    +            raise IllegalOperationException("Deleting indexes via the REST API is "
    +                                            "not supported before Splunk version 5.")
    +
    +
    +class Index(Entity):
    +    """This class represents an index and provides different operations, such as
    +    cleaning the index, writing to the index, and so forth."""
    +    def __init__(self, service, path, **kwargs):
    +        Entity.__init__(self, service, path, **kwargs)
    +
    +    def attach(self, host=None, source=None, sourcetype=None):
    +        """Opens a stream (a writable socket) for writing events to the index.
    +
    +        :param host: The host value for events written to the stream.
    +        :type host: ``string``
    +        :param source: The source value for events written to the stream.
    +        :type source: ``string``
    +        :param sourcetype: The sourcetype value for events written to the
    +            stream.
    +        :type sourcetype: ``string``
    +
    +        :return: A writable socket.
    +        """
    +        args = { 'index': self.name }
    +        if host is not None: args['host'] = host
    +        if source is not None: args['source'] = source
    +        if sourcetype is not None: args['sourcetype'] = sourcetype
    +        path = UrlEncoded(PATH_RECEIVERS_STREAM + "?" + urllib.parse.urlencode(args), skip_encode=True)
    +
    +        cookie_or_auth_header = "Authorization: Splunk %s\r\n" % \
    +                                (self.service.token if self.service.token is _NoAuthenticationToken
    +                                 else self.service.token.replace("Splunk ", ""))
    +
    +        # If we have cookie(s), use them instead of "Authorization: ..."
    +        if self.service.has_cookies():
    +            cookie_or_auth_header = "Cookie: %s\r\n" % _make_cookie_header(self.service.get_cookies().items())
    +
    +        # Since we need to stream to the index connection, we have to keep
    +        # the connection open and use the Splunk extension headers to note
    +        # the input mode
    +        sock = self.service.connect()
    +        headers = [("POST %s HTTP/1.1\r\n" % str(self.service._abspath(path))).encode('utf-8'),
    +                   ("Host: %s:%s\r\n" % (self.service.host, int(self.service.port))).encode('utf-8'),
    +                   b"Accept-Encoding: identity\r\n",
    +                   cookie_or_auth_header.encode('utf-8'),
    +                   b"X-Splunk-Input-Mode: Streaming\r\n",
    +                   b"\r\n"]
    +
    +        for h in headers:
    +            sock.write(h)
    +        return sock
    +
    +    @contextlib.contextmanager
    +    def attached_socket(self, *args, **kwargs):
    +        """Opens a raw socket in a ``with`` block to write data to Splunk.
    +
    +        The arguments are identical to those for :meth:`attach`. The socket is
    +        automatically closed at the end of the ``with`` block, even if an
    +        exception is raised in the block.
    +
    +        :param host: The host value for events written to the stream.
    +        :type host: ``string``
    +        :param source: The source value for events written to the stream.
    +        :type source: ``string``
    +        :param sourcetype: The sourcetype value for events written to the
    +            stream.
    +        :type sourcetype: ``string``
    +
    +        :returns: Nothing.
    +
    +        **Example**::
    +
    +            import splunklib.client as client
    +            s = client.connect(...)
    +            index = s.indexes['some_index']
    +            with index.attached_socket(sourcetype='test') as sock:
    +                sock.send('Test event\\r\\n')
    +
    +        """
    +        try:
    +            sock = self.attach(*args, **kwargs)
    +            yield sock
    +        finally:
    +            sock.shutdown(socket.SHUT_RDWR)
    +            sock.close()
    +
    +    def clean(self, timeout=60):
    +        """Deletes the contents of the index.
    +
    +        This method blocks until the index is empty, because it needs to restore
    +        values at the end of the operation.
    +
    +        :param timeout: The time-out period for the operation, in seconds (the
    +            default is 60).
    +        :type timeout: ``integer``
    +
    +        :return: The :class:`Index`.
    +        """
    +        self.refresh()
    +
    +        tds = self['maxTotalDataSizeMB']
    +        ftp = self['frozenTimePeriodInSecs']
    +        was_disabled_initially = self.disabled
    +        try:
    +            if (not was_disabled_initially and \
    +                self.service.splunk_version < (5,)):
    +                # Need to disable the index first on Splunk 4.x,
    +                # but it doesn't work to disable it on 5.0.
    +                self.disable()
    +            self.update(maxTotalDataSizeMB=1, frozenTimePeriodInSecs=1)
    +            self.roll_hot_buckets()
    +
    +            # Wait until event count goes to 0.
    +            start = datetime.now()
    +            diff = timedelta(seconds=timeout)
    +            while self.content.totalEventCount != '0' and datetime.now() < start+diff:
    +                sleep(1)
    +                self.refresh()
    +
    +            if self.content.totalEventCount != '0':
    +                raise OperationError("Cleaning index %s took longer than %s seconds; timing out." % (self.name, timeout))
    +        finally:
    +            # Restore original values
    +            self.update(maxTotalDataSizeMB=tds, frozenTimePeriodInSecs=ftp)
    +            if (not was_disabled_initially and \
    +                self.service.splunk_version < (5,)):
    +                # Re-enable the index if it was originally enabled and we messed with it.
    +                self.enable()
    +
    +        return self
    +
    +    def roll_hot_buckets(self):
    +        """Performs rolling hot buckets for this index.
    +
    +        :return: The :class:`Index`.
    +        """
    +        self.post("roll-hot-buckets")
    +        return self
    +
    +    def submit(self, event, host=None, source=None, sourcetype=None):
    +        """Submits a single event to the index using ``HTTP POST``.
    +
    +        :param event: The event to submit.
    +        :type event: ``string``
    +        :param `host`: The host value of the event.
    +        :type host: ``string``
    +        :param `source`: The source value of the event.
    +        :type source: ``string``
    +        :param `sourcetype`: The sourcetype value of the event.
    +        :type sourcetype: ``string``
    +
    +        :return: The :class:`Index`.
    +        """
    +        args = { 'index': self.name }
    +        if host is not None: args['host'] = host
    +        if source is not None: args['source'] = source
    +        if sourcetype is not None: args['sourcetype'] = sourcetype
    +
    +        self.service.post(PATH_RECEIVERS_SIMPLE, body=event, **args)
    +        return self
    +
    +    # kwargs: host, host_regex, host_segment, rename-source, sourcetype
    +    def upload(self, filename, **kwargs):
    +        """Uploads a file for immediate indexing.
    +
    +        **Note**: The file must be locally accessible from the server.
    +
    +        :param filename: The name of the file to upload. The file can be a
    +            plain, compressed, or archived file.
    +        :type filename: ``string``
    +        :param kwargs: Additional arguments (optional). For more about the
    +            available parameters, see `Index parameters <http://dev.splunk.com/view/SP-CAAAEE6#indexparams>`_ on Splunk Developer Portal.
    +        :type kwargs: ``dict``
    +
    +        :return: The :class:`Index`.
    +        """
    +        kwargs['index'] = self.name
    +        path = 'data/inputs/oneshot'
    +        self.service.post(path, name=filename, **kwargs)
    +        return self
    +
    +
    +class Input(Entity):
    +    """This class represents a Splunk input. This class is the base for all
    +    typed input classes and is also used when the client does not recognize an
    +    input kind.
    +    """
    +    def __init__(self, service, path, kind=None, **kwargs):
    +        # kind can be omitted (in which case it is inferred from the path)
    +        # Otherwise, valid values are the paths from data/inputs ("udp",
    +        # "monitor", "tcp/raw"), or two special cases: "tcp" (which is "tcp/raw")
    +        # and "splunktcp" (which is "tcp/cooked").
    +        Entity.__init__(self, service, path, **kwargs)
    +        if kind is None:
    +            path_segments = path.split('/')
    +            i = path_segments.index('inputs') + 1
    +            if path_segments[i] == 'tcp':
    +                self.kind = path_segments[i] + '/' + path_segments[i+1]
    +            else:
    +                self.kind = path_segments[i]
    +        else:
    +            self.kind = kind
    +
    +        # Handle old input kind names.
    +        if self.kind == 'tcp':
    +            self.kind = 'tcp/raw'
    +        if self.kind == 'splunktcp':
    +            self.kind = 'tcp/cooked'
    +
    +    def update(self, **kwargs):
    +        """Updates the server with any changes you've made to the current input
    +        along with any additional arguments you specify.
    +
    +        :param kwargs: Additional arguments (optional). For more about the
    +            available parameters, see `Input parameters <http://dev.splunk.com/view/SP-CAAAEE6#inputparams>`_ on Splunk Developer Portal.
    +        :type kwargs: ``dict``
    +
    +        :return: The input this method was called on.
    +        :rtype: class:`Input`
    +        """
    +        # UDP and TCP inputs require special handling due to their restrictToHost
    +        # field. For all other inputs kinds, we can dispatch to the superclass method.
    +        if self.kind not in ['tcp', 'splunktcp', 'tcp/raw', 'tcp/cooked', 'udp']:
    +            return super(Input, self).update(**kwargs)
    +        else:
    +            # The behavior of restrictToHost is inconsistent across input kinds and versions of Splunk.
    +            # In Splunk 4.x, the name of the entity is only the port, independent of the value of
    +            # restrictToHost. In Splunk 5.0 this changed so the name will be of the form <restrictToHost>:<port>.
    +            # In 5.0 and 5.0.1, if you don't supply the restrictToHost value on every update, it will
    +            # remove the host restriction from the input. As of 5.0.2 you simply can't change restrictToHost
    +            # on an existing input.
    +
    +            # The logic to handle all these cases:
    +            # - Throw an exception if the user tries to set restrictToHost on an existing input
    +            #   for *any* version of Splunk.
    +            # - Set the existing restrictToHost value on the update args internally so we don't
    +            #   cause it to change in Splunk 5.0 and 5.0.1.
    +            to_update = kwargs.copy()
    +
    +            if 'restrictToHost' in kwargs:
    +                raise IllegalOperationException("Cannot set restrictToHost on an existing input with the SDK.")
    +            elif 'restrictToHost' in self._state.content and self.kind != 'udp':
    +                to_update['restrictToHost'] = self._state.content['restrictToHost']
    +
    +            # Do the actual update operation.
    +            return super(Input, self).update(**to_update)
    +
    +
    +# Inputs is a "kinded" collection, which is a heterogenous collection where
    +# each item is tagged with a kind, that provides a single merged view of all
    +# input kinds.
    +class Inputs(Collection):
    +    """This class represents a collection of inputs. The collection is
    +    heterogeneous and each member of the collection contains a *kind* property
    +    that indicates the specific type of input.
    +    Retrieve this collection using :meth:`Service.inputs`."""
    +
    +    def __init__(self, service, kindmap=None):
    +        Collection.__init__(self, service, PATH_INPUTS, item=Input)
    +
    +    def __getitem__(self, key):
    +        # The key needed to retrieve the input needs it's parenthesis to be URL encoded
    +        # based on the REST API for input
    +        # <http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTinput>
    +        if isinstance(key, tuple) and len(key) == 2:
    +            # Fetch a single kind
    +            key, kind = key
    +            key = UrlEncoded(key, encode_slash=True)
    +            try:
    +                response = self.get(self.kindpath(kind) + "/" + key)
    +                entries = self._load_list(response)
    +                if len(entries) > 1:
    +                    raise AmbiguousReferenceException("Found multiple inputs of kind %s named %s." % (kind, key))
    +                elif len(entries) == 0:
    +                    raise KeyError((key, kind))
    +                else:
    +                    return entries[0]
    +            except HTTPError as he:
    +                if he.status == 404: # No entity matching kind and key
    +                    raise KeyError((key, kind))
    +                else:
    +                    raise
    +        else:
    +            # Iterate over all the kinds looking for matches.
    +            kind = None
    +            candidate = None
    +            key = UrlEncoded(key, encode_slash=True)
    +            for kind in self.kinds:
    +                try:
    +                    response = self.get(kind + "/" + key)
    +                    entries = self._load_list(response)
    +                    if len(entries) > 1:
    +                        raise AmbiguousReferenceException("Found multiple inputs of kind %s named %s." % (kind, key))
    +                    elif len(entries) == 0:
    +                        pass
    +                    else:
    +                        if candidate is not None: # Already found at least one candidate
    +                            raise AmbiguousReferenceException("Found multiple inputs named %s, please specify a kind" % key)
    +                        candidate = entries[0]
    +                except HTTPError as he:
    +                    if he.status == 404:
    +                        pass # Just carry on to the next kind.
    +                    else:
    +                        raise
    +            if candidate is None:
    +                raise KeyError(key) # Never found a match.
    +            else:
    +                return candidate
    +
    +    def __contains__(self, key):
    +        if isinstance(key, tuple) and len(key) == 2:
    +            # If we specify a kind, this will shortcut properly
    +            try:
    +                self.__getitem__(key)
    +                return True
    +            except KeyError:
    +                return False
    +        else:
    +            # Without a kind, we want to minimize the number of round trips to the server, so we
    +            # reimplement some of the behavior of __getitem__ in order to be able to stop searching
    +            # on the first hit.
    +            for kind in self.kinds:
    +                try:
    +                    response = self.get(self.kindpath(kind) + "/" + key)
    +                    entries = self._load_list(response)
    +                    if len(entries) > 0:
    +                        return True
    +                    else:
    +                        pass
    +                except HTTPError as he:
    +                    if he.status == 404:
    +                        pass # Just carry on to the next kind.
    +                    else:
    +                        raise
    +            return False
    +
    +    def create(self, name, kind, **kwargs):
    +        """Creates an input of a specific kind in this collection, with any
    +        arguments you specify.
    +
    +        :param `name`: The input name.
    +        :type name: ``string``
    +        :param `kind`: The kind of input:
    +
    +            - "ad": Active Directory
    +
    +            - "monitor": Files and directories
    +
    +            - "registry": Windows Registry
    +
    +            - "script": Scripts
    +
    +            - "splunktcp": TCP, processed
    +
    +            - "tcp": TCP, unprocessed
    +
    +            - "udp": UDP
    +
    +            - "win-event-log-collections": Windows event log
    +
    +            - "win-perfmon": Performance monitoring
    +
    +            - "win-wmi-collections": WMI
    +
    +        :type kind: ``string``
    +        :param `kwargs`: Additional arguments (optional). For more about the
    +            available parameters, see `Input parameters <http://dev.splunk.com/view/SP-CAAAEE6#inputparams>`_ on Splunk Developer Portal.
    +
    +        :type kwargs: ``dict``
    +
    +        :return: The new :class:`Input`.
    +        """
    +        kindpath = self.kindpath(kind)
    +        self.post(kindpath, name=name, **kwargs)
    +
    +        # If we created an input with restrictToHost set, then
    +        # its path will be <restrictToHost>:<name>, not just <name>,
    +        # and we have to adjust accordingly.
    +
    +        # Url encodes the name of the entity.
    +        name = UrlEncoded(name, encode_slash=True)
    +        path = _path(
    +            self.path + kindpath,
    +            '%s:%s' % (kwargs['restrictToHost'], name) \
    +                if 'restrictToHost' in kwargs else name
    +                )
    +        return Input(self.service, path, kind)
    +
    +    def delete(self, name, kind=None):
    +        """Removes an input from the collection.
    +
    +        :param `kind`: The kind of input:
    +
    +            - "ad": Active Directory
    +
    +            - "monitor": Files and directories
    +
    +            - "registry": Windows Registry
    +
    +            - "script": Scripts
    +
    +            - "splunktcp": TCP, processed
    +
    +            - "tcp": TCP, unprocessed
    +
    +            - "udp": UDP
    +
    +            - "win-event-log-collections": Windows event log
    +
    +            - "win-perfmon": Performance monitoring
    +
    +            - "win-wmi-collections": WMI
    +
    +        :type kind: ``string``
    +        :param name: The name of the input to remove.
    +        :type name: ``string``
    +
    +        :return: The :class:`Inputs` collection.
    +        """
    +        if kind is None:
    +            self.service.delete(self[name].path)
    +        else:
    +            self.service.delete(self[name, kind].path)
    +        return self
    +
    +    def itemmeta(self, kind):
    +        """Returns metadata for the members of a given kind.
    +
    +        :param `kind`: The kind of input:
    +
    +            - "ad": Active Directory
    +
    +            - "monitor": Files and directories
    +
    +            - "registry": Windows Registry
    +
    +            - "script": Scripts
    +
    +            - "splunktcp": TCP, processed
    +
    +            - "tcp": TCP, unprocessed
    +
    +            - "udp": UDP
    +
    +            - "win-event-log-collections": Windows event log
    +
    +            - "win-perfmon": Performance monitoring
    +
    +            - "win-wmi-collections": WMI
    +
    +        :type kind: ``string``
    +
    +        :return: The metadata.
    +        :rtype: class:``splunklib.data.Record``
    +        """
    +        response = self.get("%s/_new" % self._kindmap[kind])
    +        content = _load_atom(response, MATCH_ENTRY_CONTENT)
    +        return _parse_atom_metadata(content)
    +
    +    def _get_kind_list(self, subpath=None):
    +        if subpath is None:
    +            subpath = []
    +
    +        kinds = []
    +        response = self.get('/'.join(subpath))
    +        content = _load_atom_entries(response)
    +        for entry in content:
    +            this_subpath = subpath + [entry.title]
    +            # The "all" endpoint doesn't work yet.
    +            # The "tcp/ssl" endpoint is not a real input collection.
    +            if entry.title == 'all' or this_subpath == ['tcp','ssl']:
    +                continue
    +            elif 'create' in [x.rel for x in entry.link]:
    +                path = '/'.join(subpath + [entry.title])
    +                kinds.append(path)
    +            else:
    +                subkinds = self._get_kind_list(subpath + [entry.title])
    +                kinds.extend(subkinds)
    +        return kinds
    +
    +    @property
    +    def kinds(self):
    +        """Returns the input kinds on this Splunk instance.
    +
    +        :return: The list of input kinds.
    +        :rtype: ``list``
    +        """
    +        return self._get_kind_list()
    +
    +    def kindpath(self, kind):
    +        """Returns a path to the resources for a given input kind.
    +
    +        :param `kind`: The kind of input:
    +
    +            - "ad": Active Directory
    +
    +            - "monitor": Files and directories
    +
    +            - "registry": Windows Registry
    +
    +            - "script": Scripts
    +
    +            - "splunktcp": TCP, processed
    +
    +            - "tcp": TCP, unprocessed
    +
    +            - "udp": UDP
    +
    +            - "win-event-log-collections": Windows event log
    +
    +            - "win-perfmon": Performance monitoring
    +
    +            - "win-wmi-collections": WMI
    +
    +        :type kind: ``string``
    +
    +        :return: The relative endpoint path.
    +        :rtype: ``string``
    +        """
    +        if kind == 'tcp':
    +            return UrlEncoded('tcp/raw', skip_encode=True)
    +        elif kind == 'splunktcp':
    +            return UrlEncoded('tcp/cooked', skip_encode=True)
    +        else:
    +            return UrlEncoded(kind, skip_encode=True)
    +
    +    def list(self, *kinds, **kwargs):
    +        """Returns a list of inputs that are in the :class:`Inputs` collection.
    +        You can also filter by one or more input kinds.
    +
    +        This function iterates over all possible inputs, regardless of any arguments you
    +        specify. Because the :class:`Inputs` collection is the union of all the inputs of each
    +        kind, this method implements parameters such as "count", "search", and so
    +        on at the Python level once all the data has been fetched. The exception
    +        is when you specify a single input kind, and then this method makes a single request
    +        with the usual semantics for parameters.
    +
    +        :param kinds: The input kinds to return (optional).
    +
    +            - "ad": Active Directory
    +
    +            - "monitor": Files and directories
    +
    +            - "registry": Windows Registry
    +
    +            - "script": Scripts
    +
    +            - "splunktcp": TCP, processed
    +
    +            - "tcp": TCP, unprocessed
    +
    +            - "udp": UDP
    +
    +            - "win-event-log-collections": Windows event log
    +
    +            - "win-perfmon": Performance monitoring
    +
    +            - "win-wmi-collections": WMI
    +
    +        :type kinds: ``string``
    +        :param kwargs: Additional arguments (optional):
    +
    +            - "count" (``integer``): The maximum number of items to return.
    +
    +            - "offset" (``integer``): The offset of the first item to return.
    +
    +            - "search" (``string``): The search query to filter responses.
    +
    +            - "sort_dir" (``string``): The direction to sort returned items:
    +              "asc" or "desc".
    +
    +            - "sort_key" (``string``): The field to use for sorting (optional).
    +
    +            - "sort_mode" (``string``): The collating sequence for sorting
    +              returned items: "auto", "alpha", "alpha_case", or "num".
    +
    +        :type kwargs: ``dict``
    +
    +        :return: A list of input kinds.
    +        :rtype: ``list``
    +        """
    +        if len(kinds) == 0:
    +            kinds = self.kinds
    +        if len(kinds) == 1:
    +            kind = kinds[0]
    +            logger.debug("Inputs.list taking short circuit branch for single kind.")
    +            path = self.kindpath(kind)
    +            logger.debug("Path for inputs: %s", path)
    +            try:
    +                path = UrlEncoded(path, skip_encode=True)
    +                response = self.get(path, **kwargs)
    +            except HTTPError as he:
    +                if he.status == 404: # No inputs of this kind
    +                    return []
    +            entities = []
    +            entries = _load_atom_entries(response)
    +            if entries is None:
    +                return [] # No inputs in a collection comes back with no feed or entry in the XML
    +            for entry in entries:
    +                state = _parse_atom_entry(entry)
    +                # Unquote the URL, since all URL encoded in the SDK
    +                # should be of type UrlEncoded, and all str should not
    +                # be URL encoded.
    +                path = urllib.parse.unquote(state.links.alternate)
    +                entity = Input(self.service, path, kind, state=state)
    +                entities.append(entity)
    +            return entities
    +
    +        search = kwargs.get('search', '*')
    +
    +        entities = []
    +        for kind in kinds:
    +            response = None
    +            try:
    +                kind = UrlEncoded(kind, skip_encode=True)
    +                response = self.get(self.kindpath(kind), search=search)
    +            except HTTPError as e:
    +                if e.status == 404:
    +                    continue # No inputs of this kind
    +                else:
    +                    raise
    +
    +            entries = _load_atom_entries(response)
    +            if entries is None: continue # No inputs to process
    +            for entry in entries:
    +                state = _parse_atom_entry(entry)
    +                # Unquote the URL, since all URL encoded in the SDK
    +                # should be of type UrlEncoded, and all str should not
    +                # be URL encoded.
    +                path = urllib.parse.unquote(state.links.alternate)
    +                entity = Input(self.service, path, kind, state=state)
    +                entities.append(entity)
    +        if 'offset' in kwargs:
    +            entities = entities[kwargs['offset']:]
    +        if 'count' in kwargs:
    +            entities = entities[:kwargs['count']]
    +        if kwargs.get('sort_mode', None) == 'alpha':
    +            sort_field = kwargs.get('sort_field', 'name')
    +            if sort_field == 'name':
    +                f = lambda x: x.name.lower()
    +            else:
    +                f = lambda x: x[sort_field].lower()
    +            entities = sorted(entities, key=f)
    +        if kwargs.get('sort_mode', None) == 'alpha_case':
    +            sort_field = kwargs.get('sort_field', 'name')
    +            if sort_field == 'name':
    +                f = lambda x: x.name
    +            else:
    +                f = lambda x: x[sort_field]
    +            entities = sorted(entities, key=f)
    +        if kwargs.get('sort_dir', 'asc') == 'desc':
    +            entities = list(reversed(entities))
    +        return entities
    +
    +    def __iter__(self, **kwargs):
    +        for item in self.iter(**kwargs):
    +            yield item
    +
    +    def iter(self, **kwargs):
    +        """ Iterates over the collection of inputs.
    +
    +        :param kwargs: Additional arguments (optional):
    +
    +            - "count" (``integer``): The maximum number of items to return.
    +
    +            - "offset" (``integer``): The offset of the first item to return.
    +
    +            - "search" (``string``): The search query to filter responses.
    +
    +            - "sort_dir" (``string``): The direction to sort returned items:
    +              "asc" or "desc".
    +
    +            - "sort_key" (``string``): The field to use for sorting (optional).
    +
    +            - "sort_mode" (``string``): The collating sequence for sorting
    +              returned items: "auto", "alpha", "alpha_case", or "num".
    +
    +        :type kwargs: ``dict``
    +        """
    +        for item in self.list(**kwargs):
    +            yield item
    +
    +    def oneshot(self, path, **kwargs):
    +        """ Creates a oneshot data input, which is an upload of a single file
    +        for one-time indexing.
    +
    +        :param path: The path and filename.
    +        :type path: ``string``
    +        :param kwargs: Additional arguments (optional). For more about the
    +            available parameters, see `Input parameters <http://dev.splunk.com/view/SP-CAAAEE6#inputparams>`_ on Splunk Developer Portal.
    +        :type kwargs: ``dict``
    +        """
    +        self.post('oneshot', name=path, **kwargs)
    +
    +
    +class Job(Entity):
    +    """This class represents a search job."""
    +    def __init__(self, service, sid, **kwargs):
    +        # Default to v2 in Splunk Version 9+
    +        path = "{path}{sid}"
    +        # Formatting path based on the Splunk Version
    +        if service.disable_v2_api:
    +            path = path.format(path=PATH_JOBS, sid=sid)
    +        else:
    +            path = path.format(path=PATH_JOBS_V2, sid=sid)
    +
    +        Entity.__init__(self, service, path, skip_refresh=True, **kwargs)
    +        self.sid = sid
    +
    +    # The Job entry record is returned at the root of the response
    +    def _load_atom_entry(self, response):
    +        return _load_atom(response).entry
    +
    +    def cancel(self):
    +        """Stops the current search and deletes the results cache.
    +
    +        :return: The :class:`Job`.
    +        """
    +        try:
    +            self.post("control", action="cancel")
    +        except HTTPError as he:
    +            if he.status == 404:
    +                # The job has already been cancelled, so
    +                # cancelling it twice is a nop.
    +                pass
    +            else:
    +                raise
    +        return self
    +
    +    def disable_preview(self):
    +        """Disables preview for this job.
    +
    +        :return: The :class:`Job`.
    +        """
    +        self.post("control", action="disablepreview")
    +        return self
    +
    +    def enable_preview(self):
    +        """Enables preview for this job.
    +
    +        **Note**: Enabling preview might slow search considerably.
    +
    +        :return: The :class:`Job`.
    +        """
    +        self.post("control", action="enablepreview")
    +        return self
    +
    +    def events(self, **kwargs):
    +        """Returns a streaming handle to this job's events.
    +
    +        :param kwargs: Additional parameters (optional). For a list of valid
    +            parameters, see `GET search/jobs/{search_id}/events
    +            <http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTsearch#GET_search.2Fjobs.2F.7Bsearch_id.7D.2Fevents>`_
    +            in the REST API documentation.
    +        :type kwargs: ``dict``
    +
    +        :return: The ``InputStream`` IO handle to this job's events.
    +        """
    +        kwargs['segmentation'] = kwargs.get('segmentation', 'none')
    +        
    +        # Search API v1(GET) and v2(POST)
    +        if self.service.disable_v2_api:
    +            return self.get("events", **kwargs).body
    +        return self.post("events", **kwargs).body
    +
    +    def finalize(self):
    +        """Stops the job and provides intermediate results for retrieval.
    +
    +        :return: The :class:`Job`.
    +        """
    +        self.post("control", action="finalize")
    +        return self
    +
    +    def is_done(self):
    +        """Indicates whether this job finished running.
    +
    +        :return: ``True`` if the job is done, ``False`` if not.
    +        :rtype: ``boolean``
    +        """
    +        if not self.is_ready():
    +            return False
    +        done = (self._state.content['isDone'] == '1')
    +        return done
    +
    +    def is_ready(self):
    +        """Indicates whether this job is ready for querying.
    +
    +        :return: ``True`` if the job is ready, ``False`` if not.
    +        :rtype: ``boolean``
    +
    +        """
    +        response = self.get()
    +        if response.status == 204:
    +            return False
    +        self._state = self.read(response)
    +        ready = self._state.content['dispatchState'] not in ['QUEUED', 'PARSING']
    +        return ready
    +
    +    @property
    +    def name(self):
    +        """Returns the name of the search job, which is the search ID (SID).
    +
    +        :return: The search ID.
    +        :rtype: ``string``
    +        """
    +        return self.sid
    +
    +    def pause(self):
    +        """Suspends the current search.
    +
    +        :return: The :class:`Job`.
    +        """
    +        self.post("control", action="pause")
    +        return self
    +
    +    def results(self, **query_params):
    +        """Returns a streaming handle to this job's search results. To get a nice, Pythonic iterator, pass the handle
    +        to :class:`splunklib.results.JSONResultsReader` along with the query param "output_mode='json'", as in::
    +
    +            import splunklib.client as client
    +            import splunklib.results as results
    +            from time import sleep
    +            service = client.connect(...)
    +            job = service.jobs.create("search * | head 5")
    +            while not job.is_done():
    +                sleep(.2)
    +            rr = results.JSONResultsReader(job.results(output_mode='json'))
    +            for result in rr:
    +                if isinstance(result, results.Message):
    +                    # Diagnostic messages may be returned in the results
    +                    print '%s: %s' % (result.type, result.message)
    +                elif isinstance(result, dict):
    +                    # Normal events are returned as dicts
    +                    print result
    +            assert rr.is_preview == False
    +
    +        Results are not available until the job has finished. If called on
    +        an unfinished job, the result is an empty event set.
    +
    +        This method makes a single roundtrip
    +        to the server, plus at most two additional round trips if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        :param query_params: Additional parameters (optional). For a list of valid
    +            parameters, see `GET search/jobs/{search_id}/results
    +            <http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTsearch#GET_search.2Fjobs.2F.7Bsearch_id.7D.2Fresults>`_.
    +        :type query_params: ``dict``
    +
    +        :return: The ``InputStream`` IO handle to this job's results.
    +        """
    +        query_params['segmentation'] = query_params.get('segmentation', 'none')
    +        
    +        # Search API v1(GET) and v2(POST)
    +        if self.service.disable_v2_api:
    +            return self.get("results", **query_params).body
    +        return self.post("results", **query_params).body
    +
    +    def preview(self, **query_params):
    +        """Returns a streaming handle to this job's preview search results.
    +
    +        Unlike :class:`splunklib.results.JSONResultsReader`along with the query param "output_mode='json'",
    +        which requires a job to be finished to return any results, the ``preview`` method returns any results that
    +        have been generated so far, whether the job is running or not. The returned search results are the raw data
    +        from the server. Pass the handle returned to :class:`splunklib.results.JSONResultsReader` to get a nice,
    +        Pythonic iterator over objects, as in::
    +
    +            import splunklib.client as client
    +            import splunklib.results as results
    +            service = client.connect(...)
    +            job = service.jobs.create("search * | head 5")
    +            rr = results.JSONResultsReader(job.preview(output_mode='json'))
    +            for result in rr:
    +                if isinstance(result, results.Message):
    +                    # Diagnostic messages may be returned in the results
    +                    print '%s: %s' % (result.type, result.message)
    +                elif isinstance(result, dict):
    +                    # Normal events are returned as dicts
    +                    print result
    +            if rr.is_preview:
    +                print "Preview of a running search job."
    +            else:
    +                print "Job is finished. Results are final."
    +
    +        This method makes one roundtrip to the server, plus at most
    +        two more if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        :param query_params: Additional parameters (optional). For a list of valid
    +            parameters, see `GET search/jobs/{search_id}/results_preview
    +            <http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTsearch#GET_search.2Fjobs.2F.7Bsearch_id.7D.2Fresults_preview>`_
    +            in the REST API documentation.
    +        :type query_params: ``dict``
    +
    +        :return: The ``InputStream`` IO handle to this job's preview results.
    +        """
    +        query_params['segmentation'] = query_params.get('segmentation', 'none')
    +        
    +        # Search API v1(GET) and v2(POST)
    +        if self.service.disable_v2_api:
    +            return self.get("results_preview", **query_params).body
    +        return self.post("results_preview", **query_params).body
    +
    +    def searchlog(self, **kwargs):
    +        """Returns a streaming handle to this job's search log.
    +
    +        :param `kwargs`: Additional parameters (optional). For a list of valid
    +            parameters, see `GET search/jobs/{search_id}/search.log
    +            <http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTsearch#GET_search.2Fjobs.2F.7Bsearch_id.7D.2Fsearch.log>`_
    +            in the REST API documentation.
    +        :type kwargs: ``dict``
    +
    +        :return: The ``InputStream`` IO handle to this job's search log.
    +        """
    +        return self.get("search.log", **kwargs).body
    +
    +    def set_priority(self, value):
    +        """Sets this job's search priority in the range of 0-10.
    +
    +        Higher numbers indicate higher priority. Unless splunkd is
    +        running as *root*, you can only decrease the priority of a running job.
    +
    +        :param `value`: The search priority.
    +        :type value: ``integer``
    +
    +        :return: The :class:`Job`.
    +        """
    +        self.post('control', action="setpriority", priority=value)
    +        return self
    +
    +    def summary(self, **kwargs):
    +        """Returns a streaming handle to this job's summary.
    +
    +        :param `kwargs`: Additional parameters (optional). For a list of valid
    +            parameters, see `GET search/jobs/{search_id}/summary
    +            <http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTsearch#GET_search.2Fjobs.2F.7Bsearch_id.7D.2Fsummary>`_
    +            in the REST API documentation.
    +        :type kwargs: ``dict``
    +
    +        :return: The ``InputStream`` IO handle to this job's summary.
    +        """
    +        return self.get("summary", **kwargs).body
    +
    +    def timeline(self, **kwargs):
    +        """Returns a streaming handle to this job's timeline results.
    +
    +        :param `kwargs`: Additional timeline arguments (optional). For a list of valid
    +            parameters, see `GET search/jobs/{search_id}/timeline
    +            <http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTsearch#GET_search.2Fjobs.2F.7Bsearch_id.7D.2Ftimeline>`_
    +            in the REST API documentation.
    +        :type kwargs: ``dict``
    +
    +        :return: The ``InputStream`` IO handle to this job's timeline.
    +        """
    +        return self.get("timeline", **kwargs).body
    +
    +    def touch(self):
    +        """Extends the expiration time of the search to the current time (now) plus
    +        the time-to-live (ttl) value.
    +
    +        :return: The :class:`Job`.
    +        """
    +        self.post("control", action="touch")
    +        return self
    +
    +    def set_ttl(self, value):
    +        """Set the job's time-to-live (ttl) value, which is the time before the
    +        search job expires and is still available.
    +
    +        :param `value`: The ttl value, in seconds.
    +        :type value: ``integer``
    +
    +        :return: The :class:`Job`.
    +        """
    +        self.post("control", action="setttl", ttl=value)
    +        return self
    +
    +    def unpause(self):
    +        """Resumes the current search, if paused.
    +
    +        :return: The :class:`Job`.
    +        """
    +        self.post("control", action="unpause")
    +        return self
    +
    +
    +class Jobs(Collection):
    +    """This class represents a collection of search jobs. Retrieve this
    +    collection using :meth:`Service.jobs`."""
    +    def __init__(self, service):
    +        # Splunk 9 introduces the v2 endpoint
    +        if not service.disable_v2_api:
    +            path = PATH_JOBS_V2
    +        else:
    +            path = PATH_JOBS
    +        Collection.__init__(self, service, path, item=Job)
    +        # The count value to say list all the contents of this
    +        # Collection is 0, not -1 as it is on most.
    +        self.null_count = 0
    +
    +    def _load_list(self, response):
    +        # Overridden because Job takes a sid instead of a path.
    +        entries = _load_atom_entries(response)
    +        if entries is None: return []
    +        entities = []
    +        for entry in entries:
    +            state = _parse_atom_entry(entry)
    +            entity = self.item(
    +                self.service,
    +                entry['content']['sid'],
    +                state=state)
    +            entities.append(entity)
    +        return entities
    +
    +    def create(self, query, **kwargs):
    +        """ Creates a search using a search query and any additional parameters
    +        you provide.
    +
    +        :param query: The search query.
    +        :type query: ``string``
    +        :param kwargs: Additiona parameters (optional). For a list of available
    +            parameters, see `Search job parameters
    +            <http://dev.splunk.com/view/SP-CAAAEE5#searchjobparams>`_
    +            on Splunk Developer Portal.
    +        :type kwargs: ``dict``
    +
    +        :return: The :class:`Job`.
    +        """
    +        if kwargs.get("exec_mode", None) == "oneshot":
    +            raise TypeError("Cannot specify exec_mode=oneshot; use the oneshot method instead.")
    +        response = self.post(search=query, **kwargs)
    +        sid = _load_sid(response, kwargs.get("output_mode", None))
    +        return Job(self.service, sid)
    +
    +    def export(self, query, **params):
    +        """Runs a search and immediately starts streaming preview events. This method returns a streaming handle to
    +        this job's events as an XML document from the server. To parse this stream into usable Python objects,
    +        pass the handle to :class:`splunklib.results.JSONResultsReader` along with the query param
    +        "output_mode='json'"::
    +
    +            import splunklib.client as client
    +            import splunklib.results as results
    +            service = client.connect(...)
    +            rr = results.JSONResultsReader(service.jobs.export("search * | head 5",output_mode='json'))
    +            for result in rr:
    +                if isinstance(result, results.Message):
    +                    # Diagnostic messages may be returned in the results
    +                    print '%s: %s' % (result.type, result.message)
    +                elif isinstance(result, dict):
    +                    # Normal events are returned as dicts
    +                    print result
    +            assert rr.is_preview == False
    +
    +        Running an export search is more efficient as it streams the results
    +        directly to you, rather than having to write them out to disk and make
    +        them available later. As soon as results are ready, you will receive
    +        them.
    +
    +        The ``export`` method makes a single roundtrip to the server (as opposed
    +        to two for :meth:`create` followed by :meth:`preview`), plus at most two
    +        more if the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        :raises `ValueError`: Raised for invalid queries.
    +        :param query: The search query.
    +        :type query: ``string``
    +        :param params: Additional arguments (optional). For a list of valid
    +            parameters, see `GET search/jobs/export
    +            <http://docs/Documentation/Splunk/latest/RESTAPI/RESTsearch#search.2Fjobs.2Fexport>`_
    +            in the REST API documentation.
    +        :type params: ``dict``
    +
    +        :return: The ``InputStream`` IO handle to raw XML returned from the server.
    +        """
    +        if "exec_mode" in params:
    +            raise TypeError("Cannot specify an exec_mode to export.")
    +        params['segmentation'] = params.get('segmentation', 'none')
    +        return self.post(path_segment="export",
    +                         search=query,
    +                         **params).body
    +
    +    def itemmeta(self):
    +        """There is no metadata available for class:``Jobs``.
    +
    +        Any call to this method raises a class:``NotSupportedError``.
    +
    +        :raises: class:``NotSupportedError``
    +        """
    +        raise NotSupportedError()
    +
    +    def oneshot(self, query, **params):
    +        """Run a oneshot search and returns a streaming handle to the results.
    +
    +        The ``InputStream`` object streams fragments from the server. To parse this stream into usable Python
    +        objects, pass the handle to :class:`splunklib.results.JSONResultsReader` along with the query param
    +        "output_mode='json'" ::
    +
    +            import splunklib.client as client
    +            import splunklib.results as results
    +            service = client.connect(...)
    +            rr = results.JSONResultsReader(service.jobs.oneshot("search * | head 5",output_mode='json'))
    +            for result in rr:
    +                if isinstance(result, results.Message):
    +                    # Diagnostic messages may be returned in the results
    +                    print '%s: %s' % (result.type, result.message)
    +                elif isinstance(result, dict):
    +                    # Normal events are returned as dicts
    +                    print result
    +            assert rr.is_preview == False
    +
    +        The ``oneshot`` method makes a single roundtrip to the server (as opposed
    +        to two for :meth:`create` followed by :meth:`results`), plus at most two more
    +        if the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        :raises ValueError: Raised for invalid queries.
    +
    +        :param query: The search query.
    +        :type query: ``string``
    +        :param params: Additional arguments (optional):
    +
    +            - "output_mode": Specifies the output format of the results (XML,
    +              JSON, or CSV).
    +
    +            - "earliest_time": Specifies the earliest time in the time range to
    +              search. The time string can be a UTC time (with fractional seconds),
    +              a relative time specifier (to now), or a formatted time string.
    +
    +            - "latest_time": Specifies the latest time in the time range to
    +              search. The time string can be a UTC time (with fractional seconds),
    +              a relative time specifier (to now), or a formatted time string.
    +
    +            - "rf": Specifies one or more fields to add to the search.
    +
    +        :type params: ``dict``
    +
    +        :return: The ``InputStream`` IO handle to raw XML returned from the server.
    +        """
    +        if "exec_mode" in params:
    +            raise TypeError("Cannot specify an exec_mode to oneshot.")
    +        params['segmentation'] = params.get('segmentation', 'none')
    +        return self.post(search=query,
    +                         exec_mode="oneshot",
    +                         **params).body
    +
    +
    +class Loggers(Collection):
    +    """This class represents a collection of service logging categories.
    +    Retrieve this collection using :meth:`Service.loggers`."""
    +    def __init__(self, service):
    +        Collection.__init__(self, service, PATH_LOGGER)
    +
    +    def itemmeta(self):
    +        """There is no metadata available for class:``Loggers``.
    +
    +        Any call to this method raises a class:``NotSupportedError``.
    +
    +        :raises: class:``NotSupportedError``
    +        """
    +        raise NotSupportedError()
    +
    +
    +class Message(Entity):
    +    def __init__(self, service, path, **kwargs):
    +        Entity.__init__(self, service, path, **kwargs)
    +
    +    @property
    +    def value(self):
    +        """Returns the message value.
    +
    +        :return: The message value.
    +        :rtype: ``string``
    +        """
    +        return self[self.name]
    +
    +
    +class ModularInputKind(Entity):
    +    """This class contains the different types of modular inputs. Retrieve this
    +    collection using :meth:`Service.modular_input_kinds`.
    +    """
    +    def __contains__(self, name):
    +        args = self.state.content['endpoints']['args']
    +        if name in args:
    +            return True
    +        else:
    +            return Entity.__contains__(self, name)
    +
    +    def __getitem__(self, name):
    +        args = self.state.content['endpoint']['args']
    +        if name in args:
    +            return args['item']
    +        else:
    +            return Entity.__getitem__(self, name)
    +
    +    @property
    +    def arguments(self):
    +        """A dictionary of all the arguments supported by this modular input kind.
    +
    +        The keys in the dictionary are the names of the arguments. The values are
    +        another dictionary giving the metadata about that argument. The possible
    +        keys in that dictionary are ``"title"``, ``"description"``, ``"required_on_create``",
    +        ``"required_on_edit"``, ``"data_type"``. Each value is a string. It should be one
    +        of ``"true"`` or ``"false"`` for ``"required_on_create"`` and ``"required_on_edit"``,
    +        and one of ``"boolean"``, ``"string"``, or ``"number``" for ``"data_type"``.
    +
    +        :return: A dictionary describing the arguments this modular input kind takes.
    +        :rtype: ``dict``
    +        """
    +        return self.state.content['endpoint']['args']
    +
    +    def update(self, **kwargs):
    +        """Raises an error. Modular input kinds are read only."""
    +        raise IllegalOperationException("Modular input kinds cannot be updated via the REST API.")
    +
    +
    +class SavedSearch(Entity):
    +    """This class represents a saved search."""
    +    def __init__(self, service, path, **kwargs):
    +        Entity.__init__(self, service, path, **kwargs)
    +
    +    def acknowledge(self):
    +        """Acknowledges the suppression of alerts from this saved search and
    +        resumes alerting.
    +
    +        :return: The :class:`SavedSearch`.
    +        """
    +        self.post("acknowledge")
    +        return self
    +
    +    @property
    +    def alert_count(self):
    +        """Returns the number of alerts fired by this saved search.
    +
    +        :return: The number of alerts fired by this saved search.
    +        :rtype: ``integer``
    +        """
    +        return int(self._state.content.get('triggered_alert_count', 0))
    +
    +    def dispatch(self, **kwargs):
    +        """Runs the saved search and returns the resulting search job.
    +
    +        :param `kwargs`: Additional dispatch arguments (optional). For details,
    +                         see the `POST saved/searches/{name}/dispatch
    +                         <http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTsearch#POST_saved.2Fsearches.2F.7Bname.7D.2Fdispatch>`_
    +                         endpoint in the REST API documentation.
    +        :type kwargs: ``dict``
    +        :return: The :class:`Job`.
    +        """
    +        response = self.post("dispatch", **kwargs)
    +        sid = _load_sid(response, kwargs.get("output_mode", None))
    +        return Job(self.service, sid)
    +
    +    @property
    +    def fired_alerts(self):
    +        """Returns the collection of fired alerts (a fired alert group)
    +        corresponding to this saved search's alerts.
    +
    +        :raises IllegalOperationException: Raised when the search is not scheduled.
    +
    +        :return: A collection of fired alerts.
    +        :rtype: :class:`AlertGroup`
    +        """
    +        if self['is_scheduled'] == '0':
    +            raise IllegalOperationException('Unscheduled saved searches have no alerts.')
    +        c = Collection(
    +            self.service,
    +            self.service._abspath(PATH_FIRED_ALERTS + self.name,
    +                                  owner=self._state.access.owner,
    +                                  app=self._state.access.app,
    +                                  sharing=self._state.access.sharing),
    +            item=AlertGroup)
    +        return c
    +
    +    def history(self, **kwargs):
    +        """Returns a list of search jobs corresponding to this saved search.
    +
    +        :param `kwargs`: Additional arguments (optional).
    +        :type kwargs: ``dict``
    +
    +        :return: A list of :class:`Job` objects.
    +        """
    +        response = self.get("history", **kwargs)
    +        entries = _load_atom_entries(response)
    +        if entries is None: return []
    +        jobs = []
    +        for entry in entries:
    +            job = Job(self.service, entry.title)
    +            jobs.append(job)
    +        return jobs
    +
    +    def update(self, search=None, **kwargs):
    +        """Updates the server with any changes you've made to the current saved
    +        search along with any additional arguments you specify.
    +
    +        :param `search`: The search query (optional).
    +        :type search: ``string``
    +        :param `kwargs`: Additional arguments (optional). For a list of available
    +            parameters, see `Saved search parameters
    +            <http://dev.splunk.com/view/SP-CAAAEE5#savedsearchparams>`_
    +            on Splunk Developer Portal.
    +        :type kwargs: ``dict``
    +
    +        :return: The :class:`SavedSearch`.
    +        """
    +        # Updates to a saved search *require* that the search string be
    +        # passed, so we pass the current search string if a value wasn't
    +        # provided by the caller.
    +        if search is None: search = self.content.search
    +        Entity.update(self, search=search, **kwargs)
    +        return self
    +
    +    def scheduled_times(self, earliest_time='now', latest_time='+1h'):
    +        """Returns the times when this search is scheduled to run.
    +
    +        By default this method returns the times in the next hour. For different
    +        time ranges, set *earliest_time* and *latest_time*. For example,
    +        for all times in the last day use "earliest_time=-1d" and
    +        "latest_time=now".
    +
    +        :param earliest_time: The earliest time.
    +        :type earliest_time: ``string``
    +        :param latest_time: The latest time.
    +        :type latest_time: ``string``
    +
    +        :return: The list of search times.
    +        """
    +        response = self.get("scheduled_times",
    +                            earliest_time=earliest_time,
    +                            latest_time=latest_time)
    +        data = self._load_atom_entry(response)
    +        rec = _parse_atom_entry(data)
    +        times = [datetime.fromtimestamp(int(t))
    +                 for t in rec.content.scheduled_times]
    +        return times
    +
    +    def suppress(self, expiration):
    +        """Skips any scheduled runs of this search in the next *expiration*
    +        number of seconds.
    +
    +        :param expiration: The expiration period, in seconds.
    +        :type expiration: ``integer``
    +
    +        :return: The :class:`SavedSearch`.
    +        """
    +        self.post("suppress", expiration=expiration)
    +        return self
    +
    +    @property
    +    def suppressed(self):
    +        """Returns the number of seconds that this search is blocked from running
    +        (possibly 0).
    +
    +        :return: The number of seconds.
    +        :rtype: ``integer``
    +        """
    +        r = self._run_action("suppress")
    +        if r.suppressed == "1":
    +            return int(r.expiration)
    +        else:
    +            return 0
    +
    +    def unsuppress(self):
    +        """Cancels suppression and makes this search run as scheduled.
    +
    +        :return: The :class:`SavedSearch`.
    +        """
    +        self.post("suppress", expiration="0")
    +        return self
    +
    +
    +class SavedSearches(Collection):
    +    """This class represents a collection of saved searches. Retrieve this
    +    collection using :meth:`Service.saved_searches`."""
    +    def __init__(self, service):
    +        Collection.__init__(
    +            self, service, PATH_SAVED_SEARCHES, item=SavedSearch)
    +
    +    def create(self, name, search, **kwargs):
    +        """ Creates a saved search.
    +
    +        :param name: The name for the saved search.
    +        :type name: ``string``
    +        :param search: The search query.
    +        :type search: ``string``
    +        :param kwargs: Additional arguments (optional). For a list of available
    +            parameters, see `Saved search parameters
    +            <http://dev.splunk.com/view/SP-CAAAEE5#savedsearchparams>`_
    +            on Splunk Developer Portal.
    +        :type kwargs: ``dict``
    +        :return: The :class:`SavedSearches` collection.
    +        """
    +        return Collection.create(self, name, search=search, **kwargs)
    +
    +
    +class Settings(Entity):
    +    """This class represents configuration settings for a Splunk service.
    +    Retrieve this collection using :meth:`Service.settings`."""
    +    def __init__(self, service, **kwargs):
    +        Entity.__init__(self, service, "/services/server/settings", **kwargs)
    +
    +    # Updates on the settings endpoint are POSTed to server/settings/settings.
    +    def update(self, **kwargs):
    +        """Updates the settings on the server using the arguments you provide.
    +
    +        :param kwargs: Additional arguments. For a list of valid arguments, see
    +            `POST server/settings/{name}
    +            <http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTsystem#POST_server.2Fsettings.2F.7Bname.7D>`_
    +            in the REST API documentation.
    +        :type kwargs: ``dict``
    +        :return: The :class:`Settings` collection.
    +        """
    +        self.service.post("/services/server/settings/settings", **kwargs)
    +        return self
    +
    +
    +class User(Entity):
    +    """This class represents a Splunk user.
    +    """
    +    @property
    +    def role_entities(self):
    +        """Returns a list of roles assigned to this user.
    +
    +        :return: The list of roles.
    +        :rtype: ``list``
    +        """
    +        return [self.service.roles[name] for name in self.content.roles]
    +
    +
    +# Splunk automatically lowercases new user names so we need to match that
    +# behavior here to ensure that the subsequent member lookup works correctly.
    +class Users(Collection):
    +    """This class represents the collection of Splunk users for this instance of
    +    Splunk. Retrieve this collection using :meth:`Service.users`.
    +    """
    +    def __init__(self, service):
    +        Collection.__init__(self, service, PATH_USERS, item=User)
    +
    +    def __getitem__(self, key):
    +        return Collection.__getitem__(self, key.lower())
    +
    +    def __contains__(self, name):
    +        return Collection.__contains__(self, name.lower())
    +
    +    def create(self, username, password, roles, **params):
    +        """Creates a new user.
    +
    +        This function makes two roundtrips to the server, plus at most
    +        two more if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        :param username: The username.
    +        :type username: ``string``
    +        :param password: The password.
    +        :type password: ``string``
    +        :param roles: A single role or list of roles for the user.
    +        :type roles: ``string`` or  ``list``
    +        :param params: Additional arguments (optional). For a list of available
    +            parameters, see `User authentication parameters
    +            <http://dev.splunk.com/view/SP-CAAAEJ6#userauthparams>`_
    +            on Splunk Developer Portal.
    +        :type params: ``dict``
    +
    +        :return: The new user.
    +        :rtype: :class:`User`
    +
    +        **Example**::
    +
    +            import splunklib.client as client
    +            c = client.connect(...)
    +            users = c.users
    +            boris = users.create("boris", "securepassword", roles="user")
    +            hilda = users.create("hilda", "anotherpassword", roles=["user","power"])
    +        """
    +        if not isinstance(username, six.string_types):
    +            raise ValueError("Invalid username: %s" % str(username))
    +        username = username.lower()
    +        self.post(name=username, password=password, roles=roles, **params)
    +        # splunkd doesn't return the user in the POST response body,
    +        # so we have to make a second round trip to fetch it.
    +        response = self.get(username)
    +        entry = _load_atom(response, XNAME_ENTRY).entry
    +        state = _parse_atom_entry(entry)
    +        entity = self.item(
    +            self.service,
    +            urllib.parse.unquote(state.links.alternate),
    +            state=state)
    +        return entity
    +
    +    def delete(self, name):
    +        """ Deletes the user and returns the resulting collection of users.
    +
    +        :param name: The name of the user to delete.
    +        :type name: ``string``
    +
    +        :return:
    +        :rtype: :class:`Users`
    +        """
    +        return Collection.delete(self, name.lower())
    +
    +
    +class Role(Entity):
    +    """This class represents a user role.
    +    """
    +    def grant(self, *capabilities_to_grant):
    +        """Grants additional capabilities to this role.
    +
    +        :param capabilities_to_grant: Zero or more capabilities to grant this
    +            role. For a list of capabilities, see
    +            `Capabilities <http://dev.splunk.com/view/SP-CAAAEJ6#capabilities>`_
    +            on Splunk Developer Portal.
    +        :type capabilities_to_grant: ``string`` or ``list``
    +        :return: The :class:`Role`.
    +
    +        **Example**::
    +
    +            service = client.connect(...)
    +            role = service.roles['somerole']
    +            role.grant('change_own_password', 'search')
    +        """
    +        possible_capabilities = self.service.capabilities
    +        for capability in capabilities_to_grant:
    +            if capability not in possible_capabilities:
    +                raise NoSuchCapability(capability)
    +        new_capabilities = self['capabilities'] + list(capabilities_to_grant)
    +        self.post(capabilities=new_capabilities)
    +        return self
    +
    +    def revoke(self, *capabilities_to_revoke):
    +        """Revokes zero or more capabilities from this role.
    +
    +        :param capabilities_to_revoke: Zero or more capabilities to grant this
    +            role. For a list of capabilities, see
    +            `Capabilities <http://dev.splunk.com/view/SP-CAAAEJ6#capabilities>`_
    +            on Splunk Developer Portal.
    +        :type capabilities_to_revoke: ``string`` or ``list``
    +
    +        :return: The :class:`Role`.
    +
    +        **Example**::
    +
    +            service = client.connect(...)
    +            role = service.roles['somerole']
    +            role.revoke('change_own_password', 'search')
    +        """
    +        possible_capabilities = self.service.capabilities
    +        for capability in capabilities_to_revoke:
    +            if capability not in possible_capabilities:
    +                raise NoSuchCapability(capability)
    +        old_capabilities = self['capabilities']
    +        new_capabilities = []
    +        for c in old_capabilities:
    +            if c not in capabilities_to_revoke:
    +                new_capabilities.append(c)
    +        if new_capabilities == []:
    +            new_capabilities = '' # Empty lists don't get passed in the body, so we have to force an empty argument.
    +        self.post(capabilities=new_capabilities)
    +        return self
    +
    +
    +class Roles(Collection):
    +    """This class represents the collection of roles in the Splunk instance.
    +    Retrieve this collection using :meth:`Service.roles`."""
    +    def __init__(self, service):
    +        return Collection.__init__(self, service, PATH_ROLES, item=Role)
    +
    +    def __getitem__(self, key):
    +        return Collection.__getitem__(self, key.lower())
    +
    +    def __contains__(self, name):
    +        return Collection.__contains__(self, name.lower())
    +
    +    def create(self, name, **params):
    +        """Creates a new role.
    +
    +        This function makes two roundtrips to the server, plus at most
    +        two more if
    +        the ``autologin`` field of :func:`connect` is set to ``True``.
    +
    +        :param name: Name for the role.
    +        :type name: ``string``
    +        :param params: Additional arguments (optional). For a list of available
    +            parameters, see `Roles parameters
    +            <http://dev.splunk.com/view/SP-CAAAEJ6#rolesparams>`_
    +            on Splunk Developer Portal.
    +        :type params: ``dict``
    +
    +        :return: The new role.
    +        :rtype: :class:`Role`
    +
    +        **Example**::
    +
    +            import splunklib.client as client
    +            c = client.connect(...)
    +            roles = c.roles
    +            paltry = roles.create("paltry", imported_roles="user", defaultApp="search")
    +        """
    +        if not isinstance(name, six.string_types):
    +            raise ValueError("Invalid role name: %s" % str(name))
    +        name = name.lower()
    +        self.post(name=name, **params)
    +        # splunkd doesn't return the user in the POST response body,
    +        # so we have to make a second round trip to fetch it.
    +        response = self.get(name)
    +        entry = _load_atom(response, XNAME_ENTRY).entry
    +        state = _parse_atom_entry(entry)
    +        entity = self.item(
    +            self.service,
    +            urllib.parse.unquote(state.links.alternate),
    +            state=state)
    +        return entity
    +
    +    def delete(self, name):
    +        """ Deletes the role and returns the resulting collection of roles.
    +
    +        :param name: The name of the role to delete.
    +        :type name: ``string``
    +
    +        :rtype: The :class:`Roles`
    +        """
    +        return Collection.delete(self, name.lower())
    +
    +
    +class Application(Entity):
    +    """Represents a locally-installed Splunk app."""
    +    @property
    +    def setupInfo(self):
    +        """Returns the setup information for the app.
    +
    +        :return: The setup information.
    +        """
    +        return self.content.get('eai:setup', None)
    +
    +    def package(self):
    +        """ Creates a compressed package of the app for archiving."""
    +        return self._run_action("package")
    +
    +    def updateInfo(self):
    +        """Returns any update information that is available for the app."""
    +        return self._run_action("update")
    +
    +class KVStoreCollections(Collection):
    +    def __init__(self, service):
    +        Collection.__init__(self, service, 'storage/collections/config', item=KVStoreCollection)
    +
    +    def __getitem__(self, item):
    +        res = Collection.__getitem__(self, item)
    +        for k, v in res.content.items():
    +            if "accelerated_fields" in k:
    +                res.content[k] = json.loads(v)
    +        return res
    +
    +    def create(self, name, accelerated_fields={}, fields={}, **kwargs):
    +        """Creates a KV Store Collection.
    +
    +        :param name: name of collection to create
    +        :type name: ``string``
    +        :param accelerated_fields: dictionary of accelerated_fields definitions
    +        :type accelerated_fields: ``dict``
    +        :param fields: dictionary of field definitions
    +        :type fields: ``dict``
    +        :param kwargs: a dictionary of additional parameters specifying indexes and field definitions
    +        :type kwargs: ``dict``
    +
    +        :return: Result of POST request
    +        """
    +        for k, v in six.iteritems(accelerated_fields):
    +            if isinstance(v, dict):
    +                v = json.dumps(v)
    +            kwargs['accelerated_fields.' + k] = v
    +        for k, v in six.iteritems(fields):
    +            kwargs['field.' + k] = v
    +        return self.post(name=name, **kwargs)
    +
    +class KVStoreCollection(Entity):
    +    @property
    +    def data(self):
    +        """Returns data object for this Collection.
    +
    +        :rtype: :class:`KVStoreCollectionData`
    +        """
    +        return KVStoreCollectionData(self)
    +
    +    def update_accelerated_field(self, name, value):
    +        """Changes the definition of a KV Store accelerated_field.
    +
    +        :param name: name of accelerated_fields to change
    +        :type name: ``string``
    +        :param value: new accelerated_fields definition
    +        :type value: ``dict``
    +
    +        :return: Result of POST request
    +        """
    +        kwargs = {}
    +        if isinstance(value, dict):
    +            value = json.dumps(value)
    +        kwargs['accelerated_fields.' + name] = value
    +        return self.post(**kwargs)
    +
    +    def update_field(self, name, value):
    +        """Changes the definition of a KV Store field.
    +
    +        :param name: name of field to change
    +        :type name: ``string``
    +        :param value: new field definition
    +        :type value: ``string``
    +
    +        :return: Result of POST request
    +        """
    +        kwargs = {}
    +        kwargs['field.' + name] = value
    +        return self.post(**kwargs)
    +
    +class KVStoreCollectionData(object):
    +    """This class represents the data endpoint for a KVStoreCollection.
    +
    +    Retrieve using :meth:`KVStoreCollection.data`
    +    """
    +    JSON_HEADER = [('Content-Type', 'application/json')]
    +
    +    def __init__(self, collection):
    +        self.service = collection.service
    +        self.collection = collection
    +        self.owner, self.app, self.sharing = collection._proper_namespace()
    +        self.path = 'storage/collections/data/' + UrlEncoded(self.collection.name, encode_slash=True) + '/'
    +
    +    def _get(self, url, **kwargs):
    +        return self.service.get(self.path + url, owner=self.owner, app=self.app, sharing=self.sharing, **kwargs)
    +
    +    def _post(self, url, **kwargs):
    +        return self.service.post(self.path + url, owner=self.owner, app=self.app, sharing=self.sharing, **kwargs)
    +
    +    def _delete(self, url, **kwargs):
    +        return self.service.delete(self.path + url, owner=self.owner, app=self.app, sharing=self.sharing, **kwargs)
    +
    +    def query(self, **query):
    +        """
    +        Gets the results of query, with optional parameters sort, limit, skip, and fields.
    +
    +        :param query: Optional parameters. Valid options are sort, limit, skip, and fields
    +        :type query: ``dict``
    +
    +        :return: Array of documents retrieved by query.
    +        :rtype: ``array``
    +        """
    +
    +        for key, value in query.items():
    +            if isinstance(query[key], dict):
    +                query[key] = json.dumps(value)
    +
    +        return json.loads(self._get('', **query).body.read().decode('utf-8'))
    +
    +    def query_by_id(self, id):
    +        """
    +        Returns object with _id = id.
    +
    +        :param id: Value for ID. If not a string will be coerced to string.
    +        :type id: ``string``
    +
    +        :return: Document with id
    +        :rtype: ``dict``
    +        """
    +        return json.loads(self._get(UrlEncoded(str(id), encode_slash=True)).body.read().decode('utf-8'))
    +
    +    def insert(self, data):
    +        """
    +        Inserts item into this collection. An _id field will be generated if not assigned in the data.
    +
    +        :param data: Document to insert
    +        :type data: ``string``
    +
    +        :return: _id of inserted object
    +        :rtype: ``dict``
    +        """
    +        if isinstance(data, dict):
    +            data = json.dumps(data)
    +        return json.loads(self._post('', headers=KVStoreCollectionData.JSON_HEADER, body=data).body.read().decode('utf-8'))
    +
    +    def delete(self, query=None):
    +        """
    +        Deletes all data in collection if query is absent. Otherwise, deletes all data matched by query.
    +
    +        :param query: Query to select documents to delete
    +        :type query: ``string``
    +
    +        :return: Result of DELETE request
    +        """
    +        return self._delete('', **({'query': query}) if query else {})
    +
    +    def delete_by_id(self, id):
    +        """
    +        Deletes document that has _id = id.
    +
    +        :param id: id of document to delete
    +        :type id: ``string``
    +
    +        :return: Result of DELETE request
    +        """
    +        return self._delete(UrlEncoded(str(id), encode_slash=True))
    +
    +    def update(self, id, data):
    +        """
    +        Replaces document with _id = id with data.
    +
    +        :param id: _id of document to update
    +        :type id: ``string``
    +        :param data: the new document to insert
    +        :type data: ``string``
    +
    +        :return: id of replaced document
    +        :rtype: ``dict``
    +        """
    +        if isinstance(data, dict):
    +            data = json.dumps(data)
    +        return json.loads(self._post(UrlEncoded(str(id), encode_slash=True), headers=KVStoreCollectionData.JSON_HEADER, body=data).body.read().decode('utf-8'))
    +
    +    def batch_find(self, *dbqueries):
    +        """
    +        Returns array of results from queries dbqueries.
    +
    +        :param dbqueries: Array of individual queries as dictionaries
    +        :type dbqueries: ``array`` of ``dict``
    +
    +        :return: Results of each query
    +        :rtype: ``array`` of ``array``
    +        """
    +        if len(dbqueries) < 1:
    +            raise Exception('Must have at least one query.')
    +
    +        data = json.dumps(dbqueries)
    +
    +        return json.loads(self._post('batch_find', headers=KVStoreCollectionData.JSON_HEADER, body=data).body.read().decode('utf-8'))
    +
    +    def batch_save(self, *documents):
    +        """
    +        Inserts or updates every document specified in documents.
    +
    +        :param documents: Array of documents to save as dictionaries
    +        :type documents: ``array`` of ``dict``
    +
    +        :return: Results of update operation as overall stats
    +        :rtype: ``dict``
    +        """
    +        if len(documents) < 1:
    +            raise Exception('Must have at least one document.')
    +
    +        data = json.dumps(documents)
    +
    +        return json.loads(self._post('batch_save', headers=KVStoreCollectionData.JSON_HEADER, body=data).body.read().decode('utf-8'))
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/data.py b/deployment-apps/metricator-for-nmon/lib/splunklib/data.py
    new file mode 100644
    index 0000000..f9ffb86
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/data.py
    @@ -0,0 +1,266 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +"""The **splunklib.data** module reads the responses from splunkd in Atom Feed 
    +format, which is the format used by most of the REST API.
    +"""
    +
    +from __future__ import absolute_import
    +import sys
    +from xml.etree.ElementTree import XML
    +from splunklib import six
    +
    +__all__ = ["load"]
    +
    +# LNAME refers to element names without namespaces; XNAME is the same
    +# name, but with an XML namespace.
    +LNAME_DICT = "dict"
    +LNAME_ITEM = "item"
    +LNAME_KEY = "key"
    +LNAME_LIST = "list"
    +
    +XNAMEF_REST = "{http://dev.splunk.com/ns/rest}%s"
    +XNAME_DICT = XNAMEF_REST % LNAME_DICT
    +XNAME_ITEM = XNAMEF_REST % LNAME_ITEM
    +XNAME_KEY = XNAMEF_REST % LNAME_KEY
    +XNAME_LIST = XNAMEF_REST % LNAME_LIST
    +
    +# Some responses don't use namespaces (eg: search/parse) so we look for
    +# both the extended and local versions of the following names.
    +
    +def isdict(name):
    +    return name == XNAME_DICT or name == LNAME_DICT
    +
    +def isitem(name):
    +    return name == XNAME_ITEM or name == LNAME_ITEM
    +
    +def iskey(name):
    +    return name == XNAME_KEY or name == LNAME_KEY
    +
    +def islist(name):
    +    return name == XNAME_LIST or name == LNAME_LIST
    +
    +def hasattrs(element):
    +    return len(element.attrib) > 0
    +
    +def localname(xname):
    +    rcurly = xname.find('}')
    +    return xname if rcurly == -1 else xname[rcurly+1:]
    +
    +def load(text, match=None):
    +    """This function reads a string that contains the XML of an Atom Feed, then 
    +    returns the 
    +    data in a native Python structure (a ``dict`` or ``list``). If you also 
    +    provide a tag name or path to match, only the matching sub-elements are 
    +    loaded.
    +
    +    :param text: The XML text to load.
    +    :type text: ``string``
    +    :param match: A tag name or path to match (optional).
    +    :type match: ``string``
    +    """
    +    if text is None: return None
    +    text = text.strip()
    +    if len(text) == 0: return None
    +    nametable = {
    +        'namespaces': [],
    +        'names': {}
    +    }
    +
    +    # Convert to unicode encoding in only python 2 for xml parser
    +    if(sys.version_info < (3, 0, 0) and isinstance(text, unicode)):
    +        text = text.encode('utf-8')
    +
    +    root = XML(text)
    +    items = [root] if match is None else root.findall(match)
    +    count = len(items)
    +    if count == 0: 
    +        return None
    +    elif count == 1: 
    +        return load_root(items[0], nametable)
    +    else:
    +        return [load_root(item, nametable) for item in items]
    +
    +# Load the attributes of the given element.
    +def load_attrs(element):
    +    if not hasattrs(element): return None
    +    attrs = record()
    +    for key, value in six.iteritems(element.attrib): 
    +        attrs[key] = value
    +    return attrs
    +
    +# Parse a <dict> element and return a Python dict
    +def load_dict(element, nametable = None):
    +    value = record()
    +    children = list(element)
    +    for child in children:
    +        assert iskey(child.tag)
    +        name = child.attrib["name"]
    +        value[name] = load_value(child, nametable)
    +    return value
    +
    +# Loads the given elements attrs & value into single merged dict.
    +def load_elem(element, nametable=None):
    +    name = localname(element.tag)
    +    attrs = load_attrs(element)
    +    value = load_value(element, nametable)
    +    if attrs is None: return name, value
    +    if value is None: return name, attrs
    +    # If value is simple, merge into attrs dict using special key
    +    if isinstance(value, six.string_types):
    +        attrs["$text"] = value
    +        return name, attrs
    +    # Both attrs & value are complex, so merge the two dicts, resolving collisions.
    +    collision_keys = []
    +    for key, val in six.iteritems(attrs):
    +        if key in value and key in collision_keys:
    +            value[key].append(val)
    +        elif key in value and key not in collision_keys:
    +            value[key] = [value[key], val]
    +            collision_keys.append(key)
    +        else:
    +            value[key] = val
    +    return name, value
    +
    +# Parse a <list> element and return a Python list
    +def load_list(element, nametable=None):
    +    assert islist(element.tag)
    +    value = []
    +    children = list(element)
    +    for child in children:
    +        assert isitem(child.tag)
    +        value.append(load_value(child, nametable))
    +    return value
    +
    +# Load the given root element.
    +def load_root(element, nametable=None):
    +    tag = element.tag
    +    if isdict(tag): return load_dict(element, nametable)
    +    if islist(tag): return load_list(element, nametable)
    +    k, v = load_elem(element, nametable)
    +    return Record.fromkv(k, v)
    +
    +# Load the children of the given element.
    +def load_value(element, nametable=None):
    +    children = list(element)
    +    count = len(children)
    +
    +    # No children, assume a simple text value
    +    if count == 0:
    +        text = element.text
    +        if text is None: 
    +            return None
    +
    +        if len(text.strip()) == 0:
    +            return None
    +        return text
    +
    +    # Look for the special case of a single well-known structure
    +    if count == 1:
    +        child = children[0]
    +        tag = child.tag
    +        if isdict(tag): return load_dict(child, nametable)
    +        if islist(tag): return load_list(child, nametable)
    +
    +    value = record()
    +    for child in children:
    +        name, item = load_elem(child, nametable)
    +        # If we have seen this name before, promote the value to a list
    +        if name in value:
    +            current = value[name]
    +            if not isinstance(current, list): 
    +                value[name] = [current]
    +            value[name].append(item)
    +        else:
    +            value[name] = item
    +
    +    return value
    +
    +# A generic utility that enables "dot" access to dicts
    +class Record(dict):
    +    """This generic utility class enables dot access to members of a Python 
    +    dictionary.
    +
    +    Any key that is also a valid Python identifier can be retrieved as a field. 
    +    So, for an instance of ``Record`` called ``r``, ``r.key`` is equivalent to 
    +    ``r['key']``. A key such as ``invalid-key`` or ``invalid.key`` cannot be 
    +    retrieved as a field, because ``-`` and ``.`` are not allowed in 
    +    identifiers.
    +
    +    Keys of the form ``a.b.c`` are very natural to write in Python as fields. If 
    +    a group of keys shares a prefix ending in ``.``, you can retrieve keys as a 
    +    nested dictionary by calling only the prefix. For example, if ``r`` contains
    +    keys ``'foo'``, ``'bar.baz'``, and ``'bar.qux'``, ``r.bar`` returns a record
    +    with the keys ``baz`` and ``qux``. If a key contains multiple ``.``, each 
    +    one is placed into a nested dictionary, so you can write ``r.bar.qux`` or 
    +    ``r['bar.qux']`` interchangeably.
    +    """
    +    sep = '.'
    +
    +    def __call__(self, *args):
    +        if len(args) == 0: return self
    +        return Record((key, self[key]) for key in args)
    +
    +    def __getattr__(self, name):
    +        try:
    +            return self[name]
    +        except KeyError: 
    +            raise AttributeError(name)
    +
    +    def __delattr__(self, name):
    +        del self[name]
    +
    +    def __setattr__(self, name, value):
    +        self[name] = value
    +
    +    @staticmethod
    +    def fromkv(k, v):
    +        result = record()
    +        result[k] = v
    +        return result
    +
    +    def __getitem__(self, key):
    +        if key in self:
    +            return dict.__getitem__(self, key)
    +        key += self.sep
    +        result = record()
    +        for k,v in six.iteritems(self):
    +            if not k.startswith(key):
    +                continue
    +            suffix = k[len(key):]
    +            if '.' in suffix:
    +                ks = suffix.split(self.sep)
    +                z = result
    +                for x in ks[:-1]:
    +                    if x not in z:
    +                        z[x] = record()
    +                    z = z[x]
    +                z[ks[-1]] = v
    +            else:
    +                result[suffix] = v
    +        if len(result) == 0:
    +            raise KeyError("No key or prefix: %s" % key)
    +        return result
    +    
    +
    +def record(value=None): 
    +    """This function returns a :class:`Record` instance constructed with an 
    +    initial value that you provide.
    +    
    +    :param `value`: An initial record value.
    +    :type `value`: ``dict``
    +    """
    +    if value is None: value = {}
    +    return Record(value)
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/__init__.py
    new file mode 100644
    index 0000000..ace954a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/__init__.py
    @@ -0,0 +1,12 @@
    +"""The following imports allow these classes to be imported via
    +the splunklib.modularinput package like so:
    +
    +from splunklib.modularinput import *
    +"""
    +from .argument import Argument
    +from .event import Event
    +from .event_writer import EventWriter
    +from .input_definition import InputDefinition
    +from .scheme import Scheme
    +from .script import Script
    +from .validation_definition import ValidationDefinition
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/argument.py b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/argument.py
    new file mode 100644
    index 0000000..04214d1
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/argument.py
    @@ -0,0 +1,103 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import
    +try:
    +    import xml.etree.ElementTree as ET
    +except ImportError:
    +    import xml.etree.cElementTree as ET
    +
    +class Argument(object):
    +    """Class representing an argument to a modular input kind.
    +
    +    ``Argument`` is meant to be used with ``Scheme`` to generate an XML 
    +    definition of the modular input kind that Splunk understands.
    +
    +    ``name`` is the only required parameter for the constructor.
    +
    +        **Example with least parameters**::
    +
    +            arg1 = Argument(name="arg1")
    +
    +        **Example with all parameters**::
    +
    +            arg2 = Argument(
    +                name="arg2",
    +                description="This is an argument with lots of parameters",
    +                validation="is_pos_int('some_name')",
    +                data_type=Argument.data_type_number,
    +                required_on_edit=True,
    +                required_on_create=True
    +            )
    +    """
    +
    +    # Constant values, do not change.
    +    # These should be used for setting the value of an Argument object's data_type field.
    +    data_type_boolean = "BOOLEAN"
    +    data_type_number = "NUMBER"
    +    data_type_string = "STRING"
    +
    +    def __init__(self, name, description=None, validation=None,
    +                 data_type=data_type_string, required_on_edit=False, required_on_create=False, title=None):
    +        """
    +        :param name: ``string``, identifier for this argument in Splunk.
    +        :param description: ``string``, human-readable description of the argument.
    +        :param validation: ``string`` specifying how the argument should be validated, if using internal validation.
    +               If using external validation, this will be ignored.
    +        :param data_type: ``string``, data type of this field; use the class constants.
    +               "data_type_boolean", "data_type_number", or "data_type_string".
    +        :param required_on_edit: ``Boolean``, whether this arg is required when editing an existing modular input of this kind.
    +        :param required_on_create: ``Boolean``, whether this arg is required when creating a modular input of this kind.
    +        :param title: ``String``, a human-readable title for the argument.
    +        """
    +        self.name = name
    +        self.description = description
    +        self.validation = validation
    +        self.data_type = data_type
    +        self.required_on_edit = required_on_edit
    +        self.required_on_create = required_on_create
    +        self.title = title
    +
    +    def add_to_document(self, parent):
    +        """Adds an ``Argument`` object to this ElementTree document.
    +
    +        Adds an <arg> subelement to the parent element, typically <args>
    +        and sets up its subelements with their respective text.
    +
    +        :param parent: An ``ET.Element`` to be the parent of a new <arg> subelement
    +        :returns: An ``ET.Element`` object representing this argument.
    +        """
    +        arg = ET.SubElement(parent, "arg")
    +        arg.set("name", self.name)
    +
    +        if self.title is not None:
    +            ET.SubElement(arg, "title").text = self.title
    +
    +        if self.description is not None:
    +            ET.SubElement(arg, "description").text = self.description
    +
    +        if self.validation is not None:
    +            ET.SubElement(arg, "validation").text = self.validation
    +
    +        # add all other subelements to this Argument, represented by (tag, text)
    +        subelements = [
    +            ("data_type", self.data_type),
    +            ("required_on_edit", self.required_on_edit),
    +            ("required_on_create", self.required_on_create)
    +        ]
    +
    +        for name, value in subelements:
    +            ET.SubElement(arg, name).text = str(value).lower()
    +
    +        return arg
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/event.py b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/event.py
    new file mode 100644
    index 0000000..9cd6cf3
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/event.py
    @@ -0,0 +1,114 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import
    +from io import TextIOBase
    +from splunklib.six import ensure_text
    +
    +try:
    +    import xml.etree.cElementTree as ET
    +except ImportError as ie:
    +    import xml.etree.ElementTree as ET
    +
    +class Event(object):
    +    """Represents an event or fragment of an event to be written by this modular input to Splunk.
    +
    +    To write an input to a stream, call the ``write_to`` function, passing in a stream.
    +    """
    +    def __init__(self, data=None, stanza=None, time=None, host=None, index=None, source=None,
    +                 sourcetype=None, done=True, unbroken=True):
    +        """There are no required parameters for constructing an Event
    +
    +        **Example with minimal configuration**::
    +
    +            my_event = Event(
    +                data="This is a test of my new event.",
    +                stanza="myStanzaName",
    +                time="%.3f" % 1372187084.000
    +            )
    +
    +        **Example with full configuration**::
    +
    +            excellent_event = Event(
    +                data="This is a test of my excellent event.",
    +                stanza="excellenceOnly",
    +                time="%.3f" % 1372274622.493,
    +                host="localhost",
    +                index="main",
    +                source="Splunk",
    +                sourcetype="misc",
    +                done=True,
    +                unbroken=True
    +            )
    +
    +        :param data: ``string``, the event's text.
    +        :param stanza: ``string``, name of the input this event should be sent to.
    +        :param time: ``float``, time in seconds, including up to 3 decimal places to represent milliseconds.
    +        :param host: ``string``, the event's host, ex: localhost.
    +        :param index: ``string``, the index this event is specified to write to, or None if default index.
    +        :param source: ``string``, the source of this event, or None to have Splunk guess.
    +        :param sourcetype: ``string``, source type currently set on this event, or None to have Splunk guess.
    +        :param done: ``boolean``, is this a complete ``Event``? False if an ``Event`` fragment.
    +        :param unbroken: ``boolean``, Is this event completely encapsulated in this ``Event`` object?
    +        """
    +        self.data = data
    +        self.done = done
    +        self.host = host
    +        self.index = index
    +        self.source = source
    +        self.sourceType = sourcetype
    +        self.stanza = stanza
    +        self.time = time
    +        self.unbroken = unbroken
    +
    +    def write_to(self, stream):
    +        """Write an XML representation of self, an ``Event`` object, to the given stream.
    +
    +        The ``Event`` object will only be written if its data field is defined,
    +        otherwise a ``ValueError`` is raised.
    +
    +        :param stream: stream to write XML to.
    +        """
    +        if self.data is None:
    +            raise ValueError("Events must have at least the data field set to be written to XML.")
    +
    +        event = ET.Element("event")
    +        if self.stanza is not None:
    +            event.set("stanza", self.stanza)
    +        event.set("unbroken", str(int(self.unbroken)))
    +
    +        # if a time isn't set, let Splunk guess by not creating a <time> element
    +        if self.time is not None:
    +            ET.SubElement(event, "time").text = str(self.time)
    +
    +        # add all other subelements to this Event, represented by (tag, text)
    +        subelements = [
    +            ("source", self.source),
    +            ("sourcetype", self.sourceType),
    +            ("index", self.index),
    +            ("host", self.host),
    +            ("data", self.data)
    +        ]
    +        for node, value in subelements:
    +            if value is not None:
    +                ET.SubElement(event, node).text = value
    +
    +        if self.done:
    +            ET.SubElement(event, "done")
    +
    +        if isinstance(stream, TextIOBase):
    +            stream.write(ensure_text(ET.tostring(event)))
    +        else:
    +            stream.write(ET.tostring(event))
    +        stream.flush()
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/event_writer.py b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/event_writer.py
    new file mode 100644
    index 0000000..5f8c5aa
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/event_writer.py
    @@ -0,0 +1,87 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import
    +import sys
    +
    +from splunklib.six import ensure_str
    +from .event import ET
    +
    +try:
    +    from splunklib.six.moves import cStringIO as StringIO
    +except ImportError:
    +    from splunklib.six import StringIO
    +
    +class EventWriter(object):
    +    """``EventWriter`` writes events and error messages to Splunk from a modular input.
    +    Its two important methods are ``writeEvent``, which takes an ``Event`` object,
    +    and ``log``, which takes a severity and an error message.
    +    """
    +
    +    # Severities that Splunk understands for log messages from modular inputs.
    +    # Do not change these
    +    DEBUG = "DEBUG"
    +    INFO = "INFO"
    +    WARN = "WARN"
    +    ERROR = "ERROR"
    +    FATAL = "FATAL"
    +
    +    def __init__(self, output = sys.stdout, error = sys.stderr):
    +        """
    +        :param output: Where to write the output; defaults to sys.stdout.
    +        :param error: Where to write any errors; defaults to sys.stderr.
    +        """
    +        self._out = output
    +        self._err = error
    +
    +        # has the opening <stream> tag been written yet?
    +        self.header_written = False
    +
    +    def write_event(self, event):
    +        """Writes an ``Event`` object to Splunk.
    +
    +        :param event: An ``Event`` object.
    +        """
    +
    +        if not self.header_written:
    +            self._out.write("<stream>")
    +            self.header_written = True
    +
    +        event.write_to(self._out)
    +
    +    def log(self, severity, message):
    +        """Logs messages about the state of this modular input to Splunk.
    +        These messages will show up in Splunk's internal logs.
    +
    +        :param severity: ``string``, severity of message, see severities defined as class constants.
    +        :param message: ``string``, message to log.
    +        """
    +
    +        self._err.write("%s %s\n" % (severity, message))
    +        self._err.flush()
    +
    +    def write_xml_document(self, document):
    +        """Writes a string representation of an
    +        ``ElementTree`` object to the output stream.
    +
    +        :param document: An ``ElementTree`` object.
    +        """
    +        self._out.write(ensure_str(ET.tostring(document)))
    +        self._out.flush()
    +
    +    def close(self):
    +        """Write the closing </stream> tag to make this XML well formed."""
    +        if self.header_written:
    +          self._out.write("</stream>")
    +        self._out.flush()
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/input_definition.py b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/input_definition.py
    new file mode 100644
    index 0000000..fdc7cbb
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/input_definition.py
    @@ -0,0 +1,60 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import
    +try:
    +    import xml.etree.cElementTree as ET
    +except ImportError as ie:
    +    import xml.etree.ElementTree as ET
    +
    +from .utils import parse_xml_data
    +
    +class InputDefinition:
    +    """``InputDefinition`` encodes the XML defining inputs that Splunk passes to
    +    a modular input script.
    +
    +     **Example**::
    +
    +        i = InputDefinition()
    +
    +    """
    +    def __init__ (self):
    +        self.metadata = {}
    +        self.inputs = {}
    +
    +    def __eq__(self, other):
    +        if not isinstance(other, InputDefinition):
    +            return False
    +        return self.metadata == other.metadata and self.inputs == other.inputs
    +
    +    @staticmethod
    +    def parse(stream):
    +        """Parse a stream containing XML into an ``InputDefinition``.
    +
    +        :param stream: stream containing XML to parse.
    +        :return: definition: an ``InputDefinition`` object.
    +        """
    +        definition = InputDefinition()
    +
    +        # parse XML from the stream, then get the root node
    +        root = ET.parse(stream).getroot()
    +
    +        for node in root:
    +            if node.tag == "configuration":
    +                # get config for each stanza
    +                definition.inputs = parse_xml_data(node, "stanza")
    +            else:
    +                definition.metadata[node.tag] = node.text
    +
    +        return definition
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/scheme.py b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/scheme.py
    new file mode 100644
    index 0000000..4104e4a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/scheme.py
    @@ -0,0 +1,85 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import
    +try:
    +    import xml.etree.cElementTree as ET
    +except ImportError:
    +    import xml.etree.ElementTree as ET
    +
    +class Scheme(object):
    +    """Class representing the metadata for a modular input kind.
    +
    +    A ``Scheme`` specifies a title, description, several options of how Splunk should run modular inputs of this
    +    kind, and a set of arguments which define a particular modular input's properties.
    +
    +    The primary use of ``Scheme`` is to abstract away the construction of XML to feed to Splunk.
    +    """
    +
    +    # Constant values, do not change
    +    # These should be used for setting the value of a Scheme object's streaming_mode field.
    +    streaming_mode_simple = "SIMPLE"
    +    streaming_mode_xml = "XML"
    +
    +    def __init__(self, title):
    +        """
    +        :param title: ``string`` identifier for this Scheme in Splunk.
    +        """
    +        self.title = title
    +        self.description = None
    +        self.use_external_validation = True
    +        self.use_single_instance = False
    +        self.streaming_mode = Scheme.streaming_mode_xml
    +
    +        # list of Argument objects, each to be represented by an <arg> tag
    +        self.arguments = []
    +
    +    def add_argument(self, arg):
    +        """Add the provided argument, ``arg``, to the ``self.arguments`` list.
    +
    +        :param arg: An ``Argument`` object to add to ``self.arguments``.
    +        """
    +        self.arguments.append(arg)
    +
    +    def to_xml(self):
    +        """Creates an ``ET.Element`` representing self, then returns it.
    +
    +        :returns: an ``ET.Element`` representing this scheme.
    +        """
    +        root = ET.Element("scheme")
    +
    +        ET.SubElement(root, "title").text = self.title
    +
    +        # add a description subelement if it's defined
    +        if self.description is not None:
    +            ET.SubElement(root, "description").text = self.description
    +
    +        # add all other subelements to this Scheme, represented by (tag, text)
    +        subelements = [
    +            ("use_external_validation", self.use_external_validation),
    +            ("use_single_instance", self.use_single_instance),
    +            ("streaming_mode", self.streaming_mode)
    +        ]
    +        for name, value in subelements:
    +            ET.SubElement(root, name).text = str(value).lower()
    +
    +        endpoint = ET.SubElement(root, "endpoint")
    +
    +        args = ET.SubElement(endpoint, "args")
    +
    +        # add arguments as subelements to the <args> element
    +        for arg in self.arguments:
    +            arg.add_to_document(args)
    +
    +        return root
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/script.py b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/script.py
    new file mode 100644
    index 0000000..8595dc4
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/script.py
    @@ -0,0 +1,177 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import
    +from abc import ABCMeta, abstractmethod
    +from splunklib.six.moves.urllib.parse import urlsplit
    +import sys
    +
    +from ..client import Service
    +from .event_writer import EventWriter
    +from .input_definition import InputDefinition
    +from .validation_definition import ValidationDefinition
    +from splunklib import six
    +
    +try:
    +    import xml.etree.cElementTree as ET
    +except ImportError:
    +    import xml.etree.ElementTree as ET
    +
    +
    +class Script(six.with_metaclass(ABCMeta, object)):
    +    """An abstract base class for implementing modular inputs.
    +
    +    Subclasses should override ``get_scheme``, ``stream_events``,
    +    and optionally ``validate_input`` if the modular input uses
    +    external validation.
    +
    +    The ``run`` function is used to run modular inputs; it typically should
    +    not be overridden.
    +    """
    +
    +    def __init__(self):
    +        self._input_definition = None
    +        self._service = None
    +
    +    def run(self, args):
    +        """Runs this modular input
    +
    +        :param args: List of command line arguments passed to this script.
    +        :returns: An integer to be used as the exit value of this program.
    +        """
    +
    +        # call the run_script function, which handles the specifics of running
    +        # a modular input
    +        return self.run_script(args, EventWriter(), sys.stdin)
    +
    +    def run_script(self, args, event_writer, input_stream):
    +        """Handles all the specifics of running a modular input
    +
    +        :param args: List of command line arguments passed to this script.
    +        :param event_writer: An ``EventWriter`` object for writing events.
    +        :param input_stream: An input stream for reading inputs.
    +        :returns: An integer to be used as the exit value of this program.
    +        """
    +
    +        try:
    +            if len(args) == 1:
    +                # This script is running as an input. Input definitions will be
    +                # passed on stdin as XML, and the script will write events on
    +                # stdout and log entries on stderr.
    +                self._input_definition = InputDefinition.parse(input_stream)
    +                self.stream_events(self._input_definition, event_writer)
    +                event_writer.close()
    +                return 0
    +
    +            elif str(args[1]).lower() == "--scheme":
    +                # Splunk has requested XML specifying the scheme for this
    +                # modular input Return it and exit.
    +                scheme = self.get_scheme()
    +                if scheme is None:
    +                    event_writer.log(
    +                        EventWriter.FATAL,
    +                        "Modular input script returned a null scheme.")
    +                    return 1
    +                else:
    +                    event_writer.write_xml_document(scheme.to_xml())
    +                    return 0
    +
    +            elif args[1].lower() == "--validate-arguments":
    +                validation_definition = ValidationDefinition.parse(input_stream)
    +                try:
    +                    self.validate_input(validation_definition)
    +                    return 0
    +                except Exception as e:
    +                    root = ET.Element("error")
    +                    ET.SubElement(root, "message").text = str(e)
    +                    event_writer.write_xml_document(root)
    +
    +                    return 1
    +            else:
    +                err_string = "ERROR Invalid arguments to modular input script:" + ' '.join(
    +                    args)
    +                event_writer._err.write(err_string)
    +                return 1
    +
    +        except Exception as e:
    +            event_writer.log(EventWriter.ERROR, str(e))
    +            return 1
    +
    +    @property
    +    def service(self):
    +        """ Returns a Splunk service object for this script invocation.
    +
    +        The service object is created from the Splunkd URI and session key
    +        passed to the command invocation on the modular input stream. It is
    +        available as soon as the :code:`Script.stream_events` method is
    +        called.
    +
    +        :return: :class:`splunklib.client.Service`. A value of None is returned,
    +            if you call this method before the :code:`Script.stream_events` method
    +            is called.
    +
    +        """
    +        if self._service is not None:
    +            return self._service
    +
    +        if self._input_definition is None:
    +            return None
    +
    +        splunkd_uri = self._input_definition.metadata["server_uri"]
    +        session_key = self._input_definition.metadata["session_key"]
    +
    +        splunkd = urlsplit(splunkd_uri, allow_fragments=False)
    +
    +        self._service = Service(
    +            scheme=splunkd.scheme,
    +            host=splunkd.hostname,
    +            port=splunkd.port,
    +            token=session_key,
    +        )
    +
    +        return self._service
    +
    +    @abstractmethod
    +    def get_scheme(self):
    +        """The scheme defines the parameters understood by this modular input.
    +
    +        :return: a ``Scheme`` object representing the parameters for this modular input.
    +        """
    +
    +    def validate_input(self, definition):
    +        """Handles external validation for modular input kinds.
    +
    +        When Splunk calls a modular input script in validation mode, it will
    +        pass in an XML document giving information about the Splunk instance (so
    +        you can call back into it if needed) and the name and parameters of the
    +        proposed input.
    +
    +        If this function does not throw an exception, the validation is assumed
    +        to succeed. Otherwise any errors thrown will be turned into a string and
    +        logged back to Splunk.
    +
    +        The default implementation always passes.
    +
    +        :param definition: The parameters for the proposed input passed by splunkd.
    +        """
    +        pass
    +
    +    @abstractmethod
    +    def stream_events(self, inputs, ew):
    +        """The method called to stream events into Splunk. It should do all of its output via
    +        EventWriter rather than assuming that there is a console attached.
    +
    +        :param inputs: An ``InputDefinition`` object.
    +        :param ew: An object with methods to write events and log messages to Splunk.
    +        """
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/utils.py b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/utils.py
    new file mode 100644
    index 0000000..3d42b63
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/utils.py
    @@ -0,0 +1,77 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +# File for utility functions
    +
    +from __future__ import absolute_import
    +from splunklib.six.moves import zip
    +def xml_compare(expected, found):
    +    """Checks equality of two ``ElementTree`` objects.
    +
    +    :param expected: An ``ElementTree`` object.
    +    :param found: An ``ElementTree`` object.
    +    :return: ``Boolean``, whether the two objects are equal.
    +    """
    +
    +    # if comparing the same ET object
    +    if expected == found:
    +        return True
    +
    +    # compare element attributes, ignoring order
    +    if set(expected.items()) != set(found.items()):
    +        return False
    +
    +    # check for equal number of children
    +    expected_children = list(expected)
    +    found_children = list(found)
    +    if len(expected_children) != len(found_children):
    +        return False
    +
    +    # compare children
    +    if not all([xml_compare(a, b) for a, b in zip(expected_children, found_children)]):
    +        return False
    +
    +    # compare elements, if there is no text node, return True
    +    if (expected.text is None or expected.text.strip() == "") \
    +        and (found.text is None or found.text.strip() == ""):
    +        return True
    +    else:
    +        return expected.tag == found.tag and expected.text == found.text \
    +            and expected.attrib == found.attrib
    +
    +def parse_parameters(param_node):
    +    if param_node.tag == "param":
    +        return param_node.text
    +    elif param_node.tag == "param_list":
    +        parameters = []
    +        for mvp in param_node:
    +            parameters.append(mvp.text)
    +        return parameters
    +    else:
    +        raise ValueError("Invalid configuration scheme, %s tag unexpected." % param_node.tag)
    +
    +def parse_xml_data(parent_node, child_node_tag):
    +    data = {}
    +    for child in parent_node:
    +        child_name = child.get("name")
    +        if child.tag == child_node_tag:
    +            if child_node_tag == "stanza":
    +                data[child_name] = {
    +                    "__app": child.get("app", None)
    +                }
    +                for param in child:
    +                    data[child_name][param.get("name")] = parse_parameters(param)
    +        elif "item" == parent_node.tag:
    +            data[child_name] = parse_parameters(child)
    +    return data
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/validation_definition.py b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/validation_definition.py
    new file mode 100644
    index 0000000..3bbe976
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/modularinput/validation_definition.py
    @@ -0,0 +1,86 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +
    +from __future__ import absolute_import
    +try:
    +    import xml.etree.cElementTree as ET
    +except ImportError as ie:
    +    import xml.etree.ElementTree as ET
    +
    +from .utils import parse_xml_data
    +
    +
    +class ValidationDefinition(object):
    +    """This class represents the XML sent by Splunk for external validation of a
    +    new modular input.
    +
    +    **Example**::
    +
    +        v = ValidationDefinition()
    +
    +    """
    +    def __init__(self):
    +        self.metadata = {}
    +        self.parameters = {}
    +
    +    def __eq__(self, other):
    +        if not isinstance(other, ValidationDefinition):
    +            return False
    +        return self.metadata == other.metadata and self.parameters == other.parameters
    +
    +    @staticmethod
    +    def parse(stream):
    +        """Creates a ``ValidationDefinition`` from a provided stream containing XML.
    +
    +        The XML typically will look like this:
    +
    +        ..  code-block:: xml
    +
    +            <items>
    +               <server_host>myHost</server_host>
    +                 <server_uri>https://127.0.0.1:8089</server_uri>
    +                 <session_key>123102983109283019283</session_key>
    +                 <checkpoint_dir>/opt/splunk/var/lib/splunk/modinputs</checkpoint_dir>
    +                 <item name="myScheme">
    +                   <param name="param1">value1</param>
    +                   <param_list name="param2">
    +                     <value>value2</value>
    +                     <value>value3</value>
    +                     <value>value4</value>
    +                   </param_list>
    +                 </item>
    +            </items>
    +
    +        :param stream: ``Stream`` containing XML to parse.
    +        :return: A ``ValidationDefinition`` object.
    +
    +        """
    +
    +        definition = ValidationDefinition()
    +
    +        # parse XML from the stream, then get the root node
    +        root = ET.parse(stream).getroot()
    +
    +        for node in root:
    +            # lone item node
    +            if node.tag == "item":
    +                # name from item node
    +                definition.metadata["name"] = node.get("name")
    +                definition.parameters = parse_xml_data(node, "")
    +            else:
    +                # Store anything else in metadata
    +                definition.metadata[node.tag] = node.text
    +
    +        return definition
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/results.py b/deployment-apps/metricator-for-nmon/lib/splunklib/results.py
    new file mode 100644
    index 0000000..8543ab0
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/results.py
    @@ -0,0 +1,373 @@
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +"""The **splunklib.results** module provides a streaming XML reader for Splunk
    +search results.
    +
    +Splunk search results can be returned in a variety of formats including XML,
    +JSON, and CSV. To make it easier to stream search results in XML format, they
    +are returned as a stream of XML *fragments*, not as a single XML document. This
    +module supports incrementally reading one result record at a time from such a
    +result stream. This module also provides a friendly iterator-based interface for
    +accessing search results while avoiding buffering the result set, which can be
    +very large.
    +
    +To use the reader, instantiate :class:`JSONResultsReader` on a search result stream
    +as follows:::
    +
    +    reader = ResultsReader(result_stream)
    +    for item in reader:
    +        print(item)
    +    print "Results are a preview: %s" % reader.is_preview
    +"""
    +
    +from __future__ import absolute_import
    +
    +from io import BufferedReader, BytesIO
    +
    +from splunklib import six
    +
    +from splunklib.six import deprecated
    +
    +try:
    +    import xml.etree.cElementTree as et
    +except:
    +    import xml.etree.ElementTree as et
    +
    +from collections import OrderedDict
    +from json import loads as json_loads
    +
    +try:
    +    from splunklib.six.moves import cStringIO as StringIO
    +except:
    +    from splunklib.six import StringIO
    +
    +__all__ = [
    +    "ResultsReader",
    +    "Message",
    +    "JSONResultsReader"
    +]
    +
    +
    +class Message(object):
    +    """This class represents informational messages that Splunk interleaves in the results stream.
    +
    +    ``Message`` takes two arguments: a string giving the message type (e.g., "DEBUG"), and
    +    a string giving the message itself.
    +
    +    **Example**::
    +
    +        m = Message("DEBUG", "There's something in that variable...")
    +    """
    +
    +    def __init__(self, type_, message):
    +        self.type = type_
    +        self.message = message
    +
    +    def __repr__(self):
    +        return "%s: %s" % (self.type, self.message)
    +
    +    def __eq__(self, other):
    +        return (self.type, self.message) == (other.type, other.message)
    +
    +    def __hash__(self):
    +        return hash((self.type, self.message))
    +
    +
    +class _ConcatenatedStream(object):
    +    """Lazily concatenate zero or more streams into a stream.
    +
    +    As you read from the concatenated stream, you get characters from
    +    each stream passed to ``_ConcatenatedStream``, in order.
    +
    +    **Example**::
    +
    +        from StringIO import StringIO
    +        s = _ConcatenatedStream(StringIO("abc"), StringIO("def"))
    +        assert s.read() == "abcdef"
    +    """
    +
    +    def __init__(self, *streams):
    +        self.streams = list(streams)
    +
    +    def read(self, n=None):
    +        """Read at most *n* characters from this stream.
    +
    +        If *n* is ``None``, return all available characters.
    +        """
    +        response = b""
    +        while len(self.streams) > 0 and (n is None or n > 0):
    +            txt = self.streams[0].read(n)
    +            response += txt
    +            if n is not None:
    +                n -= len(txt)
    +            if n is None or n > 0:
    +                del self.streams[0]
    +        return response
    +
    +
    +class _XMLDTDFilter(object):
    +    """Lazily remove all XML DTDs from a stream.
    +
    +    All substrings matching the regular expression <?[^>]*> are
    +    removed in their entirety from the stream. No regular expressions
    +    are used, however, so everything still streams properly.
    +
    +    **Example**::
    +
    +        from StringIO import StringIO
    +        s = _XMLDTDFilter("<?xml abcd><element><?xml ...></element>")
    +        assert s.read() == "<element></element>"
    +    """
    +
    +    def __init__(self, stream):
    +        self.stream = stream
    +
    +    def read(self, n=None):
    +        """Read at most *n* characters from this stream.
    +
    +        If *n* is ``None``, return all available characters.
    +        """
    +        response = b""
    +        while n is None or n > 0:
    +            c = self.stream.read(1)
    +            if c == b"":
    +                break
    +            elif c == b"<":
    +                c += self.stream.read(1)
    +                if c == b"<?":
    +                    while True:
    +                        q = self.stream.read(1)
    +                        if q == b">":
    +                            break
    +                else:
    +                    response += c
    +                    if n is not None:
    +                        n -= len(c)
    +            else:
    +                response += c
    +                if n is not None:
    +                    n -= 1
    +        return response
    +
    +
    +@deprecated("Use the JSONResultsReader function instead in conjuction with the 'output_mode' query param set to 'json'")
    +class ResultsReader(object):
    +    """This class returns dictionaries and Splunk messages from an XML results
    +    stream.
    +
    +    ``ResultsReader`` is iterable, and returns a ``dict`` for results, or a
    +    :class:`Message` object for Splunk messages. This class has one field,
    +    ``is_preview``, which is ``True`` when the results are a preview from a
    +    running search, or ``False`` when the results are from a completed search.
    +
    +    This function has no network activity other than what is implicit in the
    +    stream it operates on.
    +
    +    :param `stream`: The stream to read from (any object that supports
    +        ``.read()``).
    +
    +    **Example**::
    +
    +        import results
    +        response = ... # the body of an HTTP response
    +        reader = results.ResultsReader(response)
    +        for result in reader:
    +            if isinstance(result, dict):
    +                print "Result: %s" % result
    +            elif isinstance(result, results.Message):
    +                print "Message: %s" % result
    +        print "is_preview = %s " % reader.is_preview
    +    """
    +
    +    # Be sure to update the docstrings of client.Jobs.oneshot,
    +    # client.Job.results_preview and client.Job.results to match any
    +    # changes made to ResultsReader.
    +    #
    +    # This wouldn't be a class, just the _parse_results function below,
    +    # except that you cannot get the current generator inside the
    +    # function creating that generator. Thus it's all wrapped up for
    +    # the sake of one field.
    +    def __init__(self, stream):
    +        # The search/jobs/exports endpoint, when run with
    +        # earliest_time=rt and latest_time=rt streams a sequence of
    +        # XML documents, each containing a result, as opposed to one
    +        # results element containing lots of results. Python's XML
    +        # parsers are broken, and instead of reading one full document
    +        # and returning the stream that follows untouched, they
    +        # destroy the stream and throw an error. To get around this,
    +        # we remove all the DTD definitions inline, then wrap the
    +        # fragments in a fiction <doc> element to make the parser happy.
    +        stream = _XMLDTDFilter(stream)
    +        stream = _ConcatenatedStream(BytesIO(b"<doc>"), stream, BytesIO(b"</doc>"))
    +        self.is_preview = None
    +        self._gen = self._parse_results(stream)
    +
    +    def __iter__(self):
    +        return self
    +
    +    def next(self):
    +        return next(self._gen)
    +
    +    __next__ = next
    +
    +    def _parse_results(self, stream):
    +        """Parse results and messages out of *stream*."""
    +        result = None
    +        values = None
    +        try:
    +            for event, elem in et.iterparse(stream, events=('start', 'end')):
    +                if elem.tag == 'results' and event == 'start':
    +                    # The wrapper element is a <results preview="0|1">. We
    +                    # don't care about it except to tell is whether these
    +                    # are preview results, or the final results from the
    +                    # search.
    +                    is_preview = elem.attrib['preview'] == '1'
    +                    self.is_preview = is_preview
    +                if elem.tag == 'result':
    +                    if event == 'start':
    +                        result = OrderedDict()
    +                    elif event == 'end':
    +                        yield result
    +                        result = None
    +                        elem.clear()
    +
    +                elif elem.tag == 'field' and result is not None:
    +                    # We need the 'result is not None' check because
    +                    # 'field' is also the element name in the <meta>
    +                    # header that gives field order, which is not what we
    +                    # want at all.
    +                    if event == 'start':
    +                        values = []
    +                    elif event == 'end':
    +                        field_name = elem.attrib['k']
    +                        if len(values) == 1:
    +                            result[field_name] = values[0]
    +                        else:
    +                            result[field_name] = values
    +                        # Calling .clear() is necessary to let the
    +                        # element be garbage collected. Otherwise
    +                        # arbitrarily large results sets will use
    +                        # arbitrarily large memory intead of
    +                        # streaming.
    +                        elem.clear()
    +
    +                elif elem.tag in ('text', 'v') and event == 'end':
    +                    try:
    +                        text = "".join(elem.itertext())
    +                    except AttributeError:
    +                        # Assume we're running in Python < 2.7, before itertext() was added
    +                        # So we'll define it here
    +
    +                        def __itertext(self):
    +                            tag = self.tag
    +                            if not isinstance(tag, six.string_types) and tag is not None:
    +                                return
    +                            if self.text:
    +                                yield self.text
    +                            for e in self:
    +                                for s in __itertext(e):
    +                                    yield s
    +                                if e.tail:
    +                                    yield e.tail
    +
    +                        text = "".join(__itertext(elem))
    +                    values.append(text)
    +                    elem.clear()
    +
    +                elif elem.tag == 'msg':
    +                    if event == 'start':
    +                        msg_type = elem.attrib['type']
    +                    elif event == 'end':
    +                        text = elem.text if elem.text is not None else ""
    +                        yield Message(msg_type, text)
    +                        elem.clear()
    +        except SyntaxError as pe:
    +            # This is here to handle the same incorrect return from
    +            # splunk that is described in __init__.
    +            if 'no element found' in pe.msg:
    +                return
    +            else:
    +                raise
    +
    +
    +class JSONResultsReader(object):
    +    """This class returns dictionaries and Splunk messages from a JSON results
    +    stream.
    +    ``JSONResultsReader`` is iterable, and returns a ``dict`` for results, or a
    +    :class:`Message` object for Splunk messages. This class has one field,
    +    ``is_preview``, which is ``True`` when the results are a preview from a
    +    running search, or ``False`` when the results are from a completed search.
    +
    +    This function has no network activity other than what is implicit in the
    +    stream it operates on.
    +
    +    :param `stream`: The stream to read from (any object that supports``.read()``).
    +
    +    **Example**::
    +
    +        import results
    +        response = ... # the body of an HTTP response
    +        reader = results.JSONResultsReader(response)
    +        for result in reader:
    +            if isinstance(result, dict):
    +                print "Result: %s" % result
    +            elif isinstance(result, results.Message):
    +                print "Message: %s" % result
    +        print "is_preview = %s " % reader.is_preview
    +    """
    +
    +    # Be sure to update the docstrings of client.Jobs.oneshot,
    +    # client.Job.results_preview and client.Job.results to match any
    +    # changes made to JSONResultsReader.
    +    #
    +    # This wouldn't be a class, just the _parse_results function below,
    +    # except that you cannot get the current generator inside the
    +    # function creating that generator. Thus it's all wrapped up for
    +    # the sake of one field.
    +    def __init__(self, stream):
    +        # The search/jobs/exports endpoint, when run with
    +        # earliest_time=rt and latest_time=rt, output_mode=json, streams a sequence of
    +        # JSON documents, each containing a result, as opposed to one
    +        # results element containing lots of results.
    +        stream = BufferedReader(stream)
    +        self.is_preview = None
    +        self._gen = self._parse_results(stream)
    +
    +    def __iter__(self):
    +        return self
    +
    +    def next(self):
    +        return next(self._gen)
    +
    +    __next__ = next
    +
    +    def _parse_results(self, stream):
    +        """Parse results and messages out of *stream*."""
    +        for line in stream.readlines():
    +            strip_line = line.strip()
    +            if strip_line.__len__() == 0: continue
    +            parsed_line = json_loads(strip_line)
    +            if "preview" in parsed_line:
    +                self.is_preview = parsed_line["preview"]
    +            if "messages" in parsed_line and parsed_line["messages"].__len__() > 0:
    +                for message in parsed_line["messages"]:
    +                    msg_type = message.get("type", "Unknown Message Type")
    +                    text = message.get("text")
    +                yield Message(msg_type, text)
    +            if "result" in parsed_line:
    +                yield parsed_line["result"]
    +            if "results" in parsed_line:
    +                for result in parsed_line["results"]:
    +                    yield result
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/__init__.py
    new file mode 100644
    index 0000000..8a92903
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/__init__.py
    @@ -0,0 +1,159 @@
    +# coding=utf-8
    +#
    +# Copyright © 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +"""
    +
    +.. topic:: Design Notes
    +
    +  1. Commands are constrained to this ABNF grammar::
    +
    +        command       = command-name *[wsp option] *[wsp [dquote] field-name [dquote]]
    +        command-name  = alpha *( alpha / digit )
    +        option        = option-name [wsp] "=" [wsp] option-value
    +        option-name   = alpha *( alpha / digit / "_" )
    +        option-value  = word / quoted-string
    +        word          = 1*( %01-%08 / %0B / %0C / %0E-1F / %21 / %23-%FF ) ; Any character but DQUOTE and WSP
    +        quoted-string = dquote *( word / wsp / "\" dquote / dquote dquote ) dquote
    +        field-name    = ( "_" / alpha ) *( alpha / digit / "_" / "." / "-" )
    +
    +     It does not show that :code:`field-name` values may be comma-separated. This is because Splunk strips commas from
    +     the command line. A search command will never see them.
    +
    +  2. Search commands targeting versions of Splunk prior to 6.3 must be statically configured as follows:
    +
    +     .. code-block:: text
    +        :linenos:
    +
    +        [command_name]
    +        filename = command_name.py
    +        supports_getinfo = true
    +        supports_rawargs = true
    +
    +     No other static configuration is required or expected and may interfere with command execution.
    +
    +  3. Commands support dynamic probing for settings.
    +
    +     Splunk probes for settings dynamically when :code:`supports_getinfo=true`.
    +     You must add this line to the commands.conf stanza for each of your search
    +     commands.
    +
    +  4. Commands do not support parsed arguments on the command line.
    +
    +     Splunk parses arguments when :code:`supports_rawargs=false`. The
    +     :code:`SearchCommand` class sets this value unconditionally. You cannot
    +     override it.
    +
    +     **Rationale**
    +
    +     Splunk parses arguments by stripping quotes, nothing more. This may be useful
    +     in some cases, but doesn't work well with our chosen grammar.
    +
    +  5. Commands consume input headers.
    +
    +     An input header is provided by Splunk when :code:`enableheader=true`. The
    +     :class:`SearchCommand` class sets this value unconditionally. You cannot
    +     override it.
    +
    +  6. Commands produce an output messages header.
    +
    +     Splunk expects a command to produce an output messages header when
    +     :code:`outputheader=true`. The :class:`SearchCommand` class sets this value
    +     unconditionally. You cannot override it.
    +
    +  7. Commands support multi-value fields.
    +
    +     Multi-value fields are provided and consumed by Splunk when
    +     :code:`supports_multivalue=true`. This value is fixed. You cannot override
    +     it.
    +
    +  8. This module represents all fields on the output stream in multi-value
    +     format.
    +
    +     Splunk recognizes two kinds of data: :code:`value` and :code:`list(value)`.
    +     The multi-value format represents these data in field pairs. Given field
    +     :code:`name` the multi-value format calls for the creation of this pair of
    +     fields.
    +
    +     ================= =========================================================
    +     Field name         Field data
    +     ================= =========================================================
    +     :code:`name`      Value or text from which a list of values was derived.
    +
    +     :code:`__mv_name` Empty, if :code:`field` represents a :code:`value`;
    +                       otherwise, an encoded :code:`list(value)`. Values in the
    +                       list are wrapped in dollar signs ($) and separated by
    +                       semi-colons (;). Dollar signs ($) within a value are
    +                       represented by a pair of dollar signs ($$).
    +     ================= =========================================================
    +
    +     Serializing data in this format enables streaming and reduces a command's
    +     memory footprint at the cost of one extra byte of data per field per record
    +     and a small amount of extra processing time by the next command in the
    +     pipeline.
    +
    +  9. A :class:`ReportingCommand` must override :meth:`~ReportingCommand.reduce`
    +     and may override :meth:`~ReportingCommand.map`. Map/reduce commands on the
    +     Splunk processing pipeline are distinguished as this example illustrates.
    +
    +     **Splunk command**
    +
    +     .. code-block:: text
    +
    +         sum total=total_date_hour date_hour
    +
    +     **Map command line**
    +
    +     .. code-block:: text
    +
    +        sum __GETINFO__ __map__ total=total_date_hour date_hour
    +        sum __EXECUTE__ __map__ total=total_date_hour date_hour
    +
    +     **Reduce command line**
    +
    +     .. code-block:: text
    +
    +        sum __GETINFO__ total=total_date_hour date_hour
    +        sum __EXECUTE__ total=total_date_hour date_hour
    +
    +     The :code:`__map__` argument is introduced by
    +     :meth:`ReportingCommand._execute`. Search command authors cannot influence
    +     the contents of the command line in this release.
    +
    +.. topic:: References
    +
    +  1. `Custom Search Command manual: <https://dev.splunk.com/enterprise/docs/devtools/customsearchcommands>`__
    +
    +  2. `Create Custom Search Commands with commands.conf.spec <http://docs.splunk.com/Documentation/Splunk/latest/Admin/Commandsconf>`_
    +
    +  3. `Configure seach assistant with searchbnf.conf <https://docs.splunk.com/Documentation/Splunk/latest/Admin/Searchbnfconf>`_
    +  
    +  4. `Control search distribution with distsearch.conf <https://docs.splunk.com/Documentation/Splunk/latest/Admin/Distsearchconf>`_
    +
    +"""
    +
    +from __future__ import absolute_import, division, print_function, unicode_literals
    +
    +from .environment import *
    +from .decorators import *
    +from .validators import *
    +
    +from .generating_command import GeneratingCommand
    +from .streaming_command import StreamingCommand
    +from .eventing_command import EventingCommand
    +from .reporting_command import ReportingCommand
    +
    +from .external_search_command import execute, ExternalSearchCommand
    +from .search_command import dispatch, SearchMetric
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/decorators.py b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/decorators.py
    new file mode 100644
    index 0000000..d8b3f48
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/decorators.py
    @@ -0,0 +1,447 @@
    +# coding=utf-8
    +#
    +# Copyright © 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import, division, print_function, unicode_literals
    +from splunklib import six
    +
    +from collections import OrderedDict  # must be python 2.7
    +
    +from inspect import getmembers, isclass, isfunction
    +from splunklib.six.moves import map as imap
    +
    +from .internals import ConfigurationSettingsType, json_encode_string
    +from .validators import OptionName
    +
    +
    +class Configuration(object):
    +    """ Defines the configuration settings for a search command.
    +
    +    Documents, validates, and ensures that only relevant configuration settings are applied. Adds a :code:`name` class
    +    variable to search command classes that don't have one. The :code:`name` is derived from the name of the class.
    +    By convention command class names end with the word "Command". To derive :code:`name` the word "Command" is removed
    +    from the end of the class name and then converted to lower case for conformance with the `Search command style guide
    +    <http://docs.splunk.com/Documentation/Splunk/latest/Search/Searchcommandstyleguide>`__
    +
    +    """
    +    def __init__(self, o=None, **kwargs):
    +        #
    +        # The o argument enables the configuration decorator to be used with or without parentheses. For example, it
    +        # enables you to write code that looks like this:
    +        #
    +        #   @Configuration
    +        #   class Foo(SearchCommand):
    +        #       ...
    +        #
    +        #   @Configuration()
    +        #   class Bar(SearchCommand):
    +        #       ...
    +        #
    +        # Without the o argument, the Python compiler will complain about the first form. With the o argument, both
    +        # forms work. The first form provides a value for o: Foo. The second form does does not provide a value for o.
    +        # The class or method decorated is not passed to the constructor. A value of None is passed instead.
    +        #
    +        self.settings = kwargs
    +
    +    def __call__(self, o):
    +
    +        if isfunction(o):
    +            # We must wait to finalize configuration as the class containing this function is under construction
    +            # at the time this call to decorate a member function. This will be handled in the call to
    +            # o.ConfigurationSettings.fix_up(o) in the elif clause of this code block.
    +            o._settings = self.settings
    +        elif isclass(o):
    +
    +            # Set command name
    +
    +            name = o.__name__
    +            if name.endswith('Command'):
    +                name = name[:-len('Command')]
    +            o.name = six.text_type(name.lower())
    +
    +            # Construct ConfigurationSettings instance for the command class
    +
    +            o.ConfigurationSettings = ConfigurationSettingsType(
    +                module=o.__module__ + '.' + o.__name__,
    +                name='ConfigurationSettings',
    +                bases=(o.ConfigurationSettings,))
    +
    +            ConfigurationSetting.fix_up(o.ConfigurationSettings, self.settings)
    +            o.ConfigurationSettings.fix_up(o)
    +            Option.fix_up(o)
    +        else:
    +            raise TypeError('Incorrect usage: Configuration decorator applied to {0}'.format(type(o), o.__name__))
    +
    +        return o
    +
    +
    +class ConfigurationSetting(property):
    +    """ Generates a :class:`property` representing the named configuration setting
    +
    +    This is a convenience function designed to reduce the amount of boiler-plate code you must write; most notably for
    +    property setters.
    +
    +    :param name: Configuration setting name.
    +    :type name: str or unicode
    +
    +    :param doc: A documentation string.
    +    :type doc: bytes, unicode or NoneType
    +
    +    :param readonly: If true, specifies that the configuration setting is fixed.
    +    :type name: bool or NoneType
    +
    +    :param value: Configuration setting value.
    +
    +    :return: A :class:`property` instance representing the configuration setting.
    +    :rtype: property
    +
    +    """
    +    def __init__(self, fget=None, fset=None, fdel=None, doc=None, name=None, readonly=None, value=None):
    +        property.__init__(self, fget=fget, fset=fset, fdel=fdel, doc=doc)
    +        self._readonly = readonly
    +        self._value = value
    +        self._name = name
    +
    +    def __call__(self, function):
    +        return self.getter(function)
    +
    +    def deleter(self, function):
    +        return self._copy_extra_attributes(property.deleter(self, function))
    +
    +    def getter(self, function):
    +        return self._copy_extra_attributes(property.getter(self, function))
    +
    +    def setter(self, function):
    +        return self._copy_extra_attributes(property.setter(self, function))
    +
    +    @staticmethod
    +    def fix_up(cls, values):
    +
    +        is_configuration_setting = lambda attribute: isinstance(attribute, ConfigurationSetting)
    +        definitions = getmembers(cls, is_configuration_setting)
    +        i = 0
    +
    +        for name, setting in definitions:
    +
    +            if setting._name is None:
    +                setting._name = name = six.text_type(name)
    +            else:
    +                name = setting._name
    +
    +            validate, specification = setting._get_specification()
    +            backing_field_name = '_' + name
    +
    +            if setting.fget is None and setting.fset is None and setting.fdel is None:
    +
    +                value = setting._value
    +
    +                if setting._readonly or value is not None:
    +                    validate(specification, name, value)
    +
    +                def fget(bfn, value):
    +                    return lambda this: getattr(this, bfn, value)
    +
    +                setting = setting.getter(fget(backing_field_name, value))
    +
    +                if not setting._readonly:
    +
    +                    def fset(bfn, validate, specification, name):
    +                        return lambda this, value: setattr(this, bfn, validate(specification, name, value))
    +
    +                    setting = setting.setter(fset(backing_field_name, validate, specification, name))
    +
    +                setattr(cls, name, setting)
    +
    +            def is_supported_by_protocol(supporting_protocols):
    +
    +                def is_supported_by_protocol(version):
    +                    return version in supporting_protocols
    +
    +                return is_supported_by_protocol
    +
    +            del setting._name, setting._value, setting._readonly
    +
    +            setting.is_supported_by_protocol = is_supported_by_protocol(specification.supporting_protocols)
    +            setting.supporting_protocols = specification.supporting_protocols
    +            setting.backing_field_name = backing_field_name
    +            definitions[i] = setting
    +            setting.name = name
    +
    +            i += 1
    +
    +            try:
    +                value = values[name]
    +            except KeyError:
    +                continue
    +
    +            if setting.fset is None:
    +                raise ValueError('The value of configuration setting {} is fixed'.format(name))
    +
    +            setattr(cls, backing_field_name, validate(specification, name, value))
    +            del values[name]
    +
    +        if len(values) > 0:
    +            settings = sorted(list(six.iteritems(values)))
    +            settings = imap(lambda n_v: '{}={}'.format(n_v[0], repr(n_v[1])), settings)
    +            raise AttributeError('Inapplicable configuration settings: ' + ', '.join(settings))
    +
    +        cls.configuration_setting_definitions = definitions
    +
    +    def _copy_extra_attributes(self, other):
    +        other._readonly = self._readonly
    +        other._value = self._value
    +        other._name = self._name
    +        return other
    +
    +    def _get_specification(self):
    +
    +        name = self._name
    +
    +        try:
    +            specification = ConfigurationSettingsType.specification_matrix[name]
    +        except KeyError:
    +            raise AttributeError('Unknown configuration setting: {}={}'.format(name, repr(self._value)))
    +
    +        return ConfigurationSettingsType.validate_configuration_setting, specification
    +
    +
    +class Option(property):
    +    """ Represents a search command option.
    +
    +    Required options must be specified on the search command line.
    +
    +    **Example:**
    +
    +    Short form (recommended). When you are satisfied with built-in or custom validation behaviors.
    +
    +    ..  code-block:: python
    +        :linenos:
    +
    +        from splunklib.searchcommands.decorators import Option
    +        from splunklib.searchcommands.validators import Fieldname
    +
    +        total = Option(
    +            doc=''' **Syntax:** **total=***<fieldname>*
    +            **Description:** Name of the field that will hold the computed
    +            sum''',
    +            require=True, validate=Fieldname())
    +
    +    **Example:**
    +
    +    Long form. Useful when you wish to manage the option value and its deleter/getter/setter side-effects yourself. You
    +    must provide a getter and a setter. If your :code:`Option` requires `destruction <https://docs.python.org/2/reference/datamodel.html#object.__del__>`_ you must
    +    also provide a deleter. You must be prepared to accept a value of :const:`None` which indicates that your
    +    :code:`Option` is unset.
    +
    +    ..  code-block:: python
    +        :linenos:
    +
    +        from splunklib.searchcommands import Option
    +
    +        @Option()
    +        def logging_configuration(self):
    +            \""" **Syntax:** logging_configuration=<path>
    +            **Description:** Loads an alternative logging configuration file for a command invocation. The logging
    +            configuration file must be in Python ConfigParser-format. The *<path>* name and all path names specified in
    +            configuration are relative to the app root directory.
    +
    +            \"""
    +            return self._logging_configuration
    +
    +        @logging_configuration.setter
    +        def logging_configuration(self, value):
    +            if value is not None
    +                logging.configure(value)
    +                self._logging_configuration = value
    +
    +        def __init__(self)
    +            self._logging_configuration = None
    +
    +    """
    +    def __init__(self, fget=None, fset=None, fdel=None, doc=None, name=None, default=None, require=None, validate=None):
    +        property.__init__(self, fget, fset, fdel, doc)
    +        self.name = name
    +        self.default = default
    +        self.validate = validate
    +        self.require = bool(require)
    +
    +    def __call__(self, function):
    +        return self.getter(function)
    +
    +    # region Methods
    +
    +    def deleter(self, function):
    +        return self._copy_extra_attributes(property.deleter(self, function))
    +
    +    def getter(self, function):
    +        return self._copy_extra_attributes(property.getter(self, function))
    +
    +    def setter(self, function):
    +        return self._copy_extra_attributes(property.setter(self, function))
    +
    +    @classmethod
    +    def fix_up(cls, command_class):
    +
    +        is_option = lambda attribute: isinstance(attribute, Option)
    +        definitions = getmembers(command_class, is_option)
    +        validate_option_name = OptionName()
    +        i = 0
    +
    +        for name, option in definitions:
    +
    +            if option.name is None:
    +                option.name = name  # no validation required
    +            else:
    +                validate_option_name(option.name)
    +
    +            if option.fget is None and option.fset is None and option.fdel is None:
    +                backing_field_name = '_' + name
    +
    +                def fget(bfn):
    +                    return lambda this: getattr(this, bfn, None)
    +
    +                option = option.getter(fget(backing_field_name))
    +
    +                def fset(bfn, validate):
    +                    if validate is None:
    +                        return lambda this, value: setattr(this, bfn, value)
    +                    return lambda this, value: setattr(this, bfn, validate(value))
    +
    +                option = option.setter(fset(backing_field_name, option.validate))
    +                setattr(command_class, name, option)
    +
    +            elif option.validate is not None:
    +
    +                def fset(function, validate):
    +                    return lambda this, value: function(this, validate(value))
    +
    +                option = option.setter(fset(option.fset, option.validate))
    +                setattr(command_class, name, option)
    +
    +            definitions[i] = name, option
    +            i += 1
    +
    +        command_class.option_definitions = definitions
    +
    +    def _copy_extra_attributes(self, other):
    +        other.name = self.name
    +        other.default = self.default
    +        other.require = self.require
    +        other.validate = self.validate
    +        return other
    +
    +    # endregion
    +
    +    # region Types
    +
    +    class Item(object):
    +        """ Presents an instance/class view over a search command `Option`.
    +
    +        This class is used by SearchCommand.process to parse and report on option values.
    +
    +        """
    +        def __init__(self, command, option):
    +            self._command = command
    +            self._option = option
    +            self._is_set = False
    +            validator = self.validator
    +            self._format = six.text_type if validator is None else validator.format
    +
    +        def __repr__(self):
    +            return '(' + repr(self.name) + ', ' + repr(self._format(self.value)) + ')'
    +
    +        def __str__(self):
    +            value = self.value
    +            value = 'None' if value is None else json_encode_string(self._format(value))
    +            return self.name + '=' + value
    +
    +        # region Properties
    +
    +        @property
    +        def is_required(self):
    +            return bool(self._option.require)
    +
    +        @property
    +        def is_set(self):
    +            """ Indicates whether an option value was provided as argument.
    +
    +            """
    +            return self._is_set
    +
    +        @property
    +        def name(self):
    +            return self._option.name
    +
    +        @property
    +        def validator(self):
    +            return self._option.validate
    +
    +        @property
    +        def value(self):
    +            return self._option.__get__(self._command)
    +
    +        @value.setter
    +        def value(self, value):
    +            self._option.__set__(self._command, value)
    +            self._is_set = True
    +
    +        # endregion
    +
    +        # region Methods
    +
    +        def reset(self):
    +            self._option.__set__(self._command, self._option.default)
    +            self._is_set = False
    +
    +        pass
    +        # endregion
    +
    +    class View(OrderedDict):
    +        """ Presents an ordered dictionary view of the set of :class:`Option` arguments to a search command.
    +
    +        This class is used by SearchCommand.process to parse and report on option values.
    +
    +        """
    +        def __init__(self, command):
    +            definitions = type(command).option_definitions
    +            item_class = Option.Item
    +            OrderedDict.__init__(self, ((option.name, item_class(command, option)) for (name, option) in definitions))
    +
    +        def __repr__(self):
    +            text = 'Option.View([' + ','.join(imap(lambda item: repr(item), six.itervalues(self))) + '])'
    +            return text
    +
    +        def __str__(self):
    +            text = ' '.join([str(item) for item in six.itervalues(self) if item.is_set])
    +            return text
    +
    +        # region Methods
    +
    +        def get_missing(self):
    +            missing = [item.name for item in six.itervalues(self) if item.is_required and not item.is_set]
    +            return missing if len(missing) > 0 else None
    +
    +        def reset(self):
    +            for value in six.itervalues(self):
    +                value.reset()
    +
    +        pass
    +        # endregion
    +
    +    pass
    +    # endregion
    +
    +
    +__all__ = ['Configuration', 'Option']
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/environment.py b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/environment.py
    new file mode 100644
    index 0000000..e92018f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/environment.py
    @@ -0,0 +1,123 @@
    +# coding=utf-8
    +#
    +# Copyright © 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import, division, print_function, unicode_literals
    +
    +from logging import getLogger, root, StreamHandler
    +from logging.config import fileConfig
    +from os import chdir, environ, path
    +from splunklib.six.moves import getcwd
    +
    +import sys
    +
    +
    +def configure_logging(logger_name, filename=None):
    +    """ Configure logging and return the named logger and the location of the logging configuration file loaded.
    +
    +    This function expects a Splunk app directory structure::
    +
    +        <app-root>
    +            bin
    +                ...
    +            default
    +                ...
    +            local
    +                ...
    +
    +    This function looks for a logging configuration file at each of these locations, loading the first, if any,
    +    logging configuration file that it finds::
    +
    +        local/{name}.logging.conf
    +        default/{name}.logging.conf
    +        local/logging.conf
    +        default/logging.conf
    +
    +    The current working directory is set to *<app-root>* before the logging configuration file is loaded. Hence, paths
    +    in the logging configuration file are relative to *<app-root>*. The current directory is reset before return.
    +
    +    You may short circuit the search for a logging configuration file by providing an alternative file location in
    +    `path`. Logging configuration files must be in `ConfigParser format`_.
    +
    +    #Arguments:
    +
    +    :param logger_name: Logger name
    +    :type logger_name: bytes, unicode
    +
    +    :param filename: Location of an alternative logging configuration file or `None`.
    +    :type filename: bytes, unicode or NoneType
    +
    +    :returns: The named logger and the location of the logging configuration file loaded.
    +    :rtype: tuple
    +
    +    .. _ConfigParser format: https://docs.python.org/2/library/logging.config.html#configuration-file-format
    +
    +    """
    +    if filename is None:
    +        if logger_name is None:
    +            probing_paths = [path.join('local', 'logging.conf'), path.join('default', 'logging.conf')]
    +        else:
    +            probing_paths = [
    +                path.join('local', logger_name + '.logging.conf'),
    +                path.join('default', logger_name + '.logging.conf'),
    +                path.join('local', 'logging.conf'),
    +                path.join('default', 'logging.conf')]
    +        for relative_path in probing_paths:
    +            configuration_file = path.join(app_root, relative_path)
    +            if path.exists(configuration_file):
    +                filename = configuration_file
    +                break
    +    elif not path.isabs(filename):
    +        found = False
    +        for conf in 'local', 'default':
    +            configuration_file = path.join(app_root, conf, filename)
    +            if path.exists(configuration_file):
    +                filename = configuration_file
    +                found = True
    +                break
    +        if not found:
    +            raise ValueError('Logging configuration file "{}" not found in local or default directory'.format(filename))
    +    elif not path.exists(filename):
    +        raise ValueError('Logging configuration file "{}" not found'.format(filename))
    +
    +    if filename is not None:
    +        global _current_logging_configuration_file
    +        filename = path.realpath(filename)
    +
    +        if filename != _current_logging_configuration_file:
    +            working_directory = getcwd()
    +            chdir(app_root)
    +            try:
    +                fileConfig(filename, {'SPLUNK_HOME': splunk_home})
    +            finally:
    +                chdir(working_directory)
    +            _current_logging_configuration_file = filename
    +
    +    if len(root.handlers) == 0:
    +        root.addHandler(StreamHandler())
    +
    +    return None if logger_name is None else getLogger(logger_name), filename
    +
    +
    +_current_logging_configuration_file = None
    +
    +splunk_home = path.abspath(path.join(getcwd(), environ.get('SPLUNK_HOME', '')))
    +app_file = getattr(sys.modules['__main__'], '__file__', sys.executable)
    +app_root = path.dirname(path.abspath(path.dirname(app_file)))
    +
    +splunklib_logger, logging_configuration = configure_logging('splunklib')
    +
    +
    +__all__ = ['app_file', 'app_root', 'logging_configuration', 'splunk_home', 'splunklib_logger']
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/eventing_command.py b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/eventing_command.py
    new file mode 100644
    index 0000000..27dc13a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/eventing_command.py
    @@ -0,0 +1,149 @@
    +# coding=utf-8
    +#
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import, division, print_function, unicode_literals
    +
    +from splunklib import six
    +from splunklib.six.moves import map as imap
    +
    +from .decorators import ConfigurationSetting
    +from .search_command import SearchCommand
    +
    +
    +class EventingCommand(SearchCommand):
    +    """ Applies a transformation to search results as they travel through the events pipeline.
    +
    +    Eventing commands typically filter, group, order, and/or or augment event records. Examples of eventing commands
    +    from Splunk's built-in command set include sort_, dedup_, and cluster_. Each execution of an eventing command
    +    should produce a set of event records that is independently usable by downstream processors.
    +
    +    .. _sort: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Sort
    +    .. _dedup: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Dedup
    +    .. _cluster: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Cluster
    +
    +    EventingCommand configuration
    +    ==============================
    +
    +    You can configure your command for operation under Search Command Protocol (SCP) version 1 or 2. SCP 2 requires
    +    Splunk 6.3 or later.
    +
    +    """
    +    # region Methods
    +
    +    def transform(self, records):
    +        """ Generator function that processes and yields event records to the Splunk events pipeline.
    +
    +        You must override this method.
    +
    +        """
    +        raise NotImplementedError('EventingCommand.transform(self, records)')
    +
    +    def _execute(self, ifile, process):
    +        SearchCommand._execute(self, ifile, self.transform)
    +
    +    # endregion
    +
    +    class ConfigurationSettings(SearchCommand.ConfigurationSettings):
    +        """ Represents the configuration settings that apply to a :class:`EventingCommand`.
    +
    +        """
    +        # region SCP v1/v2 properties
    +
    +        required_fields = ConfigurationSetting(doc='''
    +            List of required fields for this search which back-propagates to the generating search.
    +
    +            Setting this value enables selected fields mode under SCP 2. Under SCP 1 you must also specify
    +            :code:`clear_required_fields=True` to enable selected fields mode. To explicitly select all fields,
    +            specify a value of :const:`['*']`. No error is generated if a specified field is missing.
    +
    +            Default: :const:`None`, which implicitly selects all fields.
    +
    +            ''')
    +
    +        # endregion
    +
    +        # region SCP v1 properties
    +
    +        clear_required_fields = ConfigurationSetting(doc='''
    +            :const:`True`, if required_fields represent the *only* fields required.
    +
    +            If :const:`False`, required_fields are additive to any fields that may be required by subsequent commands.
    +            In most cases, :const:`False` is appropriate for eventing commands.
    +
    +            Default: :const:`False`
    +
    +            ''')
    +
    +        retainsevents = ConfigurationSetting(readonly=True, value=True, doc='''
    +            :const:`True`, if the command retains events the way the sort/dedup/cluster commands do.
    +
    +            If :const:`False`, the command transforms events the way the stats command does.
    +
    +            Fixed: :const:`True`
    +
    +            ''')
    +
    +        # endregion
    +
    +        # region SCP v2 properties
    +
    +        maxinputs = ConfigurationSetting(doc='''
    +            Specifies the maximum number of events that can be passed to the command for each invocation.
    +
    +            This limit cannot exceed the value of `maxresultrows` as defined in limits.conf_. Under SCP 1 you must
    +            specify this value in commands.conf_.
    +
    +            Default: The value of `maxresultrows`.
    +
    +            Supported by: SCP 2
    +
    +            .. _limits.conf: http://docs.splunk.com/Documentation/Splunk/latest/admin/Limitsconf
    +
    +            ''')
    +
    +        type = ConfigurationSetting(readonly=True, value='events', doc='''
    +            Command type
    +
    +            Fixed: :const:`'events'`.
    +
    +            Supported by: SCP 2
    +
    +            ''')
    +
    +        # endregion
    +
    +        # region Methods
    +
    +        @classmethod
    +        def fix_up(cls, command):
    +            """ Verifies :code:`command` class structure.
    +
    +            """
    +            if command.transform == EventingCommand.transform:
    +                raise AttributeError('No EventingCommand.transform override')
    +            SearchCommand.ConfigurationSettings.fix_up(command)
    +
    +        # TODO: Stop looking like a dictionary because we don't obey the semantics
    +        # N.B.: Does not use Python 2 dict copy semantics
    +        def iteritems(self):
    +            iteritems = SearchCommand.ConfigurationSettings.iteritems(self)
    +            return imap(lambda name_value: (name_value[0], 'events' if name_value[0] == 'type' else name_value[1]), iteritems)
    +
    +        # N.B.: Does not use Python 3 dict view semantics
    +        if not six.PY2:
    +            items = iteritems
    +
    +        # endregion
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/external_search_command.py b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/external_search_command.py
    new file mode 100644
    index 0000000..c230624
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/external_search_command.py
    @@ -0,0 +1,228 @@
    +# coding=utf-8
    +#
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import, division, print_function, unicode_literals
    +
    +from logging import getLogger
    +import os
    +import sys
    +import traceback
    +from splunklib import six
    +
    +if sys.platform == 'win32':
    +    from signal import signal, CTRL_BREAK_EVENT, SIGBREAK, SIGINT, SIGTERM
    +    from subprocess import Popen
    +    import atexit
    +
    +from . import splunklib_logger as logger
    +
    +# P1 [ ] TODO: Add ExternalSearchCommand class documentation
    +
    +
    +class ExternalSearchCommand(object):
    +    """
    +    """
    +    def __init__(self, path, argv=None, environ=None):
    +
    +        if not isinstance(path, (bytes, six.text_type)):
    +            raise ValueError('Expected a string value for path, not {}'.format(repr(path)))
    +
    +        self._logger = getLogger(self.__class__.__name__)
    +        self._path = six.text_type(path)
    +        self._argv = None
    +        self._environ = None
    +
    +        self.argv = argv
    +        self.environ = environ
    +
    +    # region Properties
    +
    +    @property
    +    def argv(self):
    +        return getattr(self, '_argv')
    +
    +    @argv.setter
    +    def argv(self, value):
    +        if not (value is None or isinstance(value, (list, tuple))):
    +            raise ValueError('Expected a list, tuple or value of None for argv, not {}'.format(repr(value)))
    +        self._argv = value
    +
    +    @property
    +    def environ(self):
    +        return getattr(self, '_environ')
    +
    +    @environ.setter
    +    def environ(self, value):
    +        if not (value is None or isinstance(value, dict)):
    +            raise ValueError('Expected a dictionary value for environ, not {}'.format(repr(value)))
    +        self._environ = value
    +
    +    @property
    +    def logger(self):
    +        return self._logger
    +
    +    @property
    +    def path(self):
    +        return self._path
    +
    +    # endregion
    +
    +    # region Methods
    +
    +    def execute(self):
    +        # noinspection PyBroadException
    +        try:
    +            if self._argv is None:
    +                self._argv = os.path.splitext(os.path.basename(self._path))[0]
    +            self._execute(self._path, self._argv, self._environ)
    +        except:
    +            error_type, error, tb = sys.exc_info()
    +            message = 'Command execution failed: ' + six.text_type(error)
    +            self._logger.error(message + '\nTraceback:\n' + ''.join(traceback.format_tb(tb)))
    +            sys.exit(1)
    +
    +    if sys.platform == 'win32':
    +
    +        @staticmethod
    +        def _execute(path, argv=None, environ=None):
    +            """ Executes an external search command.
    +
    +            :param path: Path to the external search command.
    +            :type path: unicode
    +
    +            :param argv: Argument list.
    +            :type argv: list or tuple
    +                The arguments to the child process should start with the name of the command being run, but this is not
    +                enforced. A value of :const:`None` specifies that the base name of path name :param:`path` should be used.
    +
    +            :param environ: A mapping which is used to define the environment variables for the new process.
    +            :type environ: dict or None.
    +                This mapping is used instead of the current process’s environment. A value of :const:`None` specifies that
    +                the :data:`os.environ` mapping should be used.
    +
    +            :return: None
    +
    +            """
    +            search_path = os.getenv('PATH') if environ is None else environ.get('PATH')
    +            found = ExternalSearchCommand._search_path(path, search_path)
    +
    +            if found is None:
    +                raise ValueError('Cannot find command on path: {}'.format(path))
    +
    +            path = found
    +            logger.debug('starting command="%s", arguments=%s', path, argv)
    +
    +            def terminate(signal_number, frame):
    +                sys.exit('External search command is terminating on receipt of signal={}.'.format(signal_number))
    +
    +            def terminate_child():
    +                if p.pid is not None and p.returncode is None:
    +                    logger.debug('terminating command="%s", arguments=%d, pid=%d', path, argv, p.pid)
    +                    os.kill(p.pid, CTRL_BREAK_EVENT)
    +
    +            p = Popen(argv, executable=path, env=environ, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)
    +            atexit.register(terminate_child)
    +            signal(SIGBREAK, terminate)
    +            signal(SIGINT, terminate)
    +            signal(SIGTERM, terminate)
    +
    +            logger.debug('started command="%s", arguments=%s, pid=%d', path, argv, p.pid)
    +            p.wait()
    +
    +            logger.debug('finished command="%s", arguments=%s, pid=%d, returncode=%d', path, argv, p.pid, p.returncode)
    +
    +            if p.returncode != 0:
    +                sys.exit(p.returncode)
    +
    +        @staticmethod
    +        def _search_path(executable, paths):
    +            """ Locates an executable program file.
    +
    +            :param executable: The name of the executable program to locate.
    +            :type executable: unicode
    +
    +            :param paths: A list of one or more directory paths where executable programs are located.
    +            :type paths: unicode
    +
    +            :return:
    +            :rtype: Path to the executable program located or :const:`None`.
    +
    +            """
    +            directory, filename = os.path.split(executable)
    +            extension = os.path.splitext(filename)[1].upper()
    +            executable_extensions = ExternalSearchCommand._executable_extensions
    +
    +            if directory:
    +                if len(extension) and extension in executable_extensions:
    +                    return None
    +                for extension in executable_extensions:
    +                    path = executable + extension
    +                    if os.path.isfile(path):
    +                        return path
    +                return None
    +
    +            if not paths:
    +                return None
    +
    +            directories = [directory for directory in paths.split(';') if len(directory)]
    +
    +            if len(directories) == 0:
    +                return None
    +
    +            if len(extension) and extension in executable_extensions:
    +                for directory in directories:
    +                    path = os.path.join(directory, executable)
    +                    if os.path.isfile(path):
    +                        return path
    +                return None
    +
    +            for directory in directories:
    +                path_without_extension = os.path.join(directory, executable)
    +                for extension in executable_extensions:
    +                    path = path_without_extension + extension
    +                    if os.path.isfile(path):
    +                        return path
    +
    +            return None
    +
    +        _executable_extensions = ('.COM', '.EXE')
    +    else:
    +        @staticmethod
    +        def _execute(path, argv, environ):
    +            if environ is None:
    +                os.execvp(path, argv)
    +            else:
    +                os.execvpe(path, argv, environ)
    +            return
    +
    +    # endregion
    +
    +
    +def execute(path, argv=None, environ=None, command_class=ExternalSearchCommand):
    +    """
    +    :param path:
    +    :type path: basestring
    +    :param argv:
    +    :type: argv: list, tuple, or None
    +    :param environ:
    +    :type environ: dict
    +    :param command_class: External search command class to instantiate and execute.
    +    :type command_class: type
    +    :return:
    +    :rtype: None
    +    """
    +    assert issubclass(command_class, ExternalSearchCommand)
    +    command_class(path, argv, environ).execute()
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/generating_command.py b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/generating_command.py
    new file mode 100644
    index 0000000..6a75d2c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/generating_command.py
    @@ -0,0 +1,387 @@
    +# coding=utf-8
    +#
    +# Copyright © 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import, division, print_function, unicode_literals
    +import sys
    +
    +from .decorators import ConfigurationSetting
    +from .search_command import SearchCommand
    +
    +from splunklib import six
    +from splunklib.six.moves import map as imap, filter as ifilter
    +
    +# P1 [O] TODO: Discuss generates_timeorder in the class-level documentation for GeneratingCommand
    +
    +
    +class GeneratingCommand(SearchCommand):
    +    """ Generates events based on command arguments.
    +
    +    Generating commands receive no input and must be the first command on a pipeline. There are three pipelines:
    +    streams, events, and reports. The streams pipeline generates or processes time-ordered event records on an
    +    indexer or search head.
    +
    +    Streaming commands filter, modify, or augment event records and can be applied to subsets of index data in a
    +    parallel manner. An example of a streaming command from Splunk's built-in command set is rex_ which extracts and
    +    adds fields to event records at search time. Records that pass through the streams pipeline move on to the events
    +    pipeline.
    +
    +    The events pipeline generates or processes records on a search head. Eventing commands typically filter, group,
    +    order, or augment event records. Examples of eventing commands from Splunk's built-in command set include sort_,
    +    dedup_, and cluster_. Each execution of an eventing command should produce a set of event records that is
    +    independently usable by downstream processors. Records that pass through the events pipeline move on to the reports
    +    pipeline.
    +
    +    The reports pipeline also runs on a search head, but yields data structures for presentation, not event records.
    +    Examples of streaming from Splunk's built-in command set include chart_, stats_, and contingency_.
    +
    +    GeneratingCommand configuration
    +    ===============================
    +
    +    Configure your generating command based on the pipeline that it targets. How you configure your command depends on
    +    the Search Command Protocol (SCP) version.
    +
    +    +----------+-------------------------------------+--------------------------------------------+
    +    | Pipeline | SCP 1                               | SCP 2                                      |
    +    +==========+=====================================+============================================+
    +    | streams  | streaming=True[,local=[True|False]] | type='streaming'[,distributed=[true|false] |
    +    +----------+-------------------------------------+--------------------------------------------+
    +    | events   | retainsevents=True, streaming=False | type='events'                              |
    +    +----------+-------------------------------------+--------------------------------------------+
    +    | reports  | streaming=False                     | type='reporting'                           |
    +    +----------+-------------------------------------+--------------------------------------------+
    +
    +    Only streaming commands may be distributed to indexers. By default generating commands are configured to run
    +    locally in the streams pipeline and will run under either SCP 1 or SCP 2.
    +
    +    .. code-block:: python
    +
    +        @Configuration()
    +        class StreamingGeneratingCommand(GeneratingCommand)
    +            ...
    +
    +    How you configure your command to run on a different pipeline or in a distributed fashion depends on what SCP
    +    protocol versions you wish to support. You must be sure to configure your command consistently for each protocol,
    +    if you wish to support both protocol versions correctly.
    +
    +    .. _chart: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Chart
    +    .. _cluster: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Cluster
    +    .. _contingency: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Contingency
    +    .. _dedup: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Dedup
    +    .. _rex: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Rex
    +    .. _sort: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Sort
    +    .. _stats: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Stats
    +
    +    Distributed Generating command
    +    ==============================
    +
    +    Commands configured like this will run as the first command on search heads and/or indexers on the streams pipeline.
    +
    +    +----------+---------------------------------------------------+---------------------------------------------------+
    +    | Pipeline | SCP 1                                             | SCP 2                                             |
    +    +==========+===================================================+===================================================+
    +    | streams  | 1. Add this line to your command's stanza in      | 1. Add this configuration setting to your code:   |
    +    |          |                                                   |                                                   |
    +    |          |    default/commands.conf::                        |    ..  code-block:: python                        |
    +    |          |                                                   |                                                   |
    +    |          |        local = false                              |        @Configuration(distributed=True)           |
    +    |          |                                                   |        class SomeCommand(GeneratingCommand)       |
    +    |          |                                                   |            ...                                    |
    +    |          | 2. Restart splunk                                 |                                                   |
    +    |          |                                                   | 2. You are good to go; no need to restart Splunk  |
    +    +----------+---------------------------------------------------+---------------------------------------------------+
    +
    +    Eventing Generating command
    +    ===========================
    +
    +    Generating commands configured like this will run as the first command on a search head on the events pipeline.
    +
    +    +----------+---------------------------------------------------+---------------------------------------------------+
    +    | Pipeline | SCP 1                                             | SCP 2                                             |
    +    +==========+===================================================+===================================================+
    +    | events   | You have a choice. Add these configuration        | Add this configuration setting to your command    |
    +    |          | settings to your command class:                   | setting to your command class:                    |
    +    |          |                                                   |                                                   |
    +    |          | .. code-block:: python                            | .. code-block:: python                            |
    +    |          |                                                   |                                                   |
    +    |          |     @Configuration(                               |     @Configuration(type='events')                 |
    +    |          |         retainsevents=True, streaming=False)      |     class SomeCommand(GeneratingCommand)          |
    +    |          |     class SomeCommand(GeneratingCommand)          |         ...                                       |
    +    |          |         ...                                       |                                                   |
    +    |          |                                                   |                                                   |
    +    |          | Or add these lines to default/commands.conf:      |                                                   |
    +    |          |                                                   |                                                   |
    +    |          | ..  code-block:: text                             |                                                   |
    +    |          |                                                   |                                                   |
    +    |          |     retainsevents = true                          |                                                   |
    +    |          |     streaming = false                             |                                                   |
    +    +----------+---------------------------------------------------+---------------------------------------------------+
    +
    +    Configure your command class like this, if you wish to support both protocols:
    +
    +    ..  code-block:: python
    +
    +        @Configuration(type='events', retainsevents=True, streaming=False)
    +        class SomeCommand(GeneratingCommand)
    +            ...
    +
    +    You might also consider adding these lines to commands.conf instead of adding them to your command class:
    +
    +    ..  code-block:: python
    +
    +        retainsevents = false
    +        streaming = false
    +
    +    Reporting Generating command
    +    ============================
    +
    +    Commands configured like this will run as the first command on a search head on the reports pipeline.
    +
    +    +----------+---------------------------------------------------+---------------------------------------------------+
    +    | Pipeline | SCP 1                                             | SCP 2                                             |
    +    +==========+===================================================+===================================================+
    +    | events   | You have a choice. Add these configuration        | Add this configuration setting to your command    |
    +    |          | settings to your command class:                   | setting to your command class:                    |
    +    |          |                                                   |                                                   |
    +    |          | .. code-block:: python                            | .. code-block:: python                            |
    +    |          |                                                   |                                                   |
    +    |          |     @Configuration(retainsevents=False)           |     @Configuration(type='reporting')              |
    +    |          |     class SomeCommand(GeneratingCommand)          |     class SomeCommand(GeneratingCommand)          |
    +    |          |         ...                                       |         ...                                       |
    +    |          |                                                   |                                                   |
    +    |          | Or add this lines to default/commands.conf:       |                                                   |
    +    |          |                                                   |                                                   |
    +    |          | .. code-block:: text                              |                                                   |
    +    |          |                                                   |                                                   |
    +    |          |     retainsevents = false                         |                                                   |
    +    |          |     streaming = false                             |                                                   |
    +    +----------+---------------------------------------------------+---------------------------------------------------+
    +
    +    Configure your command class like this, if you wish to support both protocols:
    +
    +    ..  code-block:: python
    +
    +        @Configuration(type='reporting', streaming=False)
    +        class SomeCommand(GeneratingCommand)
    +            ...
    +
    +    You might also consider adding these lines to commands.conf instead of adding them to your command class:
    +
    +    ..  code-block:: text
    +
    +        retainsevents = false
    +        streaming = false
    +
    +    """
    +    # region Methods
    +
    +    def generate(self):
    +        """ A generator that yields records to the Splunk processing pipeline
    +
    +        You must override this method.
    +
    +        """
    +        raise NotImplementedError('GeneratingCommand.generate(self)')
    +
    +    def _execute(self, ifile, process):
    +        """ Execution loop
    +
    +        :param ifile: Input file object. Unused.
    +        :type ifile: file
    +
    +        :return: `None`.
    +
    +        """
    +        if self._protocol_version == 2:
    +            self._execute_v2(ifile, self.generate())
    +        else:
    +            assert self._protocol_version == 1
    +            self._record_writer.write_records(self.generate())
    +        self.finish()
    +
    +    def _execute_chunk_v2(self, process, chunk):
    +        count = 0
    +        records = []
    +        for row in process:
    +            records.append(row)
    +            count += 1
    +            if count == self._record_writer._maxresultrows:
    +                break
    +
    +        for row in records:
    +            self._record_writer.write_record(row)
    +
    +        if count == self._record_writer._maxresultrows:
    +            self._finished = False
    +        else:
    +            self._finished = True
    +
    +    def process(self, argv=sys.argv, ifile=sys.stdin, ofile=sys.stdout, allow_empty_input=True):
    +        """ Process data.
    +
    +        :param argv: Command line arguments.
    +        :type argv: list or tuple
    +
    +        :param ifile: Input data file.
    +        :type ifile: file
    +
    +        :param ofile: Output data file.
    +        :type ofile: file
    +
    +        :param allow_empty_input: For generating commands, it must be true. Doing otherwise will cause an error.
    +        :type allow_empty_input: bool
    +
    +        :return: :const:`None`
    +        :rtype: NoneType
    +
    +        """
    +
    +        # Generating commands are expected to run on an empty set of inputs as the first command being run in a search,
    +        # also this class implements its own separate _execute_chunk_v2 method which does not respect allow_empty_input
    +        # so ensure that allow_empty_input is always True
    +
    +        if not allow_empty_input:
    +            raise ValueError("allow_empty_input cannot be False for Generating Commands")
    +        else:
    +            return super(GeneratingCommand, self).process(argv=argv, ifile=ifile, ofile=ofile, allow_empty_input=True)
    +
    +    # endregion
    +
    +    # region Types
    +
    +    class ConfigurationSettings(SearchCommand.ConfigurationSettings):
    +        """ Represents the configuration settings for a :code:`GeneratingCommand` class.
    +
    +        """
    +        # region SCP v1/v2 Properties
    +
    +        generating = ConfigurationSetting(readonly=True, value=True, doc='''
    +            Tells Splunk that this command generates events, but does not process inputs.
    +
    +            Generating commands must appear at the front of the search pipeline identified by :meth:`type`.
    +
    +            Fixed: :const:`True`
    +
    +            Supported by: SCP 1, SCP 2
    +
    +            ''')
    +
    +        # endregion
    +
    +        # region SCP v1 Properties
    +
    +        generates_timeorder = ConfigurationSetting(doc='''
    +            :const:`True`, if the command generates new events.
    +
    +            Default: :const:`False`
    +
    +            Supported by: SCP 1
    +
    +            ''')
    +
    +        local = ConfigurationSetting(doc='''
    +            :const:`True`, if the command should run locally on the search head.
    +
    +            Default: :const:`False`
    +
    +            Supported by: SCP 1
    +
    +            ''')
    +
    +        retainsevents = ConfigurationSetting(doc='''
    +            :const:`True`, if the command retains events the way the sort, dedup, and cluster commands do, or whether it
    +            transforms them the way the stats command does.
    +
    +            Default: :const:`False`
    +
    +            Supported by: SCP 1
    +
    +            ''')
    +
    +        streaming = ConfigurationSetting(doc='''
    +            :const:`True`, if the command is streamable.
    +
    +            Default: :const:`True`
    +
    +            Supported by: SCP 1
    +
    +            ''')
    +
    +        # endregion
    +
    +        # region SCP v2 Properties
    +
    +        distributed = ConfigurationSetting(value=False, doc='''
    +            True, if this command should be distributed to indexers.
    +
    +            This value is ignored unless :meth:`type` is equal to :const:`streaming`. It is only this command type that
    +            may be distributed.
    +
    +            Default: :const:`False`
    +
    +            Supported by: SCP 2
    +
    +            ''')
    +
    +        type = ConfigurationSetting(value='streaming', doc='''
    +            A command type name.
    +
    +            ====================  ======================================================================================
    +            Value                 Description
    +            --------------------  --------------------------------------------------------------------------------------
    +            :const:`'events'`     Runs as the first command in the Splunk events pipeline. Cannot be distributed.
    +            :const:`'reporting'`  Runs as the first command in the Splunk reports pipeline. Cannot be distributed.
    +            :const:`'streaming'`  Runs as the first command in the Splunk streams pipeline. May be distributed.
    +            ====================  ======================================================================================
    +
    +            Default: :const:`'streaming'`
    +
    +            Supported by: SCP 2
    +
    +            ''')
    +
    +        # endregion
    +
    +        # region Methods
    +
    +        @classmethod
    +        def fix_up(cls, command):
    +            """ Verifies :code:`command` class structure.
    +
    +            """
    +            if command.generate == GeneratingCommand.generate:
    +                raise AttributeError('No GeneratingCommand.generate override')
    +
    +        # TODO: Stop looking like a dictionary because we don't obey the semantics
    +        # N.B.: Does not use Python 2 dict copy semantics
    +        def iteritems(self):
    +            iteritems = SearchCommand.ConfigurationSettings.iteritems(self)
    +            version = self.command.protocol_version
    +            if version == 2:
    +                iteritems = ifilter(lambda name_value1: name_value1[0] != 'distributed', iteritems)
    +                if not self.distributed and self.type == 'streaming':
    +                    iteritems = imap(
    +                        lambda name_value: (name_value[0], 'stateful') if name_value[0] == 'type' else (name_value[0], name_value[1]), iteritems)
    +            return iteritems
    +
    +        # N.B.: Does not use Python 3 dict view semantics
    +        if not six.PY2:
    +            items = iteritems
    +
    +        pass
    +        # endregion
    +
    +    pass
    +    # endregion
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/internals.py b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/internals.py
    new file mode 100644
    index 0000000..1ea2833
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/internals.py
    @@ -0,0 +1,844 @@
    +# coding=utf-8
    +#
    +# Copyright © 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import, division, print_function
    +
    +from io import TextIOWrapper
    +from collections import deque, namedtuple
    +from splunklib import six
    +from collections import OrderedDict
    +from splunklib.six.moves import StringIO
    +from itertools import chain
    +from splunklib.six.moves import map as imap
    +from json import JSONDecoder, JSONEncoder
    +from json.encoder import encode_basestring_ascii as json_encode_string
    +from splunklib.six.moves import urllib
    +
    +import csv
    +import gzip
    +import os
    +import re
    +import sys
    +import warnings
    +
    +from . import environment
    +
    +csv.field_size_limit(10485760)  # The default value is 128KB; upping to 10MB. See SPL-12117 for background on this issue
    +
    +
    +def set_binary_mode(fh):
    +    """ Helper method to set up binary mode for file handles.
    +    Emphasis being sys.stdin, sys.stdout, sys.stderr.
    +    For python3, we want to return .buffer
    +    For python2+windows we want to set os.O_BINARY
    +    """
    +    typefile = TextIOWrapper if sys.version_info >= (3, 0) else file
    +    # check for file handle
    +    if not isinstance(fh, typefile):
    +        return fh
    +
    +    # check for python3 and buffer
    +    if sys.version_info >= (3, 0) and hasattr(fh, 'buffer'):
    +        return fh.buffer
    +    # check for python3
    +    elif sys.version_info >= (3, 0):
    +        pass
    +    # check for windows python2. SPL-175233 -- python3 stdout is already binary
    +    elif sys.platform == 'win32':
    +        # Work around the fact that on Windows '\n' is mapped to '\r\n'. The typical solution is to simply open files in
    +        # binary mode, but stdout is already open, thus this hack. 'CPython' and 'PyPy' work differently. We assume that
    +        # all other Python implementations are compatible with 'CPython'. This might or might not be a valid assumption.
    +        from platform import python_implementation
    +        implementation = python_implementation()
    +        if implementation == 'PyPy':
    +            return os.fdopen(fh.fileno(), 'wb', 0)
    +        else:
    +            import msvcrt
    +            msvcrt.setmode(fh.fileno(), os.O_BINARY)
    +    return fh
    +
    +
    +class CommandLineParser(object):
    +    r""" Parses the arguments to a search command.
    +
    +    A search command line is described by the following syntax.
    +
    +    **Syntax**::
    +
    +       command       = command-name *[wsp option] *[wsp [dquote] field-name [dquote]]
    +       command-name  = alpha *( alpha / digit )
    +       option        = option-name [wsp] "=" [wsp] option-value
    +       option-name   = alpha *( alpha / digit / "_" )
    +       option-value  = word / quoted-string
    +       word          = 1*( %01-%08 / %0B / %0C / %0E-1F / %21 / %23-%FF ) ; Any character but DQUOTE and WSP
    +       quoted-string = dquote *( word / wsp / "\" dquote / dquote dquote ) dquote
    +       field-name    = ( "_" / alpha ) *( alpha / digit / "_" / "." / "-" )
    +
    +    **Note:**
    +
    +    This syntax is constrained to an 8-bit character set.
    +
    +    **Note:**
    +
    +    This syntax does not show that `field-name` values may be comma-separated when in fact they can be. This is
    +    because Splunk strips commas from the command line. A custom search command will never see them.
    +
    +    **Example:**
    +
    +    countmatches fieldname = word_count pattern = \w+ some_text_field
    +
    +    Option names are mapped to properties in the targeted ``SearchCommand``. It is the responsibility of the property
    +    setters to validate the values they receive. Property setters may also produce side effects. For example,
    +    setting the built-in `log_level` immediately changes the `log_level`.
    +
    +    """
    +    @classmethod
    +    def parse(cls, command, argv):
    +        """ Splits an argument list into an options dictionary and a fieldname
    +        list.
    +
    +        The argument list, `argv`, must be of the form::
    +
    +            *[option]... *[<field-name>]
    +
    +        Options are validated and assigned to items in `command.options`. Field names are validated and stored in the
    +        list of `command.fieldnames`.
    +
    +        #Arguments:
    +
    +        :param command: Search command instance.
    +        :type command: ``SearchCommand``
    +        :param argv: List of search command arguments.
    +        :type argv: ``list``
    +        :return: ``None``
    +
    +        #Exceptions:
    +
    +        ``SyntaxError``: Argument list is incorrectly formed.
    +        ``ValueError``: Unrecognized option/field name, or an illegal field value.
    +
    +        """
    +        debug = environment.splunklib_logger.debug
    +        command_class = type(command).__name__
    +
    +        # Prepare
    +
    +        debug('Parsing %s command line: %r', command_class, argv)
    +        command.fieldnames = None
    +        command.options.reset()
    +        argv = ' '.join(argv)
    +
    +        command_args = cls._arguments_re.match(argv)
    +
    +        if command_args is None:
    +            raise SyntaxError('Syntax error: {}'.format(argv))
    +
    +        # Parse options
    +
    +        for option in cls._options_re.finditer(command_args.group('options')):
    +            name, value = option.group('name'), option.group('value')
    +            if name not in command.options:
    +                raise ValueError(
    +                    'Unrecognized {} command option: {}={}'.format(command.name, name, json_encode_string(value)))
    +            command.options[name].value = cls.unquote(value)
    +
    +        missing = command.options.get_missing()
    +
    +        if missing is not None:
    +            if len(missing) > 1:
    +                raise ValueError(
    +                    'Values for these {} command options are required: {}'.format(command.name, ', '.join(missing)))
    +            raise ValueError('A value for {} command option {} is required'.format(command.name, missing[0]))
    +
    +        # Parse field names
    +
    +        fieldnames = command_args.group('fieldnames')
    +
    +        if fieldnames is None:
    +            command.fieldnames = []
    +        else:
    +            command.fieldnames = [cls.unquote(value.group(0)) for value in cls._fieldnames_re.finditer(fieldnames)]
    +
    +        debug('  %s: %s', command_class, command)
    +
    +    @classmethod
    +    def unquote(cls, string):
    +        """ Removes quotes from a quoted string.
    +
    +        Splunk search command quote rules are applied. The enclosing double-quotes, if present, are removed. Escaped
    +        double-quotes ('\"' or '""') are replaced by a single double-quote ('"').
    +
    +        **NOTE**
    +
    +        We are not using a json.JSONDecoder because Splunk quote rules are different than JSON quote rules. A
    +        json.JSONDecoder does not recognize a pair of double-quotes ('""') as an escaped quote ('"') and will
    +        decode single-quoted strings ("'") in addition to double-quoted ('"') strings.
    +
    +        """
    +        if len(string) == 0:
    +            return ''
    +
    +        if string[0] == '"':
    +            if len(string) == 1 or string[-1] != '"':
    +                raise SyntaxError('Poorly formed string literal: ' + string)
    +            string = string[1:-1]
    +
    +        if len(string) == 0:
    +            return ''
    +
    +        def replace(match):
    +            value = match.group(0)
    +            if value == '""':
    +                return '"'
    +            if len(value) < 2:
    +                raise SyntaxError('Poorly formed string literal: ' + string)
    +            return value[1]
    +
    +        result = re.sub(cls._escaped_character_re, replace, string)
    +        return result
    +
    +    # region Class variables
    +
    +    _arguments_re = re.compile(r"""
    +        ^\s*
    +        (?P<options>     # Match a leading set of name/value pairs
    +            (?:
    +                (?:(?=\w)[^\d]\w*)                         # name
    +                \s*=\s*                                    # =
    +                (?:"(?:\\.|""|[^"])*"|(?:\\.|[^\s"])+)\s*  # value
    +            )*
    +        )\s*
    +        (?P<fieldnames>  # Match a trailing set of field names
    +            (?:
    +                (?:"(?:\\.|""|[^"])*"|(?:\\.|[^\s"])+)\s*
    +            )*
    +        )\s*$
    +        """, re.VERBOSE | re.UNICODE)
    +
    +    _escaped_character_re = re.compile(r'(\\.|""|[\\"])')
    +
    +    _fieldnames_re = re.compile(r"""("(?:\\.|""|[^"\\])+"|(?:\\.|[^\s"])+)""")
    +
    +    _options_re = re.compile(r"""
    +        # Captures a set of name/value pairs when used with re.finditer
    +        (?P<name>(?:(?=\w)[^\d]\w*))                   # name
    +        \s*=\s*                                        # =
    +        (?P<value>"(?:\\.|""|[^"])*"|(?:\\.|[^\s"])+)  # value
    +        """, re.VERBOSE | re.UNICODE)
    +
    +    # endregion
    +
    +
    +class ConfigurationSettingsType(type):
    +    """ Metaclass for constructing ConfigurationSettings classes.
    +
    +    Instances of :class:`ConfigurationSettingsType` construct :class:`ConfigurationSettings` classes from classes from
    +    a base :class:`ConfigurationSettings` class and a dictionary of configuration settings. The settings in the
    +    dictionary are validated against the settings in the base class. You cannot add settings, you can only change their
    +    backing-field values and you cannot modify settings without backing-field values. These are considered fixed
    +    configuration setting values.
    +
    +    This is an internal class used in two places:
    +
    +    + :meth:`decorators.Configuration.__call__`
    +
    +      Adds a ConfigurationSettings attribute to a :class:`SearchCommand` class.
    +
    +    + :meth:`reporting_command.ReportingCommand.fix_up`
    +
    +      Adds a ConfigurationSettings attribute to a :meth:`ReportingCommand.map` method, if there is one.
    +
    +    """
    +    def __new__(mcs, module, name, bases):
    +        mcs = super(ConfigurationSettingsType, mcs).__new__(mcs, str(name), bases, {})
    +        return mcs
    +
    +    def __init__(cls, module, name, bases):
    +
    +        super(ConfigurationSettingsType, cls).__init__(name, bases, None)
    +        cls.__module__ = module
    +
    +    @staticmethod
    +    def validate_configuration_setting(specification, name, value):
    +        if not isinstance(value, specification.type):
    +            if isinstance(specification.type, type):
    +                type_names = specification.type.__name__
    +            else:
    +                type_names = ', '.join(imap(lambda t: t.__name__, specification.type))
    +            raise ValueError('Expected {} value, not {}={}'.format(type_names, name, repr(value)))
    +        if specification.constraint and not specification.constraint(value):
    +            raise ValueError('Illegal value: {}={}'.format(name, repr(value)))
    +        return value
    +
    +    specification = namedtuple(
    +        'ConfigurationSettingSpecification', (
    +            'type',
    +            'constraint',
    +            'supporting_protocols'))
    +
    +    # P1 [ ] TODO: Review ConfigurationSettingsType.specification_matrix for completeness and correctness
    +
    +    specification_matrix = {
    +        'clear_required_fields': specification(
    +            type=bool,
    +            constraint=None,
    +            supporting_protocols=[1]),
    +        'distributed': specification(
    +            type=bool,
    +            constraint=None,
    +            supporting_protocols=[2]),
    +        'generates_timeorder': specification(
    +            type=bool,
    +            constraint=None,
    +            supporting_protocols=[1]),
    +        'generating': specification(
    +            type=bool,
    +            constraint=None,
    +            supporting_protocols=[1, 2]),
    +        'local': specification(
    +            type=bool,
    +            constraint=None,
    +            supporting_protocols=[1]),
    +        'maxinputs': specification(
    +            type=int,
    +            constraint=lambda value: 0 <= value <= six.MAXSIZE,
    +            supporting_protocols=[2]),
    +        'overrides_timeorder': specification(
    +            type=bool,
    +            constraint=None,
    +            supporting_protocols=[1]),
    +        'required_fields': specification(
    +            type=(list, set, tuple),
    +            constraint=None,
    +            supporting_protocols=[1, 2]),
    +        'requires_preop': specification(
    +            type=bool,
    +            constraint=None,
    +            supporting_protocols=[1]),
    +        'retainsevents': specification(
    +            type=bool,
    +            constraint=None,
    +            supporting_protocols=[1]),
    +        'run_in_preview': specification(
    +            type=bool,
    +            constraint=None,
    +            supporting_protocols=[2]),
    +        'streaming': specification(
    +            type=bool,
    +            constraint=None,
    +            supporting_protocols=[1]),
    +        'streaming_preop': specification(
    +            type=(bytes, six.text_type),
    +            constraint=None,
    +            supporting_protocols=[1, 2]),
    +        'type': specification(
    +            type=(bytes, six.text_type),
    +            constraint=lambda value: value in ('events', 'reporting', 'streaming'),
    +            supporting_protocols=[2])}
    +
    +
    +class CsvDialect(csv.Dialect):
    +    """ Describes the properties of Splunk CSV streams """
    +    delimiter = ','
    +    quotechar = '"'
    +    doublequote = True
    +    skipinitialspace = False
    +    lineterminator = '\r\n'
    +    if sys.version_info >= (3, 0) and sys.platform == 'win32':
    +        lineterminator = '\n'
    +    quoting = csv.QUOTE_MINIMAL
    +
    +
    +class InputHeader(dict):
    +    """ Represents a Splunk input header as a collection of name/value pairs.
    +
    +    """
    +
    +    def __str__(self):
    +        return '\n'.join([name + ':' + value for name, value in six.iteritems(self)])
    +
    +    def read(self, ifile):
    +        """ Reads an input header from an input file.
    +
    +        The input header is read as a sequence of *<name>***:***<value>* pairs separated by a newline. The end of the
    +        input header is signalled by an empty line or an end-of-file.
    +
    +        :param ifile: File-like object that supports iteration over lines.
    +
    +        """
    +        name, value = None, None
    +
    +        for line in ifile:
    +            if line == '\n':
    +                break
    +            item = line.split(':', 1)
    +            if len(item) == 2:
    +                # start of a new item
    +                if name is not None:
    +                    self[name] = value[:-1]  # value sans trailing newline
    +                name, value = item[0], urllib.parse.unquote(item[1])
    +            elif name is not None:
    +                # continuation of the current item
    +                value += urllib.parse.unquote(line)
    +
    +        if name is not None:
    +            self[name] = value[:-1] if value[-1] == '\n' else value
    +
    +
    +Message = namedtuple('Message', ('type', 'text'))
    +
    +
    +class MetadataDecoder(JSONDecoder):
    +
    +    def __init__(self):
    +        JSONDecoder.__init__(self, object_hook=self._object_hook)
    +
    +    @staticmethod
    +    def _object_hook(dictionary):
    +
    +        object_view = ObjectView(dictionary)
    +        stack = deque()
    +        stack.append((None, None, dictionary))
    +
    +        while len(stack):
    +            instance, member_name, dictionary = stack.popleft()
    +
    +            for name, value in six.iteritems(dictionary):
    +                if isinstance(value, dict):
    +                    stack.append((dictionary, name, value))
    +
    +            if instance is not None:
    +                instance[member_name] = ObjectView(dictionary)
    +
    +        return object_view
    +
    +
    +class MetadataEncoder(JSONEncoder):
    +
    +    def __init__(self):
    +        JSONEncoder.__init__(self, separators=MetadataEncoder._separators)
    +
    +    def default(self, o):
    +        return o.__dict__ if isinstance(o, ObjectView) else JSONEncoder.default(self, o)
    +
    +    _separators = (',', ':')
    +
    +
    +class ObjectView(object):
    +
    +    def __init__(self, dictionary):
    +        self.__dict__ = dictionary
    +
    +    def __repr__(self):
    +        return repr(self.__dict__)
    +
    +    def __str__(self):
    +        return str(self.__dict__)
    +
    +
    +class Recorder(object):
    +
    +    def __init__(self, path, f):
    +        self._recording = gzip.open(path + '.gz', 'wb')
    +        self._file = f
    +
    +    def __getattr__(self, name):
    +        return getattr(self._file, name)
    +
    +    def __iter__(self):
    +        for line in self._file:
    +            self._recording.write(line)
    +            self._recording.flush()
    +            yield line
    +
    +    def read(self, size=None):
    +        value = self._file.read() if size is None else self._file.read(size)
    +        self._recording.write(value)
    +        self._recording.flush()
    +        return value
    +
    +    def readline(self, size=None):
    +        value = self._file.readline() if size is None else self._file.readline(size)
    +        if len(value) > 0:
    +            self._recording.write(value)
    +            self._recording.flush()
    +        return value
    +
    +    def record(self, *args):
    +        for arg in args:
    +            self._recording.write(arg)
    +
    +    def write(self, text):
    +        self._recording.write(text)
    +        self._file.write(text)
    +        self._recording.flush()
    +
    +
    +class RecordWriter(object):
    +
    +    def __init__(self, ofile, maxresultrows=None):
    +        self._maxresultrows = 50000 if maxresultrows is None else maxresultrows
    +
    +        self._ofile = set_binary_mode(ofile)
    +        self._fieldnames = None
    +        self._buffer = StringIO()
    +
    +        self._writer = csv.writer(self._buffer, dialect=CsvDialect)
    +        self._writerow = self._writer.writerow
    +        self._finished = False
    +        self._flushed = False
    +
    +        self._inspector = OrderedDict()
    +        self._chunk_count = 0
    +        self._pending_record_count = 0
    +        self._committed_record_count = 0
    +        self.custom_fields = set()
    +
    +    @property
    +    def is_flushed(self):
    +        return self._flushed
    +
    +    @is_flushed.setter
    +    def is_flushed(self, value):
    +        self._flushed = True if value else False
    +
    +    @property
    +    def ofile(self):
    +        return self._ofile
    +
    +    @ofile.setter
    +    def ofile(self, value):
    +        self._ofile = set_binary_mode(value)
    +
    +    @property
    +    def pending_record_count(self):
    +        return self._pending_record_count
    +
    +    @property
    +    def _record_count(self):
    +        warnings.warn(
    +            "_record_count will be deprecated soon. Use pending_record_count instead.",
    +             PendingDeprecationWarning
    +        )
    +        return self.pending_record_count
    +
    +    @property
    +    def committed_record_count(self):
    +        return self._committed_record_count
    +
    +    @property
    +    def _total_record_count(self):
    +        warnings.warn(
    +            "_total_record_count will be deprecated soon. Use committed_record_count instead.",
    +             PendingDeprecationWarning
    +        )
    +        return self.committed_record_count
    +
    +    def write(self, data):
    +        bytes_type = bytes if sys.version_info >= (3, 0) else str
    +        if not isinstance(data, bytes_type):
    +            data = data.encode('utf-8')
    +        self.ofile.write(data)
    +
    +    def flush(self, finished=None, partial=None):
    +        assert finished is None or isinstance(finished, bool)
    +        assert partial is None or isinstance(partial, bool)
    +        assert not (finished is None and partial is None)
    +        assert finished is None or partial is None
    +        self._ensure_validity()
    +
    +    def write_message(self, message_type, message_text, *args, **kwargs):
    +        self._ensure_validity()
    +        self._inspector.setdefault('messages', []).append((message_type, message_text.format(*args, **kwargs)))
    +
    +    def write_record(self, record):
    +        self._ensure_validity()
    +        self._write_record(record)
    +
    +    def write_records(self, records):
    +        self._ensure_validity()
    +        records = list(records)
    +        write_record = self._write_record
    +        for record in records:
    +            write_record(record)
    +
    +    def _clear(self):
    +        self._buffer.seek(0)
    +        self._buffer.truncate()
    +        self._inspector.clear()
    +        self._pending_record_count = 0
    +
    +    def _ensure_validity(self):
    +        if self._finished is True:
    +            assert self._record_count == 0 and len(self._inspector) == 0
    +            raise RuntimeError('I/O operation on closed record writer')
    +
    +    def _write_record(self, record):
    +
    +        fieldnames = self._fieldnames
    +
    +        if fieldnames is None:
    +            self._fieldnames = fieldnames = list(record.keys())
    +            self._fieldnames.extend([i for i in self.custom_fields if i not in self._fieldnames])
    +            value_list = imap(lambda fn: (str(fn), str('__mv_') + str(fn)), fieldnames)
    +            self._writerow(list(chain.from_iterable(value_list)))
    +
    +        get_value = record.get
    +        values = []
    +
    +        for fieldname in fieldnames:
    +            value = get_value(fieldname, None)
    +
    +            if value is None:
    +                values += (None, None)
    +                continue
    +
    +            value_t = type(value)
    +
    +            if issubclass(value_t, (list, tuple)):
    +
    +                if len(value) == 0:
    +                    values += (None, None)
    +                    continue
    +
    +                if len(value) > 1:
    +                    value_list = value
    +                    sv = ''
    +                    mv = '$'
    +
    +                    for value in value_list:
    +
    +                        if value is None:
    +                            sv += '\n'
    +                            mv += '$;$'
    +                            continue
    +
    +                        value_t = type(value)
    +
    +                        if value_t is not bytes:
    +
    +                            if value_t is bool:
    +                                value = str(value.real)
    +                            elif value_t is six.text_type:
    +                                value = value
    +                            elif isinstance(value, six.integer_types) or value_t is float or value_t is complex:
    +                                value = str(value)
    +                            elif issubclass(value_t, (dict, list, tuple)):
    +                                value = str(''.join(RecordWriter._iterencode_json(value, 0)))
    +                            else:
    +                                value = repr(value).encode('utf-8', errors='backslashreplace')
    +
    +                        sv += value + '\n'
    +                        mv += value.replace('$', '$$') + '$;$'
    +
    +                    values += (sv[:-1], mv[:-2])
    +                    continue
    +
    +                value = value[0]
    +                value_t = type(value)
    +
    +            if value_t is bool:
    +                values += (str(value.real), None)
    +                continue
    +
    +            if value_t is bytes:
    +                values += (value, None)
    +                continue
    +
    +            if value_t is six.text_type:
    +                if six.PY2:
    +                    value = value.encode('utf-8')
    +                values += (value, None)
    +                continue
    +
    +            if isinstance(value, six.integer_types) or value_t is float or value_t is complex:
    +                values += (str(value), None)
    +                continue
    +
    +            if issubclass(value_t, dict):
    +                values += (str(''.join(RecordWriter._iterencode_json(value, 0))), None)
    +                continue
    +
    +            values += (repr(value), None)
    +
    +        self._writerow(values)
    +        self._pending_record_count += 1
    +
    +        if self.pending_record_count >= self._maxresultrows:
    +            self.flush(partial=True)
    +
    +    try:
    +        # noinspection PyUnresolvedReferences
    +        from _json import make_encoder
    +    except ImportError:
    +        # We may be running under PyPy 2.5 which does not include the _json module
    +        _iterencode_json = JSONEncoder(separators=(',', ':')).iterencode
    +    else:
    +        # Creating _iterencode_json this way yields a two-fold performance improvement on Python 2.7.9 and 2.7.10
    +        from json.encoder import encode_basestring_ascii
    +
    +        @staticmethod
    +        def _default(o):
    +            raise TypeError(repr(o) + ' is not JSON serializable')
    +
    +        _iterencode_json = make_encoder(
    +            {},                       # markers (for detecting circular references)
    +            _default,                 # object_encoder
    +            encode_basestring_ascii,  # string_encoder
    +            None,                     # indent
    +            ':', ',',                 # separators
    +            False,                    # sort_keys
    +            False,                    # skip_keys
    +            True                      # allow_nan
    +        )
    +
    +        del make_encoder
    +
    +
    +class RecordWriterV1(RecordWriter):
    +
    +    def flush(self, finished=None, partial=None):
    +
    +        RecordWriter.flush(self, finished, partial)  # validates arguments and the state of this instance
    +
    +        if self.pending_record_count > 0 or (self._chunk_count == 0 and 'messages' in self._inspector):
    +
    +            messages = self._inspector.get('messages')
    +
    +            if self._chunk_count == 0:
    +
    +                # Messages are written to the messages header when we write the first chunk of data
    +                # Guarantee: These messages are displayed by splunkweb and the job inspector
    +
    +                if messages is not None:
    +
    +                    message_level = RecordWriterV1._message_level.get
    +
    +                    for level, text in messages:
    +                        self.write(message_level(level, level))
    +                        self.write('=')
    +                        self.write(text)
    +                        self.write('\r\n')
    +
    +                self.write('\r\n')
    +
    +            elif messages is not None:
    +
    +                # Messages are written to the messages header when we write subsequent chunks of data
    +                # Guarantee: These messages are displayed by splunkweb and the job inspector, if and only if the
    +                # command is configured with
    +                #
    +                #       stderr_dest = message
    +                #
    +                # stderr_dest is a static configuration setting. This means that it can only be set in commands.conf.
    +                # It cannot be set in code.
    +
    +                stderr = sys.stderr
    +
    +                for level, text in messages:
    +                    print(level, text, file=stderr)
    +
    +            self.write(self._buffer.getvalue())
    +            self._chunk_count += 1
    +            self._committed_record_count += self.pending_record_count
    +            self._clear()
    +
    +        self._finished = finished is True
    +
    +    _message_level = {
    +        'DEBUG': 'debug_message',
    +        'ERROR': 'error_message',
    +        'FATAL': 'error_message',
    +        'INFO': 'info_message',
    +        'WARN': 'warn_message'
    +    }
    +
    +
    +class RecordWriterV2(RecordWriter):
    +
    +    def flush(self, finished=None, partial=None):
    +
    +        RecordWriter.flush(self, finished, partial)  # validates arguments and the state of this instance
    +
    +        if partial or not finished:
    +            # Don't flush partial chunks, since the SCP v2 protocol does not
    +            # provide a way to send partial chunks yet.
    +            return
    +
    +        if not self.is_flushed:
    +            self.write_chunk(finished=True)
    +
    +    def write_chunk(self, finished=None):
    +        inspector = self._inspector
    +        self._committed_record_count += self.pending_record_count
    +        self._chunk_count += 1
    +
    +        # TODO: DVPL-6448: splunklib.searchcommands | Add support for partial: true when it is implemented in
    +        # ChunkedExternProcessor (See SPL-103525)
    +        #
    +        # We will need to replace the following block of code with this block:
    +        #
    +        # metadata = [item for item in (('inspector', inspector), ('finished', finished), ('partial', partial))]
    +        #
    +        # if partial is True:
    +        #     finished = False
    +
    +        if len(inspector) == 0:
    +            inspector = None
    +
    +        metadata = [item for item in (('inspector', inspector), ('finished', finished))]
    +        self._write_chunk(metadata, self._buffer.getvalue())
    +        self._clear()
    +
    +    def write_metadata(self, configuration):
    +        self._ensure_validity()
    +
    +        metadata = chain(six.iteritems(configuration), (('inspector', self._inspector if self._inspector else None),))
    +        self._write_chunk(metadata, '')
    +        self.write('\n')
    +        self._clear()
    +
    +    def write_metric(self, name, value):
    +        self._ensure_validity()
    +        self._inspector['metric.' + name] = value
    +
    +    def _clear(self):
    +        super(RecordWriterV2, self)._clear()
    +        self._fieldnames = None
    +
    +    def _write_chunk(self, metadata, body):
    +
    +        if metadata:
    +            metadata = str(''.join(self._iterencode_json(dict([(n, v) for n, v in metadata if v is not None]), 0)))
    +            if sys.version_info >= (3, 0):
    +                metadata = metadata.encode('utf-8')
    +            metadata_length = len(metadata)
    +        else:
    +            metadata_length = 0
    +
    +        if sys.version_info >= (3, 0):
    +            body = body.encode('utf-8')
    +        body_length = len(body)
    +
    +        if not (metadata_length > 0 or body_length > 0):
    +            return
    +
    +        start_line = 'chunked 1.0,%s,%s\n' % (metadata_length, body_length)
    +        self.write(start_line)
    +        self.write(metadata)
    +        self.write(body)
    +        self._ofile.flush()
    +        self._flushed = True
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/reporting_command.py b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/reporting_command.py
    new file mode 100644
    index 0000000..9470861
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/reporting_command.py
    @@ -0,0 +1,281 @@
    +# coding=utf-8
    +#
    +# Copyright © 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import, division, print_function, unicode_literals
    +
    +from itertools import chain
    +
    +from .internals import ConfigurationSettingsType, json_encode_string
    +from .decorators import ConfigurationSetting, Option
    +from .streaming_command import StreamingCommand
    +from .search_command import SearchCommand
    +from .validators import Set
    +from splunklib import six
    +
    +
    +class ReportingCommand(SearchCommand):
    +    """ Processes search result records and generates a reporting data structure.
    +
    +    Reporting search commands run as either reduce or map/reduce operations. The reduce part runs on a search head and
    +    is responsible for processing a single chunk of search results to produce the command's reporting data structure.
    +    The map part is called a streaming preop. It feeds the reduce part with partial results and by default runs on the
    +    search head and/or one or more indexers.
    +
    +    You must implement a :meth:`reduce` method as a generator function that iterates over a set of event records and
    +    yields a reporting data structure. You may implement a :meth:`map` method as a generator function that iterates
    +    over a set of event records and yields :class:`dict` or :class:`list(dict)` instances.
    +
    +    ReportingCommand configuration
    +    ==============================
    +
    +    Configure the :meth:`map` operation using a Configuration decorator on your :meth:`map` method. Configure it like
    +    you would a :class:`StreamingCommand`. Configure the :meth:`reduce` operation using a Configuration decorator on
    +    your :meth:`ReportingCommand` class.
    +
    +    You can configure your command for operation under Search Command Protocol (SCP) version 1 or 2. SCP 2 requires
    +    Splunk 6.3 or later.
    +
    +    """
    +    # region Special methods
    +
    +    def __init__(self):
    +        SearchCommand.__init__(self)
    +
    +    # endregion
    +
    +    # region Options
    +
    +    phase = Option(doc='''
    +        **Syntax:** phase=[map|reduce]
    +
    +        **Description:** Identifies the phase of the current map-reduce operation.
    +
    +    ''', default='reduce', validate=Set('map', 'reduce'))
    +
    +    # endregion
    +
    +    # region Methods
    +
    +    def map(self, records):
    +        """ Override this method to compute partial results.
    +
    +        :param records:
    +        :type records:
    +
    +        You must override this method, if :code:`requires_preop=True`.
    +
    +        """
    +        return NotImplemented
    +
    +    def prepare(self):
    +
    +        phase = self.phase
    +
    +        if phase == 'map':
    +            # noinspection PyUnresolvedReferences
    +            self._configuration = self.map.ConfigurationSettings(self)
    +            return
    +
    +        if phase == 'reduce':
    +            streaming_preop = chain((self.name, 'phase="map"', str(self._options)), self.fieldnames)
    +            self._configuration.streaming_preop = ' '.join(streaming_preop)
    +            return
    +
    +        raise RuntimeError('Unrecognized reporting command phase: {}'.format(json_encode_string(six.text_type(phase))))
    +
    +    def reduce(self, records):
    +        """ Override this method to produce a reporting data structure.
    +
    +        You must override this method.
    +
    +        """
    +        raise NotImplementedError('reduce(self, records)')
    +
    +    def _execute(self, ifile, process):
    +        SearchCommand._execute(self, ifile, getattr(self, self.phase))
    +
    +    # endregion
    +
    +    # region Types
    +
    +    class ConfigurationSettings(SearchCommand.ConfigurationSettings):
    +        """ Represents the configuration settings for a :code:`ReportingCommand`.
    +
    +        """
    +        # region SCP v1/v2 Properties
    +
    +        required_fields = ConfigurationSetting(doc='''
    +            List of required fields for this search which back-propagates to the generating search.
    +
    +            Setting this value enables selected fields mode under SCP 2. Under SCP 1 you must also specify
    +            :code:`clear_required_fields=True` to enable selected fields mode. To explicitly select all fields,
    +            specify a value of :const:`['*']`. No error is generated if a specified field is missing.
    +
    +            Default: :const:`None`, which implicitly selects all fields.
    +
    +            Supported by: SCP 1, SCP 2
    +
    +            ''')
    +
    +        requires_preop = ConfigurationSetting(doc='''
    +            Indicates whether :meth:`ReportingCommand.map` is required for proper command execution.
    +
    +            If :const:`True`, :meth:`ReportingCommand.map` is guaranteed to be called. If :const:`False`, Splunk
    +            considers it to be an optimization that may be skipped.
    +
    +            Default: :const:`False`
    +
    +            Supported by: SCP 1, SCP 2
    +
    +            ''')
    +
    +        streaming_preop = ConfigurationSetting(doc='''
    +            Denotes the requested streaming preop search string.
    +
    +            Computed.
    +
    +            Supported by: SCP 1, SCP 2
    +
    +            ''')
    +
    +        # endregion
    +
    +        # region SCP v1 Properties
    +
    +        clear_required_fields = ConfigurationSetting(doc='''
    +            :const:`True`, if required_fields represent the *only* fields required.
    +
    +            If :const:`False`, required_fields are additive to any fields that may be required by subsequent commands.
    +            In most cases, :const:`True` is appropriate for reporting commands.
    +
    +            Default: :const:`True`
    +
    +            Supported by: SCP 1
    +
    +            ''')
    +
    +        retainsevents = ConfigurationSetting(readonly=True, value=False, doc='''
    +            Signals that :meth:`ReportingCommand.reduce` transforms _raw events to produce a reporting data structure.
    +
    +            Fixed: :const:`False`
    +
    +            Supported by: SCP 1
    +
    +            ''')
    +
    +        streaming = ConfigurationSetting(readonly=True, value=False, doc='''
    +            Signals that :meth:`ReportingCommand.reduce` runs on the search head.
    +
    +            Fixed: :const:`False`
    +
    +            Supported by: SCP 1
    +
    +            ''')
    +
    +        # endregion
    +
    +        # region SCP v2 Properties
    +
    +        maxinputs = ConfigurationSetting(doc='''
    +            Specifies the maximum number of events that can be passed to the command for each invocation.
    +
    +            This limit cannot exceed the value of `maxresultrows` in limits.conf_. Under SCP 1 you must specify this
    +            value in commands.conf_.
    +
    +            Default: The value of `maxresultrows`.
    +
    +            Supported by: SCP 2
    +
    +            .. _limits.conf: http://docs.splunk.com/Documentation/Splunk/latest/admin/Limitsconf
    +
    +            ''')
    +
    +        run_in_preview = ConfigurationSetting(doc='''
    +            :const:`True`, if this command should be run to generate results for preview; not wait for final output.
    +
    +            This may be important for commands that have side effects (e.g., outputlookup).
    +
    +            Default: :const:`True`
    +
    +            Supported by: SCP 2
    +
    +            ''')
    +
    +        type = ConfigurationSetting(readonly=True, value='reporting', doc='''
    +            Command type name.
    +
    +            Fixed: :const:`'reporting'`.
    +
    +            Supported by: SCP 2
    +
    +            ''')
    +
    +        # endregion
    +
    +        # region Methods
    +
    +        @classmethod
    +        def fix_up(cls, command):
    +            """ Verifies :code:`command` class structure and configures the :code:`command.map` method.
    +
    +            Verifies that :code:`command` derives from :class:`ReportingCommand` and overrides
    +            :code:`ReportingCommand.reduce`. It then configures :code:`command.reduce`, if an overriding implementation
    +            of :code:`ReportingCommand.reduce` has been provided.
    +
    +            :param command: :code:`ReportingCommand` class
    +
    +            Exceptions:
    +
    +            :code:`TypeError` :code:`command` class is not derived from :code:`ReportingCommand`
    +            :code:`AttributeError` No :code:`ReportingCommand.reduce` override
    +
    +            """
    +            if not issubclass(command, ReportingCommand):
    +                raise TypeError('{} is not a ReportingCommand'.format( command))
    +
    +            if command.reduce == ReportingCommand.reduce:
    +                raise AttributeError('No ReportingCommand.reduce override')
    +
    +            if command.map == ReportingCommand.map:
    +                cls._requires_preop = False
    +                return
    +
    +            f = vars(command)['map']   # Function backing the map method
    +
    +            # EXPLANATION OF PREVIOUS STATEMENT: There is no way to add custom attributes to methods. See [Why does
    +            # setattr fail on a method](http://stackoverflow.com/questions/7891277/why-does-setattr-fail-on-a-bound-method) for a discussion of this issue.
    +
    +            try:
    +                settings = f._settings
    +            except AttributeError:
    +                f.ConfigurationSettings = StreamingCommand.ConfigurationSettings
    +                return
    +
    +            # Create new StreamingCommand.ConfigurationSettings class
    +
    +            module = command.__module__ + '.' + command.__name__ + '.map'
    +            name = b'ConfigurationSettings'
    +            bases = (StreamingCommand.ConfigurationSettings,)
    +
    +            f.ConfigurationSettings = ConfigurationSettingsType(module, name, bases)
    +            ConfigurationSetting.fix_up(f.ConfigurationSettings, settings)
    +            del f._settings
    +
    +        pass
    +        # endregion
    +
    +    pass
    +    # endregion
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/search_command.py b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/search_command.py
    new file mode 100644
    index 0000000..dd11391
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/search_command.py
    @@ -0,0 +1,1154 @@
    +# coding=utf-8
    +#
    +# Copyright © 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import, division, print_function, unicode_literals
    +
    +# Absolute imports
    +
    +from collections import namedtuple
    +
    +import io
    +
    +from collections import OrderedDict
    +from copy import deepcopy
    +from splunklib.six.moves import StringIO
    +from itertools import chain, islice
    +from splunklib.six.moves import filter as ifilter, map as imap, zip as izip
    +from splunklib import six
    +if six.PY2:
    +    from logging import _levelNames, getLevelName, getLogger
    +else:
    +    from logging import _nameToLevel as _levelNames, getLevelName, getLogger
    +try:
    +    from shutil import make_archive
    +except ImportError:
    +    # Used for recording, skip on python 2.6
    +    pass
    +from time import time
    +from splunklib.six.moves.urllib.parse import unquote
    +from splunklib.six.moves.urllib.parse import urlsplit
    +from warnings import warn
    +from xml.etree import ElementTree
    +
    +import os
    +import sys
    +import re
    +import csv
    +import tempfile
    +import traceback
    +
    +# Relative imports
    +
    +from .internals import (
    +    CommandLineParser,
    +    CsvDialect,
    +    InputHeader,
    +    Message,
    +    MetadataDecoder,
    +    MetadataEncoder,
    +    ObjectView,
    +    Recorder,
    +    RecordWriterV1,
    +    RecordWriterV2,
    +    json_encode_string)
    +
    +from . import Boolean, Option, environment
    +from ..client import Service
    +
    +
    +# ----------------------------------------------------------------------------------------------------------------------
    +
    +# P1 [ ] TODO: Log these issues against ChunkedExternProcessor
    +#
    +# 1. Implement requires_preop configuration setting.
    +#    This configuration setting is currently rejected by ChunkedExternProcessor.
    +#
    +# 2. Rename type=events as type=eventing for symmetry with type=reporting and type=streaming
    +#    Eventing commands process records on the events pipeline. This change effects ChunkedExternProcessor.cpp,
    +#    eventing_command.py, and generating_command.py.
    +#
    +# 3. For consistency with SCPV1, commands.conf should not require filename setting when chunked = true
    +#    The SCPV1 processor uses <stanza-name>.py as the default filename. The ChunkedExternProcessor should do the same.
    +
    +# P1 [ ] TODO: Verify that ChunkedExternProcessor complains if a streaming_preop has a type other than 'streaming'
    +# It once looked like sending type='reporting' for the streaming_preop was accepted.
    +
    +# ----------------------------------------------------------------------------------------------------------------------
    +
    +# P2 [ ] TODO: Consider bumping None formatting up to Option.Item.__str__
    +
    +
    +class SearchCommand(object):
    +    """ Represents a custom search command.
    +
    +    """
    +
    +    def __init__(self):
    +
    +        # Variables that may be used, but not altered by derived classes
    +
    +        class_name = self.__class__.__name__
    +
    +        self._logger, self._logging_configuration = getLogger(class_name), environment.logging_configuration
    +
    +        # Variables backing option/property values
    +
    +        self._configuration = self.ConfigurationSettings(self)
    +        self._input_header = InputHeader()
    +        self._fieldnames = None
    +        self._finished = None
    +        self._metadata = None
    +        self._options = None
    +        self._protocol_version = None
    +        self._search_results_info = None
    +        self._service = None
    +
    +        # Internal variables
    +
    +        self._default_logging_level = self._logger.level
    +        self._record_writer = None
    +        self._records = None
    +        self._allow_empty_input = True
    +
    +    def __str__(self):
    +        text = ' '.join(chain((type(self).name, str(self.options)), [] if self.fieldnames is None else self.fieldnames))
    +        return text
    +
    +    # region Options
    +
    +    @Option
    +    def logging_configuration(self):
    +        """ **Syntax:** logging_configuration=<path>
    +
    +        **Description:** Loads an alternative logging configuration file for
    +        a command invocation. The logging configuration file must be in Python
    +        ConfigParser-format. Path names are relative to the app root directory.
    +
    +        """
    +        return self._logging_configuration
    +
    +    @logging_configuration.setter
    +    def logging_configuration(self, value):
    +        self._logger, self._logging_configuration = environment.configure_logging(self.__class__.__name__, value)
    +
    +    @Option
    +    def logging_level(self):
    +        """ **Syntax:** logging_level=[CRITICAL|ERROR|WARNING|INFO|DEBUG|NOTSET]
    +
    +        **Description:** Sets the threshold for the logger of this command invocation. Logging messages less severe than
    +        `logging_level` will be ignored.
    +
    +        """
    +        return getLevelName(self._logger.getEffectiveLevel())
    +
    +    @logging_level.setter
    +    def logging_level(self, value):
    +        if value is None:
    +            value = self._default_logging_level
    +        if isinstance(value, (bytes, six.text_type)):
    +            try:
    +                level = _levelNames[value.upper()]
    +            except KeyError:
    +                raise ValueError('Unrecognized logging level: {}'.format(value))
    +        else:
    +            try:
    +                level = int(value)
    +            except ValueError:
    +                raise ValueError('Unrecognized logging level: {}'.format(value))
    +        self._logger.setLevel(level)
    +
    +    def add_field(self, current_record, field_name, field_value):
    +        self._record_writer.custom_fields.add(field_name)
    +        current_record[field_name] = field_value
    +
    +    def gen_record(self, **record):
    +        self._record_writer.custom_fields |= set(record.keys())
    +        return record
    +
    +    record = Option(doc='''
    +        **Syntax: record=<bool>
    +
    +        **Description:** When `true`, records the interaction between the command and splunkd. Defaults to `false`.
    +
    +        ''', default=False, validate=Boolean())
    +
    +    show_configuration = Option(doc='''
    +        **Syntax:** show_configuration=<bool>
    +
    +        **Description:** When `true`, reports command configuration as an informational message. Defaults to `false`.
    +
    +        ''', default=False, validate=Boolean())
    +
    +    # endregion
    +
    +    # region Properties
    +
    +    @property
    +    def configuration(self):
    +        """ Returns the configuration settings for this command.
    +
    +        """
    +        return self._configuration
    +
    +    @property
    +    def fieldnames(self):
    +        """ Returns the fieldnames specified as argument to this command.
    +
    +        """
    +        return self._fieldnames
    +
    +    @fieldnames.setter
    +    def fieldnames(self, value):
    +        self._fieldnames = value
    +
    +    @property
    +    def input_header(self):
    +        """ Returns the input header for this command.
    +
    +        :return: The input header for this command.
    +        :rtype: InputHeader
    +
    +        """
    +        warn(
    +            'SearchCommand.input_header is deprecated and will be removed in a future release. '
    +            'Please use SearchCommand.metadata instead.', DeprecationWarning, 2)
    +        return self._input_header
    +
    +    @property
    +    def logger(self):
    +        """ Returns the logger for this command.
    +
    +        :return: The logger for this command.
    +        :rtype:
    +
    +        """
    +        return self._logger
    +
    +    @property
    +    def metadata(self):
    +        return self._metadata
    +
    +    @property
    +    def options(self):
    +        """ Returns the options specified as argument to this command.
    +
    +        """
    +        if self._options is None:
    +            self._options = Option.View(self)
    +        return self._options
    +
    +    @property
    +    def protocol_version(self):
    +        return self._protocol_version
    +
    +    @property
    +    def search_results_info(self):
    +        """ Returns the search results info for this command invocation.
    +
    +        The search results info object is created from the search results info file associated with the command
    +        invocation.
    +
    +        :return: Search results info:const:`None`, if the search results info file associated with the command
    +                 invocation is inaccessible.
    +        :rtype: SearchResultsInfo or NoneType
    +
    +        """
    +        if self._search_results_info is not None:
    +            return self._search_results_info
    +
    +        if self._protocol_version == 1:
    +            try:
    +                path = self._input_header['infoPath']
    +            except KeyError:
    +                return None
    +        else:
    +            assert self._protocol_version == 2
    +
    +            try:
    +                dispatch_dir = self._metadata.searchinfo.dispatch_dir
    +            except AttributeError:
    +                return None
    +
    +            path = os.path.join(dispatch_dir, 'info.csv')
    +
    +        try:
    +            with io.open(path, 'r') as f:
    +                reader = csv.reader(f, dialect=CsvDialect)
    +                fields = next(reader)
    +                values = next(reader)
    +        except IOError as error:
    +            if error.errno == 2:
    +                self.logger.error('Search results info file {} does not exist.'.format(json_encode_string(path)))
    +                return
    +            raise
    +
    +        def convert_field(field):
    +            return (field[1:] if field[0] == '_' else field).replace('.', '_')
    +
    +        decode = MetadataDecoder().decode
    +
    +        def convert_value(value):
    +            try:
    +                return decode(value) if len(value) > 0 else value
    +            except ValueError:
    +                return value
    +
    +        info = ObjectView(dict(imap(lambda f_v: (convert_field(f_v[0]), convert_value(f_v[1])), izip(fields, values))))
    +
    +        try:
    +            count_map = info.countMap
    +        except AttributeError:
    +            pass
    +        else:
    +            count_map = count_map.split(';')
    +            n = len(count_map)
    +            info.countMap = dict(izip(islice(count_map, 0, n, 2), islice(count_map, 1, n, 2)))
    +
    +        try:
    +            msg_type = info.msgType
    +            msg_text = info.msg
    +        except AttributeError:
    +            pass
    +        else:
    +            messages = ifilter(lambda t_m: t_m[0] or t_m[1], izip(msg_type.split('\n'), msg_text.split('\n')))
    +            info.msg = [Message(message) for message in messages]
    +            del info.msgType
    +
    +        try:
    +            info.vix_families = ElementTree.fromstring(info.vix_families)
    +        except AttributeError:
    +            pass
    +
    +        self._search_results_info = info
    +        return info
    +
    +    @property
    +    def service(self):
    +        """ Returns a Splunk service object for this command invocation or None.
    +
    +        The service object is created from the Splunkd URI and authentication token passed to the command invocation in
    +        the search results info file. This data is not passed to a command invocation by default. You must request it by
    +        specifying this pair of configuration settings in commands.conf:
    +
    +           .. code-block:: python
    +
    +               enableheader = true
    +               requires_srinfo = true
    +
    +        The :code:`enableheader` setting is :code:`true` by default. Hence, you need not set it. The
    +        :code:`requires_srinfo` setting is false by default. Hence, you must set it.
    +
    +        :return: :class:`splunklib.client.Service`, if :code:`enableheader` and :code:`requires_srinfo` are both
    +            :code:`true`. Otherwise, if either :code:`enableheader` or :code:`requires_srinfo` are :code:`false`, a value
    +            of :code:`None` is returned.
    +
    +        """
    +        if self._service is not None:
    +            return self._service
    +
    +        metadata = self._metadata
    +
    +        if metadata is None:
    +            return None
    +
    +        try:
    +            searchinfo = self._metadata.searchinfo
    +        except AttributeError:
    +            return None
    +
    +        splunkd_uri = searchinfo.splunkd_uri
    +
    +        if splunkd_uri is None:
    +            return None
    +
    +        uri = urlsplit(splunkd_uri, allow_fragments=False)
    +
    +        self._service = Service(
    +            scheme=uri.scheme, host=uri.hostname, port=uri.port, app=searchinfo.app, token=searchinfo.session_key)
    +
    +        return self._service
    +
    +    # endregion
    +
    +    # region Methods
    +
    +    def error_exit(self, error, message=None):
    +        self.write_error(error.message if message is None else message)
    +        self.logger.error('Abnormal exit: %s', error)
    +        exit(1)
    +
    +    def finish(self):
    +        """ Flushes the output buffer and signals that this command has finished processing data.
    +
    +        :return: :const:`None`
    +
    +        """
    +        self._record_writer.flush(finished=True)
    +
    +    def flush(self):
    +        """ Flushes the output buffer.
    +
    +        :return: :const:`None`
    +
    +        """
    +        self._record_writer.flush(finished=False)
    +
    +    def prepare(self):
    +        """ Prepare for execution.
    +
    +        This method should be overridden in search command classes that wish to examine and update their configuration
    +        or option settings prior to execution. It is called during the getinfo exchange before command metadata is sent
    +        to splunkd.
    +
    +        :return: :const:`None`
    +        :rtype: NoneType
    +
    +        """
    +        pass
    +
    +    def process(self, argv=sys.argv, ifile=sys.stdin, ofile=sys.stdout, allow_empty_input=True):
    +        """ Process data.
    +
    +        :param argv: Command line arguments.
    +        :type argv: list or tuple
    +
    +        :param ifile: Input data file.
    +        :type ifile: file
    +
    +        :param ofile: Output data file.
    +        :type ofile: file
    +
    +        :param allow_empty_input: Allow empty input records for the command, if False an Error will be returned if empty chunk body is encountered when read
    +        :type allow_empty_input: bool
    +
    +        :return: :const:`None`
    +        :rtype: NoneType
    +
    +        """
    +
    +        self._allow_empty_input = allow_empty_input
    +
    +        if len(argv) > 1:
    +            self._process_protocol_v1(argv, ifile, ofile)
    +        else:
    +            self._process_protocol_v2(argv, ifile, ofile)
    +
    +    def _map_input_header(self):
    +        metadata = self._metadata
    +        searchinfo = metadata.searchinfo
    +        self._input_header.update(
    +            allowStream=None,
    +            infoPath=os.path.join(searchinfo.dispatch_dir, 'info.csv'),
    +            keywords=None,
    +            preview=metadata.preview,
    +            realtime=searchinfo.earliest_time != 0 and searchinfo.latest_time != 0,
    +            search=searchinfo.search,
    +            sid=searchinfo.sid,
    +            splunkVersion=searchinfo.splunk_version,
    +            truncated=None)
    +
    +    def _map_metadata(self, argv):
    +        source = SearchCommand._MetadataSource(argv, self._input_header, self.search_results_info)
    +
    +        def _map(metadata_map):
    +            metadata = {}
    +
    +            for name, value in six.iteritems(metadata_map):
    +                if isinstance(value, dict):
    +                    value = _map(value)
    +                else:
    +                    transform, extract = value
    +                    if extract is None:
    +                        value = None
    +                    else:
    +                        value = extract(source)
    +                        if not (value is None or transform is None):
    +                            value = transform(value)
    +                metadata[name] = value
    +
    +            return ObjectView(metadata)
    +
    +        self._metadata = _map(SearchCommand._metadata_map)
    +
    +    _metadata_map = {
    +        'action':
    +            (lambda v: 'getinfo' if v == '__GETINFO__' else 'execute' if v == '__EXECUTE__' else None, lambda s: s.argv[1]),
    +        'preview':
    +            (bool, lambda s: s.input_header.get('preview')),
    +        'searchinfo': {
    +            'app':
    +                (lambda v: v.ppc_app, lambda s: s.search_results_info),
    +            'args':
    +                (None, lambda s: s.argv),
    +            'dispatch_dir':
    +                (os.path.dirname, lambda s: s.input_header.get('infoPath')),
    +            'earliest_time':
    +                (lambda v: float(v.rt_earliest) if len(v.rt_earliest) > 0 else 0.0, lambda s: s.search_results_info),
    +            'latest_time':
    +                (lambda v: float(v.rt_latest) if len(v.rt_latest) > 0 else 0.0, lambda s: s.search_results_info),
    +            'owner':
    +                (None, None),
    +            'raw_args':
    +                (None, lambda s: s.argv),
    +            'search':
    +                (unquote, lambda s: s.input_header.get('search')),
    +            'session_key':
    +                (lambda v: v.auth_token, lambda s: s.search_results_info),
    +            'sid':
    +                (None, lambda s: s.input_header.get('sid')),
    +            'splunk_version':
    +                (None, lambda s: s.input_header.get('splunkVersion')),
    +            'splunkd_uri':
    +                (lambda v: v.splunkd_uri, lambda s: s.search_results_info),
    +            'username':
    +                (lambda v: v.ppc_user, lambda s: s.search_results_info)}}
    +
    +    _MetadataSource = namedtuple('Source', ('argv', 'input_header', 'search_results_info'))
    +
    +    def _prepare_protocol_v1(self, argv, ifile, ofile):
    +
    +        debug = environment.splunklib_logger.debug
    +
    +        # Provide as much context as possible in advance of parsing the command line and preparing for execution
    +
    +        self._input_header.read(ifile)
    +        self._protocol_version = 1
    +        self._map_metadata(argv)
    +
    +        debug('  metadata=%r, input_header=%r', self._metadata, self._input_header)
    +
    +        try:
    +            tempfile.tempdir = self._metadata.searchinfo.dispatch_dir
    +        except AttributeError:
    +            raise RuntimeError('{}.metadata.searchinfo.dispatch_dir is undefined'.format(self.__class__.__name__))
    +
    +        debug('  tempfile.tempdir=%r', tempfile.tempdir)
    +
    +        CommandLineParser.parse(self, argv[2:])
    +        self.prepare()
    +
    +        if self.record:
    +            self.record = False
    +
    +            record_argv = [argv[0], argv[1], str(self._options), ' '.join(self.fieldnames)]
    +            ifile, ofile = self._prepare_recording(record_argv, ifile, ofile)
    +            self._record_writer.ofile = ofile
    +            ifile.record(str(self._input_header), '\n\n')
    +
    +        if self.show_configuration:
    +            self.write_info(self.name + ' command configuration: ' + str(self._configuration))
    +
    +        return ifile  # wrapped, if self.record is True
    +
    +    def _prepare_recording(self, argv, ifile, ofile):
    +
    +        # Create the recordings directory, if it doesn't already exist
    +
    +        recordings = os.path.join(environment.splunk_home, 'var', 'run', 'splunklib.searchcommands', 'recordings')
    +
    +        if not os.path.isdir(recordings):
    +            os.makedirs(recordings)
    +
    +        # Create input/output recorders from ifile and ofile
    +
    +        recording = os.path.join(recordings, self.__class__.__name__ + '-' + repr(time()) + '.' + self._metadata.action)
    +        ifile = Recorder(recording + '.input', ifile)
    +        ofile = Recorder(recording + '.output', ofile)
    +
    +        # Archive the dispatch directory--if it exists--so that it can be used as a baseline in mocks)
    +
    +        dispatch_dir = self._metadata.searchinfo.dispatch_dir
    +
    +        if dispatch_dir is not None:  # __GETINFO__ action does not include a dispatch_dir
    +            root_dir, base_dir = os.path.split(dispatch_dir)
    +            make_archive(recording + '.dispatch_dir', 'gztar', root_dir, base_dir, logger=self.logger)
    +
    +        # Save a splunk command line because it is useful for developing tests
    +
    +        with open(recording + '.splunk_cmd', 'wb') as f:
    +            f.write('splunk cmd python '.encode())
    +            f.write(os.path.basename(argv[0]).encode())
    +            for arg in islice(argv, 1, len(argv)):
    +                f.write(' '.encode())
    +                f.write(arg.encode())
    +
    +        return ifile, ofile
    +
    +    def _process_protocol_v1(self, argv, ifile, ofile):
    +
    +        debug = environment.splunklib_logger.debug
    +        class_name = self.__class__.__name__
    +
    +        debug('%s.process started under protocol_version=1', class_name)
    +        self._record_writer = RecordWriterV1(ofile)
    +
    +        # noinspection PyBroadException
    +        try:
    +            if argv[1] == '__GETINFO__':
    +
    +                debug('Writing configuration settings')
    +
    +                ifile = self._prepare_protocol_v1(argv, ifile, ofile)
    +                self._record_writer.write_record(dict(
    +                    (n, ','.join(v) if isinstance(v, (list, tuple)) else v) for n, v in six.iteritems(self._configuration)))
    +                self.finish()
    +
    +            elif argv[1] == '__EXECUTE__':
    +
    +                debug('Executing')
    +
    +                ifile = self._prepare_protocol_v1(argv, ifile, ofile)
    +                self._records = self._records_protocol_v1
    +                self._metadata.action = 'execute'
    +                self._execute(ifile, None)
    +
    +            else:
    +                message = (
    +                    'Command {0} appears to be statically configured for search command protocol version 1 and static '
    +                    'configuration is unsupported by splunklib.searchcommands. Please ensure that '
    +                    'default/commands.conf contains this stanza:\n'
    +                    '[{0}]\n'
    +                    'filename = {1}\n'
    +                    'enableheader = true\n'
    +                    'outputheader = true\n'
    +                    'requires_srinfo = true\n'
    +                    'supports_getinfo = true\n'
    +                    'supports_multivalues = true\n'
    +                    'supports_rawargs = true'.format(self.name, os.path.basename(argv[0])))
    +                raise RuntimeError(message)
    +
    +        except (SyntaxError, ValueError) as error:
    +            self.write_error(six.text_type(error))
    +            self.flush()
    +            exit(0)
    +
    +        except SystemExit:
    +            self.flush()
    +            raise
    +
    +        except:
    +            self._report_unexpected_error()
    +            self.flush()
    +            exit(1)
    +
    +        debug('%s.process finished under protocol_version=1', class_name)
    +
    +    def _protocol_v2_option_parser(self, arg):
    +        """ Determines if an argument is an Option/Value pair, or just a Positional Argument.
    +            Method so different search commands can handle parsing of arguments differently.
    +
    +            :param arg: A single argument provided to the command from SPL
    +            :type arg: str
    +
    +            :return: [OptionName, OptionValue] OR [PositionalArgument]
    +            :rtype: List[str]
    +
    +        """
    +        return arg.split('=', 1)
    +
    +    def _process_protocol_v2(self, argv, ifile, ofile):
    +        """ Processes records on the `input stream optionally writing records to the output stream.
    +
    +        :param ifile: Input file object.
    +        :type ifile: file or InputType
    +
    +        :param ofile: Output file object.
    +        :type ofile: file or OutputType
    +
    +        :return: :const:`None`
    +
    +        """
    +        debug = environment.splunklib_logger.debug
    +        class_name = self.__class__.__name__
    +
    +        debug('%s.process started under protocol_version=2', class_name)
    +        self._protocol_version = 2
    +
    +        # Read search command metadata from splunkd
    +        # noinspection PyBroadException
    +        try:
    +            debug('Reading metadata')
    +            metadata, body = self._read_chunk(self._as_binary_stream(ifile))
    +
    +            action = getattr(metadata, 'action', None)
    +
    +            if action != 'getinfo':
    +                raise RuntimeError('Expected getinfo action, not {}'.format(action))
    +
    +            if len(body) > 0:
    +                raise RuntimeError('Did not expect data for getinfo action')
    +
    +            self._metadata = deepcopy(metadata)
    +
    +            searchinfo = self._metadata.searchinfo
    +
    +            searchinfo.earliest_time = float(searchinfo.earliest_time)
    +            searchinfo.latest_time = float(searchinfo.latest_time)
    +            searchinfo.search = unquote(searchinfo.search)
    +
    +            self._map_input_header()
    +
    +            debug('  metadata=%r, input_header=%r', self._metadata, self._input_header)
    +
    +            try:
    +                tempfile.tempdir = self._metadata.searchinfo.dispatch_dir
    +            except AttributeError:
    +                raise RuntimeError('%s.metadata.searchinfo.dispatch_dir is undefined'.format(class_name))
    +
    +            debug('  tempfile.tempdir=%r', tempfile.tempdir)
    +        except:
    +            self._record_writer = RecordWriterV2(ofile)
    +            self._report_unexpected_error()
    +            self.finish()
    +            exit(1)
    +
    +        # Write search command configuration for consumption by splunkd
    +        # noinspection PyBroadException
    +        try:
    +            self._record_writer = RecordWriterV2(ofile, getattr(self._metadata.searchinfo, 'maxresultrows', None))
    +            self.fieldnames = []
    +            self.options.reset()
    +
    +            args = self.metadata.searchinfo.args
    +            error_count = 0
    +
    +            debug('Parsing arguments')
    +
    +            if args and type(args) == list:
    +                for arg in args:
    +                    result = self._protocol_v2_option_parser(arg)
    +                    if len(result) == 1:
    +                        self.fieldnames.append(str(result[0]))
    +                    else:
    +                        name, value = result
    +                        name = str(name)
    +                        try:
    +                            option = self.options[name]
    +                        except KeyError:
    +                            self.write_error('Unrecognized option: {}={}'.format(name, value))
    +                            error_count += 1
    +                            continue
    +                        try:
    +                            option.value = value
    +                        except ValueError:
    +                            self.write_error('Illegal value: {}={}'.format(name, value))
    +                            error_count += 1
    +                            continue
    +
    +            missing = self.options.get_missing()
    +
    +            if missing is not None:
    +                if len(missing) == 1:
    +                    self.write_error('A value for "{}" is required'.format(missing[0]))
    +                else:
    +                    self.write_error('Values for these required options are missing: {}'.format(', '.join(missing)))
    +                error_count += 1
    +
    +            if error_count > 0:
    +                exit(1)
    +
    +            debug('  command: %s', six.text_type(self))
    +
    +            debug('Preparing for execution')
    +            self.prepare()
    +
    +            if self.record:
    +
    +                ifile, ofile = self._prepare_recording(argv, ifile, ofile)
    +                self._record_writer.ofile = ofile
    +
    +                # Record the metadata that initiated this command after removing the record option from args/raw_args
    +
    +                info = self._metadata.searchinfo
    +
    +                for attr in 'args', 'raw_args':
    +                    setattr(info, attr, [arg for arg in getattr(info, attr) if not arg.startswith('record=')])
    +
    +                metadata = MetadataEncoder().encode(self._metadata)
    +                ifile.record('chunked 1.0,', six.text_type(len(metadata)), ',0\n', metadata)
    +
    +            if self.show_configuration:
    +                self.write_info(self.name + ' command configuration: ' + str(self._configuration))
    +
    +            debug('  command configuration: %s', self._configuration)
    +
    +        except SystemExit:
    +            self._record_writer.write_metadata(self._configuration)
    +            self.finish()
    +            raise
    +        except:
    +            self._record_writer.write_metadata(self._configuration)
    +            self._report_unexpected_error()
    +            self.finish()
    +            exit(1)
    +
    +        self._record_writer.write_metadata(self._configuration)
    +
    +        # Execute search command on data passing through the pipeline
    +        # noinspection PyBroadException
    +        try:
    +            debug('Executing under protocol_version=2')
    +            self._metadata.action = 'execute'
    +            self._execute(ifile, None)
    +        except SystemExit:
    +            self.finish()
    +            raise
    +        except:
    +            self._report_unexpected_error()
    +            self.finish()
    +            exit(1)
    +
    +        debug('%s.process completed', class_name)
    +
    +    def write_debug(self, message, *args):
    +        self._record_writer.write_message('DEBUG', message, *args)
    +
    +    def write_error(self, message, *args):
    +        self._record_writer.write_message('ERROR', message, *args)
    +
    +    def write_fatal(self, message, *args):
    +        self._record_writer.write_message('FATAL', message, *args)
    +
    +    def write_info(self, message, *args):
    +        self._record_writer.write_message('INFO', message, *args)
    +
    +    def write_warning(self, message, *args):
    +        self._record_writer.write_message('WARN', message, *args)
    +
    +    def write_metric(self, name, value):
    +        """ Writes a metric that will be added to the search inspector.
    +
    +        :param name: Name of the metric.
    +        :type name: basestring
    +
    +        :param value: A 4-tuple containing the value of metric ``name`` where
    +
    +            value[0] = Elapsed seconds or :const:`None`.
    +            value[1] = Number of invocations or :const:`None`.
    +            value[2] = Input count or :const:`None`.
    +            value[3] = Output count or :const:`None`.
    +
    +        The :data:`SearchMetric` type provides a convenient encapsulation of ``value``.
    +        The :data:`SearchMetric` type provides a convenient encapsulation of ``value``.
    +
    +        :return: :const:`None`.
    +
    +        """
    +        self._record_writer.write_metric(name, value)
    +
    +    # P2 [ ] TODO: Support custom inspector values
    +
    +    @staticmethod
    +    def _decode_list(mv):
    +        return [match.replace('$$', '$') for match in SearchCommand._encoded_value.findall(mv)]
    +
    +    _encoded_value = re.compile(r'\$(?P<item>(?:\$\$|[^$])*)\$(?:;|$)')  # matches a single value in an encoded list
    +
    +    # Note: Subclasses must override this method so that it can be called
    +    # called as self._execute(ifile, None)
    +    def _execute(self, ifile, process):
    +        """ Default processing loop
    +
    +        :param ifile: Input file object.
    +        :type ifile: file
    +
    +        :param process: Bound method to call in processing loop.
    +        :type process: instancemethod
    +
    +        :return: :const:`None`.
    +        :rtype: NoneType
    +
    +        """
    +        if self.protocol_version == 1:
    +            self._record_writer.write_records(process(self._records(ifile)))
    +            self.finish()
    +        else:
    +            assert self._protocol_version == 2
    +            self._execute_v2(ifile, process)
    +
    +    @staticmethod
    +    def _as_binary_stream(ifile):
    +        naught = ifile.read(0)
    +        if isinstance(naught, bytes):
    +            return ifile
    +
    +        try:
    +            return ifile.buffer
    +        except AttributeError as error:
    +            raise RuntimeError('Failed to get underlying buffer: {}'.format(error))
    +
    +    @staticmethod
    +    def _read_chunk(istream):
    +        # noinspection PyBroadException
    +        assert isinstance(istream.read(0), six.binary_type), 'Stream must be binary'
    +
    +        try:
    +            header = istream.readline()
    +        except Exception as error:
    +            raise RuntimeError('Failed to read transport header: {}'.format(error))
    +
    +        if not header:
    +            return None
    +
    +        match = SearchCommand._header.match(six.ensure_str(header))
    +
    +        if match is None:
    +            raise RuntimeError('Failed to parse transport header: {}'.format(header))
    +
    +        metadata_length, body_length = match.groups()
    +        metadata_length = int(metadata_length)
    +        body_length = int(body_length)
    +
    +        try:
    +            metadata = istream.read(metadata_length)
    +        except Exception as error:
    +            raise RuntimeError('Failed to read metadata of length {}: {}'.format(metadata_length, error))
    +
    +        decoder = MetadataDecoder()
    +
    +        try:
    +            metadata = decoder.decode(six.ensure_str(metadata))
    +        except Exception as error:
    +            raise RuntimeError('Failed to parse metadata of length {}: {}'.format(metadata_length, error))
    +
    +        # if body_length <= 0:
    +        #     return metadata, ''
    +
    +        body = ""
    +        try:
    +            if body_length > 0:
    +                body = istream.read(body_length)
    +        except Exception as error:
    +            raise RuntimeError('Failed to read body of length {}: {}'.format(body_length, error))
    +
    +        return metadata, six.ensure_str(body)
    +
    +    _header = re.compile(r'chunked\s+1.0\s*,\s*(\d+)\s*,\s*(\d+)\s*\n')
    +
    +    def _records_protocol_v1(self, ifile):
    +        return self._read_csv_records(ifile)
    +
    +    def _read_csv_records(self, ifile):
    +        reader = csv.reader(ifile, dialect=CsvDialect)
    +
    +        try:
    +            fieldnames = next(reader)
    +        except StopIteration:
    +            return
    +
    +        mv_fieldnames = dict([(name, name[len('__mv_'):]) for name in fieldnames if name.startswith('__mv_')])
    +
    +        if len(mv_fieldnames) == 0:
    +            for values in reader:
    +                yield OrderedDict(izip(fieldnames, values))
    +            return
    +
    +        for values in reader:
    +            record = OrderedDict()
    +            for fieldname, value in izip(fieldnames, values):
    +                if fieldname.startswith('__mv_'):
    +                    if len(value) > 0:
    +                        record[mv_fieldnames[fieldname]] = self._decode_list(value)
    +                elif fieldname not in record:
    +                    record[fieldname] = value
    +            yield record
    +
    +    def _execute_v2(self, ifile, process):
    +        istream = self._as_binary_stream(ifile)
    +
    +        while True:
    +            result = self._read_chunk(istream)
    +
    +            if not result:
    +                return
    +
    +            metadata, body = result
    +            action = getattr(metadata, 'action', None)
    +            if action != 'execute':
    +                raise RuntimeError('Expected execute action, not {}'.format(action))
    +
    +            self._finished = getattr(metadata, 'finished', False)
    +            self._record_writer.is_flushed = False
    +
    +            self._execute_chunk_v2(process, result)
    +
    +            self._record_writer.write_chunk(finished=self._finished)
    +
    +    def _execute_chunk_v2(self, process, chunk):
    +            metadata, body = chunk
    +
    +            if len(body) <= 0 and not self._allow_empty_input:
    +                raise ValueError(
    +                    "No records found to process. Set allow_empty_input=True in dispatch function to move forward "
    +                    "with empty records.")
    +
    +            records = self._read_csv_records(StringIO(body))
    +            self._record_writer.write_records(process(records))
    +
    +    def _report_unexpected_error(self):
    +
    +        error_type, error, tb = sys.exc_info()
    +        origin = tb
    +
    +        while origin.tb_next is not None:
    +            origin = origin.tb_next
    +
    +        filename = origin.tb_frame.f_code.co_filename
    +        lineno = origin.tb_lineno
    +        message = '{0} at "{1}", line {2:d} : {3}'.format(error_type.__name__, filename, lineno, error)
    +
    +        environment.splunklib_logger.error(message + '\nTraceback:\n' + ''.join(traceback.format_tb(tb)))
    +        self.write_error(message)
    +
    +    # endregion
    +
    +    # region Types
    +
    +    class ConfigurationSettings(object):
    +        """ Represents the configuration settings common to all :class:`SearchCommand` classes.
    +
    +        """
    +        def __init__(self, command):
    +            self.command = command
    +
    +        def __repr__(self):
    +            """ Converts the value of this instance to its string representation.
    +
    +            The value of this ConfigurationSettings instance is represented as a string of comma-separated
    +            :code:`(name, value)` pairs.
    +
    +            :return: String representation of this instance
    +
    +            """
    +            definitions = type(self).configuration_setting_definitions
    +            settings = imap(
    +                lambda setting: repr((setting.name, setting.__get__(self), setting.supporting_protocols)), definitions)
    +            return '[' + ', '.join(settings) + ']'
    +
    +        def __str__(self):
    +            """ Converts the value of this instance to its string representation.
    +
    +            The value of this ConfigurationSettings instance is represented as a string of comma-separated
    +            :code:`name=value` pairs. Items with values of :const:`None` are filtered from the list.
    +
    +            :return: String representation of this instance
    +
    +            """
    +            #text = ', '.join(imap(lambda (name, value): name + '=' + json_encode_string(unicode(value)), self.iteritems()))
    +            text = ', '.join(['{}={}'.format(name, json_encode_string(six.text_type(value))) for (name, value) in six.iteritems(self)])
    +            return text
    +
    +        # region Methods
    +
    +        @classmethod
    +        def fix_up(cls, command_class):
    +            """ Adjusts and checks this class and its search command class.
    +
    +            Derived classes typically override this method. It is used by the :decorator:`Configuration` decorator to
    +            fix up the :class:`SearchCommand` class it adorns. This method is overridden by :class:`EventingCommand`,
    +            :class:`GeneratingCommand`, :class:`ReportingCommand`, and :class:`StreamingCommand`, the base types for
    +            all other search commands.
    +
    +            :param command_class: Command class targeted by this class
    +
    +            """
    +            return
    +
    +        # TODO: Stop looking like a dictionary because we don't obey the semantics
    +        # N.B.: Does not use Python 2 dict copy semantics
    +        def iteritems(self):
    +            definitions = type(self).configuration_setting_definitions
    +            version = self.command.protocol_version
    +            return ifilter(
    +                lambda name_value1: name_value1[1] is not None, imap(
    +                    lambda setting: (setting.name, setting.__get__(self)), ifilter(
    +                        lambda setting: setting.is_supported_by_protocol(version), definitions)))
    +
    +        # N.B.: Does not use Python 3 dict view semantics
    +        if not six.PY2:
    +            items = iteritems
    +
    +        pass  # endregion
    +
    +    pass  # endregion
    +
    +
    +SearchMetric = namedtuple('SearchMetric', ('elapsed_seconds', 'invocation_count', 'input_count', 'output_count'))
    +
    +
    +def dispatch(command_class, argv=sys.argv, input_file=sys.stdin, output_file=sys.stdout, module_name=None, allow_empty_input=True):
    +    """ Instantiates and executes a search command class
    +
    +    This function implements a `conditional script stanza <https://docs.python.org/2/library/__main__.html>`_ based on the value of
    +    :code:`module_name`::
    +
    +        if module_name is None or module_name == '__main__':
    +            # execute command
    +
    +    Call this function at module scope with :code:`module_name=__name__`, if you would like your module to act as either
    +    a reusable module or a standalone program. Otherwise, if you wish this function to unconditionally instantiate and
    +    execute :code:`command_class`, pass :const:`None` as the value of :code:`module_name`.
    +
    +    :param command_class: Search command class to instantiate and execute.
    +    :type command_class: type
    +    :param argv: List of arguments to the command.
    +    :type argv: list or tuple
    +    :param input_file: File from which the command will read data.
    +    :type input_file: :code:`file`
    +    :param output_file: File to which the command will write data.
    +    :type output_file: :code:`file`
    +    :param module_name: Name of the module calling :code:`dispatch` or :const:`None`.
    +    :type module_name: :code:`basestring`
    +    :param allow_empty_input: Allow empty input records for the command, if False an Error will be returned if empty chunk body is encountered when read
    +    :type allow_empty_input: bool
    +    :returns: :const:`None`
    +
    +    **Example**
    +
    +    ..  code-block:: python
    +        :linenos:
    +
    +        #!/usr/bin/env python
    +        from splunklib.searchcommands import dispatch, StreamingCommand, Configuration, Option, validators
    +        @Configuration()
    +        class SomeStreamingCommand(StreamingCommand):
    +            ...
    +            def stream(records):
    +                ...
    +        dispatch(SomeStreamingCommand, module_name=__name__)
    +
    +    Dispatches the :code:`SomeStreamingCommand`, if and only if :code:`__name__` is equal to :code:`'__main__'`.
    +
    +    **Example**
    +
    +    ..  code-block:: python
    +        :linenos:
    +
    +        from splunklib.searchcommands import dispatch, StreamingCommand, Configuration, Option, validators
    +        @Configuration()
    +        class SomeStreamingCommand(StreamingCommand):
    +            ...
    +            def stream(records):
    +                ...
    +        dispatch(SomeStreamingCommand)
    +
    +    Unconditionally dispatches :code:`SomeStreamingCommand`.
    +
    +    """
    +    assert issubclass(command_class, SearchCommand)
    +
    +    if module_name is None or module_name == '__main__':
    +        command_class().process(argv, input_file, output_file, allow_empty_input)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/streaming_command.py b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/streaming_command.py
    new file mode 100644
    index 0000000..fa075ed
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/streaming_command.py
    @@ -0,0 +1,195 @@
    +# coding=utf-8
    +#
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import, division, print_function, unicode_literals
    +
    +from splunklib import six
    +from splunklib.six.moves import map as imap, filter as ifilter
    +
    +from .decorators import ConfigurationSetting
    +from .search_command import SearchCommand
    +
    +
    +class StreamingCommand(SearchCommand):
    +    """ Applies a transformation to search results as they travel through the streams pipeline.
    +
    +    Streaming commands typically filter, augment, or update, search result records. Splunk will send them in batches of
    +    up to 50,000 records. Hence, a search command must be prepared to be invoked many times during the course of
    +    pipeline processing. Each invocation should produce a set of results independently usable by downstream processors.
    +
    +    By default Splunk may choose to run a streaming command locally on a search head and/or remotely on one or more
    +    indexers concurrently. The size and frequency of the search result batches sent to the command will vary based
    +    on scheduling considerations.
    +
    +    StreamingCommand configuration
    +    ==============================
    +
    +    You can configure your command for operation under Search Command Protocol (SCP) version 1 or 2. SCP 2 requires
    +    Splunk 6.3 or later.
    +
    +    """
    +    # region Methods
    +
    +    def stream(self, records):
    +        """ Generator function that processes and yields event records to the Splunk stream pipeline.
    +
    +        You must override this method.
    +
    +        """
    +        raise NotImplementedError('StreamingCommand.stream(self, records)')
    +
    +    def _execute(self, ifile, process):
    +        SearchCommand._execute(self, ifile, self.stream)
    +
    +    # endregion
    +
    +    class ConfigurationSettings(SearchCommand.ConfigurationSettings):
    +        """ Represents the configuration settings that apply to a :class:`StreamingCommand`.
    +
    +        """
    +        # region SCP v1/v2 properties
    +
    +        required_fields = ConfigurationSetting(doc='''
    +            List of required fields for this search which back-propagates to the generating search.
    +
    +            Setting this value enables selected fields mode under SCP 2. Under SCP 1 you must also specify
    +            :code:`clear_required_fields=True` to enable selected fields mode. To explicitly select all fields,
    +            specify a value of :const:`['*']`. No error is generated if a specified field is missing.
    +
    +            Default: :const:`None`, which implicitly selects all fields.
    +
    +            Supported by: SCP 1, SCP 2
    +
    +            ''')
    +
    +        # endregion
    +
    +        # region SCP v1 properties
    +
    +        clear_required_fields = ConfigurationSetting(doc='''
    +            :const:`True`, if required_fields represent the *only* fields required.
    +
    +            If :const:`False`, required_fields are additive to any fields that may be required by subsequent commands.
    +            In most cases, :const:`False` is appropriate for streaming commands.
    +
    +            Default: :const:`False`
    +
    +            Supported by: SCP 1
    +
    +            ''')
    +
    +        local = ConfigurationSetting(doc='''
    +            :const:`True`, if the command should run locally on the search head.
    +
    +            Default: :const:`False`
    +
    +            Supported by: SCP 1
    +
    +            ''')
    +
    +        overrides_timeorder = ConfigurationSetting(doc='''
    +            :const:`True`, if the command changes the order of events with respect to time.
    +
    +            Default: :const:`False`
    +
    +            Supported by: SCP 1
    +
    +            ''')
    +
    +        streaming = ConfigurationSetting(readonly=True, value=True, doc='''
    +            Specifies that the command is streamable.
    +
    +            Fixed: :const:`True`
    +
    +            Supported by: SCP 1
    +
    +            ''')
    +
    +        # endregion
    +
    +        # region SCP v2 Properties
    +
    +        distributed = ConfigurationSetting(value=True, doc='''
    +            :const:`True`, if this command should be distributed to indexers.
    +
    +            Under SCP 1 you must either specify `local = False` or include this line in commands.conf_, if this command
    +            should be distributed to indexers.
    +
    +            ..code:
    +                local = true
    +
    +            Default: :const:`True`
    +
    +            Supported by: SCP 2
    +
    +            .. commands.conf_: http://docs.splunk.com/Documentation/Splunk/latest/Admin/Commandsconf
    +
    +            ''')
    +
    +        maxinputs = ConfigurationSetting(doc='''
    +            Specifies the maximum number of events that can be passed to the command for each invocation.
    +
    +            This limit cannot exceed the value of `maxresultrows` in limits.conf. Under SCP 1 you must specify this
    +            value in commands.conf_.
    +
    +            Default: The value of `maxresultrows`.
    +
    +            Supported by: SCP 2
    +
    +            ''')
    +
    +        type = ConfigurationSetting(readonly=True, value='streaming', doc='''
    +            Command type name.
    +
    +            Fixed: :const:`'streaming'`
    +
    +            Supported by: SCP 2
    +
    +            ''')
    +
    +        # endregion
    +
    +        # region Methods
    +
    +        @classmethod
    +        def fix_up(cls, command):
    +            """ Verifies :code:`command` class structure.
    +
    +            """
    +            if command.stream == StreamingCommand.stream:
    +                raise AttributeError('No StreamingCommand.stream override')
    +            return
    +
    +        # TODO: Stop looking like a dictionary because we don't obey the semantics
    +        # N.B.: Does not use Python 2 dict copy semantics
    +        def iteritems(self):
    +            iteritems = SearchCommand.ConfigurationSettings.iteritems(self)
    +            version = self.command.protocol_version
    +            if version == 1:
    +                if self.required_fields is None:
    +                    iteritems = ifilter(lambda name_value: name_value[0] != 'clear_required_fields', iteritems)
    +            else:
    +                iteritems = ifilter(lambda name_value2: name_value2[0] != 'distributed', iteritems)
    +                if not self.distributed:
    +                    iteritems = imap(
    +                        lambda name_value1: (name_value1[0], 'stateful') if name_value1[0] == 'type' else (name_value1[0], name_value1[1]), iteritems)
    +            return iteritems
    +
    +        # N.B.: Does not use Python 3 dict view semantics
    +        if not six.PY2:
    +            items = iteritems
    +
    +        # endregion
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/validators.py b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/validators.py
    new file mode 100644
    index 0000000..22f0e16
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/searchcommands/validators.py
    @@ -0,0 +1,433 @@
    +# coding=utf-8
    +#
    +# Copyright 2011-2015 Splunk, Inc.
    +#
    +# Licensed 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.
    +
    +from __future__ import absolute_import, division, print_function, unicode_literals
    +
    +from json.encoder import encode_basestring_ascii as json_encode_string
    +from collections import namedtuple
    +from splunklib.six.moves import StringIO
    +from io import open
    +import csv
    +import os
    +import re
    +from splunklib import six
    +from splunklib.six.moves import getcwd
    +
    +
    +class Validator(object):
    +    """ Base class for validators that check and format search command options.
    +
    +    You must inherit from this class and override :code:`Validator.__call__` and
    +    :code:`Validator.format`. :code:`Validator.__call__` should convert the
    +    value it receives as argument and then return it or raise a
    +    :code:`ValueError`, if the value will not convert.
    +
    +    :code:`Validator.format` should return a human readable version of the value
    +    it receives as argument the same way :code:`str` does.
    +
    +    """
    +    def __call__(self, value):
    +        raise NotImplementedError()
    +
    +    def format(self, value):
    +        raise NotImplementedError()
    +
    +
    +class Boolean(Validator):
    +    """ Validates Boolean option values.
    +
    +    """
    +    truth_values = {
    +        '1': True, '0': False,
    +        't': True, 'f': False,
    +        'true': True, 'false': False,
    +        'y': True, 'n': False,
    +        'yes': True, 'no': False
    +    }
    +
    +    def __call__(self, value):
    +        if not (value is None or isinstance(value, bool)):
    +            value = six.text_type(value).lower()
    +            if value not in Boolean.truth_values:
    +                raise ValueError('Unrecognized truth value: {0}'.format(value))
    +            value = Boolean.truth_values[value]
    +        return value
    +
    +    def format(self, value):
    +        return None if value is None else 't' if value else 'f'
    +
    +
    +class Code(Validator):
    +    """ Validates code option values.
    +
    +    This validator compiles an option value into a Python code object that can be executed by :func:`exec` or evaluated
    +    by :func:`eval`. The value returned is a :func:`namedtuple` with two members: object, the result of compilation, and
    +    source, the original option value.
    +
    +    """
    +    def __init__(self, mode='eval'):
    +        """
    +        :param mode: Specifies what kind of code must be compiled; it can be :const:`'exec'`, if source consists of a
    +            sequence of statements, :const:`'eval'`, if it consists of a single expression, or :const:`'single'` if it
    +            consists of a single interactive statement. In the latter case, expression statements that evaluate to
    +            something other than :const:`None` will be printed.
    +        :type mode: unicode or bytes
    +
    +        """
    +        self._mode = mode
    +
    +    def __call__(self, value):
    +        if value is None:
    +            return None
    +        try:
    +            return Code.object(compile(value, 'string', self._mode), six.text_type(value))
    +        except (SyntaxError, TypeError) as error:
    +            message = str(error)
    +
    +            six.raise_from(ValueError(message), error)
    +
    +    def format(self, value):
    +        return None if value is None else value.source
    +
    +    object = namedtuple('Code', ('object', 'source'))
    +
    +
    +class Fieldname(Validator):
    +    """ Validates field name option values.
    +
    +    """
    +    pattern = re.compile(r'''[_.a-zA-Z-][_.a-zA-Z0-9-]*$''')
    +
    +    def __call__(self, value):
    +        if value is not None:
    +            value = six.text_type(value)
    +            if Fieldname.pattern.match(value) is None:
    +                raise ValueError('Illegal characters in fieldname: {}'.format(value))
    +        return value
    +
    +    def format(self, value):
    +        return value
    +
    +
    +class File(Validator):
    +    """ Validates file option values.
    +
    +    """
    +    def __init__(self, mode='rt', buffering=None, directory=None):
    +        self.mode = mode
    +        self.buffering = buffering
    +        self.directory = File._var_run_splunk if directory is None else directory
    +
    +    def __call__(self, value):
    +
    +        if value is None:
    +            return value
    +
    +        path = six.text_type(value)
    +
    +        if not os.path.isabs(path):
    +            path = os.path.join(self.directory, path)
    +
    +        try:
    +            value = open(path, self.mode) if self.buffering is None else open(path, self.mode, self.buffering)
    +        except IOError as error:
    +            raise ValueError('Cannot open {0} with mode={1} and buffering={2}: {3}'.format(
    +                value, self.mode, self.buffering, error))
    +
    +        return value
    +
    +    def format(self, value):
    +        return None if value is None else value.name
    +
    +    _var_run_splunk = os.path.join(
    +        os.environ['SPLUNK_HOME'] if 'SPLUNK_HOME' in os.environ else getcwd(), 'var', 'run', 'splunk')
    +
    +
    +class Integer(Validator):
    +    """ Validates integer option values.
    +
    +    """
    +    def __init__(self, minimum=None, maximum=None):
    +        if minimum is not None and maximum is not None:
    +            def check_range(value):
    +                if not (minimum <= value <= maximum):
    +                    raise ValueError('Expected integer in the range [{0},{1}], not {2}'.format(minimum, maximum, value))
    +                return
    +        elif minimum is not None:
    +            def check_range(value):
    +                if value < minimum:
    +                    raise ValueError('Expected integer in the range [{0},+∞], not {1}'.format(minimum, value))
    +                return
    +        elif maximum is not None:
    +            def check_range(value):
    +                if value > maximum:
    +                    raise ValueError('Expected integer in the range [-∞,{0}], not {1}'.format(maximum, value))
    +                return
    +        else:
    +            def check_range(value):
    +                return
    +
    +        self.check_range = check_range
    +        return
    +
    +    def __call__(self, value):
    +        if value is None:
    +            return None
    +        try:
    +            if six.PY2:
    +                value = long(value)
    +            else:
    +                value = int(value)
    +        except ValueError:
    +            raise ValueError('Expected integer value, not {}'.format(json_encode_string(value)))
    +
    +        self.check_range(value)
    +        return value
    +
    +    def format(self, value):
    +        return None if value is None else six.text_type(int(value))
    +
    +
    +class Float(Validator):
    +    """ Validates float option values.
    +
    +    """
    +    def __init__(self, minimum=None, maximum=None):
    +        if minimum is not None and maximum is not None:
    +            def check_range(value):
    +                if not (minimum <= value <= maximum):
    +                    raise ValueError('Expected float in the range [{0},{1}], not {2}'.format(minimum, maximum, value))
    +                return
    +        elif minimum is not None:
    +            def check_range(value):
    +                if value < minimum:
    +                    raise ValueError('Expected float in the range [{0},+∞], not {1}'.format(minimum, value))
    +                return
    +        elif maximum is not None:
    +            def check_range(value):
    +                if value > maximum:
    +                    raise ValueError('Expected float in the range [-∞,{0}], not {1}'.format(maximum, value))
    +                return
    +        else:
    +            def check_range(value):
    +                return
    +
    +        self.check_range = check_range
    +        return
    +
    +    def __call__(self, value):
    +        if value is None:
    +            return None
    +        try:
    +            value = float(value)
    +        except ValueError:
    +            raise ValueError('Expected float value, not {}'.format(json_encode_string(value)))
    +
    +        self.check_range(value)
    +        return value
    +
    +    def format(self, value):
    +        return None if value is None else six.text_type(float(value))
    +
    +
    +class Duration(Validator):
    +    """ Validates duration option values.
    +
    +    """
    +    def __call__(self, value):
    +
    +        if value is None:
    +            return None
    +
    +        p = value.split(':', 2)
    +        result = None
    +        _60 = Duration._60
    +        _unsigned = Duration._unsigned
    +
    +        try:
    +            if len(p) == 1:
    +                result = _unsigned(p[0])
    +            if len(p) == 2:
    +                result = 60 * _unsigned(p[0]) + _60(p[1])
    +            if len(p) == 3:
    +                result = 3600 * _unsigned(p[0]) + 60 * _60(p[1]) + _60(p[2])
    +        except ValueError:
    +            raise ValueError('Invalid duration value: {0}'.format(value))
    +
    +        return result
    +
    +    def format(self, value):
    +
    +        if value is None:
    +            return None
    +
    +        value = int(value)
    +
    +        s = value % 60
    +        m = value // 60 % 60
    +        h = value // (60 * 60)
    +
    +        return '{0:02d}:{1:02d}:{2:02d}'.format(h, m, s)
    +
    +    _60 = Integer(0, 59)
    +    _unsigned = Integer(0)
    +
    +
    +class List(Validator):
    +    """ Validates a list of strings
    +
    +    """
    +    class Dialect(csv.Dialect):
    +        """ Describes the properties of list option values. """
    +        strict = True
    +        delimiter = str(',')
    +        quotechar = str('"')
    +        doublequote = True
    +        lineterminator = str('\n')
    +        skipinitialspace = True
    +        quoting = csv.QUOTE_MINIMAL
    +
    +    def __init__(self, validator=None):
    +        if not (validator is None or isinstance(validator, Validator)):
    +            raise ValueError('Expected a Validator instance or None for validator, not {}', repr(validator))
    +        self._validator = validator
    +
    +    def __call__(self, value):
    +
    +        if value is None or isinstance(value, list):
    +            return value
    +
    +        try:
    +            value = next(csv.reader([value], self.Dialect))
    +        except csv.Error as error:
    +            raise ValueError(error)
    +
    +        if self._validator is None:
    +            return value
    +
    +        try:
    +            for index, item in enumerate(value):
    +                value[index] = self._validator(item)
    +        except ValueError as error:
    +            raise ValueError('Could not convert item {}: {}'.format(index, error))
    +
    +        return value
    +
    +    def format(self, value):
    +        output = StringIO()
    +        writer = csv.writer(output, List.Dialect)
    +        writer.writerow(value)
    +        value = output.getvalue()
    +        return value[:-1]
    +
    +
    +class Map(Validator):
    +    """ Validates map option values.
    +
    +    """
    +    def __init__(self, **kwargs):
    +        self.membership = kwargs
    +
    +    def __call__(self, value):
    +
    +        if value is None:
    +            return None
    +
    +        value = six.text_type(value)
    +
    +        if value not in self.membership:
    +            raise ValueError('Unrecognized value: {0}'.format(value))
    +
    +        return self.membership[value]
    +
    +    def format(self, value):
    +        return None if value is None else list(self.membership.keys())[list(self.membership.values()).index(value)]
    +
    +
    +class Match(Validator):
    +    """ Validates that a value matches a regular expression pattern.
    +
    +    """
    +    def __init__(self, name, pattern, flags=0):
    +        self.name = six.text_type(name)
    +        self.pattern = re.compile(pattern, flags)
    +
    +    def __call__(self, value):
    +        if value is None:
    +            return None
    +        value = six.text_type(value)
    +        if self.pattern.match(value) is None:
    +            raise ValueError('Expected {}, not {}'.format(self.name, json_encode_string(value)))
    +        return value
    +
    +    def format(self, value):
    +        return None if value is None else six.text_type(value)
    +
    +
    +class OptionName(Validator):
    +    """ Validates option names.
    +
    +    """
    +    pattern = re.compile(r'''(?=\w)[^\d]\w*$''', re.UNICODE)
    +
    +    def __call__(self, value):
    +        if value is not None:
    +            value = six.text_type(value)
    +            if OptionName.pattern.match(value) is None:
    +                raise ValueError('Illegal characters in option name: {}'.format(value))
    +        return value
    +
    +    def format(self, value):
    +        return None if value is None else six.text_type(value)
    +
    +
    +class RegularExpression(Validator):
    +    """ Validates regular expression option values.
    +
    +    """
    +    def __call__(self, value):
    +        if value is None:
    +            return None
    +        try:
    +            value = re.compile(six.text_type(value))
    +        except re.error as error:
    +            raise ValueError('{}: {}'.format(six.text_type(error).capitalize(), value))
    +        return value
    +
    +    def format(self, value):
    +        return None if value is None else value.pattern
    +
    +
    +class Set(Validator):
    +    """ Validates set option values.
    +
    +    """
    +    def __init__(self, *args):
    +        self.membership = set(args)
    +
    +    def __call__(self, value):
    +        if value is None:
    +            return None
    +        value = six.text_type(value)
    +        if value not in self.membership:
    +            raise ValueError('Unrecognized value: {}'.format(value))
    +        return value
    +
    +    def format(self, value):
    +        return self.__call__(value)
    +
    +
    +__all__ = ['Boolean', 'Code', 'Duration', 'File', 'Integer', 'Float', 'List', 'Map', 'RegularExpression', 'Set']
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunklib/six.py b/deployment-apps/metricator-for-nmon/lib/splunklib/six.py
    new file mode 100644
    index 0000000..d13e50c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunklib/six.py
    @@ -0,0 +1,993 @@
    +# Copyright (c) 2010-2020 Benjamin Peterson
    +#
    +# Permission is hereby granted, free of charge, to any person obtaining a copy
    +# of this software and associated documentation files (the "Software"), to deal
    +# in the Software without restriction, including without limitation the rights
    +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +# copies of the Software, and to permit persons to whom the Software is
    +# furnished to do so, subject to the following conditions:
    +#
    +# The above copyright notice and this permission notice shall be included in all
    +# copies or substantial portions of the Software.
    +#
    +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    +# SOFTWARE.
    +
    +"""Utilities for writing code that runs on Python 2 and 3"""
    +
    +from __future__ import absolute_import
    +
    +import functools
    +import itertools
    +import operator
    +import sys
    +import types
    +
    +__author__ = "Benjamin Peterson <benjamin@python.org>"
    +__version__ = "1.14.0"
    +
    +
    +# Useful for very coarse version differentiation.
    +PY2 = sys.version_info[0] == 2
    +PY3 = sys.version_info[0] == 3
    +PY34 = sys.version_info[0:2] >= (3, 4)
    +
    +if PY3:
    +    string_types = str,
    +    integer_types = int,
    +    class_types = type,
    +    text_type = str
    +    binary_type = bytes
    +
    +    MAXSIZE = sys.maxsize
    +else:
    +    string_types = basestring,
    +    integer_types = (int, long)
    +    class_types = (type, types.ClassType)
    +    text_type = unicode
    +    binary_type = str
    +
    +    if sys.platform.startswith("java"):
    +        # Jython always uses 32 bits.
    +        MAXSIZE = int((1 << 31) - 1)
    +    else:
    +        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
    +        class X(object):
    +
    +            def __len__(self):
    +                return 1 << 31
    +        try:
    +            len(X())
    +        except OverflowError:
    +            # 32-bit
    +            MAXSIZE = int((1 << 31) - 1)
    +        else:
    +            # 64-bit
    +            MAXSIZE = int((1 << 63) - 1)
    +        del X
    +
    +
    +def _add_doc(func, doc):
    +    """Add documentation to a function."""
    +    func.__doc__ = doc
    +
    +
    +def _import_module(name):
    +    """Import module, returning the module after the last dot."""
    +    __import__(name)
    +    return sys.modules[name]
    +
    +
    +class _LazyDescr(object):
    +
    +    def __init__(self, name):
    +        self.name = name
    +
    +    def __get__(self, obj, tp):
    +        result = self._resolve()
    +        setattr(obj, self.name, result)  # Invokes __set__.
    +        try:
    +            # This is a bit ugly, but it avoids running this again by
    +            # removing this descriptor.
    +            delattr(obj.__class__, self.name)
    +        except AttributeError:
    +            pass
    +        return result
    +
    +
    +class MovedModule(_LazyDescr):
    +
    +    def __init__(self, name, old, new=None):
    +        super(MovedModule, self).__init__(name)
    +        if PY3:
    +            if new is None:
    +                new = name
    +            self.mod = new
    +        else:
    +            self.mod = old
    +
    +    def _resolve(self):
    +        return _import_module(self.mod)
    +
    +    def __getattr__(self, attr):
    +        _module = self._resolve()
    +        value = getattr(_module, attr)
    +        setattr(self, attr, value)
    +        return value
    +
    +
    +class _LazyModule(types.ModuleType):
    +
    +    def __init__(self, name):
    +        super(_LazyModule, self).__init__(name)
    +        self.__doc__ = self.__class__.__doc__
    +
    +    def __dir__(self):
    +        attrs = ["__doc__", "__name__"]
    +        attrs += [attr.name for attr in self._moved_attributes]
    +        return attrs
    +
    +    # Subclasses should override this
    +    _moved_attributes = []
    +
    +
    +class MovedAttribute(_LazyDescr):
    +
    +    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
    +        super(MovedAttribute, self).__init__(name)
    +        if PY3:
    +            if new_mod is None:
    +                new_mod = name
    +            self.mod = new_mod
    +            if new_attr is None:
    +                if old_attr is None:
    +                    new_attr = name
    +                else:
    +                    new_attr = old_attr
    +            self.attr = new_attr
    +        else:
    +            self.mod = old_mod
    +            if old_attr is None:
    +                old_attr = name
    +            self.attr = old_attr
    +
    +    def _resolve(self):
    +        module = _import_module(self.mod)
    +        return getattr(module, self.attr)
    +
    +
    +class _SixMetaPathImporter(object):
    +
    +    """
    +    A meta path importer to import six.moves and its submodules.
    +
    +    This class implements a PEP302 finder and loader. It should be compatible
    +    with Python 2.5 and all existing versions of Python3
    +    """
    +
    +    def __init__(self, six_module_name):
    +        self.name = six_module_name
    +        self.known_modules = {}
    +
    +    def _add_module(self, mod, *fullnames):
    +        for fullname in fullnames:
    +            self.known_modules[self.name + "." + fullname] = mod
    +
    +    def _get_module(self, fullname):
    +        return self.known_modules[self.name + "." + fullname]
    +
    +    def find_module(self, fullname, path=None):
    +        if fullname in self.known_modules:
    +            return self
    +        return None
    +
    +    def __get_module(self, fullname):
    +        try:
    +            return self.known_modules[fullname]
    +        except KeyError:
    +            raise ImportError("This loader does not know module " + fullname)
    +
    +    def load_module(self, fullname):
    +        try:
    +            # in case of a reload
    +            return sys.modules[fullname]
    +        except KeyError:
    +            pass
    +        mod = self.__get_module(fullname)
    +        if isinstance(mod, MovedModule):
    +            mod = mod._resolve()
    +        else:
    +            mod.__loader__ = self
    +        sys.modules[fullname] = mod
    +        return mod
    +
    +    def is_package(self, fullname):
    +        """
    +        Return true, if the named module is a package.
    +
    +        We need this method to get correct spec objects with
    +        Python 3.4 (see PEP451)
    +        """
    +        return hasattr(self.__get_module(fullname), "__path__")
    +
    +    def get_code(self, fullname):
    +        """Return None
    +
    +        Required, if is_package is implemented"""
    +        self.__get_module(fullname)  # eventually raises ImportError
    +        return None
    +    get_source = get_code  # same as get_code
    +
    +_importer = _SixMetaPathImporter(__name__)
    +
    +
    +class _MovedItems(_LazyModule):
    +
    +    """Lazy loading of moved objects"""
    +    __path__ = []  # mark as package
    +
    +
    +_moved_attributes = [
    +    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
    +    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
    +    MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
    +    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
    +    MovedAttribute("intern", "__builtin__", "sys"),
    +    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
    +    MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
    +    MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
    +    MovedAttribute("getoutput", "commands", "subprocess"),
    +    MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
    +    MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
    +    MovedAttribute("reduce", "__builtin__", "functools"),
    +    MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
    +    MovedAttribute("StringIO", "StringIO", "io"),
    +    MovedAttribute("UserDict", "UserDict", "collections"),
    +    MovedAttribute("UserList", "UserList", "collections"),
    +    MovedAttribute("UserString", "UserString", "collections"),
    +    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
    +    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
    +    MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
    +    MovedModule("builtins", "__builtin__"),
    +    MovedModule("configparser", "ConfigParser"),
    +    MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"),
    +    MovedModule("copyreg", "copy_reg"),
    +    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
    +    MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
    +    MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"),
    +    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
    +    MovedModule("http_cookies", "Cookie", "http.cookies"),
    +    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
    +    MovedModule("html_parser", "HTMLParser", "html.parser"),
    +    MovedModule("http_client", "httplib", "http.client"),
    +    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
    +    MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
    +    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
    +    MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
    +    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
    +    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
    +    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
    +    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
    +    MovedModule("cPickle", "cPickle", "pickle"),
    +    MovedModule("queue", "Queue"),
    +    MovedModule("reprlib", "repr"),
    +    MovedModule("socketserver", "SocketServer"),
    +    MovedModule("_thread", "thread", "_thread"),
    +    MovedModule("tkinter", "Tkinter"),
    +    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
    +    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
    +    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
    +    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
    +    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
    +    MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
    +    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
    +    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
    +    MovedModule("tkinter_colorchooser", "tkColorChooser",
    +                "tkinter.colorchooser"),
    +    MovedModule("tkinter_commondialog", "tkCommonDialog",
    +                "tkinter.commondialog"),
    +    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
    +    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
    +    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
    +    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
    +                "tkinter.simpledialog"),
    +    MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
    +    MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
    +    MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
    +    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
    +    MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
    +    MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
    +]
    +# Add windows specific modules.
    +if sys.platform == "win32":
    +    _moved_attributes += [
    +        MovedModule("winreg", "_winreg"),
    +    ]
    +
    +for attr in _moved_attributes:
    +    setattr(_MovedItems, attr.name, attr)
    +    if isinstance(attr, MovedModule):
    +        _importer._add_module(attr, "moves." + attr.name)
    +del attr
    +
    +_MovedItems._moved_attributes = _moved_attributes
    +
    +moves = _MovedItems(__name__ + ".moves")
    +_importer._add_module(moves, "moves")
    +
    +
    +class Module_six_moves_urllib_parse(_LazyModule):
    +
    +    """Lazy loading of moved objects in six.moves.urllib_parse"""
    +
    +
    +_urllib_parse_moved_attributes = [
    +    MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
    +    MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
    +    MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
    +    MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
    +    MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
    +    MovedAttribute("urljoin", "urlparse", "urllib.parse"),
    +    MovedAttribute("urlparse", "urlparse", "urllib.parse"),
    +    MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
    +    MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
    +    MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
    +    MovedAttribute("quote", "urllib", "urllib.parse"),
    +    MovedAttribute("quote_plus", "urllib", "urllib.parse"),
    +    MovedAttribute("unquote", "urllib", "urllib.parse"),
    +    MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
    +    MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"),
    +    MovedAttribute("urlencode", "urllib", "urllib.parse"),
    +    MovedAttribute("splitquery", "urllib", "urllib.parse"),
    +    MovedAttribute("splittag", "urllib", "urllib.parse"),
    +    MovedAttribute("splituser", "urllib", "urllib.parse"),
    +    MovedAttribute("splitvalue", "urllib", "urllib.parse"),
    +    MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
    +    MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
    +    MovedAttribute("uses_params", "urlparse", "urllib.parse"),
    +    MovedAttribute("uses_query", "urlparse", "urllib.parse"),
    +    MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
    +]
    +for attr in _urllib_parse_moved_attributes:
    +    setattr(Module_six_moves_urllib_parse, attr.name, attr)
    +del attr
    +
    +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
    +
    +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
    +                      "moves.urllib_parse", "moves.urllib.parse")
    +
    +
    +class Module_six_moves_urllib_error(_LazyModule):
    +
    +    """Lazy loading of moved objects in six.moves.urllib_error"""
    +
    +
    +_urllib_error_moved_attributes = [
    +    MovedAttribute("URLError", "urllib2", "urllib.error"),
    +    MovedAttribute("HTTPError", "urllib2", "urllib.error"),
    +    MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
    +]
    +for attr in _urllib_error_moved_attributes:
    +    setattr(Module_six_moves_urllib_error, attr.name, attr)
    +del attr
    +
    +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
    +
    +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
    +                      "moves.urllib_error", "moves.urllib.error")
    +
    +
    +class Module_six_moves_urllib_request(_LazyModule):
    +
    +    """Lazy loading of moved objects in six.moves.urllib_request"""
    +
    +
    +_urllib_request_moved_attributes = [
    +    MovedAttribute("urlopen", "urllib2", "urllib.request"),
    +    MovedAttribute("install_opener", "urllib2", "urllib.request"),
    +    MovedAttribute("build_opener", "urllib2", "urllib.request"),
    +    MovedAttribute("pathname2url", "urllib", "urllib.request"),
    +    MovedAttribute("url2pathname", "urllib", "urllib.request"),
    +    MovedAttribute("getproxies", "urllib", "urllib.request"),
    +    MovedAttribute("Request", "urllib2", "urllib.request"),
    +    MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
    +    MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
    +    MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("FileHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
    +    MovedAttribute("urlretrieve", "urllib", "urllib.request"),
    +    MovedAttribute("urlcleanup", "urllib", "urllib.request"),
    +    MovedAttribute("URLopener", "urllib", "urllib.request"),
    +    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
    +    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
    +    MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
    +    MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
    +]
    +for attr in _urllib_request_moved_attributes:
    +    setattr(Module_six_moves_urllib_request, attr.name, attr)
    +del attr
    +
    +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
    +
    +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
    +                      "moves.urllib_request", "moves.urllib.request")
    +
    +
    +class Module_six_moves_urllib_response(_LazyModule):
    +
    +    """Lazy loading of moved objects in six.moves.urllib_response"""
    +
    +
    +_urllib_response_moved_attributes = [
    +    MovedAttribute("addbase", "urllib", "urllib.response"),
    +    MovedAttribute("addclosehook", "urllib", "urllib.response"),
    +    MovedAttribute("addinfo", "urllib", "urllib.response"),
    +    MovedAttribute("addinfourl", "urllib", "urllib.response"),
    +]
    +for attr in _urllib_response_moved_attributes:
    +    setattr(Module_six_moves_urllib_response, attr.name, attr)
    +del attr
    +
    +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
    +
    +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
    +                      "moves.urllib_response", "moves.urllib.response")
    +
    +
    +class Module_six_moves_urllib_robotparser(_LazyModule):
    +
    +    """Lazy loading of moved objects in six.moves.urllib_robotparser"""
    +
    +
    +_urllib_robotparser_moved_attributes = [
    +    MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
    +]
    +for attr in _urllib_robotparser_moved_attributes:
    +    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
    +del attr
    +
    +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
    +
    +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
    +                      "moves.urllib_robotparser", "moves.urllib.robotparser")
    +
    +
    +class Module_six_moves_urllib(types.ModuleType):
    +
    +    """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
    +    __path__ = []  # mark as package
    +    parse = _importer._get_module("moves.urllib_parse")
    +    error = _importer._get_module("moves.urllib_error")
    +    request = _importer._get_module("moves.urllib_request")
    +    response = _importer._get_module("moves.urllib_response")
    +    robotparser = _importer._get_module("moves.urllib_robotparser")
    +
    +    def __dir__(self):
    +        return ['parse', 'error', 'request', 'response', 'robotparser']
    +
    +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
    +                      "moves.urllib")
    +
    +
    +def add_move(move):
    +    """Add an item to six.moves."""
    +    setattr(_MovedItems, move.name, move)
    +
    +
    +def remove_move(name):
    +    """Remove item from six.moves."""
    +    try:
    +        delattr(_MovedItems, name)
    +    except AttributeError:
    +        try:
    +            del moves.__dict__[name]
    +        except KeyError:
    +            raise AttributeError("no such move, %r" % (name,))
    +
    +
    +if PY3:
    +    _meth_func = "__func__"
    +    _meth_self = "__self__"
    +
    +    _func_closure = "__closure__"
    +    _func_code = "__code__"
    +    _func_defaults = "__defaults__"
    +    _func_globals = "__globals__"
    +else:
    +    _meth_func = "im_func"
    +    _meth_self = "im_self"
    +
    +    _func_closure = "func_closure"
    +    _func_code = "func_code"
    +    _func_defaults = "func_defaults"
    +    _func_globals = "func_globals"
    +
    +
    +try:
    +    advance_iterator = next
    +except NameError:
    +    def advance_iterator(it):
    +        return it.next()
    +next = advance_iterator
    +
    +
    +try:
    +    callable = callable
    +except NameError:
    +    def callable(obj):
    +        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
    +
    +
    +if PY3:
    +    def get_unbound_function(unbound):
    +        return unbound
    +
    +    create_bound_method = types.MethodType
    +
    +    def create_unbound_method(func, cls):
    +        return func
    +
    +    Iterator = object
    +else:
    +    def get_unbound_function(unbound):
    +        return unbound.im_func
    +
    +    def create_bound_method(func, obj):
    +        return types.MethodType(func, obj, obj.__class__)
    +
    +    def create_unbound_method(func, cls):
    +        return types.MethodType(func, None, cls)
    +
    +    class Iterator(object):
    +
    +        def next(self):
    +            return type(self).__next__(self)
    +
    +    callable = callable
    +_add_doc(get_unbound_function,
    +         """Get the function out of a possibly unbound function""")
    +
    +
    +get_method_function = operator.attrgetter(_meth_func)
    +get_method_self = operator.attrgetter(_meth_self)
    +get_function_closure = operator.attrgetter(_func_closure)
    +get_function_code = operator.attrgetter(_func_code)
    +get_function_defaults = operator.attrgetter(_func_defaults)
    +get_function_globals = operator.attrgetter(_func_globals)
    +
    +
    +if PY3:
    +    def iterkeys(d, **kw):
    +        return iter(d.keys(**kw))
    +
    +    def itervalues(d, **kw):
    +        return iter(d.values(**kw))
    +
    +    def iteritems(d, **kw):
    +        return iter(d.items(**kw))
    +
    +    def iterlists(d, **kw):
    +        return iter(d.lists(**kw))
    +
    +    viewkeys = operator.methodcaller("keys")
    +
    +    viewvalues = operator.methodcaller("values")
    +
    +    viewitems = operator.methodcaller("items")
    +else:
    +    def iterkeys(d, **kw):
    +        return d.iterkeys(**kw)
    +
    +    def itervalues(d, **kw):
    +        return d.itervalues(**kw)
    +
    +    def iteritems(d, **kw):
    +        return d.iteritems(**kw)
    +
    +    def iterlists(d, **kw):
    +        return d.iterlists(**kw)
    +
    +    viewkeys = operator.methodcaller("viewkeys")
    +
    +    viewvalues = operator.methodcaller("viewvalues")
    +
    +    viewitems = operator.methodcaller("viewitems")
    +
    +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
    +_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
    +_add_doc(iteritems,
    +         "Return an iterator over the (key, value) pairs of a dictionary.")
    +_add_doc(iterlists,
    +         "Return an iterator over the (key, [values]) pairs of a dictionary.")
    +
    +
    +if PY3:
    +    def b(s):
    +        return s.encode("latin-1")
    +
    +    def u(s):
    +        return s
    +    unichr = chr
    +    import struct
    +    int2byte = struct.Struct(">B").pack
    +    del struct
    +    byte2int = operator.itemgetter(0)
    +    indexbytes = operator.getitem
    +    iterbytes = iter
    +    import io
    +    StringIO = io.StringIO
    +    BytesIO = io.BytesIO
    +    del io
    +    _assertCountEqual = "assertCountEqual"
    +    if sys.version_info[1] <= 1:
    +        _assertRaisesRegex = "assertRaisesRegexp"
    +        _assertRegex = "assertRegexpMatches"
    +        _assertNotRegex = "assertNotRegexpMatches"
    +    else:
    +        _assertRaisesRegex = "assertRaisesRegex"
    +        _assertRegex = "assertRegex"
    +        _assertNotRegex = "assertNotRegex"
    +else:
    +    def b(s):
    +        return s
    +    # Workaround for standalone backslash
    +
    +    def u(s):
    +        return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
    +    unichr = unichr
    +    int2byte = chr
    +
    +    def byte2int(bs):
    +        return ord(bs[0])
    +
    +    def indexbytes(buf, i):
    +        return ord(buf[i])
    +    iterbytes = functools.partial(itertools.imap, ord)
    +    import StringIO
    +    StringIO = BytesIO = StringIO.StringIO
    +    _assertCountEqual = "assertItemsEqual"
    +    _assertRaisesRegex = "assertRaisesRegexp"
    +    _assertRegex = "assertRegexpMatches"
    +    _assertNotRegex = "assertNotRegexpMatches"
    +_add_doc(b, """Byte literal""")
    +_add_doc(u, """Text literal""")
    +
    +
    +def assertCountEqual(self, *args, **kwargs):
    +    return getattr(self, _assertCountEqual)(*args, **kwargs)
    +
    +
    +def assertRaisesRegex(self, *args, **kwargs):
    +    return getattr(self, _assertRaisesRegex)(*args, **kwargs)
    +
    +
    +def assertRegex(self, *args, **kwargs):
    +    return getattr(self, _assertRegex)(*args, **kwargs)
    +
    +
    +def assertNotRegex(self, *args, **kwargs):
    +    return getattr(self, _assertNotRegex)(*args, **kwargs)
    +
    +
    +if PY3:
    +    exec_ = getattr(moves.builtins, "exec")
    +
    +    def reraise(tp, value, tb=None):
    +        try:
    +            if value is None:
    +                value = tp()
    +            if value.__traceback__ is not tb:
    +                raise value.with_traceback(tb)
    +            raise value
    +        finally:
    +            value = None
    +            tb = None
    +
    +else:
    +    def exec_(_code_, _globs_=None, _locs_=None):
    +        """Execute code in a namespace."""
    +        if _globs_ is None:
    +            frame = sys._getframe(1)
    +            _globs_ = frame.f_globals
    +            if _locs_ is None:
    +                _locs_ = frame.f_locals
    +            del frame
    +        elif _locs_ is None:
    +            _locs_ = _globs_
    +        exec("""exec _code_ in _globs_, _locs_""")
    +
    +    exec_("""def reraise(tp, value, tb=None):
    +    try:
    +        raise tp, value, tb
    +    finally:
    +        tb = None
    +""")
    +
    +
    +if sys.version_info[:2] > (3,):
    +    exec_("""def raise_from(value, from_value):
    +    try:
    +        raise value from from_value
    +    finally:
    +        value = None
    +""")
    +else:
    +    def raise_from(value, from_value):
    +        raise value
    +
    +
    +print_ = getattr(moves.builtins, "print", None)
    +if print_ is None:
    +    def print_(*args, **kwargs):
    +        """The new-style print function for Python 2.4 and 2.5."""
    +        fp = kwargs.pop("file", sys.stdout)
    +        if fp is None:
    +            return
    +
    +        def write(data):
    +            if not isinstance(data, basestring):
    +                data = str(data)
    +            # If the file has an encoding, encode unicode with it.
    +            if (isinstance(fp, file) and
    +                    isinstance(data, unicode) and
    +                    fp.encoding is not None):
    +                errors = getattr(fp, "errors", None)
    +                if errors is None:
    +                    errors = "strict"
    +                data = data.encode(fp.encoding, errors)
    +            fp.write(data)
    +        want_unicode = False
    +        sep = kwargs.pop("sep", None)
    +        if sep is not None:
    +            if isinstance(sep, unicode):
    +                want_unicode = True
    +            elif not isinstance(sep, str):
    +                raise TypeError("sep must be None or a string")
    +        end = kwargs.pop("end", None)
    +        if end is not None:
    +            if isinstance(end, unicode):
    +                want_unicode = True
    +            elif not isinstance(end, str):
    +                raise TypeError("end must be None or a string")
    +        if kwargs:
    +            raise TypeError("invalid keyword arguments to print()")
    +        if not want_unicode:
    +            for arg in args:
    +                if isinstance(arg, unicode):
    +                    want_unicode = True
    +                    break
    +        if want_unicode:
    +            newline = unicode("\n")
    +            space = unicode(" ")
    +        else:
    +            newline = "\n"
    +            space = " "
    +        if sep is None:
    +            sep = space
    +        if end is None:
    +            end = newline
    +        for i, arg in enumerate(args):
    +            if i:
    +                write(sep)
    +            write(arg)
    +        write(end)
    +if sys.version_info[:2] < (3, 3):
    +    _print = print_
    +
    +    def print_(*args, **kwargs):
    +        fp = kwargs.get("file", sys.stdout)
    +        flush = kwargs.pop("flush", False)
    +        _print(*args, **kwargs)
    +        if flush and fp is not None:
    +            fp.flush()
    +
    +_add_doc(reraise, """Reraise an exception.""")
    +
    +if sys.version_info[0:2] < (3, 4):
    +    # This does exactly the same what the :func:`py3:functools.update_wrapper`
    +    # function does on Python versions after 3.2. It sets the ``__wrapped__``
    +    # attribute on ``wrapper`` object and it doesn't raise an error if any of
    +    # the attributes mentioned in ``assigned`` and ``updated`` are missing on
    +    # ``wrapped`` object.
    +    def _update_wrapper(wrapper, wrapped,
    +                        assigned=functools.WRAPPER_ASSIGNMENTS,
    +                        updated=functools.WRAPPER_UPDATES):
    +        for attr in assigned:
    +            try:
    +                value = getattr(wrapped, attr)
    +            except AttributeError:
    +                continue
    +            else:
    +                setattr(wrapper, attr, value)
    +        for attr in updated:
    +            getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
    +        wrapper.__wrapped__ = wrapped
    +        return wrapper
    +    _update_wrapper.__doc__ = functools.update_wrapper.__doc__
    +
    +    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
    +              updated=functools.WRAPPER_UPDATES):
    +        return functools.partial(_update_wrapper, wrapped=wrapped,
    +                                 assigned=assigned, updated=updated)
    +    wraps.__doc__ = functools.wraps.__doc__
    +
    +else:
    +    wraps = functools.wraps
    +
    +
    +def with_metaclass(meta, *bases):
    +    """Create a base class with a metaclass."""
    +    # This requires a bit of explanation: the basic idea is to make a dummy
    +    # metaclass for one level of class instantiation that replaces itself with
    +    # the actual metaclass.
    +    class metaclass(type):
    +
    +        def __new__(cls, name, this_bases, d):
    +            if sys.version_info[:2] >= (3, 7):
    +                # This version introduced PEP 560 that requires a bit
    +                # of extra care (we mimic what is done by __build_class__).
    +                resolved_bases = types.resolve_bases(bases)
    +                if resolved_bases is not bases:
    +                    d['__orig_bases__'] = bases
    +            else:
    +                resolved_bases = bases
    +            return meta(name, resolved_bases, d)
    +
    +        @classmethod
    +        def __prepare__(cls, name, this_bases):
    +            return meta.__prepare__(name, bases)
    +    return type.__new__(metaclass, 'temporary_class', (), {})
    +
    +
    +def add_metaclass(metaclass):
    +    """Class decorator for creating a class with a metaclass."""
    +    def wrapper(cls):
    +        orig_vars = cls.__dict__.copy()
    +        slots = orig_vars.get('__slots__')
    +        if slots is not None:
    +            if isinstance(slots, str):
    +                slots = [slots]
    +            for slots_var in slots:
    +                orig_vars.pop(slots_var)
    +        orig_vars.pop('__dict__', None)
    +        orig_vars.pop('__weakref__', None)
    +        if hasattr(cls, '__qualname__'):
    +            orig_vars['__qualname__'] = cls.__qualname__
    +        return metaclass(cls.__name__, cls.__bases__, orig_vars)
    +    return wrapper
    +
    +
    +def ensure_binary(s, encoding='utf-8', errors='strict'):
    +    """Coerce **s** to six.binary_type.
    +
    +    For Python 2:
    +      - `unicode` -> encoded to `str`
    +      - `str` -> `str`
    +
    +    For Python 3:
    +      - `str` -> encoded to `bytes`
    +      - `bytes` -> `bytes`
    +    """
    +    if isinstance(s, text_type):
    +        return s.encode(encoding, errors)
    +    elif isinstance(s, binary_type):
    +        return s
    +    else:
    +        raise TypeError("not expecting type '%s'" % type(s))
    +
    +
    +def ensure_str(s, encoding='utf-8', errors='strict'):
    +    """Coerce *s* to `str`.
    +
    +    For Python 2:
    +      - `unicode` -> encoded to `str`
    +      - `str` -> `str`
    +
    +    For Python 3:
    +      - `str` -> `str`
    +      - `bytes` -> decoded to `str`
    +    """
    +    if not isinstance(s, (text_type, binary_type)):
    +        raise TypeError("not expecting type '%s'" % type(s))
    +    if PY2 and isinstance(s, text_type):
    +        s = s.encode(encoding, errors)
    +    elif PY3 and isinstance(s, binary_type):
    +        s = s.decode(encoding, errors)
    +    return s
    +
    +
    +def ensure_text(s, encoding='utf-8', errors='strict'):
    +    """Coerce *s* to six.text_type.
    +
    +    For Python 2:
    +      - `unicode` -> `unicode`
    +      - `str` -> `unicode`
    +
    +    For Python 3:
    +      - `str` -> `str`
    +      - `bytes` -> decoded to `str`
    +    """
    +    if isinstance(s, binary_type):
    +        return s.decode(encoding, errors)
    +    elif isinstance(s, text_type):
    +        return s
    +    else:
    +        raise TypeError("not expecting type '%s'" % type(s))
    +
    +
    +def python_2_unicode_compatible(klass):
    +    """
    +    A class decorator that defines __unicode__ and __str__ methods under Python 2.
    +    Under Python 3 it does nothing.
    +
    +    To support Python 2 and 3 with a single code base, define a __str__ method
    +    returning text and apply this decorator to the class.
    +    """
    +    if PY2:
    +        if '__str__' not in klass.__dict__:
    +            raise ValueError("@python_2_unicode_compatible cannot be applied "
    +                             "to %s because it doesn't define __str__()." %
    +                             klass.__name__)
    +        klass.__unicode__ = klass.__str__
    +        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
    +    return klass
    +
    +
    +# Complete the moves implementation.
    +# This code is at the end of this module to speed up module loading.
    +# Turn this module into a package.
    +__path__ = []  # required for PEP 302 and PEP 451
    +__package__ = __name__  # see PEP 366 @ReservedAssignment
    +if globals().get("__spec__") is not None:
    +    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
    +# Remove other six meta path importers, since they cause problems. This can
    +# happen if six is removed from sys.modules and then reloaded. (Setuptools does
    +# this for some reason.)
    +if sys.meta_path:
    +    for i, importer in enumerate(sys.meta_path):
    +        # Here's some real nastiness: Another "instance" of the six module might
    +        # be floating around. Therefore, we can't use isinstance() to check for
    +        # the six meta path importer, since the other six instance will have
    +        # inserted an importer with different class.
    +        if (type(importer).__name__ == "_SixMetaPathImporter" and
    +                importer.name == __name__):
    +            del sys.meta_path[i]
    +            break
    +    del i, importer
    +# Finally, add the importer to the meta path import hook.
    +sys.meta_path.append(_importer)
    +
    +import warnings
    +
    +def deprecated(message):
    +  def deprecated_decorator(func):
    +      def deprecated_func(*args, **kwargs):
    +          warnings.warn("{} is a deprecated function. {}".format(func.__name__, message),
    +                        category=DeprecationWarning,
    +                        stacklevel=2)
    +          warnings.simplefilter('default', DeprecationWarning)
    +          return func(*args, **kwargs)
    +      return deprecated_func
    +  return deprecated_decorator
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/INSTALLER b/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/INSTALLER
    new file mode 100644
    index 0000000..a1b589e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/INSTALLER
    @@ -0,0 +1 @@
    +pip
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/LICENSE b/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/LICENSE
    new file mode 100644
    index 0000000..4240ec1
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/LICENSE
    @@ -0,0 +1,202 @@
    +
    +                                 Apache License
    +                           Version 2.0, January 2004
    +                        http://www.apache.org/licenses/
    +
    +   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    +
    +   1. Definitions.
    +
    +      "License" shall mean the terms and conditions for use, reproduction,
    +      and distribution as defined by Sections 1 through 9 of this document.
    +
    +      "Licensor" shall mean the copyright owner or entity authorized by
    +      the copyright owner that is granting the License.
    +
    +      "Legal Entity" shall mean the union of the acting entity and all
    +      other entities that control, are controlled by, or are under common
    +      control with that entity. For the purposes of this definition,
    +      "control" means (i) the power, direct or indirect, to cause the
    +      direction or management of such entity, whether by contract or
    +      otherwise, or (ii) ownership of fifty percent (50%) or more of the
    +      outstanding shares, or (iii) beneficial ownership of such entity.
    +
    +      "You" (or "Your") shall mean an individual or Legal Entity
    +      exercising permissions granted by this License.
    +
    +      "Source" form shall mean the preferred form for making modifications,
    +      including but not limited to software source code, documentation
    +      source, and configuration files.
    +
    +      "Object" form shall mean any form resulting from mechanical
    +      transformation or translation of a Source form, including but
    +      not limited to compiled object code, generated documentation,
    +      and conversions to other media types.
    +
    +      "Work" shall mean the work of authorship, whether in Source or
    +      Object form, made available under the License, as indicated by a
    +      copyright notice that is included in or attached to the work
    +      (an example is provided in the Appendix below).
    +
    +      "Derivative Works" shall mean any work, whether in Source or Object
    +      form, that is based on (or derived from) the Work and for which the
    +      editorial revisions, annotations, elaborations, or other modifications
    +      represent, as a whole, an original work of authorship. For the purposes
    +      of this License, Derivative Works shall not include works that remain
    +      separable from, or merely link (or bind by name) to the interfaces of,
    +      the Work and Derivative Works thereof.
    +
    +      "Contribution" shall mean any work of authorship, including
    +      the original version of the Work and any modifications or additions
    +      to that Work or Derivative Works thereof, that is intentionally
    +      submitted to Licensor for inclusion in the Work by the copyright owner
    +      or by an individual or Legal Entity authorized to submit on behalf of
    +      the copyright owner. For the purposes of this definition, "submitted"
    +      means any form of electronic, verbal, or written communication sent
    +      to the Licensor or its representatives, including but not limited to
    +      communication on electronic mailing lists, source code control systems,
    +      and issue tracking systems that are managed by, or on behalf of, the
    +      Licensor for the purpose of discussing and improving the Work, but
    +      excluding communication that is conspicuously marked or otherwise
    +      designated in writing by the copyright owner as "Not a Contribution."
    +
    +      "Contributor" shall mean Licensor and any individual or Legal Entity
    +      on behalf of whom a Contribution has been received by Licensor and
    +      subsequently incorporated within the Work.
    +
    +   2. Grant of Copyright License. Subject to the terms and conditions of
    +      this License, each Contributor hereby grants to You a perpetual,
    +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    +      copyright license to reproduce, prepare Derivative Works of,
    +      publicly display, publicly perform, sublicense, and distribute the
    +      Work and such Derivative Works in Source or Object form.
    +
    +   3. Grant of Patent License. Subject to the terms and conditions of
    +      this License, each Contributor hereby grants to You a perpetual,
    +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    +      (except as stated in this section) patent license to make, have made,
    +      use, offer to sell, sell, import, and otherwise transfer the Work,
    +      where such license applies only to those patent claims licensable
    +      by such Contributor that are necessarily infringed by their
    +      Contribution(s) alone or by combination of their Contribution(s)
    +      with the Work to which such Contribution(s) was submitted. If You
    +      institute patent litigation against any entity (including a
    +      cross-claim or counterclaim in a lawsuit) alleging that the Work
    +      or a Contribution incorporated within the Work constitutes direct
    +      or contributory patent infringement, then any patent licenses
    +      granted to You under this License for that Work shall terminate
    +      as of the date such litigation is filed.
    +
    +   4. Redistribution. You may reproduce and distribute copies of the
    +      Work or Derivative Works thereof in any medium, with or without
    +      modifications, and in Source or Object form, provided that You
    +      meet the following conditions:
    +
    +      (a) You must give any other recipients of the Work or
    +          Derivative Works a copy of this License; and
    +
    +      (b) You must cause any modified files to carry prominent notices
    +          stating that You changed the files; and
    +
    +      (c) You must retain, in the Source form of any Derivative Works
    +          that You distribute, all copyright, patent, trademark, and
    +          attribution notices from the Source form of the Work,
    +          excluding those notices that do not pertain to any part of
    +          the Derivative Works; and
    +
    +      (d) If the Work includes a "NOTICE" text file as part of its
    +          distribution, then any Derivative Works that You distribute must
    +          include a readable copy of the attribution notices contained
    +          within such NOTICE file, excluding those notices that do not
    +          pertain to any part of the Derivative Works, in at least one
    +          of the following places: within a NOTICE text file distributed
    +          as part of the Derivative Works; within the Source form or
    +          documentation, if provided along with the Derivative Works; or,
    +          within a display generated by the Derivative Works, if and
    +          wherever such third-party notices normally appear. The contents
    +          of the NOTICE file are for informational purposes only and
    +          do not modify the License. You may add Your own attribution
    +          notices within Derivative Works that You distribute, alongside
    +          or as an addendum to the NOTICE text from the Work, provided
    +          that such additional attribution notices cannot be construed
    +          as modifying the License.
    +
    +      You may add Your own copyright statement to Your modifications and
    +      may provide additional or different license terms and conditions
    +      for use, reproduction, or distribution of Your modifications, or
    +      for any such Derivative Works as a whole, provided Your use,
    +      reproduction, and distribution of the Work otherwise complies with
    +      the conditions stated in this License.
    +
    +   5. Submission of Contributions. Unless You explicitly state otherwise,
    +      any Contribution intentionally submitted for inclusion in the Work
    +      by You to the Licensor shall be under the terms and conditions of
    +      this License, without any additional terms or conditions.
    +      Notwithstanding the above, nothing herein shall supersede or modify
    +      the terms of any separate license agreement you may have executed
    +      with Licensor regarding such Contributions.
    +
    +   6. Trademarks. This License does not grant permission to use the trade
    +      names, trademarks, service marks, or product names of the Licensor,
    +      except as required for reasonable and customary use in describing the
    +      origin of the Work and reproducing the content of the NOTICE file.
    +
    +   7. Disclaimer of Warranty. Unless required by applicable law or
    +      agreed to in writing, Licensor provides the Work (and each
    +      Contributor provides its Contributions) on an "AS IS" BASIS,
    +      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    +      implied, including, without limitation, any warranties or conditions
    +      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
    +      PARTICULAR PURPOSE. You are solely responsible for determining the
    +      appropriateness of using or redistributing the Work and assume any
    +      risks associated with Your exercise of permissions under this License.
    +
    +   8. Limitation of Liability. In no event and under no legal theory,
    +      whether in tort (including negligence), contract, or otherwise,
    +      unless required by applicable law (such as deliberate and grossly
    +      negligent acts) or agreed to in writing, shall any Contributor be
    +      liable to You for damages, including any direct, indirect, special,
    +      incidental, or consequential damages of any character arising as a
    +      result of this License or out of the use or inability to use the
    +      Work (including but not limited to damages for loss of goodwill,
    +      work stoppage, computer failure or malfunction, or any and all
    +      other commercial damages or losses), even if such Contributor
    +      has been advised of the possibility of such damages.
    +
    +   9. Accepting Warranty or Additional Liability. While redistributing
    +      the Work or Derivative Works thereof, You may choose to offer,
    +      and charge a fee for, acceptance of support, warranty, indemnity,
    +      or other liability obligations and/or rights consistent with this
    +      License. However, in accepting such obligations, You may act only
    +      on Your own behalf and on Your sole responsibility, not on behalf
    +      of any other Contributor, and only if You agree to indemnify,
    +      defend, and hold each Contributor harmless for any liability
    +      incurred by, or claims asserted against, such Contributor by reason
    +      of your accepting any such warranty or additional liability.
    +
    +   END OF TERMS AND CONDITIONS
    +
    +   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 "[]"
    +      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
    +      file or class name and description of purpose be included on the
    +      same "printed page" as the copyright notice for easier
    +      identification within third-party archives.
    +
    +   Copyright 2021 Splunk Inc.
    +
    +   Licensed 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.
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/METADATA b/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/METADATA
    new file mode 100644
    index 0000000..64651ad
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/METADATA
    @@ -0,0 +1,20 @@
    +Metadata-Version: 2.1
    +Name: splunktalib
    +Version: 3.0.3
    +Summary: Supporting library for Splunk Add-ons
    +Home-page: https://github.com/splunk/addonfactory-ta-library-python
    +License: Apache-2.0
    +Author: rfaircloth-splunk
    +Author-email: rfaircloth@splunk.com
    +Requires-Python: >=3.7,<4.0
    +Classifier: License :: OSI Approved :: Apache Software License
    +Classifier: Programming Language :: Python :: 3
    +Classifier: Programming Language :: Python :: 3.7
    +Classifier: Programming Language :: Python :: 3.8
    +Classifier: Programming Language :: Python :: 3.9
    +Classifier: Programming Language :: Python :: 3.10
    +Classifier: Programming Language :: Python :: 3.11
    +Requires-Dist: defusedxml (>=0,<1)
    +Requires-Dist: requests (>=2.26.0,<3.0.0)
    +Requires-Dist: sortedcontainers (>=2,<3)
    +Project-URL: Repository, https://github.com/splunk/addonfactory-ta-library-python
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/RECORD b/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/RECORD
    new file mode 100644
    index 0000000..4b48a9b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/RECORD
    @@ -0,0 +1,39 @@
    +splunktalib-3.0.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
    +splunktalib-3.0.3.dist-info/LICENSE,sha256=UOQ5YRO6vOLTeTqm5ezsxIYeUglieyiz-4ligAVIfZI,11342
    +splunktalib-3.0.3.dist-info/METADATA,sha256=aDwstU0pVOJZGIH-wt2r4dmf1CZNCBM-n0cSJHFvTII,843
    +splunktalib-3.0.3.dist-info/RECORD,,
    +splunktalib-3.0.3.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
    +splunktalib/__init__.py,sha256=X8oiEDRCcUeEwYsGa7grUJJDyjwzkv3HEjGMT5xdebg,598
    +splunktalib/common/__init__.py,sha256=TB1W22zY5u1d91XSos8Qa2V5NMCpgLTgIiV2wT4hx3Y,575
    +splunktalib/common/consts.py,sha256=pb1lKSam8tVeh6yIH6k_XN6eFZO7oSihujlPPK4SKaU,594
    +splunktalib/common/log.py,sha256=JWc-7bUbgIfukwpc9nzQYGpeQJ9WCJSvBVoVQGwadxc,4951
    +splunktalib/common/pattern.py,sha256=_jgi1rgtcaoSttZTE6pVL37LG7oTXj_N1SnV3cHhNi4,1599
    +splunktalib/common/util.py,sha256=HlzvppTbTWoQFGtFLEknwkWRzb7WelfQUCvnCBrMZj8,3922
    +splunktalib/common/xml_dom_parser.py,sha256=V9bo6l0XAr2aDCZqhq4rNtAscKLhlDcXaWE2SElk05M,2251
    +splunktalib/concurrent/__init__.py,sha256=TB1W22zY5u1d91XSos8Qa2V5NMCpgLTgIiV2wT4hx3Y,575
    +splunktalib/concurrent/concurrent_executor.py,sha256=alyEw1ft7EfaQRwD-aVCDUDPpRsvhme1ShPi-YxFvQI,3497
    +splunktalib/concurrent/process_pool.py,sha256=c1LnOMe9lDd4urpkA8_y9V6Bp9mtC7rxvk_E1E_LJVM,2247
    +splunktalib/concurrent/thread_pool.py,sha256=2IqinAKvUlS3REUJxyEh3jsK4qmDEDrNTDbW20z8AxU,10691
    +splunktalib/conf_manager/__init__.py,sha256=TB1W22zY5u1d91XSos8Qa2V5NMCpgLTgIiV2wT4hx3Y,575
    +splunktalib/conf_manager/conf_endpoints.py,sha256=oMG8IgJJE8IKwr273MK9mifYdkP8eCGXlD-i-jJia0Y,6088
    +splunktalib/conf_manager/conf_manager.py,sha256=jQy81zS7O62qlG8iWH-l90pez1w7NNctYw5rqpLc2pk,9206
    +splunktalib/conf_manager/data_input_endpoints.py,sha256=3PmWnBJRq9ZRuKdxsXz8R_094VtSxlUnsyXmQCmM4Q8,7195
    +splunktalib/conf_manager/property_endpoints.py,sha256=lDfpAhJ1ozZuUPXkpObJYyO8AsWy2luc6XL4MxPrfK0,3467
    +splunktalib/conf_manager/request.py,sha256=Xnff88Eajm2YfiSrnR36tFKWKB-ix8Svb4LYsSNCkIE,1796
    +splunktalib/conf_manager/ta_conf_manager.py,sha256=AKznVbir-6TR4d4U_PqTubFPREmJBtnv1gm2soQ6M9c,6892
    +splunktalib/credentials.py,sha256=dZLK89ruZ2RhVZVUalKZyq6lhIcr4z4YlwYSG5NCEF4,12871
    +splunktalib/event_writer.py,sha256=tRsMpiFB8NV737cr0pEMHcvzTNZdnj8Y-b09iChjBH0,5830
    +splunktalib/file_monitor.py,sha256=RtAZWD_TKJR97tMPD-QVKFI0rKfmMdnzXWWjOKxKdKk,2358
    +splunktalib/kv_client.py,sha256=Izl8ETaRxj_Z3ZZu5vCyyvDenU9r9rrdOk3zFP9F28M,7444
    +splunktalib/modinput.py,sha256=VMJyJQgXYKB5HuWvzH3bVWqVbndHxe76gb6yrDIzxbY,5207
    +splunktalib/orphan_process_monitor.py,sha256=C6hAEMUkX8saNlzKzTQxiYNc-0LdpDseQ4j21WxRo9s,2586
    +splunktalib/rest.py,sha256=LvPzyF3YxHCvi3zViN5wlG0vDggDEBxzbKdLE44Dd2E,3001
    +splunktalib/schedule/__init__.py,sha256=TB1W22zY5u1d91XSos8Qa2V5NMCpgLTgIiV2wT4hx3Y,575
    +splunktalib/schedule/job.py,sha256=P2UYJxyQE8ZUe2eu2yG4-PdLH-r30qrjmmdJxy0zV6s,3065
    +splunktalib/schedule/scheduler.py,sha256=sRPJ-wgPXfKOIBFDfbPVAh2ySVtta3iqWo5vjpb5GSY,4637
    +splunktalib/setting.conf,sha256=eSsEk9cwPaV8MUQN63aN02AYPNShHAp5pcN5vCGyan0,667
    +splunktalib/splunk_cluster.py,sha256=CxxbOHgrKujb5Ipre8KL58L3Nrz4HdOdfyfrRdQD6tg,2336
    +splunktalib/splunk_platform.py,sha256=5kR86y1sHstF-eCw8-zPr-KLvYQh38bXtfWDI6-dbFI,1906
    +splunktalib/state_store.py,sha256=-PRd644OXc3JsV-gxKbJizcT25LNah7jBIVxLrvEg_M,9147
    +splunktalib/timer.py,sha256=DQy4LiLRzIHu74jpTNu9m4nc6PG7-6ErHvt0oRmF5VY,2617
    +splunktalib/timer_queue.py,sha256=kMAuffC2oiemrCut0p6M4_cupUMrEUGxvAz30eybOOQ,4779
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/WHEEL b/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/WHEEL
    new file mode 100644
    index 0000000..4ba7671
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib-3.0.3.dist-info/WHEEL
    @@ -0,0 +1,4 @@
    +Wheel-Version: 1.0
    +Generator: poetry-core 1.4.0
    +Root-Is-Purelib: true
    +Tag: py3-none-any
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/__init__.py
    new file mode 100644
    index 0000000..93cfdd5
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/__init__.py
    @@ -0,0 +1,17 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +__version__ = "3.0.3"
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/common/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/common/__init__.py
    new file mode 100644
    index 0000000..72d4509
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/common/__init__.py
    @@ -0,0 +1,15 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/common/consts.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/common/consts.py
    new file mode 100644
    index 0000000..8bdcb61
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/common/consts.py
    @@ -0,0 +1,17 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +util_log = "util"
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/common/log.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/common/log.py
    new file mode 100644
    index 0000000..a8dd423
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/common/log.py
    @@ -0,0 +1,164 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +Copyright (C) 2005-2019 Splunk Inc. All Rights Reserved.
    +
    +log utility for TA
    +"""
    +
    +import logging
    +import logging.handlers as handlers
    +import os.path as op
    +import time
    +import warnings
    +
    +import splunktalib.common.util as cutil
    +from splunktalib.common.pattern import singleton
    +from splunktalib.splunk_platform import make_splunkhome_path
    +
    +logging.Formatter.converter = time.gmtime
    +
    +
    +def log_enter_exit(logger):
    +    """
    +    Log decorator to log function enter and exit
    +    """
    +    warnings.warn(
    +        "This function is deprecated. "
    +        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +        DeprecationWarning,
    +        stacklevel=2,
    +    )
    +
    +    def log_decorator(func):
    +        def wrapper(*args, **kwargs):
    +            logger.debug("{} entered.".format(func.__name__))
    +            result = func(*args, **kwargs)
    +            logger.debug("{} exited.".format(func.__name__))
    +            return result
    +
    +        return wrapper
    +
    +    return log_decorator
    +
    +
    +@singleton
    +class Logs:
    +    def __init__(self, namespace=None, default_level=logging.INFO):
    +        warnings.warn(
    +            "This class is deprecated. "
    +            "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +            DeprecationWarning,
    +            stacklevel=2,
    +        )
    +        self._loggers = {}
    +        self._default_level = default_level
    +        if namespace is None:
    +            namespace = cutil.get_appname_from_path(op.abspath(__file__))
    +
    +        if namespace:
    +            namespace = namespace.lower()
    +        self._namespace = namespace
    +
    +    def get_logger(self, name, level=None, maxBytes=25000000, backupCount=5):
    +        """
    +        Set up a default logger.
    +
    +        :param name: The log file name.
    +        :param level: The logging level.
    +        :param maxBytes: The maximum log file size before rollover.
    +        :param backupCount: The number of log files to retain.
    +        """
    +
    +        # Strip ".py" from the log file name if auto-generated by a script.
    +        if level is None:
    +            level = self._default_level
    +
    +        name = self._get_log_name(name)
    +        if name in self._loggers:
    +            return self._loggers[name]
    +
    +        logfile = make_splunkhome_path(["var", "log", "splunk", name])
    +        logger = logging.getLogger(name)
    +
    +        handler_exists = any(
    +            [True for h in logger.handlers if h.baseFilename == logfile]
    +        )
    +        if not handler_exists:
    +            file_handler = handlers.RotatingFileHandler(
    +                logfile, mode="a", maxBytes=maxBytes, backupCount=backupCount
    +            )
    +
    +            formatter = logging.Formatter(
    +                "%(asctime)s +0000 log_level=%(levelname)s, pid=%(process)d, tid=%(threadName)s, "
    +                "file=%(filename)s, func_name=%(funcName)s, code_line_no=%(lineno)d | %(message)s"
    +            )
    +            file_handler.setFormatter(formatter)
    +            logger.addHandler(file_handler)
    +            logger.setLevel(level)
    +            logger.propagate = False
    +
    +        self._loggers[name] = logger
    +        return logger
    +
    +    def set_level(self, level, name=None):
    +        """
    +        Change the log level of the logging
    +
    +        :param level: the level of the logging to be setLevel
    +        :param name: the name of the logging to set, in case it is not set,
    +                     all the loggers will be affected
    +        """
    +
    +        if name is not None:
    +            name = self._get_log_name(name)
    +            logger = self._loggers.get(name)
    +            if logger is not None:
    +                logger.setLevel(level)
    +        else:
    +            self._default_level = level
    +            for logger in self._loggers.values():
    +                logger.setLevel(level)
    +
    +    def _get_log_name(self, name):
    +        if name.endswith(".py"):
    +            name = name.replace(".py", "")
    +
    +        if self._namespace:
    +            name = "{}_{}.log".format(self._namespace, name)
    +        else:
    +            name = "{}.log".format(name)
    +        return name
    +
    +
    +# Global logger
    +logger = Logs().get_logger("util")
    +
    +
    +def reset_logger(name):
    +    """
    +    Reset global logger.
    +    """
    +    warnings.warn(
    +        "This function is deprecated. "
    +        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +        DeprecationWarning,
    +        stacklevel=2,
    +    )
    +
    +    global logger
    +    logger = Logs().get_logger(name)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/common/pattern.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/common/pattern.py
    new file mode 100644
    index 0000000..6fd03fc
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/common/pattern.py
    @@ -0,0 +1,59 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +Copyright (C) 2005-2019 Splunk Inc. All Rights Reserved.
    +
    +Commonly used design partten for python user, includes:
    +  - singleton (Decorator function used to build singleton)
    +"""
    +import warnings
    +from functools import wraps
    +
    +
    +def singleton(class_):
    +    """
    +    Singleton decoorator function.
    +    """
    +    warnings.warn(
    +        "This function is deprecated. "
    +        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +        DeprecationWarning,
    +        stacklevel=2,
    +    )
    +    instances = {}
    +
    +    @wraps(class_)
    +    def getinstance(*args, **kwargs):
    +        if class_ not in instances:
    +            instances[class_] = class_(*args, **kwargs)
    +        return instances[class_]
    +
    +    return getinstance
    +
    +
    +class Singleton(type):
    +    """
    +    Singleton meta class
    +    """
    +
    +    _instances = {}
    +
    +    def __call__(cls, *args, **kwargs):
    +        if cls not in cls._instances:
    +            cls._instances[cls] = super().__call__(*args, **kwargs)
    +            print(cls)
    +        return cls._instances[cls]
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/common/util.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/common/util.py
    new file mode 100644
    index 0000000..6209b57
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/common/util.py
    @@ -0,0 +1,147 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +Copyright (C) 2005-2019 Splunk Inc. All Rights Reserved.
    +"""
    +
    +import datetime
    +import gc
    +import os
    +import os.path as op
    +import sys
    +import urllib.error
    +import urllib.parse
    +import urllib.request
    +import warnings
    +
    +
    +def handle_tear_down_signals(callback):
    +    warnings.warn(
    +        "This function is deprecated. "
    +        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +        DeprecationWarning,
    +        stacklevel=2,
    +    )
    +    import signal
    +
    +    signal.signal(signal.SIGTERM, callback)
    +    signal.signal(signal.SIGINT, callback)
    +
    +    if os.name == "nt":
    +        signal.signal(signal.SIGBREAK, callback)
    +
    +
    +def datetime_to_seconds(dt):
    +    warnings.warn(
    +        "This function is deprecated. "
    +        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +        DeprecationWarning,
    +        stacklevel=2,
    +    )
    +    epoch_time = datetime.datetime.utcfromtimestamp(0)
    +    return (dt - epoch_time).total_seconds()
    +
    +
    +def is_true(val):
    +    warnings.warn(
    +        "This function is deprecated. "
    +        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +        DeprecationWarning,
    +        stacklevel=2,
    +    )
    +    value = str(val).strip().upper()
    +    if value in ("1", "TRUE", "T", "Y", "YES"):
    +        return True
    +    return False
    +
    +
    +def is_false(val):
    +    warnings.warn(
    +        "This function is deprecated. "
    +        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +        DeprecationWarning,
    +        stacklevel=2,
    +    )
    +    value = str(val).strip().upper()
    +    if value in ("0", "FALSE", "F", "N", "NO", "NONE", ""):
    +        return True
    +    return False
    +
    +
    +def remove_http_proxy_env_vars():
    +    warnings.warn(
    +        "This function is deprecated. "
    +        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +        DeprecationWarning,
    +        stacklevel=2,
    +    )
    +    for k in ("http_proxy", "https_proxy"):
    +        if k in os.environ:
    +            del os.environ[k]
    +        elif k.upper() in os.environ:
    +            del os.environ[k.upper()]
    +
    +
    +def get_appname_from_path(absolute_path):
    +    absolute_path = op.normpath(absolute_path)
    +    parts = absolute_path.split(os.path.sep)
    +    parts.reverse()
    +    for key in ("apps", "slave-apps", "master-apps"):
    +        try:
    +            idx = parts.index(key)
    +        except ValueError:
    +            continue
    +        else:
    +            try:
    +                if parts[idx + 1] == "etc":
    +                    return parts[idx - 1]
    +            except IndexError:
    +                pass
    +            continue
    +    return "-"
    +
    +
    +def escape_cdata(data):
    +    data = data.encode("utf-8", errors="xmlcharrefreplace").decode("utf-8")
    +    data = data.replace("]]>", "]]&gt;")
    +    if data.endswith("]"):
    +        data = data[:-1] + "%5D"
    +    return data
    +
    +
    +def extract_datainput_name(stanza_name):
    +    """
    +    stansa_name: string like aws_s3://my_s3_data_input
    +    """
    +
    +    sep = "://"
    +    try:
    +        idx = stanza_name.index(sep)
    +    except ValueError:
    +        return stanza_name
    +
    +    return stanza_name[idx + len(sep) :]
    +
    +
    +def disable_stdout_buffer():
    +    os.environ["PYTHONUNBUFFERED"] = "1"
    +    sys.stdout = os.fdopen(sys.stdout.fileno(), "wb", 0)
    +    gc.garbage.append(sys.stdout)
    +
    +
    +def format_stanza_name(name):
    +    return urllib.parse.quote(name.encode("utf-8"), "")
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/common/xml_dom_parser.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/common/xml_dom_parser.py
    new file mode 100644
    index 0000000..974b9e8
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/common/xml_dom_parser.py
    @@ -0,0 +1,63 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 re
    +
    +from defusedxml import ElementTree as et
    +
    +
    +def parse_conf_xml_dom(xml_content):
    +    """
    +    @xml_content: XML DOM from splunkd
    +    """
    +    m = re.search(r'xmlns="([^"]+)"', xml_content)
    +    ns = m.group(1)
    +    m = re.search(r'xmlns:s="([^"]+)"', xml_content)
    +    sub_ns = m.group(1)
    +    entry_path = "./{%s}entry" % ns
    +    stanza_path = "./{%s}title" % ns
    +    key_path = "./{{{}}}content/{{{}}}dict/{{{}}}key".format(ns, sub_ns, sub_ns)
    +    meta_path = "./{{{}}}dict/{{{}}}key".format(sub_ns, sub_ns)
    +    list_path = "./{{{}}}list/{{{}}}item".format(sub_ns, sub_ns)
    +
    +    xml_conf = et.fromstring(xml_content)
    +    stanza_objs = []
    +    for entry in xml_conf.iterfind(entry_path):
    +        for stanza in entry.iterfind(stanza_path):
    +            stanza_obj = {"name": stanza.text, "stanza": stanza.text}
    +            break
    +        else:
    +            continue
    +
    +        for key in entry.iterfind(key_path):
    +            if key.get("name") == "eai:acl":
    +                meta = {}
    +                for k in key.iterfind(meta_path):
    +                    meta[k.get("name")] = k.text
    +                stanza_obj[key.get("name")] = meta
    +            elif key.get("name") != "eai:attributes":
    +                name = key.get("name")
    +                if name.startswith("eai:"):
    +                    name = name[4:]
    +                list_vals = [k.text for k in key.iterfind(list_path)]
    +                if list_vals:
    +                    stanza_obj[name] = list_vals
    +                else:
    +                    stanza_obj[name] = key.text
    +                    if key.text == "None":
    +                        stanza_obj[name] = None
    +        stanza_objs.append(stanza_obj)
    +    return stanza_objs
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/concurrent/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/concurrent/__init__.py
    new file mode 100644
    index 0000000..72d4509
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/concurrent/__init__.py
    @@ -0,0 +1,15 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/concurrent/concurrent_executor.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/concurrent/concurrent_executor.py
    new file mode 100644
    index 0000000..6615f53
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/concurrent/concurrent_executor.py
    @@ -0,0 +1,104 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +Concurrent executor provides concurrent executing function either in
    +a thread pool or a process pool
    +"""
    +
    +import splunktalib.concurrent.process_pool as pp
    +import splunktalib.concurrent.thread_pool as tp
    +
    +
    +class ConcurrentExecutor:
    +    def __init__(self, config):
    +        """
    +        :param config: dict like object, contains thread_min_size (int),
    +                       thread_max_size (int), daemonize_thread (bool),
    +                       process_size (int)
    +        """
    +
    +        self._io_executor = tp.ThreadPool(
    +            config.get("thread_min_size", 0),
    +            config.get("thread_max_size", 0),
    +            config.get("task_queue_size", 1024),
    +            config.get("daemonize_thread", True),
    +        )
    +        self._compute_executor = None
    +        if config.get("process_size", 0):
    +            self._compute_executor = pp.ProcessPool(config.get("process_size", 0))
    +
    +    def start(self):
    +        self._io_executor.start()
    +
    +    def tear_down(self):
    +        self._io_executor.tear_down()
    +        if self._compute_executor is not None:
    +            self._compute_executor.tear_down()
    +
    +    def run_io_func_sync(self, func, args=(), kwargs=None):
    +        """
    +        :param func: callable
    +        :param args: free params
    +        :param kwargs: named params
    +        :return whatever the func returns
    +        """
    +
    +        return self._io_executor.apply(func, args, kwargs)
    +
    +    def run_io_func_async(self, func, args=(), kwargs=None, callback=None):
    +        """
    +        :param func: callable
    +        :param args: free params
    +        :param kwargs: named params
    +        :calllback: when func is done and without exception, call the callback
    +        :return whatever the func returns
    +        """
    +
    +        return self._io_executor.apply_async(func, args, kwargs, callback)
    +
    +    def enqueue_io_funcs(self, funcs, block=True):
    +        """
    +        run jobs in a fire and forget way, no result will be handled
    +        over to clients
    +        :param funcs: tuple/list-like or generator like object, func shall be
    +                      callable
    +        """
    +
    +        return self._io_executor.enqueue_funcs(funcs, block)
    +
    +    def run_compute_func_sync(self, func, args=(), kwargs={}):
    +        """
    +        :param func: callable
    +        :param args: free params
    +        :param kwargs: named params
    +        :return whatever the func returns
    +        """
    +
    +        assert self._compute_executor is not None
    +        return self._compute_executor.apply(func, args, kwargs)
    +
    +    def run_compute_func_async(self, func, args=(), kwargs={}, callback=None):
    +        """
    +        :param func: callable
    +        :param args: free params
    +        :param kwargs: named params
    +        :calllback: when func is done and without exception, call the callback
    +        :return whatever the func returns
    +        """
    +
    +        assert self._compute_executor is not None
    +        return self._compute_executor.apply_async(func, args, kwargs, callback)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/concurrent/process_pool.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/concurrent/process_pool.py
    new file mode 100644
    index 0000000..6d9b4c7
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/concurrent/process_pool.py
    @@ -0,0 +1,81 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +A wrapper of multiprocessing.pool
    +"""
    +
    +import multiprocessing
    +
    +from splunktalib.common import log
    +
    +
    +class ProcessPool:
    +    """
    +    A simple wrapper of multiprocessing.pool
    +    """
    +
    +    def __init__(self, size=0, maxtasksperchild=10000):
    +        if size <= 0:
    +            size = multiprocessing.cpu_count()
    +        self.size = size
    +        self._pool = multiprocessing.Pool(
    +            processes=size, maxtasksperchild=maxtasksperchild
    +        )
    +        self._stopped = False
    +
    +    def tear_down(self):
    +        """
    +        Tear down the pool
    +        """
    +
    +        if self._stopped:
    +            log.logger.info("ProcessPool has already stopped.")
    +            return
    +        self._stopped = True
    +
    +        self._pool.close()
    +        self._pool.join()
    +        log.logger.info("ProcessPool stopped.")
    +
    +    def apply(self, func, args=(), kwargs={}):
    +        """
    +        :param func: callable
    +        :param args: free params
    +        :param kwargs: named params
    +        :return whatever the func returns
    +        """
    +
    +        if self._stopped:
    +            log.logger.info("ProcessPool has already stopped.")
    +            return None
    +
    +        return self._pool.apply(func, args, kwargs)
    +
    +    def apply_async(self, func, args=(), kwargs={}, callback=None):
    +        """
    +        :param func: callable
    +        :param args: free params
    +        :param kwargs: named params
    +        :callback: when func is done without exception, call this callack
    +        :return whatever the func returns
    +        """
    +
    +        if self._stopped:
    +            log.logger.info("ProcessPool has already stopped.")
    +            return None
    +
    +        return self._pool.apply_async(func, args, kwargs, callback)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/concurrent/thread_pool.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/concurrent/thread_pool.py
    new file mode 100644
    index 0000000..57c74e8
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/concurrent/thread_pool.py
    @@ -0,0 +1,366 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +A simple thread pool implementation
    +"""
    +
    +import multiprocessing
    +import queue
    +import threading
    +import traceback
    +from time import time
    +
    +from splunktalib.common import log
    +
    +
    +class ThreadPool:
    +    """
    +    A simple thread pool implementation
    +    """
    +
    +    _high_watermark = 0.2
    +    _resize_window = 10
    +
    +    def __init__(self, min_size=1, max_size=128, task_queue_size=1024, daemon=True):
    +        assert task_queue_size
    +
    +        if not min_size or min_size <= 0:
    +            min_size = multiprocessing.cpu_count()
    +
    +        if not max_size or max_size <= 0:
    +            max_size = multiprocessing.cpu_count() * 8
    +
    +        self._min_size = min_size
    +        self._max_size = max_size
    +        self._daemon = daemon
    +
    +        self._work_queue = queue.Queue(task_queue_size)
    +        self._thrs = []
    +        for _ in range(min_size):
    +            thr = threading.Thread(target=self._run)
    +            self._thrs.append(thr)
    +        self._admin_queue = queue.Queue()
    +        self._admin_thr = threading.Thread(target=self._do_admin)
    +        self._last_resize_time = time()
    +        self._last_size = min_size
    +        self._lock = threading.Lock()
    +        self._occupied_threads = 0
    +        self._count_lock = threading.Lock()
    +        self._started = False
    +
    +    def start(self):
    +        """
    +        Start threads in the pool
    +        """
    +
    +        with self._lock:
    +            if self._started:
    +                return
    +            self._started = True
    +
    +            for thr in self._thrs:
    +                thr.daemon = self._daemon
    +                thr.start()
    +
    +            self._admin_thr.start()
    +        log.logger.info("ThreadPool started.")
    +
    +    def tear_down(self):
    +        """
    +        Tear down thread pool
    +        """
    +
    +        with self._lock:
    +            if not self._started:
    +                return
    +            self._started = False
    +
    +            for thr in self._thrs:
    +                self._work_queue.put(None, block=True)
    +
    +            self._admin_queue.put(None)
    +
    +            if not self._daemon:
    +                log.logger.info("Wait for threads to stop.")
    +                for thr in self._thrs:
    +                    thr.join()
    +            self._admin_thr.join()
    +
    +        log.logger.info("ThreadPool stopped.")
    +
    +    def enqueue_funcs(self, funcs, block=True):
    +        """
    +        run jobs in a fire and forget way, no result will be handled
    +        over to clients
    +        :param funcs: tuple/list-like or generator like object, func shall be
    +                      callable
    +        """
    +
    +        if not self._started:
    +            log.logger.info("ThreadPool has already stopped.")
    +            return
    +
    +        for func in funcs:
    +            self._work_queue.put(func, block)
    +
    +    def apply_async(self, func, args=(), kwargs=None, callback=None):
    +        """
    +        :param func: callable
    +        :param args: free params
    +        :param kwargs: named params
    +        :callback: when func is done and without exception, call the callback
    +        :return AsyncResult, clients can poll or wait the result through it
    +        """
    +
    +        if not self._started:
    +            log.logger.info("ThreadPool has already stopped.")
    +            return None
    +
    +        res = AsyncResult(func, args, kwargs, callback)
    +        self._work_queue.put(res)
    +        return res
    +
    +    def apply(self, func, args=(), kwargs=None):
    +        """
    +        :param func: callable
    +        :param args: free params
    +        :param kwargs: named params
    +        :return whatever the func returns
    +        """
    +
    +        if not self._started:
    +            log.logger.info("ThreadPool has already stopped.")
    +            return None
    +
    +        res = self.apply_async(func, args, kwargs)
    +        return res.get()
    +
    +    def size(self):
    +        return self._last_size
    +
    +    def resize(self, new_size):
    +        """
    +        Resize the pool size, spawn or destroy threads if necessary
    +        """
    +
    +        if new_size <= 0:
    +            return
    +
    +        if self._lock.locked() or not self._started:
    +            log.logger.info(
    +                "Try to resize thread pool during the tear " "down process, do nothing"
    +            )
    +            return
    +
    +        with self._lock:
    +            self._remove_exited_threads_with_lock()
    +            size = self._last_size
    +            self._last_size = new_size
    +            if new_size > size:
    +                for _ in range(new_size - size):
    +                    thr = threading.Thread(target=self._run)
    +                    thr.daemon = self._daemon
    +                    thr.start()
    +                    self._thrs.append(thr)
    +            elif new_size < size:
    +                for _ in range(size - new_size):
    +                    self._work_queue.put(None)
    +        log.logger.info("Finished ThreadPool resizing. New size=%d", new_size)
    +
    +    def _remove_exited_threads_with_lock(self):
    +        """
    +        Join the exited threads last time when resize was called
    +        """
    +
    +        joined_thrs = set()
    +        for thr in self._thrs:
    +            if not thr.is_alive():
    +                try:
    +                    if not thr.daemon:
    +                        thr.join(timeout=0.5)
    +                    joined_thrs.add(thr.ident)
    +                except RuntimeError:
    +                    pass
    +
    +        if joined_thrs:
    +            live_thrs = []
    +            for thr in self._thrs:
    +                if thr.ident not in joined_thrs:
    +                    live_thrs.append(thr)
    +            self._thrs = live_thrs
    +
    +    def _do_resize_according_to_loads(self):
    +        if (
    +            self._last_resize_time
    +            and time() - self._last_resize_time < self._resize_window
    +        ):
    +            return
    +
    +        thr_size = self._last_size
    +        free_thrs = thr_size - self._occupied_threads
    +        work_size = self._work_queue.qsize()
    +
    +        log.logger.debug(
    +            "current_thr_size=%s, free_thrs=%s, work_size=%s",
    +            thr_size,
    +            free_thrs,
    +            work_size,
    +        )
    +        if work_size and work_size > free_thrs:
    +            if thr_size < self._max_size:
    +                thr_size = min(thr_size * 2, self._max_size)
    +                self.resize(thr_size)
    +        elif free_thrs > 0:
    +            free = free_thrs * 1.0
    +            if free / thr_size >= self._high_watermark and free_thrs >= 2:
    +                # 20 % thrs are idle, tear down half of the idle ones
    +                thr_size = thr_size - int(free_thrs // 2)
    +                if thr_size > self._min_size:
    +                    self.resize(thr_size)
    +        self._last_resize_time = time()
    +
    +    def _do_admin(self):
    +        admin_q = self._admin_queue
    +        resize_win = self._resize_window
    +        while 1:
    +            try:
    +                wakup = admin_q.get(timeout=resize_win + 1)
    +            except queue.Empty:
    +                self._do_resize_according_to_loads()
    +                continue
    +
    +            if wakup is None:
    +                break
    +            else:
    +                self._do_resize_according_to_loads()
    +        log.logger.info(
    +            "ThreadPool admin thread=%s stopped.", threading.current_thread().getName()
    +        )
    +
    +    def _run(self):
    +        """
    +        Threads callback func, run forever to handle jobs from the job queue
    +        """
    +
    +        work_queue = self._work_queue
    +        count_lock = self._count_lock
    +        while 1:
    +            log.logger.debug("Going to get job")
    +            func = work_queue.get()
    +            if func is None:
    +                break
    +
    +            if not self._started:
    +                break
    +
    +            log.logger.debug("Going to exec job")
    +            with count_lock:
    +                self._occupied_threads += 1
    +
    +            try:
    +                func()
    +            except Exception:
    +                log.logger.error(traceback.format_exc())
    +
    +            with count_lock:
    +                self._occupied_threads -= 1
    +
    +            log.logger.debug("Done with exec job")
    +            log.logger.info("Thread work_queue_size=%d", work_queue.qsize())
    +
    +        log.logger.debug(
    +            "Worker thread %s stopped.", threading.current_thread().getName()
    +        )
    +
    +
    +class AsyncResult:
    +    def __init__(self, func, args, kwargs, callback):
    +        self._func = func
    +        self._args = args
    +        self._kwargs = kwargs
    +        self._callback = callback
    +        self._q = queue.Queue()
    +
    +    def __call__(self):
    +        try:
    +            if self._args and self._kwargs:
    +                res = self._func(*self._args, **self._kwargs)
    +            elif self._args:
    +                res = self._func(*self._args)
    +            elif self._kwargs:
    +                res = self._func(**self._kwargs)
    +            else:
    +                res = self._func()
    +        except Exception as e:
    +            self._q.put(e)
    +            return
    +        else:
    +            self._q.put(res)
    +
    +        if self._callback is not None:
    +            self._callback()
    +
    +    def get(self, timeout=None):
    +        """
    +        Return the result when it arrives. If timeout is not None and the
    +        result does not arrive within timeout seconds then
    +        multiprocessing.TimeoutError is raised. If the remote call raised an
    +        exception then that exception will be reraised by get().
    +        """
    +
    +        try:
    +            res = self._q.get(timeout=timeout)
    +        except queue.Empty:
    +            raise multiprocessing.TimeoutError("Timed out")
    +
    +        if isinstance(res, Exception):
    +            raise res
    +        return res
    +
    +    def wait(self, timeout=None):
    +        """
    +        Wait until the result is available or until timeout seconds pass.
    +        """
    +
    +        try:
    +            res = self._q.get(timeout=timeout)
    +        except queue.Empty:
    +            pass
    +        else:
    +            self._q.put(res)
    +
    +    def ready(self):
    +        """
    +        Return whether the call has completed.
    +        """
    +
    +        return len(self._q)
    +
    +    def successful(self):
    +        """
    +        Return whether the call completed without raising an exception.
    +        Will raise AssertionError if the result is not ready.
    +        """
    +
    +        if not self.ready():
    +            raise AssertionError("Function is not ready")
    +        res = self._q.get()
    +        self._q.put(res)
    +
    +        if isinstance(res, Exception):
    +            return False
    +        return True
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/__init__.py
    new file mode 100644
    index 0000000..72d4509
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/__init__.py
    @@ -0,0 +1,15 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/conf_endpoints.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/conf_endpoints.py
    new file mode 100644
    index 0000000..ebda81c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/conf_endpoints.py
    @@ -0,0 +1,162 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 splunktalib.common.util as util
    +import splunktalib.common.xml_dom_parser as xdp
    +from splunktalib.conf_manager.request import content_request
    +
    +CONF_ENDPOINT = "%s/servicesNS/%s/%s/configs/conf-%s"
    +
    +
    +def _conf_endpoint_ns(uri, owner, app, conf_name):
    +    return CONF_ENDPOINT % (uri, owner, app, conf_name)
    +
    +
    +def reload_conf(splunkd_uri, session_key, app_name, conf_name, throw=False):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param conf_names: a list of the name of the conf file, e.g. ["props"]
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    """
    +
    +    uri = _conf_endpoint_ns(splunkd_uri, "nobody", app_name, conf_name)
    +    uri += "/_reload"
    +    msg = "Failed to reload conf in app={}: {}".format(app_name, conf_name)
    +
    +    try:
    +        content_request(uri, session_key, "GET", None, msg)
    +    except Exception:
    +        if throw:
    +            raise
    +
    +
    +def create_stanza(
    +    splunkd_uri, session_key, owner, app_name, conf_name, stanza, key_values
    +):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param conf_name: the name of the conf file, e.g. "props"
    +    :param stanza: stanza name, e.g. "aws:cloudtrail"
    +    :param key_values: the key-value dict of the stanza
    +    :return: None on success otherwise throw exception
    +    """
    +
    +    uri = _conf_endpoint_ns(splunkd_uri, owner, app_name, conf_name)
    +    msg = "Failed to create stanza={} in conf={}".format(stanza, conf_name)
    +    payload = {"name": str(stanza).encode("utf-8")}
    +    for key in key_values:
    +        if key != "name":
    +            payload[key] = str(key_values[key])
    +
    +    content_request(uri, session_key, "POST", payload, msg)
    +
    +
    +def get_conf(splunkd_uri, session_key, owner, app_name, conf_name, stanza=None):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param conf_name: the name of the conf file, e.g. "props"
    +    :param stanza: stanza name, e.g. "aws:cloudtrail"
    +    :return: a list of stanzas in the conf file, including metadata
    +    """
    +
    +    uri = _conf_endpoint_ns(splunkd_uri, owner, app_name, conf_name)
    +
    +    if stanza:
    +        uri += "/" + util.format_stanza_name(stanza)
    +
    +    # get all the stanzas at one time
    +    uri += "?count=0&offset=0"
    +
    +    msg = "Failed to get stanza={} in conf={}".format(
    +        stanza if stanza else stanza,
    +        conf_name,
    +    )
    +    content = content_request(uri, session_key, "GET", None, msg)
    +    return xdp.parse_conf_xml_dom(content)
    +
    +
    +def update_stanza(
    +    splunkd_uri, session_key, owner, app_name, conf_name, stanza, key_values
    +):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param conf_name: the name of the conf file, e.g. "props"
    +    :param stanza: stanza name, e.g. "aws:cloudtrail"
    +    :param key_values: the key-value dict of the stanza
    +    :return: None on success otherwise raise exception
    +    """
    +
    +    uri = _conf_endpoint_ns(splunkd_uri, owner, app_name, conf_name)
    +    uri += "/" + util.format_stanza_name(stanza)
    +    msg = "Failed to update stanza={} in conf={}".format(stanza, conf_name)
    +    return content_request(uri, session_key, "POST", key_values, msg)
    +
    +
    +def delete_stanza(
    +    splunkd_uri, session_key, owner, app_name, conf_name, stanza, throw=False
    +):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param conf_name: the name of the conf file, e.g. "props"
    +    :param stanza: stanza name, e.g. "aws:cloudtrail"
    +    :return: None on success otherwise raise exception
    +    """
    +
    +    uri = _conf_endpoint_ns(splunkd_uri, owner, app_name, conf_name)
    +    uri += "/" + util.format_stanza_name(stanza)
    +    msg = "Failed to delete stanza={} in conf={}".format(stanza, conf_name)
    +    content_request(uri, session_key, "DELETE", None, msg)
    +
    +
    +def stanza_exist(splunkd_uri, session_key, owner, app_name, conf_name, stanza):
    +    try:
    +        res = get_conf(splunkd_uri, session_key, owner, app_name, conf_name, stanza)
    +        return len(res) > 0
    +    except Exception:
    +        return False
    +
    +
    +def operate_conf(
    +    splunkd_uri, session_key, owner, app_name, conf_name, stanza, operation
    +):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param conf_name: the name of the conf file, e.g. "props"
    +    :param stanza: stanza name, e.g. "aws:cloudtrail"
    +    :param operation: must be "disable" or "enable"
    +    """
    +
    +    assert operation in ("disable", "enable")
    +    uri = _conf_endpoint_ns(splunkd_uri, owner, app_name, conf_name)
    +    uri += "/{}/{}".format(util.format_stanza_name(stanza), operation)
    +    msg = "Failed to disable/enable stanza={} in conf={}".format(stanza, conf_name)
    +    content_request(uri, session_key, "POST", None, msg)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/conf_manager.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/conf_manager.py
    new file mode 100644
    index 0000000..3fea0c1
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/conf_manager.py
    @@ -0,0 +1,311 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +This module hanles configuration related stuff
    +"""
    +
    +import os.path as op
    +
    +import splunktalib.conf_manager.conf_endpoints as scmc
    +import splunktalib.conf_manager.data_input_endpoints as scmdi
    +import splunktalib.conf_manager.property_endpoints as scmp
    +import splunktalib.conf_manager.request as req
    +
    +
    +def conf_file2name(conf_file):
    +    conf_name = op.basename(conf_file)
    +    if conf_name.endswith(".conf"):
    +        conf_name = conf_name[:-5]
    +    return conf_name
    +
    +
    +class ConfManager:
    +    def __init__(self, splunkd_uri, session_key, owner="nobody", app_name="-"):
    +        """
    +        :app_name: when creating conf stanza, app_name is required to set not
    +        to "-"
    +        :owner: when creating conf stanza, app_name is required to set not
    +        to "-"
    +        """
    +
    +        self.splunkd_uri = splunkd_uri
    +        self.session_key = session_key
    +        self.owner = owner
    +        self.app_name = app_name
    +
    +    def set_appname(self, appname):
    +        """
    +        This are cases we need edit/remove/create confs in different app
    +        context. call this interface to switch app context before manipulate
    +        the confs in different app context
    +        """
    +
    +        self.app_name = appname
    +
    +    def all_stanzas(self, conf_name, do_reload=False, ret_metadata=False):
    +        """
    +        :return: a list of dict stanza objects if successful.
    +                 Otherwise raise exception
    +        """
    +
    +        if do_reload:
    +            self.reload_conf(conf_name)
    +
    +        stanzas = scmc.get_conf(self.splunkd_uri, self.session_key, "-", "-", conf_name)
    +        return self._delete_metadata(stanzas, ret_metadata)
    +
    +    def all_stanzas_as_dicts(self, conf_name, do_reload=False, ret_metadata=False):
    +        """
    +        :return: a dict of dict stanza objects if successful.
    +                 otherwise raise exception
    +        """
    +
    +        stanzas = self.all_stanzas(conf_name, do_reload, ret_metadata)
    +        return {stanza["name"]: stanza for stanza in stanzas}
    +
    +    def get_stanza(self, conf_name, stanza, do_reload=False, ret_metadata=False):
    +        """
    +        @return dict if success otherwise raise exception
    +        """
    +
    +        if do_reload:
    +            self.reload_conf(conf_name)
    +
    +        stanzas = scmc.get_conf(
    +            self.splunkd_uri, self.session_key, "-", "-", conf_name, stanza
    +        )
    +        stanzas = self._delete_metadata(stanzas, ret_metadata)
    +        return stanzas[0]
    +
    +    def reload_conf(self, conf_name):
    +        scmc.reload_conf(self.splunkd_uri, self.session_key, "-", conf_name)
    +
    +    def enable_conf(self, conf_name, stanza):
    +        scmc.operate_conf(
    +            self.splunkd_uri,
    +            self.session_key,
    +            self.owner,
    +            self.app_name,
    +            conf_name,
    +            stanza,
    +            "enable",
    +        )
    +
    +    def disable_conf(self, conf_name, stanza):
    +        scmc.operate_conf(
    +            self.splunkd_uri,
    +            self.session_key,
    +            self.owner,
    +            self.app_name,
    +            conf_name,
    +            stanza,
    +            "disable",
    +        )
    +
    +    def get_property(self, conf_name, stanza, key, do_reload=False):
    +        if do_reload:
    +            self.reload_conf(conf_name)
    +
    +        return scmp.get_property(
    +            self.splunkd_uri, self.session_key, "-", "-", conf_name, stanza, key
    +        )
    +
    +    def stanza_exist(self, conf_name, stanza):
    +        return scmc.stanza_exist(
    +            self.splunkd_uri, self.session_key, "-", "-", conf_name, stanza
    +        )
    +
    +    def create_stanza(self, conf_name, stanza, key_values):
    +        scmc.create_stanza(
    +            self.splunkd_uri,
    +            self.session_key,
    +            self.owner,
    +            self.app_name,
    +            conf_name,
    +            stanza,
    +            key_values,
    +        )
    +
    +    def update_stanza(self, conf_name, stanza, key_values):
    +        scmc.update_stanza(
    +            self.splunkd_uri,
    +            self.session_key,
    +            self.owner,
    +            self.app_name,
    +            conf_name,
    +            stanza,
    +            key_values,
    +        )
    +
    +    def delete_stanza(self, conf_name, stanza):
    +        scmc.delete_stanza(
    +            self.splunkd_uri,
    +            self.session_key,
    +            self.owner,
    +            self.app_name,
    +            conf_name,
    +            stanza,
    +        )
    +
    +    def create_properties(self, conf_name, stanza):
    +        scmp.create_properties(
    +            self.splunkd_uri,
    +            self.session_key,
    +            self.owner,
    +            self.app_name,
    +            conf_name,
    +            stanza,
    +        )
    +
    +    def update_properties(self, conf_name, stanza, key_values):
    +        scmp.update_properties(
    +            self.splunkd_uri,
    +            self.session_key,
    +            self.owner,
    +            self.app_name,
    +            conf_name,
    +            stanza,
    +            key_values,
    +        )
    +
    +    def delete_stanzas(self, conf_name, stanzas):
    +        """
    +        :param stanzas: list of stanzas
    +        :return: list of failed stanzas
    +        """
    +
    +        failed_stanzas = []
    +        for stanza in stanzas:
    +            try:
    +                self.delete_stanza(conf_name, stanza)
    +            except Exception:
    +                failed_stanzas.append(stanza)
    +        return failed_stanzas
    +
    +    # data input management
    +    def create_data_input(self, input_type, name, key_values=None):
    +        scmdi.create_data_input(
    +            self.splunkd_uri,
    +            self.session_key,
    +            self.owner,
    +            self.app_name,
    +            input_type,
    +            name,
    +            key_values,
    +        )
    +
    +    def update_data_input(self, input_type, name, key_values):
    +        scmdi.update_data_input(
    +            self.splunkd_uri,
    +            self.session_key,
    +            self.owner,
    +            self.app_name,
    +            input_type,
    +            name,
    +            key_values,
    +        )
    +
    +    def delete_data_input(self, input_type, name):
    +        scmdi.delete_data_input(
    +            self.splunkd_uri,
    +            self.session_key,
    +            self.owner,
    +            self.app_name,
    +            input_type,
    +            name,
    +        )
    +
    +    def get_data_input(self, input_type, name=None, do_reload=False):
    +        if do_reload:
    +            self.reload_data_input(input_type)
    +
    +        return scmdi.get_data_input(
    +            self.splunkd_uri, self.session_key, "-", "-", input_type, name
    +        )
    +
    +    def reload_data_input(self, input_type):
    +        scmdi.reload_data_input(
    +            self.splunkd_uri, self.session_key, "-", "-", input_type
    +        )
    +
    +    def enable_data_input(self, input_type, name):
    +        scmdi.operate_data_input(
    +            self.splunkd_uri,
    +            self.session_key,
    +            self.owner,
    +            self.app_name,
    +            input_type,
    +            name,
    +            "enable",
    +        )
    +
    +    def disable_data_input(self, input_type, name):
    +        scmdi.operate_data_input(
    +            self.splunkd_uri,
    +            self.session_key,
    +            self.owner,
    +            self.app_name,
    +            input_type,
    +            name,
    +            "disable",
    +        )
    +
    +    def data_input_exist(self, input_type, name):
    +        try:
    +            result = self.get_data_input(input_type, name)
    +        except req.ConfNotExistsException:
    +            return False
    +
    +        return result is not None
    +
    +    def all_data_input_stanzas(self, input_type, do_reload=False, ret_metadata=False):
    +        stanzas = self.get_data_input(input_type, do_reload=do_reload)
    +        for stanza in stanzas:
    +            if "eai:acl" in stanza and "app" in stanza["eai:acl"]:
    +                stanza["appName"] = stanza["eai:acl"]["app"]
    +                stanza["userName"] = stanza["eai:acl"].get("owner", "nobody")
    +        return self._delete_metadata(stanzas, ret_metadata)
    +
    +    def get_data_input_stanza(
    +        self, input_type, name, do_reload=False, ret_metadata=False
    +    ):
    +
    +        stanzas = self.get_data_input(input_type, name, do_reload)
    +        stanzas = self._delete_metadata(stanzas, ret_metadata)
    +        return stanzas[0]
    +
    +    def delete_data_input_stanzas(self, input_type, names):
    +        """
    +        :param stanzas: list of stanzas
    +        :return: list of failed stanzas
    +        """
    +
    +        failed_names = []
    +        for name in names:
    +            try:
    +                self.delete_data_input(input_type, name)
    +            except Exception:
    +                failed_names.append(name)
    +        return failed_names
    +
    +    def _delete_metadata(self, stanzas, ret_metadata):
    +        if stanzas and not ret_metadata:
    +            for stanza in stanzas:
    +                for key in list(stanza.keys()):
    +                    if key.startswith("eai:"):
    +                        del stanza[key]
    +        return stanzas
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/data_input_endpoints.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/data_input_endpoints.py
    new file mode 100644
    index 0000000..a17ab72
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/data_input_endpoints.py
    @@ -0,0 +1,186 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 splunktalib.common.util as util
    +import splunktalib.common.xml_dom_parser as xdp
    +from splunktalib.conf_manager.request import content_request
    +
    +INPUT_ENDPOINT = "%s/servicesNS/%s/%s/data/inputs/%s"
    +
    +
    +def _input_endpoint_ns(uri, owner, app, input_type):
    +    return INPUT_ENDPOINT % (uri, owner, app, input_type)
    +
    +
    +def reload_data_input(
    +    splunkd_uri, session_key, owner, app_name, input_type, throw=False
    +):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param input_type: name of the input type.
    +                       if it is a script input, the input is "script",
    +                       for modinput, say snow, the input is "snow"
    +    """
    +
    +    uri = _input_endpoint_ns(splunkd_uri, owner, app_name, input_type)
    +    uri += "/_reload"
    +    msg = "Failed to reload data input in app={}: {}".format(app_name, input_type)
    +    try:
    +        content_request(uri, session_key, "GET", None, msg)
    +    except Exception:
    +        if throw:
    +            raise
    +
    +
    +def create_data_input(
    +    splunkd_uri, session_key, owner, app_name, input_type, name, key_values
    +):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param input_type: name of the input type.
    +                       if it is a script input, the input is "script",
    +                       for modinput, say snow, the input is "snow"
    +    :param name: The name of the input stanza to create.
    +                 i.e. stanza [<input_type>://<name>] will be created.
    +    :param key_values: a K-V dict of details in the data input stanza.
    +    :return: None on success else raise exception
    +    """
    +
    +    key_values["name"] = str(name).encode("utf-8")
    +    uri = _input_endpoint_ns(splunkd_uri, owner, app_name, input_type)
    +    msg = "Failed to create data input in app={}: {}://{}".format(
    +        app_name,
    +        input_type,
    +        name,
    +    )
    +    content_request(uri, session_key, "POST", key_values, msg)
    +
    +
    +def get_data_input(splunkd_uri, session_key, owner, app_name, input_type, name=None):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param input_type: name of the input type.
    +                       if it is a script input, the input is "script",
    +                       for modinput, say snow, the input is "snow"
    +    :param name: The name of the input stanza to create.
    +                 i.e. stanza [<input_type>://<name>] will be deleted.
    +    :return: a list of stanzas in the input type, including metadata
    +    """
    +
    +    uri = _input_endpoint_ns(splunkd_uri, owner, app_name, input_type)
    +    if name:
    +        uri += "/" + util.format_stanza_name(name)
    +
    +    # get all the stanzas at one time
    +    uri += "?count=0&offset=0"
    +
    +    msg = "Failed to get data input in app={}: {}://{}".format(
    +        app_name,
    +        input_type,
    +        name if name else name,
    +    )
    +    content = content_request(uri, session_key, "GET", None, msg)
    +    return xdp.parse_conf_xml_dom(content)
    +
    +
    +def update_data_input(
    +    splunkd_uri, session_key, owner, app_name, input_type, name, key_values
    +):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param input_type: name of the input type.
    +                       if it is a script input, the input is "script",
    +                       for modinput, say snow, the input is "snow"
    +    :param name: The name of the input stanza to create.
    +                 i.e. stanza [<input_type>://<name>] will be updated.
    +    :param key_values: a K-V dict of details in the data input stanza.
    +    :return: raise exception when failure
    +    """
    +
    +    if "name" in key_values:
    +        del key_values["name"]
    +    uri = _input_endpoint_ns(splunkd_uri, owner, app_name, input_type)
    +    uri += "/" + util.format_stanza_name(name)
    +    msg = "Failed to update data input in app={}: {}://{}".format(
    +        app_name,
    +        input_type,
    +        name,
    +    )
    +    content_request(uri, session_key, "POST", key_values, msg)
    +
    +
    +def delete_data_input(splunkd_uri, session_key, owner, app_name, input_type, name):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param input_type: name of the input type.
    +                       if it is a script input, the input is "script",
    +                       for modinput, say snow, the input is "snow"
    +    :param name: The name of the input stanza to create.
    +                 i.e. stanza [<input_type>://<name>] will be deleted.
    +    :return raise exception when failed
    +    """
    +
    +    uri = _input_endpoint_ns(splunkd_uri, owner, app_name, input_type)
    +    uri += "/" + util.format_stanza_name(name)
    +    msg = "Failed to delete data input in app={}: {}://{}".format(
    +        app_name,
    +        input_type,
    +        name,
    +    )
    +    content_request(uri, session_key, "DELETE", None, msg)
    +
    +
    +def operate_data_input(
    +    splunkd_uri, session_key, owner, app_name, input_type, name, operation
    +):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param input_type: name of the input type.
    +                       if it is a script input, the input is "script",
    +                       for modinput, say snow, the input is "snow"
    +    :param name: The name of the input stanza to create.
    +                 i.e. stanza [<input_type>://<name>] will be operated.
    +    :param operation: must be "disable" or "enable"
    +    """
    +
    +    assert operation in ("disable", "enable")
    +    uri = _input_endpoint_ns(splunkd_uri, owner, app_name, input_type)
    +    uri += "/{}/{}".format(util.format_stanza_name(name), operation)
    +    msg = "Failed to {} data input in app={}: {}://{}".format(
    +        operation,
    +        app_name,
    +        input_type,
    +        name,
    +    )
    +    content_request(uri, session_key, "POST", None, msg)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/property_endpoints.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/property_endpoints.py
    new file mode 100644
    index 0000000..b28e2e5
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/property_endpoints.py
    @@ -0,0 +1,93 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 splunktalib.common.util as util
    +from splunktalib.conf_manager.request import content_request
    +
    +PROPERTY_ENDPOINT = "%s/servicesNS/%s/%s/properties/%s"
    +
    +
    +def _property_endpoint_ns(uri, owner, app, conf_name):
    +    return PROPERTY_ENDPOINT % (uri, owner, app, conf_name)
    +
    +
    +def create_properties(splunkd_uri, session_key, owner, app_name, conf_name, stanza):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param conf_name: the name of the conf file, e.g. "props"
    +    :param stanza: stanza name, e.g. "aws:cloudtrail"
    +    :return: None on success else raise exception
    +    """
    +
    +    uri = _property_endpoint_ns(splunkd_uri, owner, app_name, conf_name)
    +    msg = "Properties: failed to create stanza={} in conf={}".format(stanza, conf_name)
    +    payload = {"__stanza": stanza}
    +    content_request(uri, session_key, "POST", payload, msg)
    +
    +
    +def get_property(splunkd_uri, session_key, owner, app_name, conf_name, stanza, key):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param conf_name: the name of the conf file, e.g. "props"
    +    :param stanza: stanza name, e.g. "aws:cloudtrail"
    +    :param key: the property name
    +    :return: the property value
    +    """
    +
    +    uri = _property_endpoint_ns(splunkd_uri, owner, app_name, conf_name)
    +    uri += "/{}/{}".format(util.format_stanza_name(stanza), key)
    +    msg = "Properties: failed to get conf={}, stanza={}, key={}".format(
    +        conf_name,
    +        stanza,
    +        key,
    +    )
    +    return content_request(uri, session_key, "GET", None, msg)
    +
    +
    +def update_properties(
    +    splunkd_uri, session_key, owner, app_name, conf_name, stanza, key_values
    +):
    +    """
    +    :param splunkd_uri: splunkd uri, e.g. https://127.0.0.1:8089
    +    :param session_key: splunkd session key
    +    :param owner: the owner (ACL user), e.g. "-", "nobody"
    +    :param app_name: the app"s name, e.g. "Splunk_TA_aws"
    +    :param conf_name: the name of the conf file, e.g. "props"
    +    :param stanza: stanza name, e.g. "aws:cloudtrail"
    +    :param key_values: the key-value dict of the stanza
    +    :return: raise exception when failed
    +    """
    +
    +    uri = _property_endpoint_ns(splunkd_uri, owner, app_name, conf_name)
    +    uri += "/" + util.format_stanza_name(stanza)
    +    msg = "Properties: failed to update conf={}, stanza={}".format(conf_name, stanza)
    +
    +    has_name = False
    +    if "name" in key_values:
    +        has_name = True
    +        name = key_values["name"]
    +        del key_values["name"]
    +
    +    content_request(uri, session_key, "POST", key_values, msg)
    +
    +    if has_name:
    +        key_values["name"] = name
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/request.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/request.py
    new file mode 100644
    index 0000000..c1bc3fb
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/request.py
    @@ -0,0 +1,63 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 splunktalib.rest as rest
    +from splunktalib.common import log
    +
    +
    +class ConfRequestException(Exception):
    +    pass
    +
    +
    +class ConfNotExistsException(ConfRequestException):
    +    pass
    +
    +
    +class ConfExistsException(ConfRequestException):
    +    pass
    +
    +
    +def content_request(uri, session_key, method, payload, err_msg):
    +    """
    +    :return: response content if successful otherwise raise
    +    ConfRequestException
    +    """
    +
    +    resp = rest.splunkd_request(uri, session_key, method, data=payload, retry=3)
    +    if resp is None:
    +        return None
    +
    +    if resp.status_code >= 200 and resp.status_code <= 204:
    +        return resp.text
    +    else:
    +        msg = "{}, status={}, reason={}, detail={}".format(
    +            err_msg,
    +            resp.status_code,
    +            resp.reason,
    +            resp.text,
    +        )
    +
    +        if not (method == "GET" and resp.status_code == 404):
    +            log.logger.error(msg)
    +
    +        if resp.status_code == 404:
    +            raise ConfNotExistsException(msg)
    +        if resp.status_code == 409:
    +            raise ConfExistsException(msg)
    +        else:
    +            if resp.text and "already exists" in resp.text:
    +                raise ConfExistsException(msg)
    +            raise ConfRequestException(msg)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/ta_conf_manager.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/ta_conf_manager.py
    new file mode 100644
    index 0000000..bc51242
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/conf_manager/ta_conf_manager.py
    @@ -0,0 +1,226 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +This module hanles high level TA configuration related stuff
    +"""
    +
    +import copy
    +import os.path as op
    +
    +import splunktalib.common.util as utils
    +import splunktalib.conf_manager.conf_manager as conf
    +import splunktalib.conf_manager.request as conf_req
    +import splunktalib.credentials as cred
    +
    +
    +class TAConfManager:
    +
    +    encrypted_token = "******"
    +    reserved_keys = ("userName", "appName")
    +
    +    def __init__(self, conf_file, splunkd_uri, session_key, appname=None):
    +        if appname is None:
    +            appname = utils.get_appname_from_path(op.abspath(__file__))
    +        self._conf_file = conf.conf_file2name(conf_file)
    +        self._conf_mgr = conf.ConfManager(splunkd_uri, session_key, app_name=appname)
    +        self._cred_mgr = cred.CredentialManager(
    +            splunkd_uri, session_key, app=appname, owner="nobody", realm=appname
    +        )
    +        self._keys = None
    +
    +    def set_appname(self, appname):
    +        """
    +        This are cases we need edit/remove/create confs in different app
    +        context. call this interface to switch app context before manipulate
    +        the confs in different app context
    +        """
    +
    +        self._conf_mgr.set_appname(appname)
    +        self._cred_mgr.set_appname(appname)
    +
    +    def _delete_reserved_keys(self, stanza):
    +        new_stanza = copy.deepcopy(stanza)
    +        for k in self.reserved_keys:
    +            if k in new_stanza:
    +                del new_stanza[k]
    +        return new_stanza
    +
    +    def create(self, stanza):
    +        """
    +        @stanza: dict like object
    +        {
    +        "name": xxx,
    +        "k1": v1,
    +        "k2": v2,
    +        ...
    +        }
    +        @return exception if failure
    +        """
    +
    +        stanza = self._delete_reserved_keys(stanza)
    +        encrypted_stanza = self._encrypt(stanza)
    +        self._conf_mgr.create_stanza(
    +            self._conf_file, encrypted_stanza["name"], encrypted_stanza
    +        )
    +
    +    def update(self, stanza):
    +        """
    +        @stanza: dict like object
    +        {
    +        "name": xxx,
    +        "k1": v1,
    +        "k2": v2,
    +        ...
    +        }
    +
    +        @return: exception if failure
    +        """
    +
    +        if not self._conf_mgr.stanza_exist(self._conf_file, stanza["name"]):
    +            self.create(stanza)
    +        else:
    +            stanza = self._delete_reserved_keys(stanza)
    +            encrypted_stanza = self._encrypt(stanza)
    +            self._conf_mgr.update_properties(
    +                self._conf_file, encrypted_stanza["name"], encrypted_stanza
    +            )
    +
    +    def delete(self, stanza_name):
    +        """
    +        @return: exception if failure
    +        """
    +
    +        try:
    +            stanza = self._conf_mgr.get_stanza(self._conf_file, stanza_name)
    +        except conf_req.ConfNotExistsException:
    +            return
    +
    +        self._delete_creds(stanza)
    +        self._conf_mgr.delete_stanza(self._conf_file, stanza_name)
    +
    +    def get(self, stanza_name, return_acl=False):
    +        """
    +        @return: dict object if sucess otherwise raise exception
    +        """
    +
    +        stanza = self._conf_mgr.get_stanza(
    +            self._conf_file, stanza_name, ret_metadata=return_acl
    +        )
    +        stanza = self._decrypt(stanza)
    +        stanza["disabled"] = utils.is_true(stanza.get("disabled"))
    +        return stanza
    +
    +    def all(self, filter_disabled=False, return_acl=True):
    +        """
    +        @return: a dict of dict objects if success
    +        otherwise exception
    +        """
    +
    +        results = {}
    +        stanzas = self._conf_mgr.all_stanzas(self._conf_file, ret_metadata=return_acl)
    +        for stanza in stanzas:
    +            stanza = self._decrypt(stanza)
    +            stanza["disabled"] = utils.is_true(stanza.get("disabled"))
    +            if filter_disabled and stanza["disabled"]:
    +                continue
    +            results[stanza["name"]] = stanza
    +        return results
    +
    +    def reload(self):
    +        self._conf_mgr.reload_conf(self._conf_file)
    +
    +    def set_encrypt_keys(self, keys):
    +        """
    +        :keys: a list keys of a stanza which need to be encrypted
    +        for example: ["username", "password"]
    +        """
    +
    +        self._keys = keys
    +
    +    def is_encrypted(self, stanza):
    +        """
    +        :stanza: dict object
    +        return True if the values of encrypt keys equals self.encrypted_token
    +        otherwise return False
    +        """
    +
    +        if self._keys is None:
    +            return False
    +
    +        for k in stanza.keys():
    +            if k in self._keys:
    +                if stanza.get(k) == self.encrypted_token:
    +                    return True
    +        return False
    +
    +    def _encrypt(self, stanza):
    +        """
    +        :stanza: if self._keys are in stanza, encrypt the values of the key
    +        and then mask the value to self.encrypted_token
    +        """
    +
    +        if self._keys is None:
    +            return stanza
    +
    +        stanza_to_be_encrypted = {}
    +        for key in self._keys:
    +            if key in stanza:
    +                stanza_to_be_encrypted[key] = stanza[key]
    +
    +        if stanza_to_be_encrypted:
    +            self._cred_mgr.update({stanza["name"]: stanza_to_be_encrypted})
    +            encrypted_stanza = copy.deepcopy(stanza)
    +            for key in stanza_to_be_encrypted.keys():
    +                encrypted_stanza[key] = self.encrypted_token
    +            return encrypted_stanza
    +        return stanza
    +
    +    def _decrypt(self, stanza):
    +        """
    +        :stanza: if there are keys in self._keys in stanza and if the values of
    +        the keys are self.encrypted_token, decrypt the value
    +        """
    +
    +        if self._keys is None:
    +            return stanza
    +
    +        stanza_name = stanza["name"]
    +        clear_password = None
    +        for key in self._keys:
    +            if key in stanza and stanza[key] == self.encrypted_token:
    +                clear_password = self._cred_mgr.get_clear_password(stanza_name)
    +                break
    +
    +        if clear_password:
    +            for key in self._keys:
    +                if key in clear_password[stanza_name]:
    +                    stanza[key] = clear_password[stanza_name][key]
    +        return stanza
    +
    +    def _delete_creds(self, stanza):
    +        """
    +        :stanza: if there are keys of self._keys and the keys are in stanza,
    +        delete the encrypted creds
    +        """
    +
    +        if self._keys is None:
    +            return
    +
    +        for key in self._keys:
    +            if key in stanza:
    +                self._cred_mgr.delete(stanza["name"])
    +                break
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/credentials.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/credentials.py
    new file mode 100644
    index 0000000..5985bfd
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/credentials.py
    @@ -0,0 +1,391 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +Handles credentials related stuff
    +"""
    +
    +import re
    +import warnings
    +
    +import defusedxml.minidom as xdm
    +
    +import splunktalib.common.util as util
    +import splunktalib.common.xml_dom_parser as xdp
    +import splunktalib.rest as rest
    +
    +# Splunk can only encrypt string when length <=255
    +SPLUNK_CRED_LEN_LIMIT = 255
    +
    +
    +class CredException(Exception):
    +    pass
    +
    +
    +class CredNotFound(CredException):
    +    """
    +    Credential information not exists
    +    """
    +
    +    pass
    +
    +
    +def create_credential_manager(username, password, splunkd_uri, app, owner, realm):
    +    warnings.warn(
    +        "This function is deprecated. "
    +        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +        DeprecationWarning,
    +        stacklevel=2,
    +    )
    +    session_key = CredentialManager.get_session_key(username, password, splunkd_uri)
    +    return CredentialManager(splunkd_uri, session_key, app, owner, realm)
    +
    +
    +class CredentialManager:
    +    """
    +    Credential related interfaces
    +    """
    +
    +    def __init__(self, splunkd_uri, session_key, app="-", owner="nobody", realm=None):
    +        """
    +        :app: when creating/upating/deleting app is required
    +        """
    +        warnings.warn(
    +            "This class is deprecated. "
    +            "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +            DeprecationWarning,
    +            stacklevel=2,
    +        )
    +
    +        self._app = app
    +        self._splunkd_uri = splunkd_uri
    +        self._owner = owner
    +        self._sep = "``splunk_cred_sep``"
    +
    +        if realm:
    +            self._realm = realm
    +        else:
    +            self._realm = app
    +
    +        self._session_key = session_key
    +
    +    def set_appname(self, app):
    +        """
    +        This are cases we need edit/remove/create confs in different app
    +        context. call this interface to switch app context before manipulate
    +        the confs in different app context
    +        """
    +
    +        self._app = app
    +
    +    @staticmethod
    +    def get_session_key(username, password, splunkd_uri="https://localhost:8089"):
    +        """
    +        Get session key by using login username and passwrod
    +        :return: session_key if successful, None if failed
    +        """
    +
    +        eid = "".join((splunkd_uri, "/services/auth/login"))
    +        postargs = {
    +            "username": username,
    +            "password": password,
    +        }
    +
    +        response = rest.splunkd_request(eid, None, method="POST", data=postargs)
    +
    +        if response is None:
    +            raise CredException("Get session key failed.")
    +
    +        xml_obj = xdm.parseString(response.text)
    +        session_nodes = xml_obj.getElementsByTagName("sessionKey")
    +        if not session_nodes:
    +            raise CredException("Invalid username or password.")
    +        session_key = session_nodes[0].firstChild.nodeValue
    +        if not session_key:
    +            raise CredException("Get session key failed.")
    +        return session_key
    +
    +    def update(self, stanza):
    +        """
    +        Update or Create credentials based on the stanza
    +        :stanza: nested dict object. The outlayer keys are stanza name, and
    +                 inner dict is user/pass key/value pair to be encrypted
    +         {
    +         "stanza_name": {"tommy": "tommypasswod", "jerry": "jerrypassword"}
    +         }
    +        :return: raise on failure
    +        """
    +
    +        for name, encr_dict in list(stanza.items()):
    +            encrypts = []
    +            for key, val in list(encr_dict.items()):
    +                encrypts.append(key)
    +                encrypts.append(val)
    +            self._update(name, self._sep.join(encrypts))
    +
    +    def _update(self, name, str_to_encrypt):
    +        """
    +        Update the string for the name.
    +        :return: raise on failure
    +        """
    +
    +        if len(str_to_encrypt) <= SPLUNK_CRED_LEN_LIMIT:
    +            self._do_update(name, str_to_encrypt)
    +            return
    +
    +        # split the str_to_encrypt when len > 255
    +        length = SPLUNK_CRED_LEN_LIMIT
    +        i = 0
    +        while length < len(str_to_encrypt) + SPLUNK_CRED_LEN_LIMIT:
    +            curr_str = str_to_encrypt[length - SPLUNK_CRED_LEN_LIMIT : length]
    +            length += SPLUNK_CRED_LEN_LIMIT
    +
    +            stanza_name = self._sep.join((name, str(i)))
    +            self._do_update(stanza_name, curr_str)
    +            i += 1
    +
    +    def _do_update(self, name, password):
    +        try:
    +            self._create(name, password)
    +        except CredException:
    +            payload = {"password": password}
    +            endpoint = self._get_endpoint(name)
    +            response = rest.splunkd_request(
    +                endpoint, self._session_key, method="POST", data=payload
    +            )
    +            if not response or response.status_code not in (200, 201):
    +                raise CredException(
    +                    "Unable to update password for username={}, status={}".format(
    +                        name, response.status_code
    +                    )
    +                )
    +
    +    def _create(self, name, str_to_encrypt):
    +        """
    +        Create a new stored credential.
    +        :return: raise on failure
    +        """
    +
    +        payload = {
    +            "name": name,
    +            "password": str_to_encrypt,
    +            "realm": self._realm,
    +        }
    +
    +        endpoint = self._get_endpoint(name)
    +        resp = rest.splunkd_request(
    +            endpoint, self._session_key, method="POST", data=payload
    +        )
    +        if not resp or resp.status_code not in (200, 201):
    +            raise CredException("Failed to encrypt username {}".format(name))
    +
    +    def delete(self, name, throw=False):
    +        """
    +        Delete the encrypted entry
    +        """
    +
    +        try:
    +            self._delete(name, throw=True)
    +        except CredNotFound:
    +            # try to delete the split stanzas
    +            try:
    +                stanzas = self._get_all_passwords()
    +            except Exception:
    +                raise
    +
    +            prefix = self._realm + ":" + name + self._sep
    +            for stanza in stanzas:
    +                stanza_name = stanza.get("name")
    +                match = True
    +                try:
    +                    if stanza_name[: len(prefix)] != prefix:
    +                        match = False
    +                    num = stanza_name[len(prefix) : -1]
    +                    int(num)
    +                except (IndexError, ValueError):
    +                    match = False
    +                if match:
    +                    try:
    +                        delete_name = name + self._sep + num
    +                        self._delete(delete_name, throw=True)
    +                    except CredNotFound:
    +                        pass
    +                    except CredException:
    +                        raise
    +        except CredException:
    +            raise
    +
    +    def _delete(self, name, throw=False):
    +        """
    +        Delete the encrypted entry
    +        """
    +
    +        endpoint = self._get_endpoint(name)
    +        response = rest.splunkd_request(endpoint, self._session_key, method="DELETE")
    +
    +        if response is not None and response.status_code == 404:
    +            if throw:
    +                raise CredNotFound("Credential stanza not exits - {}".format(name))
    +        elif not response or response.status_code not in (200, 201):
    +            if throw:
    +                raise CredException(
    +                    "Failed to delete credential stanza {}".format(name)
    +                )
    +
    +    def get_all_passwords(self):
    +        results = {}
    +        all_stanzas = self._get_all_passwords()
    +        for stanza in all_stanzas:
    +            name = stanza.get("name")
    +            match = re.match(r"(.+){}(\d+)".format(self._sep), name)
    +            if match:
    +                actual_name = match.group(1) + ":"
    +                index = int(match.group(2))
    +                if results.get(actual_name):
    +                    exist_stanza = results.get(actual_name)
    +                else:
    +                    exist_stanza = stanza
    +                    exist_stanza["name"] = actual_name
    +                    exist_stanza["username"] = exist_stanza["username"].split(
    +                        self._sep
    +                    )[0]
    +                    exist_stanza["clears"] = {}
    +                    exist_stanza["encrs"] = {}
    +
    +                try:
    +                    exist_stanza["clears"][index] = stanza.get("clear_password")
    +                    exist_stanza["encrs"][index] = stanza.get("encr_password")
    +                except KeyError:
    +                    exist_stanza["clears"] = {}
    +                    exist_stanza["encrs"] = {}
    +                    exist_stanza["clears"][index] = stanza.get("clear_password")
    +                    exist_stanza["encrs"][index] = stanza.get("encr_password")
    +
    +                results[actual_name] = exist_stanza
    +
    +            else:
    +                results[name] = stanza
    +
    +        # merge the stanzas by index
    +        for name, stanza in list(results.items()):
    +            field_clear = stanza.get("clears")
    +            field_encr = stanza.get("encrs")
    +            if isinstance(field_clear, dict):
    +                clear_password = ""
    +                encr_password = ""
    +                for index in sorted(field_clear.keys()):
    +                    clear_password += field_clear.get(index)
    +                    encr_password += field_encr.get(index)
    +                stanza["clear_password"] = clear_password
    +                stanza["encr_password"] = encr_password
    +
    +                del stanza["clears"]
    +                del stanza["encrs"]
    +        return list(results.values())
    +
    +    def _get_all_passwords(self):
    +        """
    +        :return: a list of dict when successful, None when failed.
    +        the dict at least contains
    +        {
    +            "realm": xxx,
    +            "username": yyy,
    +            "clear_password": zzz,
    +        }
    +        """
    +
    +        endpoint = self._get_endpoint()
    +        response = rest.splunkd_request(endpoint, self._session_key, method="GET")
    +        if response and response.status_code in (200, 201) and response.text:
    +            return xdp.parse_conf_xml_dom(response.text)
    +        raise CredException("Failed to get credentials")
    +
    +    def get_clear_password(self, name=None):
    +        """
    +        :return: clear password(s)
    +        {
    +        stanza_name: {"user": pass}
    +        }
    +        """
    +
    +        return self._get_credentials("clear_password", name)
    +
    +    def get_encrypted_password(self, name=None):
    +        """
    +        :return: encyrpted password(s)
    +        """
    +
    +        return self._get_credentials("encr_password", name)
    +
    +    def _get_credentials(self, prop, name=None):
    +        """
    +        :return: clear or encrypted password for specified realm, user
    +        """
    +
    +        all_stanzas = self.get_all_passwords()
    +        results = {}
    +
    +        for stanza in all_stanzas:
    +            if name and not stanza.get("name").endswith(":" + name + ":"):
    +                continue
    +            if stanza.get("realm") == self._realm:
    +                values = stanza[prop].split(self._sep)
    +                if len(values) % 2 == 1:
    +                    continue
    +                result = {values[i]: values[i + 1] for i in range(0, len(values), 2)}
    +                results[stanza.get("username")] = result
    +        return results
    +
    +    @staticmethod
    +    def _build_name(realm, name):
    +        return util.format_stanza_name(
    +            "".join(
    +                (
    +                    CredentialManager._escape_string(realm),
    +                    ":",
    +                    CredentialManager._escape_string(name),
    +                    ":",
    +                )
    +            )
    +        )
    +
    +    @staticmethod
    +    def _escape_string(string_to_escape):
    +        r"""
    +        Splunk secure credential storage actually requires a custom style of
    +        escaped string where all the :'s are escaped by a single \.
    +        But don't escape the control : in the stanza name.
    +        """
    +
    +        return string_to_escape.replace(":", "\\:")
    +
    +    def _get_endpoint(self, name=None, query=False):
    +        app = self._app
    +        owner = self._owner
    +        if query:
    +            app = "-"
    +            owner = "-"
    +
    +        if name:
    +            realm_user = self._build_name(self._realm, name)
    +            rest_endpoint = "{}/servicesNS/{}/{}/storage/passwords/{}".format(
    +                self._splunkd_uri, owner, app, realm_user
    +            )
    +        else:
    +            rest_endpoint = "{}/servicesNS/{}/{}/storage/passwords?count=-1" "".format(
    +                self._splunkd_uri, owner, app
    +            )
    +        return rest_endpoint
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/event_writer.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/event_writer.py
    new file mode 100644
    index 0000000..fad5fcc
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/event_writer.py
    @@ -0,0 +1,166 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 multiprocessing
    +import queue
    +import sys
    +import threading
    +import warnings
    +from collections import Iterable
    +
    +from splunktalib.common import log
    +
    +
    +class EventWriter:
    +    def __init__(self, process_safe=False):
    +        warnings.warn(
    +            "This class is deprecated. "
    +            "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +            DeprecationWarning,
    +            stacklevel=2,
    +        )
    +        if process_safe:
    +            self._mgr = multiprocessing.Manager()
    +            self._event_queue = self._mgr.Queue(1000)
    +        else:
    +            self._event_queue = queue.Queue(1000)
    +        self._event_writer = threading.Thread(target=self._do_write_events)
    +        self._event_writer.daemon = True
    +        self._started = False
    +        self._exception = False
    +
    +    def start(self):
    +        if self._started:
    +            return
    +        self._started = True
    +
    +        self._event_writer.start()
    +        log.logger.info("Event writer started.")
    +
    +    def tear_down(self):
    +        if not self._started:
    +            return
    +        self._started = False
    +
    +        self._event_queue.put(None)
    +        self._event_writer.join()
    +        log.logger.info("Event writer stopped.")
    +
    +    def isopen(self):
    +        return self._started and (not self._exception)
    +
    +    def write_events(self, events):
    +        if not self.isopen():
    +            return False
    +        if events is None:
    +            return True
    +        self._event_queue.put(events)
    +        return True
    +
    +    def _do_write_events(self):
    +        event_queue = self._event_queue
    +        write = sys.stdout.write
    +        got_shutdown_signal = False
    +
    +        while 1:
    +            try:
    +                event = event_queue.get(timeout=3)
    +                if event is not None:
    +                    if isinstance(event, str):
    +                        write(event.encode("utf-8"))
    +                    elif isinstance(event, Iterable):
    +                        for evt in event:
    +                            write(evt.encode("utf-8"))
    +                else:
    +                    log.logger.info("Event writer got tear down signal")
    +                    got_shutdown_signal = True
    +            except queue.Empty:
    +                # We need drain the queue before shutdown
    +                # timeout means empty for now
    +                if got_shutdown_signal:
    +                    log.logger.info("Event writer is going to exit...")
    +                    break
    +                else:
    +                    continue
    +            except Exception:
    +                log.logger.exception(
    +                    "EventWriter encounter exception which may"
    +                    "cause data loss, queue leftsize={"
    +                    "}".format(event_queue.qsize())
    +                )
    +                self._exception = True
    +                break
    +
    +        log.logger.info(
    +            "Event writer stopped, queue leftsize={}".format(event_queue.qsize())
    +        )
    +
    +
    +class EventWriterWithCheckpoint(EventWriter):
    +    def _do_write_events(self):
    +        event_queue = self._event_queue
    +        write = sys.stdout.write
    +        got_shutdown_signal = False
    +
    +        while 1:
    +            try:
    +                event = event_queue.get(timeout=3)
    +                if event is not None:
    +                    # event is a tuple which consists of events and checkpoint
    +                    # information: (events, checkpoint_tuple)
    +                    # checkpoint_tuple includes the checkpoint manager obj, key
    +                    # and value of checkpoint: (ckpt_mgr_obj, key, state)
    +                    events = event[0]
    +                    ckpt_tuple = event[1]
    +                    if isinstance(events, str):
    +                        write(events.encode("utf-8"))
    +                    elif isinstance(events, Iterable):
    +                        for evt in events:
    +                            write(evt.encode("utf-8"))
    +
    +                    # Update checkpoint after events are sent to stdout to avoid
    +                    # data loss.
    +                    if ckpt_tuple and ckpt_tuple[2]:
    +                        ckpt_tuple[0].update_state(ckpt_tuple[1], ckpt_tuple[2])
    +
    +                    # Close the checkpoint obj to flush the data in cache to
    +                    # disk to aviod data duplication if it is teared down
    +                    if not self._started:
    +                        ckpt_tuple[0].close()
    +                else:
    +                    log.logger.info("Event writer got tear down signal")
    +                    got_shutdown_signal = True
    +
    +            except queue.Empty:
    +                # We need drain the queue before shutdown
    +                # timeout means empty for now
    +                if got_shutdown_signal:
    +                    log.logger.info("Event writer is going to exit...")
    +                    break
    +                else:
    +                    continue
    +            except Exception:
    +                log.logger.exception(
    +                    "EventWriter encounter exception which may"
    +                    "cause data loss, queue leftsize={"
    +                    "}".format(event_queue.qsize())
    +                )
    +                self._exception = True
    +                break
    +
    +        log.logger.info(
    +            "Event writer stopped, queue leftsize={}".format(event_queue.qsize())
    +        )
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/file_monitor.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/file_monitor.py
    new file mode 100644
    index 0000000..ed04c14
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/file_monitor.py
    @@ -0,0 +1,77 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 os.path as op
    +import traceback
    +import warnings
    +
    +from splunktalib.common import log
    +
    +
    +class FileMonitor:
    +    def __init__(self, callback, files):
    +        """
    +        :files: files to be monidtored with full path
    +        """
    +        warnings.warn(
    +            "This class is deprecated. "
    +            "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +            DeprecationWarning,
    +            stacklevel=2,
    +        )
    +
    +        self._callback = callback
    +        self._files = files
    +
    +        self.file_mtimes = {file_name: None for file_name in self._files}
    +        for k in self.file_mtimes:
    +            if not op.exists(k):
    +                continue
    +
    +            try:
    +                if not op.exists(k):
    +                    continue
    +                self.file_mtimes[k] = op.getmtime(k)
    +            except OSError:
    +                log.logger.error(
    +                    "Getmtime for %s, failed: %s", k, traceback.format_exc()
    +                )
    +
    +    def __call__(self):
    +        return self.check_changes()
    +
    +    def check_changes(self):
    +        log.logger.debug("Checking files=%s", self._files)
    +        file_mtimes = self.file_mtimes
    +        changed_files = []
    +        for f, last_mtime in file_mtimes.items():
    +            try:
    +                if not op.exists(f):
    +                    continue
    +
    +                current_mtime = op.getmtime(f)
    +                if current_mtime != last_mtime:
    +                    file_mtimes[f] = current_mtime
    +                    changed_files.append(f)
    +                    log.logger.info("Detect %s has changed", f)
    +            except OSError:
    +                pass
    +
    +        if changed_files:
    +            if self._callback:
    +                self._callback(changed_files)
    +            return True
    +        return False
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/kv_client.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/kv_client.py
    new file mode 100644
    index 0000000..806f03c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/kv_client.py
    @@ -0,0 +1,227 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 json
    +import re
    +import warnings
    +
    +from defusedxml import ElementTree as et
    +
    +import splunktalib.rest as rest
    +
    +
    +class KVException(Exception):
    +    pass
    +
    +
    +class KVAlreadyExists(KVException):
    +    pass
    +
    +
    +class KVNotExists(KVException):
    +    pass
    +
    +
    +class KVClient:
    +    def __init__(self, splunkd_host, session_key):
    +        warnings.warn(
    +            "This class is deprecated. "
    +            "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +            DeprecationWarning,
    +            stacklevel=2,
    +        )
    +        self._splunkd_host = splunkd_host
    +        self._session_key = session_key
    +
    +    def create_collection(self, collection, app, owner="nobody"):
    +        """
    +        :collection: collection name
    +        :return: None if successful otherwise KV exception thrown
    +        """
    +
    +        assert collection
    +        assert app
    +
    +        uri = self._get_config_endpoint(app, owner)
    +        data = {"name": collection}
    +        self._do_request(uri, "POST", data)
    +
    +    def list_collection(self, collection=None, app=None, owner="nobody"):
    +        """
    +        :collection: collection name. When euqals "None", return all
    +        collections in the system.
    +        :return: a list containing the connection names if successful, throws
    +        KVNotExists if no such colection or other exception if other error
    +        happened
    +        """
    +
    +        uri = self._get_config_endpoint(app, owner, collection)
    +
    +        content = self._do_request(uri, method="GET")
    +        m = re.search(r'xmlns="([^"]+)"', content)
    +        path = "./entry/title"
    +        if m:
    +            ns = m.group(1)
    +            path = "./{{{}}}entry/{{{}}}title".format(ns, ns)
    +
    +        collections = et.fromstring(content)
    +        return [node.text for node in collections.iterfind(path)]
    +
    +    def delete_collection(self, collection, app, owner="nobody"):
    +        """
    +        :collection: collection name to be deleted
    +        :return: None if successful otherwise throw KVNotExists exception if
    +        the collection doesn't exist in the system or other exception if other
    +        error happened
    +        """
    +
    +        assert collection
    +
    +        uri = self._get_config_endpoint(app, owner, collection)
    +        self._do_request(uri, method="DELETE")
    +
    +    def insert_collection_data(self, collection, data, app, owner="nobody"):
    +        """
    +        :collection: collection name
    +        :data: dict like key values to be inserted and attached to
    +        this collection
    +        :return: {"_key": "key_id"} when successful, clients can use this
    +        key to do query/delete/update, throws KV exceptions when failed
    +        """
    +
    +        assert collection
    +        assert data is not None
    +        assert app
    +
    +        uri = self._get_data_endpoint(app, owner, collection)
    +        key = self._do_request(uri, "POST", data, content_type="application/json")
    +        return json.loads(key)
    +
    +    def delete_collection_data(self, collection, key_id, app, owner="nobody"):
    +        """
    +        :collection: collection name
    +        :key_id: key id returned when creation. If None, delete all data
    +        associated with this collection
    +        :return: None if successful otherwise throws KV exception
    +        """
    +
    +        assert collection
    +
    +        uri = self._get_data_endpoint(app, owner, collection, key_id)
    +        self._do_request(uri, "DELETE", content_type="application/json")
    +
    +    def update_collection_data(self, collection, key_id, data, app, owner="nobody"):
    +        """
    +        :collection: collection name
    +        :key_id: key id returned when creation
    +        :return: key id if successful otherwise throws KV exception
    +        """
    +
    +        assert collection
    +        assert key_id
    +        assert app
    +
    +        uri = self._get_data_endpoint(app, owner, collection, key_id)
    +        k = self._do_request(uri, "POST", data, content_type="application/json")
    +        return json.loads(k)
    +
    +    def get_collection_data(self, collection, key_id, app, owner="nobody"):
    +        """
    +        :collection: collection name
    +        :key_id: key id returned when creation. If None, get all data
    +        associated with this collection
    +        :return: when key_id is not None, return key values if
    +        successful. when key_id is None, return a list of key values if
    +        sucessful. Throws KV exception if failure
    +        """
    +
    +        assert collection
    +
    +        uri = self._get_data_endpoint(app, owner, collection, key_id)
    +        k = self._do_request(uri, "GET")
    +        return json.loads(k)
    +
    +    def _do_request(
    +        self, uri, method, data=None, content_type="application/x-www-form-urlencoded"
    +    ):
    +        headers = {"Content-Type": content_type}
    +
    +        resp = rest.splunkd_request(uri, self._session_key, method, headers, data)
    +        if resp is None:
    +            raise KVException("Failed uri={}, data={}".format(uri, data))
    +
    +        if resp.status_code in (200, 201):
    +            return resp.text
    +        elif resp.status_code == 409:
    +            raise KVAlreadyExists("{}-{} already exists".format(uri, data))
    +        elif resp.status_code == 404:
    +            raise KVNotExists("{}-{} not exists".format(uri, data))
    +        else:
    +            raise KVException(
    +                "Failed to {} {}, reason={}".format(method, uri, resp.reason)
    +            )
    +
    +    def _get_config_endpoint(self, app, owner, collection=None):
    +        uri = "{0}/servicesNS/{1}/{2}/storage/collections/config"
    +        return self._do_get_endpoint(app, owner, collection, None, uri)
    +
    +    def _get_data_endpoint(self, app, owner, collection, key_id=None):
    +        uri = "{0}/servicesNS/{1}/{2}/storage/collections/data"
    +        return self._do_get_endpoint(app, owner, collection, key_id, uri)
    +
    +    def _do_get_endpoint(self, app, owner, collection, key_id, uri_template):
    +        if not app:
    +            app = "-"
    +
    +        if not owner:
    +            owner = "-"
    +
    +        uri = uri_template.format(self._splunkd_host, owner, app)
    +
    +        if collection is not None:
    +            uri += "/{}".format(collection)
    +            if key_id is not None:
    +                uri += "/{}".format(key_id)
    +        return uri
    +
    +
    +def create_collection(kv_client, collection, appname):
    +    warnings.warn(
    +        "This function is deprecated. "
    +        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +        DeprecationWarning,
    +        stacklevel=2,
    +    )
    +    not_exists = False
    +    try:
    +        res = kv_client.list_collection(collection, appname)
    +    except KVNotExists:
    +        not_exists = True
    +    except Exception:
    +        not_exists = True
    +
    +    if not_exists or not res:
    +        for i in range(3):
    +            try:
    +                kv_client.create_collection(collection, appname)
    +            except KVAlreadyExists:
    +                return
    +            except Exception as e:
    +                ex = e
    +            else:
    +                return
    +        else:
    +            raise ex
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/modinput.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/modinput.py
    new file mode 100644
    index 0000000..625bdc7
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/modinput.py
    @@ -0,0 +1,164 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 subprocess
    +import sys
    +import traceback
    +
    +import splunktalib.splunk_platform as sp
    +from splunktalib.common import log
    +
    +
    +def _parse_modinput_configs(root, outer_block, inner_block):
    +    """
    +    When user splunkd spawns modinput script to do config check or run
    +
    +    <?xml version="1.0" encoding="UTF-8"?>
    +    <input>
    +      <server_host>localhost.localdomain</server_host>
    +      <server_uri>https://127.0.0.1:8089</server_uri>
    +      <session_key>xxxyyyzzz</session_key>
    +      <checkpoint_dir>ckpt_dir</checkpoint_dir>
    +      <configuration>
    +        <stanza name="snow://alm_asset">
    +          <param name="duration">60</param>
    +            <param name="host">localhost.localdomain</param>
    +            <param name="index">snow</param>
    +            <param name="priority">10</param>
    +        </stanza>
    +        ...
    +      </configuration>
    +    </input>
    +
    +    When user create an stanza through data input on WebUI
    +
    +    <?xml version="1.0" encoding="UTF-8"?>
    +    <items>
    +      <server_host>localhost.localdomain</server_host>
    +      <server_uri>https://127.0.0.1:8089</server_uri>
    +      <session_key>xxxyyyzzz</session_key>
    +      <checkpoint_dir>ckpt_dir</checkpoint_dir>
    +      <item name="abc">
    +        <param name="duration">60</param>
    +        <param name="exclude"></param>
    +        <param name="host">localhost.localdomain</param>
    +        <param name="index">snow</param>
    +        <param name="priority">10</param>
    +      </item>
    +    </items>
    +    """
    +
    +    confs = root.getElementsByTagName(outer_block)
    +    if not confs:
    +        log.logger.error("Invalid config, missing %s section", outer_block)
    +        raise Exception(f"Invalid config, missing {outer_block} section")
    +
    +    configs = []
    +    stanzas = confs[0].getElementsByTagName(inner_block)
    +    for stanza in stanzas:
    +        config = {}
    +        stanza_name = stanza.getAttribute("name")
    +        if not stanza_name:
    +            log.logger.error("Invalid config, missing name")
    +            raise Exception("Invalid config, missing name")
    +
    +        config["name"] = stanza_name
    +        params = stanza.getElementsByTagName("param")
    +        for param in params:
    +            name = param.getAttribute("name")
    +            if (
    +                name
    +                and param.firstChild
    +                and param.firstChild.nodeType == param.firstChild.TEXT_NODE
    +            ):
    +                config[name] = param.firstChild.data
    +        configs.append(config)
    +    return configs
    +
    +
    +def parse_modinput_configs(config_str):
    +    """
    +    @config_str: modinput XML configuration feed by splunkd
    +    @return: meta_config and stanza_config
    +    """
    +
    +    import defusedxml.minidom as xdm
    +
    +    meta_configs = {
    +        "server_host": None,
    +        "server_uri": None,
    +        "session_key": None,
    +        "checkpoint_dir": None,
    +    }
    +    root = xdm.parseString(config_str)
    +    doc = root.documentElement
    +    for tag in meta_configs.keys():
    +        nodes = doc.getElementsByTagName(tag)
    +        if not nodes:
    +            log.logger.error("Invalid config, missing %s section", tag)
    +            raise Exception("Invalid config, missing %s section", tag)
    +
    +        if nodes[0].firstChild and nodes[0].firstChild.nodeType == nodes[0].TEXT_NODE:
    +            meta_configs[tag] = nodes[0].firstChild.data
    +        else:
    +            log.logger.error("Invalid config, expect text ndoe")
    +            raise Exception("Invalid config, expect text ndoe")
    +
    +    if doc.nodeName == "input":
    +        configs = _parse_modinput_configs(doc, "configuration", "stanza")
    +    else:
    +        configs = _parse_modinput_configs(root, "items", "item")
    +    return meta_configs, configs
    +
    +
    +def get_modinput_configs_from_cli(modinput, modinput_stanza=None):
    +    """
    +    @modinput: modinput name
    +    @modinput_stanza: modinput stanza name, for multiple instance only
    +    """
    +
    +    assert modinput
    +
    +    splunkbin = sp.get_splunk_bin()
    +    cli = [splunkbin, "cmd", "splunkd", "print-modinput-config", modinput]
    +    if modinput_stanza:
    +        cli.append(modinput_stanza)
    +
    +    out, err = subprocess.Popen(
    +        cli, stdout=subprocess.PIPE, stderr=subprocess.PIPE
    +    ).communicate()
    +    if err:
    +        log.logger.error("Failed to get modinput configs with error: %s", err)
    +        return None, None
    +    else:
    +        return parse_modinput_configs(out)
    +
    +
    +def get_modinput_config_str_from_stdin():
    +    """
    +    Get modinput from stdin which is feed by splunkd
    +    """
    +
    +    try:
    +        return sys.stdin.read(5000)
    +    except Exception:
    +        log.logger.error(traceback.format_exc())
    +        raise
    +
    +
    +def get_modinput_configs_from_stdin():
    +    config_str = get_modinput_config_str_from_stdin()
    +    return parse_modinput_configs(config_str)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/orphan_process_monitor.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/orphan_process_monitor.py
    new file mode 100644
    index 0000000..fe93f7d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/orphan_process_monitor.py
    @@ -0,0 +1,90 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 os
    +import threading
    +import time
    +import traceback
    +import warnings
    +
    +from splunktalib.common import log
    +
    +
    +class OrphanProcessChecker:
    +    def __init__(self, callback=None):
    +        """
    +        Only work for Linux platform. On Windows platform, is_orphan is always
    +        False
    +        """
    +
    +        if os.name == "nt":
    +            self._ppid = 0
    +        else:
    +            self._ppid = os.getppid()
    +        self._callback = callback
    +
    +    def is_orphan(self):
    +        if os.name == "nt":
    +            return False
    +        res = self._ppid != os.getppid()
    +        if res:
    +            log.logger.warn("Process=%s has become orphan", os.getpid())
    +        return res
    +
    +    def check_orphan(self):
    +        res = self.is_orphan()
    +        if res and self._callback:
    +            self._callback()
    +        return res
    +
    +
    +class OrphanProcessMonitor:
    +    def __init__(self, callback):
    +        warnings.warn(
    +            "splunktalib's OrphanProcessMonitor is going to be deprecated and "
    +            "removed. Please switch to solnlib's "
    +            "(https://github.com/splunk/addonfactory-solutions-library-python) "
    +            "version of OrphanProcessMonitor located in orphan_process_monitor.py.",
    +            DeprecationWarning,
    +            stacklevel=2,
    +        )
    +        self._checker = OrphanProcessChecker(callback)
    +        self._thr = threading.Thread(target=self._do_monitor)
    +        self._thr.daemon = True
    +        self._started = False
    +
    +    def start(self):
    +        if self._started:
    +            return
    +        self._started = True
    +
    +        self._thr.start()
    +
    +    def stop(self):
    +        self._started = False
    +
    +    def _do_monitor(self):
    +        while self._started:
    +            try:
    +                res = self._checker.check_orphan()
    +                if res:
    +                    break
    +                time.sleep(1)
    +            except Exception:
    +                log.logger.error(
    +                    "Failed to monitor orphan process, reason=%s",
    +                    traceback.format_exc(),
    +                )
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/rest.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/rest.py
    new file mode 100644
    index 0000000..982862a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/rest.py
    @@ -0,0 +1,95 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 json
    +import urllib.parse
    +from traceback import format_exc
    +from typing import Optional
    +
    +import requests
    +
    +import splunktalib.common.log as log
    +
    +
    +def splunkd_request(
    +    splunkd_uri,
    +    session_key,
    +    method="GET",
    +    headers=None,
    +    data=None,
    +    timeout=300,
    +    retry=1,
    +    verify=False,
    +) -> Optional[requests.Response]:
    +
    +    headers = headers if headers is not None else {}
    +    headers["Authorization"] = "Splunk {}".format(session_key)
    +    content_type = headers.get("Content-Type")
    +    if not content_type:
    +        content_type = headers.get("content-type")
    +
    +    if not content_type:
    +        content_type = "application/x-www-form-urlencoded"
    +        headers["Content-Type"] = content_type
    +
    +    if data is not None:
    +        if content_type == "application/json":
    +            data = json.dumps(data)
    +        else:
    +            data = urllib.parse.urlencode(data)
    +
    +    msg_temp = "Failed to send rest request=%s, errcode=%s, reason=%s"
    +    resp = None
    +    for _ in range(retry):
    +        try:
    +            resp = requests.request(
    +                method=method,
    +                url=splunkd_uri,
    +                data=data,
    +                headers=headers,
    +                timeout=timeout,
    +                verify=verify,
    +            )
    +        except Exception:
    +            log.logger.error(msg_temp, splunkd_uri, "unknown", format_exc())
    +        else:
    +            if resp.status_code not in (200, 201):
    +                if not (method == "GET" and resp.status_code == 404):
    +                    log.logger.debug(
    +                        msg_temp, splunkd_uri, resp.status_code, code_to_msg(resp)
    +                    )
    +            else:
    +                return resp
    +    else:
    +        return resp
    +
    +
    +def code_to_msg(response: requests.Response):
    +    code_msg_tbl = {
    +        400: "Request error. reason={}".format(response.text),
    +        401: "Authentication failure, invalid access credentials.",
    +        402: "In-use license disables this feature.",
    +        403: "Insufficient permission.",
    +        404: "Requested endpoint does not exist.",
    +        409: "Invalid operation for this endpoint. reason={}".format(response.text),
    +        500: "Unspecified internal server error. reason={}".format(response.text),
    +        503: (
    +            "Feature is disabled in the configuration file. "
    +            "reason={}".format(response.text)
    +        ),
    +    }
    +
    +    return code_msg_tbl.get(response.status_code, response.text)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/schedule/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/schedule/__init__.py
    new file mode 100644
    index 0000000..72d4509
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/schedule/__init__.py
    @@ -0,0 +1,15 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/schedule/job.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/schedule/job.py
    new file mode 100644
    index 0000000..de7e939
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/schedule/job.py
    @@ -0,0 +1,124 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 threading
    +import time
    +
    +
    +class Job:
    +    """
    +    Timer wraps the callback and timestamp related stuff
    +    """
    +
    +    _ident = 0
    +    _lock = threading.Lock()
    +
    +    def __init__(self, func, job_props, interval, when=None, job_id=None):
    +        """
    +        @job_props: dict like object
    +        @func: execution function
    +        @interval: execution interval
    +        @when: seconds from epoch
    +        @job_id: a unique id for the job
    +        """
    +
    +        self._props = job_props
    +        self._func = func
    +        if when is None:
    +            self._when = time.time()
    +        else:
    +            self._when = when
    +        self._interval = interval
    +
    +        if job_id is not None:
    +            self._id = job_id
    +        else:
    +            with Job._lock:
    +                self._id = Job._ident + 1
    +                Job._ident = Job._ident + 1
    +        self._stopped = False
    +
    +    def ident(self):
    +        return self._id
    +
    +    def get_interval(self):
    +        return self._interval
    +
    +    def set_interval(self, interval):
    +        self._interval = interval
    +
    +    def get_expiration(self):
    +        return self._when
    +
    +    def set_initial_due_time(self, when):
    +        if self._when is None:
    +            self._when = when
    +
    +    def update_expiration(self):
    +        self._when += self._interval
    +
    +    def get(self, key, default):
    +        return self._props.get(key, default)
    +
    +    def get_props(self):
    +        return self._props
    +
    +    def set_props(self, props):
    +        self._props = props
    +
    +    def __cmp__(self, other):
    +        if other is None:
    +            return 1
    +
    +        self_k = (self.get_expiration(), self.ident())
    +        other_k = (other.get_expiration(), other.ident())
    +
    +        if self_k == other_k:
    +            return 0
    +        elif self_k < other_k:
    +            return -1
    +        else:
    +            return 1
    +
    +    def __eq__(self, other):
    +        return isinstance(other, Job) and (self.ident() == other.ident())
    +
    +    def __lt__(self, other):
    +        return self.__cmp__(other) == -1
    +
    +    def __gt__(self, other):
    +        return self.__cmp__(other) == 1
    +
    +    def __ne__(self, other):
    +        return not self.__eq__(other)
    +
    +    def __le__(self, other):
    +        return self.__lt__(other) or self.__eq__(other)
    +
    +    def __ge__(self, other):
    +        return self.__gt__(other) or self.__eq__(other)
    +
    +    def __hash__(self):
    +        return self.ident()
    +
    +    def __call__(self):
    +        self._func(self)
    +
    +    def stop(self):
    +        self._stopped = True
    +
    +    def stopped(self):
    +        return self._stopped
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/schedule/scheduler.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/schedule/scheduler.py
    new file mode 100644
    index 0000000..a03a7cc
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/schedule/scheduler.py
    @@ -0,0 +1,163 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 queue
    +import random
    +import threading
    +from time import time
    +
    +from splunktalib.common import log
    +
    +
    +class Scheduler:
    +    """
    +    A simple scheduler which schedules the periodic or once event
    +    """
    +
    +    import sortedcontainers as sc
    +
    +    max_delay_time = 60
    +
    +    def __init__(self):
    +        self._jobs = Scheduler.sc.SortedSet()
    +        self._wakeup_q = queue.Queue()
    +        self._lock = threading.Lock()
    +        self._thr = threading.Thread(target=self._do_jobs)
    +        self._thr.deamon = True
    +        self._started = False
    +
    +    def start(self):
    +        """
    +        Start the schduler which will start the internal thread for scheduling
    +        jobs. Please do tear_down when doing cleanup
    +        """
    +
    +        if self._started:
    +            log.logger.info("Scheduler already started.")
    +            return
    +        self._started = True
    +
    +        self._thr.start()
    +
    +    def tear_down(self):
    +        """
    +        Stop the schduler which will stop the internal thread for scheduling
    +        jobs.
    +        """
    +
    +        if not self._started:
    +            log.logger.info("Scheduler already tear down.")
    +            return
    +
    +        self._wakeup_q.put(True)
    +
    +    def _do_jobs(self):
    +        while 1:
    +            (sleep_time, jobs) = self.get_ready_jobs()
    +            self._do_execution(jobs)
    +            try:
    +                done = self._wakeup_q.get(timeout=sleep_time)
    +            except queue.Empty:
    +                pass
    +            else:
    +                if done:
    +                    break
    +        self._started = False
    +        log.logger.info("Scheduler exited.")
    +
    +    def get_ready_jobs(self):
    +        """
    +        @return: a 2 element tuple. The first element is the next ready
    +                 duration. The second element is ready jobs list
    +        """
    +
    +        now = time()
    +        ready_jobs = []
    +        sleep_time = 1
    +
    +        with self._lock:
    +            job_set = self._jobs
    +            total_jobs = len(job_set)
    +            for job in job_set:
    +                if job.get_expiration() <= now:
    +                    ready_jobs.append(job)
    +
    +            if ready_jobs:
    +                del job_set[: len(ready_jobs)]
    +
    +            for job in ready_jobs:
    +                if job.get_interval() != 0 and not job.stopped():
    +                    # repeated job, calculate next due time and enqueue
    +                    job.update_expiration()
    +                    job_set.add(job)
    +
    +            if job_set:
    +                sleep_time = job_set[0].get_expiration() - now
    +                if sleep_time < 0:
    +                    log.logger.warn("Scheduler satuation, sleep_time=%s", sleep_time)
    +                    sleep_time = 0.1
    +
    +        if ready_jobs:
    +            log.logger.info(
    +                "Get %d ready jobs, next duration is %f, "
    +                "and there are %s jobs scheduling",
    +                len(ready_jobs),
    +                sleep_time,
    +                total_jobs,
    +            )
    +
    +        ready_jobs.sort(key=lambda job: job.get("priority", 0), reverse=True)
    +        return (sleep_time, ready_jobs)
    +
    +    def add_jobs(self, jobs):
    +        with self._lock:
    +            now = time()
    +            job_set = self._jobs
    +            for job in jobs:
    +                delay_time = random.randrange(0, self.max_delay_time)
    +                job.set_initial_due_time(now + delay_time)
    +                job_set.add(job)
    +        self._wakeup()
    +
    +    def update_jobs(self, jobs):
    +        with self._lock:
    +            job_set = self._jobs
    +            for njob in jobs:
    +                job_set.discard(njob)
    +                job_set.add(njob)
    +        self._wakeup()
    +
    +    def remove_jobs(self, jobs):
    +        with self._lock:
    +            job_set = self._jobs
    +            for njob in jobs:
    +                njob.stop()
    +                job_set.discard(njob)
    +        self._wakeup()
    +
    +    def number_of_jobs(self):
    +        with self._lock:
    +            return len(self._jobs)
    +
    +    def disable_randomization(self):
    +        self.max_delay_time = 1
    +
    +    def _wakeup(self):
    +        self._wakeup_q.put(None)
    +
    +    def _do_execution(self, jobs):
    +        for job in jobs:
    +            job()
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/setting.conf b/deployment-apps/metricator-for-nmon/lib/splunktalib/setting.conf
    new file mode 100644
    index 0000000..87497cc
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/setting.conf
    @@ -0,0 +1,21 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +[global]
    +process_size = 0
    +thread_min_size = 4
    +thread_max_size = 128
    +task_queue_size = 1024
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/splunk_cluster.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/splunk_cluster.py
    new file mode 100644
    index 0000000..73e8aea
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/splunk_cluster.py
    @@ -0,0 +1,77 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 warnings
    +
    +import splunktalib.common.xml_dom_parser as xdp
    +import splunktalib.rest as rest
    +
    +
    +def _do_rest(uri, session_key):
    +    resp = rest.splunkd_request(uri, session_key)
    +    if resp is None:
    +        return None
    +
    +    if resp.status_code not in (200, 201):
    +        return None
    +
    +    stanza_objs = xdp.parse_conf_xml_dom(resp.text)
    +    if not stanza_objs:
    +        return None
    +
    +    return stanza_objs[0]
    +
    +
    +class ServerInfo:
    +    def __init__(self, splunkd_uri, session_key):
    +        warnings.warn(
    +            "splunktalib's ServerInfo is going to be deprecated and removed. "
    +            "Please switch to solnlib's "
    +            "(https://github.com/splunk/addonfactory-solutions-library-python) "
    +            "version of ServerInfo located in server_info.py.",
    +            DeprecationWarning,
    +            stacklevel=2,
    +        )
    +        uri = "{}/services/server/info".format(splunkd_uri)
    +        server_info = _do_rest(uri, session_key)
    +        if server_info is None:
    +            raise Exception("Failed to init ServerInfo")
    +
    +        self._server_info = server_info
    +
    +    def is_captain(self):
    +        """
    +        :return: True if splunkd_uri is captain otherwise False
    +        """
    +
    +        return "shc_captain" in self._server_info["server_roles"]
    +
    +    def is_search_head(self):
    +        for sh in ("search_head", "cluster_search_head"):
    +            if sh in self._server_info["server_roles"]:
    +                return True
    +        return False
    +
    +    def is_shc_member(self):
    +        for sh in ("shc_member", "shc_captain"):
    +            if sh in self._server_info["server_roles"]:
    +                return True
    +        return False
    +
    +    def version(self):
    +        return self._server_info["version"]
    +
    +    def to_dict(self):
    +        return self._server_info
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/splunk_platform.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/splunk_platform.py
    new file mode 100644
    index 0000000..1a151df
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/splunk_platform.py
    @@ -0,0 +1,63 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 os
    +import warnings
    +
    +from splunktalib.common import util as scu
    +
    +
    +def make_splunkhome_path(parts):
    +    """
    +    create a path string by the several parts of the path
    +    """
    +    warnings.warn(
    +        "This function is deprecated. "
    +        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +        DeprecationWarning,
    +        stacklevel=2,
    +    )
    +    relpath = os.path.normpath(os.path.join(*parts))
    +
    +    basepath = os.environ["SPLUNK_HOME"]  # Assume SPLUNK_HOME env has been set
    +
    +    fullpath = os.path.normpath(os.path.join(basepath, relpath))
    +
    +    # Check that we haven't escaped from intended parent directories.
    +    if os.path.relpath(fullpath, basepath)[0:2] == "..":
    +        raise ValueError(
    +            'Illegal escape from parent directory "{}": {}'.format(basepath, fullpath)
    +        )
    +
    +    return fullpath
    +
    +
    +def get_splunk_bin():
    +    warnings.warn(
    +        "This function is deprecated. "
    +        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +        DeprecationWarning,
    +        stacklevel=2,
    +    )
    +    if os.name == "nt":
    +        splunk_bin = "splunk.exe"
    +    else:
    +        splunk_bin = "splunk"
    +    return make_splunkhome_path(("bin", splunk_bin))
    +
    +
    +def get_appname_from_path(absolute_path):
    +    return scu.get_appname_from_path(absolute_path)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/state_store.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/state_store.py
    new file mode 100644
    index 0000000..f6ee6bb
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/state_store.py
    @@ -0,0 +1,280 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 json
    +import os
    +import os.path as op
    +import threading
    +import time
    +
    +import splunktalib.kv_client as kvc
    +from splunktalib.common import log, util
    +
    +
    +def get_state_store(
    +    meta_configs,
    +    appname,
    +    collection_name="talib_states",
    +    use_kv_store=False,
    +    use_cached_store=False,
    +):
    +    if util.is_true(use_kv_store):
    +        return StateStore(meta_configs, appname, collection_name)
    +    elif util.is_true(use_cached_store):
    +        return CachedFileStateStore(meta_configs, appname)
    +    else:
    +        return FileStateStore(meta_configs, appname)
    +
    +
    +class BaseStateStore:
    +    def __init__(self, meta_configs, appname):
    +        self._meta_configs = meta_configs
    +        self._appname = appname
    +
    +    def update_state(self, key, states):
    +        pass
    +
    +    def get_state(self, key):
    +        pass
    +
    +    def delete_state(self, key):
    +        pass
    +
    +    def close(self, key=None):
    +        pass
    +
    +
    +class StateStore(BaseStateStore):
    +    def __init__(self, meta_configs, appname, collection_name="talib_states"):
    +        """
    +        :meta_configs: dict like and contains checkpoint_dir, session_key,
    +         server_uri etc
    +        :app_name: the name of the app
    +        :collection_name: the collection name to be used.
    +        Don"t use other method to visit the collection if you are using
    +         StateStore to visit it.
    +        """
    +        super().__init__(meta_configs, appname)
    +
    +        # State cache is a dict from _key to value
    +        self._states_cache = {}
    +        self._kv_client = None
    +        self._collection = collection_name
    +        self._kv_client = kvc.KVClient(
    +            meta_configs["server_uri"], meta_configs["session_key"]
    +        )
    +        kvc.create_collection(self._kv_client, self._collection, self._appname)
    +        self._load_states_cache()
    +
    +    def update_state(self, key, states):
    +        """
    +        :state: Any JSON serializable
    +        :return: None if successful, otherwise throws exception
    +        """
    +
    +        if key not in self._states_cache:
    +            self._kv_client.insert_collection_data(
    +                self._collection,
    +                {"_key": key, "value": json.dumps(states)},
    +                self._appname,
    +            )
    +        else:
    +            self._kv_client.update_collection_data(
    +                self._collection, key, {"value": json.dumps(states)}, self._appname
    +            )
    +        self._states_cache[key] = states
    +
    +    def get_state(self, key=None):
    +        if key:
    +            return self._states_cache.get(key, None)
    +        return self._states_cache
    +
    +    def delete_state(self, key=None):
    +        if key:
    +            self._delete_state(key)
    +        else:
    +            [self._delete_state(_key) for _key in list(self._states_cache.keys())]
    +
    +    def _delete_state(self, key):
    +        if key not in self._states_cache:
    +            return
    +
    +        self._kv_client.delete_collection_data(self._collection, key, self._appname)
    +        del self._states_cache[key]
    +
    +    def _load_states_cache(self):
    +        states = self._kv_client.get_collection_data(
    +            self._collection, None, self._appname
    +        )
    +        if not states:
    +            return
    +
    +        for state in states:
    +            if "value" in state:
    +                value = state["value"]
    +            else:
    +                value = state
    +
    +            try:
    +                value = json.loads(value)
    +            except Exception:
    +                pass
    +
    +            self._states_cache[state["_key"]] = value
    +
    +
    +class FileStateStore(BaseStateStore):
    +    def __init__(self, meta_configs, appname):
    +        """
    +        :meta_configs: dict like and contains checkpoint_dir, session_key,
    +        server_uri etc
    +        """
    +
    +        super().__init__(meta_configs, appname)
    +
    +    def update_state(self, key, states):
    +        """
    +        :state: Any JSON serializable
    +        :return: None if successful, otherwise throws exception
    +        """
    +
    +        fname = op.join(self._meta_configs["checkpoint_dir"], key)
    +        with open(fname + ".new", "w") as jsonfile:
    +            json.dump(states, jsonfile)
    +
    +        if op.exists(fname):
    +            os.remove(fname)
    +
    +        os.rename(fname + ".new", fname)
    +        # commented this to disable state cache for local file
    +        # if key not in self._states_cache:
    +        # self._states_cache[key] = {}
    +        # self._states_cache[key] = states
    +
    +    def get_state(self, key):
    +        fname = op.join(self._meta_configs["checkpoint_dir"], key)
    +        if op.exists(fname) and op.isfile(fname):
    +            with open(fname) as jsonfile:
    +                state = json.load(jsonfile)
    +                # commented this to disable state cache for local file
    +                # self._states_cache[key] = state
    +                return state
    +        else:
    +            return None
    +
    +    def delete_state(self, key):
    +        fname = op.join(self._meta_configs["checkpoint_dir"], key)
    +        if op.exists(fname):
    +            os.remove(fname)
    +
    +
    +class CachedFileStateStore(BaseStateStore):
    +    def __init__(self, meta_configs, appname, max_cache_seconds=5):
    +        """
    +        :meta_configs: dict like and contains checkpoint_dir, session_key,
    +        server_uri etc
    +        """
    +
    +        super().__init__(meta_configs, appname)
    +        self._states_cache = {}  # item: time, dict
    +        self._states_cache_lmd = {}  # item: time, dict
    +        self.max_cache_seconds = max_cache_seconds
    +        self._lock = threading.RLock()
    +
    +    def update_state(self, key, states):
    +        with self._lock:
    +            now = time.time()
    +            if key in self._states_cache:
    +                last = self._states_cache_lmd[key][0]
    +                if now - last >= self.max_cache_seconds:
    +                    self.update_state_flush(now, key, states)
    +            else:
    +                self.update_state_flush(now, key, states)
    +            self._states_cache[key] = (now, states)
    +
    +    def update_state_flush(self, now, key, states):
    +        """
    +        :state: Any JSON serializable
    +        :return: None if successful, otherwise throws exception
    +        """
    +        for i in range(3):
    +            try:
    +                with self._lock:
    +                    self._states_cache_lmd[key] = (now, states)
    +                    fname = op.join(self._meta_configs["checkpoint_dir"], key)
    +                    with open(fname + ".new", "w") as jsonfile:
    +                        json.dump(states, jsonfile)
    +
    +                    if op.exists(fname):
    +                        os.remove(fname)
    +
    +                    os.rename(fname + ".new", fname)
    +            except Exception:
    +                log.logger.exception("Failed to update checkpoint:")
    +                time.sleep(1)
    +                continue
    +            else:
    +                return
    +        raise Exception("Failed to update checkpoint")
    +
    +    def get_state(self, key):
    +        with self._lock:
    +            if key in self._states_cache:
    +                return self._states_cache[key][1]
    +
    +            fname = op.join(self._meta_configs["checkpoint_dir"], key)
    +            if op.exists(fname):
    +                with open(fname) as jsonfile:
    +                    state = json.load(jsonfile)
    +                    now = time.time()
    +                    self._states_cache[key] = now, state
    +                    self._states_cache_lmd[key] = now, state
    +                    return state
    +            else:
    +                return None
    +
    +    def delete_state(self, key):
    +        with self._lock:
    +            fname = op.join(self._meta_configs["checkpoint_dir"], key)
    +            if op.exists(fname):
    +                os.remove(fname)
    +
    +            if self._states_cache.get(key):
    +                del self._states_cache[key]
    +            if self._states_cache_lmd.get(key):
    +                del self._states_cache_lmd[key]
    +
    +    def close(self, key=None):
    +        for i in range(3):
    +            try:
    +                with self._lock:
    +                    if not key:
    +                        for k, (t, s) in self._states_cache.items():
    +                            self.update_state_flush(t, k, s)
    +                        self._states_cache.clear()
    +                        self._states_cache_lmd.clear()
    +                    elif key in self._states_cache:
    +                        self.update_state_flush(
    +                            self._states_cache[key][0], key, self._states_cache[key][1]
    +                        )
    +                        del self._states_cache[key]
    +                        del self._states_cache_lmd[key]
    +            except Exception:
    +                log.logger.exception("Failed to close checkpoint:")
    +                time.sleep(1)
    +                continue
    +            else:
    +                return
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/timer.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/timer.py
    new file mode 100644
    index 0000000..84fbf89
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/timer.py
    @@ -0,0 +1,101 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 threading
    +import warnings
    +
    +
    +class Timer:
    +    """
    +    Timer wraps the callback and timestamp related stuff
    +    """
    +
    +    _ident = 0
    +    _lock = threading.Lock()
    +
    +    def __init__(self, callback, when, interval, ident=None):
    +        warnings.warn(
    +            "This class is deprecated. "
    +            "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +            DeprecationWarning,
    +            stacklevel=2,
    +        )
    +        self._callback = callback
    +        self._when = when
    +        self._interval = interval
    +
    +        if ident is not None:
    +            self._id = ident
    +        else:
    +            with Timer._lock:
    +                self._id = Timer._ident + 1
    +                Timer._ident = Timer._ident + 1
    +
    +    def get_interval(self):
    +        return self._interval
    +
    +    def set_interval(self, interval):
    +        self._interval = interval
    +
    +    def get_expiration(self):
    +        return self._when
    +
    +    def set_initial_due_time(self, when):
    +        self._when = when
    +
    +    def update_expiration(self):
    +        self._when += self._interval
    +
    +    def __cmp__(self, other):
    +        if other is None:
    +            return 1
    +
    +        self_k = (self.get_expiration(), self.ident())
    +        other_k = (other.get_expiration(), other.ident())
    +
    +        if self_k == other_k:
    +            return 0
    +        elif self_k < other_k:
    +            return -1
    +        else:
    +            return 1
    +
    +    def __eq__(self, other):
    +        return isinstance(other, Timer) and (self.ident() == other.ident())
    +
    +    def __lt__(self, other):
    +        return self.__cmp__(other) == -1
    +
    +    def __gt__(self, other):
    +        return self.__cmp__(other) == 1
    +
    +    def __ne__(self, other):
    +        return not self.__eq__(other)
    +
    +    def __le__(self, other):
    +        return self.__lt__(other) or self.__eq__(other)
    +
    +    def __ge__(self, other):
    +        return self.__gt__(other) or self.__eq__(other)
    +
    +    def __hash__(self):
    +        return self.ident()
    +
    +    def __call__(self):
    +        self._callback()
    +
    +    def ident(self):
    +        return self._id
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktalib/timer_queue.py b/deployment-apps/metricator-for-nmon/lib/splunktalib/timer_queue.py
    new file mode 100644
    index 0000000..4eba00d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktalib/timer_queue.py
    @@ -0,0 +1,163 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +A timer queue implementation
    +"""
    +
    +import queue
    +import threading
    +import traceback
    +import warnings
    +from time import time
    +
    +from splunktalib.common import log
    +from splunktalib.timer import Timer
    +
    +
    +class TimerQueue:
    +    """
    +    A timer queue implementation, runs a separate thread to handle timers
    +    """
    +
    +    import sortedcontainers as sc
    +
    +    def __init__(self):
    +        warnings.warn(
    +            "This class is deprecated. "
    +            "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
    +            DeprecationWarning,
    +            stacklevel=2,
    +        )
    +        self._timers = TimerQueue.sc.SortedSet()
    +        self._cancelling_timers = {}
    +        self._lock = threading.Lock()
    +        self._wakeup_queue = queue.Queue()
    +        self._thr = threading.Thread(target=self._check_and_execute)
    +        self._started = False
    +
    +    def start(self):
    +        """
    +        Start the timer queue to make it start function
    +        """
    +
    +        if self._started:
    +            return
    +        self._started = True
    +
    +        self._thr.start()
    +        log.logger.info("TimerQueue started.")
    +
    +    def tear_down(self):
    +        if not self._started:
    +            return
    +        self._started = True
    +        self._wakeup(None)
    +        self._thr.join()
    +
    +    def add_timer(self, callback, when, interval):
    +        """
    +        Add timer to the queue
    +        """
    +
    +        timer = Timer(callback, when, interval)
    +        with self._lock:
    +            self._timers.add(timer)
    +        self._wakeup()
    +        return timer
    +
    +    def remove_timer(self, timer):
    +        """
    +        Remove timer from the queue.
    +        """
    +
    +        with self._lock:
    +            try:
    +                self._timers.remove(timer)
    +            except ValueError:
    +                log.logger.info(
    +                    "Timer=%s is not in queue, move it to cancelling " "list",
    +                    timer.ident(),
    +                )
    +            else:
    +                self._cancelling_timers[timer.ident()] = timer
    +
    +    def _check_and_execute(self):
    +        wakeup_queue = self._wakeup_queue
    +        while 1:
    +            (next_expired_time, expired_timers) = self._get_expired_timers()
    +            for timer in expired_timers:
    +                try:
    +                    timer()
    +                except Exception:
    +                    log.logger.error(traceback.format_exc())
    +
    +            self._reset_timers(expired_timers)
    +
    +            # Calc sleep time
    +            if next_expired_time:
    +                now = time()
    +                if now < next_expired_time:
    +                    sleep_time = next_expired_time - now
    +                else:
    +                    sleep_time = 0.1
    +            else:
    +                sleep_time = 1
    +
    +            try:
    +                wakeup = wakeup_queue.get(timeout=sleep_time)
    +                if wakeup is None:
    +                    break
    +            except queue.Empty:
    +                pass
    +        log.logger.info("TimerQueue stopped.")
    +
    +    def _get_expired_timers(self):
    +        next_expired_time = 0
    +        now = time()
    +        expired_timers = []
    +        with self._lock:
    +            for timer in self._timers:
    +                if timer.get_expiration() <= now:
    +                    expired_timers.append(timer)
    +
    +            if expired_timers:
    +                del self._timers[: len(expired_timers)]
    +
    +            if self._timers:
    +                next_expired_time = self._timers[0].get_expiration()
    +        return (next_expired_time, expired_timers)
    +
    +    def _reset_timers(self, expired_timers):
    +        has_new_timer = False
    +        with self._lock:
    +            cancelling_timers = self._cancelling_timers
    +            for timer in expired_timers:
    +                if timer.ident() in cancelling_timers:
    +                    log.logger.INFO("Timer=%s has been cancelled", timer.ident())
    +                    continue
    +                elif timer.get_interval():
    +                    # Repeated timer
    +                    timer.update_expiration()
    +                    self._timers.add(timer)
    +                    has_new_timer = True
    +            cancelling_timers.clear()
    +
    +        if has_new_timer:
    +            self._wakeup()
    +
    +    def _wakeup(self, something="not_None"):
    +        self._wakeup_queue.put(something)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/INSTALLER b/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/INSTALLER
    new file mode 100644
    index 0000000..a1b589e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/INSTALLER
    @@ -0,0 +1 @@
    +pip
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/LICENSE b/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/LICENSE
    new file mode 100644
    index 0000000..56c8192
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/LICENSE
    @@ -0,0 +1,201 @@
    +                                 Apache License
    +                           Version 2.0, January 2004
    +                        http://www.apache.org/licenses/
    +
    +   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    +
    +   1. Definitions.
    +
    +      "License" shall mean the terms and conditions for use, reproduction,
    +      and distribution as defined by Sections 1 through 9 of this document.
    +
    +      "Licensor" shall mean the copyright owner or entity authorized by
    +      the copyright owner that is granting the License.
    +
    +      "Legal Entity" shall mean the union of the acting entity and all
    +      other entities that control, are controlled by, or are under common
    +      control with that entity. For the purposes of this definition,
    +      "control" means (i) the power, direct or indirect, to cause the
    +      direction or management of such entity, whether by contract or
    +      otherwise, or (ii) ownership of fifty percent (50%) or more of the
    +      outstanding shares, or (iii) beneficial ownership of such entity.
    +
    +      "You" (or "Your") shall mean an individual or Legal Entity
    +      exercising permissions granted by this License.
    +
    +      "Source" form shall mean the preferred form for making modifications,
    +      including but not limited to software source code, documentation
    +      source, and configuration files.
    +
    +      "Object" form shall mean any form resulting from mechanical
    +      transformation or translation of a Source form, including but
    +      not limited to compiled object code, generated documentation,
    +      and conversions to other media types.
    +
    +      "Work" shall mean the work of authorship, whether in Source or
    +      Object form, made available under the License, as indicated by a
    +      copyright notice that is included in or attached to the work
    +      (an example is provided in the Appendix below).
    +
    +      "Derivative Works" shall mean any work, whether in Source or Object
    +      form, that is based on (or derived from) the Work and for which the
    +      editorial revisions, annotations, elaborations, or other modifications
    +      represent, as a whole, an original work of authorship. For the purposes
    +      of this License, Derivative Works shall not include works that remain
    +      separable from, or merely link (or bind by name) to the interfaces of,
    +      the Work and Derivative Works thereof.
    +
    +      "Contribution" shall mean any work of authorship, including
    +      the original version of the Work and any modifications or additions
    +      to that Work or Derivative Works thereof, that is intentionally
    +      submitted to Licensor for inclusion in the Work by the copyright owner
    +      or by an individual or Legal Entity authorized to submit on behalf of
    +      the copyright owner. For the purposes of this definition, "submitted"
    +      means any form of electronic, verbal, or written communication sent
    +      to the Licensor or its representatives, including but not limited to
    +      communication on electronic mailing lists, source code control systems,
    +      and issue tracking systems that are managed by, or on behalf of, the
    +      Licensor for the purpose of discussing and improving the Work, but
    +      excluding communication that is conspicuously marked or otherwise
    +      designated in writing by the copyright owner as "Not a Contribution."
    +
    +      "Contributor" shall mean Licensor and any individual or Legal Entity
    +      on behalf of whom a Contribution has been received by Licensor and
    +      subsequently incorporated within the Work.
    +
    +   2. Grant of Copyright License. Subject to the terms and conditions of
    +      this License, each Contributor hereby grants to You a perpetual,
    +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    +      copyright license to reproduce, prepare Derivative Works of,
    +      publicly display, publicly perform, sublicense, and distribute the
    +      Work and such Derivative Works in Source or Object form.
    +
    +   3. Grant of Patent License. Subject to the terms and conditions of
    +      this License, each Contributor hereby grants to You a perpetual,
    +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    +      (except as stated in this section) patent license to make, have made,
    +      use, offer to sell, sell, import, and otherwise transfer the Work,
    +      where such license applies only to those patent claims licensable
    +      by such Contributor that are necessarily infringed by their
    +      Contribution(s) alone or by combination of their Contribution(s)
    +      with the Work to which such Contribution(s) was submitted. If You
    +      institute patent litigation against any entity (including a
    +      cross-claim or counterclaim in a lawsuit) alleging that the Work
    +      or a Contribution incorporated within the Work constitutes direct
    +      or contributory patent infringement, then any patent licenses
    +      granted to You under this License for that Work shall terminate
    +      as of the date such litigation is filed.
    +
    +   4. Redistribution. You may reproduce and distribute copies of the
    +      Work or Derivative Works thereof in any medium, with or without
    +      modifications, and in Source or Object form, provided that You
    +      meet the following conditions:
    +
    +      (a) You must give any other recipients of the Work or
    +          Derivative Works a copy of this License; and
    +
    +      (b) You must cause any modified files to carry prominent notices
    +          stating that You changed the files; and
    +
    +      (c) You must retain, in the Source form of any Derivative Works
    +          that You distribute, all copyright, patent, trademark, and
    +          attribution notices from the Source form of the Work,
    +          excluding those notices that do not pertain to any part of
    +          the Derivative Works; and
    +
    +      (d) If the Work includes a "NOTICE" text file as part of its
    +          distribution, then any Derivative Works that You distribute must
    +          include a readable copy of the attribution notices contained
    +          within such NOTICE file, excluding those notices that do not
    +          pertain to any part of the Derivative Works, in at least one
    +          of the following places: within a NOTICE text file distributed
    +          as part of the Derivative Works; within the Source form or
    +          documentation, if provided along with the Derivative Works; or,
    +          within a display generated by the Derivative Works, if and
    +          wherever such third-party notices normally appear. The contents
    +          of the NOTICE file are for informational purposes only and
    +          do not modify the License. You may add Your own attribution
    +          notices within Derivative Works that You distribute, alongside
    +          or as an addendum to the NOTICE text from the Work, provided
    +          that such additional attribution notices cannot be construed
    +          as modifying the License.
    +
    +      You may add Your own copyright statement to Your modifications and
    +      may provide additional or different license terms and conditions
    +      for use, reproduction, or distribution of Your modifications, or
    +      for any such Derivative Works as a whole, provided Your use,
    +      reproduction, and distribution of the Work otherwise complies with
    +      the conditions stated in this License.
    +
    +   5. Submission of Contributions. Unless You explicitly state otherwise,
    +      any Contribution intentionally submitted for inclusion in the Work
    +      by You to the Licensor shall be under the terms and conditions of
    +      this License, without any additional terms or conditions.
    +      Notwithstanding the above, nothing herein shall supersede or modify
    +      the terms of any separate license agreement you may have executed
    +      with Licensor regarding such Contributions.
    +
    +   6. Trademarks. This License does not grant permission to use the trade
    +      names, trademarks, service marks, or product names of the Licensor,
    +      except as required for reasonable and customary use in describing the
    +      origin of the Work and reproducing the content of the NOTICE file.
    +
    +   7. Disclaimer of Warranty. Unless required by applicable law or
    +      agreed to in writing, Licensor provides the Work (and each
    +      Contributor provides its Contributions) on an "AS IS" BASIS,
    +      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    +      implied, including, without limitation, any warranties or conditions
    +      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
    +      PARTICULAR PURPOSE. You are solely responsible for determining the
    +      appropriateness of using or redistributing the Work and assume any
    +      risks associated with Your exercise of permissions under this License.
    +
    +   8. Limitation of Liability. In no event and under no legal theory,
    +      whether in tort (including negligence), contract, or otherwise,
    +      unless required by applicable law (such as deliberate and grossly
    +      negligent acts) or agreed to in writing, shall any Contributor be
    +      liable to You for damages, including any direct, indirect, special,
    +      incidental, or consequential damages of any character arising as a
    +      result of this License or out of the use or inability to use the
    +      Work (including but not limited to damages for loss of goodwill,
    +      work stoppage, computer failure or malfunction, or any and all
    +      other commercial damages or losses), even if such Contributor
    +      has been advised of the possibility of such damages.
    +
    +   9. Accepting Warranty or Additional Liability. While redistributing
    +      the Work or Derivative Works thereof, You may choose to offer,
    +      and charge a fee for, acceptance of support, warranty, indemnity,
    +      or other liability obligations and/or rights consistent with this
    +      License. However, in accepting such obligations, You may act only
    +      on Your own behalf and on Your sole responsibility, not on behalf
    +      of any other Contributor, and only if You agree to indemnify,
    +      defend, and hold each Contributor harmless for any liability
    +      incurred by, or claims asserted against, such Contributor by reason
    +      of your accepting any such warranty or additional liability.
    +
    +   END OF TERMS AND CONDITIONS
    +
    +   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 "[]"
    +      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
    +      file or class name and description of purpose be included on the
    +      same "printed page" as the copyright notice for easier
    +      identification within third-party archives.
    +
    +   Copyright 2021 Splunk Inc.
    +
    +   Licensed 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.
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/METADATA b/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/METADATA
    new file mode 100644
    index 0000000..41f4b30
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/METADATA
    @@ -0,0 +1,20 @@
    +Metadata-Version: 2.1
    +Name: splunktaucclib
    +Version: 6.0.7
    +Summary: 
    +License: Apache-2.0
    +Author: Splunk
    +Author-email: addonfactory@splunk.com
    +Requires-Python: >=3.7,<4.0
    +Classifier: License :: OSI Approved :: Apache Software License
    +Classifier: Programming Language :: Python :: 3
    +Classifier: Programming Language :: Python :: 3.7
    +Classifier: Programming Language :: Python :: 3.8
    +Classifier: Programming Language :: Python :: 3.9
    +Classifier: Programming Language :: Python :: 3.10
    +Classifier: Programming Language :: Python :: 3.11
    +Requires-Dist: PySocks (>=1.7.1,<2.0.0)
    +Requires-Dist: requests (>=2.26.0,<3.0.0)
    +Requires-Dist: solnlib (>=4.7.0,<5.0.0)
    +Requires-Dist: splunk-sdk (>=1.6.18)
    +Requires-Dist: splunktalib (>=3.0.0,<4.0.0)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/RECORD b/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/RECORD
    new file mode 100644
    index 0000000..3a8b74c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/RECORD
    @@ -0,0 +1,54 @@
    +splunktaucclib-6.0.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
    +splunktaucclib-6.0.7.dist-info/LICENSE,sha256=MAoJOAr_Vegc2uyd5RyaSNkjRZL4p3ItNOwm6sg9PSc,11341
    +splunktaucclib-6.0.7.dist-info/METADATA,sha256=_XUUh3PWn7nibAcylnESb6QwINgaXNgas7WXxHVKt0I,735
    +splunktaucclib-6.0.7.dist-info/RECORD,,
    +splunktaucclib-6.0.7.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
    +splunktaucclib-6.0.7.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
    +splunktaucclib/__init__.py,sha256=KXL_V6zIaH71I0CIkgAHRmdl3INFm9NEQGRRF25W7ds,598
    +splunktaucclib/alert_actions_base.py,sha256=AE2sd_YWXC99sr1g4Qr8zzIvRV1eoOt-a4qFO0YMj88,6826
    +splunktaucclib/cim_actions.py,sha256=xcoy6R4-t96MUPp__BEwzkdJRGKTvxT6DwCVaDDlutA,24625
    +splunktaucclib/common/__init__.py,sha256=oM7n5derwdnifG4fpufcBhFLXu9NtLQRBRjaq5HUSSg,1625
    +splunktaucclib/common/log.py,sha256=oVcMTyPPwAibYIyLlgi2SgQMk-5NbpglRROFIZR2qxU,1607
    +splunktaucclib/config.py,sha256=69ADcm0hg0xYUKSQwFvCzioVtB2UOOSF-OjP1mE18ME,14532
    +splunktaucclib/data_collection/__init__.py,sha256=TB1W22zY5u1d91XSos8Qa2V5NMCpgLTgIiV2wT4hx3Y,575
    +splunktaucclib/data_collection/ta_checkpoint_manager.py,sha256=VpQnY4l6JQW0Lw1q9BhahIDXS30crvcTM4fQ6Vf3xjE,2423
    +splunktaucclib/data_collection/ta_config.py,sha256=71oFBy364ZlhKe65mdK-8P1WghLoz63XzxukxJmUg_c,8905
    +splunktaucclib/data_collection/ta_consts.py,sha256=ATkCQfobwL4dd8wC_mdirn-XKUbHel5FRU-o9OPcEDk,1360
    +splunktaucclib/data_collection/ta_data_client.py,sha256=614sVpRkf0zK9tOrUuR-Op-jbqnccXG_4zIzD_WLEvs,3084
    +splunktaucclib/data_collection/ta_data_collector.py,sha256=jRSN5pp0b1JLrAx0d7Er1cbcwLaMdSh3u1HhnMU0mbk,7196
    +splunktaucclib/data_collection/ta_data_loader.py,sha256=e1RZSmCvd782a5vS5QFNXQuAnVYJo6ezcOtUCXxE4Ug,5505
    +splunktaucclib/data_collection/ta_helper.py,sha256=5Q_epJfmBd1WtXWAUqBlc4yWVA0h2ypQkOLMeUIbyxM,5215
    +splunktaucclib/data_collection/ta_mod_input.py,sha256=fJhKFklPns2BhG-zjl9tp0GbhrYBjAHAI4WSx-IZApo,6617
    +splunktaucclib/global_config/__init__.py,sha256=PIfTiWI8biJSdgkiXeNyzYBUr6qA2UwOImDo7S0DHPE,2187
    +splunktaucclib/global_config/configuration.py,sha256=7Xh5gwY9UXYdcQsNkC0L7P8zF3XcmUw0rkjSEjDt3Qs,12211
    +splunktaucclib/global_config/schema.py,sha256=tv3X-69cuegnsgS-NjZ-doZXGbWjvf0YVTUeryiaxT4,2354
    +splunktaucclib/modinput_wrapper/__init__.py,sha256=TB1W22zY5u1d91XSos8Qa2V5NMCpgLTgIiV2wT4hx3Y,575
    +splunktaucclib/modinput_wrapper/base_modinput.py,sha256=dTUBGt18C5gkagJ7Ivlr3f7GiovfEgSMbp5IIa-jSZs,22456
    +splunktaucclib/rest_handler/__init__.py,sha256=59ORDvD14I_Ksfm0HCcC6fnQLJf9KZNzQT7HXg3ZAcY,622
    +splunktaucclib/rest_handler/admin_external.py,sha256=zoXakN5RNO0HbtrNOstVxRRVCvRSfSbNptWKpE1iUlY,6452
    +splunktaucclib/rest_handler/base.py,sha256=_C9phmBH0rZbfiw3jmX34yB6tdVvpJV-rzLuPYBMQsU,24305
    +splunktaucclib/rest_handler/base_hook_mixin.py,sha256=8xlN4coLM64Ob8Gf62C3c0NA963qH08QBGG25Cg78pw,1499
    +splunktaucclib/rest_handler/cred_mgmt.py,sha256=veJhtfgnEkYCP5PxV6i829yqF3FlVD-GDFycBqkJXUw,5783
    +splunktaucclib/rest_handler/credentials.py,sha256=72iKcPJaZ5BdUqI9ko8iv_lHqOwPRtxXrwf969Y1NfA,16618
    +splunktaucclib/rest_handler/datainput.py,sha256=65IVBjoceMh7mflS6kh0k8KgnTkAAeMBUInTQgLFobY,6857
    +splunktaucclib/rest_handler/eai.py,sha256=tkNySZMgU_lH2ZjWYmfAZwn-Xbpt3h29C-LL5xm2KHM,2122
    +splunktaucclib/rest_handler/endpoint/__init__.py,sha256=ootC6yqwwWv5j-5hko1poOsjy3DBF7pIDmIVSUOwsG4,4331
    +splunktaucclib/rest_handler/endpoint/converter.py,sha256=D8n1WWeDX46Q3Gnxk3zBTtCYMeDdWMs4HNl8aHACehw,8368
    +splunktaucclib/rest_handler/endpoint/field.py,sha256=CjqnDnp8Zx_fJSpjODmArjUtgAquXiBFcNvenZhi3Qk,2103
    +splunktaucclib/rest_handler/endpoint/validator.py,sha256=cpAlHGWDzMIy4X0Tt-ZcL8iYGxVhrobdSvnKY58qjpI,13158
    +splunktaucclib/rest_handler/entity.py,sha256=2lOjIYWCgg5VHLaHDdNmU90V3RJzlAiCJpSIM0PvGuk,913
    +splunktaucclib/rest_handler/error.py,sha256=v8oX8Q9L-shQ6y1CP4RHKYqbEVFXShXFMN-XJpbW-pM,1526
    +splunktaucclib/rest_handler/error_ctl.py,sha256=mqSzKTJhYlBWy7PQ5Hq0-ZC1IrtjadC4t8zZsJUbXhc,5743
    +splunktaucclib/rest_handler/handler.py,sha256=2nwRlJymbEPta6YWfxaSsZ5OoaQZ-464dPcjmJ2yRZU,13772
    +splunktaucclib/rest_handler/multimodel.py,sha256=9Ztxot7nypa2_hNWa2jPFETBusJlZ-UnadxwLD-74YE,5916
    +splunktaucclib/rest_handler/normaliser.py,sha256=Nnf-MC3J3_WGIOCbzuEjdhlUX31Oky1TIjcFAHrPFB4,2952
    +splunktaucclib/rest_handler/poster.py,sha256=TFtX9yephUDqsd0tgg2PRmT_uYob_AvPMswkkphtWSg,6854
    +splunktaucclib/rest_handler/schema.py,sha256=62gIJdYOWVSnoYBLRUrsUtDsBWfDT_nwsiFD_FuBQn0,1115
    +splunktaucclib/rest_handler/teardown.py,sha256=soR9KUQvnl5gQcOsvEfVLb5b-Q-bHC2J0kNI5g4g4BY,5023
    +splunktaucclib/rest_handler/util.py,sha256=OVZVXtOGBOyjbrokMT2TKTT80-ceTwnq6r7I5sJMNqs,4461
    +splunktaucclib/rest_handler/validator.py,sha256=otCxdaOUvdo1wBhZGFo7KHOFkeg9NU0yaqnVvuCkv5g,9160
    +splunktaucclib/splunk_aoblib/__init__.py,sha256=TB1W22zY5u1d91XSos8Qa2V5NMCpgLTgIiV2wT4hx3Y,575
    +splunktaucclib/splunk_aoblib/rest_helper.py,sha256=bPCVWnhlMl-io64XKXzTM0OpYNhtETUSPD74Awaq8Pc,2250
    +splunktaucclib/splunk_aoblib/rest_migration.py,sha256=xLPA1Ev9xPkbXygkXJ2Q-zfYGeljl59MGI6y-bqzvGQ,7768
    +splunktaucclib/splunk_aoblib/setup_util.py,sha256=jMmc7-YvPZ7GzeO9HX2Fk40wRITIFnO-M8Or212Te5c,13882
    +splunktaucclib/splunk_aoblib/utility.py,sha256=j9z3pvRGgQnmH9RSOggBS1Rctv5lFNTD48EbqKrxENg,1152
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/REQUESTED b/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/REQUESTED
    new file mode 100644
    index 0000000..e69de29
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/WHEEL b/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/WHEEL
    new file mode 100644
    index 0000000..4ba7671
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib-6.0.7.dist-info/WHEEL
    @@ -0,0 +1,4 @@
    +Wheel-Version: 1.0
    +Generator: poetry-core 1.4.0
    +Root-Is-Purelib: true
    +Tag: py3-none-any
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/__init__.py
    new file mode 100644
    index 0000000..84e68ad
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/__init__.py
    @@ -0,0 +1,17 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +__version__ = "6.0.7"
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/alert_actions_base.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/alert_actions_base.py
    new file mode 100644
    index 0000000..9580f0c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/alert_actions_base.py
    @@ -0,0 +1,220 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 csv
    +import gzip
    +import logging
    +import sys
    +
    +from solnlib import log
    +
    +from splunktaucclib.cim_actions import ModularAction
    +from splunktaucclib.rest_handler import util
    +from splunktaucclib.splunk_aoblib.rest_helper import TARestHelper
    +from splunktaucclib.splunk_aoblib.setup_util import Setup_Util
    +
    +try:
    +    from splunk.clilib.bundle_paths import make_splunkhome_path
    +except ImportError:
    +    from splunk.appserver.mrsparkle.lib.util import make_splunkhome_path
    +
    +sys.path.insert(0, make_splunkhome_path(["etc", "apps", "Splunk_SA_CIM", "lib"]))
    +
    +
    +class ModularAlertBase(ModularAction):
    +    def __init__(self, ta_name, alert_name):
    +        self._alert_name = alert_name
    +        self._logger_name = alert_name + "_modalert"
    +        self._logger = log.Logs().get_logger(self._logger_name)
    +        super().__init__(sys.stdin.read(), self._logger, alert_name)
    +        self.setup_util_module = None
    +        self.setup_util = None
    +        self.result_handle = None
    +        self.ta_name = ta_name
    +        self.splunk_uri = self.settings.get("server_uri")
    +        self.setup_util = Setup_Util(self.splunk_uri, self.session_key, self._logger)
    +
    +        self.rest_helper = TARestHelper(self._logger)
    +
    +    def log_error(self, msg):
    +        self.message(msg, "failure", level=logging.ERROR)
    +
    +    def log_info(self, msg):
    +        self.message(msg, "success", level=logging.INFO)
    +
    +    def log_debug(self, msg):
    +        self.message(msg, None, level=logging.DEBUG)
    +
    +    def log_warn(self, msg):
    +        self.message(msg, None, level=logging.WARN)
    +
    +    def set_log_level(self, level):
    +        self._logger.setLevel(level)
    +
    +    def get_param(self, param_name):
    +        return self.configuration.get(param_name)
    +
    +    def get_global_setting(self, var_name):
    +        return self.setup_util.get_customized_setting(var_name)
    +
    +    def get_user_credential(self, username):
    +        """
    +        if the username exists, return
    +        {
    +            "username": username,
    +            "password": credential
    +        }
    +        """
    +        return self.setup_util.get_credential_by_username(username)
    +
    +    def get_user_credential_by_account_id(self, account_id):
    +        """
    +        if the account_id exists, return
    +        {
    +            "username": username,
    +            "password": credential
    +        }
    +        """
    +        return self.setup_util.get_credential_by_id(account_id)
    +
    +    @property
    +    def log_level(self):
    +        return self.get_log_level()
    +
    +    @property
    +    def proxy(self):
    +        return self.get_proxy()
    +
    +    def get_log_level(self):
    +        return self.setup_util.get_log_level()
    +
    +    def get_proxy(self):
    +        """if the proxy setting is set. return a dict like
    +        {
    +        proxy_url: ... ,
    +        proxy_port: ... ,
    +        proxy_username: ... ,
    +        proxy_password: ... ,
    +        proxy_type: ... ,
    +        proxy_rdns: ...
    +        }
    +        """
    +        return self.setup_util.get_proxy_settings()
    +
    +    def _get_proxy_uri(self):
    +        proxy = self.get_proxy()
    +        return util.get_proxy_uri(proxy)
    +
    +    def send_http_request(
    +        self,
    +        url,
    +        method,
    +        parameters=None,
    +        payload=None,
    +        headers=None,
    +        cookies=None,
    +        verify=True,
    +        cert=None,
    +        timeout=None,
    +        use_proxy=True,
    +    ):
    +        return self.rest_helper.send_http_request(
    +            url=url,
    +            method=method,
    +            parameters=parameters,
    +            payload=payload,
    +            headers=headers,
    +            cookies=cookies,
    +            verify=verify,
    +            cert=cert,
    +            timeout=timeout,
    +            proxy_uri=self._get_proxy_uri() if use_proxy else None,
    +        )
    +
    +    def build_http_connection(self, config, timeout=120, disable_ssl_validation=False):
    +        raise NotImplementedError(
    +            "Replace the usage of this function to send_http_request function of same class "
    +            "or use requests.request method"
    +        )
    +
    +    def process_event(self, *args, **kwargs):
    +        raise NotImplemented()
    +
    +    def pre_handle(self, num, result):
    +        result.setdefault("rid", str(num))
    +        self.update(result)
    +        return result
    +
    +    def get_events(self):
    +        try:
    +            self.result_handle = gzip.open(self.results_file, "rt")
    +            return (
    +                self.pre_handle(num, result)
    +                for num, result in enumerate(csv.DictReader(self.result_handle))
    +            )
    +        except OSError:
    +            msg = "Error: {}."
    +            self.log_error(msg.format("No search result. Cannot send alert action."))
    +            sys.exit(2)
    +
    +    def prepare_meta_for_cam(self):
    +        with gzip.open(self.results_file, "rt") as rf:
    +            for num, result in enumerate(csv.DictReader(rf)):
    +                result.setdefault("rid", str(num))
    +                self.update(result)
    +                self.invoke()
    +                break
    +
    +    def run(self, argv):
    +        status = 0
    +        if len(argv) < 2 or argv[1] != "--execute":
    +            msg = f'Error: argv="{argv}", expected="--execute"'
    +            print(msg, file=sys.stderr)
    +            sys.exit(1)
    +
    +        # prepare meta first for permission lack error handling: TAB-2455
    +        self.prepare_meta_for_cam()
    +        try:
    +            level = self.get_log_level()
    +            if level:
    +                self._logger.setLevel(level)
    +        except Exception as e:
    +            if str(e) and "403" in str(e):  # Handled e.message with str(e)
    +                self.log_error("User does not have permissions")
    +            else:
    +                self.log_error("Unable to set log level")
    +            sys.exit(2)
    +
    +        try:
    +            status = self.process_event()
    +        except OSError:
    +            msg = "Error: {}."
    +            self.log_error(msg.format("No search result. Cannot send alert action."))
    +            sys.exit(2)
    +        except Exception as e:
    +            msg = "Unexpected error: {}."
    +            if str(e):  # e.message handled
    +                self.log_error(msg.format(str(e)))  # e.message handled
    +            else:
    +                import traceback
    +
    +                self.log_error(msg.format(traceback.format_exc()))
    +            sys.exit(2)
    +        finally:
    +            if self.result_handle:
    +                self.result_handle.close()
    +
    +        return status
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/cim_actions.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/cim_actions.py
    new file mode 100644
    index 0000000..893c69c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/cim_actions.py
    @@ -0,0 +1,593 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 collections
    +import csv
    +import json
    +import logging
    +import logging.handlers
    +import os
    +import random
    +import re
    +import time
    +
    +import splunk.rest as rest
    +from splunk.clilib.bundle_paths import make_splunkhome_path
    +from splunk.util import mktimegm, normalizeBoolean
    +
    +# set the maximum allowable CSV field size
    +#
    +# The default of the csv module is 128KB; upping to 10MB. See SPL-12117 for
    +# the background on issues surrounding field sizes.
    +# (this method is new in python 2.5)
    +csv.field_size_limit(10485760)
    +
    +
    +class InvalidResultID(Exception):
    +    pass
    +
    +
    +class ModularAction:
    +    DEFAULT_MSGFIELDS = [
    +        "signature",
    +        "action_name",
    +        "search_name",
    +        "sid",
    +        "orig_sid",
    +        "rid",
    +        "orig_rid",
    +        "app",
    +        "user",
    +        "action_mode",
    +        "action_status",
    +    ]
    +    DEFAULT_MESSAGE = "sendmodaction - " + " ".join(
    +        ['{i}="{{d[{i}]}}"'.format(i=i) for i in DEFAULT_MSGFIELDS]
    +    )
    +    # The above yields a string.format() compatible format string:
    +    #
    +    #   'sendmodaction - signature="{d[signature]}" action_name="{d[action_name]}"
    +    #   search_name="{d[search_name]}" sid="{d[sid]}" orig_sid="{d[orig_sid]}"
    +    #   rid="{d[rid]}" orig_rid="{d[orig_rid]}" app="{d[app]}" user="{d[user]}"
    +    #   action_mode="{d[action_mode]}" action_status="{d[action_status]}"'
    +
    +    DEFAULT_DROPEXP = lambda x: (
    +        (x.startswith("_") and x not in ["_raw", "_time"])
    +        or x.startswith("date_")
    +        or x in ["punct", "sid", "rid", "orig_sid", "orig_rid"]
    +    )
    +
    +    DEFAULT_MAPEXP = lambda x: (
    +        x.startswith("tag::")
    +        or x
    +        in [
    +            "_time",
    +            "_raw",
    +            "splunk_server",
    +            "index",
    +            "source",
    +            "sourcetype",
    +            "host",
    +            "linecount",
    +            "timestartpos",
    +            "timeendpos",
    +            "eventtype",
    +            "tag",
    +            "search_name",
    +            "event_hash",
    +            "event_id",
    +        ]
    +    )
    +
    +    DEFAULT_HEADER = '***SPLUNK*** index="%s" host="%s" source="%s"'
    +    DEFAULT_BREAKER = "==##~~##~~  1E8N3D4E6V5E7N2T9 ~~##~~##==\n"
    +    DEFAULT_IDLINE = '***Common Action Model*** orig_action_name="%s" orig_sid="%s" orig_rid="%s" sourcetype="%s"\n'
    +    DEFAULT_INDEX = "summary"
    +    DEFAULT_CHUNK = 50000
    +
    +    SHORT_FORMAT = "%(asctime)s %(levelname)s %(message)s"
    +
    +    def __init__(self, settings, logger, action_name="unknown"):
    +        """Initialize ModularAction class.
    +
    +        @param settings:    A modular action payload in JSON format.
    +        @param logger:      A logging instance.
    +                            Recommend using ModularAction.setup_logger.
    +        @param action_name: The action name.
    +                            action_name in payload will take precedence.
    +        """
    +        self.settings = json.loads(settings)
    +        self.logger = logger
    +        self.session_key = self.settings.get("session_key")
    +        self.sid = self.settings.get("sid")
    +        self.sid_snapshot = ""
    +        ## if sid contains rt_scheduler with snapshot-sid; drop snapshot-sid
    +        ## sometimes self.sid may be an integer (1465593470.1228)
    +        try:
    +            rtsid = re.match(r"^(rt_scheduler.*)\.(\d+)$", self.sid)
    +            if rtsid:
    +                self.sid = rtsid.group(1)
    +                self.sid_snapshot = rtsid.group(2)
    +        except:
    +            pass
    +
    +        ## rid_ntuple is a named tuple that represents
    +        ## the three variables that change on a per-result basis
    +        self.rid_ntuple = collections.namedtuple("ID", ["orig_sid", "rid", "orig_rid"])
    +        ## rids is a list of rid_ntuple values
    +        ## automatically maintained by update() calls
    +        self.rids = []
    +        ## current orig_sid based on update()
    +        ## aka self.rids[-1].orig_sid
    +        self.orig_sid = ""
    +        ## current rid based on update()
    +        ## aka self.rids[-1].rid
    +        self.rid = ""
    +        ## current orig_rid based on update()
    +        ## aka self.rids[-1].orig_rid
    +        self.orig_rid = ""
    +
    +        self.results_file = self.settings.get("results_file")
    +        ## info
    +        self.info = {}
    +        if self.results_file:
    +            self.info_file = os.path.join(
    +                os.path.dirname(self.results_file), "info.csv"
    +            )
    +        self.search_name = self.settings.get("search_name")
    +        self.app = self.settings.get("app")
    +        self.user = self.settings.get("user") or self.settings.get("owner")
    +        self.configuration = self.settings.get("configuration", {})
    +        ## enforce configuration is a 'dict'
    +        if not isinstance(self.configuration, dict):
    +            self.configuration = {}
    +        ## set loglevel to DEBUG if verbose
    +        if normalizeBoolean(self.configuration.get("verbose", "false")):
    +            self.logger.setLevel(logging.DEBUG)
    +            self.logger.debug("loglevel set to DEBUG")
    +        ## use | sendalert param.action_name=$action_name$
    +        self.action_name = self.configuration.get("action_name") or action_name
    +        ## use sid to determine action_mode
    +        if isinstance(self.sid, str) and "scheduler" in self.sid:
    +            self.action_mode = "saved"
    +        else:
    +            self.action_mode = "adhoc"
    +
    +        self.action_status = ""
    +        ## Since we don't use the result object we get from settings it will be purged
    +        try:
    +            del self.settings["result"]
    +        except Exception:
    +            pass
    +        ## events
    +        self.events = []
    +
    +    def addinfo(self):
    +        """The purpose of this method is to populate the
    +        modular action info variable with the contents of info.csv.
    +
    +        @raise Exception: raises Exception if self.info_file could not be opened
    +                          or if there were problems parsing the info.csv data
    +        """
    +        if self.info_file:
    +            try:
    +                with open(self.info_file) as fh:
    +                    self.info = next(csv.DictReader(fh))
    +            except Exception as e:
    +                self.message("Could not retrieve info.csv", level=logging.WARN)
    +
    +    def addjobinfo(self):
    +        """The purpose of this method is to populate the job variable
    +        with the contents from REST (/services/search/jobs/<sid>)
    +
    +        SPL-112815 - sendalert - not all $job.<param>$ parameters come through
    +
    +        @raise Exception: raises Exception if search job information could not
    +                          be retrieved via REST (search/jobs) based on self.sid
    +        """
    +        self.job = {}
    +        if self.sid:
    +            try:
    +                response, content = rest.simpleRequest(
    +                    "search/jobs/%s" % self.sid,
    +                    sessionKey=self.session_key,
    +                    getargs={"output_mode": "json"},
    +                )
    +                if response.status == 200:
    +                    self.job = json.loads(content)["entry"][0]["content"]
    +                    self.message("Successfully retrieved search job info")
    +                    self.logger.debug(self.job)
    +                else:
    +                    self.message(
    +                        "Could not retrieve search job info", level=logging.WARN
    +                    )
    +            except Exception as e:
    +                self.message("Could not retrieve search job info", level=logging.WARN)
    +
    +    def message(self, signature, status=None, rids=None, level=logging.INFO, **kwargs):
    +        """The purpose of this method is to provide a common messaging interface.
    +
    +        @param signature: A string representing the message we want to log.
    +        @param status:    An optional status that we want to log.
    +                          Defaults to None.
    +        @param rids:      An optional list of rid_ntuple values in case we
    +                          want to generate the message for multiple rids.
    +                          Defaults to None (use the rid currently loaded).
    +        @param level:     The logging level to use when writing the message.
    +                          Defaults to logging.INFO (INFO)
    +        @param kwargs:    Additional keyword arguments to be included with the
    +                          message.
    +                          Defaults to "no arguments".
    +
    +        @return message:  This method logs the message; however, for
    +                          backwards compatibility we also return the message.
    +        """
    +        ## status
    +        status = status or self.action_status or ""
    +        ## rid
    +        if not isinstance(rids, list):
    +            rids = [self.rid_ntuple(self.orig_sid, self.rid, self.orig_rid)]
    +        ## kwargs - prune any duplicate keys based on DEFAULT_MSGFIELDS
    +        ##          prune any keys with special characters [A-Za-z_]+
    +        newargs = [
    +            x
    +            for x in kwargs
    +            if (x not in ModularAction.DEFAULT_MSGFIELDS) and re.match("[A-Za-z_]+", x)
    +        ]
    +        ## MSG
    +        msg = "{} {}".format(
    +            ModularAction.DEFAULT_MESSAGE,
    +            " ".join(['{i}="{{d[{i}]}}"'.format(i=i) for i in newargs]),
    +        )
    +
    +        # This will set the default value of any value NOT in the dictionary to the
    +        # empty string.
    +        argsdict = collections.defaultdict(str)
    +        # order is important here - here we update first from kwargs, then from our
    +        # expected arg set.
    +        argsdict.update(kwargs)
    +        argsdict.update(
    +            {
    +                "signature": signature or "",
    +                "action_name": self.action_name or "",
    +                "search_name": self.search_name or "",
    +                "sid": self.sid or "",
    +                "app": self.app or "",
    +                "user": self.user or "",
    +                "action_mode": self.action_mode or "",
    +                "action_status": status,
    +            }
    +        )
    +
    +        for rid_ntuple in rids:
    +            if len(rid_ntuple) == 3:
    +                ## Update the arguments dictionary
    +                argsdict.update(
    +                    {
    +                        "orig_sid": rid_ntuple.orig_sid or "",
    +                        "rid": rid_ntuple.rid or "",
    +                        "orig_rid": rid_ntuple.orig_rid or "",
    +                    }
    +                )
    +                ## This is where the magic happens. The format string will use the
    +                ## attributes of "argsdict"
    +                message = msg.format(d=argsdict)
    +                ## prune empty string key-value pairs
    +                for match in re.finditer(r'[A-Za-z_]+=""(\s|$)', message):
    +                    message = message.replace(match.group(0), "", 1)
    +                message = message.strip()
    +                self.logger.log(level, message)
    +            else:
    +                self.logger.warn("Could not unpack rid_ntuple")
    +                message = ""
    +
    +        return message
    +
    +    def update(self, result):
    +        """The purpose of this method is to update the ModularAction instance
    +        identifiers based on the current result being operated on.
    +
    +        This is the most important method in the library as it sets up
    +        rid, orig_sid, and orig_rid to be used by subsequent class methods.
    +
    +        Not calling update() immediately for each result before doing additional
    +        work can have adverse affects.
    +
    +        @param signature: A string representing the message we want to log.
    +        @param status:    An optional status that we want to log.
    +                          Defaults to None.
    +        @param rids:      An optional list of rid_ntuple values in case we
    +                          want to generate the message for multiple rids.
    +                          Defaults to None (use the rid currently loaded).
    +        @param level:     The logging level to use when writing the message.
    +                          Defaults to logging.INFO (INFO)
    +        @param kwargs:    Additional keyword arguments to be included with the
    +                          message.
    +                          Defaults to "no arguments".
    +
    +        @return message:  This method logs the message; however, for
    +                          backwards compatiblity we also return the message.
    +        """
    +        ## This is for events/results that were created as the result of a previous action
    +        self.orig_sid = result.get("orig_sid", "")
    +        ## This is for events/results that were created as the result of a previous action
    +        self.orig_rid = result.get("orig_rid", "")
    +        if "rid" in result and isinstance(result["rid"], (str, int)):
    +            self.rid = str(result["rid"])
    +            if self.sid_snapshot:
    +                self.rid = f"{self.rid}.{self.sid_snapshot}"
    +            ## add result info to list of named tuples
    +            self.rids.append(self.rid_ntuple(self.orig_sid, self.rid, self.orig_rid))
    +        else:
    +            raise InvalidResultID("Result must have an ID")
    +
    +    def invoke(self):
    +        """The purpose of this method is to generate per-result invocation messages.
    +        This method is used to identify that an action is being attempted on a per-result basis.
    +
    +        Remember to call update() prior to invoke() to ensure that the invocation message
    +        reflects the appropriate identifiers.
    +        """
    +        self.message("Invoking modular action")
    +
    +    def result2stash(
    +        self, result, dropexp=DEFAULT_DROPEXP, mapexp=DEFAULT_MAPEXP, addinfo=False
    +    ):
    +        """The purpose of this method is to formulate an event in stash format
    +
    +        @param result:  The result dictionary to generate a stash event for.
    +        @param dropexp: A lambda expression used to determine whether a field
    +                        should be dropped or not.
    +                        Defaults to DEFAULT_DROPEXP.
    +        @param mapexp:  A lambda expression used to determine whether a field
    +                        should be mapped (prepended with "orig_") or not.
    +                        Defaults to DEFAULT_MAPEXP.
    +        @param addinfo: Whether or not to add search information to the event.
    +                        "info" includes search_now, info_min_time, info_max_time,
    +                        and info_search_time fields.
    +                        Requires that information was loaded into the ModularAction
    +                        instance via addinfo()
    +
    +        @return _raw:   Returns a string which represents the result in stash format.
    +
    +        The following example has been broken onto multiple lines for readability:
    +        06/21/2016 10:00:00 -0700,
    +        search_name="Access - Brute Force Access Behavior Detected - Rule",
    +        search_now=0.000, info_min_time=1466528400.000, info_max_time=1466532600.000, info_search_time=1465296264.179,
    +        key1=key1val, key2=key2val, key3=key3val, key4=key4val1, key4=key4val2, ...
    +        """
    +        dropexp = dropexp or (lambda x: False)
    +        mapexp = mapexp or (lambda x: False)
    +        orig_dropexp = (
    +            lambda x: x.startswith("orig_") and x[5:] in result and mapexp(x[5:])
    +        )
    +
    +        ## addinfo
    +        if addinfo:
    +            result["info_min_time"] = self.info.get("_search_et", "0.000")
    +            info_max_time = self.info.get("_search_lt")
    +            if not info_max_time or info_max_time == 0 or info_max_time == "0":
    +                info_max_time = "+Infinity"
    +            result["info_max_time"] = info_max_time
    +            result["info_search_time"] = self.info.get("_timestamp", "")
    +
    +        ## construct _raw
    +        _raw = "%s" % result.get("_time", mktimegm(time.gmtime()))
    +        if self.search_name:
    +            _raw += ', search_name="%s"' % self.search_name
    +
    +        processed_keys = []
    +        for key, val in sorted(result.items()):
    +            vals = []
    +            ## if we have a proper mv field
    +            if (
    +                key.startswith("__mv_")
    +                and val
    +                and isinstance(val, str)
    +                and val.startswith("$")
    +                and val.endswith("$")
    +            ):
    +                real_key = key[5:]
    +                vals = val[1:-1].split("$;$")
    +            ## if proper sv field
    +            elif val and not key.startswith("__mv_"):
    +                real_key = key
    +                vals = [val]
    +
    +            ## if we have vals and key hasn't been processed
    +            ## and key is not to be dropped...
    +            if (
    +                vals
    +                and (real_key not in processed_keys)
    +                and not dropexp(real_key)
    +                and not orig_dropexp(real_key)
    +            ):
    +                ## iterate vals
    +                for val in vals:
    +                    ## format literal '$'
    +                    if key.startswith("__mv"):
    +                        val = val.replace("$$", "$")
    +                    ## escape quotes
    +                    if isinstance(val, str):
    +                        val = val.replace('"', r"\"")
    +                    ## check map
    +                    if mapexp(real_key):
    +                        _raw += ', {}="{}"'.format("orig_" + real_key.lstrip("_"), val)
    +                    else:
    +                        _raw += f', {real_key}="{val}"'
    +                processed_keys.append(real_key)
    +
    +        return _raw
    +
    +    def addevent(self, raw, sourcetype, cam_header=True):
    +        """The purpose of this method is to add a properly constructed event
    +        to the events list in the ModularAction instance.  This ensures events
    +        are created with the appropriate index-time header.
    +
    +        The index-time header is responsible for setting sourcetype,
    +        orig_action_name, orig_sid, and orig_rid.  The index-time header will
    +        not be present in the _raw of generated events.
    +
    +        Remember to call update() prior to addevent() to ensure that the events
    +        reflect the appropriate orig_sid and orig_rid identifiers.
    +
    +        @param raw:        The text of the event you want to generate.
    +        @param sourcetype: The sourcetype of the event you want to generate.
    +        @param cam_header: Optionally exclude the inclusion of the index-time header.
    +                           Defaults to True (include header).
    +        """
    +        if cam_header:
    +            if self.orig_sid:
    +                action_idline = ModularAction.DEFAULT_IDLINE % (
    +                    self.action_name,
    +                    self.orig_sid,
    +                    self.orig_rid,
    +                    sourcetype,
    +                )
    +            else:
    +                action_idline = ModularAction.DEFAULT_IDLINE % (
    +                    self.action_name,
    +                    self.sid,
    +                    self.rid,
    +                    sourcetype,
    +                )
    +            self.events.append(action_idline + raw)
    +        else:
    +            self.events.append(raw)
    +
    +    def writeevents(
    +        self, index="summary", host=None, source=None, fext="common_action_model"
    +    ):
    +        """The purpose of this method is to create arbitrary splunk events
    +        from the list of events in the ModularAction instance.
    +
    +        Please use addevent() for populating the list of events in
    +        the ModularAction instance.
    +
    +        @param index:  The index to write the events to.
    +                       Defaults to "summary".
    +        @param host:   The value of host the events should take on.
    +                       Defaults to None (auto).
    +        @param source: The value of source the events should take on.
    +                       Defaults to None (auto).
    +        @param fext:   The extension of the file to write out.
    +                       Files are written to $SPLUNK_HOME/var/spool/splunk.
    +                       File extensions can only contain word characters,
    +                       dash, and have a 200 char max.
    +                       "stash_" is automatically prepended to all extensions.
    +                       Defaults to "common_action_model" ("stash_common_action_model").
    +                       Only override if you've set up a corresponding props.conf
    +                       stanza to handle the extension.
    +
    +        @return bool:  Returns True if all events were successfully written
    +                       Returns False if any errors were encountered
    +        """
    +        ## internal makeevents method for normalizing strings
    +        ## that will be used in the various headers we write out
    +        def get_string(input, default):
    +            try:
    +                return input.replace('"', "_")
    +            except AttributeError:
    +                return default
    +
    +        if self.events:
    +            ## sanitize file extension
    +            if not fext or not re.match(r"^[\w-]+$", fext):
    +                self.logger.warn(
    +                    "Requested file extension was ignored due to invalid characters"
    +                )
    +                fext = "common_action_model"
    +            elif len(fext) > 200:
    +                self.logger.warn("Requested file extension was ignored due to length")
    +                fext = "common_action_model"
    +            ## header
    +            header_line = ModularAction.DEFAULT_HEADER % (
    +                get_string(index, ModularAction.DEFAULT_INDEX),
    +                get_string(host, ""),
    +                get_string(source, ""),
    +            )
    +            ## process event chunks
    +            for chunk in (
    +                self.events[x : x + ModularAction.DEFAULT_CHUNK]
    +                for x in range(0, len(self.events), ModularAction.DEFAULT_CHUNK)
    +            ):
    +                ## initialize output string
    +                default_breaker = "\n" + ModularAction.DEFAULT_BREAKER
    +                fout = header_line + default_breaker + (default_breaker).join(chunk)
    +                ## write output string
    +                try:
    +                    fn = "{}_{}.stash_{}".format(
    +                        mktimegm(time.gmtime()),
    +                        random.randint(0, 100000),
    +                        fext,
    +                    )
    +                    fp = make_splunkhome_path(["var", "spool", "splunk", fn])
    +                    ## obtain fh
    +                    with open(fp, "w") as fh:
    +                        fh.write(fout)
    +                except:
    +                    signature = "Error obtaining file handle during makeevents"
    +                    self.message(signature, level=logging.ERROR, file_path=fp)
    +                    self.logger.exception(signature + " file_path=%s" % fp)
    +                    return False
    +            self.message(
    +                "Successfully created splunk events", event_count=len(self.events)
    +            )
    +            return True
    +        return False
    +
    +    def dowork(self):
    +        """This method serves as an illustration stub.
    +        Serves as a container for operations which satisfy the nature of the action.
    +        For instance, the third party API call.
    +
    +        For cleanliness it is recommended that you subclass ModularAction
    +        and implement your own dowork() method.
    +        """
    +        return
    +
    +    @staticmethod
    +    def setup_logger(
    +        name, level=logging.INFO, maxBytes=25000000, backupCount=5, format=SHORT_FORMAT
    +    ):
    +        """Set up a logging instance.
    +
    +        @param name:        The log file name.
    +                            We recommend "$action_name$_modalert".
    +        @param level:       The logging level.
    +        @param maxBytes:    The maximum log file size before rollover.
    +        @param backupCount: The number of log files to retain.
    +
    +        @return logger:     Returns an instance of logger
    +        """
    +        logfile = make_splunkhome_path(["var", "log", "splunk", name + ".log"])
    +        logger = logging.getLogger(name)
    +        logger.setLevel(level)
    +        logger.propagate = False  # Prevent the log messages from being duplicated in the python.log file
    +
    +        # Prevent re-adding handlers to the logger object, which can cause duplicate log lines.
    +        handler_exists = any(
    +            [True for h in logger.handlers if h.baseFilename == logfile]
    +        )
    +        if not handler_exists:
    +            file_handler = logging.handlers.RotatingFileHandler(
    +                logfile, maxBytes=maxBytes, backupCount=backupCount
    +            )
    +            formatter = logging.Formatter(format)
    +            file_handler.setFormatter(formatter)
    +            logger.addHandler(file_handler)
    +
    +        return logger
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/common/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/common/__init__.py
    new file mode 100644
    index 0000000..8c65e97
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/common/__init__.py
    @@ -0,0 +1,67 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 hashlib
    +import json
    +
    +
    +def load_schema_file(schema_file):
    +    """
    +    Load schema file.
    +    """
    +
    +    with open(schema_file) as f:
    +        ret = json.load(f)
    +
    +    common = ret.get("_common_", dict())
    +    if common:
    +        for k, v in list(ret.items()):
    +            if k == "_common_" or not isinstance(v, dict):
    +                continue
    +            # merge common into other values
    +            for _k, _v in list(common.items()):
    +                if _k not in v:
    +                    v[_k] = _v
    +            ret[k] = v
    +
    +    return ret
    +
    +
    +def md5_of_dict(data):
    +    """
    +    MD5 of dict data.
    +    """
    +
    +    md5 = hashlib.sha256()
    +    if isinstance(data, dict):
    +        for key in sorted(data.keys()):
    +            md5.update(repr(key))
    +            md5.update(md5_of_dict(data[key]))
    +    elif isinstance(data, list):
    +        for item in sorted(data):
    +            md5.update(md5_of_dict(item))
    +    else:
    +        md5.update(repr(data))
    +
    +    return md5.hexdigest()
    +
    +
    +class UCCException(Exception):
    +    """
    +    Dispatch engine exception.
    +    """
    +
    +    pass
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/common/log.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/common/log.py
    new file mode 100644
    index 0000000..368317a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/common/log.py
    @@ -0,0 +1,64 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 logging
    +
    +import splunktalib.common.log as stclog
    +
    +_level_by_name = {
    +    "DEBUG": logging.DEBUG,
    +    "INFO": logging.INFO,
    +    "WARNING": logging.WARNING,
    +    "ERROR": logging.ERROR,
    +    "FATAL": logging.FATAL,
    +    "CRITICAL": logging.CRITICAL,
    +}
    +
    +
    +def _get_log_level(log_level, default_level=logging.INFO):
    +    if not log_level:
    +        return default_level
    +    if isinstance(log_level, str):
    +        log_level = log_level.upper()
    +        for k, v in _level_by_name.items():
    +            if k.startswith(log_level):
    +                return v
    +    if isinstance(log_level, int):
    +        if log_level in list(_level_by_name.values()):
    +            return log_level
    +    return default_level
    +
    +
    +def set_log_level(log_level):
    +    """
    +    Set log level.
    +    """
    +    stclog.Logs().set_level(_get_log_level(log_level))
    +
    +
    +# Global logger
    +logger = stclog.Logs().get_logger("ucc_lib")
    +
    +
    +def reset_logger(name):
    +    """
    +    Reset logger.
    +    """
    +
    +    stclog.reset_logger(name)
    +
    +    global logger
    +    logger = stclog.Logs().get_logger(name)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/config.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/config.py
    new file mode 100644
    index 0000000..2e294ef
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/config.py
    @@ -0,0 +1,421 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""UCC Config Module
    +This is for load/save configuration in UCC server or TA.
    +The load/save action is based on specified schema.
    +"""
    +
    +
    +import json
    +import logging
    +import time
    +import traceback
    +from urllib.parse import quote
    +
    +from splunktalib.common import util as sc_util
    +from splunktalib.rest import code_to_msg, splunkd_request
    +
    +import splunktaucclib.common.log as stulog
    +from splunktaucclib.common import UCCException
    +
    +LOGGING_STOPPED = False
    +
    +
    +def stop_logging():
    +    """
    +    Stop Config Logging. This is for not showing REST request error
    +    while splunkd shutting down.
    +    :return:
    +    """
    +    global LOGGING_STOPPED
    +    LOGGING_STOPPED = True
    +
    +
    +def log(msg, msgx="", level=logging.INFO, need_tb=False):
    +    """
    +    Logging in UCC Config Module.
    +    :param msg: message content
    +    :param msgx: detail info.
    +    :param level: logging level
    +    :param need_tb: if need logging traceback
    +    :return:
    +    """
    +    global LOGGING_STOPPED
    +    if LOGGING_STOPPED:
    +        return
    +
    +    msgx = " - " + msgx if msgx else ""
    +    content = f"UCC Config Module: {msg}{msgx}"
    +    if need_tb:
    +        stack = "".join(traceback.format_stack())
    +        content = f"{content}\r\n{stack}"
    +    stulog.logger.log(level, content, exc_info=1)
    +
    +
    +class ConfigException(UCCException):
    +    """Exception for UCC Config Exception"""
    +
    +    pass
    +
    +
    +class Config:
    +    """UCC Config Module"""
    +
    +    # Placeholder stands for any field
    +    FIELD_PLACEHOLDER = "*"
    +
    +    # Head of non-processing endpoint
    +    NON_PROC_ENDPOINT = "#"
    +
    +    # Some meta fields in UCC Config schema
    +    META_FIELDS = (
    +        "_product",
    +        "_rest_namespace",
    +        "_rest_prefix",
    +        "_version",
    +        "_encryption_formatter",
    +    )
    +
    +    # Default Values for Meta fields
    +    META_FIELDS_DEFAULT = {
    +        "_encryption_formatter": "",
    +    }
    +
    +    def __init__(self, splunkd_uri, session_key, schema, user="nobody", app="-"):
    +        """
    +        :param splunkd_uri: the root uri of Splunk server,
    +            like https://127.0.0.1:8089
    +        :param session_key: session key for Splunk server
    +        :param schema:
    +        :param user: owner of the resources requested
    +        :param app: namespace of the resources requested
    +        :return:
    +        """
    +        self.splunkd_uri = splunkd_uri.strip("/")
    +        self.session_key = session_key
    +        self.user, self.app = user, app
    +        self._parse_schema(schema)
    +
    +    def load(self):
    +        """Load Configurations in UCC according to the schema
    +        It will raise exception if failing to load any endpoint,
    +        because it make no sense with not complete configuration info.
    +        """
    +        log('"load" method in', level=logging.DEBUG)
    +
    +        ret = {
    +            meta_field: getattr(self, meta_field) for meta_field in Config.META_FIELDS
    +        }
    +
    +        for ep_id, ep in self._endpoints.items():
    +            data = {"output_mode": "json", "--cred--": "1"}
    +
    +            retries = 4
    +            waiting_time = [1, 2, 2]
    +            for retry in range(retries):
    +                resp = splunkd_request(
    +                    splunkd_uri=self.make_uri(ep_id),
    +                    session_key=self.session_key,
    +                    data=data,
    +                    retry=3,
    +                )
    +
    +                if resp is None or resp.status_code != 200:
    +                    msg = f'Fail to load endpoint "{ep_id}" - {code_to_msg(resp)}'
    +                    log(msg, level=logging.ERROR, need_tb=True)
    +                    raise ConfigException(msg)
    +
    +                try:
    +                    ret[ep_id] = self._parse_content(ep_id, resp.text)
    +                except ConfigException as exc:
    +                    log(exc, level=logging.WARNING, need_tb=True)
    +                    if retry < retries - 1:
    +                        time.sleep(waiting_time[retry])
    +                else:
    +                    break
    +            else:
    +                log(exc, level=logging.ERROR, need_tb=True)
    +                raise exc
    +
    +        log('"load" method out', level=logging.DEBUG)
    +        return ret
    +
    +    def update_items(
    +        self, endpoint_id, item_names, field_names, data, raise_if_failed=False
    +    ):
    +        """Update items in specified endpoint with given fields in data
    +        :param endpoint_id: endpoint id in schema, the key name in schema
    +        :param item_names: a list of item name
    +        :param field_names: a list of updated fields
    +        :param data: a dict of content for items, for example:
    +            {
    +                "item_name_1": {
    +                    "field_name_1": "value_1",
    +                    "field_name_2": "value_2",
    +                },
    +                "item_name_2": {
    +                    "field_name_1": "value_1x",
    +                    "field_name_2": "value_2x",
    +                }
    +            }
    +        :raise_if_failed: raise an exception if updating failed.
    +        :return: a list of endpoint ids, which are failed to be updated.
    +            If raise_if_failed is True, it will exist with an exception
    +            on any updating failed.
    +        """
    +        log(
    +            '"update_items" method in',
    +            msgx="endpoint_id=%s, item_names=%s, field_names=%s"
    +            % (endpoint_id, item_names, field_names),
    +            level=logging.DEBUG,
    +        )
    +
    +        assert (
    +            endpoint_id in self._endpoints
    +        ), "Unexpected endpoint id in given schema - {ep_id}" "".format(
    +            ep_id=endpoint_id
    +        )
    +
    +        item_names_failed = []
    +        for item_name in item_names:
    +            item_data = data.get(item_name, {})
    +            post_data = {
    +                field_name: self.dump_value(
    +                    endpoint_id, item_name, field_name, item_data[field_name]
    +                )
    +                for field_name in field_names
    +                if field_name in item_data
    +            }
    +            if not post_data:
    +                continue
    +            item_uri = self.make_uri(endpoint_id, item_name=item_name)
    +
    +            resp = splunkd_request(
    +                splunkd_uri=item_uri,
    +                session_key=self.session_key,
    +                data=post_data,
    +                method="POST",
    +                retry=3,
    +            )
    +            if resp is None or resp.status_code not in (200, 201):
    +                msg = f'Fail to update item "{item_name}" in endpoint "{endpoint_id}" - {code_to_msg(resp)}'
    +                log(msg, level=logging.ERROR)
    +                if raise_if_failed:
    +                    raise ConfigException(msg)
    +                item_names_failed.append(item_name)
    +
    +        log('"update_items" method out', level=logging.DEBUG)
    +        return item_names_failed
    +
    +    def make_uri(self, endpoint_id, item_name=None):
    +        """Make uri for REST endpoint in TA according to given schema
    +        :param endpoint_id: endpoint id in schema
    +        :param item_name: item name for given endpoint. None for listing all
    +        :return:
    +        """
    +        endpoint = self._endpoints[endpoint_id]["endpoint"]
    +        ep_full = (
    +            endpoint[1:].strip("/")
    +            if endpoint.startswith(Config.NON_PROC_ENDPOINT)
    +            else "{endpoint}"
    +            "".format(
    +                endpoint=(self._rest_prefix + self._endpoints[endpoint_id]["endpoint"])
    +            )
    +        )
    +        ep_uri = (
    +            None
    +            if endpoint_id not in self._endpoints
    +            else "{splunkd_uri}/servicesNS/{user}/{app}/{endpoint_full}"
    +            "".format(
    +                splunkd_uri=self.splunkd_uri,
    +                user=self.user,
    +                app=self.app,
    +                endpoint_full=ep_full,
    +            )
    +        )
    +        url = (
    +            ep_uri
    +            if item_name is None
    +            else "{ep_uri}/{item_name}".format(
    +                ep_uri=ep_uri, item_name=quote(item_name)
    +            )
    +        )
    +        if item_name is None:
    +            url += "?count=-1"
    +        log('"make_uri" method', msgx="url=%s" % url, level=logging.DEBUG)
    +        return url
    +
    +    def _parse_content(self, endpoint_id, content):
    +        """Parse content returned from REST
    +        :param content: a JSON string returned from REST.
    +        """
    +        try:
    +            content = json.loads(content)["entry"]
    +            ret = {ent["name"]: ent["content"] for ent in content}
    +        except Exception as exc:
    +            msg = "Fail to parse content from endpoint_id=%s" " - %s" % (
    +                endpoint_id,
    +                exc,
    +            )
    +            log(msg, level=logging.ERROR, need_tb=True)
    +            raise ConfigException(msg)
    +
    +        ret = {
    +            name: {
    +                key: self.load_value(endpoint_id, name, key, val)
    +                for key, val in ent.items()
    +                if not key.startswith("eai:")
    +            }
    +            for name, ent in ret.items()
    +        }
    +        return ret
    +
    +    def _parse_schema(self, ucc_config_schema):
    +        try:
    +            ucc_config_schema = json.loads(ucc_config_schema)
    +        except ValueError:
    +            msg = "Invalid JSON content of schema"
    +            log(msg, level=logging.ERROR, need_tb=True)
    +            raise ConfigException(msg)
    +        except Exception as exc:
    +            log(exc, level=logging.ERROR, need_tb=True)
    +            raise ConfigException(exc)
    +
    +        ucc_config_schema.update(
    +            {
    +                key: val
    +                for key, val in Config.META_FIELDS_DEFAULT.items()
    +                if key not in ucc_config_schema
    +            }
    +        )
    +        for field in Config.META_FIELDS:
    +            assert field in ucc_config_schema and isinstance(
    +                ucc_config_schema[field], str
    +            ), ('Missing or invalid field "%s" in given schema' % field)
    +            setattr(self, field, ucc_config_schema[field])
    +
    +        self._endpoints = {}
    +        for key, val in ucc_config_schema.items():
    +            if key.startswith("_"):
    +                continue
    +
    +            assert isinstance(val, dict), (
    +                'The schema of endpoint "%s" should be dict' % key
    +            )
    +            assert "endpoint" in val, 'The endpoint "%s" has no endpoint entry' % key
    +
    +            self._endpoints[key] = val
    +
    +    def load_value(self, endpoint_id, item_name, fname, fval):
    +        field_type = self._get_field_type(endpoint_id, item_name, fname)
    +        if field_type == "":
    +            return fval
    +
    +        try:
    +            field_type = field_type.lower()
    +            if field_type == "bool":
    +                return True if sc_util.is_true(fval) else False
    +            elif field_type == "int":
    +                return int(fval)
    +            elif field_type == "json":
    +                try:
    +                    return json.loads(fval)
    +                except ValueError as err:
    +                    if err.message.startswith("Extra data:"):
    +                        return json.loads(self.try_fix_corrupted_json(fval, err))
    +                    else:
    +                        raise err
    +        except Exception as exc:
    +            msg = (
    +                'Fail to load value of "{type_name}" - '
    +                "endpoint={endpoint}, item={item}, field={field}"
    +                "".format(
    +                    type_name=field_type,
    +                    endpoint=endpoint_id,
    +                    item=item_name,
    +                    field=fname,
    +                )
    +            )
    +            log(msg, msgx=str(exc), level=logging.WARNING, need_tb=True)
    +            log("Value of failed load_value is", msgx=fval, level=logging.DEBUG)
    +            raise ConfigException(msg)
    +
    +    def try_fix_corrupted_json(self, corrupted_json, value_err):
    +        """
    +        A bug was encountered that 'access_token_encrypted' or 'refresh_token'
    +        got corrupted when it was saved in the conf file
    +        """
    +        # value_err.message is in this format:
    +        #   Extra data: line 1 column 2720 - line 1 column 2941 (char 2719 - 2940)
    +        # what we need is the first number in the parenthesis (2719 in the above example)
    +        end_index = int(value_err.message.split("(char")[1].split("-")[0].strip())
    +        return corrupted_json[0:end_index]
    +
    +    def dump_value(self, endpoint_id, item_name, fname, fval):
    +        field_type = self._get_field_type(endpoint_id, item_name, fname)
    +        if field_type == "":
    +            return fval
    +
    +        try:
    +            field_type = field_type.lower()
    +            if field_type == "bool":
    +                return str(fval).lower()
    +            elif field_type == "json":
    +                return json.dumps(fval)
    +            else:
    +                return fval
    +        except Exception as exc:
    +            msg = (
    +                'Fail to dump value of "{type_name}" - '
    +                "endpoint={endpoint}, item={item}, field={field}"
    +                "".format(
    +                    type_name=field_type,
    +                    endpoint=endpoint_id,
    +                    item=item_name,
    +                    field=fname,
    +                )
    +            )
    +            log(msg, msgx=str(exc), level=logging.ERROR, need_tb=True)
    +            raise ConfigException(msg)
    +
    +    def _get_field_type(self, endpoint_id, item_name, fname):
    +        field_types = self._endpoints[endpoint_id].get("field_types", {})
    +        if item_name in field_types:
    +            fields = field_types[item_name]
    +        elif Config.FIELD_PLACEHOLDER in field_types:
    +            fields = field_types[Config.FIELD_PLACEHOLDER]
    +        else:
    +            fields = {}
    +
    +        field_type = fields.get(fname, "")
    +        if field_type not in ("", "bool", "int", "json"):
    +            msg = (
    +                'Unsupported type "{type_name}" for value in schema - '
    +                "endpoint={endpoint}, item={item}, field={field}"
    +                "".format(
    +                    type_name=field_type,
    +                    endpoint=endpoint_id,
    +                    item=item_name,
    +                    field=fname,
    +                )
    +            )
    +            log(msg, level=logging.ERROR, need_tb=True)
    +            raise ConfigException(msg)
    +        return field_type
    +
    +    def get_endpoints(self):
    +        return self._endpoints
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/__init__.py
    new file mode 100644
    index 0000000..72d4509
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/__init__.py
    @@ -0,0 +1,15 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_checkpoint_manager.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_checkpoint_manager.py
    new file mode 100644
    index 0000000..86346f7
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_checkpoint_manager.py
    @@ -0,0 +1,76 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 re
    +import urllib.error
    +import urllib.parse
    +import urllib.request
    +
    +import splunktalib.state_store as ss
    +
    +import splunktaucclib.common.log as stulog
    +
    +from . import ta_consts as c
    +
    +
    +class TACheckPointMgr:
    +    SEPARATOR = "___"
    +
    +    def __init__(self, meta_config, task_config):
    +        self._task_config = task_config
    +        self._store = ss.get_state_store(
    +            meta_config, task_config[c.appname], use_kv_store=self._use_kv_store()
    +        )
    +        if isinstance(self._store, ss.CachedFileStateStore):
    +            stulog.logger.info("State store type is CachedFileStateStore")
    +
    +    def _use_kv_store(self):
    +        use_kv_store = self._task_config.get(c.use_kv_store, False)
    +        if use_kv_store:
    +            stulog.logger.info(
    +                "Stanza={} Using KV store for checkpoint".format(
    +                    self._task_config[c.stanza_name]
    +                )
    +            )
    +        return use_kv_store
    +
    +    def get_ckpt_key(self):
    +        return self.key_formatter()
    +
    +    def get_ckpt(self):
    +        key = self.get_ckpt_key()
    +        return self._store.get_state(key)
    +
    +    def update_ckpt(self, ckpt):
    +        key = self.get_ckpt_key()
    +        self._store.update_state(key, ckpt)
    +
    +    def remove_ckpt(self):
    +        key = self.get_ckpt_key()
    +        self._store.delete_state(key)
    +
    +    def key_formatter(self):
    +        divide_value = [self._task_config[c.stanza_name]]
    +        for key in self._task_config[c.divide_key]:
    +            divide_value.append(self._task_config[key])
    +        key_str = TACheckPointMgr.SEPARATOR.join(divide_value)
    +        qualified_key_str = ""
    +        for i in range(len(key_str)):
    +            if re.match(r"[^\w]", key_str[i]):
    +                qualified_key_str += urllib.parse.quote(key_str[i])
    +            else:
    +                qualified_key_str += key_str[i]
    +        return qualified_key_str
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_config.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_config.py
    new file mode 100644
    index 0000000..4a9842c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_config.py
    @@ -0,0 +1,228 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 os.path as op
    +import socket
    +
    +import splunktalib.modinput as modinput
    +import splunktalib.splunk_cluster as sc
    +from splunktalib.common import util
    +
    +import splunktaucclib.common.log as stulog
    +
    +from . import ta_consts as c
    +from . import ta_helper as th
    +
    +
    +# methods can be overrided by subclass : process_task_configs
    +class TaConfig:
    +    _current_hostname = socket.gethostname()
    +    _appname = util.get_appname_from_path(op.abspath(__file__))
    +
    +    def __init__(self, meta_config, client_schema, stanza_name=None, log_suffix=None):
    +        self._meta_config = meta_config
    +        self._stanza_name = stanza_name
    +        self._log_suffix = log_suffix
    +        if self._stanza_name and self._log_suffix:
    +            stulog.reset_logger(
    +                self._log_suffix
    +                + "_"
    +                + th.format_input_name_for_file(self._stanza_name)
    +            )
    +            stulog.logger.info(f"Start {self._stanza_name} task")
    +        self._task_configs = []
    +        self._client_schema = client_schema
    +        self._server_info = sc.ServerInfo(
    +            meta_config[c.server_uri], meta_config[c.session_key]
    +        )
    +        self._all_conf_contents = {}
    +        self._get_division_settings = {}
    +        self._load_task_configs()
    +        self._log_level = self._get_log_level()
    +
    +    def is_shc_but_not_captain(self):
    +        return self._server_info.is_shc_member() and not self._server_info.is_captain()
    +
    +    def get_meta_config(self):
    +        return self._meta_config
    +
    +    def get_task_configs(self):
    +        return self._task_configs
    +
    +    def get_all_conf_contents(self):
    +        return self._all_conf_contents
    +
    +    def get_divide_settings(self):
    +        return self._divide_settings
    +
    +    def get_log_level(self):
    +        return self._log_level
    +
    +    def _load_task_configs(self):
    +        config_handler = th.ConfigSchemaHandler(self._meta_config, self._client_schema)
    +        self._all_conf_contents = config_handler.get_all_conf_contents()
    +        self._divide_settings = config_handler.get_division_settings()
    +        assert self._divide_settings, "division is empty"
    +        self._generate_task_configs(self._all_conf_contents, self._divide_settings)
    +
    +    def _generate_task_configs(self, all_conf_contents, divide_settings):
    +        all_task_configs = list()
    +        for division_endpoint, divide_setting in divide_settings.items():
    +            task_configs = self._get_task_configs(
    +                all_conf_contents, division_endpoint, divide_setting
    +            )
    +            all_task_configs = all_task_configs + task_configs
    +
    +        for task_config in all_task_configs:
    +            task_config[c.use_kv_store] = task_config.get(c.use_kv_store, False)
    +            task_config[c.appname] = TaConfig._appname
    +            task_config[c.index] = task_config.get(c.index, "default")
    +            if self._server_info.is_shc_member():
    +                task_config[c.use_kv_store] = True
    +            stulog.logger.debug("Task info: %s", task_config)
    +        self.process_task_configs(all_task_configs)
    +        # interval
    +        for task_config in all_task_configs:
    +            assert task_config.get(c.interval), "task config has no interval " "field"
    +            task_config[c.interval] = int(task_config[c.interval])
    +            if task_config[c.interval] <= 0:
    +                raise ValueError(
    +                    "The interval value {} is invalid. It "
    +                    "should be a positive integer".format(task_config[c.interval])
    +                )
    +        self._task_configs = all_task_configs
    +        stulog.logger.info(f"Totally generated {len(self._task_configs)} task configs")
    +
    +    # Override this method if some transforms or validations needs to be done
    +    # before task_configs is exposed
    +    def process_task_configs(self, task_configs):
    +        if self._stanza_name:
    +            for task_config in task_configs:
    +                collection_interval = "collection_interval"
    +                task_config[c.interval] = task_config.get(collection_interval)
    +
    +    def _get_log_level(self):
    +        if not self._client_schema["basic"].get("config_meta"):
    +            return "INFO"
    +        if not self._client_schema["basic"]["config_meta"].get("logging_setting"):
    +            return "INFO"
    +        paths = self._client_schema["basic"]["config_meta"]["logging_setting"].split(
    +            ">"
    +        )
    +        global_setting = self.get_all_conf_contents()[paths[0].strip()]
    +        if not global_setting:
    +            return "INFO"
    +        log_level = self.get_all_conf_contents()
    +        for i in range(len(paths)):
    +            log_level = log_level[paths[i].strip()]
    +        if not log_level:
    +            return "INFO"
    +        else:
    +            return log_level
    +
    +    def _get_task_configs(self, all_conf_contents, division_endpoint, divide_setting):
    +        task_configs = list()
    +        orig_task_configs = all_conf_contents.get(division_endpoint)
    +        for (
    +            orig_task_config_stanza,
    +            orig_task_config_contents,
    +        ) in orig_task_configs.items():
    +            if util.is_true(orig_task_config_contents.get(c.disabled, False)):
    +                stulog.logger.debug("Stanza %s is disabled", orig_task_config_contents)
    +                continue
    +            orig_task_config_contents[c.divide_endpoint] = division_endpoint
    +            divide_tasks = self._divide_task_config(
    +                orig_task_config_stanza,
    +                orig_task_config_contents,
    +                divide_setting,
    +                all_conf_contents,
    +            )
    +            task_configs = task_configs + divide_tasks
    +        if self._stanza_name:
    +            for task_config in task_configs:
    +                if task_config[c.stanza_name] == self._stanza_name:
    +                    return [task_config]
    +        return task_configs
    +
    +    def _divide_task_config(
    +        self,
    +        task_config_stanza,
    +        task_config_contents,
    +        divide_setting,
    +        all_conf_contents,
    +    ):
    +        task_config = dict()
    +        task_config[c.stanza_name] = [self._get_stanza_name(task_config_stanza)]
    +        multi = 1
    +        for key, value in task_config_contents.items():
    +            task_config[key] = [value]
    +            for divide_rule in divide_setting:
    +                if divide_rule.metric() == key:
    +                    if divide_rule.type() == th.ConfigSchemaHandler.TYPE_MULTI:
    +                        task_config[key] = value.split(divide_rule.separator())
    +                        multi = multi * len(task_config[key])
    +        scale_task_config = {}
    +        times = 0
    +        for key, value in task_config.items():
    +            count = multi // len(value)
    +            scale_task_config[key] = value * count
    +            if len(value) == 1:
    +                continue
    +            times += 1
    +            if times % 2 == 0:
    +                scale_task_config[key].sort()
    +        return self._build_task_configs(
    +            scale_task_config, all_conf_contents, divide_setting, multi
    +        )
    +
    +    def _build_task_configs(
    +        self, raw_task_config, all_conf_contents, divide_setting, length
    +    ):
    +        task_configs = list()
    +        # split task configs
    +        for i in range(length):
    +            task_config = dict()
    +            # handle endpoint config
    +            for raw_key, raw_value in raw_task_config.items():
    +                value = raw_value[i]
    +                task_config[raw_key] = value
    +            # handle divide settings
    +            task_config[c.divide_key] = list()
    +            for divide_rule in divide_setting:
    +                task_config[c.divide_key].append(divide_rule.metric())
    +            task_config[c.divide_key].sort()
    +            task_configs.append(task_config)
    +        return task_configs
    +
    +    def _get_stanza_name(self, input_item):
    +        if isinstance(input_item, str):
    +            in_name = input_item
    +        else:
    +            in_name = input_item[c.name]
    +
    +        pos = in_name.find("://")
    +        if pos > 0:
    +            in_name = in_name[pos + 3 :]
    +        return in_name
    +
    +
    +def create_ta_config(settings, config_cls=TaConfig, log_suffix=None):
    +    meta_config, configs = modinput.get_modinput_configs_from_stdin()
    +    if configs and "://" in configs[0].get("name", ""):
    +        stanza_name = configs[0].get("name").split("://", 1)[1]
    +    else:
    +        stanza_name = None
    +    return config_cls(meta_config, settings, stanza_name, log_suffix)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_consts.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_consts.py
    new file mode 100644
    index 0000000..766bb62
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_consts.py
    @@ -0,0 +1,50 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +server_uri = "server_uri"
    +session_key = "session_key"
    +version = "version"
    +appname = "appname"
    +event_writer = "event_writer"
    +index = "index"
    +default_index = "default"
    +source = "source"
    +sourcetype = "sourcetype"
    +data_loader = "data_loader"
    +
    +meta_configs = "meta_configs"
    +disabled = "disabled"
    +resource = "resource"
    +events = "events"
    +scope = "scope"
    +checkpoint_dir = "checkpoint_dir"
    +
    +ckpt_dict = "ckpt_dict"
    +inputs = "inputs"
    +input_name = "input_name"
    +input_data = "input_data"
    +interval = "interval"
    +data = "data"
    +batch_size = "batch_size"
    +time_fmt = "%Y-%m-%dT%H:%M:%S"
    +utc_time_fmt = "%Y-%m-%dT%H:%M:%S.%fZ"
    +
    +use_kv_store = "use_kv_store"
    +name = "name"
    +config = "config"
    +division = "division"
    +stanza_name = "stanza_name"
    +divide_key = "_divide_key"
    +divide_endpoint = "_divide_endpoint"
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_data_client.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_data_client.py
    new file mode 100644
    index 0000000..2f259aa
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_data_client.py
    @@ -0,0 +1,108 @@
    +#!/usr/bin/python
    +
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 splunktaucclib.data_collection.ta_data_collector as tdc
    +from splunktaucclib.data_collection import ta_checkpoint_manager as cp
    +
    +
    +def build_event(
    +    host=None,
    +    source=None,
    +    sourcetype=None,
    +    time=None,
    +    index=None,
    +    raw_data="",
    +    is_unbroken=False,
    +    is_done=False,
    +):
    +    if is_unbroken is False and is_done is True:
    +        raise Exception("is_unbroken=False is_done=True is invalid")
    +    return tdc.event_tuple._make(
    +        [host, source, sourcetype, time, index, raw_data, is_unbroken, is_done]
    +    )
    +
    +
    +class TaDataClient:
    +    def __init__(
    +        self,
    +        all_conf_contents,
    +        meta_config,
    +        task_config,
    +        ckpt=None,
    +        checkpoint_mgr=None,
    +    ):
    +        self._all_conf_contents = all_conf_contents
    +        self._meta_config = meta_config
    +        self._task_config = task_config
    +        self._checkpoint_mgr = checkpoint_mgr
    +        self._ckpt = ckpt or {}
    +        self._stop = False
    +
    +    def is_stopped(self):
    +        return self._stop
    +
    +    def stop(self):
    +        self._stop = True
    +
    +    def get(self):
    +        raise StopIteration
    +
    +
    +def create_data_collector(
    +    dataloader, tconfig, meta_configs, task_config, data_client_cls, checkpoint_cls=None
    +):
    +    checkpoint_manager_cls = checkpoint_cls or cp.TACheckPointMgr
    +    return tdc.TADataCollector(
    +        tconfig,
    +        meta_configs,
    +        task_config,
    +        checkpoint_manager_cls,
    +        data_client_cls,
    +        dataloader,
    +    )
    +
    +
    +def client_adapter(job_func):
    +    class TaDataClientAdapter(TaDataClient):
    +        def __init__(self, all_conf_contents, meta_config, task_config, ckpt, chp_mgr):
    +            super().__init__(all_conf_contents, meta_config, task_config, ckpt, chp_mgr)
    +            self._execute_times = 0
    +            self._gen = job_func(self._all_conf_contents, self._task_config, self._ckpt)
    +
    +        def stop(self):
    +            """
    +            overwrite to handle stop control command
    +            """
    +
    +            # normaly base class just set self._stop as True
    +            super().stop()
    +
    +        def get(self):
    +            """
    +            overwrite to get events
    +            """
    +            self._execute_times += 1
    +            if self.is_stopped():
    +                # send stop signal
    +                self._gen.send(self.is_stopped())
    +                raise StopIteration
    +            if self._execute_times == 1:
    +                return next(self._gen)
    +            return self._gen.send(self.is_stopped())
    +
    +    return TaDataClientAdapter
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_data_collector.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_data_collector.py
    new file mode 100644
    index 0000000..372eff0
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_data_collector.py
    @@ -0,0 +1,245 @@
    +#!/usr/bin/python
    +
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 threading
    +import time
    +from collections import namedtuple
    +
    +import splunktaucclib.common.log as stulog
    +
    +from . import ta_consts as c
    +
    +
    +def _escape(data):
    +    """Escape &, <, and > in a string of data."""
    +    # must do ampersand first
    +    data = data.replace("&", "&amp;")
    +    data = data.replace(">", "&gt;")
    +    data = data.replace("<", "&lt;")
    +    return data
    +
    +
    +evt_fmt = (
    +    "<stream><event><host>{0}</host>"
    +    "<source><![CDATA[{1}]]></source>"
    +    "<sourcetype><![CDATA[{2}]]></sourcetype>"
    +    "<time>{3}</time>"
    +    "<index>{4}</index><data>"
    +    "{5}</data></event></stream>"
    +)
    +
    +unbroken_evt_fmt = (
    +    "<stream>"
    +    '<event unbroken="1">'
    +    "<host>{0}</host>"
    +    "<source><![CDATA[{1}]]></source>"
    +    "<sourcetype><![CDATA[{2}]]></sourcetype>"
    +    "<time>{3}</time>"
    +    "<index>{4}</index>"
    +    "<data>{5}</data>"
    +    "{6}"
    +    "</event>"
    +    "</stream>"
    +)
    +
    +event_tuple = namedtuple(
    +    "Event",
    +    [
    +        "host",
    +        "source",
    +        "sourcetype",
    +        "time",
    +        "index",
    +        "raw_data",
    +        "is_unbroken",
    +        "is_done",
    +    ],
    +)
    +
    +
    +class TADataCollector:
    +    def __init__(
    +        self,
    +        tconfig,
    +        meta_config,
    +        task_config,
    +        checkpoint_manager_cls,
    +        data_client_cls,
    +        data_loader,
    +    ):
    +        self._lock = threading.Lock()
    +        self._ta_config = tconfig
    +        self._meta_config = meta_config
    +        self._task_config = task_config
    +        self._stopped = True
    +        self._p = self._get_logger_prefix()
    +        self._checkpoint_manager = checkpoint_manager_cls(meta_config, task_config)
    +        self.data_client_cls = data_client_cls
    +        self._data_loader = data_loader
    +        self._client = None
    +
    +    def get_meta_configs(self):
    +        return self._meta_config
    +
    +    def get_task_config(self):
    +        return self._task_config
    +
    +    def get_interval(self):
    +        return self._task_config[c.interval]
    +
    +    def _get_logger_prefix(self):
    +        pairs = [f'{c.stanza_name}="{self._task_config[c.stanza_name]}"']
    +        for key in self._task_config[c.divide_key]:
    +            pairs.append(f'{key}="{self._task_config[key]}"')
    +        return "[{}]".format(" ".join(pairs))
    +
    +    def stop(self):
    +        self._stopped = True
    +        if self._client:
    +            self._client.stop()
    +
    +    def __call__(self):
    +        self.index_data()
    +
    +    def _build_event(self, events):
    +        if not events:
    +            return None
    +        if not isinstance(events, list):
    +            events = [events]
    +        evts = []
    +        for event in events:
    +            assert event.raw_data, "the raw data of events is empty"
    +            if event.is_unbroken:
    +                evt = unbroken_evt_fmt.format(
    +                    event.host or "",
    +                    event.source or "",
    +                    event.sourcetype or "",
    +                    event.time or "",
    +                    event.index or "",
    +                    _escape(event.raw_data),
    +                    "<done/>" if event.is_done else "",
    +                )
    +            else:
    +                evt = evt_fmt.format(
    +                    event.host or "",
    +                    event.source or "",
    +                    event.sourcetype or "",
    +                    event.time or "",
    +                    event.index or "",
    +                    _escape(event.raw_data),
    +                )
    +            evts.append(evt)
    +        return evts
    +
    +    def _get_ckpt(self):
    +        return self._checkpoint_manager.get_ckpt()
    +
    +    def _get_ckpt_key(self):
    +        return self._checkpoint_manager.get_ckpt_key()
    +
    +    def _update_ckpt(self, ckpt):
    +        return self._checkpoint_manager.update_ckpt(ckpt)
    +
    +    def _create_data_client(self):
    +        ckpt = self._get_ckpt()
    +        data_client = self.data_client_cls(
    +            self._ta_config.get_all_conf_contents(),
    +            self._meta_config,
    +            self._task_config,
    +            ckpt,
    +            self._checkpoint_manager,
    +        )
    +
    +        stulog.logger.debug(f"{self._p} Set {c.ckpt_dict}={ckpt} ")
    +        return data_client
    +
    +    def index_data(self):
    +        if self._lock.locked():
    +            stulog.logger.debug(
    +                "Last round of stanza={} is not done yet".format(
    +                    self._task_config[c.stanza_name]
    +                )
    +            )
    +            return
    +        with self._lock:
    +            self._stopped = False
    +            checkpoint_key = self._get_ckpt_key()
    +            stulog.logger.info(
    +                "{} Start indexing data for checkpoint_key={"
    +                "}".format(self._p, checkpoint_key)
    +            )
    +            try:
    +
    +                self._do_safe_index()
    +            except Exception:
    +                stulog.logger.exception(f"{self._p} Failed to index data")
    +            stulog.logger.info(
    +                "{} End of indexing data for checkpoint_key={}".format(
    +                    self._p, checkpoint_key
    +                )
    +            )
    +
    +    def _write_events(self, ckpt, events):
    +        evts = self._build_event(events)
    +        if evts:
    +            if not self._data_loader.write_events(evts):
    +                stulog.logger.info(
    +                    "{} the event queue is closed and the "
    +                    "received data will be discarded".format(self._p)
    +                )
    +                return False
    +        if ckpt is None:
    +            return True
    +        for i in range(3):
    +            try:
    +                self._update_ckpt(ckpt)
    +            except Exception:
    +                stulog.logger.exception(
    +                    "{} Failed to update ckpt {} to {}".format(
    +                        self._p, self._get_ckpt_key(), ckpt
    +                    )
    +                )
    +                time.sleep(2)
    +                continue
    +            else:
    +                return True
    +        # write checkpoint fail
    +        self.stop()
    +        return False
    +
    +    def _do_safe_index(self):
    +        self._client = self._create_data_client()
    +        while not self._stopped:
    +            try:
    +                events, ckpt = self._client.get()
    +                if not events and not ckpt:
    +                    continue
    +                else:
    +                    if not self._write_events(ckpt, events):
    +                        break
    +            except StopIteration:
    +                stulog.logger.debug(f"{self._p} Finished this round")
    +                break
    +            except Exception:
    +                stulog.logger.exception(f"{self._p} Failed to get msg")
    +                break
    +        self.stop()
    +        try:
    +            self._client.get()
    +        except StopIteration:
    +            stulog.logger.debug(f"{self._p} Invoke client.get() after stop ")
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_data_loader.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_data_loader.py
    new file mode 100644
    index 0000000..c2b17bd
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_data_loader.py
    @@ -0,0 +1,178 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +Data Loader main entry point
    +"""
    +
    +
    +import configparser
    +import os.path as op
    +import queue
    +
    +import splunktalib.concurrent.concurrent_executor as ce
    +import splunktalib.schedule.job as sjob
    +import splunktalib.timer_queue as tq
    +from splunktalib.common import log
    +
    +
    +class TADataLoader:
    +    """
    +    Data Loader boots all underlying facilities to handle data collection
    +    """
    +
    +    def __init__(self, meta_configs, job_scheduler, event_writer):
    +        """
    +        @configs: a list like object containing a list of dict
    +        like object. Each element shall implement dict.get/[] like interfaces
    +        to get the value for a key.
    +        @job_scheduler: schedulering the jobs. shall implement get_ready_jobs
    +        @event_writer: write_events
    +        """
    +
    +        self._settings = self._read_default_settings()
    +        self._settings["daemonize_thread"] = False
    +        self._meta_configs = meta_configs
    +        self._event_writer = event_writer
    +        self._wakeup_queue = queue.Queue()
    +        self._scheduler = job_scheduler
    +        self._timer_queue = tq.TimerQueue()
    +        self._executor = ce.ConcurrentExecutor(self._settings)
    +        self._started = False
    +
    +    def run(self, jobs):
    +        if self._started:
    +            return
    +        self._started = True
    +
    +        self._event_writer.start()
    +        self._executor.start()
    +        self._timer_queue.start()
    +        self._scheduler.start()
    +        log.logger.info("TADataLoader started.")
    +
    +        def _enqueue_io_job(job):
    +            job_props = job.get_props()
    +            real_job = job_props["real_job"]
    +            self.run_io_jobs((real_job,))
    +
    +        for job in jobs:
    +            j = sjob.Job(_enqueue_io_job, {"real_job": job}, job.get_interval())
    +            self._scheduler.add_jobs((j,))
    +
    +        self._wait_for_tear_down()
    +
    +        for job in jobs:
    +            job.stop()
    +
    +        self._scheduler.tear_down()
    +        self._timer_queue.tear_down()
    +        self._executor.tear_down()
    +        self._event_writer.tear_down()
    +        log.logger.info("DataLoader stopped.")
    +
    +    def _wait_for_tear_down(self):
    +        wakeup_q = self._wakeup_queue
    +        while 1:
    +            try:
    +                go_exit = wakeup_q.get(timeout=1)
    +            except queue.Empty:
    +                pass
    +            else:
    +                if go_exit:
    +                    log.logger.info("DataLoader got stop signal")
    +                    self._stopped = True
    +                    break
    +
    +    def tear_down(self):
    +        self._wakeup_queue.put(True)
    +        log.logger.info("DataLoader is going to stop.")
    +
    +    def stopped(self):
    +        return self._stopped
    +
    +    def run_io_jobs(self, jobs, block=True):
    +        self._executor.enqueue_io_funcs(jobs, block)
    +
    +    def run_compute_job(self, func, args=(), kwargs={}):
    +        self._executor.run_compute_func_sync(func, args, kwargs)
    +
    +    def run_compute_job_async(self, func, args=(), kwargs={}, callback=None):
    +        """
    +        @return: AsyncResult
    +        """
    +
    +        return self._executor.run_compute_func_async(func, args, kwargs, callback)
    +
    +    def add_timer(self, callback, when, interval):
    +        return self._timer_queue.add_timer(callback, when, interval)
    +
    +    def remove_timer(self, timer):
    +        self._timer_queue.remove_timer(timer)
    +
    +    def write_events(self, events):
    +        return self._event_writer.write_events(events)
    +
    +    @staticmethod
    +    def _read_default_settings():
    +        cur_dir = op.dirname(op.abspath(__file__))
    +        setting_file = op.join(cur_dir, "../../", "splunktalib", "setting.conf")
    +        parser = configparser.ConfigParser()
    +        parser.read(setting_file)
    +        settings = {}
    +        keys = ("process_size", "thread_min_size", "thread_max_size", "task_queue_size")
    +        for option in keys:
    +            try:
    +                settings[option] = parser.get("global", option)
    +            except configparser.NoOptionError:
    +                settings[option] = -1
    +
    +            try:
    +                settings[option] = int(settings[option])
    +            except ValueError:
    +                settings[option] = -1
    +        log.logger.debug("settings: %s", settings)
    +        return settings
    +
    +
    +class GlobalDataLoader:
    +    """Singleton, inited when started"""
    +
    +    __instance = None
    +
    +    @staticmethod
    +    def get_data_loader(meta_configs, scheduler, writer):
    +        if GlobalDataLoader.__instance is None:
    +            GlobalDataLoader.__instance = TADataLoader(meta_configs, scheduler, writer)
    +        return GlobalDataLoader.__instance
    +
    +    @staticmethod
    +    def reset():
    +        GlobalDataLoader.__instance = None
    +
    +
    +def create_data_loader(meta_configs):
    +    """
    +    create a data loader with default event_writer, job_scheudler
    +    """
    +
    +    import splunktalib.event_writer as ew
    +    import splunktalib.schedule.scheduler as sched
    +
    +    writer = ew.EventWriter()
    +    scheduler = sched.Scheduler()
    +    loader = GlobalDataLoader.get_data_loader(meta_configs, scheduler, writer)
    +    return loader
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_helper.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_helper.py
    new file mode 100644
    index 0000000..2baec18
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_helper.py
    @@ -0,0 +1,169 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 hashlib
    +import json
    +import os.path as op
    +import re
    +from calendar import timegm
    +from datetime import datetime
    +
    +from splunktalib.common import util
    +
    +import splunktaucclib.config as sc
    +from splunktaucclib.data_collection import ta_consts as c
    +
    +
    +def utc2timestamp(human_time):
    +    regex1 = r"\d{4}-\d{2}-\d{2}.\d{2}:\d{2}:\d{2}"
    +    match = re.search(regex1, human_time)
    +    if match:
    +        formated = match.group()
    +    else:
    +        return None
    +
    +    strped_time = datetime.strptime(formated, c.time_fmt)
    +    timestamp = timegm(strped_time.utctimetuple())
    +
    +    regex2 = r"\d{4}-\d{2}-\d{2}.\d{2}:\d{2}:\d{2}(\.\d+)"
    +    match = re.search(regex2, human_time)
    +    if match:
    +        timestamp += float(match.group(1))
    +    else:
    +        timestamp += float("0.000000")
    +    return timestamp
    +
    +
    +def get_md5(data):
    +    """
    +    function name is not change, actually use sha1 instead
    +    :param data:
    +    :return:
    +    """
    +    assert data is not None, "The input cannot be None"
    +    string_type = isinstance(data, str)
    +    if string_type:
    +        return hashlib.sha256(data.encode("utf-8")).hexdigest()
    +    elif isinstance(data, (list, tuple, dict)):
    +        return hashlib.sha256(json.dumps(data).encode("utf-8")).hexdigest()
    +
    +
    +def format_input_name_for_file(name):
    +    import base64
    +
    +    base64_name = base64.b64encode(name.encode("utf-8"), b"__").decode("ascii")
    +    qualified_name_str = re.sub(r"[^a-zA-Z0-9]+", "_", name)
    +    return f"{qualified_name_str}_B64_{base64_name}"
    +
    +
    +class ConfigSchemaHandler:
    +    _app_name = util.get_appname_from_path(op.abspath(__file__))
    +    # Division schema keys.
    +    TYPE = "type"
    +
    +    TYPE_SINGLE = "single"
    +    TYPE_MULTI = "multi"
    +    REFER = "refer"
    +    SEPARATOR = "separator"
    +
    +    def __init__(self, meta_configs, client_schema):
    +        self._config = sc.Config(
    +            splunkd_uri=meta_configs[c.server_uri],
    +            session_key=meta_configs[c.session_key],
    +            schema=json.dumps(client_schema[c.config]),
    +            user="nobody",
    +            app=ConfigSchemaHandler._app_name,
    +        )
    +        self._client_schema = client_schema
    +        self._all_conf_contents = {}
    +        self._load_conf_contents()
    +        self._division_settings = self._divide_settings()
    +
    +    def get_endpoints(self):
    +        return self._config.get_endpoints()
    +
    +    def get_all_conf_contents(self):
    +        return self._all_conf_contents
    +
    +    def get_single_conf_contents(self, endpoint):
    +        return self._all_conf_contents.get(endpoint)
    +
    +    def get_division_settings(self):
    +        return self._division_settings
    +
    +    def _divide_settings(self):
    +        division_schema = self._client_schema[c.division]
    +        division_settings = dict()
    +        for division_endpoint, division_contents in division_schema.items():
    +            division_settings[division_endpoint] = self._process_division(
    +                division_endpoint, division_contents
    +            )
    +        return division_settings
    +
    +    def _load_conf_contents(self):
    +        self._all_conf_contents = self._config.load()
    +
    +    def _process_division(self, division_endpoint, division_contents):
    +        division_metrics = []
    +        assert isinstance(division_contents, dict)
    +        for division_key, division_value in division_contents.items():
    +            try:
    +                assert (
    +                    self.TYPE in division_value
    +                    and division_value[self.TYPE] in [self.TYPE_SINGLE, self.TYPE_MULTI]
    +                    and self.SEPARATOR in division_value
    +                    if division_value[self.TYPE] == self.TYPE_MULTI
    +                    else True
    +                )
    +            except Exception:
    +                raise Exception("Invalid division schema")
    +            division_metrics.append(
    +                DivisionRule(
    +                    division_endpoint,
    +                    division_key,
    +                    division_value[self.TYPE],
    +                    division_value.get(
    +                        self.SEPARATOR,
    +                    ),
    +                    division_value.get(
    +                        self.REFER,
    +                    ),
    +                )
    +            )
    +        return division_metrics
    +
    +
    +class DivisionRule:
    +    def __init__(self, endpoint, metric, type, separator, refer):
    +        self._endpoint = endpoint
    +        self._metric = metric
    +        self._type = type
    +        self._separator = separator
    +        self._refer = refer
    +
    +    def endpoint(self):
    +        return self._endpoint
    +
    +    def metric(self):
    +        return self._metric
    +
    +    def type(self):
    +        return self._type
    +
    +    def separator(self):
    +        return self._separator
    +
    +    def refer(self):
    +        return self._refer
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_mod_input.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_mod_input.py
    new file mode 100644
    index 0000000..7cc52c3
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/data_collection/ta_mod_input.py
    @@ -0,0 +1,235 @@
    +#!/usr/bin/python
    +
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +This is the main entry point for My TA
    +"""
    +
    +import os.path as op
    +import sys
    +import time
    +
    +import splunktalib.common.util as utils
    +import splunktalib.file_monitor as fm
    +import splunktalib.modinput as modinput
    +import splunktalib.orphan_process_monitor as opm
    +
    +import splunktaucclib.common.log as stulog
    +from splunktaucclib.common import load_schema_file as ld
    +from splunktaucclib.data_collection import ta_checkpoint_manager as cpmgr
    +from splunktaucclib.data_collection import ta_config as tc
    +from splunktaucclib.data_collection import ta_data_client as tdc
    +from splunktaucclib.data_collection import ta_data_loader as dl
    +
    +utils.remove_http_proxy_env_vars()
    +
    +
    +def do_scheme(ta_short_name, ta_name, schema_para_list=None, single_instance=True):
    +    """
    +    Feed splunkd the TA's scheme
    +
    +    """
    +    param_str = ""
    +    builtsin_names = {"name", "index", "sourcetype", "host", "source", "disabled"}
    +
    +    schema_para_list = schema_para_list or ()
    +    for param in schema_para_list:
    +        if param in builtsin_names:
    +            continue
    +        param_str += """<arg name="{param}">
    +          <title>{param}</title>
    +          <required_on_create>0</required_on_create>
    +          <required_on_edit>0</required_on_edit>
    +        </arg>""".format(
    +            param=param
    +        )
    +
    +    print(
    +        """
    +    <scheme>
    +    <title>Splunk Add-on for {ta_short_name}</title>
    +    <description>Enable data inputs for {ta_name}</description>
    +    <use_external_validation>true</use_external_validation>
    +    <streaming_mode>xml</streaming_mode>
    +    <use_single_instance>{}</use_single_instance>
    +    <endpoint>
    +      <args>
    +        <arg name="name">
    +          <title>{ta_name} Data Input Name</title>
    +        </arg>
    +        {param_str}
    +      </args>
    +    </endpoint>
    +    </scheme>
    +    """.format(
    +            (str(single_instance)).lower(),
    +            ta_short_name=ta_short_name,
    +            ta_name=ta_name,
    +            param_str=param_str,
    +        )
    +    )
    +
    +
    +def _setup_signal_handler(data_loader, ta_short_name):
    +    """
    +    Setup signal handlers
    +    :data_loader: data_loader.DataLoader instance
    +    """
    +
    +    def _handle_exit(signum, frame):
    +        stulog.logger.info(f"{ta_short_name} receives exit signal")
    +        if data_loader is not None:
    +            data_loader.tear_down()
    +
    +    utils.handle_tear_down_signals(_handle_exit)
    +
    +
    +def _handle_file_changes(data_loader):
    +    """
    +    :reload conf files and exit
    +    """
    +
    +    def _handle_refresh(changed_files):
    +        stulog.logger.info(f"Detect {changed_files} changed, reboot itself")
    +        data_loader.tear_down()
    +
    +    return _handle_refresh
    +
    +
    +def _get_conf_files(local_file_list):
    +    cur_dir = op.dirname(op.dirname(op.dirname(op.dirname(op.abspath(__file__)))))
    +    files = []
    +    for f in local_file_list:
    +        files.append(op.join(cur_dir, "local", f))
    +    return files
    +
    +
    +def run(collector_cls, settings, checkpoint_cls=None, config_cls=None, log_suffix=None):
    +    """
    +    Main loop. Run this TA forever
    +    """
    +    # This is for stdout flush
    +    utils.disable_stdout_buffer()
    +
    +    # http://bugs.python.org/issue7980
    +    time.strptime("2016-01-01", "%Y-%m-%d")
    +
    +    tconfig = tc.create_ta_config(settings, config_cls or tc.TaConfig, log_suffix)
    +    stulog.set_log_level(tconfig.get_log_level())
    +    task_configs = tconfig.get_task_configs()
    +
    +    if not task_configs:
    +        stulog.logger.debug("No task and exiting...")
    +        return
    +    meta_config = tconfig.get_meta_config()
    +
    +    loader = dl.create_data_loader(meta_config)
    +
    +    jobs = [
    +        tdc.create_data_collector(
    +            loader,
    +            tconfig,
    +            meta_config,
    +            task_config,
    +            collector_cls,
    +            checkpoint_cls=checkpoint_cls or cpmgr.TACheckPointMgr,
    +        )
    +        for task_config in task_configs
    +    ]
    +
    +    # handle signal
    +    _setup_signal_handler(loader, settings["basic"]["title"])
    +
    +    # monitor files to reboot
    +    if settings["basic"].get("monitor_file"):
    +        monitor = fm.FileMonitor(
    +            _handle_file_changes(loader),
    +            _get_conf_files(settings["basic"]["monitor_file"]),
    +        )
    +        loader.add_timer(monitor.check_changes, time.time(), 10)
    +
    +    # add orphan process handling, which will check each 1 second
    +    orphan_checker = opm.OrphanProcessChecker(loader.tear_down)
    +    loader.add_timer(orphan_checker.check_orphan, time.time(), 1)
    +
    +    loader.run(jobs)
    +
    +
    +def validate_config():
    +    """
    +    Validate inputs.conf
    +    """
    +
    +    _, configs = modinput.get_modinput_configs_from_stdin()
    +    return 0
    +
    +
    +def usage():
    +    """
    +    Print usage of this binary
    +    """
    +
    +    hlp = "%s --scheme|--validate-arguments|-h"
    +    print(hlp % sys.argv[0], file=sys.stderr)
    +    sys.exit(1)
    +
    +
    +def main(
    +    collector_cls,
    +    schema_file_path,
    +    log_suffix="modinput",
    +    checkpoint_cls=None,
    +    configer_cls=None,
    +    schema_para_list=None,
    +    single_instance=True,
    +):
    +    """
    +    Main entry point
    +    """
    +    assert collector_cls, "ucc modinput collector is None."
    +    assert schema_file_path, "ucc modinput schema file is None"
    +
    +    stulog.reset_logger(log_suffix)
    +    settings = ld(schema_file_path)
    +    ta_short_name = settings["basic"]["title"]
    +    ta_desc = settings["basic"]["description"]
    +
    +    args = sys.argv
    +    if len(args) > 1:
    +        if args[1] == "--scheme":
    +            do_scheme(ta_short_name, ta_desc, schema_para_list, single_instance)
    +        elif args[1] == "--validate-arguments":
    +            sys.exit(validate_config())
    +        elif args[1] in ("-h", "--h", "--help"):
    +            usage()
    +        else:
    +            usage()
    +    else:
    +        stulog.logger.info(f"Start {ta_short_name} task")
    +        try:
    +            run(
    +                collector_cls,
    +                settings,
    +                checkpoint_cls=checkpoint_cls,
    +                config_cls=configer_cls,
    +                log_suffix=log_suffix,
    +            )
    +        except Exception as e:
    +            stulog.logger.exception(f"{ta_short_name} task encounter exception")
    +        stulog.logger.info(f"End {ta_short_name} task")
    +    sys.exit(0)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/global_config/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/global_config/__init__.py
    new file mode 100644
    index 0000000..193cb2c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/global_config/__init__.py
    @@ -0,0 +1,80 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +Global Config Module
    +"""
    +
    +
    +import urllib.parse
    +
    +from solnlib.splunk_rest_client import SplunkRestClient
    +
    +from .configuration import Configs, Configuration, GlobalConfigError, Inputs, Settings
    +from .schema import GlobalConfigSchema
    +
    +__all__ = [
    +    "GlobalConfigError",
    +    "GlobalConfigSchema",
    +    "GlobalConfig",
    +    "Inputs",
    +    "Configs",
    +    "Settings",
    +]
    +
    +
    +class GlobalConfig:
    +    def __init__(self, splunkd_uri, session_key, schema):
    +        """
    +        Global Config.
    +
    +        :param splunkd_uri:
    +        :param session_key:
    +        :param schema:
    +        :type schema: GlobalConfigSchema
    +        """
    +        self._splunkd_uri = splunkd_uri
    +        self._session_key = session_key
    +        self._schema = schema
    +
    +        splunkd_info = urllib.parse.urlparse(self._splunkd_uri)
    +        self._client = SplunkRestClient(
    +            self._session_key,
    +            self._schema.product,
    +            scheme=splunkd_info.scheme,
    +            host=splunkd_info.hostname,
    +            port=splunkd_info.port,
    +        )
    +        self._configuration = Configuration(self._client, self._schema)
    +        self._inputs = Inputs(self._client, self._schema)
    +        self._configs = Configs(self._client, self._schema)
    +        self._settings = Settings(self._client, self._schema)
    +
    +    @property
    +    def inputs(self):
    +        return self._inputs
    +
    +    @property
    +    def configs(self):
    +        return self._configs
    +
    +    @property
    +    def settings(self):
    +        return self._settings
    +
    +    # add support for batch save of configuration payload
    +    def save(self, payload):
    +        return self._configuration.save(payload)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/global_config/configuration.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/global_config/configuration.py
    new file mode 100644
    index 0000000..7ecf109
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/global_config/configuration.py
    @@ -0,0 +1,389 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 copy
    +import json
    +from multiprocessing.pool import ThreadPool
    +
    +from splunklib.binding import HTTPError
    +
    +from ..rest_handler.handler import RestHandler
    +from ..rest_handler.schema import RestSchema
    +
    +__all__ = [
    +    "GlobalConfigError",
    +    "Configuration",
    +    "Inputs",
    +    "Configs",
    +    "Settings",
    +]
    +
    +
    +class GlobalConfigError(Exception):
    +    pass
    +
    +
    +class Configuration:
    +    """
    +    Splunk Configuration Handler.
    +    """
    +
    +    FILTERS = ["eai:appName", "eai:acl", "eai:userName"]
    +    ENTITY_NAME = "name"
    +    SETTINGS = "settings"
    +    NOT_FOUND = "[404]: Not Found"
    +
    +    def __init__(self, splunkd_client, schema):
    +        """
    +
    +        :param splunkd_client: SplunkRestClient
    +        :param schema:
    +        """
    +        self._client = splunkd_client
    +        self._schema = schema
    +
    +    def load(self, *args, **kwargs):
    +        """
    +        Load all stored configuration for given schema.
    +
    +        :param args:
    +        :param kwargs:
    +        :return:
    +        """
    +        raise NotImplementedError()
    +
    +    def save_stanza(self, item):
    +        """
    +        Save configuration with type_name and configuration
    +
    +        :param item:
    +        :return: error while save the configuration
    +        """
    +        return self._save_configuration(item[0], item[1])
    +
    +    def save(self, payload):
    +        """
    +        Save configuration. Return error while saving.
    +        It includes creating and updating. That is, it will try to
    +        update first, then create if NOT FOUND error occurs.
    +
    +        :param payload: same format with return of ``load``.
    +        :return:
    +
    +        Usage::
    +        >>> from splunktaucclib.global_config import GlobalConfig
    +        >>> global_config = GlobalConfig()
    +        >>> payload = {
    +        >>>    'settings': [
    +        >>>        {
    +        >>>            'name': 'proxy',
    +        >>>            'proxy_host': '1.2.3.4',
    +        >>>            'proxy_port': '5678',
    +        >>>        },
    +        >>>        {
    +        >>>            'name': 'logging',
    +        >>>            'level': 'DEBUG',
    +        >>>        }
    +        >>>    ]
    +        >>> }
    +        >>> global_config.settings.save(payload)
    +        """
    +        # expand the payload to task_list
    +        task_list = []
    +        for type_name, configurations in payload.items():
    +            task_list.extend(
    +                [(type_name, configuration) for configuration in configurations]
    +            )
    +        task_len = len(task_list)
    +        # return empty error list if task list is empty
    +        if not task_list:
    +            return []
    +        task_len = min(8, task_len)
    +        pool = ThreadPool(processes=task_len)
    +        errors = pool.map(self.save_stanza, task_list)
    +        pool.close()
    +        pool.join()
    +        return errors
    +
    +    @property
    +    def internal_schema(self):
    +        """
    +        Get the schema for inputs, configs and settings
    +
    +        :return:
    +        """
    +        return self._schema.inputs + self._schema.configs + self._schema.settings
    +
    +    def _save_configuration(self, type_name, configuration):
    +        schema = self._search_configuration_schema(
    +            type_name,
    +            configuration[self.ENTITY_NAME],
    +        )
    +        configuration = copy.copy(configuration)
    +        self._dump_multiple_select(configuration, schema)
    +
    +        # update
    +        try:
    +            self._update(type_name, copy.copy(configuration))
    +        except HTTPError as exc:
    +            if self.NOT_FOUND in str(exc):
    +                # not exists, go to create
    +                pass
    +            else:
    +                return exc
    +        except Exception as exc:
    +            return exc
    +        else:
    +            return None
    +
    +        # create
    +        try:
    +            self._create(type_name, configuration)
    +        except Exception as exc:
    +            return exc
    +        else:
    +            return None
    +
    +    def _create(self, type_name, configuration):
    +        self._save_endpoint(
    +            type_name,
    +            configuration,
    +        )
    +
    +    def _update(self, type_name, configuration):
    +        name = configuration[self.ENTITY_NAME]
    +        del configuration[self.ENTITY_NAME]
    +        self._save_endpoint(
    +            type_name,
    +            configuration,
    +            name=name,
    +        )
    +
    +    @classmethod
    +    def _filter_fields(cls, entity):
    +        for (k, v) in list(entity.items()):
    +            if k in cls.FILTERS:
    +                del entity[k]
    +
    +    def _load_endpoint(self, name, schema):
    +        query = {
    +            "output_mode": "json",
    +            "count": "0",
    +            "--cred--": "1",
    +        }
    +        response = self._client.get(
    +            RestHandler.path_segment(self._endpoint_path(name)), **query
    +        )
    +        body = response.body.read()
    +        cont = json.loads(body)
    +
    +        entities = []
    +        for entry in cont["entry"]:
    +            entity = entry["content"]
    +            entity[self.ENTITY_NAME] = entry["name"]
    +            self._load_multiple_select(entity, schema)
    +            entities.append(entity)
    +        return entities
    +
    +    def _save_endpoint(self, endpoint, content, name=None):
    +        endpoint = self._endpoint_path(endpoint)
    +        self._client.post(RestHandler.path_segment(endpoint, name=name), **content)
    +
    +    @classmethod
    +    def _load_multiple_select(cls, entity, schema):
    +        for field in schema:
    +            field_type = field.get("type")
    +            value = entity.get(field["field"])
    +            if field_type != "multipleSelect" or not value:
    +                continue
    +            delimiter = field["options"]["delimiter"]
    +            entity[field["field"]] = value.split(delimiter)
    +
    +    @classmethod
    +    def _dump_multiple_select(cls, entity, schema):
    +        for field in schema:
    +            field_type = field.get("type")
    +            value = entity.get(field["field"])
    +            if field_type != "multipleSelect" or not value:
    +                continue
    +            if not isinstance(value, list):
    +                continue
    +            delimiter = field["options"]["delimiter"]
    +            entity[field["field"]] = delimiter.join(value)
    +
    +    def _endpoint_path(self, name):
    +        return "{admin_match}/{endpoint_name}".format(
    +            admin_match=self._schema.admin_match,
    +            endpoint_name=RestSchema.endpoint_name(name, self._schema.namespace),
    +        )
    +
    +    def _search_configuration_schema(self, type_name, configuration_name):
    +        for item in self.internal_schema:
    +            # add support for settings schema
    +            if item["name"] == type_name or (
    +                type_name == self.SETTINGS and item["name"] == configuration_name
    +            ):
    +                return item["entity"]
    +        else:
    +            raise GlobalConfigError(
    +                "Schema Not Found for Configuration, "
    +                "configuration_type={configuration_type}, "
    +                "configuration_name={configuration_name}".format(
    +                    configuration_type=type_name,
    +                    configuration_name=configuration_name,
    +                ),
    +            )
    +
    +
    +class Inputs(Configuration):
    +    def __init__(self, splunkd_client, schema):
    +        super().__init__(splunkd_client, schema)
    +        self._splunkd_client = splunkd_client
    +        self._schema = schema
    +        self._references = None
    +
    +    def load(self, input_type=None):
    +        """
    +
    +        :param input_type:
    +        :return:
    +
    +        Usage::
    +        >>> from splunktaucclib.global_config import GlobalConfig
    +        >>> global_config = GlobalConfig()
    +        >>> inputs = global_config.inputs.load()
    +        """
    +        # move configs read operation out of init method
    +        if not self._references:
    +            self._references = Configs(self._splunkd_client, self._schema).load()
    +        inputs = {}
    +        for input_item in self.internal_schema:
    +            if input_type is None or input_item["name"] == input_type:
    +                input_entities = self._load_endpoint(
    +                    input_item["name"], input_item["entity"]
    +                )
    +                # filter unused fields in response
    +                for input_entity in input_entities:
    +                    self._filter_fields(input_entity)
    +                # expand referenced entity
    +                self._reference(
    +                    input_entities,
    +                    input_item,
    +                    self._references,
    +                )
    +                inputs[input_item["name"]] = input_entities
    +        return inputs
    +
    +    @property
    +    def internal_schema(self):
    +        return self._schema.inputs
    +
    +    @classmethod
    +    def _reference(cls, input_entities, input_item, configs):
    +        for input_entity in input_entities:
    +            cls._input_reference(
    +                input_item["name"], input_entity, input_item["entity"], configs
    +            )
    +
    +    @classmethod
    +    def _input_reference(cls, input_type, input_entity, input_schema, configs):
    +        for field in input_schema:
    +            options = field.get("options", {})
    +            config_type = options.get("referenceName")
    +            config_name = input_entity.get(field["field"])
    +            if not config_type or not config_name:
    +                continue
    +
    +            for config in configs.get(config_type, []):
    +                if config["name"] == config_name:
    +                    input_entity[field["field"]] = config
    +                    break
    +            else:
    +                raise GlobalConfigError(
    +                    "Config Not Found for Input, "
    +                    "input_type={input_type}, "
    +                    "input_name={input_name}, "
    +                    "config_type={config_type}, "
    +                    "config_name={config_name}".format(
    +                        input_type=input_type,
    +                        input_name=input_entity["name"],
    +                        config_type=config_type,
    +                        config_name=config_name,
    +                    )
    +                )
    +
    +
    +class Configs(Configuration):
    +    def load(self, config_type=None):
    +        """
    +
    +        :param config_type:
    +        :return:
    +
    +         Usage::
    +        >>> from splunktaucclib.global_config import GlobalConfig
    +        >>> global_config = GlobalConfig()
    +        >>> configs = global_config.configs.load()
    +        """
    +        configs = {}
    +        for config in self.internal_schema:
    +            if config_type is None or config["name"] == config_type:
    +                config_entities = self._load_endpoint(config["name"], config["entity"])
    +                for config_entity in config_entities:
    +                    self._filter_fields(config_entity)
    +                configs[config["name"]] = config_entities
    +        return configs
    +
    +    @property
    +    def internal_schema(self):
    +        return self._schema.configs
    +
    +
    +class Settings(Configuration):
    +
    +    TYPE_NAME = "settings"
    +
    +    def load(self):
    +        """
    +
    +        :return:
    +
    +         Usage::
    +        >>> from splunktaucclib.global_config import GlobalConfig
    +        >>> global_config = GlobalConfig()
    +        >>> settings = global_config.settings.load()
    +        """
    +        settings = []
    +        for setting in self.internal_schema:
    +            setting_entity = self._load_endpoint(
    +                "settings/%s" % setting["name"], setting["entity"]
    +            )
    +            self._load_multiple_select(setting_entity[0], setting["entity"])
    +            entity = setting_entity[0]
    +            self._filter_fields(entity)
    +            settings.append(entity)
    +        return {Settings.TYPE_NAME: settings}
    +
    +    @property
    +    def internal_schema(self):
    +        return self._schema.settings
    +
    +    def _search_configuration_schema(self, type_name, configuration_name):
    +        return super()._search_configuration_schema(
    +            configuration_name,
    +            configuration_name,
    +        )
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/global_config/schema.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/global_config/schema.py
    new file mode 100644
    index 0000000..5704538
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/global_config/schema.py
    @@ -0,0 +1,86 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 traceback
    +
    +from ..rest_handler.schema import RestSchema, RestSchemaError
    +
    +
    +class GlobalConfigSchema(RestSchema):
    +    def __init__(self, content, *args, **kwargs):
    +        """
    +
    +        :param content: Python object for Global Config Schema
    +        :param args:
    +        :param kwargs:
    +        """
    +        super().__init__(*args, **kwargs)
    +        self._content = content
    +        self._inputs = []
    +        self._configs = []
    +        self._settings = []
    +
    +        try:
    +            self._parse()
    +        except Exception:
    +            raise RestSchemaError(
    +                "Invalid Global Config Schema: %s" % traceback.format_exc(),
    +            )
    +
    +    @property
    +    def product(self):
    +        return self._meta["name"]
    +
    +    @property
    +    def namespace(self):
    +        return self._meta["restRoot"]
    +
    +    @property
    +    def admin_match(self):
    +        return ""
    +
    +    @property
    +    def inputs(self):
    +        return self._inputs
    +
    +    @property
    +    def configs(self):
    +        return self._configs
    +
    +    @property
    +    def settings(self):
    +        return self._settings
    +
    +    def _parse(self):
    +        self._meta = self._content["meta"]
    +        pages = self._content["pages"]
    +        self._parse_configuration(pages.get("configuration"))
    +        self._parse_inputs(pages.get("inputs"))
    +
    +    def _parse_configuration(self, configurations):
    +        if not configurations or "tabs" not in configurations:
    +            return
    +        for configuration in configurations["tabs"]:
    +            if "table" in configuration:
    +                self._configs.append(configuration)
    +            else:
    +                self._settings.append(configuration)
    +
    +    def _parse_inputs(self, inputs):
    +        if not inputs or "services" not in inputs:
    +            return
    +        self._inputs = inputs["services"]
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/modinput_wrapper/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/modinput_wrapper/__init__.py
    new file mode 100644
    index 0000000..72d4509
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/modinput_wrapper/__init__.py
    @@ -0,0 +1,15 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/modinput_wrapper/base_modinput.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/modinput_wrapper/base_modinput.py
    new file mode 100644
    index 0000000..73ce931
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/modinput_wrapper/base_modinput.py
    @@ -0,0 +1,583 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +# encoding = utf-8
    +import copy
    +import json
    +import logging
    +import os
    +import sys
    +import tempfile
    +
    +from solnlib import utils as sutils
    +from solnlib.log import Logs
    +from solnlib.modular_input import checkpointer
    +from splunklib import modularinput as smi
    +
    +from splunktaucclib.global_config import GlobalConfig, GlobalConfigSchema
    +from splunktaucclib.splunk_aoblib.rest_helper import TARestHelper
    +from splunktaucclib.splunk_aoblib.setup_util import Setup_Util
    +
    +DATA_INPUTS_OPTIONS = "data_inputs_options"
    +AOB_TEST_FLAG = "AOB_TEST"
    +FIELD_TYPE = "type"
    +FIELD_FORMAT = "format_type"
    +CUSTOMIZED_VAR = "customized_var"
    +TYPE_CHECKBOX = "checkbox"
    +TYPE_ACCOUNT = "global_account"
    +
    +
    +class BaseModInput(smi.Script):
    +    """
    +    This is a modular input wrapper, which provides some helper
    +    functions to read the paramters from setup pages and the arguments
    +    from input definition
    +    """
    +
    +    LogLevelMapping = {
    +        "debug": logging.DEBUG,
    +        "info": logging.INFO,
    +        "warning": logging.WARNING,
    +        "error": logging.ERROR,
    +        "critical": logging.CRITICAL,
    +    }
    +
    +    def __init__(self, app_namespace, input_name, use_single_instance=False):
    +        super().__init__()
    +        self.use_single_instance = use_single_instance
    +        self._canceled = False
    +        self.input_type = input_name
    +        self.input_stanzas = {}
    +        self.context_meta = {}
    +        self.namespace = app_namespace
    +        # redirect all the logging to one file
    +        Logs.set_context(namespace=app_namespace, root_logger_log_file=input_name)
    +        self.logger = logging.getLogger()
    +        self.logger.setLevel(logging.INFO)
    +        self.rest_helper = TARestHelper(self.logger)
    +        # check point
    +        self.ckpt = None
    +        self.setup_util = None
    +
    +    @property
    +    def app(self):
    +        return self.get_app_name()
    +
    +    @property
    +    def global_setup_util(self):
    +        """
    +        This is a private API used in AoB code internally. It is not allowed to be used in user's code.
    +        :return: setup util instance to read global configurations
    +        """
    +        return self.setup_util
    +
    +    def get_app_name(self):
    +        """Get TA name.
    +        :return: the name of TA this modular input is in
    +        """
    +        raise NotImplemented
    +
    +    def get_scheme(self):
    +        """Get basic scheme, with use_single_instance field set.
    +        :return: a basic input scheme
    +        """
    +        scheme = smi.Scheme(self.input_type)
    +        scheme.use_single_instance = self.use_single_instance
    +        return scheme
    +
    +    def stream_events(self, inputs, ew):
    +        """The method called to stream events into Splunk.
    +        This method overrides method in splunklib modular input.
    +        It pre-processes the input args and call collect_events to stream events.
    +        :param inputs: An ``InputDefinition`` object.
    +        :param ew: An object with methods to write events and log messages to Splunk.
    +        """
    +        # the input metadata is like
    +        # {
    +        #     'server_uri': 'https://127.0.0.1:8089',
    +        #     'server_host': 'localhost',
    +        #     'checkpoint_dir': '...',
    +        #     'session_key': 'ceAvf3z^hZHYxe7wjTyTNo6_0ZRpf5cvWPdtSg'
    +        # }
    +        self.context_meta = inputs.metadata
    +        # init setup util
    +        uri = inputs.metadata["server_uri"]
    +        session_key = inputs.metadata["session_key"]
    +        self.setup_util = Setup_Util(uri, session_key, self.logger)
    +
    +        input_definition = smi.input_definition.InputDefinition()
    +        input_definition.metadata = copy.deepcopy(inputs.metadata)
    +        input_definition.inputs = copy.deepcopy(inputs.inputs)
    +        try:
    +            self.parse_input_args(input_definition)
    +        except Exception as e:
    +            import traceback
    +
    +            self.log_error(traceback.format_exc())
    +            print(traceback.format_exc(), file=sys.stderr)
    +            # print >> sys.stderr, traceback.format_exc()
    +            self.input_stanzas = {}
    +        if not self.input_stanzas:
    +            # if no stanza found. Just return
    +            return
    +        try:
    +            self.set_log_level(self.log_level)
    +        except:
    +            self.log_debug("set log level fails.")
    +        try:
    +            self.collect_events(ew)
    +        except Exception as e:
    +            import traceback
    +
    +            self.log_error(
    +                "Get error when collecting events.\n" + traceback.format_exc()
    +            )
    +            print(traceback.format_exc(), file=sys.stderr)
    +            # print >> sys.stderr, traceback.format_exc()
    +            raise RuntimeError(str(e))
    +
    +    def collect_events(self, event_writer):
    +        """Collect events and stream to Splunk using event writer provided.
    +        Note: This method is originally collect_events(self, inputs, event_writer).
    +        :param event_writer: An object with methods to write events and log messages to Splunk.
    +        """
    +        raise NotImplemented()
    +
    +    def parse_input_args(self, inputs):
    +        """Parse input arguments, either from os environment when testing or from global configuration.
    +        :param inputs: An ``InputDefinition`` object.
    +        :return:
    +        """
    +        if os.environ.get(AOB_TEST_FLAG, "false") == "true":
    +            self._parse_input_args_from_env(inputs)
    +        else:
    +            self._parse_input_args_from_global_config(inputs)
    +        if not self.use_single_instance:
    +            assert len(self.input_stanzas) == 1
    +
    +    def _parse_input_args_from_global_config(self, inputs):
    +        """Parse input arguments from global configuration.
    +        :param inputs:
    +        """
    +        # dirname at this point will be <splunk_home>/etc/apps/<ta-name>/lib/splunktaucclib/modinput_wrapper, go up 3 dirs from this file to find the root TA directory
    +        dirname = os.path.dirname
    +        config_path = os.path.join(
    +            dirname(dirname(dirname(dirname(__file__)))),
    +            "appserver",
    +            "static",
    +            "js",
    +            "build",
    +            "globalConfig.json",
    +        )
    +        with open(config_path) as f:
    +            schema_json = "".join([l for l in f])
    +        global_schema = GlobalConfigSchema(json.loads(schema_json))
    +
    +        uri = inputs.metadata["server_uri"]
    +        session_key = inputs.metadata["session_key"]
    +        global_config = GlobalConfig(uri, session_key, global_schema)
    +        ucc_inputs = global_config.inputs.load(input_type=self.input_type)
    +        all_stanzas = ucc_inputs.get(self.input_type, {})
    +        if not all_stanzas:
    +            # for single instance input. There might be no input stanza.
    +            # Only the default stanza. In this case, modinput should exit.
    +            self.log_warning("No stanza found for input type: " + self.input_type)
    +            sys.exit(0)
    +
    +        account_fields = self.get_account_fields()
    +        checkbox_fields = self.get_checkbox_fields()
    +        self.input_stanzas = {}
    +        for stanza in all_stanzas:
    +            full_stanza_name = "{}://{}".format(self.input_type, stanza.get("name"))
    +            if full_stanza_name in inputs.inputs:
    +                if stanza.get("disabled", False):
    +                    raise RuntimeError("Running disabled data input!")
    +                stanza_params = {}
    +                for k, v in stanza.items():
    +                    if k in checkbox_fields:
    +                        stanza_params[k] = sutils.is_true(v)
    +                    elif k in account_fields:
    +                        stanza_params[k] = copy.deepcopy(v)
    +                    else:
    +                        stanza_params[k] = v
    +                self.input_stanzas[stanza.get("name")] = stanza_params
    +
    +    def _parse_input_args_from_env(self, inputs):
    +        """Parse input arguments from os environment. This is used for testing inputs.
    +        :param inputs:
    +        """
    +        data_inputs_options = json.loads(os.environ.get(DATA_INPUTS_OPTIONS, "[]"))
    +        account_fields = self.get_account_fields()
    +        checkbox_fields = self.get_checkbox_fields()
    +        self.input_stanzas = {}
    +        while len(inputs.inputs) > 0:
    +            input_stanza, stanza_args = inputs.inputs.popitem()
    +            kind_and_name = input_stanza.split("://")
    +            if len(kind_and_name) == 2:
    +                stanza_params = {}
    +                for arg_name, arg_value in stanza_args.items():
    +                    try:
    +                        arg_value_trans = json.loads(arg_value)
    +                    except ValueError:
    +                        arg_value_trans = arg_value
    +                    stanza_params[arg_name] = arg_value_trans
    +                    if arg_name in account_fields:
    +                        stanza_params[arg_name] = self.get_user_credential_by_id(
    +                            arg_value_trans
    +                        )
    +                    elif arg_name in checkbox_fields:
    +                        stanza_params[arg_name] = sutils.is_true(arg_value_trans)
    +                self.input_stanzas[kind_and_name[1]] = stanza_params
    +
    +    def get_account_fields(self):
    +        """Get the names of account variables.
    +        Should be implemented in subclass.
    +        :return: a list of variable names
    +        """
    +        raise NotImplemented
    +
    +    def get_checkbox_fields(self):
    +        """Get the names of checkbox variables.
    +        Should be implemented in subclass.
    +        :return: a list of variable names
    +        """
    +        raise NotImplemented
    +
    +    def get_global_checkbox_fields(self):
    +        """Get the names of checkbox global parameters.
    +        :return: a list of global variable names
    +        """
    +        raise NotImplemented
    +
    +    # Global setting related functions.
    +    # Global settings consist of log setting, proxy, account(user_credential) and customized settings.
    +    @property
    +    def log_level(self):
    +        return self.get_log_level()
    +
    +    def get_log_level(self):
    +        """Get the log level configured in global configuration.
    +        :return: log level set in global configuration or "INFO" by default.
    +        """
    +        return self.setup_util.get_log_level()
    +
    +    def set_log_level(self, level):
    +        """Set the log level this python process uses.
    +        :param level: log level in `string`. Accept "DEBUG", "INFO", "WARNING", "ERROR" and "CRITICAL".
    +        """
    +        if isinstance(level, str):
    +            level = level.lower()
    +            if level in self.LogLevelMapping:
    +                level = self.LogLevelMapping[level]
    +            else:
    +                level = logging.INFO
    +        self.logger.setLevel(level)
    +
    +    def log(self, msg):
    +        """Log msg using logging level in global configuration.
    +        :param msg: log `string`
    +        """
    +        self.logger.log(level=self.log_level, msg=msg)
    +
    +    def log_debug(self, msg):
    +        """Log msg using logging.DEBUG level.
    +        :param msg: log `string`
    +        """
    +        self.logger.debug(msg)
    +
    +    def log_info(self, msg):
    +        """Log msg using logging.INFO level.
    +        :param msg: log `string`
    +        """
    +        self.logger.info(msg)
    +
    +    def log_warning(self, msg):
    +        """Log msg using logging.WARNING level.
    +        :param msg: log `string`
    +        """
    +        self.logger.warning(msg)
    +
    +    def log_error(self, msg):
    +        """Log msg using logging.ERROR level.
    +        :param msg: log `string`
    +        """
    +        self.logger.error(msg)
    +
    +    def log_critical(self, msg):
    +        """Log msg using logging.CRITICAL level.
    +        :param msg: log `string`
    +        """
    +        self.logger.critical(msg)
    +
    +    @property
    +    def proxy(self):
    +        return self.get_proxy()
    +
    +    def get_proxy(self):
    +        """Get proxy settings in global configuration.
    +        Proxy settings include fields "proxy_url", "proxy_port", "proxy_username", "proxy_password", "proxy_type" and "proxy_rdns".
    +        :return: a `dict` containing proxy parameters or empty `dict` if proxy is not set.
    +        """
    +        return self.setup_util.get_proxy_settings()
    +
    +    def get_user_credential_by_username(self, username):
    +        """Get global credential information based on username.
    +        Credential settings include fields "name"(account id), "username" and "password".
    +        :param username: `string`
    +        :return: if credential with username exists, return a `dict`, else None.
    +        """
    +        return self.setup_util.get_credential_by_username(username)
    +
    +    def get_user_credential_by_id(self, account_id):
    +        """Get global credential information based on account id.
    +        Credential settings include fields "name"(account id), "username" and "password".
    +        :param account_id: `string`
    +        :return: if credential with account_id exists, return a `dict`, else None.
    +        """
    +        return self.setup_util.get_credential_by_id(account_id)
    +
    +    def get_global_setting(self, var_name):
    +        """Get customized setting value configured in global configuration.
    +        :param var_name: `string`
    +        :return: customized global configuration value or None
    +        """
    +        var_value = self.setup_util.get_customized_setting(var_name)
    +        if var_value is not None and var_name in self.get_global_checkbox_fields():
    +            var_value = sutils.is_true(var_value)
    +        return var_value
    +
    +    # Functions to help create events.
    +    def new_event(
    +        self,
    +        data,
    +        time=None,
    +        host=None,
    +        index=None,
    +        source=None,
    +        sourcetype=None,
    +        done=True,
    +        unbroken=True,
    +    ):
    +        """Create a Splunk event object.
    +        :param data: ``string``, the event's text.
    +        :param time: ``float``, time in seconds, including up to 3 decimal places to represent milliseconds.
    +        :param host: ``string``, the event's host, ex: localhost.
    +        :param index: ``string``, the index this event is specified to write to, or None if default index.
    +        :param source: ``string``, the source of this event, or None to have Splunk guess.
    +        :param sourcetype: ``string``, source type currently set on this event, or None to have Splunk guess.
    +        :param done: ``boolean``, is this a complete ``Event``? False if an ``Event`` fragment.
    +        :param unbroken: ``boolean``, Is this event completely encapsulated in this ``Event`` object?
    +        :return: ``Event`` object
    +        """
    +        return smi.Event(
    +            data=data,
    +            time=time,
    +            host=host,
    +            index=index,
    +            source=source,
    +            sourcetype=sourcetype,
    +            done=done,
    +            unbroken=unbroken,
    +        )
    +
    +    # Basic get functions. To get params in input stanza.
    +    def get_input_type(self):
    +        """Get input type.
    +        :return: the modular input type
    +        """
    +        return self.input_type
    +
    +    def get_input_stanza(self, input_stanza_name=None):
    +        """Get input stanzas.
    +        If stanza name is None, return a dict with stanza name as key and params as values.
    +        Else return a dict with param name as key and param value as value.
    +        :param input_stanza_name: None or `string`
    +        :return: `dict`
    +        """
    +        if input_stanza_name:
    +            return self.input_stanzas.get(input_stanza_name, None)
    +        return self.input_stanzas
    +
    +    def get_input_stanza_names(self):
    +        """Get all stanza names this modular input instance is given.
    +        For multi instance mode, a single string value will be returned.
    +        For single instance mode, stanza names will be returned in a list.
    +        :return: `string` or `list`
    +        """
    +        if self.input_stanzas:
    +            names = list(self.input_stanzas.keys())
    +            if self.use_single_instance:
    +                return names
    +            else:
    +                assert len(names) == 1
    +                return names[0]
    +        return None
    +
    +    def get_arg(self, arg_name, input_stanza_name=None):
    +        """Get the input argument.
    +        If input_stanza_name is not provided:
    +            For single instance mode, return a dict <input_name, arg_value>.
    +            For multi instance mode, return a single value or None.
    +        If input_stanza_name is provided, return a single value or None.
    +        :param arg_name: `string`, argument name
    +        :param input_stanza_name: None or `string`, a stanza name
    +        :return: `dict` or `string` or None
    +        """
    +        if input_stanza_name is None:
    +            args_dict = {
    +                k: args[arg_name]
    +                for k, args in self.input_stanzas.items()
    +                if arg_name in args
    +            }
    +            if self.use_single_instance:
    +                return args_dict
    +            else:
    +                if len(args_dict) == 1:
    +                    return list(args_dict.values())[0]
    +                return None
    +        else:
    +            return self.input_stanzas.get(input_stanza_name, {}).get(arg_name, None)
    +
    +    def get_output_index(self, input_stanza_name=None):
    +        """Get output Splunk index.
    +        :param input_stanza_name: `string`
    +        :return: `string` output index
    +        """
    +        return self.get_arg("index", input_stanza_name)
    +
    +    def get_sourcetype(self, input_stanza_name=None):
    +        """Get sourcetype to index.
    +        :param input_stanza_name: `string`
    +        :return: the sourcetype to index to
    +        """
    +        return self.get_arg("sourcetype", input_stanza_name)
    +
    +    # HTTP request helper
    +    def send_http_request(
    +        self,
    +        url,
    +        method,
    +        parameters=None,
    +        payload=None,
    +        headers=None,
    +        cookies=None,
    +        verify=True,
    +        cert=None,
    +        timeout=None,
    +        use_proxy=True,
    +    ):
    +        """Send http request and get response.
    +        :param url: URL for the new Request object.
    +        :param method: method for the new Request object. Can be "GET", "POST", "PUT", "DELETE"
    +        :param parameters: (optional) Dictionary or bytes to be sent in the query string for the Request.
    +        :param payload: (optional) Dictionary, bytes, or file-like object to send in the body of the Request.
    +        :param headers: (optional) Dictionary of HTTP Headers to send with the Request.
    +        :param cookies: (optional) Dict or CookieJar object to send with the Request.
    +        :param verify: (optional) whether the SSL cert will be verified. A CA_BUNDLE path can also be provided.
    +        :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
    +        :param timeout: (optional) How long to wait for the server to send data before giving up, as a float,
    +            or a (connect timeout, read timeout) tuple. Default to (10.0, 5.0).
    +        :param use_proxy: (optional) whether to use proxy. If set to True, proxy in global setting will be used.
    +        :return: Response
    +        """
    +        return self.rest_helper.send_http_request(
    +            url=url,
    +            method=method,
    +            parameters=parameters,
    +            payload=payload,
    +            headers=headers,
    +            cookies=cookies,
    +            verify=verify,
    +            cert=cert,
    +            timeout=timeout,
    +            proxy_uri=self._get_proxy_uri() if use_proxy else None,
    +        )
    +
    +    def _get_proxy_uri(self):
    +        uri = None
    +        proxy = self.get_proxy()
    +        if proxy and proxy.get("proxy_url") and proxy.get("proxy_type"):
    +            uri = proxy["proxy_url"]
    +            if proxy.get("proxy_port"):
    +                uri = "{}:{}".format(uri, proxy.get("proxy_port"))
    +            if proxy.get("proxy_username") and proxy.get("proxy_password"):
    +                uri = "{}://{}:{}@{}/".format(
    +                    proxy["proxy_type"],
    +                    proxy["proxy_username"],
    +                    proxy["proxy_password"],
    +                    uri,
    +                )
    +            else:
    +                uri = "{}://{}".format(proxy["proxy_type"], uri)
    +        return uri
    +
    +    # Checkpointing related functions
    +    def _init_ckpt(self):
    +        if self.ckpt is None:
    +            if "AOB_TEST" in os.environ:
    +                ckpt_dir = self.context_meta.get("checkpoint_dir", tempfile.mkdtemp())
    +                if not os.path.exists(ckpt_dir):
    +                    os.makedirs(ckpt_dir)
    +                self.ckpt = checkpointer.FileCheckpointer(ckpt_dir)
    +            else:
    +                if "server_uri" not in self.context_meta:
    +                    raise ValueError("server_uri not found in input meta.")
    +                if "session_key" not in self.context_meta:
    +                    raise ValueError("session_key not found in input meta.")
    +                dscheme, dhost, dport = sutils.extract_http_scheme_host_port(
    +                    self.context_meta["server_uri"]
    +                )
    +                self.ckpt = checkpointer.KVStoreCheckpointer(
    +                    self.app + "_checkpointer",
    +                    self.context_meta["session_key"],
    +                    self.app,
    +                    scheme=dscheme,
    +                    host=dhost,
    +                    port=dport,
    +                )
    +
    +    def get_check_point(self, key):
    +        """Get checkpoint.
    +        :param key: `string`
    +        :return: Checkpoint state if exists else None.
    +        """
    +        if self.ckpt is None:
    +            self._init_ckpt()
    +        return self.ckpt.get(key)
    +
    +    def save_check_point(self, key, state):
    +        """Update checkpoint.
    +        :param key: Checkpoint key. `string`
    +        :param state: Checkpoint state.
    +        """
    +        if self.ckpt is None:
    +            self._init_ckpt()
    +        self.ckpt.update(key, state)
    +
    +    def batch_save_check_point(self, states):
    +        """Batch update checkpoint.
    +        :param states: a `dict` states with checkpoint key as key and checkpoint state as value.
    +        """
    +        if self.ckpt is None:
    +            self._init_ckpt()
    +        self.ckpt.batch_update(states)
    +
    +    def delete_check_point(self, key):
    +        """Delete checkpoint.
    +        :param key: Checkpoint key. `string`
    +        """
    +        if self.ckpt is None:
    +            self._init_ckpt()
    +        self.ckpt.delete(key)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/__init__.py
    new file mode 100644
    index 0000000..e9d8e1f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/__init__.py
    @@ -0,0 +1,19 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +Custom REST Handler in Splunk add-on.
    +"""
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/admin_external.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/admin_external.py
    new file mode 100644
    index 0000000..8e7d295
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/admin_external.py
    @@ -0,0 +1,222 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 os
    +from functools import wraps
    +
    +from solnlib.splunkenv import get_splunkd_uri
    +from solnlib.utils import is_true
    +from splunk import admin
    +
    +from .eai import EAI_FIELDS
    +from .endpoint import DataInputModel, MultipleModel, SingleModel
    +from .handler import RestHandler
    +
    +try:
    +    from custom_hook_mixin import CustomHookMixin as HookMixin
    +except ImportError:
    +    from .base_hook_mixin import BaseHookMixin as HookMixin
    +
    +
    +__all__ = [
    +    "make_conf_item",
    +    "build_conf_info",
    +    "AdminExternalHandler",
    +]
    +
    +
    +def make_conf_item(conf_item, content, eai):
    +    for key, val in content.items():
    +        conf_item[key] = val
    +
    +    for eai_field in EAI_FIELDS:
    +        conf_item.setMetadata(eai_field, eai.content[eai_field])
    +
    +    return conf_item
    +
    +
    +def build_conf_info(meth):
    +    """
    +    Build conf info for admin external REST endpoint.
    +
    +    :param meth:
    +    :return:
    +    """
    +
    +    @wraps(meth)
    +    def wrapper(self, confInfo):
    +        result = meth(self, confInfo)
    +        for entity in result:
    +            make_conf_item(
    +                confInfo[entity.name],
    +                entity.content,
    +                entity.eai,
    +            )
    +
    +    return wrapper
    +
    +
    +def get_splunkd_endpoint():
    +    if os.environ.get("SPLUNKD_URI"):
    +        return os.environ["SPLUNKD_URI"]
    +    else:
    +        splunkd_uri = get_splunkd_uri()
    +        os.environ["SPLUNKD_URI"] = splunkd_uri
    +        return splunkd_uri
    +
    +
    +class AdminExternalHandler(HookMixin, admin.MConfigHandler):
    +
    +    # Leave it for setting REST model
    +    endpoint = None
    +
    +    # action parameter for getting clear credentials
    +    ACTION_CRED = "--cred--"
    +
    +    def __init__(self, *args, **kwargs):
    +        # use classic inheritance to be compatible for
    +        # old version of Splunk private SDK
    +        admin.MConfigHandler.__init__(self, *args, **kwargs)
    +        self.handler = RestHandler(
    +            get_splunkd_endpoint(),
    +            self.getSessionKey(),
    +            self.endpoint,
    +        )
    +        self.payload = self._convert_payload()
    +
    +    def setup(self):
    +        # add args for getting clear credentials
    +        if self.requestedAction == admin.ACTION_LIST:
    +            self.supportedArgs.addOptArg(self.ACTION_CRED)
    +
    +        # add args in payload while creating/updating
    +        actions = (admin.ACTION_LIST, admin.ACTION_REMOVE)
    +        if self.requestedAction in actions:
    +            return
    +        model = self.endpoint.model(self.callerArgs.id)
    +        if self.requestedAction == admin.ACTION_CREATE:
    +            for field in model.fields:
    +                if field.required:
    +                    self.supportedArgs.addReqArg(field.name)
    +                else:
    +                    self.supportedArgs.addOptArg(field.name)
    +
    +        if self.requestedAction == admin.ACTION_EDIT:
    +            for field in model.fields:
    +                self.supportedArgs.addOptArg(field.name)
    +
    +    @build_conf_info
    +    def handleList(self, confInfo):
    +        decrypt = self.callerArgs.data.get(
    +            self.ACTION_CRED,
    +            [False],
    +        )
    +        decrypt = is_true(decrypt[0])
    +        if self.callerArgs.id:
    +            result = self.handler.get(
    +                self.callerArgs.id,
    +                decrypt=decrypt,
    +            )
    +        else:
    +            result = self.handler.all(
    +                decrypt=decrypt,
    +                count=0,
    +            )
    +        return result
    +
    +    @build_conf_info
    +    def handleCreate(self, confInfo):
    +        self.create_hook(
    +            session_key=self.getSessionKey(),
    +            config_name=self._get_name(),
    +            stanza_id=self.callerArgs.id,
    +            payload=self.payload,
    +        )
    +        return self.handler.create(
    +            self.callerArgs.id,
    +            self.payload,
    +        )
    +
    +    @build_conf_info
    +    def handleEdit(self, confInfo):
    +        disabled = self.payload.get("disabled")
    +        if disabled is None:
    +            self.edit_hook(
    +                session_key=self.getSessionKey(),
    +                config_name=self._get_name(),
    +                stanza_id=self.callerArgs.id,
    +                payload=self.payload,
    +            )
    +            return self.handler.update(
    +                self.callerArgs.id,
    +                self.payload,
    +            )
    +        elif is_true(disabled):
    +            return self.handler.disable(self.callerArgs.id)
    +        else:
    +            return self.handler.enable(self.callerArgs.id)
    +
    +    @build_conf_info
    +    def handleRemove(self, confInfo):
    +        self.delete_hook(
    +            session_key=self.getSessionKey(),
    +            config_name=self._get_name(),
    +            stanza_id=self.callerArgs.id,
    +        )
    +        return self.handler.delete(self.callerArgs.id)
    +
    +    def _get_name(self):
    +        name = None
    +        if isinstance(self.handler.get_endpoint(), DataInputModel):
    +            name = self.handler.get_endpoint().input_type
    +        elif isinstance(self.handler.get_endpoint(), SingleModel):
    +            name = self.handler.get_endpoint().config_name
    +        elif isinstance(self.handler.get_endpoint(), MultipleModel):
    +            # For multiple model, the configuraiton name is same with stanza id
    +            name = self.callerArgs.id
    +        return name
    +
    +    def _convert_payload(self):
    +        check_actions = (admin.ACTION_CREATE, admin.ACTION_EDIT)
    +        if self.requestedAction not in check_actions:
    +            return None
    +
    +        payload = {}
    +        for filed, value in self.callerArgs.data.items():
    +            payload[filed] = value[0] if value and value[0] else ""
    +        return payload
    +
    +
    +def handle(
    +    endpoint,
    +    handler=AdminExternalHandler,
    +    context_info=admin.CONTEXT_APP_ONLY,
    +):
    +    """
    +    Handle request.
    +
    +    :param endpoint: REST endpoint
    +    :param handler: REST handler
    +    :param context_info:
    +    :return:
    +    """
    +    real_handler = type(
    +        handler.__name__,
    +        (handler,),
    +        {"endpoint": endpoint},
    +    )
    +    admin.init(real_handler, ctxInfo=context_info)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/base.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/base.py
    new file mode 100644
    index 0000000..6500ce2
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/base.py
    @@ -0,0 +1,715 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""Base Handler Class of REST Manager.
    +"""
    +
    +import copy
    +import itertools
    +import json
    +import logging
    +from inspect import ismethod
    +from os import path as op
    +
    +from splunk import ResourceNotFound, RESTException, admin, entity, rest
    +from splunktalib.common import util as sc_util
    +from splunktalib.rest import splunkd_request
    +
    +import splunktaucclib.common.log as stulog
    +from splunktaucclib.rest_handler.cred_mgmt import CredMgmt
    +from splunktaucclib.rest_handler.error_ctl import RestHandlerError as RH_Err
    +from splunktaucclib.rest_handler.util import makeConfItem
    +
    +__all__ = ["user_caps", "BaseRestHandler", "BaseModel", "ResourceHandler"]
    +
    +APP_NAME = sc_util.get_appname_from_path(op.abspath(__file__))
    +
    +
    +def get_entities(endpoint, session_key, user, app, get_args):
    +    url = rest.makeSplunkdUri() + "servicesNS/" + user + "/" + app + "/" + endpoint
    +    try:
    +        response, content = rest.simpleRequest(
    +            url,
    +            sessionKey=session_key,
    +            method="GET",
    +            getargs=get_args,
    +            raiseAllErrors=True,
    +        )
    +        res = json.loads(content)
    +        if "entry" in res:
    +            return {entry["name"]: entry["content"] for entry in res["entry"]}
    +        else:
    +            return {}
    +    except Exception as exc:
    +        RH_Err.ctl(-1, msgx=exc, logLevel=logging.INFO)
    +    return
    +
    +
    +def user_caps(mgmt_uri, session_key):
    +    """
    +    Get capabilities of sessioned Splunk user.
    +    :param mgmt_uri:
    +    :param session_key:
    +    :return:
    +    """
    +    url = mgmt_uri + "/services/authentication/current-context"
    +
    +    resp = splunkd_request(
    +        url, session_key, method="GET", data={"output_mode": "json"}, retry=3
    +    )
    +    if resp is None:
    +        RH_Err.ctl(500, logging.ERROR, "Fail to get capabilities of sessioned user")
    +    elif resp.status_code != 200:
    +        RH_Err.ctl(resp.status_code, logging.ERROR, resp.text)
    +
    +    cont = resp.json()
    +    caps = cont["entry"][0]["content"]["capabilities"]
    +    return set(caps)
    +
    +
    +class BaseRestHandler(admin.MConfigHandler):
    +    """Base Class for Splunk REST Handler.
    +
    +    Note: It gets a mask for encrypted fields by default.
    +    But you will get clear password with field ``--get-clear-credential--``
    +    equalling to ``1`` in request. This is for back-end.
    +    """
    +
    +    def __init__(self, *args, **kwargs):
    +        admin.MConfigHandler.__init__(self, *args, **kwargs)
    +        self._log_request()
    +
    +        # not allow to create object with name starting with '_'
    +        if (
    +            self.requestedAction == admin.ACTION_CREATE
    +            and self.callerArgs.id
    +            and self.callerArgs.id.startswith("_")
    +        ):
    +            RH_Err.ctl(
    +                400,
    +                msgx="It is not allowed to create object with "
    +                'name starting with "_"',
    +                logLevel=logging.INFO,
    +            )
    +
    +        # check required attributes
    +        assert getattr(self, "endpoint", ""), RH_Err.ctl(
    +            1002, msgx="%s.endpoint" % (self._getHandlerName()), shouldPrint=False
    +        )
    +        assert hasattr(self, "validate") and ismethod(self.validate), RH_Err.ctl(
    +            1002, msgx="%s.validate" % (self._getHandlerName()), shouldPrint=False
    +        )
    +        assert hasattr(self, "normalize") and ismethod(self.normalize), RH_Err.ctl(
    +            1002, msgx="%s.normalize" % (self._getHandlerName()), shouldPrint=False
    +        )
    +
    +        # check capabilities of sessioned user
    +        self.check_caps()
    +
    +        # Check if entry exists for "_sync"
    +        if self.customAction == "_sync":
    +            try:
    +                self.get(self.callerArgs.id)
    +            except ResourceNotFound:
    +                self.exist4sync = False
    +            except Exception as exc:
    +                RH_Err.ctl(1102, msgx=f"object={self.callerArgs.id}, err={exc}")
    +            else:
    +                self.exist4sync = True
    +        self._cred_mgmt = self.get_cred_mgmt(self.endpoint)
    +
    +    def setup(self):
    +        if self.customAction == "_sync":
    +            action = admin.ACTION_EDIT if self.exist4sync else admin.ACTION_CREATE
    +            self.setupArgs(action)
    +        elif self.requestedAction in (admin.ACTION_CREATE, admin.ACTION_EDIT):
    +            self.setupArgs(self.requestedAction)
    +        elif self.requestedAction == admin.ACTION_LIST:
    +            self.supportedArgs.addOptArg("--get-clear-credential--")
    +
    +    def setupArgs(self, action):
    +        if action in [admin.ACTION_CREATE]:
    +            self._addArgs(
    +                reqArgsIter=self.requiredArgs,
    +                optArgsIter=itertools.chain(self.optionalArgs, self.transientArgs),
    +            )
    +        elif action in [admin.ACTION_EDIT]:
    +            self._addArgs(
    +                optArgsIter=itertools.chain(
    +                    self.requiredArgs, self.optionalArgs, self.transientArgs
    +                )
    +            )
    +        if self.allowExtra:
    +            arguments = set(
    +                itertools.chain(
    +                    self.requiredArgs, self.optionalArgs, self.transientArgs
    +                )
    +            )
    +            extra_args = (
    +                arg for arg in list(self.callerArgs.data.keys()) if arg not in arguments
    +            )
    +            self._addArgs(optArgsIter=extra_args)
    +
    +    def _addArgs(self, reqArgsIter=(), optArgsIter=()):
    +        for arg in reqArgsIter:
    +            self.supportedArgs.addReqArg(arg)
    +        for arg in optArgsIter:
    +            self.supportedArgs.addOptArg(arg)
    +
    +    def check_caps(self):
    +        current_caps = user_caps(rest.makeSplunkdUri(), self.getSessionKey())
    +
    +        cap4endpoint = (
    +            self.rest_prefix + "_" + self.cap4endpoint if self.cap4endpoint else ""
    +        )
    +        if cap4endpoint and cap4endpoint not in current_caps:
    +            RH_Err.ctl(403, msgx="capability=" + cap4endpoint, logLevel=logging.INFO)
    +        if 0 < len(self.customAction):
    +            self.customActionCap = cap4endpoint
    +
    +        cap4get_cred = (
    +            self.rest_prefix + "_" + self.cap4get_cred if self.cap4get_cred else ""
    +        )
    +        if (
    +            "--get-clear-credential--" in self.callerArgs.data
    +            and cap4get_cred
    +            and cap4get_cred not in current_caps
    +        ):
    +            RH_Err.ctl(403, msgx="capability=" + cap4get_cred, logLevel=logging.INFO)
    +
    +    def get_cred_mgmt(self, endpoint):
    +        # credential fields
    +        self.encryptedArgs = {
    +            (self.keyMap.get(arg) or arg) for arg in self.encryptedArgs
    +        }
    +        user, app = self.user_app()
    +        return CredMgmt(
    +            sessionKey=self.getSessionKey(),
    +            user=user,
    +            app=app,
    +            endpoint=endpoint,
    +            encryptedArgs=self.encryptedArgs,
    +        )
    +
    +    def handleList(self, confInfo):
    +        user, app = self.user_app()
    +
    +        # reload the conf before reading it
    +        try:
    +            entity.refreshEntities(
    +                self.endpoint,
    +                namespace=app,
    +                owner=user,
    +                sessionKey=self.getSessionKey(),
    +            )
    +        except Exception as exc:
    +            RH_Err.ctl(
    +                1023,
    +                msgx=exc,
    +                logLevel=logging.INFO,
    +                shouldPrint=False,
    +                shouldRaise=False,
    +            )
    +
    +        if self.callerArgs.id is None:
    +            ents = self.all()
    +            for name, ent in list(ents.items()):
    +                makeConfItem(name, ent, confInfo, user=user, app=app)
    +        else:
    +            try:
    +                ent = self.get(self.callerArgs.id)
    +                makeConfItem(self.callerArgs.id, ent, confInfo, user=user, app=app)
    +            except ResourceNotFound as exc:
    +                RH_Err.ctl(-1, exc, logLevel=logging.INFO)
    +
    +    def handleReload(self, confInfo):
    +        self._reload(confInfo)
    +
    +    def handleACL(self, confInfo):
    +        ent = self.get(self.callerArgs.id)
    +        meta = ent[admin.EAI_ENTRY_ACL]
    +
    +        if self.requestedAction != admin.ACTION_LIST:
    +
    +            if (
    +                self.requestedAction in [admin.ACTION_CREATE, admin.ACTION_EDIT]
    +                and len(self.callerArgs.data) > 0
    +            ):
    +                ent.properties = dict()
    +
    +                ent["sharing"] = meta["sharing"]
    +                ent["owner"] = meta["owner"]
    +
    +            hasWritePerms = "perms.write" in self.callerArgs
    +            hasReadPerms = "perms.read" in self.callerArgs
    +            isPermsPost = hasWritePerms or hasReadPerms
    +
    +            if (
    +                "sharing" in self.callerArgs
    +                and "user" in self.callerArgs["sharing"]
    +                and isPermsPost
    +            ):
    +                msg = "ACL cannot be set for user-level sharing"
    +                stulog.logger.error(msg)
    +                raise Exception(msg)
    +
    +            perms = meta.get("perms", {})
    +            # for some reason, this can still return None
    +            if perms is None:
    +                perms = {}
    +            ent["perms.read"] = perms.get("read", [])
    +            ent["perms.write"] = perms.get("write", [])
    +
    +            for k, v in list(self.callerArgs.data.items()):
    +                ent[k] = v
    +
    +            entity.setEntity(ent, self.getSessionKey(), uri=ent.id + "/acl")
    +
    +        confItem = confInfo[self.callerArgs.id]
    +        acl = copy.deepcopy(meta)
    +        confItem.actions = self.requestedAction
    +        confItem.setMetadata(admin.EAI_ENTRY_ACL, acl)
    +        self.handleList(confInfo)
    +
    +    def handleCreate(self, confInfo):
    +        try:  # nosemgrep: gitlab.bandit.B110
    +            self.get(self.callerArgs.id)
    +        except Exception:
    +            pass
    +        else:
    +            RH_Err.ctl(
    +                409, msgx=("object=%s" % self.callerArgs.id), logLevel=logging.INFO
    +            )
    +
    +        try:
    +            args = self.encode(self.callerArgs.data)
    +            self.create(self.callerArgs.id, **args)
    +            self.handleList(confInfo)
    +        except Exception as exc:
    +            RH_Err.ctl(-1, exc, logLevel=logging.INFO)
    +
    +    def handleRemove(self, confInfo):
    +        try:
    +            self.delete(self.callerArgs.id)
    +        except Exception as exc:
    +            RH_Err.ctl(-1, exc, logLevel=logging.INFO)
    +        self._cred_mgmt.delete(self._makeStanzaName(self.callerArgs.id))
    +
    +    def handleEdit(self, confInfo):
    +        try:
    +            self.get(self.callerArgs.id)
    +        except Exception as exc:
    +            RH_Err.ctl(-1, msgx=exc, logLevel=logging.INFO)
    +
    +        try:
    +            args = self.encode(self.callerArgs.data, setDefault=False)
    +            self.update(self.callerArgs.id, **args)
    +            self.handleList(confInfo)
    +        except Exception as exc:
    +            RH_Err.ctl(-1, exc, logLevel=logging.INFO)
    +
    +    def encode(self, args, setDefault=True):
    +        """Encode request arguments before save it.
    +
    +        :param args: request arguments.
    +        :param setDefault: should set default value of missing arguments
    +        for the request. It is ``True`` for CREATE, ``False`` for EDIT.
    +        """
    +        # filter transient arguments & handle none value
    +        args = {
    +            key: "" if (val is None or val[0] is None) else val[0]
    +            for key, val in args.items()
    +            if key not in self.transientArgs
    +        }
    +
    +        # set default value if needed
    +        if setDefault:
    +            needed_args_iter = itertools.chain(self.requiredArgs, self.optionalArgs)
    +            args.update(
    +                {
    +                    k: [self.defaultVals[k]]
    +                    for k in needed_args_iter
    +                    if k in self.defaultVals and not args.get(k)
    +                }
    +            )
    +
    +        # validate
    +        args = self.validate(args)
    +
    +        # normalize
    +        args = self.normalize(args)
    +
    +        # Value Mapping
    +        args = {
    +            k: (
    +                [
    +                    (self.valMap[k].get(v) or v)
    +                    for v in (vs if isinstance(vs, list) else [vs])
    +                ]
    +                if k in self.valMap
    +                else vs
    +            )
    +            for k, vs in list(args.items())
    +        }
    +        # Key Mapping
    +        args = {
    +            (k in self.keyMap and self.keyMap[k] or k): vs
    +            for k, vs in list(args.items())
    +        }
    +
    +        # encrypt
    +        tanzaName = self._makeStanzaName(self.callerArgs.id)
    +        args = self._cred_mgmt.encrypt(tanzaName, args)
    +        return args
    +
    +    def decode(self, name, ent):
    +        """Decode data before return it.
    +
    +        :param name:
    +        :param ent:
    +        :return:
    +        """
    +        # Automatically encrypt credential information
    +        # It is for manually edited *.conf file
    +        ent = self._autoEncrypt(name, ent)
    +
    +        # decrypt
    +        if self.callerArgs.data.get("--get-clear-credential--") == ["1"]:
    +            try:
    +                ent = self._cred_mgmt.decrypt(self._makeStanzaName(name), ent)
    +            except ResourceNotFound:
    +                RH_Err.ctl(
    +                    1021,
    +                    msgx=f"endpoint={self.endpoint}, item={name}",
    +                    shouldPrint=False,
    +                    shouldRaise=False,
    +                )
    +        else:
    +            ent = {
    +                key: val for key, val in ent.items() if key not in self.encryptedArgs
    +            }
    +
    +        # Adverse Key Mapping
    +        ent = {k: v for k, v in ent.items()}
    +        keyMapAdv = {v: k for k, v in list(self.keyMap.items())}
    +        ent_new = {keyMapAdv[k]: vs for k, vs in list(ent.items()) if k in keyMapAdv}
    +        ent.update(ent_new)
    +
    +        # Adverse Value Mapping
    +        valMapAdv = {
    +            k: {y: x for x, y in list(m.items())} for k, m in list(self.valMap.items())
    +        }
    +        ent = {
    +            k: (
    +                (
    +                    [(valMapAdv[k].get(v) or v) for v in vs]
    +                    if isinstance(vs, list)
    +                    else (valMapAdv[k].get(vs) or vs)
    +                )
    +                if k in valMapAdv
    +                else vs
    +            )
    +            for k, vs in list(ent.items())
    +        }
    +
    +        # normalize
    +        ent = self.normalize(ent)
    +
    +        # filter undesired arguments & handle none value
    +        return {
    +            k: (
    +                (str(v).lower() if isinstance(v, bool) else v)
    +                if (v is not None and str(v).strip())
    +                else ""
    +            )
    +            for k, v in ent.items()
    +            if k not in self.transientArgs
    +            and (
    +                self.allowExtra
    +                or k in self.requiredArgs
    +                or k in self.optionalArgs
    +                or k in self.outputExtraFields
    +            )
    +        }
    +
    +    def _autoEncrypt(self, name, ent):
    +        cred_data = {
    +            key: ("" if val is None else val)
    +            for key, val in ent.items()
    +            if key in self.encryptedArgs and val != CredMgmt.PASSWORD_MASK
    +        }
    +        if cred_data:
    +            ent = self._cred_mgmt.encrypt(self._makeStanzaName(name), ent)
    +            args = {key: val for key, val in ent.items() if key in self.encryptedArgs}
    +            self.update(name, **args)
    +        return ent
    +
    +    def _makeStanzaName(self, name):
    +        """Make the stanza name to store credential information
    +        in passwords.conf.
    +
    +        :param name: the entry name
    +        :return:
    +        """
    +        return name
    +
    +    def _reload(self, confInfo):
    +        path = "%s/_reload" % self.endpoint
    +        response, _ = rest.simpleRequest(
    +            path, sessionKey=self.getSessionKey(), method="POST"
    +        )
    +        if response.status != 200:
    +            exc = RESTException(response.status, response.messages)
    +            RH_Err.ctl(-1, exc, logLevel=logging.INFO)
    +
    +    def handleDisableAction(self, confInfo, disabled):
    +        self.update(self.callerArgs.id, disabled=disabled)
    +
    +    def handleCustom(self, confInfo, **params):
    +        if self.customAction in ["acl"]:
    +            return self.handleACL(confInfo)
    +
    +        if self.customAction == "disable":
    +            self.handleDisableAction(confInfo, "1")
    +        elif self.customAction == "enable":
    +            self.handleDisableAction(confInfo, "0")
    +        elif self.customAction == "_reload":
    +            self._reload(confInfo)
    +        elif self.customAction == "move":
    +            self.move(confInfo, **params)
    +        elif self.customAction == "_sync":
    +            self.handleSyncAction(confInfo, **params)
    +        else:
    +            RH_Err.ctl(1101, "action=%s" % self.customAction, logLevel=logging.INFO)
    +
    +    def user_app(self):
    +        """Get context info: user/app or namespace/owner"""
    +        app = self.context != admin.CONTEXT_NONE and self.appName or "-"
    +        user = self.context == admin.CONTEXT_APP_AND_USER and self.userName or "nobody"
    +        return user, app
    +
    +    def all(self):
    +        # count=0 and offset=0 allow the rest handler
    +        # to perform pagination on the full set of results.
    +        # The pagination functions expect to apply pagination
    +        # against the full set of results.
    +        user, app = self.user_app()
    +        get_args = {
    +            "output_mode": "json",
    +            "count": -1,
    +        }
    +        ents = get_entities(self.endpoint, self.getSessionKey(), user, app, get_args)
    +        return {name: self.decode(name, ent) for name, ent in list(ents.items())}
    +
    +    def get(self, name):
    +        user, app = self.user_app()
    +        ent = entity.getEntity(
    +            self.endpoint,
    +            name,
    +            namespace=app,
    +            owner=user,
    +            sessionKey=self.getSessionKey(),
    +        )
    +        return self.decode(name, ent)
    +
    +    def create(self, name, **params):
    +        user, app = self.user_app()
    +        new = entity.Entity(self.endpoint, "_new", namespace=app, owner=user)
    +
    +        try:
    +            new["name"] = name
    +            for arg, val in list(params.items()):
    +                new[arg] = val
    +            entity.setEntity(new, sessionKey=self.getSessionKey())
    +        except Exception as exc:
    +            RH_Err.ctl(-1, exc, logLevel=logging.INFO)
    +
    +    def delete(self, name):
    +        user, app = self.user_app()
    +        entity.deleteEntity(
    +            self.endpoint,
    +            name,
    +            namespace=app,
    +            owner=user,
    +            sessionKey=self.getSessionKey(),
    +        )
    +
    +    def update(self, name, **params):
    +        user, app = self.user_app()
    +        try:
    +            ent = entity.getEntity(
    +                self.endpoint,
    +                name,
    +                namespace=app,
    +                owner=user,
    +                sessionKey=self.getSessionKey(),
    +            )
    +
    +            for arg, val in list(params.items()):
    +                ent[arg] = val
    +
    +            entity.setEntity(ent, sessionKey=self.getSessionKey())
    +        except Exception as exc:
    +            RH_Err.ctl(-1, exc, logLevel=logging.INFO)
    +
    +    def getCallerArgs(self):
    +        callargs = dict()
    +        for n, v in list(self.callerArgs.data.items()):
    +            callargs.update({n: v[0]})
    +        return callargs
    +
    +    def move(self, confInfo, **params):
    +        user, app = self.user_app()
    +        args = self.getCallerArgs()
    +        if hasattr(self, "encode"):
    +            args = self.encode(args)
    +
    +        postArgs = {"app": args["app"], "user": args["user"]}
    +        path = entity.buildEndpoint(
    +            self.endpoint, entityName=self.callerArgs.id, namespace=app, owner=user
    +        )
    +        path += "/move"
    +
    +        response, _ = rest.simpleRequest(
    +            path, sessionKey=self.getSessionKey(), method="POST", postargs=postArgs
    +        )
    +        if response.status != 200:
    +            exc = RESTException(response.status, response.messages)
    +            RH_Err.ctl(-1, exc, logLevel=logging.INFO)
    +
    +    def handleSyncAction(self, confInfo, **params):
    +        if self.exist4sync:
    +            self.handleEdit(confInfo)
    +        else:
    +            self.handleCreate(confInfo)
    +
    +    def _getHandlerName(self):
    +        return self.__class__.__name__
    +
    +    def _log_request(self):
    +        actions = {
    +            admin.ACTION_CREATE: "create",
    +            admin.ACTION_LIST: "list",
    +            admin.ACTION_EDIT: "edit",
    +            admin.ACTION_REMOVE: "remove",
    +            admin.ACTION_MEMBERS: "members",
    +            admin.ACTION_RELOAD: "reload",
    +        }
    +
    +        msg = (
    +            "Splunk Add-on REST Handler Request: "
    +            "endpoint={endpoint}, "
    +            "entry={entry}, "
    +            "action={action}, "
    +            "custom_action={custom_action}, "
    +            "args={args}".format(
    +                endpoint=self.endpoint,
    +                entry=self.callerArgs.id,
    +                action=actions.get(self.requestedAction, None),
    +                custom_action=self.customAction,
    +                args=json.dumps([arg for arg in self.callerArgs.data]),
    +            )
    +        )
    +        if self.requestedAction == admin.ACTION_LIST:
    +            stulog.logger.debug(msg)
    +        else:
    +            stulog.logger.info(msg)
    +
    +
    +class BaseModel:
    +    """Model of Data.
    +    It ensure that key/value stored in *.conf are mapped to storage key/value,
    +    key/value shown to user are mapped to interface key/value.
    +    """
    +
    +    # REST prefix. Default is lower-case app name.
    +    # Change it if needed.
    +    rest_prefix = APP_NAME
    +
    +    # Endpoint, specifies the conf name, in form:
    +    # configs/conf-<conf_file_name>
    +    endpoint = ""
    +
    +    # Argument names:
    +    # arguments are required (interface keys, which are shown to user).
    +    requiredArgs = set()
    +    # arguments are optional (interface keys, which are shown to user).
    +    optionalArgs = set()
    +    # arguments will be ignored ,not saved
    +    # (interface keys, which are shown to user).
    +    transientArgs = set()
    +    # arguments need to be encrypted
    +    # (storing keys, which are the ones after key mapping).
    +    encryptedArgs = set()
    +    allowExtra = False  # is extra parameters to persist allowed.
    +
    +    defaultVals = {}  # default values for some fields.
    +    validators = {}  # validators specified for fields
    +    normalisers = {}  # normalisers specified for fields
    +    keyMap = {}  # arguments' name mapping: interface key ==> storage key
    +    valMap = {}  # arguments' value mapping
    +
    +    # Extra fields in return data (metadata fields).
    +    outputExtraFields = (
    +        "eai:acl",
    +        "acl",
    +        "eai:attributes",
    +        "eai:appName",
    +        "eai:userName",
    +        "disabled",
    +    )
    +
    +    # Required capabilities for this REST Endpoint.
    +    # Empty string means no need to check capability.
    +    # It will add ``rest_prefix`` automatically.
    +    #   cap4endpoint: basic capability for this endpoint.
    +    #   cap4get_cred: capability to get credential info.
    +    cap4endpoint = "endpoint"
    +    cap4get_cred = "get_credential"
    +
    +    def validate(self, args):
    +        """Validate request arguments."""
    +        for k, vs in list(args.items()):
    +            if k not in self.validators or not vs:
    +                continue
    +            if not isinstance(vs, list):
    +                vs = [vs]
    +            for v in vs:
    +                if not self.validators[k].validate(v, args):
    +                    RH_Err.ctl(
    +                        1100,
    +                        msgx=(f"{self.validators[k].msg} - field={k}"),
    +                        logLevel=logging.INFO,
    +                    )
    +        return args
    +
    +    def normalize(self, data):
    +        """Normalize request arguments or response data."""
    +        for k, vs in list(data.items()):
    +            if k not in self.normalisers or not vs:
    +                continue
    +            if isinstance(vs, list) or isinstance(vs, dict) or isinstance(vs, tuple):
    +                data[k] = [
    +                    self.normalisers[k].normalize(v) if isinstance(v, str) else v
    +                    for v in vs
    +                ]
    +            else:
    +                data[k] = self.normalisers[k].normalize(vs)
    +        return data
    +
    +
    +def ResourceHandler(model, handler=BaseRestHandler):
    +    return type(handler.__name__, (handler, model), {})
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/base_hook_mixin.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/base_hook_mixin.py
    new file mode 100644
    index 0000000..120b19b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/base_hook_mixin.py
    @@ -0,0 +1,48 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +
    +class BaseHookMixin:
    +    """Base Hook Mixin class"""
    +
    +    def create_hook(self, session_key, config_name, stanza_id, payload):
    +        """Create hook called before the actual create action
    +
    +        Args:
    +            config_name: configuration name
    +            stanza_id: the id of the stanza to create
    +            payload: data dict
    +        """
    +        pass
    +
    +    def edit_hook(self, session_key, config_name, stanza_id, payload):
    +        """Edit hook called before the actual create action
    +
    +        Args:
    +            config_name: configuration name
    +            stanza_id: the id of the stanza to edit
    +            payload: data dict
    +        """
    +        pass
    +
    +    def delete_hook(self, session_key, config_name, stanza_id):
    +        """Delete hook called before the actual create action
    +
    +        Args:
    +            config_name: configuration name
    +            stanza_id: the id of the stanza to delete
    +        """
    +        pass
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/cred_mgmt.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/cred_mgmt.py
    new file mode 100644
    index 0000000..94cc7de
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/cred_mgmt.py
    @@ -0,0 +1,172 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""Credential Management for REST Endpoint
    +"""
    +
    +
    +import json
    +
    +import splunk
    +from splunk import rest
    +from splunktalib.credentials import CredentialManager as CredMgr
    +
    +from .error_ctl import RestHandlerError
    +from .util import getBaseAppName
    +
    +__all__ = ["CredMgmt"]
    +
    +
    +class CredMgmt:
    +    """Credential Management stored in app.conf
    +
    +    Note: Override it if customized form of ``realm``, ``username``,
    +        and ``password``.
    +        If so, override method ``context``.
    +    """
    +
    +    PASSWORD_MASK = "********"
    +    REALM_TEMPLATE = "__REST_CREDENTIAL__#{baseApp}#{endpoint}#{stanzaName}"
    +
    +    def __init__(self, sessionKey, user, app, endpoint, encryptedArgs):
    +        self._splunkMgmtUri = rest.makeSplunkdUri()
    +        self._sessionKey = sessionKey
    +        self._user, self._app = user, app
    +        self._endpoint = endpoint
    +        self._encryptedArgs = set(encryptedArgs)
    +
    +    def context(self, stanzaName, data=None):
    +        """Get context for credential, including ``realm``, ``username``
    +            and ``password``.
    +        It will be stored in ``app.conf`` in form:
    +            [credential:<realm>:<username>]
    +            password = <password>
    +
    +        Note: Override it if customized form of context needed.
    +
    +        :param stanzaName: stanza name to be encrypted
    +        :param data: data to be encrypted which is a dict. It is ``None``
    +            for decrypt & delete.
    +        :return: a tuple (realm, username, password)
    +        """
    +        realm = CredMgmt.REALM_TEMPLATE.format(
    +            baseApp=getBaseAppName(), endpoint=self._endpoint, stanzaName=stanzaName
    +        )
    +        username = "username"
    +        password = "" if data is None else json.dumps(data)
    +        return realm, username, password
    +
    +    def encrypt(self, stanzaName, data):
    +        """Encrypt data with given fields.
    +
    +        :param stanzaName: the stanza name for external information
    +            of the data in some *.conf
    +        :param data: data to encrypt, a dict.
    +        :return:
    +        """
    +        cred_data_new = {
    +            key: ("" if val is None else val)
    +            for key, val in data.items()
    +            if key in self._encryptedArgs and val != CredMgmt.PASSWORD_MASK
    +        }
    +        if not cred_data_new:
    +            return data
    +
    +        try:
    +            cred_data = self.decrypt(stanzaName, {})
    +        except splunk.ResourceNotFound:
    +            cred_data = {}
    +
    +        cred_data.update(cred_data_new)
    +        realm, username, password = self.context(stanzaName, data=cred_data)
    +        cred_mgr = CredMgr(
    +            self._splunkMgmtUri,
    +            self._sessionKey,
    +            app=self._app,
    +            owner=self._user,
    +            realm=realm,
    +        )
    +        try:
    +            # since the size of the to-be-encrypted data is not fixed,
    +            # if the new data have smaller size than the previous one,
    +            # part of the old data won't be updated, then the updated data will be corrupted.
    +            # we have to delete the old data first.
    +            cred_mgr.delete(username, throw=True)
    +            cred_mgr.update({username: cred_data})
    +            for arg in data:
    +                if arg in self._encryptedArgs:
    +                    data[arg] = CredMgmt.PASSWORD_MASK
    +        except Exception as exc:
    +            RestHandlerError.ctl(1020, msgx=exc, shouldPrint=False, shouldRaise=False)
    +        return data
    +
    +    def decrypt(self, stanzaName, data):
    +        """Decrypt data with given fields.
    +        If a field is not magic token in data, it will be ignored.
    +
    +        :param stanzaName: the stanza name for external information
    +            of the data in some *.conf
    +        :param data: container to store the result, a dict.
    +        :return:
    +        """
    +        if not self._encryptedArgs:
    +            return data
    +        realm, username, password = self.context(stanzaName)
    +        cred_mgr = CredMgr(
    +            self._splunkMgmtUri,
    +            self._sessionKey,
    +            app=self._app,
    +            owner=self._user,
    +            realm=realm,
    +        )
    +
    +        try:
    +            creds = cred_mgr.get_clear_password(username)
    +        except Exception as exc:
    +            RestHandlerError.ctl(1021, msgx=exc, shouldPrint=True, shouldRaise=True)
    +        cred = creds.get(username, {})
    +
    +        for arg, val in list(cred.items()):
    +            data[arg] = val if arg in self._encryptedArgs else data[arg]
    +        return data
    +
    +    def delete(self, stanzaName):
    +        """Delete encrypted data.
    +
    +        :param stanzaName: the stanza name for external information of
    +            the data in some *.conf
    +        :return:
    +        """
    +        if len(self._encryptedArgs) <= 0:
    +            return
    +
    +        realm, username, password = self.context(stanzaName)
    +        cred_mgr = CredMgr(
    +            self._splunkMgmtUri,
    +            self._sessionKey,
    +            app=self._app,
    +            owner=self._user,
    +            realm=realm,
    +        )
    +        try:
    +            cred_mgr.delete(username, throw=True)
    +        except Exception as exc:
    +            RestHandlerError.ctl(1022, msgx=exc, shouldPrint=False, shouldRaise=False)
    +            return False
    +        return True
    +
    +    def setEncryptedArgs(self, encryptedArgs):
    +        self._encryptedArgs = set(encryptedArgs)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/credentials.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/credentials.py
    new file mode 100644
    index 0000000..1435678
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/credentials.py
    @@ -0,0 +1,450 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""Credentials Management for REST Endpoint
    +"""
    +
    +
    +import json
    +import urllib.parse
    +
    +from solnlib.credentials import CredentialManager, CredentialNotExistException
    +
    +from .error import RestError
    +from .util import get_base_app_name
    +
    +__all__ = [
    +    "RestCredentialsContext",
    +    "RestCredentials",
    +]
    +
    +
    +class RestCredentialsContext:
    +    """
    +    Credentials' context, including realm, username and password.
    +    """
    +
    +    REALM = "__REST_CREDENTIAL__#{base_app}#{endpoint}"
    +
    +    def __init__(self, endpoint, name, *args, **kwargs):
    +        self._endpoint = endpoint
    +        self._name = name
    +        self._args = args
    +        self._kwargs = kwargs
    +
    +    def realm(self):
    +        """
    +        RestCredentials context ``realm``.
    +        :return:
    +        """
    +        return self.REALM.format(
    +            base_app=get_base_app_name(),
    +            endpoint=self._endpoint.internal_endpoint.strip("/"),
    +        )
    +
    +    def username(self):
    +        """
    +        RestCredentials context ``username``.
    +        :return:
    +        """
    +        return self._name
    +
    +    def dump(self, data):
    +        """
    +        RestCredentials context ``password``.
    +        Dump data to string.
    +        :param data: data to be encrypted
    +        :type data: dict
    +        :return:
    +        """
    +        return json.dumps(data)
    +
    +    def load(self, string):
    +        """
    +        RestCredentials context ``password``.
    +        Load data from string.
    +        :param string: data has been decrypted
    +        :type string: str
    +        :return:
    +        """
    +        try:
    +            return json.loads(string)
    +        except ValueError:
    +            raise RestError(500, "Fail to load encrypted string, invalid JSON")
    +
    +
    +class RestCredentials:
    +    """
    +    Credential Management stored in passwords.conf
    +    """
    +
    +    # Changed password constant to six '*' to make it consistent with solnlib password constant
    +    PASSWORD = "******"
    +    EMPTY_VALUE = ""
    +
    +    def __init__(self, splunkd_uri, session_key, endpoint):
    +        self._splunkd_uri = splunkd_uri
    +        self._splunkd_info = urllib.parse.urlparse(self._splunkd_uri)
    +        self._session_key = session_key
    +        self._endpoint = endpoint
    +        self._realm = "__REST_CREDENTIAL__#{base_app}#{endpoint}".format(
    +            base_app=get_base_app_name(),
    +            endpoint=self._endpoint.internal_endpoint.strip("/"),
    +        )
    +
    +    def get_encrypted_field_names(self, name):
    +        return [x.name for x in self._endpoint.model(name).fields if x.encrypted]
    +
    +    def encrypt_for_create(self, name, data):
    +        """
    +            force to encrypt all fields that need to be encrypted
    +            used for create scenarios
    +        :param name:
    +        :param data:
    +        :return:
    +        """
    +        encrypted_field_names = self.get_encrypted_field_names(name)
    +        encrypting = {}
    +        for field_name in encrypted_field_names:
    +            if field_name in data and data[field_name]:
    +                # if it exist in data and it's not empty,
    +                # encrypt it and set original value as "****..."
    +                encrypting[field_name] = data[field_name]
    +                data[field_name] = self.PASSWORD
    +
    +        if encrypting:
    +            # only save credential when the stanza is existing in
    +            # passwords.conf or encrypting data is not empty
    +            self._set(name, encrypting)
    +
    +    def encrypt_for_update(self, name, data):
    +        """
    +
    +        :param name:
    +        :param data:
    +        :return:
    +        """
    +        encrypted_field_names = self.get_encrypted_field_names(name)
    +        encrypting = {}
    +        if not encrypted_field_names:
    +            # return if there are not encrypted fields
    +            return
    +        for field_name in encrypted_field_names:
    +            if field_name in data and data[field_name]:
    +                if data[field_name] != self.PASSWORD:
    +                    # if the field in data and not empty and it's not '*******', encrypted it
    +                    encrypting[field_name] = data[field_name]
    +                    data[field_name] = self.PASSWORD
    +                else:
    +                    # if the field value is '******', keep the original value
    +                    original_clear_password = self._get(name)
    +                    if original_clear_password and original_clear_password.get(
    +                        field_name
    +                    ):
    +                        encrypting[field_name] = original_clear_password[field_name]
    +                    else:
    +                        # original password does not exist, use '******' as password
    +                        encrypting[field_name] = data[field_name]
    +            elif field_name in data and not data[field_name]:
    +                data[field_name] = ""
    +            else:
    +                # field not in data
    +                # if the optional encrypted field is not passed, keep original if it exist
    +                original_clear_password = self._get(name)
    +                if original_clear_password and original_clear_password.get(field_name):
    +                    encrypting[field_name] = original_clear_password[field_name]
    +                    data[field_name] = self.PASSWORD
    +
    +        if encrypting:
    +            self._set(name, encrypting)
    +        else:
    +            self.delete(name)
    +
    +    def decrypt_for_get(self, name, data):
    +        """
    +            encrypt password if conf changed and return data that needs to write back to conf
    +        :param name:
    +        :param data:
    +        :return:
    +        """
    +        data_need_write_to_conf = dict()
    +        # password dict needs to be encrypted
    +        encrypting = dict()
    +        encrypted_field_names = self.get_encrypted_field_names(name)
    +        if not encrypted_field_names:
    +            return
    +        try:
    +            # try to get clear password for the entity
    +            clear_password = self._get(name)
    +            # password exist for the entity
    +            for field_name in encrypted_field_names:
    +                if field_name in data and data[field_name]:
    +                    if data[field_name] != self.PASSWORD:
    +                        # if the field exist in data and not equals to '*******'
    +                        # add to dict to be encrypted, else treat it as unchanged
    +                        encrypting[field_name] = data[field_name]
    +                        data_need_write_to_conf[field_name] = self.PASSWORD
    +
    +                    else:
    +                        # get clear password for the field
    +                        data[field_name] = clear_password[field_name]
    +                        encrypting[field_name] = clear_password[field_name]
    +
    +            if encrypting and clear_password != encrypting:
    +                # update passwords.conf if password changed
    +                self._set(name, encrypting)
    +        except CredentialNotExistException:
    +            # password does not exist for the entity
    +            for field_name in encrypted_field_names:
    +                if field_name in data and data[field_name]:
    +                    if data[field_name] != self.PASSWORD:
    +                        # if the field exist in data and not equals to '*******'
    +                        # add to dict to be encrypted
    +                        encrypting[field_name] = data[field_name]
    +                        data_need_write_to_conf[field_name] = self.PASSWORD
    +                    else:
    +                        # treat '*******' as password
    +                        encrypting[field_name] = self.PASSWORD
    +
    +            if encrypting:
    +                # set passwords.conf if encrypting data is not empty
    +                self._set(name, encrypting)
    +
    +        return data_need_write_to_conf
    +
    +    def encrypt(self, name, data):
    +        """
    +
    +        :param name:
    +        :param data:
    +        :return:
    +        """
    +        # Check if encrypt is needed
    +        model = self._endpoint.model(name)
    +        need_encrypting = all(field.encrypted for field in model.fields)
    +        if not need_encrypting:
    +            return
    +        try:
    +            encrypted = self._get(name)
    +            existing = True
    +        except CredentialNotExistException:
    +            encrypted = {}
    +            existing = False
    +        encrypting = self._filter(name, data, encrypted)
    +        self._merge(name, encrypted, encrypting)
    +        if existing or encrypting:
    +            # only save credential when the stanza is existing in
    +            # passwords.conf or encrypting data is not empty
    +            self._set(name, encrypting)
    +
    +    def decrypt(self, name, data):
    +        """
    +
    +        :param name:
    +        :param data:
    +        :return: If the passwords.conf is updated, masked data.
    +            Else, None.
    +        """
    +        try:
    +            # clear password object loads from json
    +            encrypted = self._get(name)
    +            existing = True
    +        except CredentialNotExistException:
    +            encrypted = {}
    +            existing = False
    +        # get fields to be encrypted
    +        encrypting = self._filter(name, data, encrypted)
    +        self._merge(name, encrypted, encrypting)
    +        if existing or encrypting:
    +            # only save credential when the stanza is existing in
    +            # passwords.conf or encrypting data is not empty
    +            self._set(name, encrypting)
    +        data.update(encrypting)
    +        return encrypted
    +
    +    def decrypt_all(self, data):
    +        """
    +        :param data:
    +        :return: changed stanza list
    +        """
    +        credential_manager = CredentialManager(
    +            self._session_key,
    +            owner=self._endpoint.user,
    +            app=self._endpoint.app,
    +            realm=self._realm,
    +            scheme=self._splunkd_info.scheme,
    +            host=self._splunkd_info.hostname,
    +            port=self._splunkd_info.port,
    +        )
    +        all_passwords = credential_manager.get_clear_passwords_in_realm()
    +        realm_passwords = [x for x in all_passwords if x["realm"] == self._realm]
    +        return self._merge_passwords(data, realm_passwords)
    +
    +    @staticmethod
    +    def _delete_empty_value_for_dict(dct):
    +        empty_value_names = [k for k, v in dct.items() if v == ""]
    +        for k in empty_value_names:
    +            del dct[k]
    +
    +    def _merge_passwords(self, data, passwords):
    +        """
    +        return if some fields need to write with new "******"
    +        """
    +        # merge clear passwords to response data
    +        changed_item_list = []
    +
    +        password_dict = {
    +            pwd["username"]: json.loads(pwd["clear_password"]) for pwd in passwords
    +        }
    +        # existed passwords models: previously has encrypted value
    +        existing_encrypted_items = [x for x in data if x["name"] in password_dict]
    +
    +        # previously has no encrypted value
    +        not_encrypted_items = [x for x in data if x["name"] not in password_dict]
    +
    +        # For model that password existed
    +        # 1.Password changed: Update it and add to changed_item_list
    +        # 2.Password unchanged: Get the password and update the response data
    +        for existed_model in existing_encrypted_items:
    +            name = existed_model["name"]
    +            clear_password = password_dict[name]
    +            need_write_magic_pwd = False
    +            need_write_back_pwd = False
    +            for k, v in clear_password.items():
    +                # make sure key exist in model content
    +                if k in existed_model["content"]:
    +                    if existed_model["content"][k] == self.PASSWORD:
    +                        # set existing as raw value
    +                        existed_model["content"][k] = v
    +                    elif existed_model["content"][k] == "":
    +                        # mark to delete it
    +                        clear_password[k] = ""
    +                        need_write_back_pwd = True
    +                        continue
    +                    else:
    +                        need_write_magic_pwd = True
    +                        need_write_back_pwd = True
    +                        clear_password[k] = existed_model["content"][k]
    +                else:
    +                    # mark to delete it
    +                    clear_password[k] = ""
    +                    need_write_back_pwd = True
    +
    +            # update the password storage
    +            if need_write_magic_pwd:
    +                changed_item_list.append(existed_model)
    +
    +            if need_write_back_pwd:
    +                self._delete_empty_value_for_dict(clear_password)
    +                if clear_password:
    +                    self._set(name, clear_password)
    +                else:
    +                    # there's no any pwd any more, directly delete it.
    +                    self.delete(name)
    +
    +        # For other models, encrypt the password and return
    +        for other_model in not_encrypted_items:
    +            name = other_model["name"]
    +            content = other_model["content"]
    +            encrypted_field_names = self.get_encrypted_field_names(name)
    +            clear_password = {}
    +            for field_name in encrypted_field_names:
    +                # make sure key exist in model content
    +                if field_name in content and content[field_name] != "":
    +                    clear_password[field_name] = content[field_name]
    +            if clear_password:
    +                self._set(name, clear_password)
    +
    +        changed_item_list.extend(not_encrypted_items)
    +        return changed_item_list
    +
    +    def delete(self, name):
    +        context = RestCredentialsContext(self._endpoint, name)
    +        mgr = self._get_manager(context)
    +        try:
    +            mgr.delete_password(user=context.username())
    +        except CredentialNotExistException:
    +            pass
    +
    +    def _set(self, name, credentials):
    +        if credentials is None:
    +            return
    +        context = RestCredentialsContext(self._endpoint, name)
    +        mgr = self._get_manager(context)
    +        mgr.set_password(user=context.username(), password=context.dump(credentials))
    +
    +    def _get(self, name):
    +        context = RestCredentialsContext(self._endpoint, name)
    +        mgr = self._get_manager(context)
    +        try:
    +            string = mgr.get_password(user=context.username())
    +        except CredentialNotExistException:
    +            return None
    +        return context.load(string)
    +
    +    def _filter(self, name, data, encrypted_data):
    +        model = self._endpoint.model(name)
    +        encrypting_data = {}
    +        for field in model.fields:
    +            if not field.encrypted:
    +                # remove non-encrypted fields
    +                if field.name in encrypted_data:
    +                    del encrypted_data[field.name]
    +                continue
    +            if field.name not in data:
    +                # ignore un-posted fields
    +                continue
    +            if data[field.name] == self.PASSWORD:
    +                # ignore already-encrypted fields
    +                continue
    +            if data[field.name] != self.EMPTY_VALUE:
    +                encrypting_data[field.name] = data[field.name]
    +                # non-empty fields
    +                data[field.name] = self.PASSWORD
    +                if field.name in encrypted_data:
    +                    del encrypted_data[field.name]
    +        return encrypting_data
    +
    +    def _merge(self, name, encrypted, encrypting):
    +        model = self._endpoint.model(name)
    +        for field in model.fields:
    +            if field.encrypted is False:
    +                continue
    +
    +            val_encrypting = encrypting.get(field.name)
    +            if val_encrypting:
    +                encrypted[field.name] = self.PASSWORD
    +                continue
    +            elif val_encrypting == self.EMPTY_VALUE:
    +                del encrypting[field.name]
    +                encrypted[field.name] = self.EMPTY_VALUE
    +                continue
    +
    +            val_encrypted = encrypted.get(field.name)
    +            if val_encrypted:
    +                encrypting[field.name] = val_encrypted
    +                del encrypted[field.name]
    +
    +    def _get_manager(self, context):
    +        return CredentialManager(
    +            self._session_key,
    +            owner=self._endpoint.user,
    +            app=self._endpoint.app,
    +            realm=context.realm(),
    +            scheme=self._splunkd_info.scheme,
    +            host=self._splunkd_info.hostname,
    +            port=self._splunkd_info.port,
    +        )
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/datainput.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/datainput.py
    new file mode 100644
    index 0000000..fc4d0b3
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/datainput.py
    @@ -0,0 +1,216 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""REST Manager for data inputs (a wrapper of data inputs).
    +
    +Note: It manages inputs.conf
    +
    +"""
    +
    +import collections
    +import json
    +import logging
    +import sys
    +from urllib.parse import quote
    +
    +from splunk import admin, rest
    +
    +from . import base, util
    +from .error_ctl import RestHandlerError as RH_Err
    +
    +__all__ = ["DataInputHandler", "DataInputModel"]
    +
    +
    +class DataInputHandler(base.BaseRestHandler):
    +    """A Wrapper of Splunk Data Input REST."""
    +
    +    def __init__(self, *args, **kwargs):
    +        base.BaseRestHandler.__init__(self, *args, **kwargs)
    +        assert hasattr(self, "dataInputName") and self.dataInputName, RH_Err.ctl(
    +            1002,
    +            msgx=f"{self._getHandlerName()}.dataInputName",
    +            shouldPrint=False,
    +        )
    +
    +        self._cred_mgmt = self.get_cred_mgmt(self.dataInputName)
    +
    +    def handleCreate(self, confInfo):
    +        args = self.encode(self.callerArgs.data)
    +        args["name"] = self.callerArgs.id
    +        try:
    +            rest.simpleRequest(
    +                self.makeRequestURL(),
    +                sessionKey=self.getSessionKey(),
    +                postargs=args,
    +                method="POST",
    +                raiseAllErrors=True,
    +            )
    +        except Exception as exc:
    +            RH_Err.ctl(-1, msgx=exc, logLevel=logging.INFO)
    +        return
    +
    +    def handleEdit(self, confInfo):
    +        args = self.encode(self.callerArgs.data, setDefault=True)
    +        try:
    +            rest.simpleRequest(
    +                self.makeRequestURL(),
    +                sessionKey=self.getSessionKey(),
    +                postargs=args,
    +                method="POST",
    +                raiseAllErrors=True,
    +            )
    +        except Exception as exc:
    +            RH_Err.ctl(-1, msgx=exc, logLevel=logging.INFO)
    +        return
    +
    +    def handleList(self, confInfo):
    +        user, app = self.user_app()
    +        try:
    +            response, content = rest.simpleRequest(
    +                self.makeRequestURL(),
    +                sessionKey=self.getSessionKey(),
    +                method="GET",
    +                raiseAllErrors=True,
    +            )
    +            res = json.loads(content)
    +            if "entry" in res:
    +                for entry in res["entry"]:
    +                    name, ent = entry["name"], entry["content"]
    +                    ent[admin.EAI_ENTRY_ACL] = entry["acl"]
    +                    ent = self.decode(name, self.convert(ent))
    +                    util.makeConfItem(name, ent, confInfo, user=user, app=app)
    +        except Exception as exc:
    +            RH_Err.ctl(-1, msgx=exc, logLevel=logging.INFO)
    +        return
    +
    +    def handleRemove(self, confInfo):
    +        try:
    +            rest.simpleRequest(
    +                self.makeRequestURL(),
    +                sessionKey=self.getSessionKey(),
    +                method="DELETE",
    +                raiseAllErrors=True,
    +            )
    +        except Exception as exc:
    +            RH_Err.ctl(-1, msgx=exc, logLevel=logging.INFO)
    +        self._cred_mgmt.delete(self._makeStanzaName(self.callerArgs.id))
    +        return
    +
    +    def handleCustom(self, confInfo, **params):
    +        if self.customAction in ["acl"]:
    +            return self.handleACL(confInfo)
    +
    +        if self.customAction == "disable":
    +            self.handleDisable(confInfo)
    +        elif self.customAction == "enable":
    +            self.handleEnable(confInfo)
    +        elif self.customAction == "sync":
    +            self.sync(confInfo, **params)
    +        else:
    +            RH_Err.ctl(-1, msgx="action=%s" % self.customAction, logLevel=logging.INFO)
    +
    +    def handleDisable(self, confInfo):
    +        try:
    +            rest.simpleRequest(
    +                self.makeRequestURL().replace(
    +                    "?output_mode=json", "/disable?output_mode=json"
    +                ),
    +                sessionKey=self.getSessionKey(),
    +                method="POST",
    +                raiseAllErrors=True,
    +            )
    +        except Exception as exc:
    +            RH_Err.ctl(-1, msgx=exc, logLevel=logging.INFO)
    +        return
    +
    +    def handleEnable(self, confInfo):
    +        try:
    +            rest.simpleRequest(
    +                self.makeRequestURL().replace(
    +                    "?output_mode=json", "/enable?output_mode=json"
    +                ),
    +                sessionKey=self.getSessionKey(),
    +                method="POST",
    +                raiseAllErrors=True,
    +            )
    +        except Exception as exc:
    +            RH_Err.ctl(-1, msgx=exc, logLevel=logging.INFO)
    +        return
    +
    +    def get(self, name):
    +        rest.simpleRequest(
    +            self.makeRequestURL(),
    +            sessionKey=self.getSessionKey(),
    +            method="GET",
    +            raiseAllErrors=True,
    +        )
    +        return
    +
    +    def makeRequestURL(self):
    +        user, app = self.user_app()
    +        eid = (
    +            None
    +            if self.callerArgs.id is None
    +            else quote(self.callerArgs.id.encode("utf-8"), safe="")
    +        )
    +        actions = (admin.ACTION_EDIT, admin.ACTION_LIST, admin.ACTION_REMOVE)
    +        name = (
    +            (self.requestedAction in actions and self.callerArgs.id is not None)
    +            and ("/" + eid)
    +            or ""
    +        )
    +        return (
    +            rest.makeSplunkdUri()
    +            + "servicesNS/"
    +            + user
    +            + "/"
    +            + app
    +            + "/data/inputs/"
    +            + self.dataInputName
    +            + name
    +            + "?output_mode=json&count=-1"
    +        )
    +
    +    def convertErrMsg(self, errMsg):
    +        err = json.loads(errMsg)
    +        return err["messages"][0]["text"]
    +
    +    def convert(self, data):
    +        if isinstance(data, str):
    +            return data.encode("utf-8")
    +        elif isinstance(data, collections.Mapping):
    +            return dict(list(map(self.convert, iter(data.items()))))
    +        elif isinstance(data, collections.Iterable):
    +            return type(data)(list(map(self.convert, data)))
    +        else:
    +            return data
    +
    +    def _makeStanzaName(self, name):
    +        return "{dataInputName}://{name}".format(
    +            dataInputName=self.dataInputName, name=name
    +        )
    +
    +
    +class DataInputModel(base.BaseModel):
    +    """Base Class of Data Input Model."""
    +
    +    # For Splunkd data input TEST API:
    +    # servicesNS/<user>/<app>/data/inputs/<dataInputName>
    +    dataInputName = ""
    +
    +
    +def ResourceHandler(model, handler=DataInputHandler):
    +    return type(handler.__name__, (handler, model), {})
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/eai.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/eai.py
    new file mode 100644
    index 0000000..bc4601a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/eai.py
    @@ -0,0 +1,73 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +
    +# EAI fields
    +
    +EAI_ACL = "eai:acl"
    +EAI_ATTRIBUTES = "eai:attributes"
    +EAI_USER = "eai:userName"
    +EAI_APP = "eai:appName"
    +
    +EAI_FIELD_PREFIX = "eai:"
    +EAI_FIELDS = [EAI_ACL, EAI_ATTRIBUTES, EAI_USER, EAI_APP]
    +
    +# elements of eai:attributes
    +EAI_ATTRIBUTES_OPTIONAL = "optionalFields"
    +EAI_ATTRIBUTES_REQUIRED = "requiredFields"
    +EAI_ATTRIBUTES_WILDCARD = "wildcardFields"
    +
    +
    +class RestEAI:
    +    def __init__(self, model, user, app, acl=None):
    +        self.model = model
    +        default_acl = {
    +            "owner": user,
    +            "app": app,
    +            "global": 1,
    +            "can_write": 1,
    +            "modifiable": 1,
    +            "removable": 1,
    +            "sharing": "global",
    +            "perms": {"read": ["*"], "write": ["admin"]},
    +        }
    +        self.acl = acl or default_acl
    +        self.user = user
    +        self.app = app
    +        self.attributes = self._build_attributes()
    +
    +    @property
    +    def content(self):
    +        return {
    +            EAI_ACL: self.acl,
    +            EAI_USER: self.user,
    +            EAI_APP: self.app,
    +            EAI_ATTRIBUTES: self.attributes,
    +        }
    +
    +    def _build_attributes(self):
    +        optional_fields = []
    +        required_fields = []
    +        for field in self.model.fields:
    +            if field.required:
    +                required_fields.append(field.name)
    +            else:
    +                optional_fields.append(field.name)
    +        return {
    +            EAI_ATTRIBUTES_OPTIONAL: optional_fields,
    +            EAI_ATTRIBUTES_REQUIRED: required_fields,
    +            EAI_ATTRIBUTES_WILDCARD: [],
    +        }
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/endpoint/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/endpoint/__init__.py
    new file mode 100644
    index 0000000..ffb37e7
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/endpoint/__init__.py
    @@ -0,0 +1,173 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +
    +from ..error import RestError
    +from ..util import get_base_app_name
    +
    +__all__ = [
    +    "RestModel",
    +    "RestEndpoint",
    +    "SingleModel",
    +    "MultipleModel",
    +    "DataInputModel",
    +]
    +
    +
    +class RestModel:
    +    def __init__(self, fields, name=None):
    +        """
    +        REST Model.
    +        :param name:
    +        :param fields:
    +        """
    +        self.name = name
    +        self.fields = fields
    +
    +
    +class RestEndpoint:
    +    """
    +    REST Endpoint.
    +    """
    +
    +    def __init__(self, user="nobody", app=None, *args, **kwargs):
    +        """
    +
    +        :param user:
    +        :param app: if None, it will be base app name
    +        :param args:
    +        :param kwargs:
    +        """
    +        self.user = user
    +        self.app = app or get_base_app_name()
    +        self.args = args
    +        self.kwargs = kwargs
    +
    +        # If reload is needed while GET request
    +        self.need_reload = False
    +
    +    @property
    +    def internal_endpoint(self):
    +        """
    +        Endpoint of Splunk internal service.
    +
    +        :return:
    +        """
    +        raise NotImplementedError()
    +
    +    def model(self, name):
    +        """
    +        Real model for given name.
    +
    +        :param name:
    +        :return:
    +        """
    +        raise NotImplementedError()
    +
    +    def _loop_fields(self, meth, name, data, *args, **kwargs):
    +        model = self.model(name)
    +        return [getattr(f, meth)(data, *args, **kwargs) for f in model.fields]
    +
    +    def validate(self, name, data, existing=None):
    +        self._loop_fields("validate", name, data, existing=existing)
    +
    +    def encode(self, name, data):
    +        self._loop_fields("encode", name, data)
    +
    +    def decode(self, name, data):
    +        self._loop_fields("decode", name, data)
    +
    +
    +class SingleModel(RestEndpoint):
    +    """
    +    REST Model with Single Mode. It will store stanzas
    +    with same format  into one conf file.
    +    """
    +
    +    def __init__(self, conf_name, model, user="nobody", app=None, *args, **kwargs):
    +        """
    +
    +        :param conf_name: conf file name
    +        :param model: REST model
    +        :type model: RestModel
    +        :param args:
    +        :param kwargs:
    +        """
    +        super().__init__(user=user, app=app, *args, **kwargs)
    +        self.need_reload = True
    +
    +        self._model = model
    +        self.conf_name = conf_name
    +        self.config_name = kwargs.get("config_name")
    +
    +    @property
    +    def internal_endpoint(self):
    +        return f"configs/conf-{self.conf_name}"
    +
    +    def model(self, name):
    +        return self._model
    +
    +
    +class MultipleModel(RestEndpoint):
    +    """
    +    REST Model with Multiple Modes. It will store
    +     stanzas with different formats into one conf file.
    +    """
    +
    +    def __init__(self, conf_name, models, user="nobody", app=None, *args, **kwargs):
    +        """
    +
    +        :param conf_name:
    +        :type conf_name: str
    +        :param models: list of RestModel
    +        :type models: list
    +        :param args:
    +        :param kwargs:
    +        """
    +        super().__init__(user=user, app=app, *args, **kwargs)
    +        self.need_reload = True
    +
    +        self.conf_name = conf_name
    +        self.models = {model.name: model for model in models}
    +
    +    @property
    +    def internal_endpoint(self):
    +        return f"configs/conf-{self.conf_name}"
    +
    +    def model(self, name):
    +        try:
    +            return self.models[name]
    +        except KeyError:
    +            raise RestError(404, "name=%s" % name)
    +
    +
    +class DataInputModel(RestEndpoint):
    +    """
    +    REST Model for Data Input.
    +    """
    +
    +    def __init__(self, input_type, model, user="nobody", app=None, *args, **kwargs):
    +        super().__init__(user=user, app=app, *args, **kwargs)
    +
    +        self.input_type = input_type
    +        self._model = model
    +
    +    @property
    +    def internal_endpoint(self):
    +        return f"data/inputs/{self.input_type}"
    +
    +    def model(self, name):
    +        return self._model
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/endpoint/converter.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/endpoint/converter.py
    new file mode 100644
    index 0000000..f26e0c6
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/endpoint/converter.py
    @@ -0,0 +1,312 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +Converters for Splunk configuration.
    +"""
    +
    +
    +import base64
    +import json
    +
    +__all__ = [
    +    "Converter",
    +    "Normaliser",
    +    "ChainOf",
    +    "UserDefined",
    +    "Unifier",
    +    "Boolean",
    +    "Lower",
    +    "Upper",
    +    "Mapping",
    +    "Base64",
    +    "JSON",
    +]
    +
    +
    +class Converter:
    +    """
    +    Converting data: encode for in-coming request
    +        and decode for out-coming response.
    +    """
    +
    +    def encode(self, value, request):
    +        """
    +        Encode data from client for request.
    +
    +        :param value: value to encode for request
    +        :param request: whole request data
    +        :return:
    +        """
    +        raise NotImplementedError()
    +
    +    def decode(self, value, response):
    +        """
    +        Decode data from storage for response.
    +
    +        :param value: value to decode for response
    +        :param response: whole response data
    +        :return:
    +        """
    +        raise NotImplementedError()
    +
    +
    +class Normaliser(Converter):
    +    """
    +    Normalizing data: same converting logic for encode & decode.
    +    """
    +
    +    def normalize(self, value, data):
    +        """
    +        Normalize a given value.
    +
    +        :param value: value to normalize
    +        :param data: whole payload
    +        :returns: normalized value.
    +        """
    +        raise NotImplementedError()
    +
    +    def encode(self, value, request):
    +        return self.normalize(value, request)
    +
    +    def decode(self, value, response):
    +        return self.normalize(value, response)
    +
    +
    +class ChainOf(Converter):
    +    """
    +    A composite of converters that will covert data with specified
    +    converters on by one, and returns result from the last converter.
    +    """
    +
    +    def __init__(self, *converters):
    +        """
    +
    +        :param converters: a list of converters
    +        """
    +        super().__init__()
    +        self._converters = converters
    +
    +    def encode(self, value, request):
    +        for converter in self._converters:
    +            value = converter.encode(value, request)
    +        return value
    +
    +    def decode(self, value, response):
    +        import copy
    +
    +        converters = copy.copy(self._converters)
    +        converters.reverse()
    +        for converter in converters:
    +            value = converter.decode(value, response)
    +        return value
    +
    +
    +class UserDefined(Converter):
    +    """
    +    User-defined normaliser.
    +
    +    The user-defined normaliser function should be in form:
    +    ``def fun(value, *args, **kwargs): ...``
    +
    +    Usage::
    +    >>> def my_encoder(value, request, args):
    +    >>>     if request == args:
    +    >>>         return value
    +    >>>     else:
    +    >>>         return value
    +    >>> my_converter = UserDefined(my_encoder, 'test_val')
    +    >>> my_converter.encode('value', {'key': 'value'}, 'value1')
    +
    +    """
    +
    +    def __init__(self, encoder, decoder=None, *args, **kwargs):
    +        """
    +
    +        :param encoder: user-defined function for encoding
    +        :param decoder: user-defined function for decoding.
    +            If None, it is the same to encoder.
    +        :param args:
    +        :param kwargs:
    +        """
    +        super().__init__()
    +        self._encoder = encoder
    +        self._decoder = decoder or self._encoder
    +        self._args = args
    +        self._kwargs = kwargs
    +
    +    def encode(self, value, request):
    +        return self._encoder(value, request, *self._args, **self._kwargs)
    +
    +    def decode(self, value, response):
    +        return self._decoder(value, response, *self._args, **self._kwargs)
    +
    +
    +class Lower(Normaliser):
    +    """
    +    Normalize a string to all lower cases.
    +    """
    +
    +    def normalize(self, value, data):
    +        return value.strip().lower()
    +
    +
    +class Upper(Normaliser):
    +    """
    +    Normalize a string to all upper cases.
    +    """
    +
    +    def normalize(self, value, data):
    +        return value.strip().upper()
    +
    +
    +class Unifier(Normaliser):
    +    """
    +    Many-to-one map for normalizing request & response.
    +    """
    +
    +    def __init__(
    +        self,
    +        value_map,
    +        default=None,
    +        case_sensitive=False,
    +    ):
    +        """
    +
    +        :param value_map:
    +            {"<unified value>": "<original value list>"}
    +        :param default: default value for input not in specific list
    +        :param case_sensitive: if it is False,
    +            it will return lower case
    +        """
    +        super().__init__()
    +        self._case_sensitive = case_sensitive
    +        self._default = default
    +        self._value_map = {}
    +        for val_new, val_old_list in value_map.items():
    +            for val_old in val_old_list:
    +                val_old = val_old if case_sensitive else val_old.lower()
    +                assert val_old not in self._value_map, (
    +                    'Normaliser "Unifier" only supports Many-to-one mapping: %s'
    +                    % val_old
    +                )
    +                self._value_map[val_old] = val_new
    +
    +    def normalize(self, value, data):
    +        need_lower = not self._case_sensitive and isinstance(value, str)
    +        val_old = value.lower() if need_lower else value
    +        val_default = self._default or value
    +        return self._value_map.get(val_old, val_default)
    +
    +
    +class Boolean(Unifier):
    +    """
    +    Normalize a boolean field.
    +
    +    Normalize given value to boolean: 0 or 1
    +        (for False and True respectively).
    +    If the given value is not-a-string or unrecognizable,
    +    it returns default value.
    +    """
    +
    +    VALUES_TRUE = {"true", "t", "1", "yes", "y"}
    +    VALUES_FALSE = {"false", "f", "0", "no", "n"}
    +
    +    def __init__(self, default=True):
    +        """
    +
    +        :param default: default for unrecognizable input of boolean.
    +        """
    +        super().__init__(
    +            value_map={
    +                "1": Boolean.VALUES_TRUE,
    +                "0": Boolean.VALUES_FALSE,
    +            },
    +            default="1" if default else "0",
    +            case_sensitive=False,
    +        )
    +
    +
    +class Mapping(Converter):
    +    """
    +    One-to-one map between interface value and storage value.
    +    If value is not in specific mapping,
    +    it will return the original value.
    +    """
    +
    +    def __init__(self, value_map, case_sensitive=False):
    +        """
    +
    +        :param value_map: {"<interface value>": "<storage value>"}
    +        :param case_sensitive: if it is False,
    +            it will return lower case
    +        """
    +        super().__init__()
    +        self._case_sensitive = case_sensitive
    +        self._map_interface, self._map_storage = {}, {}
    +        for interface, storage in value_map.items():
    +            self._check_and_set(interface, storage)
    +
    +    def _check_and_set(self, interface, storage):
    +        if not self._case_sensitive:
    +            interface = interface.lower()
    +            storage = storage.lower()
    +        assert interface not in self._map_interface, (
    +            'Converter "Mapping" only supports one-to-one mapping: "%s"' % interface
    +        )
    +        assert storage not in self._map_storage, (
    +            'Converter "Mapping" only supports one-to-one mapping: "%s"' % storage
    +        )
    +        self._map_interface[interface] = storage
    +        self._map_storage[storage] = interface
    +
    +    def encode(self, value, request):
    +        if self._case_sensitive:
    +            interface = value
    +        else:
    +            interface = value.lower()
    +        return self._map_interface.get(interface, value)
    +
    +    def decode(self, value, response):
    +        if self._case_sensitive:
    +            storage = value
    +        else:
    +            storage = value.lower()
    +        return self._map_storage.get(storage, value)
    +
    +
    +class Base64(Converter):
    +    """
    +    Covert input data to base64 string.
    +    """
    +
    +    def encode(self, value, request):
    +        return base64.b64encode(value)
    +
    +    def decode(self, value, response):
    +        return base64.b64decode(value)
    +
    +
    +class JSON(Converter):
    +    """
    +    Converter between object and JSON string.
    +    """
    +
    +    def encode(self, value, request):
    +        return json.dumps(value)
    +
    +    def decode(self, value, response):
    +        return json.loads(value)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/endpoint/field.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/endpoint/field.py
    new file mode 100644
    index 0000000..ef6053c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/endpoint/field.py
    @@ -0,0 +1,70 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +
    +from ..error import RestError
    +
    +__all__ = ["RestField"]
    +
    +
    +class RestField:
    +    """
    +    REST Field.
    +    """
    +
    +    def __init__(
    +        self,
    +        name,
    +        required=False,
    +        encrypted=False,
    +        default=None,
    +        validator=None,
    +        converter=None,
    +    ):
    +        self.name = name
    +        self.required = required
    +        self.encrypted = encrypted
    +        self.default = default
    +        self.validator = validator
    +        self.converter = converter
    +
    +    def validate(self, data, existing=None):
    +        # update case: check required field in data
    +        if existing and self.name in data and not data.get(self.name) and self.required:
    +            raise RestError(400, "Required field is missing: %s" % self.name)
    +        value = data.get(self.name)
    +        if not value and existing is None:
    +            if self.required:
    +                raise RestError(400, "Required field is missing: %s" % self.name)
    +            return
    +        if self.validator is None or not value:
    +            return
    +
    +        res = self.validator.validate(value, data)
    +        if not res:
    +            raise RestError(400, self.validator.msg)
    +
    +    def encode(self, data):
    +        value = data.get(self.name)
    +        if not value or self.converter is None:
    +            return
    +        data[self.name] = self.converter.encode(value, data)
    +
    +    def decode(self, data):
    +        value = data.get(self.name)
    +        if not value or self.converter is None:
    +            return
    +        data[self.name] = self.converter.decode(value, data)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/endpoint/validator.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/endpoint/validator.py
    new file mode 100644
    index 0000000..840637a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/endpoint/validator.py
    @@ -0,0 +1,485 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +Validators for Splunk configuration.
    +"""
    +
    +
    +import json
    +import re
    +import warnings
    +from inspect import isfunction
    +
    +__all__ = [
    +    "Validator",
    +    "ValidationError",
    +    "AnyOf",
    +    "AllOf",
    +    "RequiresIf",
    +    "UserDefined",
    +    "Enum",
    +    "Number",
    +    "String",
    +    "Pattern",
    +    "Host",
    +    "Port",
    +    "Datetime",
    +    "Email",
    +    "JsonString",
    +]
    +
    +
    +class Validator:
    +    """
    +    Base class of validators.
    +    """
    +
    +    def __init__(self):
    +        self._msg = ""
    +
    +    def validate(self, value, data):
    +        """
    +        Check if the given value is valid. It assumes that
    +        the given value is a string.
    +
    +        :param value: value to validate.
    +        :param data: whole payload in request.
    +        :return If the value is invalid, return True.
    +            Or return False.
    +        """
    +        raise NotImplementedError('Function "validate" needs to be implemented.')
    +
    +    @property
    +    def msg(self):
    +        """
    +        It will return the one with highest priority.
    +
    +        :return:
    +        """
    +        return self._msg if self._msg else "Invalid input value"
    +
    +    def put_msg(self, msg, *args, **kwargs):
    +        """
    +        Put message content into pool.
    +
    +        :param msg: error message content
    +        :return:
    +        """
    +        if args or "high_priority" in kwargs:
    +            warnings.warn(
    +                "`high_priority` arg is deprecated and at a time a single message string is kept in memory."
    +                " The last message passed to `put_msg` is returned by `msg` property.",
    +                FutureWarning,
    +            )
    +        self._msg = msg
    +
    +
    +class ValidationFailed(Exception):
    +    """
    +    Validation error.
    +    """
    +
    +    pass
    +
    +
    +class AnyOf(Validator):
    +    """
    +    A composite of validators that accepts values accepted by
    +    any of its component validators.
    +    """
    +
    +    def __init__(self, *validators):
    +        """
    +
    +        :param validators: A list of validators.
    +        """
    +        super().__init__()
    +        self._validators = validators
    +
    +    def validate(self, value, data):
    +        msgs = []
    +        for validator in self._validators:
    +            if not validator.validate(value, data):
    +                msgs.append(validator.msg)
    +            else:
    +                return True
    +        else:
    +            self.put_msg(
    +                "At least one of the following errors need to be fixed: %s"
    +                % json.dumps(msgs)
    +            )
    +            return False
    +
    +
    +class AllOf(Validator):
    +    """
    +    A composite of validators that accepts values accepted by
    +    all of its component validators.
    +    """
    +
    +    def __init__(self, *validators):
    +        """
    +
    +        :param validators: A list of validators.
    +        """
    +        super().__init__()
    +        self._validators = validators
    +
    +    def validate(self, value, data):
    +        msgs = []
    +        for validator in self._validators:
    +            if not validator.validate(value, data):
    +                msgs.append(validator.msg)
    +        if msgs:
    +            self.put_msg(
    +                "All of the following errors need to be fixed: %s" % json.dumps(msgs)
    +            )
    +            return False
    +        return True
    +
    +
    +class RequiresIf(Validator):
    +    """
    +    If the given field makes the specified condition as True,
    +    it requires some other fields are not empty
    +    in the payload of request.
    +    """
    +
    +    def __init__(self, fields, condition=None):
    +        """
    +
    +        :param fields: conditionally required field name list.
    +        :param condition: it can be:
    +            1. None means any non-empty string for given field
    +            2. A function takes value & data as parameters and
    +               returns a boolean value
    +        """
    +        assert isinstance(
    +            fields, (list, set, tuple)
    +        ), 'Argument "fields" should be list, set or tuple'
    +        super().__init__()
    +        self.fields = fields
    +        self.condition = condition
    +
    +    @classmethod
    +    def _is_empty(cls, value):
    +        return value is None or value == ""
    +
    +    def validate(self, value, data):
    +        if self.condition is None and not self._is_empty(value):
    +            need_validate = True
    +        else:
    +            assert isfunction(
    +                self.condition
    +            ), "Condition should be a function for RequiresIf validator"
    +            need_validate = self.condition(value, data)
    +        if not need_validate:
    +            return True
    +
    +        fields = []
    +        for field in self.fields:
    +            val = data.get(field)
    +            if val is None or val == "":
    +                fields.append(field)
    +        if fields:
    +            self.put_msg("For given input, fields are required: %s" % ", ".join(fields))
    +            return False
    +        return True
    +
    +
    +class UserDefined(Validator):
    +    """
    +    A validator that defined by user.
    +
    +    The user-defined validator function should be in form:
    +    ``def func(value, data, *args, **kwargs): ...``
    +    ValidationFailed will be raised if validation failed.
    +
    +    Usage::
    +    >>> def my_validate(value, data, args):
    +    >>>     if value != args or not data:
    +    >>>         raise ValidationFailed('Invalid input')
    +    >>>
    +    >>> my_validator = UserDefined(my_validate, 'test_val')
    +    >>> my_validator.validate('value', {'key': 'value'}, 'value1')
    +
    +    """
    +
    +    def __init__(self, validator, *args, **kwargs):
    +        """
    +
    +        :param validator: user-defined validating function
    +        """
    +        super().__init__()
    +        self._validator = validator
    +        self._args = args
    +        self._kwargs = kwargs
    +
    +    def validate(self, value, data):
    +        try:
    +            self._validator(value, data, *self._args, **self._kwargs)
    +        except ValidationFailed as exc:
    +            self.put_msg(str(exc))
    +            return False
    +        else:
    +            return True
    +
    +
    +class Enum(Validator):
    +    """
    +    A validator that accepts only a finite set of values.
    +    """
    +
    +    def __init__(self, values=()):
    +        """
    +
    +        :param values: The collection of valid values
    +        """
    +        super().__init__()
    +        try:
    +            self._values = set(values)
    +        except TypeError:
    +            self._values = list(values)
    +
    +        self.put_msg("Value should be in %s" % json.dumps(list(self._values)))
    +
    +    def validate(self, value, data):
    +        return value in self._values
    +
    +
    +class Number(Validator):
    +    """
    +    A validator that accepts values within a certain range.
    +    This is for numeric value.
    +
    +    Accepted condition: min_val <= value <= max_val
    +    """
    +
    +    def __init__(self, min_val=None, max_val=None, is_int=False):
    +        """
    +
    +        :param min_val: if not None, it requires min_val <= value
    +        :param max_val: if not None, it requires value < max_val
    +        :param is_int: the value should be integer or not
    +        """
    +
    +        assert self._check(min_val) and self._check(
    +            max_val
    +        ), "{min_val} & {max_val} should be numbers".format(
    +            min_val=min_val,
    +            max_val=max_val,
    +        )
    +
    +        super().__init__()
    +        self._min_val = min_val
    +        self._max_val = max_val
    +        self._is_int = is_int
    +
    +    def _check(self, val):
    +        return val is None or isinstance(val, (int, float))
    +
    +    def validate(self, value, data):
    +        try:
    +            value = int(value) if self._is_int else float(value)
    +        except ValueError:
    +            self.put_msg(
    +                "Invalid format for %s value"
    +                % ("integer" if self._is_int else "numeric")
    +            )
    +            return False
    +
    +        msg = None
    +        if not self._min_val and self._max_val and value > self._max_val:
    +            msg = f"Value should be smaller than {self._max_val}"
    +        elif not self._max_val and self._min_val and value < self._min_val:
    +            msg = "Value should be no smaller than {min_val}".format(
    +                min_val=self._min_val
    +            )
    +        elif self._min_val and self._max_val:
    +            if value < self._min_val or value > self._max_val:
    +                msg = "Value should be between {min_val} and {max_val}".format(
    +                    min_val=self._min_val,
    +                    max_val=self._max_val,
    +                )
    +        if msg is not None:
    +            self.put_msg(msg)
    +            return False
    +        return True
    +
    +
    +class String(Validator):
    +    """
    +    A validator that accepts string values.
    +
    +    Accepted condition: min_len <= len(value) < max_len
    +    """
    +
    +    def __init__(self, min_len=None, max_len=None):
    +        """
    +
    +        :param min_len: If not None,
    +            it should be shorter than ``min_len``
    +        :param max_len: If not None,
    +            it should be longer than ``max_len``
    +        """
    +
    +        assert self._check(min_len) and self._check(
    +            max_len
    +        ), "{min_len} & {max_len} should be numbers".format(
    +            min_len=min_len,
    +            max_len=max_len,
    +        )
    +
    +        super().__init__()
    +        self._min_len, self._max_len = min_len, max_len
    +
    +    def _check(self, val):
    +        if val is None:
    +            return True
    +        return isinstance(val, int) and val >= 0
    +
    +    def validate(self, value, data):
    +        if not isinstance(value, str):
    +            self.put_msg("Input value should be string")
    +            return False
    +
    +        str_len = len(value)
    +        msg = None
    +
    +        if not self._min_len and self._max_len and str_len > self._max_len:
    +            msg = "String should be shorter than {max_len}".format(
    +                max_len=self._max_len
    +            )
    +        elif self._min_len and not self._max_len and str_len < self._min_len:
    +            msg = "String should be no shorter than {min_len}".format(
    +                min_len=self._min_len
    +            )
    +        elif self._min_len and self._max_len:
    +            if str_len < self._min_len or str_len > self._max_len:
    +                msg = "String length should be between {min_len} and {max_len}".format(
    +                    min_len=self._min_len,
    +                    max_len=self._max_len,
    +                )
    +        if msg is not None:
    +            self.put_msg(msg)
    +            return False
    +        return True
    +
    +
    +class Datetime(Validator):
    +    """
    +    Date time validation.
    +    """
    +
    +    def __init__(self, datetime_format):
    +        """
    +
    +        :param datetime_format: Date time format,
    +            e.g. %Y-%m-%dT%H:%M:%S.%f
    +        """
    +        super().__init__()
    +        self._format = datetime_format
    +
    +    def validate(self, value, data):
    +        import datetime
    +
    +        try:
    +            datetime.datetime.strptime(value, self._format)
    +        except ValueError as exc:
    +            error = f'Wrong datetime with format "{self._format}": {str(exc)}'
    +            self.put_msg(error)
    +            return False
    +        return True
    +
    +
    +class Pattern(Validator):
    +    """
    +    A validator that accepts strings that match
    +    a given regular expression.
    +    """
    +
    +    def __init__(self, regex, flags=0):
    +        """
    +
    +        :param regex: The regular expression (string or compiled)
    +            to be matched.
    +        :param flags: flags value for regular expression.
    +        """
    +        super().__init__()
    +        self._regexp = re.compile(regex, flags=flags)
    +        self.put_msg("Not matching the pattern: %s" % regex)
    +
    +    def validate(self, value, data):
    +        return self._regexp.match(value) and True or False
    +
    +
    +class Host(Pattern):
    +    """
    +    A validator that accepts strings that represent network hostname.
    +    """
    +
    +    def __init__(self):
    +        regexp = (
    +            r"^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*"
    +            r"([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$"
    +        )
    +        super().__init__(regexp, flags=re.I)
    +        self.put_msg("Invalid hostname")
    +
    +
    +class Port(Number):
    +    """
    +    Port number.
    +    """
    +
    +    def __init__(self):
    +        super().__init__(
    +            min_val=0,
    +            max_val=65536,
    +            is_int=True,
    +        )
    +        self.put_msg(
    +            "Invalid port number, it should be a integer between 0 and 65535",
    +        )
    +
    +
    +class Email(Pattern):
    +    """
    +    A validator that accepts strings that represent network hostname.
    +    """
    +
    +    def __init__(self):
    +        regexp = (
    +            r"^[A-Z0-9][A-Z0-9._%+-]{0,63}@"
    +            r"(?:[A-Z0-9](?:[A-Z0-9-]{0,62}[A-Z0-9])?\.){1,8}[A-Z]{2,63}$"
    +        )
    +        super().__init__(regexp, flags=re.I)
    +        self.put_msg("Invalid email address")
    +
    +
    +class JsonString(Validator):
    +    """
    +    Check if the given value is valid JSON string.
    +    """
    +
    +    def validate(self, value, data):
    +        try:
    +            json.loads(value)
    +        except ValueError:
    +            self.put_msg("Invalid JSON string")
    +            return False
    +        return True
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/entity.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/entity.py
    new file mode 100644
    index 0000000..8a5beca
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/entity.py
    @@ -0,0 +1,32 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +
    +from .eai import RestEAI
    +
    +__all__ = ["RestEntity"]
    +
    +
    +class RestEntity:
    +    def __init__(self, name, content, model, user, app, acl=None):
    +        self.name = name
    +        self.content = content
    +        self.model = model
    +        self._eai = RestEAI(self.model, user, app, acl)
    +
    +    @property
    +    def eai(self):
    +        return self._eai
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/error.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/error.py
    new file mode 100644
    index 0000000..f9f8019
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/error.py
    @@ -0,0 +1,60 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +Error Handling.
    +"""
    +
    +
    +__all__ = ["STATUS_CODES", "RestError"]
    +
    +
    +# HTTP status codes
    +STATUS_CODES = {
    +    400: "Bad Request",
    +    401: "Unauthorized",
    +    402: "Payment Required",
    +    403: "Forbidden",
    +    404: "Not Found",
    +    405: "Method Not Allowed",
    +    406: "Not Acceptable",
    +    407: "Proxy Authentication Required",
    +    408: "Request Timeout",
    +    409: "Conflict",
    +    411: "Length Required",
    +    500: "Internal Server Error",
    +    503: "Service Unavailable",
    +}
    +
    +
    +class RestError(Exception):
    +    """
    +    REST Error.
    +    """
    +
    +    def __init__(self, status, message):
    +        self.status = status
    +        self.reason = STATUS_CODES.get(
    +            status,
    +            "Unknown Error",
    +        )
    +        self.message = message
    +        err_msg = "REST Error [{status}]: {reason} -- {message}".format(
    +            status=self.status,
    +            reason=self.reason,
    +            message=self.message,
    +        )
    +        super().__init__(err_msg)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/error_ctl.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/error_ctl.py
    new file mode 100644
    index 0000000..352c2bf
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/error_ctl.py
    @@ -0,0 +1,158 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""Error control
    +"""
    +
    +
    +import logging
    +import re
    +import sys
    +import traceback
    +
    +from splunk import RESTException
    +
    +import splunktaucclib.common.log as stulog
    +
    +__all__ = ["RestHandlerError", "ERROR_MAPPING"]
    +
    +
    +# Errors mapping for add-on.
    +# Edit it when you need to add new error type.
    +ERROR_MAPPING = {
    +    # splunkd internal error, occurred while calling splunkd REST API.
    +    400: "Bad Request",
    +    401: "Client is not authenticated",
    +    402: "Current license does not allow the requested action",
    +    403: "Unauthorized client for the requested action",
    +    404: "Resource/Endpoint requested dose not exist",
    +    409: "Conflict occurred due to existing object with the same name",
    +    500: "Splunkd internal error",
    +    # Rest handler predefined error in add-on.
    +    1000: "An Add-on Internal ERROR Occurred",
    +    1001: "Fatal Error",
    +    1002: "Some mandatory attributes are missing or unusable for the handler",
    +    1020: "Fail to encrypt credential information",
    +    1021: "Fail to decrypt the encrypted credential information",
    +    1022: "Fail to delete the encrypted credential information",
    +    1100: "Unsupported value in request arguments",
    +    1101: "Unsupported action on the requested endpoint",
    +    1102: "Failed to check object for _sync action",
    +    1103: "Failed to teardown configurations",
    +    1104: "Poster REST handler error",
    +}
    +
    +
    +class RestHandlerError:
    +    """Control Error in Splunk Add-on REST API.
    +    code-message mapping for errors:
    +        code < 1000: splunkd internal error, occurred while
    +            calling splunkd REST API,
    +        code >= 1000: Rest handler predefined error in add-on,
    +    """
    +
    +    def __init__(self, code, msgx=""):
    +        if code == -1:
    +            self._conv(msgx)
    +        else:
    +            self._code = code
    +            self._msgx = msgx
    +            self._msg = RestHandlerError.map(code)
    +
    +    def __str__(self):
    +        msgx = (self._msgx and self._msgx != self._msg) and " - %s" % self._msgx or ""
    +        return f"REST ERROR[{self._code}]: {self._msg}{msgx}"
    +
    +    def _conv(self, exc):
    +        """Convert a Exception form 'splunk.rest.simpleRequest'"""
    +        if isinstance(exc, RESTException):
    +            self._code = exc.statusCode
    +
    +            try:
    +                self._msg = RestHandlerError.map(self._code)
    +            except:
    +                self._msg = exc.get_message_text().strip()
    +
    +            msgx = exc.get_extended_message_text().strip()
    +            if self._msg == msgx:
    +                self._msg = "Undefined Error"
    +            try:
    +                pattern = r"In handler \'\S+\': (?P<msgx>.*$)"
    +                m = re.match(pattern, msgx)
    +                groupDict = m.groupdict()
    +                self._msgx = groupDict["msgx"]
    +            except:
    +                self._msgx = msgx
    +        else:
    +            self._code = 500
    +            self._msg = RestHandlerError.map(self._code)
    +            self._msgx = str(exc)
    +
    +    @staticmethod
    +    def map(code):
    +        """Map error code to message. Raise an exception
    +            if the code dose not exist.
    +        :param code: error code
    +        :returns: error message for the input code
    +        """
    +        msg = ERROR_MAPPING.get(code)
    +        assert msg, "Invalid error code is being used - code=%s" % code
    +        return msg
    +
    +    @staticmethod
    +    def ctl(code, msgx="", logLevel=logging.ERROR, shouldPrint=True, shouldRaise=True):
    +        """Control error, including printing out the error message,
    +        logging it and raising an exception (BaseException).
    +
    +        :param code: error code (it should be -1
    +            if 'msgx' is an splunkd internal error)
    +        :param msgx: extended message/detail, which will
    +            make it more clear (it is an exception of
    +            splunkd internal error if code=-1)
    +        :param logLevel: logging level (generally, it should be `
    +            `ERROR`` for Add-on internal error/bug,
    +            ``INFO`` for client request error)
    +        :param shouldPrint: is it required to print error info
    +            (the printed content will be shown to user)
    +        :param shouldRaise: is it required to raise an exception
    +            (the process will be terminated
    +            if an exception raised)
    +        :return: error content
    +
    +        Some Use Cases:
    +        1. for splunkd internal exception/error (exc):
    +            ``RestHandlerError.ctl(code=-1, msgx=exc, logLevel=logging.INFO)``
    +        2. for bug in user-defined Rest handler in add-on:
    +            ``assert 'expression', \
    +            RestHandlerError.ctl(code=1000, msgx='some detail...',
    +                shouldPrint=False, shouldRaise=False)``
    +        3. for client request error:
    +            RestHandlerError.ctl(code=1100, msgx='some detail...',
    +            logLevel=logging.INFO)
    +        """
    +        err = RestHandlerError(code, msgx=msgx)
    +        tb = (
    +            "\r\n" + ("".join(traceback.format_stack()))
    +            if logLevel >= logging.ERROR or isinstance(msgx, Exception)
    +            else ""
    +        )
    +
    +        stulog.logger.log(logLevel, f"{err}{tb}", exc_info=1)
    +        if shouldPrint:
    +            sys.stdout.write(str(err))
    +        if shouldRaise:
    +            raise BaseException(err)
    +        return err
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/handler.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/handler.py
    new file mode 100644
    index 0000000..9bcee83
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/handler.py
    @@ -0,0 +1,434 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +REST Handler.
    +"""
    +
    +
    +import json
    +import traceback
    +import urllib.parse
    +from functools import wraps
    +
    +from solnlib.splunk_rest_client import SplunkRestClient
    +from splunklib import binding
    +
    +from .credentials import RestCredentials
    +from .entity import RestEntity
    +from .error import RestError
    +
    +__all__ = ["RestHandler"]
    +
    +
    +def _check_name_for_create(name):
    +    if name == "default":
    +        raise RestError(400, '"%s" is not allowed for entity name' % name)
    +    if name.startswith("_"):
    +        raise RestError(400, 'Name starting with "_" is not allowed for entity')
    +
    +
    +def _pre_request(existing):
    +    """
    +    Encode payload before request.
    +    :param existing:
    +        if True: means must exist
    +        if False: means must NOT exist
    +    :return:
    +    """
    +
    +    def _pre_request_wrapper(meth):
    +        """
    +
    +        :param meth: RestHandler instance method
    +        :return:
    +        """
    +
    +        def check_existing(self, name):
    +            if not existing:
    +                # for create, check name
    +                _check_name_for_create(name)
    +            # check if the entity existed
    +            entities = []
    +            try:
    +                entities = list(self.get(name))
    +            except RestError:
    +                pass
    +
    +            if existing and not entities:
    +                raise RestError(
    +                    404,
    +                    '"%s" does not exist' % name,
    +                )
    +            elif not existing and entities:
    +                raise RestError(
    +                    409,
    +                    'Name "%s" is already in use' % name,
    +                )
    +
    +            if entities:
    +                return entities[0].content
    +            else:
    +                return None
    +
    +        @wraps(meth)
    +        def wrapper(self, name, data):
    +            self._endpoint.validate(
    +                name,
    +                data,
    +                check_existing(self, name),
    +            )
    +            self._endpoint.encode(name, data)
    +
    +            return meth(self, name, data)
    +
    +        return wrapper
    +
    +    return _pre_request_wrapper
    +
    +
    +def _decode_response(meth):
    +    """
    +    Decode response body.
    +    :param meth: RestHandler instance method
    +    :return:
    +    """
    +
    +    def decode(self, name, data, acl):
    +        self._endpoint.decode(name, data)
    +        return RestEntity(
    +            name,
    +            data,
    +            self._endpoint.model(name),
    +            self._endpoint.user,
    +            self._endpoint.app,
    +            acl=acl,
    +        )
    +
    +    @wraps(meth)
    +    def wrapper(self, *args, **kwargs):
    +        try:
    +            for name, data, acl in meth(self, *args, **kwargs):
    +                yield decode(self, name, data, acl)
    +        except RestError:
    +            raise
    +        except binding.HTTPError as exc:
    +            raise RestError(exc.status, str(exc))
    +        except Exception:
    +            raise RestError(500, traceback.format_exc())
    +
    +    return wrapper
    +
    +
    +class RestHandler:
    +    def __init__(self, splunkd_uri, session_key, endpoint, *args, **kwargs):
    +        self._splunkd_uri = splunkd_uri
    +        self._session_key = session_key
    +        self._endpoint = endpoint
    +        self._args = args
    +        self._kwargs = kwargs
    +
    +        splunkd_info = urllib.parse.urlparse(self._splunkd_uri)
    +        self._client = SplunkRestClient(
    +            self._session_key,
    +            self._endpoint.app,
    +            scheme=splunkd_info.scheme,
    +            host=splunkd_info.hostname,
    +            port=splunkd_info.port,
    +        )
    +        self.rest_credentials = RestCredentials(
    +            self._splunkd_uri,
    +            self._session_key,
    +            self._endpoint,
    +        )
    +        self.PASSWORD = "******"
    +
    +    @_decode_response
    +    def get(self, name, decrypt=False):
    +        if self._endpoint.need_reload:
    +            self.reload()
    +        response = self._client.get(
    +            self.path_segment(
    +                self._endpoint.internal_endpoint,
    +                name=name,
    +            ),
    +            output_mode="json",
    +        )
    +        return self._format_response(response, get=True, decrypt=decrypt)
    +
    +    @_decode_response
    +    def all(self, decrypt=False, **query):
    +        if self._endpoint.need_reload:
    +            self.reload()
    +        response = self._client.get(
    +            self.path_segment(self._endpoint.internal_endpoint),
    +            output_mode="json",
    +            **query
    +        )
    +        return self._format_all_response(response, decrypt)
    +
    +    def get_encrypted_field_names(self, name):
    +        return [x.name for x in self._endpoint.model(name).fields if x.encrypted]
    +
    +    @_decode_response
    +    @_pre_request(existing=False)
    +    def create(self, name, data):
    +        data["name"] = name
    +        self.rest_credentials.encrypt_for_create(name, data)
    +        response = self._client.post(
    +            self.path_segment(self._endpoint.internal_endpoint),
    +            output_mode="json",
    +            body=data,
    +        )
    +        return self._format_response(response)
    +
    +    @_decode_response
    +    @_pre_request(existing=True)
    +    def update(self, name, data):
    +        self.rest_credentials.encrypt_for_update(name, data)
    +        response = self._client.post(
    +            self.path_segment(
    +                self._endpoint.internal_endpoint,
    +                name=name,
    +            ),
    +            output_mode="json",
    +            body=data,
    +        )
    +        return self._format_response(response)
    +
    +    @_decode_response
    +    def delete(self, name):
    +        response = self._client.delete(
    +            self.path_segment(
    +                self._endpoint.internal_endpoint,
    +                name=name,
    +            ),
    +            output_mode="json",
    +        )
    +        # delete credentials if there are encrypted fields
    +        if self.get_encrypted_field_names(name):
    +            rest_credentials = RestCredentials(
    +                self._splunkd_uri,
    +                self._session_key,
    +                self._endpoint,
    +            )
    +            rest_credentials.delete(name)
    +        return self._flay_response(response)
    +
    +    @_decode_response
    +    def disable(self, name):
    +        response = self._client.post(
    +            self.path_segment(
    +                self._endpoint.internal_endpoint,
    +                name=name,
    +                action="disable",
    +            ),
    +            output_mode="json",
    +        )
    +        return self._flay_response(response)
    +
    +    @_decode_response
    +    def enable(self, name):
    +        response = self._client.post(
    +            self.path_segment(
    +                self._endpoint.internal_endpoint,
    +                name=name,
    +                action="enable",
    +            ),
    +            output_mode="json",
    +        )
    +        return self._flay_response(response)
    +
    +    def reload(self):
    +        self._client.get(
    +            self.path_segment(
    +                self._endpoint.internal_endpoint,
    +                action="_reload",
    +            ),
    +        )
    +
    +    def get_endpoint(self):
    +        return self._endpoint
    +
    +    @classmethod
    +    def path_segment(cls, endpoint, name=None, action=None):
    +        """
    +        Make path segment for given context in Splunk REST format:
    +        <endpoint>/<entity>/<action>
    +
    +        :param endpoint: Splunk REST endpoint, e.g. data/inputs
    +        :param name: entity name for request, "/" will be quoted
    +        :param action: Splunk REST action, e.g. disable, enable
    +        :return:
    +        """
    +        template = "{endpoint}{entity}{action}"
    +        entity = ""
    +        if name:
    +            # all special characters except "/" will be
    +            # url-encoded in splunklib.binding.UrlEncoded
    +            entity = "/" + name.replace("/", "%2F")
    +        path = template.format(
    +            endpoint=endpoint.strip("/"),
    +            entity=entity,
    +            action="/%s" % action if action else "",
    +        )
    +        return path.strip("/")
    +
    +    def _format_response(self, response, get=False, decrypt=False):
    +        body = response.body.read()
    +        try:
    +            cont = json.loads(body)
    +        except ValueError:
    +            raise RestError(500, "Fail to load response, invalid JSON")
    +        for entry in cont["entry"]:
    +            name = entry["name"]
    +            data = entry["content"]
    +            acl = entry["acl"]
    +            encrypted_field_names = self.get_encrypted_field_names(name)
    +            # encrypt and get clear password for get request
    +            if get:
    +                masked = self.rest_credentials.decrypt_for_get(name, data)
    +                if masked:
    +                    self._client.post(
    +                        self.path_segment(
    +                            self._endpoint.internal_endpoint,
    +                            name=name,
    +                        ),
    +                        body=masked,
    +                    )
    +
    +            if not decrypt:
    +                # replace clear password with '******'
    +                for field_name in encrypted_field_names:
    +                    if field_name in data and data[field_name]:
    +                        data[field_name] = self.PASSWORD
    +
    +            yield name, data, acl
    +
    +    def _flay_response(self, response, decrypt=False):
    +        body = response.body.read()
    +        try:
    +            cont = json.loads(body)
    +        except ValueError:
    +            raise RestError(500, "Fail to load response, invalid JSON")
    +        for entry in cont["entry"]:
    +            name = entry["name"]
    +            data = entry["content"]
    +            acl = entry["acl"]
    +            if self._need_decrypt(name, data, decrypt):
    +                self._load_credentials(name, data)
    +            if not decrypt:
    +                self._clean_credentials(name, data)
    +            yield name, data, acl
    +
    +    def _format_all_response(self, response, decrypt=False):
    +        body = response.body.read()
    +        try:
    +            cont = json.loads(body)
    +        except ValueError:
    +            raise RestError(500, "Fail to load response, invalid JSON")
    +        # cont['entry']: collection list, load credentials in one request
    +        if self.get_encrypted_field_names(None):
    +            self._encrypt_raw_credentials(cont["entry"])
    +        if not decrypt:
    +            self._clean_all_credentials(cont["entry"])
    +
    +        for entry in cont["entry"]:
    +            name = entry["name"]
    +            data = entry["content"]
    +            acl = entry["acl"]
    +            yield name, data, acl
    +
    +    def _load_credentials(self, name, data):
    +        rest_credentials = RestCredentials(
    +            self._splunkd_uri, self._session_key, self._endpoint
    +        )
    +        masked = rest_credentials.decrypt(name, data)
    +        if masked:
    +            # passwords.conf changed
    +            self._client.post(
    +                self.path_segment(
    +                    self._endpoint.internal_endpoint,
    +                    name=name,
    +                ),
    +                **masked
    +            )
    +
    +    def _encrypt_raw_credentials(self, data):
    +        rest_credentials = RestCredentials(
    +            self._splunkd_uri, self._session_key, self._endpoint
    +        )
    +        # get clear passwords for response data and get the password change list
    +        change_list = rest_credentials.decrypt_all(data)
    +
    +        field_names = self.get_encrypted_field_names(None)
    +        for model in change_list:
    +            # only updates the defined fields in schema
    +            masked = dict()
    +            for field in field_names:
    +                if (
    +                    field in model["content"]
    +                    and model["content"][field] != ""
    +                    and model["content"][field] != self.PASSWORD
    +                ):
    +                    masked[field] = self.PASSWORD
    +
    +            if masked:
    +                self._client.post(
    +                    self.path_segment(
    +                        self._endpoint.internal_endpoint,
    +                        name=model["name"],
    +                    ),
    +                    body=masked,
    +                )
    +
    +    def _need_decrypt(self, name, data, decrypt):
    +        # some encrypted-needed fields are plain text in *.conf.
    +        encrypted_field = False
    +        for field in self._endpoint.model(name).fields:
    +            if field.encrypted is False:
    +                # ignore non-encrypted fields
    +                continue
    +            encrypted_field = True
    +            if not data.get(field.name):
    +                # ignore un-stored/empty fields
    +                continue
    +            if data[field.name] == RestCredentials.PASSWORD:
    +                # ignore already-encrypted fields
    +                continue
    +            return True
    +
    +        if decrypt and encrypted_field:
    +            # clear credentials is required by request and
    +            # there are some encrypted-needed fields
    +            return True
    +        return False
    +
    +    def _clean_credentials(self, name, data):
    +        encrypted_field_names = self.get_encrypted_field_names(name)
    +        for field_name in encrypted_field_names:
    +            if field_name in data:
    +                del data[field_name]
    +
    +    def _clean_all_credentials(self, data):
    +        encrypted_field_names = self.get_encrypted_field_names(None)
    +        for model in data:
    +            for field_name in encrypted_field_names:
    +                if (
    +                    field_name in model["content"]
    +                    and model["content"][field_name] != ""
    +                ):
    +                    model["content"][field_name] = self.PASSWORD
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/multimodel.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/multimodel.py
    new file mode 100644
    index 0000000..7283679
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/multimodel.py
    @@ -0,0 +1,184 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""REST handler for multiple models with different structure in one *.conf.
    +It assumes that there are enumerable objects in every model,
    +and they will be listed in ``modelMap`` in advance, that means
    +it dose not allow to create object but update it.
    +
    +It will return fields with default values, if the object never created
    +via REST or *.conf directly.
    +
    +This handler is for some global settings like proxy, logging, etc.
    +"""
    +
    +
    +import logging
    +
    +import splunk
    +from splunk import ResourceNotFound
    +
    +from . import base
    +from .cred_mgmt import CredMgmt
    +from .error_ctl import RestHandlerError as RH_Err
    +
    +__all__ = ["MultiModelRestHandler", "MultiModel", "ResourceHandler"]
    +
    +
    +class MultiModelRestHandler(base.BaseRestHandler):
    +    """Rest handler for multiple models with different fields,
    +    and different validation.
    +    """
    +
    +    def __init__(self, *args, **kwargs):
    +        splunk.admin.MConfigHandler.__init__(self, *args, **kwargs)
    +        self._log_request()
    +
    +        # check required attributes
    +        assert hasattr(self, "endpoint"), RH_Err.ctl(
    +            1002,
    +            msgx="%s.endpoint" % self.__class__.__name__,
    +            shouldPrint=False,
    +            shouldRaise=False,
    +        )
    +        assert hasattr(self, "modelMap") and isinstance(
    +            self.modelMap, dict
    +        ), RH_Err.ctl(
    +            1002,
    +            msgx="%s.modelMap" % self.__class__.__name__,
    +            shouldPrint=False,
    +            shouldRaise=False,
    +        )
    +
    +        # Check custom actions
    +        self.check_caps()
    +        if self.customAction == "_sync":
    +            self.exist4sync = True
    +
    +        # set model for requested object
    +        self.model = None
    +        if self.callerArgs.id:
    +            self.setModel(self.callerArgs.id)
    +
    +    def setModel(self, name):
    +        """Get data model for specified object."""
    +        # get model for object
    +        if name not in self.modelMap:
    +            RH_Err.ctl(
    +                404,
    +                msgx=f"object={name}",
    +            )
    +        self.model = self.modelMap[name]
    +
    +        # load attributes from model
    +        obj = self.model()
    +        attrs = {
    +            attr: getattr(obj, attr, None)
    +            for attr in dir(obj)
    +            if not attr.startswith("__")
    +            and attr not in ("endpoint", "rest_prefix", "cap4endpoint", "cap4get_cred")
    +        }
    +        self.__dict__.update(attrs)
    +
    +        # credential fields
    +        self.encryptedArgs = {
    +            (self.keyMap.get(arg) or arg) for arg in self.encryptedArgs
    +        }
    +        user, app = self.user_app()
    +        self._cred_mgmt = CredMgmt(
    +            sessionKey=self.getSessionKey(),
    +            user=user,
    +            app=app,
    +            endpoint=self.endpoint,
    +            encryptedArgs=self.encryptedArgs,
    +        )
    +        return
    +
    +    def handleRemove(self, confInfo):
    +        try:
    +            self.delete(self.callerArgs.id)
    +        except ResourceNotFound as exc:
    +            if self.callerArgs.id not in self.modelMap:
    +                RH_Err.ctl(-1, exc, logLevel=logging.INFO)
    +        except Exception as exc:
    +            RH_Err.ctl(-1, exc, logLevel=logging.INFO)
    +        self._cred_mgmt.delete(self._makeStanzaName(self.callerArgs.id))
    +
    +    def all(self):
    +        return {name: self.get(name) for name in self.modelMap}
    +
    +    def get(self, name):
    +        # set model attribute for normalize response data
    +        self.setModel(name)
    +        try:
    +            return base.BaseRestHandler.get(self, name)
    +        except splunk.ResourceNotFound:
    +            return self.defaultVals or {}
    +
    +    def update(self, name, **params):
    +        user, app = self.user_app()
    +        try:
    +            ent = splunk.entity.getEntity(
    +                self.endpoint,
    +                name,
    +                namespace=app,
    +                owner=user,
    +                sessionKey=self.getSessionKey(),
    +            )
    +
    +            for arg, val in list(params.items()):
    +                ent[arg] = val
    +            splunk.entity.setEntity(ent, sessionKey=self.getSessionKey())
    +        except splunk.ResourceNotFound:
    +            try:
    +                args = self.encode(self.callerArgs.data)
    +                self.create(self.callerArgs.id, **args)
    +            except Exception as exc:
    +                RH_Err.ctl(-1, exc, logLevel=logging.INFO)
    +        except Exception as exc:
    +            RH_Err.ctl(-1, exc, logLevel=logging.INFO)
    +
    +    def _getHandlerName(self):
    +        return f"{self.__class__.__name__}.{self.model.__name__}"
    +
    +
    +class MultiModel:
    +    """Mapping from object name to model, which means stanzas with
    +    different structure will be stored in same endpoint.
    +    """
    +
    +    # REST prefix. Default is lower-case app name.
    +    # Change it if needed.
    +    rest_prefix = base.APP_NAME
    +
    +    # Endpoint, specifies the conf name, in form:
    +    # configs/conf-<conf_file_name>
    +    endpoint = ""
    +
    +    # mapping object name to handler model class
    +    modelMap = {}
    +
    +    # Required capabilities for this REST Endpoint.
    +    # Empty string means no need to check capability.
    +    # It will add ``rest_prefix`` automatically.
    +    #   cap4endpoint: basic capability for this endpoint.
    +    #   cap4get_cred: capability to get credential info.
    +    cap4endpoint = "endpoint"
    +    cap4get_cred = "get_credential"
    +
    +
    +def ResourceHandler(multimodel, handler=MultiModelRestHandler):
    +    return type(handler.__name__, (handler, multimodel), {})
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/normaliser.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/normaliser.py
    new file mode 100644
    index 0000000..d80a61f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/normaliser.py
    @@ -0,0 +1,109 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""Normalisers
    +"""
    +
    +
    +__all__ = ["Normaliser", "Boolean", "StringLower", "StringUpper"]
    +
    +
    +class Normaliser:
    +    """Base class of Normaliser."""
    +
    +    _name = None
    +
    +    def __init__(self):
    +        pass
    +
    +    def normalize(self, value):
    +        """Normalize a given value.
    +
    +        :param value: value to normalize.
    +        :returns: normalized value.
    +        """
    +        raise NotImplementedError
    +
    +    @property
    +    def name(self):
    +        """name of normaliser."""
    +        return self._name or self.__class__.__name__
    +
    +
    +class Userdefined(Normaliser):
    +    """A Normaliser that defined by user itself.
    +
    +    The user-defined normaliser function should be in form:
    +    ``def fun(value, *args, **kwargs): ...``
    +    It will return the original data if any exception occurred.
    +    """
    +
    +    def __init__(self, normaliser, *args, **kwargs):
    +        """
    +        :param values: The collection of valid values
    +        """
    +        super().__init__()
    +        self._normaliser, self._args, self._kwargs = normaliser, args, kwargs
    +
    +    def normalize(self, value):
    +        try:
    +            return self._normaliser(value, *self._args, **self._kwargs)
    +        except:
    +            return value
    +
    +
    +class Boolean(Normaliser):
    +    """Normalize a boolean field.
    +
    +    Normalize given value to boolean: ``0`` or ``1``.
    +    ``default`` means the return for unrecognizable input of boolean.
    +    """
    +
    +    def __init__(self, default=True):
    +        super().__init__()
    +        self._default = "1" if default else "0"
    +
    +    def normalize(self, value):
    +        if isinstance(value, (bool, int)):
    +            return value and "1" or "0"
    +        if not isinstance(value, str):
    +            return self._default
    +        value = value.strip().lower()
    +
    +        vals = {
    +            "1": {"true", "t", "1", "yes", "y"},
    +            "0": {"false", "f", "0", "no", "n"},
    +        }
    +        revDef = {"1": "0", "0": "1"}[self._default]
    +        return revDef if value in vals[revDef] else self._default
    +
    +
    +class StringLower(Normaliser):
    +    """Normalize a string to all lower cases."""
    +
    +    def normalize(self, value):
    +        if isinstance(value, str):
    +            return value.strip().lower()
    +        return value
    +
    +
    +class StringUpper(Normaliser):
    +    """Normalize a string to all upper cases."""
    +
    +    def normalize(self, value):
    +        if isinstance(value, str):
    +            return value.strip().upper()
    +        return value
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/poster.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/poster.py
    new file mode 100644
    index 0000000..6e75177
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/poster.py
    @@ -0,0 +1,195 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 re
    +import urllib.error
    +import urllib.parse
    +import urllib.request
    +
    +import requests
    +from splunk import admin, rest
    +from splunktalib.common.util import is_true
    +from splunktalib.rest import code_to_msg, splunkd_request
    +
    +from . import base, util
    +from .error_ctl import RestHandlerError as RH_Err
    +
    +
    +class PosterHandler(base.BaseRestHandler):
    +    """REST handler for retransmitting request to a url.
    +    It is designed for avoiding cross-site request in front-end.
    +    It accepts POST request only for safety of credential information.
    +    """
    +
    +    def __init__(self, *args, **kwargs):
    +        admin.MConfigHandler.__init__(self, *args, **kwargs)
    +
    +        # check required attributes
    +        assert hasattr(self, "modelMap") and isinstance(
    +            self.modelMap, dict
    +        ), RH_Err.ctl(
    +            1002, msgx=f"{self.__class__.__name__}.modelMap", shouldPrint=False
    +        )
    +
    +        if self.requestedAction != admin.ACTION_EDIT:
    +            RH_Err.ctl(1101, msgx='Only "edit" supported')
    +        self.setModel(self.callerArgs.id)
    +        self.requiredArgs.add("splunk_poster_url")
    +        self.requiredArgs.add("splunk_poster_method")
    +
    +    def setModel(self, name):
    +        # get model for object
    +        if name not in self.modelMap:
    +            RH_Err.ctl(404, msgx=f"object={name}")
    +        self.model = self.modelMap[name]
    +
    +        # load attributes from model
    +        obj = self.model()
    +        attrs = {
    +            attr: getattr(obj, attr, None)
    +            for attr in dir(obj)
    +            if not attr.startswith("__") and attr != "endpoint"
    +        }
    +        self.__dict__.update(attrs)
    +
    +    def handleEdit(self, confInfo):
    +        user, app = self.user_app()
    +        proxy_info = self.getProxyInfo(
    +            splunkdMgmtUri=rest.makeSplunkdUri(),
    +            sessionKey=self.getSessionKey(),
    +            user=user,
    +            app=app,
    +        )
    +        proxy_enabled = proxy_info.get("proxy_enabled", False)
    +        proxy_uri = util.get_proxy_uri(proxy_info if proxy_enabled else {})
    +        proxies = {"http": proxy_uri, "https": proxy_uri}
    +        try:
    +            url = self.callerArgs.data["splunk_poster_url"][0]
    +            for regex in self.allowedURLs:
    +                if re.match(regex, url):
    +                    break
    +            else:
    +                RH_Err.ctl(1104, msgx="Unsupported url to be posted")
    +
    +            method = self.callerArgs.data["splunk_poster_method"][0]
    +            if method not in self.allowedMethods:
    +                RH_Err.ctl(1104, msgx="Unsupported method to be posted")
    +
    +            payload = {
    +                key: val[0]
    +                for key, val in self.callerArgs.data.items()
    +                if key in self.retransmittedArgs
    +            }
    +            headers = {
    +                "Content-Type": "application/x-www-form-urlencoded",
    +            }
    +
    +            resp = requests.request(  # nosemgrep: python.requests.best-practice.use-raise-for-status.use-raise-for-status  # noqa: E501
    +                method=method,
    +                url=url,
    +                headers=headers,
    +                data=urllib.parse.urlencode(payload),
    +                timeout=120,
    +                proxies=proxies,
    +                verify=True,
    +            )
    +            content = resp.json()
    +            if resp.status_code not in (200, 201):
    +                RH_Err.ctl(resp.status_code, msgx=content)
    +
    +            for key, val in content.items():
    +                confInfo[self.callerArgs.id][key] = val
    +        except Exception as exc:
    +            RH_Err.ctl(1104, msgx=exc)
    +
    +
    +class PosterModel(base.BaseModel):
    +    """Model for request retransmitting target"""
    +
    +    # Argument names:
    +    # arguments are required. It contains 'splunk_poster_url'
    +    # and 'splunk_poster_method' automatically.
    +    requiredArgs = set()
    +    # arguments are optional.
    +    optionalArgs = set()
    +    # arguments will be retransmitted.
    +    retransmittedArgs = set()
    +
    +    # A white list for URLs regex.
    +    # If it is empty, it will reject all request.
    +    allowedURLs = ()
    +
    +    # A white list for HTTP methods
    +    allowedMethods = ()
    +
    +
    +class PosterMapping:
    +    """Mapping from object name to poster model."""
    +
    +    # mapping object name to handler model class
    +    modelMap = {}
    +
    +    # Endpoint for Proxy Info, like:
    +    # <admin>/<endpoint>/<proxy>
    +    proxyInfoEndpoint = None
    +
    +    def getProxyInfo(self, splunkdMgmtUri, sessionKey, user, app):
    +        """
    +        Get Proxy Information on given REST endpoint.
    +        It should be in form (if not, override the this method):
    +            {
    +               'proxy_url': '<proxy_url>',
    +               'proxy_port': '<proxy_port>',
    +               'proxy_username': '<proxy_username>',
    +               'proxy_password': '<proxy_password>',
    +               'proxy_enabled': '<proxy_enabled>',
    +               'proxy_rdns': '<proxy_rdns>',
    +               'proxy_type': '<proxy_type>'
    +            }
    +        :return:
    +        """
    +        if not self.proxyInfoEndpoint:
    +            RH_Err.ctl(1104, msgx="Empty endpoint for proxy is being used")
    +        url = "{splunkdMgmtUri}servicesNS/{user}/{app}/{proxyInfoEndpoint}".format(
    +            splunkdMgmtUri=splunkdMgmtUri,
    +            user=user,
    +            app=app,
    +            proxyInfoEndpoint=self.proxyInfoEndpoint,
    +        )
    +        data = {"output_mode": "json", "--get-clear-credential--": "1"}
    +        resp = splunkd_request(url, sessionKey, data=data, retry=3)
    +        if resp is None or resp.status_code != 200:
    +            RH_Err.ctl(1104, msgx=f"failed to load proxy info. {code_to_msg(resp)}")
    +
    +        try:
    +            proxy_info = resp.json()["entry"][0]["content"]
    +        except IndexError | KeyError:
    +            proxy_info = {}
    +
    +        return {
    +            "proxy_enabled": is_true(proxy_info.get("proxy_enabled", "false")),
    +            "proxy_url": proxy_info.get("proxy_url", ""),
    +            "proxy_port": proxy_info.get("proxy_port", ""),
    +            "proxy_username": proxy_info.get("proxy_username", ""),
    +            "proxy_password": proxy_info.get("proxy_password", ""),
    +            "proxy_rdns": proxy_info.get("proxy_rdns", "false"),
    +            "proxy_type": proxy_info.get("proxy_type", "http"),
    +        }
    +
    +
    +def ResourceHandler(poster_mapping, handler=PosterHandler):
    +    return type(handler.__name__, (handler, poster_mapping), {})
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/schema.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/schema.py
    new file mode 100644
    index 0000000..bb0b760
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/schema.py
    @@ -0,0 +1,56 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""
    +REST Schema
    +"""
    +
    +
    +from abc import abstractproperty
    +
    +__all__ = [
    +    "RestSchemaError",
    +    "RestSchema",
    +]
    +
    +
    +class RestSchemaError(Exception):
    +    pass
    +
    +
    +class RestSchema:
    +    """
    +    REST Scheme.
    +    """
    +
    +    def __init__(self, *args, **kwargs):
    +        pass
    +
    +    @staticmethod
    +    def endpoint_name(name, namespace):
    +        return f"{namespace}_{name}"
    +
    +    @abstractproperty
    +    def product(self):
    +        pass
    +
    +    @abstractproperty
    +    def namespace(self):
    +        pass
    +
    +    @abstractproperty
    +    def version(self):
    +        pass
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/teardown.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/teardown.py
    new file mode 100644
    index 0000000..2aa3690
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/teardown.py
    @@ -0,0 +1,162 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""REST Manager for cleaning configuration in add-on.
    +
    +It will return endpoints that failed to be cleaned.
    +
    +"""
    +
    +
    +import json
    +import logging
    +from inspect import ismethod
    +from itertools import chain as iter_chain
    +from urllib.parse import quote
    +
    +from splunk import admin, rest
    +from splunktalib.rest import splunkd_request
    +
    +from . import base
    +from .error_ctl import RestHandlerError as RH_Err
    +
    +__all__ = ["DataInputHandler", "DataInputModel"]
    +
    +
    +class TeardownHandler(base.BaseRestHandler):
    +    """REST Handler for Splunk Add-on configuration Teardown."""
    +
    +    def __init__(self, *args, **kwargs):
    +        admin.MConfigHandler.__init__(self, *args, **kwargs)
    +
    +        assert hasattr(self, "targets") and self.targets, RH_Err.ctl(
    +            1002, msgx=f"{self._getHandlerName()}.targets", shouldPrint=False
    +        )
    +        assert hasattr(self, "getArgs") and ismethod(self.getArgs), RH_Err.ctl(
    +            1002, msgx="%s.getArgs" % (self._getHandlerName()), shouldPrint=False
    +        )
    +        assert hasattr(self, "distinguish") and ismethod(self.distinguish), RH_Err.ctl(
    +            1002, msgx="%s.distinguish" % (self._getHandlerName()), shouldPrint=False
    +        )
    +
    +        if self.requestedAction != admin.ACTION_LIST:
    +            RH_Err.ctl(
    +                1101, msgx='Only "list" action is supported', logLevel=logging.INFO
    +            )
    +
    +    def setup(self):
    +        for arg in self.requiredArgs:
    +            self.supportedArgs.addReqArg(arg)
    +        for arg in self.optionalArgs:
    +            self.supportedArgs.addOptArg(arg)
    +
    +    def getArgs(self):
    +        """
    +        Get arguments used in "distinguish" method.
    +        :param endpoint:
    +        :return:
    +        """
    +        args = {}
    +        for arg in iter_chain(self.requiredArgs, self.optionalArgs):
    +            val = self.callerArgs.data.get(arg, [""])[0]
    +            val = "" if val is None else val
    +            args[arg] = val
    +        return args
    +
    +    def handleList(self, confInfo):
    +        all_errs = {}
    +        for ep in self.targets:
    +            all_errs.update(self.clean(ep))
    +
    +        if all_errs:
    +            RH_Err.ctl(1103, msgx=json.dumps(all_errs))
    +
    +    def make_uri(self, endpoint, entry=None):
    +        user, app = self.user_app()
    +        endpoint = endpoint.strip("/ ")
    +        entry = "" if entry is None else "/" + quote(entry.strip("/"), safe="")
    +        uri = "{splunkd_uri}servicesNS/{user}/{app}/{endpoint}{entry}" "".format(
    +            splunkd_uri=rest.makeSplunkdUri(),
    +            user=user,
    +            app=app,
    +            endpoint=endpoint,
    +            entry=entry,
    +        )
    +        return uri
    +
    +    def clean(self, endpoint):
    +        url = self.make_uri(endpoint) + "?count=-1"
    +        resp = splunkd_request(
    +            url,
    +            self.getSessionKey(),
    +            method="GET",
    +            data={"output_mode": "json"},
    +            retry=3,
    +        )
    +
    +        if resp is None:
    +            return {url: "Unknown reason"}
    +        if resp.status_code != 200:
    +            return {url: self.convertErrMsg(resp.text)}
    +
    +        cont = resp.json()
    +        ents = [ent["name"] for ent in cont.get("entry", [])]
    +        errs = {}
    +        for ent in ents:
    +            args = self.getArgs()
    +            if not self.distinguish(endpoint, ent, **args):
    +                continue
    +            url_ent = self.make_uri(endpoint, entry=ent)
    +            resp = splunkd_request(
    +                url_ent,
    +                self.getSessionKey(),
    +                method="DELETE",
    +                data={"output_mode": "json"},
    +                retry=3,
    +            )
    +
    +            if resp is None:
    +                errs[url_ent] = "Unknown reason"
    +            if resp.status_code != 200:
    +                errs[url_ent] = self.convertErrMsg(cont)
    +        return errs
    +
    +    def convertErrMsg(self, errMsg):
    +        err = json.loads(errMsg)
    +        return err["messages"][0]["text"]
    +
    +
    +class TeardownModel(base.BaseModel):
    +    """Base Class of Data Input Model."""
    +
    +    # target endpoints to tear down a dict:
    +    # key ==> endpoint, value ==> needed to be filtered (boolean)
    +    targets = set()
    +
    +    def distinguish(self, endpoint, name, **kwargs):
    +        """
    +        Determine if an item should be cleared.
    +        Override it if need.
    +        :param endpoint:
    +        :param name:
    +        :param kwargs:
    +        :return: True/False
    +        """
    +        return True
    +
    +
    +def ResourceHandler(model, handler=TeardownHandler):
    +    return type(handler.__name__, (handler, model), {})
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/util.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/util.py
    new file mode 100644
    index 0000000..23abd06
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/util.py
    @@ -0,0 +1,141 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 os.path
    +from typing import Any, Dict, Optional
    +
    +import solnlib.utils as utils
    +
    +from .error import RestError
    +
    +try:
    +    from splunk import admin
    +except Exception:
    +    print("Some functions will not be available outside of a splunk hosted process")
    +
    +try:
    +    from splunktalib.common import util
    +except Exception:
    +    print('Python Lib for Splunk add-on "splunktalib" is required')
    +    raise BaseException()
    +
    +__all__ = [
    +    "get_base_app_name",
    +    "remove_http_proxy_env_vars",
    +    "makeConfItem",
    +    "getBaseAppName",
    +]
    +
    +
    +def getBaseAppName():
    +    """Base App name, which this script belongs to."""
    +    appName = util.get_appname_from_path(__file__)
    +    if appName is None:
    +        raise Exception("Cannot get app name from file: %s" % __file__)
    +    return appName
    +
    +
    +def makeConfItem(name, entity, confInfo, user="nobody", app="-"):
    +    confItem = confInfo[name]
    +    for key, val in list(entity.items()):
    +        if key not in ("eai:attributes", "eai:userName", "eai:appName"):
    +            confItem[key] = val
    +    confItem["eai:userName"] = entity.get("eai:userName") or user
    +    confItem["eai:appName"] = entity.get("eai:appName") or app
    +    confItem.setMetadata(
    +        admin.EAI_ENTRY_ACL,
    +        entity.get(admin.EAI_ENTRY_ACL)
    +        or {
    +            "owner": user,
    +            "app": app,
    +            "global": 1,
    +            "can_write": 1,
    +            "modifiable": 1,
    +            "removable": 1,
    +            "sharing": "global",
    +            "perms": {"read": ["*"], "write": ["admin"]},
    +        },
    +    )
    +    return confItem
    +
    +
    +def get_base_app_name():
    +    """
    +    Base App name, which this script belongs to.
    +    """
    +    import __main__
    +
    +    main_name = __main__.__file__
    +    absolute_path = os.path.normpath(main_name)
    +    parts = absolute_path.split(os.path.sep)
    +    parts.reverse()
    +    for key in ("apps", "slave-apps", "master-apps"):
    +        try:
    +            idx = parts.index(key)
    +            if parts[idx + 1] == "etc":
    +                return parts[idx - 1]
    +        except (ValueError, IndexError):
    +            pass
    +    raise RestError(status=500, message="Cannot get app name from file: %s" % main_name)
    +
    +
    +def remove_http_proxy_env_vars():
    +    for k in ("http_proxy", "https_proxy"):
    +        if k in os.environ:
    +            del os.environ[k]
    +        elif k.upper() in os.environ:
    +            del os.environ[k.upper()]
    +
    +
    +def get_proxy_uri(proxy: Dict[str, Any]) -> Optional[str]:
    +    """
    +    :proxy: dict like, proxy information are in the following
    +            format {
    +                "proxy_url": zz,
    +                "proxy_port": aa,
    +                "proxy_username": bb,
    +                "proxy_password": cc,
    +                "proxy_type": http,sock4,sock5,
    +                "proxy_rdns": 0 or 1,
    +            }
    +    :return: proxy uri or None
    +    """
    +    uri = None
    +    if proxy and proxy.get("proxy_url") and proxy.get("proxy_type"):
    +        uri = proxy["proxy_url"]
    +        # socks5 causes the DNS resolution to happen on the client
    +        # socks5h causes the DNS resolution to happen on the proxy server
    +        if proxy.get("proxy_type") == "socks5" and utils.is_true(
    +            proxy.get("proxy_rdns")
    +        ):
    +            proxy["proxy_type"] = "socks5h"
    +        # setting default value of proxy_type to "http" if
    +        # its value is not from ["http", "socks4", "socks5"]
    +        if proxy.get("proxy_type") not in ["http", "socks4", "socks5"]:
    +            proxy["proxy_type"] = "http"
    +        if proxy.get("proxy_port"):
    +            uri = "{}:{}".format(uri, proxy.get("proxy_port"))
    +        if proxy.get("proxy_username") and proxy.get("proxy_password"):
    +            uri = "{}://{}:{}@{}/".format(
    +                proxy["proxy_type"],
    +                proxy["proxy_username"],
    +                proxy["proxy_password"],
    +                uri,
    +            )
    +        else:
    +            uri = "{}://{}".format(proxy["proxy_type"], uri)
    +
    +    return uri
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/validator.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/validator.py
    new file mode 100644
    index 0000000..b4a5066
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/rest_handler/validator.py
    @@ -0,0 +1,305 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +"""Validators
    +"""
    +
    +
    +import json
    +import re
    +
    +from . import error_ctl
    +
    +__all__ = [
    +    "Validator",
    +    "ValidationError",
    +    "AnyOf",
    +    "AllOf",
    +    "Userdefined",
    +    "Enum",
    +    "Range",
    +    "String",
    +    "Pattern",
    +    "Host",
    +    "Port",
    +    "RequiredIf",
    +]
    +
    +
    +class Validator:
    +    """Base class of validators."""
    +
    +    _name = None  # Validator name.
    +    _msg = "Validation Failed"  # Message when validation failed.
    +
    +    def __init__(self):
    +        pass
    +
    +    def validate(self, value, data):
    +        """Check if the value is valid.
    +        :param value: value to validate.
    +        :param data: payload in request.
    +        If it is valid, return a boolean value indicate if value is valid.
    +        """
    +        raise NotImplementedError
    +
    +    @property
    +    def name(self):
    +        """name of validator."""
    +        return self._name or self.__class__.__name__
    +
    +    @property
    +    def msg(self):
    +        """message when validation failed."""
    +        return self._msg
    +
    +
    +class ValidationError(Exception):
    +    """Exception from validation."""
    +
    +    pass
    +
    +
    +class AnyOf(Validator):
    +    """A composite validator that accepts values accepted by
    +    any of its component validators.
    +    """
    +
    +    def __init__(self, *validators):
    +        self._validators = validators
    +
    +    def validate(self, value, data):
    +        for validator in self._validators:
    +            if validator.validate(value, data):
    +                return True
    +            else:
    +                self._msg = validator.msg
    +        return False
    +
    +
    +class AllOf(Validator):
    +    """A composite validator that accepts values accepted by
    +    all of its component validators.
    +    """
    +
    +    def __init__(self, *validators):
    +        self._validators = validators
    +
    +    def validate(self, value, data):
    +        for validator in self._validators:
    +            if not validator.validate(value, data):
    +                self._msg = validator.msg
    +                return False
    +        return True
    +
    +
    +class Userdefined(Validator):
    +    """A validator that defined by user itself.
    +
    +    The user-defined validator function should be in form:
    +    ``def fun(value, *args, **kwargs): ...``
    +    It will be regarded as validation failed if a
    +    ``ValidationError`` occurred, the exception message
    +    will be set as exception content.
    +    And, it should return the validation result ``True`` or ``False``.
    +    """
    +
    +    def __init__(self, validator, *args, **kwargs):
    +        """
    +        :param values: The collection of valid values
    +        """
    +        super().__init__()
    +        self._validator, self._args, self._kwargs = validator, args, kwargs
    +
    +    def validate(self, value, data):
    +        try:
    +            return self._validator(value, *self._args, **self._kwargs)
    +        except ValidationError as exc:
    +            self._msg = exc
    +        except Exception as exc:
    +            error_ctl.RestHandlerError.ctl(1000, msgx=exc)
    +        return False
    +
    +
    +class Enum(Validator):
    +    """A validator that accepts only a finite set of values."""
    +
    +    def __init__(self, values=()):
    +        """
    +        :param values: The collection of valid values
    +        """
    +        super().__init__()
    +        try:
    +            self._values = set(values)
    +        except:
    +            self._values = list(values)
    +        self._msg = "Value should be in " "".format(json.dumps(list(self._values)))
    +
    +    def validate(self, value, data):
    +        return value in self._values
    +
    +
    +class Range(Validator):
    +    """A validator that accepts values within in a certain range.
    +    This is for numeric value.
    +
    +    Condition: minVal <= value <= maxVal
    +    """
    +
    +    def __init__(self, minVal=None, maxVal=None):
    +        """
    +        :param minVal: If not None, values less than ``minVal`` are invalid.
    +        :param maxVal: If not None, values larger than ``maxVal`` are invalid.
    +        """
    +        minVal_bool = isinstance(minVal, (int, float))
    +        maxVal_bool = isinstance(maxVal, (int, float))
    +        assert (minVal is None or minVal_bool) and (
    +            maxVal is None or maxVal_bool
    +        ), "``minVal`` & ``maxVal`` should be numeric"
    +        super().__init__()
    +        self._minVal, self._maxVal = minVal, maxVal
    +
    +        if None not in (self._minVal, self._maxVal):
    +            self._msg = "Value should be between {} and {}" "".format(
    +                self._minVal, self._maxVal
    +            )
    +        elif self._minVal is not None:
    +            self._msg = "Value should be no smaller than {}" "".format(self._minVal)
    +        elif self._maxVal is not None:
    +            self._msg = "Value should be smaller than {}" "".format(self._maxVal)
    +
    +    def validate(self, value, data):
    +        try:
    +            value = float(value)
    +        except ValueError:
    +            self._msg = "Invalid format for numeric value"
    +            return False
    +        failed = (self._minVal is not None and value < self._minVal) or (
    +            self._maxVal is not None and value > self._maxVal
    +        )
    +        return False if failed else True
    +
    +
    +class String(Validator):
    +    """A validator that accepts string values.
    +
    +    Condition: minLen <= len(value) <= maxLen
    +    """
    +
    +    def __init__(self, minLen=None, maxLen=None):
    +        """Instantiate a String validator.
    +
    +        :param minLen: If not None,
    +            strings shorter than ``minLen`` are invalid.
    +        :param maxLen: If not None,
    +            strings longer than ``maxLen`` are invalid.
    +        """
    +        minLen_bool = isinstance(minLen, (int, float))
    +        maxLen_bool = isinstance(maxLen, (int, float))
    +        assert (minLen is None or minLen_bool) and (
    +            maxLen is None or maxLen_bool
    +        ), "``minLen`` & ``maxLen`` should be numeric"
    +        super().__init__()
    +        self._minLen = 0 if minLen is not None and minLen < 0 else minLen
    +        self._maxLen = 0 if maxLen is not None and maxLen < 0 else maxLen
    +
    +        if None not in (self._minLen, self._maxLen):
    +            self._msg = "Value should be between {} and {}" "".format(
    +                self._minLen, self._maxLen
    +            )
    +        elif self._minLen is not None:
    +            self._msg = "Value should be no smaller than {}" "".format(self._minLen)
    +        elif self._maxLen is not None:
    +            self._msg = "Value should be smaller than {}" "".format(self._maxLen)
    +
    +    def validate(self, value, data):
    +        failed = (self._minLen is not None and len(value) < self._minLen) or (
    +            self._maxLen is not None and len(value) > self._maxLen
    +        )
    +        return False if (not isinstance(value, str)) or failed else True
    +
    +
    +class Pattern(Validator):
    +    """A validator that accepts strings that match a given regular expression."""
    +
    +    def __init__(self, regexp, flags=0):
    +        """
    +        :param regexp: The regular expression (string or compiled)
    +            to be matched.
    +        :param flags: flags value for regular expression.
    +        """
    +        super().__init__()
    +        self._regexp = re.compile(regexp, flags=flags)
    +        self._msg = "Not matching the pattern"
    +
    +    def validate(self, value, data):
    +        return self._regexp.match(value) and True or False
    +
    +
    +class Host(Pattern):
    +    """A validator that accepts strings that represent network hostname."""
    +
    +    def __init__(self):
    +        regexp = (
    +            r"^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*"
    +            r"([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$"
    +        )
    +        super().__init__(regexp, flags=re.I)
    +        self._msg = "Invalid hostname"
    +
    +
    +class Port(Range):
    +    """Port number."""
    +
    +    def __init__(self):
    +        super().__init__(0, 65535)
    +        self._msg = "Port number should be an integer between 0 and 65535"
    +
    +    def validate(self, value, data):
    +        try:
    +            value = int(value)
    +        except ValueError:
    +            return False
    +        return super().validate(value, data)
    +
    +
    +class RequiredIf(Validator):
    +    """
    +    Some other fields are required in the payload data of request
    +    if this one is inputted as some specified values.
    +    """
    +
    +    def __init__(self, fields, spec_vals=()):
    +        """
    +
    +        :param fields: fields to be checked
    +        :param spec_vals: specified values for this field.
    +            If value list is empty, it means any non-empty value.
    +        :return:
    +        """
    +        self.fields = fields
    +        self.spec_vals = set(spec_vals)
    +
    +    def validate(self, value, data):
    +        if self.spec_vals and value not in self.spec_vals:
    +            return True
    +
    +        for field in self.fields:
    +            val = data.get(field, "")
    +            if not val:
    +                self._msg = '"%s" is required for input' % field
    +                return False
    +        return True
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/__init__.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/__init__.py
    new file mode 100644
    index 0000000..72d4509
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/__init__.py
    @@ -0,0 +1,15 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/rest_helper.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/rest_helper.py
    new file mode 100644
    index 0000000..70c19ac
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/rest_helper.py
    @@ -0,0 +1,68 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 requests
    +
    +
    +class TARestHelper:
    +    def __init__(self, logger=None):
    +        self.logger = logger
    +        self.http_session = None
    +        self.requests_proxy = None
    +
    +    def _init_request_session(self, proxy_uri=None):
    +        self.http_session = requests.Session()
    +        self.http_session.mount("http://", requests.adapters.HTTPAdapter(max_retries=3))
    +        self.http_session.mount(
    +            "https://", requests.adapters.HTTPAdapter(max_retries=3)
    +        )
    +        if proxy_uri:
    +            self.requests_proxy = {"http": proxy_uri, "https": proxy_uri}
    +
    +    def send_http_request(
    +        self,
    +        url,
    +        method,
    +        parameters=None,
    +        payload=None,
    +        headers=None,
    +        cookies=None,
    +        verify=True,
    +        cert=None,
    +        timeout=None,
    +        proxy_uri=None,
    +    ):
    +        if self.http_session is None:
    +            self._init_request_session(proxy_uri)
    +        requests_args = {"timeout": (10.0, 5.0), "verify": verify}
    +        if parameters:
    +            requests_args["params"] = parameters
    +        if payload:
    +            if isinstance(payload, (dict, list)):
    +                requests_args["json"] = payload
    +            else:
    +                requests_args["data"] = str(payload)
    +        if headers:
    +            requests_args["headers"] = headers
    +        if cookies:
    +            requests_args["cookies"] = cookies
    +        if cert:
    +            requests_args["cert"] = cert
    +        if timeout is not None:
    +            requests_args["timeout"] = timeout
    +        if self.requests_proxy:
    +            requests_args["proxies"] = self.requests_proxy
    +        return self.http_session.request(method, url, **requests_args)
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/rest_migration.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/rest_migration.py
    new file mode 100644
    index 0000000..3ef7acf
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/rest_migration.py
    @@ -0,0 +1,227 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 json
    +import traceback
    +from urllib.parse import urlparse
    +
    +from solnlib.conf_manager import ConfManager
    +from solnlib.splunk_rest_client import SplunkRestClient
    +from solnlib.splunkenv import get_splunkd_uri
    +
    +from splunktaucclib.rest_handler import util
    +from splunktaucclib.rest_handler.admin_external import AdminExternalHandler
    +from splunktaucclib.rest_handler.error import RestError
    +
    +
    +def _migrate_error_handle(func):
    +    def handle(*args, **kwargs):
    +        try:
    +            return func(*args, **kwargs)
    +        except:
    +            raise RestError(500, "Migrating failed. %s" % traceback.format_exc())
    +
    +    return handle
    +
    +
    +class ConfigMigrationHandler(AdminExternalHandler):
    +    """
    +    REST handler, which will migrate configuration
    +    from add-on built by previous version of TAB (v2.0.0).
    +    """
    +
    +    def handleList(self, confInfo):
    +        self._migrate()
    +        # use classic inheritance to be compatible for
    +        # old version of Splunk private SDK
    +        AdminExternalHandler.handleList(self, confInfo)
    +
    +    @_migrate_error_handle
    +    def _migrate(self):
    +        internal_endpoint = self.endpoint.internal_endpoint
    +        if not (
    +            internal_endpoint.endswith("settings")
    +            or internal_endpoint.endswith("account")
    +        ):
    +            return
    +
    +        splunkd_info = urlparse(get_splunkd_uri())
    +        self.base_app_name = util.get_base_app_name()
    +        self.conf_mgr = ConfManager(
    +            self.getSessionKey(),
    +            self.base_app_name,
    +            scheme=splunkd_info.scheme,
    +            host=splunkd_info.hostname,
    +            port=splunkd_info.port,
    +        )
    +        self.client = SplunkRestClient(
    +            self.getSessionKey(),
    +            self.base_app_name,
    +            scheme=splunkd_info.scheme,
    +            host=splunkd_info.hostname,
    +            port=splunkd_info.port,
    +        )
    +        self.legacy_passwords = None
    +
    +        # migration legacy configuration in related conf files
    +        if internal_endpoint.endswith("settings"):
    +            self._migrate_conf()
    +            self._migrate_conf_customized()
    +        elif internal_endpoint.endswith("account"):
    +            self._migrate_conf_credential()
    +
    +    def get_legacy_passwords(self):
    +        if self.legacy_passwords is None:
    +            self.legacy_passwords = {}
    +            for pwd in self.client.storage_passwords.list(count=-1):
    +                if pwd.realm == self.base_app_name:
    +                    self.legacy_passwords[pwd.username] = pwd
    +        return self.legacy_passwords
    +
    +    def _migrate_conf(self):
    +        """
    +        Migrate from <TA-name>.conf to <prefix>_settings.conf
    +        :return:
    +        """
    +        if self.callerArgs.id not in ("logging", "proxy"):
    +            return
    +        conf_file_name = self.base_app_name
    +        conf_file, stanzas = self._load_conf(conf_file_name)
    +        if not stanzas:
    +            return
    +
    +        # migrate: global_settings ==> logging
    +        if "global_settings" in stanzas and self.callerArgs.id == "logging":
    +            stanza = stanzas["global_settings"]
    +            if "log_level" in stanza:
    +                stanza["loglevel"] = stanza["log_level"]
    +                del stanza["log_level"]
    +            name = "logging"
    +            response = self.handler.update(
    +                name,
    +                self._filter_stanza(name, stanza),
    +            )
    +            self._loop_response(response)
    +            # delete legacy configuration
    +            self._delete_legacy(conf_file, {"global_settings": None})
    +
    +        # migrate: proxy_settings ==> proxy
    +        if "proxy_settings" in stanzas and self.callerArgs.id == "proxy":
    +            name = "proxy"
    +            response = self.handler.update(
    +                name,
    +                self._filter_stanza(name, stanzas["proxy_settings"]),
    +            )
    +            self._loop_response(response)
    +            # delete legacy configuration
    +            self._delete_legacy(conf_file, {"proxy_settings": None})
    +
    +    def _migrate_conf_customized(self):
    +        """
    +        Migrate from <TA-name>_customized.conf to <prefix>_settings.conf
    +        :return:
    +        """
    +        if self.callerArgs.id != "additional_parameters":
    +            return
    +
    +        conf_file_name = self.base_app_name + "_customized"
    +        conf_file, stanzas = self._load_conf(conf_file_name)
    +        if not stanzas:
    +            return
    +
    +        additional_parameters = {}
    +        for stanza_name, stanza in list(stanzas.items()):
    +            for key, val in list(stanza.items()):
    +                if key == "type":
    +                    continue
    +                else:
    +                    additional_parameter = val
    +                    break
    +            else:
    +                continue
    +            if additional_parameter:
    +                additional_parameters[stanza_name] = additional_parameter
    +
    +        name = "additional_parameters"
    +        response = self.handler.update(
    +            name,
    +            self._filter_stanza(name, additional_parameters),
    +        )
    +        self._loop_response(response)
    +
    +        # delete legacy configuration
    +        self._delete_legacy(conf_file, stanzas)
    +
    +    def _migrate_conf_credential(self):
    +        """
    +        Migrate from <TA-name>_credential.conf to <prefix>_account.conf
    +        :return:
    +        """
    +        conf_file_name = self.base_app_name + "_credential"
    +        conf_file, stanzas = self._load_conf(conf_file_name)
    +
    +        for stanza_name, stanza in list(stanzas.items()):
    +            stanza["username"] = stanza_name
    +            response = self.handler.create(
    +                stanza_name,
    +                stanza,
    +            )
    +            self._loop_response(response)
    +
    +        # delete legacy configuration
    +        self._delete_legacy(conf_file, stanzas)
    +
    +    def _load_conf(self, conf_file_name):
    +        if conf_file_name not in self.client.confs:
    +            return None, {}
    +        conf_file = self.conf_mgr.get_conf(conf_file_name)
    +        stanzas = conf_file.get_all()
    +        for stanza_name, stanza in list(stanzas.items()):
    +            pwd = self.get_legacy_passwords().get(stanza_name)
    +            if pwd:
    +                pwd_cont = json.loads(pwd.clear_password)
    +                stanza.update(pwd_cont)
    +            for key in list(stanza.keys()):
    +                if key.startswith("eai:") or key == "disabled":
    +                    del stanza[key]
    +
    +        return conf_file, stanzas
    +
    +    def _delete_legacy(self, conf_file, stanzas):
    +        for stanza_name, _ in list(stanzas.items()):
    +            try:
    +                # delete stanza from related conf file
    +                conf_file.delete(stanza_name)
    +            except Exception:
    +                pass
    +
    +            pwd = self.get_legacy_passwords().get(stanza_name)
    +            try:
    +                # delete password from passwords.conf
    +                if pwd:
    +                    pwd.delete()
    +            except Exception:
    +                pass
    +
    +    def _filter_stanza(self, stanza_name, stanza):
    +        model = self.endpoint.model(stanza_name, stanza)
    +        stanza_new = {f.name: stanza[f.name] for f in model.fields if f.name in stanza}
    +        return stanza_new
    +
    +    @classmethod
    +    def _loop_response(cls, response):
    +        for _ in response:
    +            pass
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/setup_util.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/setup_util.py
    new file mode 100644
    index 0000000..3fd9e3a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/setup_util.py
    @@ -0,0 +1,397 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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 json
    +import os
    +
    +import solnlib.utils as utils
    +
    +from splunktaucclib.global_config import GlobalConfig, GlobalConfigSchema
    +
    +"""
    +Usage Examples:
    +setup_util = Setup_Util(uri, session_key)
    +setup_util.get_log_level()
    +setup_util.get_proxy_settings()
    +setup_util.get_credential_account("my_account_name")
    +setup_util.get_customized_setting("my_customized_field_name")
    +"""
    +
    +"""
    +setting object structure.
    +It is stored in self.__cached_global_settings
    +Note, this structure is only maintained in this util.
    +setup_util transforms global settings in os environment or from ucc into this structure.
    +{
    +    "proxy_settings": {
    +    "proxy_enabled": False/True,
    +    "proxy_url": "example.com",
    +    "proxy_port": "1234",
    +    "proxy_username": "",
    +    "proxy_password": "",
    +    "proxy_type": "http",
    +    "proxy_rdns": False/True
    +    },
    +    "log_settings": {
    +        "loglevel": "DEBUG"
    +    },
    +    "credential_settings": [{
    +        "name": "account_id",
    +        "username": "example_account",
    +        "password": "example_password"
    +    }, { # supported by ucc, not seen any usage in AoB
    +        "api_key": "admin",
    +        "api_uuid": "admin",
    +        "endpoint": "some url",
    +        "name": "account1"
    +    }],
    +    "customized_settings": {
    +        "text_name": "content",
    +        "pass_name": "password",
    +        "checkbox": 0/1
    +    }
    +}
    +"""
    +
    +GLOBAL_SETTING_KEY = "global_settings"
    +AOB_TEST_FLAG = "AOB_TEST"
    +
    +PROXY_SETTINGS = "proxy_settings"
    +LOG_SETTINGS = "log_settings"
    +CREDENTIAL_SETTINGS = "credential_settings"
    +CUSTOMIZED_SETTINGS = "customized_settings"
    +
    +UCC_PROXY = "proxy"
    +UCC_LOGGING = "logging"
    +UCC_CUSTOMIZED = "additional_parameters"
    +UCC_CREDENTIAL = "account"
    +
    +CONFIGS = [CREDENTIAL_SETTINGS]
    +SETTINGS = [PROXY_SETTINGS, LOG_SETTINGS, CUSTOMIZED_SETTINGS]
    +
    +PROXY_ENABLE_KEY = "proxy_enabled"
    +PROXY_RDNS_KEY = "proxy_rdns"
    +LOG_LEVEL_KEY = "loglevel"
    +LOG_LEVEL_KEY_ENV = "log_level"
    +
    +TYPE_CHECKBOX = "checkbox"
    +ALL_SETTING_TYPES = [
    +    "text",
    +    "password",
    +    "checkbox",
    +    "dropdownlist",
    +    "multi_dropdownlist",
    +    "radiogroup",
    +]
    +
    +
    +def get_schema_path():
    +    dirname = os.path.dirname
    +    basedir = dirname(dirname(dirname(dirname(__file__))))
    +    return os.path.join(
    +        basedir, "appserver", "static", "js", "build", "globalConfig.json"
    +    )
    +
    +
    +class Setup_Util:
    +    def __init__(self, uri, session_key, logger=None):
    +        self.__uri = uri
    +        self.__session_key = session_key
    +        self.__logger = logger
    +        self.scheme, self.host, self.port = utils.extract_http_scheme_host_port(
    +            self.__uri
    +        )
    +        self.__cached_global_settings = {}
    +        self.__global_config = None
    +
    +    def init_global_config(self):
    +        if self.__global_config is not None:
    +            return
    +        schema_file = get_schema_path()
    +        if not os.path.isfile(schema_file):
    +            self.log_error("Global config JSON file not found!")
    +            self.__global_config = None
    +        else:
    +            with open(get_schema_path()) as f:
    +                json_schema = "".join([l for l in f])
    +            self.__global_config = GlobalConfig(
    +                self.__uri,
    +                self.__session_key,
    +                GlobalConfigSchema(json.loads(json_schema)),
    +            )
    +
    +    def log_error(self, msg):
    +        if self.__logger:
    +            self.__logger.error(msg)
    +
    +    def log_info(self, msg):
    +        if self.__logger:
    +            self.__logger.info(msg)
    +
    +    def log_debug(self, msg):
    +        if self.__logger:
    +            self.__logger.debug(msg)
    +
    +    def _parse_conf(self, key):
    +        if os.environ.get(AOB_TEST_FLAG, "false") == "true":
    +            global_settings = self._parse_conf_from_env(
    +                json.loads(os.environ.get(GLOBAL_SETTING_KEY, "{}"))
    +            )
    +            return global_settings.get(key)
    +        else:
    +            return self._parse_conf_from_global_config(key)
    +
    +    def _parse_conf_from_env(self, global_settings):
    +        """
    +        this is run in test env
    +        """
    +        if not self.__cached_global_settings:
    +            # format the settings, the setting from env is from global_setting
    +            # meta
    +            self.__cached_global_settings = {}
    +            for s_k, s_v in list(global_settings.items()):
    +                if s_k == PROXY_SETTINGS:
    +                    proxy_enabled = s_v.get(PROXY_ENABLE_KEY)
    +                    proxy_rdns = s_v.get(PROXY_RDNS_KEY)
    +                    if type(proxy_enabled) != bool:
    +                        s_v[PROXY_ENABLE_KEY] = utils.is_true(proxy_enabled)
    +                    if type(proxy_rdns) != bool:
    +                        s_v[PROXY_RDNS_KEY] = utils.is_true(proxy_rdns)
    +                    self.__cached_global_settings[PROXY_SETTINGS] = s_v
    +                elif s_k == LOG_SETTINGS:
    +                    self.__cached_global_settings[LOG_SETTINGS] = {
    +                        LOG_LEVEL_KEY: s_v.get(LOG_LEVEL_KEY_ENV)
    +                    }
    +                elif s_k == CREDENTIAL_SETTINGS:
    +                    # add account id to accounts
    +                    for i in range(0, len(s_v)):
    +                        s_v[i]["name"] = "account" + str(i)
    +                    self.__cached_global_settings[CREDENTIAL_SETTINGS] = s_v
    +                else:  # should be customized settings
    +                    self.__cached_global_settings[CUSTOMIZED_SETTINGS] = {}
    +                    for s in s_v:
    +                        field_type = s.get("type")
    +                        if not field_type:
    +                            self.log_error(f"unknown type for customized var:{s}")
    +                            continue
    +                        self.__cached_global_settings["customized_settings"][
    +                            s.get("name", "")
    +                        ] = self._transform(s.get("value", ""), field_type)
    +
    +        return self.__cached_global_settings
    +
    +    def _parse_conf_from_global_config(self, key):
    +        if self.__cached_global_settings and key in self.__cached_global_settings:
    +            return self.__cached_global_settings.get(key)
    +        self.init_global_config()
    +        if self.__global_config is None:
    +            return None
    +        if key in CONFIGS:
    +            accounts = self.__global_config.configs.load().get(UCC_CREDENTIAL, [])
    +            if accounts:
    +                for account in accounts:
    +                    if "disabled" in account:
    +                        del account["disabled"]
    +            self.__cached_global_settings[CREDENTIAL_SETTINGS] = accounts
    +        elif key in SETTINGS:
    +            settings = self.__global_config.settings.load()
    +            self.__cached_global_settings.update(
    +                {UCC_PROXY: None, UCC_LOGGING: None, UCC_CUSTOMIZED: None}
    +            )
    +            customized_setting = {}
    +            for setting in settings.get("settings", []):
    +                # filter out disabled setting page and 'disabled' field
    +                if setting.get("disabled", False):
    +                    continue
    +                if setting["name"] == UCC_LOGGING:
    +                    self.__cached_global_settings[LOG_SETTINGS] = {
    +                        LOG_LEVEL_KEY: setting.get(LOG_LEVEL_KEY)
    +                    }
    +                elif setting["name"] == UCC_PROXY:
    +                    if "disabled" in setting:
    +                        del setting["disabled"]
    +                    setting[PROXY_ENABLE_KEY] = utils.is_true(
    +                        setting.get(PROXY_ENABLE_KEY, "0")
    +                    )
    +                    setting[PROXY_RDNS_KEY] = utils.is_true(
    +                        setting.get(PROXY_RDNS_KEY, "0")
    +                    )
    +                    self.__cached_global_settings[PROXY_SETTINGS] = setting
    +                else:  # should be customized settings
    +                    if "disabled" in setting:
    +                        del setting["disabled"]
    +                    customized_setting.update(setting)
    +            self.__cached_global_settings[CUSTOMIZED_SETTINGS] = customized_setting
    +
    +        return self.__cached_global_settings.get(key)
    +
    +    def get_log_level(self):
    +        log_level = "INFO"
    +        log_settings = self._parse_conf(LOG_SETTINGS)
    +        if log_settings is None:
    +            self.log_info("Log level is not set, use default INFO")
    +        else:
    +            log_level = log_settings.get(LOG_LEVEL_KEY, None)
    +            if not log_level:
    +                self.log_info("Log level is not set, use default INFO")
    +                log_level = "INFO"
    +        return log_level
    +
    +    def get_proxy_settings(self):
    +        proxy_settings = self._parse_conf(PROXY_SETTINGS)
    +        if proxy_settings is None:
    +            self.log_info("Proxy is not set!")
    +            return {}
    +        proxy_enabled = proxy_settings.get(PROXY_ENABLE_KEY)
    +        if not proxy_enabled:
    +            self.log_info("Proxy is not enabled!")
    +            return {}
    +        proxy_settings = {
    +            "proxy_url": proxy_settings.get("proxy_url", ""),
    +            "proxy_port": proxy_settings.get("proxy_port", None),
    +            "proxy_username": proxy_settings.get("proxy_username", ""),
    +            "proxy_password": proxy_settings.get("proxy_password", ""),
    +            "proxy_type": proxy_settings.get("proxy_type", ""),
    +            "proxy_rdns": proxy_settings.get("proxy_rdns"),
    +        }
    +        self._validate_proxy_settings(proxy_settings)
    +        return proxy_settings
    +
    +    def get_credential_by_id(self, account_id):
    +        credential_settings = self._parse_conf(CREDENTIAL_SETTINGS)
    +        for account in credential_settings:
    +            if account.get("name", None) == account_id:
    +                return account
    +        self.log_error(
    +            f"Credential account with account id {account_id} can not be found"
    +        )
    +        return None
    +
    +    def get_credential_by_username(self, username):
    +        credential_settings = self._parse_conf(CREDENTIAL_SETTINGS)
    +        for account in credential_settings:
    +            if account.get("username", None) == username:
    +                return account
    +        self.log_error(f"Credential account with username {username} can not be found")
    +        return None
    +
    +    def get_customized_setting(self, key):
    +        customized_settings = self._parse_conf(CUSTOMIZED_SETTINGS)
    +        if customized_settings is None:
    +            self.log_info("Customized setting is not set")
    +            return None
    +        if key not in customized_settings:
    +            self.log_info("Customized key can not be found")
    +            return None
    +        customized_setting = customized_settings.get(key, None)
    +        if customized_setting is None:
    +            self.log_error("Cannot find customized setting with key %s" % key)
    +        return customized_setting
    +
    +    def _validate_proxy_settings(self, proxy_settings):
    +        if proxy_settings:
    +            if proxy_settings.get("proxy_url") == "":
    +                raise Exception("Proxy host must not be empty!")
    +            proxy_port = proxy_settings.get("proxy_port")
    +            if proxy_port is None or not proxy_port.isdigit():
    +                raise Exception("Proxy port must be a number!")
    +
    +    def _transform(self, value, field_type):
    +        """
    +        This is method is only used when parsing customized global params from env.
    +        Only checkbox type needs transform. Other types will be extracted automatically when apply json.loads.
    +        :param value:
    +        :param field_type: can be checkbox, text, password, dropdownlist, multi_dropdownlist, radiogroup
    +        :return:
    +        """
    +        if field_type == TYPE_CHECKBOX:
    +            return utils.is_true(value)
    +        elif field_type in ALL_SETTING_TYPES:
    +            return value
    +        else:
    +            raise Exception(
    +                "Type of this customized setting is corrupted. Value: {}, type: {}".format(
    +                    value, field_type
    +                )
    +            )
    +
    +    """
    +    # the following methods is used by AoB internally
    +    # user should not use this
    +    # These methods returns the similiar structure like ucc libs
    +
    +    the output of config is like
    +{
    +  "account": [
    +    {
    +      "username": "admin",
    +      "credential": "a",
    +      "name": "ddddd",
    +      "disabled": false
    +    }
    +  ]
    +}
    +
    +    the output of settings is like
    +{
    +  "settings": [
    +    {
    +      "additional_parameters": {
    +        "checkbox": "1",
    +        "text": "msn",
    +        "disabled": false
    +      }
    +    },
    +    {
    +      "proxy": {
    +        "proxy_type": "http",
    +        "proxy_port": "9999",
    +        "proxy_url": "localhost",
    +        "proxy_rdns": "1",
    +        "disabled": false,
    +        "proxy_password": "a",
    +        "proxy_username": "admin",
    +        "proxy_enabled": "1"
    +      }
    +    },
    +    {
    +      "logging": {
    +        "loglevel": "ERROR",
    +        "disabled": false
    +      }
    +    }
    +  ]
    +}
    +    """
    +
    +    def get_ucc_log_setting(self):
    +        return {UCC_LOGGING: self._parse_conf(LOG_SETTINGS)}
    +
    +    def get_ucc_proxy_setting(self):
    +        p = dict(self.get_proxy_settings())
    +        p[PROXY_ENABLE_KEY] = True if p else False
    +        return {UCC_PROXY: p}
    +
    +    def get_ucc_customized_setting(self):
    +        customized_settings = self._parse_conf(CUSTOMIZED_SETTINGS)
    +        if customized_settings:
    +            return {UCC_CUSTOMIZED: customized_settings}
    +        else:
    +            return {}
    +
    +    # account belongs to the configs
    +    def get_ucc_account_config(self):
    +        return {UCC_CREDENTIAL: self._parse_conf(CREDENTIAL_SETTINGS)}
    diff --git a/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/utility.py b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/utility.py
    new file mode 100644
    index 0000000..627b659
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/splunktaucclib/splunk_aoblib/utility.py
    @@ -0,0 +1,35 @@
    +#
    +# Copyright 2021 Splunk Inc.
    +#
    +# Licensed 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.
    +#
    +
    +# encoding = utf-8
    +
    +import logging
    +import sys
    +
    +
    +def get_stderr_stream_logger(logger_name=None, log_level=logging.INFO):
    +    if logger_name is None:
    +        logger_name = "aob_default_logger"
    +    logger = logging.getLogger(logger_name)
    +    formatter = logging.Formatter(
    +        "%(asctime)s - %(name)s - [%(levelname)s] - %(message)s"
    +    )
    +    stderr_handler = logging.StreamHandler(stream=sys.stderr)
    +    stderr_handler.setLevel(logging.DEBUG)
    +    stderr_handler.setFormatter(formatter)
    +    logger.addHandler(stderr_handler)
    +    logger.setLevel(log_level)
    +    return logger
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3-1.26.14.dist-info/INSTALLER b/deployment-apps/metricator-for-nmon/lib/urllib3-1.26.14.dist-info/INSTALLER
    new file mode 100644
    index 0000000..a1b589e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3-1.26.14.dist-info/INSTALLER
    @@ -0,0 +1 @@
    +pip
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3-1.26.14.dist-info/METADATA b/deployment-apps/metricator-for-nmon/lib/urllib3-1.26.14.dist-info/METADATA
    new file mode 100644
    index 0000000..66ae6e2
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3-1.26.14.dist-info/METADATA
    @@ -0,0 +1,1464 @@
    +Metadata-Version: 2.1
    +Name: urllib3
    +Version: 1.26.14
    +Summary: HTTP library with thread-safe connection pooling, file post, and more.
    +Home-page: https://urllib3.readthedocs.io/
    +Author: Andrey Petrov
    +Author-email: andrey.petrov@shazow.net
    +License: MIT
    +Project-URL: Documentation, https://urllib3.readthedocs.io/
    +Project-URL: Code, https://github.com/urllib3/urllib3
    +Project-URL: Issue tracker, https://github.com/urllib3/urllib3/issues
    +Keywords: urllib httplib threadsafe filepost http https ssl pooling
    +Classifier: Environment :: Web Environment
    +Classifier: Intended Audience :: Developers
    +Classifier: License :: OSI Approved :: MIT License
    +Classifier: Operating System :: OS Independent
    +Classifier: Programming Language :: Python
    +Classifier: Programming Language :: Python :: 2
    +Classifier: Programming Language :: Python :: 2.7
    +Classifier: Programming Language :: Python :: 3
    +Classifier: Programming Language :: Python :: 3.6
    +Classifier: Programming Language :: Python :: 3.7
    +Classifier: Programming Language :: Python :: 3.8
    +Classifier: Programming Language :: Python :: 3.9
    +Classifier: Programming Language :: Python :: 3.10
    +Classifier: Programming Language :: Python :: 3.11
    +Classifier: Programming Language :: Python :: Implementation :: CPython
    +Classifier: Programming Language :: Python :: Implementation :: PyPy
    +Classifier: Topic :: Internet :: WWW/HTTP
    +Classifier: Topic :: Software Development :: Libraries
    +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*
    +Description-Content-Type: text/x-rst
    +License-File: LICENSE.txt
    +Provides-Extra: brotli
    +Requires-Dist: brotlicffi (>=0.8.0) ; ((os_name != "nt" or python_version >= "3") and platform_python_implementation != "CPython") and extra == 'brotli'
    +Requires-Dist: brotli (>=1.0.9) ; ((os_name != "nt" or python_version >= "3") and platform_python_implementation == "CPython") and extra == 'brotli'
    +Requires-Dist: brotlipy (>=0.6.0) ; (os_name == "nt" and python_version < "3") and extra == 'brotli'
    +Provides-Extra: secure
    +Requires-Dist: pyOpenSSL (>=0.14) ; extra == 'secure'
    +Requires-Dist: cryptography (>=1.3.4) ; extra == 'secure'
    +Requires-Dist: idna (>=2.0.0) ; extra == 'secure'
    +Requires-Dist: certifi ; extra == 'secure'
    +Requires-Dist: urllib3-secure-extra ; extra == 'secure'
    +Requires-Dist: ipaddress ; (python_version == "2.7") and extra == 'secure'
    +Provides-Extra: socks
    +Requires-Dist: PySocks (!=1.5.7,<2.0,>=1.5.6) ; extra == 'socks'
    +
    +
    +urllib3 is a powerful, *user-friendly* HTTP client for Python. Much of the
    +Python ecosystem already uses urllib3 and you should too.
    +urllib3 brings many critical features that are missing from the Python
    +standard libraries:
    +
    +- Thread safety.
    +- Connection pooling.
    +- Client-side SSL/TLS verification.
    +- File uploads with multipart encoding.
    +- Helpers for retrying requests and dealing with HTTP redirects.
    +- Support for gzip, deflate, and brotli encoding.
    +- Proxy support for HTTP and SOCKS.
    +- 100% test coverage.
    +
    +urllib3 is powerful and easy to use:
    +
    +.. code-block:: python
    +
    +    >>> import urllib3
    +    >>> http = urllib3.PoolManager()
    +    >>> r = http.request('GET', 'http://httpbin.org/robots.txt')
    +    >>> r.status
    +    200
    +    >>> r.data
    +    'User-agent: *\nDisallow: /deny\n'
    +
    +
    +Installing
    +----------
    +
    +urllib3 can be installed with `pip <https://pip.pypa.io>`_::
    +
    +    $ python -m pip install urllib3
    +
    +Alternatively, you can grab the latest source code from `GitHub <https://github.com/urllib3/urllib3>`_::
    +
    +    $ git clone https://github.com/urllib3/urllib3.git
    +    $ cd urllib3
    +    $ git checkout 1.26.x
    +    $ pip install .
    +
    +
    +Documentation
    +-------------
    +
    +urllib3 has usage and reference documentation at `urllib3.readthedocs.io <https://urllib3.readthedocs.io>`_.
    +
    +
    +Contributing
    +------------
    +
    +urllib3 happily accepts contributions. Please see our
    +`contributing documentation <https://urllib3.readthedocs.io/en/latest/contributing.html>`_
    +for some tips on getting started.
    +
    +
    +Security Disclosures
    +--------------------
    +
    +To report a security vulnerability, please use the
    +`Tidelift security contact <https://tidelift.com/security>`_.
    +Tidelift will coordinate the fix and disclosure with maintainers.
    +
    +
    +Maintainers
    +-----------
    +
    +- `@sethmlarson <https://github.com/sethmlarson>`__ (Seth M. Larson)
    +- `@pquentin <https://github.com/pquentin>`__ (Quentin Pradet)
    +- `@theacodes <https://github.com/theacodes>`__ (Thea Flowers)
    +- `@haikuginger <https://github.com/haikuginger>`__ (Jess Shapiro)
    +- `@lukasa <https://github.com/lukasa>`__ (Cory Benfield)
    +- `@sigmavirus24 <https://github.com/sigmavirus24>`__ (Ian Stapleton Cordasco)
    +- `@shazow <https://github.com/shazow>`__ (Andrey Petrov)
    +
    +👋
    +
    +
    +Sponsorship
    +-----------
    +
    +If your company benefits from this library, please consider `sponsoring its
    +development <https://urllib3.readthedocs.io/en/latest/sponsors.html>`_.
    +
    +
    +For Enterprise
    +--------------
    +
    +.. |tideliftlogo| image:: https://nedbatchelder.com/pix/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White_small.png
    +   :width: 75
    +   :alt: Tidelift
    +
    +.. list-table::
    +   :widths: 10 100
    +
    +   * - |tideliftlogo|
    +     - Professional support for urllib3 is available as part of the `Tidelift
    +       Subscription`_.  Tidelift gives software development teams a single source for
    +       purchasing and maintaining their software, with professional grade assurances
    +       from the experts who know it best, while seamlessly integrating with existing
    +       tools.
    +
    +.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-urllib3?utm_source=pypi-urllib3&utm_medium=referral&utm_campaign=readme
    +
    +
    +Changes
    +=======
    +
    +1.26.14 (2023-01-11)
    +--------------------
    +
    +* Fixed parsing of port 0 (zero) returning None, instead of 0. (`#2850 <https://github.com/urllib3/urllib3/issues/2850>`__)
    +* Removed deprecated getheaders() calls in contrib module.
    +
    +1.26.13 (2022-11-23)
    +--------------------
    +
    +* Deprecated the ``HTTPResponse.getheaders()`` and ``HTTPResponse.getheader()`` methods.
    +* Fixed an issue where parsing a URL with leading zeroes in the port would be rejected
    +  even when the port number after removing the zeroes was valid.
    +* Fixed a deprecation warning when using cryptography v39.0.0.
    +* Removed the ``<4`` in the ``Requires-Python`` packaging metadata field.
    +
    +
    +1.26.12 (2022-08-22)
    +--------------------
    +
    +* Deprecated the `urllib3[secure]` extra and the `urllib3.contrib.pyopenssl` module.
    +  Both will be removed in v2.x. See this `GitHub issue <https://github.com/urllib3/urllib3/issues/2680>`_
    +  for justification and info on how to migrate.
    +
    +
    +1.26.11 (2022-07-25)
    +--------------------
    +
    +* Fixed an issue where reading more than 2 GiB in a call to ``HTTPResponse.read`` would
    +  raise an ``OverflowError`` on Python 3.9 and earlier.
    +
    +
    +1.26.10 (2022-07-07)
    +--------------------
    +
    +* Removed support for Python 3.5
    +* Fixed an issue where a ``ProxyError`` recommending configuring the proxy as HTTP
    +  instead of HTTPS could appear even when an HTTPS proxy wasn't configured.
    +
    +
    +1.26.9 (2022-03-16)
    +-------------------
    +
    +* Changed ``urllib3[brotli]`` extra to favor installing Brotli libraries that are still
    +  receiving updates like ``brotli`` and ``brotlicffi`` instead of ``brotlipy``.
    +  This change does not impact behavior of urllib3, only which dependencies are installed.
    +* Fixed a socket leaking when ``HTTPSConnection.connect()`` raises an exception.
    +* Fixed ``server_hostname`` being forwarded from ``PoolManager`` to ``HTTPConnectionPool``
    +  when requesting an HTTP URL. Should only be forwarded when requesting an HTTPS URL.
    +
    +
    +1.26.8 (2022-01-07)
    +-------------------
    +
    +* Added extra message to ``urllib3.exceptions.ProxyError`` when urllib3 detects that
    +  a proxy is configured to use HTTPS but the proxy itself appears to only use HTTP.
    +* Added a mention of the size of the connection pool when discarding a connection due to the pool being full.
    +* Added explicit support for Python 3.11.
    +* Deprecated the ``Retry.MAX_BACKOFF`` class property in favor of ``Retry.DEFAULT_MAX_BACKOFF``
    +  to better match the rest of the default parameter names. ``Retry.MAX_BACKOFF`` is removed in v2.0.
    +* Changed location of the vendored ``ssl.match_hostname`` function from ``urllib3.packages.ssl_match_hostname``
    +  to ``urllib3.util.ssl_match_hostname`` to ensure Python 3.10+ compatibility after being repackaged
    +  by downstream distributors.
    +* Fixed absolute imports, all imports are now relative.
    +
    +
    +1.26.7 (2021-09-22)
    +-------------------
    +
    +* Fixed a bug with HTTPS hostname verification involving IP addresses and lack
    +  of SNI. (Issue #2400)
    +* Fixed a bug where IPv6 braces weren't stripped during certificate hostname
    +  matching. (Issue #2240)
    +
    +
    +1.26.6 (2021-06-25)
    +-------------------
    +
    +* Deprecated the ``urllib3.contrib.ntlmpool`` module. urllib3 is not able to support
    +  it properly due to `reasons listed in this issue <https://github.com/urllib3/urllib3/issues/2282>`_.
    +  If you are a user of this module please leave a comment.
    +* Changed ``HTTPConnection.request_chunked()`` to not erroneously emit multiple
    +  ``Transfer-Encoding`` headers in the case that one is already specified.
    +* Fixed typo in deprecation message to recommend ``Retry.DEFAULT_ALLOWED_METHODS``.
    +
    +
    +1.26.5 (2021-05-26)
    +-------------------
    +
    +* Fixed deprecation warnings emitted in Python 3.10.
    +* Updated vendored ``six`` library to 1.16.0.
    +* Improved performance of URL parser when splitting
    +  the authority component.
    +
    +
    +1.26.4 (2021-03-15)
    +-------------------
    +
    +* Changed behavior of the default ``SSLContext`` when connecting to HTTPS proxy
    +  during HTTPS requests. The default ``SSLContext`` now sets ``check_hostname=True``.
    +
    +
    +1.26.3 (2021-01-26)
    +-------------------
    +
    +* Fixed bytes and string comparison issue with headers (Pull #2141)
    +
    +* Changed ``ProxySchemeUnknown`` error message to be
    +  more actionable if the user supplies a proxy URL without
    +  a scheme. (Pull #2107)
    +
    +
    +1.26.2 (2020-11-12)
    +-------------------
    +
    +* Fixed an issue where ``wrap_socket`` and ``CERT_REQUIRED`` wouldn't
    +  be imported properly on Python 2.7.8 and earlier (Pull #2052)
    +
    +
    +1.26.1 (2020-11-11)
    +-------------------
    +
    +* Fixed an issue where two ``User-Agent`` headers would be sent if a
    +  ``User-Agent`` header key is passed as ``bytes`` (Pull #2047)
    +
    +
    +1.26.0 (2020-11-10)
    +-------------------
    +
    +* **NOTE: urllib3 v2.0 will drop support for Python 2**.
    +  `Read more in the v2.0 Roadmap <https://urllib3.readthedocs.io/en/latest/v2-roadmap.html>`_.
    +
    +* Added support for HTTPS proxies contacting HTTPS servers (Pull #1923, Pull #1806)
    +
    +* Deprecated negotiating TLSv1 and TLSv1.1 by default. Users that
    +  still wish to use TLS earlier than 1.2 without a deprecation warning
    +  should opt-in explicitly by setting ``ssl_version=ssl.PROTOCOL_TLSv1_1`` (Pull #2002)
    +  **Starting in urllib3 v2.0: Connections that receive a ``DeprecationWarning`` will fail**
    +
    +* Deprecated ``Retry`` options ``Retry.DEFAULT_METHOD_WHITELIST``, ``Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST``
    +  and ``Retry(method_whitelist=...)`` in favor of ``Retry.DEFAULT_ALLOWED_METHODS``,
    +  ``Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT``, and ``Retry(allowed_methods=...)``
    +  (Pull #2000) **Starting in urllib3 v2.0: Deprecated options will be removed**
    +
    +* Added default ``User-Agent`` header to every request (Pull #1750)
    +
    +* Added ``urllib3.util.SKIP_HEADER`` for skipping ``User-Agent``, ``Accept-Encoding``, 
    +  and ``Host`` headers from being automatically emitted with requests (Pull #2018)
    +
    +* Collapse ``transfer-encoding: chunked`` request data and framing into
    +  the same ``socket.send()`` call (Pull #1906)
    +
    +* Send ``http/1.1`` ALPN identifier with every TLS handshake by default (Pull #1894)
    +
    +* Properly terminate SecureTransport connections when CA verification fails (Pull #1977)
    +
    +* Don't emit an ``SNIMissingWarning`` when passing ``server_hostname=None``
    +  to SecureTransport (Pull #1903)
    +
    +* Disabled requesting TLSv1.2 session tickets as they weren't being used by urllib3 (Pull #1970)
    +
    +* Suppress ``BrokenPipeError`` when writing request body after the server
    +  has closed the socket (Pull #1524)
    +
    +* Wrap ``ssl.SSLError`` that can be raised from reading a socket (e.g. "bad MAC")
    +  into an ``urllib3.exceptions.SSLError`` (Pull #1939)
    +
    +
    +1.25.11 (2020-10-19)
    +--------------------
    +
    +* Fix retry backoff time parsed from ``Retry-After`` header when given
    +  in the HTTP date format. The HTTP date was parsed as the local timezone
    +  rather than accounting for the timezone in the HTTP date (typically
    +  UTC) (Pull #1932, Pull #1935, Pull #1938, Pull #1949)
    +
    +* Fix issue where an error would be raised when the ``SSLKEYLOGFILE``
    +  environment variable was set to the empty string. Now ``SSLContext.keylog_file``
    +  is not set in this situation (Pull #2016)
    +
    +
    +1.25.10 (2020-07-22)
    +--------------------
    +
    +* Added support for ``SSLKEYLOGFILE`` environment variable for
    +  logging TLS session keys with use with programs like
    +  Wireshark for decrypting captured web traffic (Pull #1867)
    +
    +* Fixed loading of SecureTransport libraries on macOS Big Sur
    +  due to the new dynamic linker cache (Pull #1905)
    +
    +* Collapse chunked request bodies data and framing into one
    +  call to ``send()`` to reduce the number of TCP packets by 2-4x (Pull #1906)
    +
    +* Don't insert ``None`` into ``ConnectionPool`` if the pool
    +  was empty when requesting a connection (Pull #1866)
    +
    +* Avoid ``hasattr`` call in ``BrotliDecoder.decompress()`` (Pull #1858)
    +
    +
    +1.25.9 (2020-04-16)
    +-------------------
    +
    +* Added ``InvalidProxyConfigurationWarning`` which is raised when
    +  erroneously specifying an HTTPS proxy URL. urllib3 doesn't currently
    +  support connecting to HTTPS proxies but will soon be able to
    +  and we would like users to migrate properly without much breakage.
    +
    +  See `this GitHub issue <https://github.com/urllib3/urllib3/issues/1850>`_
    +  for more information on how to fix your proxy config. (Pull #1851)
    +
    +* Drain connection after ``PoolManager`` redirect (Pull #1817)
    +
    +* Ensure ``load_verify_locations`` raises ``SSLError`` for all backends (Pull #1812)
    +
    +* Rename ``VerifiedHTTPSConnection`` to ``HTTPSConnection`` (Pull #1805)
    +
    +* Allow the CA certificate data to be passed as a string (Pull #1804)
    +
    +* Raise ``ValueError`` if method contains control characters (Pull #1800)
    +
    +* Add ``__repr__`` to ``Timeout`` (Pull #1795)
    +
    +
    +1.25.8 (2020-01-20)
    +-------------------
    +
    +* Drop support for EOL Python 3.4 (Pull #1774)
    +
    +* Optimize _encode_invalid_chars (Pull #1787)
    +
    +
    +1.25.7 (2019-11-11)
    +-------------------
    +
    +* Preserve ``chunked`` parameter on retries (Pull #1715, Pull #1734)
    +
    +* Allow unset ``SERVER_SOFTWARE`` in App Engine (Pull #1704, Issue #1470)
    +
    +* Fix issue where URL fragment was sent within the request target. (Pull #1732)
    +
    +* Fix issue where an empty query section in a URL would fail to parse. (Pull #1732)
    +
    +* Remove TLS 1.3 support in SecureTransport due to Apple removing support (Pull #1703)
    +
    +
    +1.25.6 (2019-09-24)
    +-------------------
    +
    +* Fix issue where tilde (``~``) characters were incorrectly
    +  percent-encoded in the path. (Pull #1692)
    +
    +
    +1.25.5 (2019-09-19)
    +-------------------
    +
    +* Add mitigation for BPO-37428 affecting Python <3.7.4 and OpenSSL 1.1.1+ which
    +  caused certificate verification to be enabled when using ``cert_reqs=CERT_NONE``.
    +  (Issue #1682)
    +
    +
    +1.25.4 (2019-09-19)
    +-------------------
    +
    +* Propagate Retry-After header settings to subsequent retries. (Pull #1607)
    +
    +* Fix edge case where Retry-After header was still respected even when
    +  explicitly opted out of. (Pull #1607)
    +
    +* Remove dependency on ``rfc3986`` for URL parsing.
    +
    +* Fix issue where URLs containing invalid characters within ``Url.auth`` would
    +  raise an exception instead of percent-encoding those characters.
    +
    +* Add support for ``HTTPResponse.auto_close = False`` which makes HTTP responses
    +  work well with BufferedReaders and other ``io`` module features. (Pull #1652)
    +
    +* Percent-encode invalid characters in URL for ``HTTPConnectionPool.request()`` (Pull #1673)
    +
    +
    +1.25.3 (2019-05-23)
    +-------------------
    +
    +* Change ``HTTPSConnection`` to load system CA certificates
    +  when ``ca_certs``, ``ca_cert_dir``, and ``ssl_context`` are
    +  unspecified. (Pull #1608, Issue #1603)
    +
    +* Upgrade bundled rfc3986 to v1.3.2. (Pull #1609, Issue #1605)
    +
    +
    +1.25.2 (2019-04-28)
    +-------------------
    +
    +* Change ``is_ipaddress`` to not detect IPvFuture addresses. (Pull #1583)
    +
    +* Change ``parse_url`` to percent-encode invalid characters within the
    +  path, query, and target components. (Pull #1586)
    +
    +
    +1.25.1 (2019-04-24)
    +-------------------
    +
    +* Add support for Google's ``Brotli`` package. (Pull #1572, Pull #1579)
    +
    +* Upgrade bundled rfc3986 to v1.3.1 (Pull #1578)
    +
    +
    +1.25 (2019-04-22)
    +-----------------
    +
    +* Require and validate certificates by default when using HTTPS (Pull #1507)
    +
    +* Upgraded ``urllib3.utils.parse_url()`` to be RFC 3986 compliant. (Pull #1487)
    +
    +* Added support for ``key_password`` for ``HTTPSConnectionPool`` to use
    +  encrypted ``key_file`` without creating your own ``SSLContext`` object. (Pull #1489)
    +
    +* Add TLSv1.3 support to CPython, pyOpenSSL, and SecureTransport ``SSLContext``
    +  implementations. (Pull #1496)
    +
    +* Switched the default multipart header encoder from RFC 2231 to HTML 5 working draft. (Issue #303, Pull #1492)
    +
    +* Fixed issue where OpenSSL would block if an encrypted client private key was
    +  given and no password was given. Instead an ``SSLError`` is raised. (Pull #1489)
    +
    +* Added support for Brotli content encoding. It is enabled automatically if
    +  ``brotlipy`` package is installed which can be requested with
    +  ``urllib3[brotli]`` extra. (Pull #1532)
    +
    +* Drop ciphers using DSS key exchange from default TLS cipher suites.
    +  Improve default ciphers when using SecureTransport. (Pull #1496)
    +
    +* Implemented a more efficient ``HTTPResponse.__iter__()`` method. (Issue #1483)
    +
    +1.24.3 (2019-05-01)
    +-------------------
    +
    +* Apply fix for CVE-2019-9740. (Pull #1591)
    +
    +1.24.2 (2019-04-17)
    +-------------------
    +
    +* Don't load system certificates by default when any other ``ca_certs``, ``ca_certs_dir`` or
    +  ``ssl_context`` parameters are specified.
    +
    +* Remove Authorization header regardless of case when redirecting to cross-site. (Issue #1510)
    +
    +* Add support for IPv6 addresses in subjectAltName section of certificates. (Issue #1269)
    +
    +
    +1.24.1 (2018-11-02)
    +-------------------
    +
    +* Remove quadratic behavior within ``GzipDecoder.decompress()`` (Issue #1467)
    +
    +* Restored functionality of ``ciphers`` parameter for ``create_urllib3_context()``. (Issue #1462)
    +
    +
    +1.24 (2018-10-16)
    +-----------------
    +
    +* Allow key_server_hostname to be specified when initializing a PoolManager to allow custom SNI to be overridden. (Pull #1449)
    +
    +* Test against Python 3.7 on AppVeyor. (Pull #1453)
    +
    +* Early-out ipv6 checks when running on App Engine. (Pull #1450)
    +
    +* Change ambiguous description of backoff_factor (Pull #1436)
    +
    +* Add ability to handle multiple Content-Encodings (Issue #1441 and Pull #1442)
    +
    +* Skip DNS names that can't be idna-decoded when using pyOpenSSL (Issue #1405).
    +
    +* Add a server_hostname parameter to HTTPSConnection which allows for
    +  overriding the SNI hostname sent in the handshake. (Pull #1397)
    +
    +* Drop support for EOL Python 2.6 (Pull #1429 and Pull #1430)
    +
    +* Fixed bug where responses with header Content-Type: message/* erroneously
    +  raised HeaderParsingError, resulting in a warning being logged. (Pull #1439)
    +
    +* Move urllib3 to src/urllib3 (Pull #1409)
    +
    +
    +1.23 (2018-06-04)
    +-----------------
    +
    +* Allow providing a list of headers to strip from requests when redirecting
    +  to a different host. Defaults to the ``Authorization`` header. Different
    +  headers can be set via ``Retry.remove_headers_on_redirect``. (Issue #1316)
    +
    +* Fix ``util.selectors._fileobj_to_fd`` to accept ``long`` (Issue #1247).
    +
    +* Dropped Python 3.3 support. (Pull #1242)
    +
    +* Put the connection back in the pool when calling stream() or read_chunked() on
    +  a chunked HEAD response. (Issue #1234)
    +
    +* Fixed pyOpenSSL-specific ssl client authentication issue when clients
    +  attempted to auth via certificate + chain (Issue #1060)
    +
    +* Add the port to the connectionpool connect print (Pull #1251)
    +
    +* Don't use the ``uuid`` module to create multipart data boundaries. (Pull #1380)
    +
    +* ``read_chunked()`` on a closed response returns no chunks. (Issue #1088)
    +
    +* Add Python 2.6 support to ``contrib.securetransport`` (Pull #1359)
    +
    +* Added support for auth info in url for SOCKS proxy (Pull #1363)
    +
    +
    +1.22 (2017-07-20)
    +-----------------
    +
    +* Fixed missing brackets in ``HTTP CONNECT`` when connecting to IPv6 address via
    +  IPv6 proxy. (Issue #1222)
    +
    +* Made the connection pool retry on ``SSLError``.  The original ``SSLError``
    +  is available on ``MaxRetryError.reason``. (Issue #1112)
    +
    +* Drain and release connection before recursing on retry/redirect.  Fixes
    +  deadlocks with a blocking connectionpool. (Issue #1167)
    +
    +* Fixed compatibility for cookiejar. (Issue #1229)
    +
    +* pyopenssl: Use vendored version of ``six``. (Issue #1231)
    +
    +
    +1.21.1 (2017-05-02)
    +-------------------
    +
    +* Fixed SecureTransport issue that would cause long delays in response body
    +  delivery. (Pull #1154)
    +
    +* Fixed regression in 1.21 that threw exceptions when users passed the
    +  ``socket_options`` flag to the ``PoolManager``.  (Issue #1165)
    +
    +* Fixed regression in 1.21 that threw exceptions when users passed the
    +  ``assert_hostname`` or ``assert_fingerprint`` flag to the ``PoolManager``.
    +  (Pull #1157)
    +
    +
    +1.21 (2017-04-25)
    +-----------------
    +
    +* Improved performance of certain selector system calls on Python 3.5 and
    +  later. (Pull #1095)
    +
    +* Resolved issue where the PyOpenSSL backend would not wrap SysCallError
    +  exceptions appropriately when sending data. (Pull #1125)
    +
    +* Selectors now detects a monkey-patched select module after import for modules
    +  that patch the select module like eventlet, greenlet. (Pull #1128)
    +
    +* Reduced memory consumption when streaming zlib-compressed responses
    +  (as opposed to raw deflate streams). (Pull #1129)
    +
    +* Connection pools now use the entire request context when constructing the
    +  pool key. (Pull #1016)
    +
    +* ``PoolManager.connection_from_*`` methods now accept a new keyword argument,
    +  ``pool_kwargs``, which are merged with the existing ``connection_pool_kw``.
    +  (Pull #1016)
    +
    +* Add retry counter for ``status_forcelist``. (Issue #1147)
    +
    +* Added ``contrib`` module for using SecureTransport on macOS:
    +  ``urllib3.contrib.securetransport``.  (Pull #1122)
    +
    +* urllib3 now only normalizes the case of ``http://`` and ``https://`` schemes:
    +  for schemes it does not recognise, it assumes they are case-sensitive and
    +  leaves them unchanged.
    +  (Issue #1080)
    +
    +
    +1.20 (2017-01-19)
    +-----------------
    +
    +* Added support for waiting for I/O using selectors other than select,
    +  improving urllib3's behaviour with large numbers of concurrent connections.
    +  (Pull #1001)
    +
    +* Updated the date for the system clock check. (Issue #1005)
    +
    +* ConnectionPools now correctly consider hostnames to be case-insensitive.
    +  (Issue #1032)
    +
    +* Outdated versions of PyOpenSSL now cause the PyOpenSSL contrib module
    +  to fail when it is injected, rather than at first use. (Pull #1063)
    +
    +* Outdated versions of cryptography now cause the PyOpenSSL contrib module
    +  to fail when it is injected, rather than at first use. (Issue #1044)
    +
    +* Automatically attempt to rewind a file-like body object when a request is
    +  retried or redirected. (Pull #1039)
    +
    +* Fix some bugs that occur when modules incautiously patch the queue module.
    +  (Pull #1061)
    +
    +* Prevent retries from occurring on read timeouts for which the request method
    +  was not in the method whitelist. (Issue #1059)
    +
    +* Changed the PyOpenSSL contrib module to lazily load idna to avoid
    +  unnecessarily bloating the memory of programs that don't need it. (Pull
    +  #1076)
    +
    +* Add support for IPv6 literals with zone identifiers. (Pull #1013)
    +
    +* Added support for socks5h:// and socks4a:// schemes when working with SOCKS
    +  proxies, and controlled remote DNS appropriately. (Issue #1035)
    +
    +
    +1.19.1 (2016-11-16)
    +-------------------
    +
    +* Fixed AppEngine import that didn't function on Python 3.5. (Pull #1025)
    +
    +
    +1.19 (2016-11-03)
    +-----------------
    +
    +* urllib3 now respects Retry-After headers on 413, 429, and 503 responses when
    +  using the default retry logic. (Pull #955)
    +
    +* Remove markers from setup.py to assist ancient setuptools versions. (Issue
    +  #986)
    +
    +* Disallow superscripts and other integerish things in URL ports. (Issue #989)
    +
    +* Allow urllib3's HTTPResponse.stream() method to continue to work with
    +  non-httplib underlying FPs. (Pull #990)
    +
    +* Empty filenames in multipart headers are now emitted as such, rather than
    +  being suppressed. (Issue #1015)
    +
    +* Prefer user-supplied Host headers on chunked uploads. (Issue #1009)
    +
    +
    +1.18.1 (2016-10-27)
    +-------------------
    +
    +* CVE-2016-9015. Users who are using urllib3 version 1.17 or 1.18 along with
    +  PyOpenSSL injection and OpenSSL 1.1.0 *must* upgrade to this version. This
    +  release fixes a vulnerability whereby urllib3 in the above configuration
    +  would silently fail to validate TLS certificates due to erroneously setting
    +  invalid flags in OpenSSL's ``SSL_CTX_set_verify`` function. These erroneous
    +  flags do not cause a problem in OpenSSL versions before 1.1.0, which
    +  interprets the presence of any flag as requesting certificate validation.
    +
    +  There is no PR for this patch, as it was prepared for simultaneous disclosure
    +  and release. The master branch received the same fix in Pull #1010.
    +
    +
    +1.18 (2016-09-26)
    +-----------------
    +
    +* Fixed incorrect message for IncompleteRead exception. (Pull #973)
    +
    +* Accept ``iPAddress`` subject alternative name fields in TLS certificates.
    +  (Issue #258)
    +
    +* Fixed consistency of ``HTTPResponse.closed`` between Python 2 and 3.
    +  (Issue #977)
    +
    +* Fixed handling of wildcard certificates when using PyOpenSSL. (Issue #979)
    +
    +
    +1.17 (2016-09-06)
    +-----------------
    +
    +* Accept ``SSLContext`` objects for use in SSL/TLS negotiation. (Issue #835)
    +
    +* ConnectionPool debug log now includes scheme, host, and port. (Issue #897)
    +
    +* Substantially refactored documentation. (Issue #887)
    +
    +* Used URLFetch default timeout on AppEngine, rather than hardcoding our own.
    +  (Issue #858)
    +
    +* Normalize the scheme and host in the URL parser (Issue #833)
    +
    +* ``HTTPResponse`` contains the last ``Retry`` object, which now also
    +  contains retries history. (Issue #848)
    +
    +* Timeout can no longer be set as boolean, and must be greater than zero.
    +  (Pull #924)
    +
    +* Removed pyasn1 and ndg-httpsclient from dependencies used for PyOpenSSL. We
    +  now use cryptography and idna, both of which are already dependencies of
    +  PyOpenSSL. (Pull #930)
    +
    +* Fixed infinite loop in ``stream`` when amt=None. (Issue #928)
    +
    +* Try to use the operating system's certificates when we are using an
    +  ``SSLContext``. (Pull #941)
    +
    +* Updated cipher suite list to allow ChaCha20+Poly1305. AES-GCM is preferred to
    +  ChaCha20, but ChaCha20 is then preferred to everything else. (Pull #947)
    +
    +* Updated cipher suite list to remove 3DES-based cipher suites. (Pull #958)
    +
    +* Removed the cipher suite fallback to allow HIGH ciphers. (Pull #958)
    +
    +* Implemented ``length_remaining`` to determine remaining content
    +  to be read. (Pull #949)
    +
    +* Implemented ``enforce_content_length`` to enable exceptions when
    +  incomplete data chunks are received. (Pull #949)
    +
    +* Dropped connection start, dropped connection reset, redirect, forced retry,
    +  and new HTTPS connection log levels to DEBUG, from INFO. (Pull #967)
    +
    +
    +1.16 (2016-06-11)
    +-----------------
    +
    +* Disable IPv6 DNS when IPv6 connections are not possible. (Issue #840)
    +
    +* Provide ``key_fn_by_scheme`` pool keying mechanism that can be
    +  overridden. (Issue #830)
    +
    +* Normalize scheme and host to lowercase for pool keys, and include
    +  ``source_address``. (Issue #830)
    +
    +* Cleaner exception chain in Python 3 for ``_make_request``.
    +  (Issue #861)
    +
    +* Fixed installing ``urllib3[socks]`` extra. (Issue #864)
    +
    +* Fixed signature of ``ConnectionPool.close`` so it can actually safely be
    +  called by subclasses. (Issue #873)
    +
    +* Retain ``release_conn`` state across retries. (Issues #651, #866)
    +
    +* Add customizable ``HTTPConnectionPool.ResponseCls``, which defaults to
    +  ``HTTPResponse`` but can be replaced with a subclass. (Issue #879)
    +
    +
    +1.15.1 (2016-04-11)
    +-------------------
    +
    +* Fix packaging to include backports module. (Issue #841)
    +
    +
    +1.15 (2016-04-06)
    +-----------------
    +
    +* Added Retry(raise_on_status=False). (Issue #720)
    +
    +* Always use setuptools, no more distutils fallback. (Issue #785)
    +
    +* Dropped support for Python 3.2. (Issue #786)
    +
    +* Chunked transfer encoding when requesting with ``chunked=True``.
    +  (Issue #790)
    +
    +* Fixed regression with IPv6 port parsing. (Issue #801)
    +
    +* Append SNIMissingWarning messages to allow users to specify it in
    +  the PYTHONWARNINGS environment variable. (Issue #816)
    +
    +* Handle unicode headers in Py2. (Issue #818)
    +
    +* Log certificate when there is a hostname mismatch. (Issue #820)
    +
    +* Preserve order of request/response headers. (Issue #821)
    +
    +
    +1.14 (2015-12-29)
    +-----------------
    +
    +* contrib: SOCKS proxy support! (Issue #762)
    +
    +* Fixed AppEngine handling of transfer-encoding header and bug
    +  in Timeout defaults checking. (Issue #763)
    +
    +
    +1.13.1 (2015-12-18)
    +-------------------
    +
    +* Fixed regression in IPv6 + SSL for match_hostname. (Issue #761)
    +
    +
    +1.13 (2015-12-14)
    +-----------------
    +
    +* Fixed ``pip install urllib3[secure]`` on modern pip. (Issue #706)
    +
    +* pyopenssl: Fixed SSL3_WRITE_PENDING error. (Issue #717)
    +
    +* pyopenssl: Support for TLSv1.1 and TLSv1.2. (Issue #696)
    +
    +* Close connections more defensively on exception. (Issue #734)
    +
    +* Adjusted ``read_chunked`` to handle gzipped, chunk-encoded bodies without
    +  repeatedly flushing the decoder, to function better on Jython. (Issue #743)
    +
    +* Accept ``ca_cert_dir`` for SSL-related PoolManager configuration. (Issue #758)
    +
    +
    +1.12 (2015-09-03)
    +-----------------
    +
    +* Rely on ``six`` for importing ``httplib`` to work around
    +  conflicts with other Python 3 shims. (Issue #688)
    +
    +* Add support for directories of certificate authorities, as supported by
    +  OpenSSL. (Issue #701)
    +
    +* New exception: ``NewConnectionError``, raised when we fail to establish
    +  a new connection, usually ``ECONNREFUSED`` socket error.
    +
    +
    +1.11 (2015-07-21)
    +-----------------
    +
    +* When ``ca_certs`` is given, ``cert_reqs`` defaults to
    +  ``'CERT_REQUIRED'``. (Issue #650)
    +
    +* ``pip install urllib3[secure]`` will install Certifi and
    +  PyOpenSSL as dependencies. (Issue #678)
    +
    +* Made ``HTTPHeaderDict`` usable as a ``headers`` input value
    +  (Issues #632, #679)
    +
    +* Added `urllib3.contrib.appengine <https://urllib3.readthedocs.io/en/latest/contrib.html#google-app-engine>`_
    +  which has an ``AppEngineManager`` for using ``URLFetch`` in a
    +  Google AppEngine environment. (Issue #664)
    +
    +* Dev: Added test suite for AppEngine. (Issue #631)
    +
    +* Fix performance regression when using PyOpenSSL. (Issue #626)
    +
    +* Passing incorrect scheme (e.g. ``foo://``) will raise
    +  ``ValueError`` instead of ``AssertionError`` (backwards
    +  compatible for now, but please migrate). (Issue #640)
    +
    +* Fix pools not getting replenished when an error occurs during a
    +  request using ``release_conn=False``. (Issue #644)
    +
    +* Fix pool-default headers not applying for url-encoded requests
    +  like GET. (Issue #657)
    +
    +* log.warning in Python 3 when headers are skipped due to parsing
    +  errors. (Issue #642)
    +
    +* Close and discard connections if an error occurs during read.
    +  (Issue #660)
    +
    +* Fix host parsing for IPv6 proxies. (Issue #668)
    +
    +* Separate warning type SubjectAltNameWarning, now issued once
    +  per host. (Issue #671)
    +
    +* Fix ``httplib.IncompleteRead`` not getting converted to
    +  ``ProtocolError`` when using ``HTTPResponse.stream()``
    +  (Issue #674)
    +
    +1.10.4 (2015-05-03)
    +-------------------
    +
    +* Migrate tests to Tornado 4. (Issue #594)
    +
    +* Append default warning configuration rather than overwrite.
    +  (Issue #603)
    +
    +* Fix streaming decoding regression. (Issue #595)
    +
    +* Fix chunked requests losing state across keep-alive connections.
    +  (Issue #599)
    +
    +* Fix hanging when chunked HEAD response has no body. (Issue #605)
    +
    +
    +1.10.3 (2015-04-21)
    +-------------------
    +
    +* Emit ``InsecurePlatformWarning`` when SSLContext object is missing.
    +  (Issue #558)
    +
    +* Fix regression of duplicate header keys being discarded.
    +  (Issue #563)
    +
    +* ``Response.stream()`` returns a generator for chunked responses.
    +  (Issue #560)
    +
    +* Set upper-bound timeout when waiting for a socket in PyOpenSSL.
    +  (Issue #585)
    +
    +* Work on platforms without `ssl` module for plain HTTP requests.
    +  (Issue #587)
    +
    +* Stop relying on the stdlib's default cipher list. (Issue #588)
    +
    +
    +1.10.2 (2015-02-25)
    +-------------------
    +
    +* Fix file descriptor leakage on retries. (Issue #548)
    +
    +* Removed RC4 from default cipher list. (Issue #551)
    +
    +* Header performance improvements. (Issue #544)
    +
    +* Fix PoolManager not obeying redirect retry settings. (Issue #553)
    +
    +
    +1.10.1 (2015-02-10)
    +-------------------
    +
    +* Pools can be used as context managers. (Issue #545)
    +
    +* Don't re-use connections which experienced an SSLError. (Issue #529)
    +
    +* Don't fail when gzip decoding an empty stream. (Issue #535)
    +
    +* Add sha256 support for fingerprint verification. (Issue #540)
    +
    +* Fixed handling of header values containing commas. (Issue #533)
    +
    +
    +1.10 (2014-12-14)
    +-----------------
    +
    +* Disabled SSLv3. (Issue #473)
    +
    +* Add ``Url.url`` property to return the composed url string. (Issue #394)
    +
    +* Fixed PyOpenSSL + gevent ``WantWriteError``. (Issue #412)
    +
    +* ``MaxRetryError.reason`` will always be an exception, not string.
    +  (Issue #481)
    +
    +* Fixed SSL-related timeouts not being detected as timeouts. (Issue #492)
    +
    +* Py3: Use ``ssl.create_default_context()`` when available. (Issue #473)
    +
    +* Emit ``InsecureRequestWarning`` for *every* insecure HTTPS request.
    +  (Issue #496)
    +
    +* Emit ``SecurityWarning`` when certificate has no ``subjectAltName``.
    +  (Issue #499)
    +
    +* Close and discard sockets which experienced SSL-related errors.
    +  (Issue #501)
    +
    +* Handle ``body`` param in ``.request(...)``. (Issue #513)
    +
    +* Respect timeout with HTTPS proxy. (Issue #505)
    +
    +* PyOpenSSL: Handle ZeroReturnError exception. (Issue #520)
    +
    +
    +1.9.1 (2014-09-13)
    +------------------
    +
    +* Apply socket arguments before binding. (Issue #427)
    +
    +* More careful checks if fp-like object is closed. (Issue #435)
    +
    +* Fixed packaging issues of some development-related files not
    +  getting included. (Issue #440)
    +
    +* Allow performing *only* fingerprint verification. (Issue #444)
    +
    +* Emit ``SecurityWarning`` if system clock is waaay off. (Issue #445)
    +
    +* Fixed PyOpenSSL compatibility with PyPy. (Issue #450)
    +
    +* Fixed ``BrokenPipeError`` and ``ConnectionError`` handling in Py3.
    +  (Issue #443)
    +
    +
    +
    +1.9 (2014-07-04)
    +----------------
    +
    +* Shuffled around development-related files. If you're maintaining a distro
    +  package of urllib3, you may need to tweak things. (Issue #415)
    +
    +* Unverified HTTPS requests will trigger a warning on the first request. See
    +  our new `security documentation
    +  <https://urllib3.readthedocs.io/en/latest/security.html>`_ for details.
    +  (Issue #426)
    +
    +* New retry logic and ``urllib3.util.retry.Retry`` configuration object.
    +  (Issue #326)
    +
    +* All raised exceptions should now wrapped in a
    +  ``urllib3.exceptions.HTTPException``-extending exception. (Issue #326)
    +
    +* All errors during a retry-enabled request should be wrapped in
    +  ``urllib3.exceptions.MaxRetryError``, including timeout-related exceptions
    +  which were previously exempt. Underlying error is accessible from the
    +  ``.reason`` property. (Issue #326)
    +
    +* ``urllib3.exceptions.ConnectionError`` renamed to
    +  ``urllib3.exceptions.ProtocolError``. (Issue #326)
    +
    +* Errors during response read (such as IncompleteRead) are now wrapped in
    +  ``urllib3.exceptions.ProtocolError``. (Issue #418)
    +
    +* Requesting an empty host will raise ``urllib3.exceptions.LocationValueError``.
    +  (Issue #417)
    +
    +* Catch read timeouts over SSL connections as
    +  ``urllib3.exceptions.ReadTimeoutError``. (Issue #419)
    +
    +* Apply socket arguments before connecting. (Issue #427)
    +
    +
    +1.8.3 (2014-06-23)
    +------------------
    +
    +* Fix TLS verification when using a proxy in Python 3.4.1. (Issue #385)
    +
    +* Add ``disable_cache`` option to ``urllib3.util.make_headers``. (Issue #393)
    +
    +* Wrap ``socket.timeout`` exception with
    +  ``urllib3.exceptions.ReadTimeoutError``. (Issue #399)
    +
    +* Fixed proxy-related bug where connections were being reused incorrectly.
    +  (Issues #366, #369)
    +
    +* Added ``socket_options`` keyword parameter which allows to define
    +  ``setsockopt`` configuration of new sockets. (Issue #397)
    +
    +* Removed ``HTTPConnection.tcp_nodelay`` in favor of
    +  ``HTTPConnection.default_socket_options``. (Issue #397)
    +
    +* Fixed ``TypeError`` bug in Python 2.6.4. (Issue #411)
    +
    +
    +1.8.2 (2014-04-17)
    +------------------
    +
    +* Fix ``urllib3.util`` not being included in the package.
    +
    +
    +1.8.1 (2014-04-17)
    +------------------
    +
    +* Fix AppEngine bug of HTTPS requests going out as HTTP. (Issue #356)
    +
    +* Don't install ``dummyserver`` into ``site-packages`` as it's only needed
    +  for the test suite. (Issue #362)
    +
    +* Added support for specifying ``source_address``. (Issue #352)
    +
    +
    +1.8 (2014-03-04)
    +----------------
    +
    +* Improved url parsing in ``urllib3.util.parse_url`` (properly parse '@' in
    +  username, and blank ports like 'hostname:').
    +
    +* New ``urllib3.connection`` module which contains all the HTTPConnection
    +  objects.
    +
    +* Several ``urllib3.util.Timeout``-related fixes. Also changed constructor
    +  signature to a more sensible order. [Backwards incompatible]
    +  (Issues #252, #262, #263)
    +
    +* Use ``backports.ssl_match_hostname`` if it's installed. (Issue #274)
    +
    +* Added ``.tell()`` method to ``urllib3.response.HTTPResponse`` which
    +  returns the number of bytes read so far. (Issue #277)
    +
    +* Support for platforms without threading. (Issue #289)
    +
    +* Expand default-port comparison in ``HTTPConnectionPool.is_same_host``
    +  to allow a pool with no specified port to be considered equal to to an
    +  HTTP/HTTPS url with port 80/443 explicitly provided. (Issue #305)
    +
    +* Improved default SSL/TLS settings to avoid vulnerabilities.
    +  (Issue #309)
    +
    +* Fixed ``urllib3.poolmanager.ProxyManager`` not retrying on connect errors.
    +  (Issue #310)
    +
    +* Disable Nagle's Algorithm on the socket for non-proxies. A subset of requests
    +  will send the entire HTTP request ~200 milliseconds faster; however, some of
    +  the resulting TCP packets will be smaller. (Issue #254)
    +
    +* Increased maximum number of SubjectAltNames in ``urllib3.contrib.pyopenssl``
    +  from the default 64 to 1024 in a single certificate. (Issue #318)
    +
    +* Headers are now passed and stored as a custom
    +  ``urllib3.collections_.HTTPHeaderDict`` object rather than a plain ``dict``.
    +  (Issue #329, #333)
    +
    +* Headers no longer lose their case on Python 3. (Issue #236)
    +
    +* ``urllib3.contrib.pyopenssl`` now uses the operating system's default CA
    +  certificates on inject. (Issue #332)
    +
    +* Requests with ``retries=False`` will immediately raise any exceptions without
    +  wrapping them in ``MaxRetryError``. (Issue #348)
    +
    +* Fixed open socket leak with SSL-related failures. (Issue #344, #348)
    +
    +
    +1.7.1 (2013-09-25)
    +------------------
    +
    +* Added granular timeout support with new ``urllib3.util.Timeout`` class.
    +  (Issue #231)
    +
    +* Fixed Python 3.4 support. (Issue #238)
    +
    +
    +1.7 (2013-08-14)
    +----------------
    +
    +* More exceptions are now pickle-able, with tests. (Issue #174)
    +
    +* Fixed redirecting with relative URLs in Location header. (Issue #178)
    +
    +* Support for relative urls in ``Location: ...`` header. (Issue #179)
    +
    +* ``urllib3.response.HTTPResponse`` now inherits from ``io.IOBase`` for bonus
    +  file-like functionality. (Issue #187)
    +
    +* Passing ``assert_hostname=False`` when creating a HTTPSConnectionPool will
    +  skip hostname verification for SSL connections. (Issue #194)
    +
    +* New method ``urllib3.response.HTTPResponse.stream(...)`` which acts as a
    +  generator wrapped around ``.read(...)``. (Issue #198)
    +
    +* IPv6 url parsing enforces brackets around the hostname. (Issue #199)
    +
    +* Fixed thread race condition in
    +  ``urllib3.poolmanager.PoolManager.connection_from_host(...)`` (Issue #204)
    +
    +* ``ProxyManager`` requests now include non-default port in ``Host: ...``
    +  header. (Issue #217)
    +
    +* Added HTTPS proxy support in ``ProxyManager``. (Issue #170 #139)
    +
    +* New ``RequestField`` object can be passed to the ``fields=...`` param which
    +  can specify headers. (Issue #220)
    +
    +* Raise ``urllib3.exceptions.ProxyError`` when connecting to proxy fails.
    +  (Issue #221)
    +
    +* Use international headers when posting file names. (Issue #119)
    +
    +* Improved IPv6 support. (Issue #203)
    +
    +
    +1.6 (2013-04-25)
    +----------------
    +
    +* Contrib: Optional SNI support for Py2 using PyOpenSSL. (Issue #156)
    +
    +* ``ProxyManager`` automatically adds ``Host: ...`` header if not given.
    +
    +* Improved SSL-related code. ``cert_req`` now optionally takes a string like
    +  "REQUIRED" or "NONE". Same with ``ssl_version`` takes strings like "SSLv23"
    +  The string values reflect the suffix of the respective constant variable.
    +  (Issue #130)
    +
    +* Vendored ``socksipy`` now based on Anorov's fork which handles unexpectedly
    +  closed proxy connections and larger read buffers. (Issue #135)
    +
    +* Ensure the connection is closed if no data is received, fixes connection leak
    +  on some platforms. (Issue #133)
    +
    +* Added SNI support for SSL/TLS connections on Py32+. (Issue #89)
    +
    +* Tests fixed to be compatible with Py26 again. (Issue #125)
    +
    +* Added ability to choose SSL version by passing an ``ssl.PROTOCOL_*`` constant
    +  to the ``ssl_version`` parameter of ``HTTPSConnectionPool``. (Issue #109)
    +
    +* Allow an explicit content type to be specified when encoding file fields.
    +  (Issue #126)
    +
    +* Exceptions are now pickleable, with tests. (Issue #101)
    +
    +* Fixed default headers not getting passed in some cases. (Issue #99)
    +
    +* Treat "content-encoding" header value as case-insensitive, per RFC 2616
    +  Section 3.5. (Issue #110)
    +
    +* "Connection Refused" SocketErrors will get retried rather than raised.
    +  (Issue #92)
    +
    +* Updated vendored ``six``, no longer overrides the global ``six`` module
    +  namespace. (Issue #113)
    +
    +* ``urllib3.exceptions.MaxRetryError`` contains a ``reason`` property holding
    +  the exception that prompted the final retry. If ``reason is None`` then it
    +  was due to a redirect. (Issue #92, #114)
    +
    +* Fixed ``PoolManager.urlopen()`` from not redirecting more than once.
    +  (Issue #149)
    +
    +* Don't assume ``Content-Type: text/plain`` for multi-part encoding parameters
    +  that are not files. (Issue #111)
    +
    +* Pass `strict` param down to ``httplib.HTTPConnection``. (Issue #122)
    +
    +* Added mechanism to verify SSL certificates by fingerprint (md5, sha1) or
    +  against an arbitrary hostname (when connecting by IP or for misconfigured
    +  servers). (Issue #140)
    +
    +* Streaming decompression support. (Issue #159)
    +
    +
    +1.5 (2012-08-02)
    +----------------
    +
    +* Added ``urllib3.add_stderr_logger()`` for quickly enabling STDERR debug
    +  logging in urllib3.
    +
    +* Native full URL parsing (including auth, path, query, fragment) available in
    +  ``urllib3.util.parse_url(url)``.
    +
    +* Built-in redirect will switch method to 'GET' if status code is 303.
    +  (Issue #11)
    +
    +* ``urllib3.PoolManager`` strips the scheme and host before sending the request
    +  uri. (Issue #8)
    +
    +* New ``urllib3.exceptions.DecodeError`` exception for when automatic decoding,
    +  based on the Content-Type header, fails.
    +
    +* Fixed bug with pool depletion and leaking connections (Issue #76). Added
    +  explicit connection closing on pool eviction. Added
    +  ``urllib3.PoolManager.clear()``.
    +
    +* 99% -> 100% unit test coverage.
    +
    +
    +1.4 (2012-06-16)
    +----------------
    +
    +* Minor AppEngine-related fixes.
    +
    +* Switched from ``mimetools.choose_boundary`` to ``uuid.uuid4()``.
    +
    +* Improved url parsing. (Issue #73)
    +
    +* IPv6 url support. (Issue #72)
    +
    +
    +1.3 (2012-03-25)
    +----------------
    +
    +* Removed pre-1.0 deprecated API.
    +
    +* Refactored helpers into a ``urllib3.util`` submodule.
    +
    +* Fixed multipart encoding to support list-of-tuples for keys with multiple
    +  values. (Issue #48)
    +
    +* Fixed multiple Set-Cookie headers in response not getting merged properly in
    +  Python 3. (Issue #53)
    +
    +* AppEngine support with Py27. (Issue #61)
    +
    +* Minor ``encode_multipart_formdata`` fixes related to Python 3 strings vs
    +  bytes.
    +
    +
    +1.2.2 (2012-02-06)
    +------------------
    +
    +* Fixed packaging bug of not shipping ``test-requirements.txt``. (Issue #47)
    +
    +
    +1.2.1 (2012-02-05)
    +------------------
    +
    +* Fixed another bug related to when ``ssl`` module is not available. (Issue #41)
    +
    +* Location parsing errors now raise ``urllib3.exceptions.LocationParseError``
    +  which inherits from ``ValueError``.
    +
    +
    +1.2 (2012-01-29)
    +----------------
    +
    +* Added Python 3 support (tested on 3.2.2)
    +
    +* Dropped Python 2.5 support (tested on 2.6.7, 2.7.2)
    +
    +* Use ``select.poll`` instead of ``select.select`` for platforms that support
    +  it.
    +
    +* Use ``Queue.LifoQueue`` instead of ``Queue.Queue`` for more aggressive
    +  connection reusing. Configurable by overriding ``ConnectionPool.QueueCls``.
    +
    +* Fixed ``ImportError`` during install when ``ssl`` module is not available.
    +  (Issue #41)
    +
    +* Fixed ``PoolManager`` redirects between schemes (such as HTTP -> HTTPS) not
    +  completing properly. (Issue #28, uncovered by Issue #10 in v1.1)
    +
    +* Ported ``dummyserver`` to use ``tornado`` instead of ``webob`` +
    +  ``eventlet``. Removed extraneous unsupported dummyserver testing backends.
    +  Added socket-level tests.
    +
    +* More tests. Achievement Unlocked: 99% Coverage.
    +
    +
    +1.1 (2012-01-07)
    +----------------
    +
    +* Refactored ``dummyserver`` to its own root namespace module (used for
    +  testing).
    +
    +* Added hostname verification for ``VerifiedHTTPSConnection`` by vendoring in
    +  Py32's ``ssl_match_hostname``. (Issue #25)
    +
    +* Fixed cross-host HTTP redirects when using ``PoolManager``. (Issue #10)
    +
    +* Fixed ``decode_content`` being ignored when set through ``urlopen``. (Issue
    +  #27)
    +
    +* Fixed timeout-related bugs. (Issues #17, #23)
    +
    +
    +1.0.2 (2011-11-04)
    +------------------
    +
    +* Fixed typo in ``VerifiedHTTPSConnection`` which would only present as a bug if
    +  you're using the object manually. (Thanks pyos)
    +
    +* Made RecentlyUsedContainer (and consequently PoolManager) more thread-safe by
    +  wrapping the access log in a mutex. (Thanks @christer)
    +
    +* Made RecentlyUsedContainer more dict-like (corrected ``__delitem__`` and
    +  ``__getitem__`` behaviour), with tests. Shouldn't affect core urllib3 code.
    +
    +
    +1.0.1 (2011-10-10)
    +------------------
    +
    +* Fixed a bug where the same connection would get returned into the pool twice,
    +  causing extraneous "HttpConnectionPool is full" log warnings.
    +
    +
    +1.0 (2011-10-08)
    +----------------
    +
    +* Added ``PoolManager`` with LRU expiration of connections (tested and
    +  documented).
    +* Added ``ProxyManager`` (needs tests, docs, and confirmation that it works
    +  with HTTPS proxies).
    +* Added optional partial-read support for responses when
    +  ``preload_content=False``. You can now make requests and just read the headers
    +  without loading the content.
    +* Made response decoding optional (default on, same as before).
    +* Added optional explicit boundary string for ``encode_multipart_formdata``.
    +* Convenience request methods are now inherited from ``RequestMethods``. Old
    +  helpers like ``get_url`` and ``post_url`` should be abandoned in favour of
    +  the new ``request(method, url, ...)``.
    +* Refactored code to be even more decoupled, reusable, and extendable.
    +* License header added to ``.py`` files.
    +* Embiggened the documentation: Lots of Sphinx-friendly docstrings in the code
    +  and docs in ``docs/`` and on https://urllib3.readthedocs.io/.
    +* Embettered all the things!
    +* Started writing this file.
    +
    +
    +0.4.1 (2011-07-17)
    +------------------
    +
    +* Minor bug fixes, code cleanup.
    +
    +
    +0.4 (2011-03-01)
    +----------------
    +
    +* Better unicode support.
    +* Added ``VerifiedHTTPSConnection``.
    +* Added ``NTLMConnectionPool`` in contrib.
    +* Minor improvements.
    +
    +
    +0.3.1 (2010-07-13)
    +------------------
    +
    +* Added ``assert_host_name`` optional parameter. Now compatible with proxies.
    +
    +
    +0.3 (2009-12-10)
    +----------------
    +
    +* Added HTTPS support.
    +* Minor bug fixes.
    +* Refactored, broken backwards compatibility with 0.2.
    +* API to be treated as stable from this version forward.
    +
    +
    +0.2 (2008-11-17)
    +----------------
    +
    +* Added unit tests.
    +* Bug fixes.
    +
    +
    +0.1 (2008-11-16)
    +----------------
    +
    +* First release.
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3-1.26.14.dist-info/RECORD b/deployment-apps/metricator-for-nmon/lib/urllib3-1.26.14.dist-info/RECORD
    new file mode 100644
    index 0000000..547b0a4
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3-1.26.14.dist-info/RECORD
    @@ -0,0 +1,44 @@
    +urllib3-1.26.14.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
    +urllib3-1.26.14.dist-info/LICENSE.txt,sha256=w3vxhuJ8-dvpYZ5V7f486nswCRzrPaY8fay-Dm13kHs,1115
    +urllib3-1.26.14.dist-info/METADATA,sha256=Xzpp771-k5KmKbJ2izOutnYr7o8QrC37ap90Xnbt1og,47722
    +urllib3-1.26.14.dist-info/RECORD,,
    +urllib3-1.26.14.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
    +urllib3-1.26.14.dist-info/top_level.txt,sha256=EMiXL2sKrTcmrMxIHTqdc3ET54pQI2Y072LexFEemvo,8
    +urllib3/__init__.py,sha256=iXLcYiJySn0GNbWOOZDDApgBL1JgP44EZ8i1760S8Mc,3333
    +urllib3/_collections.py,sha256=Rp1mVyBgc_UlAcp6M3at1skJBXR5J43NawRTvW2g_XY,10811
    +urllib3/_version.py,sha256=JWE--BUVy7--9FsXILONIpQ43irftKGjT9j2H_fdF2M,64
    +urllib3/connection.py,sha256=8976wL6sGeVMW0JnXvx5mD00yXu87uQjxtB9_VL8dx8,20070
    +urllib3/connectionpool.py,sha256=vS4UaHLoR9_5aGLXSQ776y_jTxgqqjx0YsjkYksWGOo,39095
    +urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
    +urllib3/contrib/_appengine_environ.py,sha256=bDbyOEhW2CKLJcQqAKAyrEHN-aklsyHFKq6vF8ZFsmk,957
    +urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
    +urllib3/contrib/_securetransport/bindings.py,sha256=4Xk64qIkPBt09A5q-RIFUuDhNc9mXilVapm7WnYnzRw,17632
    +urllib3/contrib/_securetransport/low_level.py,sha256=B2JBB2_NRP02xK6DCa1Pa9IuxrPwxzDzZbixQkb7U9M,13922
    +urllib3/contrib/appengine.py,sha256=6IBW6lPOoVUxASPwtn6IH1AATe5DK3lLJCfwyWlLKAE,11012
    +urllib3/contrib/ntlmpool.py,sha256=NlfkW7WMdW8ziqudopjHoW299og1BTWi0IeIibquFwk,4528
    +urllib3/contrib/pyopenssl.py,sha256=4AJAlo9NmjWofY4dJwRa4kbZuRuHfNJxu8Pv6yQk1ss,17055
    +urllib3/contrib/securetransport.py,sha256=QOhVbWrFQTKbmV-vtyG69amekkKVxXkdjk9oymaO0Ag,34416
    +urllib3/contrib/socks.py,sha256=aRi9eWXo9ZEb95XUxef4Z21CFlnnjbEiAo9HOseoMt4,7097
    +urllib3/exceptions.py,sha256=0Mnno3KHTNfXRfY7638NufOPkUb6mXOm-Lqj-4x2w8A,8217
    +urllib3/fields.py,sha256=kvLDCg_JmH1lLjUUEY_FLS8UhY7hBvDPuVETbY8mdrM,8579
    +urllib3/filepost.py,sha256=5b_qqgRHVlL7uLtdAYBzBh-GHmU5AfJVt_2N0XS3PeY,2440
    +urllib3/packages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
    +urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
    +urllib3/packages/backports/makefile.py,sha256=nbzt3i0agPVP07jqqgjhaYjMmuAi_W5E0EywZivVO8E,1417
    +urllib3/packages/six.py,sha256=b9LM0wBXv7E7SrbCjAm4wwN-hrH-iNxv18LgWNMMKPo,34665
    +urllib3/poolmanager.py,sha256=0KOOJECoeLYVjUHvv-0h4Oq3FFQQ2yb-Fnjkbj8gJO0,19786
    +urllib3/request.py,sha256=ZFSIqX0C6WizixecChZ3_okyu7BEv0lZu1VT0s6h4SM,5985
    +urllib3/response.py,sha256=UPgLmnHj4z71ZnH8ivYOyncATifTOw9FQukUqDnckCc,30761
    +urllib3/util/__init__.py,sha256=JEmSmmqqLyaw8P51gUImZh8Gwg9i1zSe-DoqAitn2nc,1155
    +urllib3/util/connection.py,sha256=5Lx2B1PW29KxBn2T0xkN1CBgRBa3gGVJBKoQoRogEVk,4901
    +urllib3/util/proxy.py,sha256=zUvPPCJrp6dOF0N4GAVbOcl6o-4uXKSrGiTkkr5vUS4,1605
    +urllib3/util/queue.py,sha256=nRgX8_eX-_VkvxoX096QWoz8Ps0QHUAExILCY_7PncM,498
    +urllib3/util/request.py,sha256=fWiAaa8pwdLLIqoTLBxCC2e4ed80muzKU3e3HWWTzFQ,4225
    +urllib3/util/response.py,sha256=GJpg3Egi9qaJXRwBh5wv-MNuRWan5BIu40oReoxWP28,3510
    +urllib3/util/retry.py,sha256=4laWh0HpwGijLiBmdBIYtbhYekQnNzzhx2W9uys0RHA,22003
    +urllib3/util/ssl_.py,sha256=c0sYiSC6272r6uPkxQpo5rYPP9QC1eR6oI7004gYqZo,17165
    +urllib3/util/ssl_match_hostname.py,sha256=Ir4cZVEjmAk8gUAIHWSi7wtOO83UCYABY2xFD1Ql_WA,5758
    +urllib3/util/ssltransport.py,sha256=NA-u5rMTrDFDFC8QzRKUEKMG0561hOD4qBTr3Z4pv6E,6895
    +urllib3/util/timeout.py,sha256=QSbBUNOB9yh6AnDn61SrLQ0hg5oz0I9-uXEG91AJuIg,10003
    +urllib3/util/url.py,sha256=znoYE94l8y-SKv2FPS-6V7HVSoULsBMPYK1WE8GKPUE,14281
    +urllib3/util/wait.py,sha256=fOX0_faozG2P7iVojQoE1mbydweNyTcm-hXEfFrTtLI,5403
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3-1.26.14.dist-info/WHEEL b/deployment-apps/metricator-for-nmon/lib/urllib3-1.26.14.dist-info/WHEEL
    new file mode 100644
    index 0000000..9d8f872
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3-1.26.14.dist-info/WHEEL
    @@ -0,0 +1,6 @@
    +Wheel-Version: 1.0
    +Generator: bdist_wheel (0.38.4)
    +Root-Is-Purelib: true
    +Tag: py2-none-any
    +Tag: py3-none-any
    +
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/__init__.py b/deployment-apps/metricator-for-nmon/lib/urllib3/__init__.py
    new file mode 100644
    index 0000000..c6fa382
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/__init__.py
    @@ -0,0 +1,102 @@
    +"""
    +Python HTTP library with thread-safe connection pooling, file post support, user friendly, and more
    +"""
    +from __future__ import absolute_import
    +
    +# Set default logging handler to avoid "No handler found" warnings.
    +import logging
    +import warnings
    +from logging import NullHandler
    +
    +from . import exceptions
    +from ._version import __version__
    +from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, connection_from_url
    +from .filepost import encode_multipart_formdata
    +from .poolmanager import PoolManager, ProxyManager, proxy_from_url
    +from .response import HTTPResponse
    +from .util.request import make_headers
    +from .util.retry import Retry
    +from .util.timeout import Timeout
    +from .util.url import get_host
    +
    +# === NOTE TO REPACKAGERS AND VENDORS ===
    +# Please delete this block, this logic is only
    +# for urllib3 being distributed via PyPI.
    +# See: https://github.com/urllib3/urllib3/issues/2680
    +try:
    +    import urllib3_secure_extra  # type: ignore # noqa: F401
    +except ImportError:
    +    pass
    +else:
    +    warnings.warn(
    +        "'urllib3[secure]' extra is deprecated and will be removed "
    +        "in a future release of urllib3 2.x. Read more in this issue: "
    +        "https://github.com/urllib3/urllib3/issues/2680",
    +        category=DeprecationWarning,
    +        stacklevel=2,
    +    )
    +
    +__author__ = "Andrey Petrov (andrey.petrov@shazow.net)"
    +__license__ = "MIT"
    +__version__ = __version__
    +
    +__all__ = (
    +    "HTTPConnectionPool",
    +    "HTTPSConnectionPool",
    +    "PoolManager",
    +    "ProxyManager",
    +    "HTTPResponse",
    +    "Retry",
    +    "Timeout",
    +    "add_stderr_logger",
    +    "connection_from_url",
    +    "disable_warnings",
    +    "encode_multipart_formdata",
    +    "get_host",
    +    "make_headers",
    +    "proxy_from_url",
    +)
    +
    +logging.getLogger(__name__).addHandler(NullHandler())
    +
    +
    +def add_stderr_logger(level=logging.DEBUG):
    +    """
    +    Helper for quickly adding a StreamHandler to the logger. Useful for
    +    debugging.
    +
    +    Returns the handler after adding it.
    +    """
    +    # This method needs to be in this __init__.py to get the __name__ correct
    +    # even if urllib3 is vendored within another package.
    +    logger = logging.getLogger(__name__)
    +    handler = logging.StreamHandler()
    +    handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
    +    logger.addHandler(handler)
    +    logger.setLevel(level)
    +    logger.debug("Added a stderr logging handler to logger: %s", __name__)
    +    return handler
    +
    +
    +# ... Clean up.
    +del NullHandler
    +
    +
    +# All warning filters *must* be appended unless you're really certain that they
    +# shouldn't be: otherwise, it's very hard for users to use most Python
    +# mechanisms to silence them.
    +# SecurityWarning's always go off by default.
    +warnings.simplefilter("always", exceptions.SecurityWarning, append=True)
    +# SubjectAltNameWarning's should go off once per host
    +warnings.simplefilter("default", exceptions.SubjectAltNameWarning, append=True)
    +# InsecurePlatformWarning's don't vary between requests, so we keep it default.
    +warnings.simplefilter("default", exceptions.InsecurePlatformWarning, append=True)
    +# SNIMissingWarnings should go off only once.
    +warnings.simplefilter("default", exceptions.SNIMissingWarning, append=True)
    +
    +
    +def disable_warnings(category=exceptions.HTTPWarning):
    +    """
    +    Helper for quickly disabling all urllib3 warnings.
    +    """
    +    warnings.simplefilter("ignore", category)
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/_collections.py b/deployment-apps/metricator-for-nmon/lib/urllib3/_collections.py
    new file mode 100644
    index 0000000..da9857e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/_collections.py
    @@ -0,0 +1,337 @@
    +from __future__ import absolute_import
    +
    +try:
    +    from collections.abc import Mapping, MutableMapping
    +except ImportError:
    +    from collections import Mapping, MutableMapping
    +try:
    +    from threading import RLock
    +except ImportError:  # Platform-specific: No threads available
    +
    +    class RLock:
    +        def __enter__(self):
    +            pass
    +
    +        def __exit__(self, exc_type, exc_value, traceback):
    +            pass
    +
    +
    +from collections import OrderedDict
    +
    +from .exceptions import InvalidHeader
    +from .packages import six
    +from .packages.six import iterkeys, itervalues
    +
    +__all__ = ["RecentlyUsedContainer", "HTTPHeaderDict"]
    +
    +
    +_Null = object()
    +
    +
    +class RecentlyUsedContainer(MutableMapping):
    +    """
    +    Provides a thread-safe dict-like container which maintains up to
    +    ``maxsize`` keys while throwing away the least-recently-used keys beyond
    +    ``maxsize``.
    +
    +    :param maxsize:
    +        Maximum number of recent elements to retain.
    +
    +    :param dispose_func:
    +        Every time an item is evicted from the container,
    +        ``dispose_func(value)`` is called.  Callback which will get called
    +    """
    +
    +    ContainerCls = OrderedDict
    +
    +    def __init__(self, maxsize=10, dispose_func=None):
    +        self._maxsize = maxsize
    +        self.dispose_func = dispose_func
    +
    +        self._container = self.ContainerCls()
    +        self.lock = RLock()
    +
    +    def __getitem__(self, key):
    +        # Re-insert the item, moving it to the end of the eviction line.
    +        with self.lock:
    +            item = self._container.pop(key)
    +            self._container[key] = item
    +            return item
    +
    +    def __setitem__(self, key, value):
    +        evicted_value = _Null
    +        with self.lock:
    +            # Possibly evict the existing value of 'key'
    +            evicted_value = self._container.get(key, _Null)
    +            self._container[key] = value
    +
    +            # If we didn't evict an existing value, we might have to evict the
    +            # least recently used item from the beginning of the container.
    +            if len(self._container) > self._maxsize:
    +                _key, evicted_value = self._container.popitem(last=False)
    +
    +        if self.dispose_func and evicted_value is not _Null:
    +            self.dispose_func(evicted_value)
    +
    +    def __delitem__(self, key):
    +        with self.lock:
    +            value = self._container.pop(key)
    +
    +        if self.dispose_func:
    +            self.dispose_func(value)
    +
    +    def __len__(self):
    +        with self.lock:
    +            return len(self._container)
    +
    +    def __iter__(self):
    +        raise NotImplementedError(
    +            "Iteration over this class is unlikely to be threadsafe."
    +        )
    +
    +    def clear(self):
    +        with self.lock:
    +            # Copy pointers to all values, then wipe the mapping
    +            values = list(itervalues(self._container))
    +            self._container.clear()
    +
    +        if self.dispose_func:
    +            for value in values:
    +                self.dispose_func(value)
    +
    +    def keys(self):
    +        with self.lock:
    +            return list(iterkeys(self._container))
    +
    +
    +class HTTPHeaderDict(MutableMapping):
    +    """
    +    :param headers:
    +        An iterable of field-value pairs. Must not contain multiple field names
    +        when compared case-insensitively.
    +
    +    :param kwargs:
    +        Additional field-value pairs to pass in to ``dict.update``.
    +
    +    A ``dict`` like container for storing HTTP Headers.
    +
    +    Field names are stored and compared case-insensitively in compliance with
    +    RFC 7230. Iteration provides the first case-sensitive key seen for each
    +    case-insensitive pair.
    +
    +    Using ``__setitem__`` syntax overwrites fields that compare equal
    +    case-insensitively in order to maintain ``dict``'s api. For fields that
    +    compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add``
    +    in a loop.
    +
    +    If multiple fields that are equal case-insensitively are passed to the
    +    constructor or ``.update``, the behavior is undefined and some will be
    +    lost.
    +
    +    >>> headers = HTTPHeaderDict()
    +    >>> headers.add('Set-Cookie', 'foo=bar')
    +    >>> headers.add('set-cookie', 'baz=quxx')
    +    >>> headers['content-length'] = '7'
    +    >>> headers['SET-cookie']
    +    'foo=bar, baz=quxx'
    +    >>> headers['Content-Length']
    +    '7'
    +    """
    +
    +    def __init__(self, headers=None, **kwargs):
    +        super(HTTPHeaderDict, self).__init__()
    +        self._container = OrderedDict()
    +        if headers is not None:
    +            if isinstance(headers, HTTPHeaderDict):
    +                self._copy_from(headers)
    +            else:
    +                self.extend(headers)
    +        if kwargs:
    +            self.extend(kwargs)
    +
    +    def __setitem__(self, key, val):
    +        self._container[key.lower()] = [key, val]
    +        return self._container[key.lower()]
    +
    +    def __getitem__(self, key):
    +        val = self._container[key.lower()]
    +        return ", ".join(val[1:])
    +
    +    def __delitem__(self, key):
    +        del self._container[key.lower()]
    +
    +    def __contains__(self, key):
    +        return key.lower() in self._container
    +
    +    def __eq__(self, other):
    +        if not isinstance(other, Mapping) and not hasattr(other, "keys"):
    +            return False
    +        if not isinstance(other, type(self)):
    +            other = type(self)(other)
    +        return dict((k.lower(), v) for k, v in self.itermerged()) == dict(
    +            (k.lower(), v) for k, v in other.itermerged()
    +        )
    +
    +    def __ne__(self, other):
    +        return not self.__eq__(other)
    +
    +    if six.PY2:  # Python 2
    +        iterkeys = MutableMapping.iterkeys
    +        itervalues = MutableMapping.itervalues
    +
    +    __marker = object()
    +
    +    def __len__(self):
    +        return len(self._container)
    +
    +    def __iter__(self):
    +        # Only provide the originally cased names
    +        for vals in self._container.values():
    +            yield vals[0]
    +
    +    def pop(self, key, default=__marker):
    +        """D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
    +        If key is not found, d is returned if given, otherwise KeyError is raised.
    +        """
    +        # Using the MutableMapping function directly fails due to the private marker.
    +        # Using ordinary dict.pop would expose the internal structures.
    +        # So let's reinvent the wheel.
    +        try:
    +            value = self[key]
    +        except KeyError:
    +            if default is self.__marker:
    +                raise
    +            return default
    +        else:
    +            del self[key]
    +            return value
    +
    +    def discard(self, key):
    +        try:
    +            del self[key]
    +        except KeyError:
    +            pass
    +
    +    def add(self, key, val):
    +        """Adds a (name, value) pair, doesn't overwrite the value if it already
    +        exists.
    +
    +        >>> headers = HTTPHeaderDict(foo='bar')
    +        >>> headers.add('Foo', 'baz')
    +        >>> headers['foo']
    +        'bar, baz'
    +        """
    +        key_lower = key.lower()
    +        new_vals = [key, val]
    +        # Keep the common case aka no item present as fast as possible
    +        vals = self._container.setdefault(key_lower, new_vals)
    +        if new_vals is not vals:
    +            vals.append(val)
    +
    +    def extend(self, *args, **kwargs):
    +        """Generic import function for any type of header-like object.
    +        Adapted version of MutableMapping.update in order to insert items
    +        with self.add instead of self.__setitem__
    +        """
    +        if len(args) > 1:
    +            raise TypeError(
    +                "extend() takes at most 1 positional "
    +                "arguments ({0} given)".format(len(args))
    +            )
    +        other = args[0] if len(args) >= 1 else ()
    +
    +        if isinstance(other, HTTPHeaderDict):
    +            for key, val in other.iteritems():
    +                self.add(key, val)
    +        elif isinstance(other, Mapping):
    +            for key in other:
    +                self.add(key, other[key])
    +        elif hasattr(other, "keys"):
    +            for key in other.keys():
    +                self.add(key, other[key])
    +        else:
    +            for key, value in other:
    +                self.add(key, value)
    +
    +        for key, value in kwargs.items():
    +            self.add(key, value)
    +
    +    def getlist(self, key, default=__marker):
    +        """Returns a list of all the values for the named field. Returns an
    +        empty list if the key doesn't exist."""
    +        try:
    +            vals = self._container[key.lower()]
    +        except KeyError:
    +            if default is self.__marker:
    +                return []
    +            return default
    +        else:
    +            return vals[1:]
    +
    +    # Backwards compatibility for httplib
    +    getheaders = getlist
    +    getallmatchingheaders = getlist
    +    iget = getlist
    +
    +    # Backwards compatibility for http.cookiejar
    +    get_all = getlist
    +
    +    def __repr__(self):
    +        return "%s(%s)" % (type(self).__name__, dict(self.itermerged()))
    +
    +    def _copy_from(self, other):
    +        for key in other:
    +            val = other.getlist(key)
    +            if isinstance(val, list):
    +                # Don't need to convert tuples
    +                val = list(val)
    +            self._container[key.lower()] = [key] + val
    +
    +    def copy(self):
    +        clone = type(self)()
    +        clone._copy_from(self)
    +        return clone
    +
    +    def iteritems(self):
    +        """Iterate over all header lines, including duplicate ones."""
    +        for key in self:
    +            vals = self._container[key.lower()]
    +            for val in vals[1:]:
    +                yield vals[0], val
    +
    +    def itermerged(self):
    +        """Iterate over all headers, merging duplicate ones together."""
    +        for key in self:
    +            val = self._container[key.lower()]
    +            yield val[0], ", ".join(val[1:])
    +
    +    def items(self):
    +        return list(self.iteritems())
    +
    +    @classmethod
    +    def from_httplib(cls, message):  # Python 2
    +        """Read headers from a Python 2 httplib message object."""
    +        # python2.7 does not expose a proper API for exporting multiheaders
    +        # efficiently. This function re-reads raw lines from the message
    +        # object and extracts the multiheaders properly.
    +        obs_fold_continued_leaders = (" ", "\t")
    +        headers = []
    +
    +        for line in message.headers:
    +            if line.startswith(obs_fold_continued_leaders):
    +                if not headers:
    +                    # We received a header line that starts with OWS as described
    +                    # in RFC-7230 S3.2.4. This indicates a multiline header, but
    +                    # there exists no previous header to which we can attach it.
    +                    raise InvalidHeader(
    +                        "Header continuation with no previous header: %s" % line
    +                    )
    +                else:
    +                    key, value = headers[-1]
    +                    headers[-1] = (key, value + " " + line.strip())
    +                    continue
    +
    +            key, value = line.split(":", 1)
    +            headers.append((key, value.strip()))
    +
    +        return cls(headers)
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/_version.py b/deployment-apps/metricator-for-nmon/lib/urllib3/_version.py
    new file mode 100644
    index 0000000..7c03166
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/_version.py
    @@ -0,0 +1,2 @@
    +# This file is protected via CODEOWNERS
    +__version__ = "1.26.14"
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/connection.py b/deployment-apps/metricator-for-nmon/lib/urllib3/connection.py
    new file mode 100644
    index 0000000..10fb36c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/connection.py
    @@ -0,0 +1,567 @@
    +from __future__ import absolute_import
    +
    +import datetime
    +import logging
    +import os
    +import re
    +import socket
    +import warnings
    +from socket import error as SocketError
    +from socket import timeout as SocketTimeout
    +
    +from .packages import six
    +from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection
    +from .packages.six.moves.http_client import HTTPException  # noqa: F401
    +from .util.proxy import create_proxy_ssl_context
    +
    +try:  # Compiled with SSL?
    +    import ssl
    +
    +    BaseSSLError = ssl.SSLError
    +except (ImportError, AttributeError):  # Platform-specific: No SSL.
    +    ssl = None
    +
    +    class BaseSSLError(BaseException):
    +        pass
    +
    +
    +try:
    +    # Python 3: not a no-op, we're adding this to the namespace so it can be imported.
    +    ConnectionError = ConnectionError
    +except NameError:
    +    # Python 2
    +    class ConnectionError(Exception):
    +        pass
    +
    +
    +try:  # Python 3:
    +    # Not a no-op, we're adding this to the namespace so it can be imported.
    +    BrokenPipeError = BrokenPipeError
    +except NameError:  # Python 2:
    +
    +    class BrokenPipeError(Exception):
    +        pass
    +
    +
    +from ._collections import HTTPHeaderDict  # noqa (historical, removed in v2)
    +from ._version import __version__
    +from .exceptions import (
    +    ConnectTimeoutError,
    +    NewConnectionError,
    +    SubjectAltNameWarning,
    +    SystemTimeWarning,
    +)
    +from .util import SKIP_HEADER, SKIPPABLE_HEADERS, connection
    +from .util.ssl_ import (
    +    assert_fingerprint,
    +    create_urllib3_context,
    +    is_ipaddress,
    +    resolve_cert_reqs,
    +    resolve_ssl_version,
    +    ssl_wrap_socket,
    +)
    +from .util.ssl_match_hostname import CertificateError, match_hostname
    +
    +log = logging.getLogger(__name__)
    +
    +port_by_scheme = {"http": 80, "https": 443}
    +
    +# When it comes time to update this value as a part of regular maintenance
    +# (ie test_recent_date is failing) update it to ~6 months before the current date.
    +RECENT_DATE = datetime.date(2022, 1, 1)
    +
    +_CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]")
    +
    +
    +class HTTPConnection(_HTTPConnection, object):
    +    """
    +    Based on :class:`http.client.HTTPConnection` but provides an extra constructor
    +    backwards-compatibility layer between older and newer Pythons.
    +
    +    Additional keyword parameters are used to configure attributes of the connection.
    +    Accepted parameters include:
    +
    +    - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool`
    +    - ``source_address``: Set the source address for the current connection.
    +    - ``socket_options``: Set specific options on the underlying socket. If not specified, then
    +      defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling
    +      Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy.
    +
    +      For example, if you wish to enable TCP Keep Alive in addition to the defaults,
    +      you might pass:
    +
    +      .. code-block:: python
    +
    +         HTTPConnection.default_socket_options + [
    +             (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
    +         ]
    +
    +      Or you may want to disable the defaults by passing an empty list (e.g., ``[]``).
    +    """
    +
    +    default_port = port_by_scheme["http"]
    +
    +    #: Disable Nagle's algorithm by default.
    +    #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]``
    +    default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]
    +
    +    #: Whether this connection verifies the host's certificate.
    +    is_verified = False
    +
    +    #: Whether this proxy connection (if used) verifies the proxy host's
    +    #: certificate.
    +    proxy_is_verified = None
    +
    +    def __init__(self, *args, **kw):
    +        if not six.PY2:
    +            kw.pop("strict", None)
    +
    +        # Pre-set source_address.
    +        self.source_address = kw.get("source_address")
    +
    +        #: The socket options provided by the user. If no options are
    +        #: provided, we use the default options.
    +        self.socket_options = kw.pop("socket_options", self.default_socket_options)
    +
    +        # Proxy options provided by the user.
    +        self.proxy = kw.pop("proxy", None)
    +        self.proxy_config = kw.pop("proxy_config", None)
    +
    +        _HTTPConnection.__init__(self, *args, **kw)
    +
    +    @property
    +    def host(self):
    +        """
    +        Getter method to remove any trailing dots that indicate the hostname is an FQDN.
    +
    +        In general, SSL certificates don't include the trailing dot indicating a
    +        fully-qualified domain name, and thus, they don't validate properly when
    +        checked against a domain name that includes the dot. In addition, some
    +        servers may not expect to receive the trailing dot when provided.
    +
    +        However, the hostname with trailing dot is critical to DNS resolution; doing a
    +        lookup with the trailing dot will properly only resolve the appropriate FQDN,
    +        whereas a lookup without a trailing dot will search the system's search domain
    +        list. Thus, it's important to keep the original host around for use only in
    +        those cases where it's appropriate (i.e., when doing DNS lookup to establish the
    +        actual TCP connection across which we're going to send HTTP requests).
    +        """
    +        return self._dns_host.rstrip(".")
    +
    +    @host.setter
    +    def host(self, value):
    +        """
    +        Setter for the `host` property.
    +
    +        We assume that only urllib3 uses the _dns_host attribute; httplib itself
    +        only uses `host`, and it seems reasonable that other libraries follow suit.
    +        """
    +        self._dns_host = value
    +
    +    def _new_conn(self):
    +        """Establish a socket connection and set nodelay settings on it.
    +
    +        :return: New socket connection.
    +        """
    +        extra_kw = {}
    +        if self.source_address:
    +            extra_kw["source_address"] = self.source_address
    +
    +        if self.socket_options:
    +            extra_kw["socket_options"] = self.socket_options
    +
    +        try:
    +            conn = connection.create_connection(
    +                (self._dns_host, self.port), self.timeout, **extra_kw
    +            )
    +
    +        except SocketTimeout:
    +            raise ConnectTimeoutError(
    +                self,
    +                "Connection to %s timed out. (connect timeout=%s)"
    +                % (self.host, self.timeout),
    +            )
    +
    +        except SocketError as e:
    +            raise NewConnectionError(
    +                self, "Failed to establish a new connection: %s" % e
    +            )
    +
    +        return conn
    +
    +    def _is_using_tunnel(self):
    +        # Google App Engine's httplib does not define _tunnel_host
    +        return getattr(self, "_tunnel_host", None)
    +
    +    def _prepare_conn(self, conn):
    +        self.sock = conn
    +        if self._is_using_tunnel():
    +            # TODO: Fix tunnel so it doesn't depend on self.sock state.
    +            self._tunnel()
    +            # Mark this connection as not reusable
    +            self.auto_open = 0
    +
    +    def connect(self):
    +        conn = self._new_conn()
    +        self._prepare_conn(conn)
    +
    +    def putrequest(self, method, url, *args, **kwargs):
    +        """ """
    +        # Empty docstring because the indentation of CPython's implementation
    +        # is broken but we don't want this method in our documentation.
    +        match = _CONTAINS_CONTROL_CHAR_RE.search(method)
    +        if match:
    +            raise ValueError(
    +                "Method cannot contain non-token characters %r (found at least %r)"
    +                % (method, match.group())
    +            )
    +
    +        return _HTTPConnection.putrequest(self, method, url, *args, **kwargs)
    +
    +    def putheader(self, header, *values):
    +        """ """
    +        if not any(isinstance(v, str) and v == SKIP_HEADER for v in values):
    +            _HTTPConnection.putheader(self, header, *values)
    +        elif six.ensure_str(header.lower()) not in SKIPPABLE_HEADERS:
    +            raise ValueError(
    +                "urllib3.util.SKIP_HEADER only supports '%s'"
    +                % ("', '".join(map(str.title, sorted(SKIPPABLE_HEADERS))),)
    +            )
    +
    +    def request(self, method, url, body=None, headers=None):
    +        if headers is None:
    +            headers = {}
    +        else:
    +            # Avoid modifying the headers passed into .request()
    +            headers = headers.copy()
    +        if "user-agent" not in (six.ensure_str(k.lower()) for k in headers):
    +            headers["User-Agent"] = _get_default_user_agent()
    +        super(HTTPConnection, self).request(method, url, body=body, headers=headers)
    +
    +    def request_chunked(self, method, url, body=None, headers=None):
    +        """
    +        Alternative to the common request method, which sends the
    +        body with chunked encoding and not as one block
    +        """
    +        headers = headers or {}
    +        header_keys = set([six.ensure_str(k.lower()) for k in headers])
    +        skip_accept_encoding = "accept-encoding" in header_keys
    +        skip_host = "host" in header_keys
    +        self.putrequest(
    +            method, url, skip_accept_encoding=skip_accept_encoding, skip_host=skip_host
    +        )
    +        if "user-agent" not in header_keys:
    +            self.putheader("User-Agent", _get_default_user_agent())
    +        for header, value in headers.items():
    +            self.putheader(header, value)
    +        if "transfer-encoding" not in header_keys:
    +            self.putheader("Transfer-Encoding", "chunked")
    +        self.endheaders()
    +
    +        if body is not None:
    +            stringish_types = six.string_types + (bytes,)
    +            if isinstance(body, stringish_types):
    +                body = (body,)
    +            for chunk in body:
    +                if not chunk:
    +                    continue
    +                if not isinstance(chunk, bytes):
    +                    chunk = chunk.encode("utf8")
    +                len_str = hex(len(chunk))[2:]
    +                to_send = bytearray(len_str.encode())
    +                to_send += b"\r\n"
    +                to_send += chunk
    +                to_send += b"\r\n"
    +                self.send(to_send)
    +
    +        # After the if clause, to always have a closed body
    +        self.send(b"0\r\n\r\n")
    +
    +
    +class HTTPSConnection(HTTPConnection):
    +    """
    +    Many of the parameters to this constructor are passed to the underlying SSL
    +    socket by means of :py:func:`urllib3.util.ssl_wrap_socket`.
    +    """
    +
    +    default_port = port_by_scheme["https"]
    +
    +    cert_reqs = None
    +    ca_certs = None
    +    ca_cert_dir = None
    +    ca_cert_data = None
    +    ssl_version = None
    +    assert_fingerprint = None
    +    tls_in_tls_required = False
    +
    +    def __init__(
    +        self,
    +        host,
    +        port=None,
    +        key_file=None,
    +        cert_file=None,
    +        key_password=None,
    +        strict=None,
    +        timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
    +        ssl_context=None,
    +        server_hostname=None,
    +        **kw
    +    ):
    +
    +        HTTPConnection.__init__(self, host, port, strict=strict, timeout=timeout, **kw)
    +
    +        self.key_file = key_file
    +        self.cert_file = cert_file
    +        self.key_password = key_password
    +        self.ssl_context = ssl_context
    +        self.server_hostname = server_hostname
    +
    +        # Required property for Google AppEngine 1.9.0 which otherwise causes
    +        # HTTPS requests to go out as HTTP. (See Issue #356)
    +        self._protocol = "https"
    +
    +    def set_cert(
    +        self,
    +        key_file=None,
    +        cert_file=None,
    +        cert_reqs=None,
    +        key_password=None,
    +        ca_certs=None,
    +        assert_hostname=None,
    +        assert_fingerprint=None,
    +        ca_cert_dir=None,
    +        ca_cert_data=None,
    +    ):
    +        """
    +        This method should only be called once, before the connection is used.
    +        """
    +        # If cert_reqs is not provided we'll assume CERT_REQUIRED unless we also
    +        # have an SSLContext object in which case we'll use its verify_mode.
    +        if cert_reqs is None:
    +            if self.ssl_context is not None:
    +                cert_reqs = self.ssl_context.verify_mode
    +            else:
    +                cert_reqs = resolve_cert_reqs(None)
    +
    +        self.key_file = key_file
    +        self.cert_file = cert_file
    +        self.cert_reqs = cert_reqs
    +        self.key_password = key_password
    +        self.assert_hostname = assert_hostname
    +        self.assert_fingerprint = assert_fingerprint
    +        self.ca_certs = ca_certs and os.path.expanduser(ca_certs)
    +        self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir)
    +        self.ca_cert_data = ca_cert_data
    +
    +    def connect(self):
    +        # Add certificate verification
    +        self.sock = conn = self._new_conn()
    +        hostname = self.host
    +        tls_in_tls = False
    +
    +        if self._is_using_tunnel():
    +            if self.tls_in_tls_required:
    +                self.sock = conn = self._connect_tls_proxy(hostname, conn)
    +                tls_in_tls = True
    +
    +            # Calls self._set_hostport(), so self.host is
    +            # self._tunnel_host below.
    +            self._tunnel()
    +            # Mark this connection as not reusable
    +            self.auto_open = 0
    +
    +            # Override the host with the one we're requesting data from.
    +            hostname = self._tunnel_host
    +
    +        server_hostname = hostname
    +        if self.server_hostname is not None:
    +            server_hostname = self.server_hostname
    +
    +        is_time_off = datetime.date.today() < RECENT_DATE
    +        if is_time_off:
    +            warnings.warn(
    +                (
    +                    "System time is way off (before {0}). This will probably "
    +                    "lead to SSL verification errors"
    +                ).format(RECENT_DATE),
    +                SystemTimeWarning,
    +            )
    +
    +        # Wrap socket using verification with the root certs in
    +        # trusted_root_certs
    +        default_ssl_context = False
    +        if self.ssl_context is None:
    +            default_ssl_context = True
    +            self.ssl_context = create_urllib3_context(
    +                ssl_version=resolve_ssl_version(self.ssl_version),
    +                cert_reqs=resolve_cert_reqs(self.cert_reqs),
    +            )
    +
    +        context = self.ssl_context
    +        context.verify_mode = resolve_cert_reqs(self.cert_reqs)
    +
    +        # Try to load OS default certs if none are given.
    +        # Works well on Windows (requires Python3.4+)
    +        if (
    +            not self.ca_certs
    +            and not self.ca_cert_dir
    +            and not self.ca_cert_data
    +            and default_ssl_context
    +            and hasattr(context, "load_default_certs")
    +        ):
    +            context.load_default_certs()
    +
    +        self.sock = ssl_wrap_socket(
    +            sock=conn,
    +            keyfile=self.key_file,
    +            certfile=self.cert_file,
    +            key_password=self.key_password,
    +            ca_certs=self.ca_certs,
    +            ca_cert_dir=self.ca_cert_dir,
    +            ca_cert_data=self.ca_cert_data,
    +            server_hostname=server_hostname,
    +            ssl_context=context,
    +            tls_in_tls=tls_in_tls,
    +        )
    +
    +        # If we're using all defaults and the connection
    +        # is TLSv1 or TLSv1.1 we throw a DeprecationWarning
    +        # for the host.
    +        if (
    +            default_ssl_context
    +            and self.ssl_version is None
    +            and hasattr(self.sock, "version")
    +            and self.sock.version() in {"TLSv1", "TLSv1.1"}
    +        ):
    +            warnings.warn(
    +                "Negotiating TLSv1/TLSv1.1 by default is deprecated "
    +                "and will be disabled in urllib3 v2.0.0. Connecting to "
    +                "'%s' with '%s' can be enabled by explicitly opting-in "
    +                "with 'ssl_version'" % (self.host, self.sock.version()),
    +                DeprecationWarning,
    +            )
    +
    +        if self.assert_fingerprint:
    +            assert_fingerprint(
    +                self.sock.getpeercert(binary_form=True), self.assert_fingerprint
    +            )
    +        elif (
    +            context.verify_mode != ssl.CERT_NONE
    +            and not getattr(context, "check_hostname", False)
    +            and self.assert_hostname is not False
    +        ):
    +            # While urllib3 attempts to always turn off hostname matching from
    +            # the TLS library, this cannot always be done. So we check whether
    +            # the TLS Library still thinks it's matching hostnames.
    +            cert = self.sock.getpeercert()
    +            if not cert.get("subjectAltName", ()):
    +                warnings.warn(
    +                    (
    +                        "Certificate for {0} has no `subjectAltName`, falling back to check for a "
    +                        "`commonName` for now. This feature is being removed by major browsers and "
    +                        "deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 "
    +                        "for details.)".format(hostname)
    +                    ),
    +                    SubjectAltNameWarning,
    +                )
    +            _match_hostname(cert, self.assert_hostname or server_hostname)
    +
    +        self.is_verified = (
    +            context.verify_mode == ssl.CERT_REQUIRED
    +            or self.assert_fingerprint is not None
    +        )
    +
    +    def _connect_tls_proxy(self, hostname, conn):
    +        """
    +        Establish a TLS connection to the proxy using the provided SSL context.
    +        """
    +        proxy_config = self.proxy_config
    +        ssl_context = proxy_config.ssl_context
    +        if ssl_context:
    +            # If the user provided a proxy context, we assume CA and client
    +            # certificates have already been set
    +            return ssl_wrap_socket(
    +                sock=conn,
    +                server_hostname=hostname,
    +                ssl_context=ssl_context,
    +            )
    +
    +        ssl_context = create_proxy_ssl_context(
    +            self.ssl_version,
    +            self.cert_reqs,
    +            self.ca_certs,
    +            self.ca_cert_dir,
    +            self.ca_cert_data,
    +        )
    +
    +        # If no cert was provided, use only the default options for server
    +        # certificate validation
    +        socket = ssl_wrap_socket(
    +            sock=conn,
    +            ca_certs=self.ca_certs,
    +            ca_cert_dir=self.ca_cert_dir,
    +            ca_cert_data=self.ca_cert_data,
    +            server_hostname=hostname,
    +            ssl_context=ssl_context,
    +        )
    +
    +        if ssl_context.verify_mode != ssl.CERT_NONE and not getattr(
    +            ssl_context, "check_hostname", False
    +        ):
    +            # While urllib3 attempts to always turn off hostname matching from
    +            # the TLS library, this cannot always be done. So we check whether
    +            # the TLS Library still thinks it's matching hostnames.
    +            cert = socket.getpeercert()
    +            if not cert.get("subjectAltName", ()):
    +                warnings.warn(
    +                    (
    +                        "Certificate for {0} has no `subjectAltName`, falling back to check for a "
    +                        "`commonName` for now. This feature is being removed by major browsers and "
    +                        "deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 "
    +                        "for details.)".format(hostname)
    +                    ),
    +                    SubjectAltNameWarning,
    +                )
    +            _match_hostname(cert, hostname)
    +
    +        self.proxy_is_verified = ssl_context.verify_mode == ssl.CERT_REQUIRED
    +        return socket
    +
    +
    +def _match_hostname(cert, asserted_hostname):
    +    # Our upstream implementation of ssl.match_hostname()
    +    # only applies this normalization to IP addresses so it doesn't
    +    # match DNS SANs so we do the same thing!
    +    stripped_hostname = asserted_hostname.strip("u[]")
    +    if is_ipaddress(stripped_hostname):
    +        asserted_hostname = stripped_hostname
    +
    +    try:
    +        match_hostname(cert, asserted_hostname)
    +    except CertificateError as e:
    +        log.warning(
    +            "Certificate did not match expected hostname: %s. Certificate: %s",
    +            asserted_hostname,
    +            cert,
    +        )
    +        # Add cert to exception and reraise so client code can inspect
    +        # the cert when catching the exception, if they want to
    +        e._peer_cert = cert
    +        raise
    +
    +
    +def _get_default_user_agent():
    +    return "python-urllib3/%s" % __version__
    +
    +
    +class DummyConnection(object):
    +    """Used to detect a failed ConnectionCls import."""
    +
    +    pass
    +
    +
    +if not ssl:
    +    HTTPSConnection = DummyConnection  # noqa: F811
    +
    +
    +VerifiedHTTPSConnection = HTTPSConnection
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/connectionpool.py b/deployment-apps/metricator-for-nmon/lib/urllib3/connectionpool.py
    new file mode 100644
    index 0000000..7087392
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/connectionpool.py
    @@ -0,0 +1,1110 @@
    +from __future__ import absolute_import
    +
    +import errno
    +import logging
    +import re
    +import socket
    +import sys
    +import warnings
    +from socket import error as SocketError
    +from socket import timeout as SocketTimeout
    +
    +from .connection import (
    +    BaseSSLError,
    +    BrokenPipeError,
    +    DummyConnection,
    +    HTTPConnection,
    +    HTTPException,
    +    HTTPSConnection,
    +    VerifiedHTTPSConnection,
    +    port_by_scheme,
    +)
    +from .exceptions import (
    +    ClosedPoolError,
    +    EmptyPoolError,
    +    HeaderParsingError,
    +    HostChangedError,
    +    InsecureRequestWarning,
    +    LocationValueError,
    +    MaxRetryError,
    +    NewConnectionError,
    +    ProtocolError,
    +    ProxyError,
    +    ReadTimeoutError,
    +    SSLError,
    +    TimeoutError,
    +)
    +from .packages import six
    +from .packages.six.moves import queue
    +from .request import RequestMethods
    +from .response import HTTPResponse
    +from .util.connection import is_connection_dropped
    +from .util.proxy import connection_requires_http_tunnel
    +from .util.queue import LifoQueue
    +from .util.request import set_file_position
    +from .util.response import assert_header_parsing
    +from .util.retry import Retry
    +from .util.ssl_match_hostname import CertificateError
    +from .util.timeout import Timeout
    +from .util.url import Url, _encode_target
    +from .util.url import _normalize_host as normalize_host
    +from .util.url import get_host, parse_url
    +
    +xrange = six.moves.xrange
    +
    +log = logging.getLogger(__name__)
    +
    +_Default = object()
    +
    +
    +# Pool objects
    +class ConnectionPool(object):
    +    """
    +    Base class for all connection pools, such as
    +    :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`.
    +
    +    .. note::
    +       ConnectionPool.urlopen() does not normalize or percent-encode target URIs
    +       which is useful if your target server doesn't support percent-encoded
    +       target URIs.
    +    """
    +
    +    scheme = None
    +    QueueCls = LifoQueue
    +
    +    def __init__(self, host, port=None):
    +        if not host:
    +            raise LocationValueError("No host specified.")
    +
    +        self.host = _normalize_host(host, scheme=self.scheme)
    +        self._proxy_host = host.lower()
    +        self.port = port
    +
    +    def __str__(self):
    +        return "%s(host=%r, port=%r)" % (type(self).__name__, self.host, self.port)
    +
    +    def __enter__(self):
    +        return self
    +
    +    def __exit__(self, exc_type, exc_val, exc_tb):
    +        self.close()
    +        # Return False to re-raise any potential exceptions
    +        return False
    +
    +    def close(self):
    +        """
    +        Close all pooled connections and disable the pool.
    +        """
    +        pass
    +
    +
    +# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252
    +_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK}
    +
    +
    +class HTTPConnectionPool(ConnectionPool, RequestMethods):
    +    """
    +    Thread-safe connection pool for one host.
    +
    +    :param host:
    +        Host used for this HTTP Connection (e.g. "localhost"), passed into
    +        :class:`http.client.HTTPConnection`.
    +
    +    :param port:
    +        Port used for this HTTP Connection (None is equivalent to 80), passed
    +        into :class:`http.client.HTTPConnection`.
    +
    +    :param strict:
    +        Causes BadStatusLine to be raised if the status line can't be parsed
    +        as a valid HTTP/1.0 or 1.1 status line, passed into
    +        :class:`http.client.HTTPConnection`.
    +
    +        .. note::
    +           Only works in Python 2. This parameter is ignored in Python 3.
    +
    +    :param timeout:
    +        Socket timeout in seconds for each individual connection. This can
    +        be a float or integer, which sets the timeout for the HTTP request,
    +        or an instance of :class:`urllib3.util.Timeout` which gives you more
    +        fine-grained control over request timeouts. After the constructor has
    +        been parsed, this is always a `urllib3.util.Timeout` object.
    +
    +    :param maxsize:
    +        Number of connections to save that can be reused. More than 1 is useful
    +        in multithreaded situations. If ``block`` is set to False, more
    +        connections will be created but they will not be saved once they've
    +        been used.
    +
    +    :param block:
    +        If set to True, no more than ``maxsize`` connections will be used at
    +        a time. When no free connections are available, the call will block
    +        until a connection has been released. This is a useful side effect for
    +        particular multithreaded situations where one does not want to use more
    +        than maxsize connections per host to prevent flooding.
    +
    +    :param headers:
    +        Headers to include with all requests, unless other headers are given
    +        explicitly.
    +
    +    :param retries:
    +        Retry configuration to use by default with requests in this pool.
    +
    +    :param _proxy:
    +        Parsed proxy URL, should not be used directly, instead, see
    +        :class:`urllib3.ProxyManager`
    +
    +    :param _proxy_headers:
    +        A dictionary with proxy headers, should not be used directly,
    +        instead, see :class:`urllib3.ProxyManager`
    +
    +    :param \\**conn_kw:
    +        Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`,
    +        :class:`urllib3.connection.HTTPSConnection` instances.
    +    """
    +
    +    scheme = "http"
    +    ConnectionCls = HTTPConnection
    +    ResponseCls = HTTPResponse
    +
    +    def __init__(
    +        self,
    +        host,
    +        port=None,
    +        strict=False,
    +        timeout=Timeout.DEFAULT_TIMEOUT,
    +        maxsize=1,
    +        block=False,
    +        headers=None,
    +        retries=None,
    +        _proxy=None,
    +        _proxy_headers=None,
    +        _proxy_config=None,
    +        **conn_kw
    +    ):
    +        ConnectionPool.__init__(self, host, port)
    +        RequestMethods.__init__(self, headers)
    +
    +        self.strict = strict
    +
    +        if not isinstance(timeout, Timeout):
    +            timeout = Timeout.from_float(timeout)
    +
    +        if retries is None:
    +            retries = Retry.DEFAULT
    +
    +        self.timeout = timeout
    +        self.retries = retries
    +
    +        self.pool = self.QueueCls(maxsize)
    +        self.block = block
    +
    +        self.proxy = _proxy
    +        self.proxy_headers = _proxy_headers or {}
    +        self.proxy_config = _proxy_config
    +
    +        # Fill the queue up so that doing get() on it will block properly
    +        for _ in xrange(maxsize):
    +            self.pool.put(None)
    +
    +        # These are mostly for testing and debugging purposes.
    +        self.num_connections = 0
    +        self.num_requests = 0
    +        self.conn_kw = conn_kw
    +
    +        if self.proxy:
    +            # Enable Nagle's algorithm for proxies, to avoid packet fragmentation.
    +            # We cannot know if the user has added default socket options, so we cannot replace the
    +            # list.
    +            self.conn_kw.setdefault("socket_options", [])
    +
    +            self.conn_kw["proxy"] = self.proxy
    +            self.conn_kw["proxy_config"] = self.proxy_config
    +
    +    def _new_conn(self):
    +        """
    +        Return a fresh :class:`HTTPConnection`.
    +        """
    +        self.num_connections += 1
    +        log.debug(
    +            "Starting new HTTP connection (%d): %s:%s",
    +            self.num_connections,
    +            self.host,
    +            self.port or "80",
    +        )
    +
    +        conn = self.ConnectionCls(
    +            host=self.host,
    +            port=self.port,
    +            timeout=self.timeout.connect_timeout,
    +            strict=self.strict,
    +            **self.conn_kw
    +        )
    +        return conn
    +
    +    def _get_conn(self, timeout=None):
    +        """
    +        Get a connection. Will return a pooled connection if one is available.
    +
    +        If no connections are available and :prop:`.block` is ``False``, then a
    +        fresh connection is returned.
    +
    +        :param timeout:
    +            Seconds to wait before giving up and raising
    +            :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and
    +            :prop:`.block` is ``True``.
    +        """
    +        conn = None
    +        try:
    +            conn = self.pool.get(block=self.block, timeout=timeout)
    +
    +        except AttributeError:  # self.pool is None
    +            raise ClosedPoolError(self, "Pool is closed.")
    +
    +        except queue.Empty:
    +            if self.block:
    +                raise EmptyPoolError(
    +                    self,
    +                    "Pool reached maximum size and no more connections are allowed.",
    +                )
    +            pass  # Oh well, we'll create a new connection then
    +
    +        # If this is a persistent connection, check if it got disconnected
    +        if conn and is_connection_dropped(conn):
    +            log.debug("Resetting dropped connection: %s", self.host)
    +            conn.close()
    +            if getattr(conn, "auto_open", 1) == 0:
    +                # This is a proxied connection that has been mutated by
    +                # http.client._tunnel() and cannot be reused (since it would
    +                # attempt to bypass the proxy)
    +                conn = None
    +
    +        return conn or self._new_conn()
    +
    +    def _put_conn(self, conn):
    +        """
    +        Put a connection back into the pool.
    +
    +        :param conn:
    +            Connection object for the current host and port as returned by
    +            :meth:`._new_conn` or :meth:`._get_conn`.
    +
    +        If the pool is already full, the connection is closed and discarded
    +        because we exceeded maxsize. If connections are discarded frequently,
    +        then maxsize should be increased.
    +
    +        If the pool is closed, then the connection will be closed and discarded.
    +        """
    +        try:
    +            self.pool.put(conn, block=False)
    +            return  # Everything is dandy, done.
    +        except AttributeError:
    +            # self.pool is None.
    +            pass
    +        except queue.Full:
    +            # This should never happen if self.block == True
    +            log.warning(
    +                "Connection pool is full, discarding connection: %s. Connection pool size: %s",
    +                self.host,
    +                self.pool.qsize(),
    +            )
    +        # Connection never got put back into the pool, close it.
    +        if conn:
    +            conn.close()
    +
    +    def _validate_conn(self, conn):
    +        """
    +        Called right before a request is made, after the socket is created.
    +        """
    +        pass
    +
    +    def _prepare_proxy(self, conn):
    +        # Nothing to do for HTTP connections.
    +        pass
    +
    +    def _get_timeout(self, timeout):
    +        """Helper that always returns a :class:`urllib3.util.Timeout`"""
    +        if timeout is _Default:
    +            return self.timeout.clone()
    +
    +        if isinstance(timeout, Timeout):
    +            return timeout.clone()
    +        else:
    +            # User passed us an int/float. This is for backwards compatibility,
    +            # can be removed later
    +            return Timeout.from_float(timeout)
    +
    +    def _raise_timeout(self, err, url, timeout_value):
    +        """Is the error actually a timeout? Will raise a ReadTimeout or pass"""
    +
    +        if isinstance(err, SocketTimeout):
    +            raise ReadTimeoutError(
    +                self, url, "Read timed out. (read timeout=%s)" % timeout_value
    +            )
    +
    +        # See the above comment about EAGAIN in Python 3. In Python 2 we have
    +        # to specifically catch it and throw the timeout error
    +        if hasattr(err, "errno") and err.errno in _blocking_errnos:
    +            raise ReadTimeoutError(
    +                self, url, "Read timed out. (read timeout=%s)" % timeout_value
    +            )
    +
    +        # Catch possible read timeouts thrown as SSL errors. If not the
    +        # case, rethrow the original. We need to do this because of:
    +        # http://bugs.python.org/issue10272
    +        if "timed out" in str(err) or "did not complete (read)" in str(
    +            err
    +        ):  # Python < 2.7.4
    +            raise ReadTimeoutError(
    +                self, url, "Read timed out. (read timeout=%s)" % timeout_value
    +            )
    +
    +    def _make_request(
    +        self, conn, method, url, timeout=_Default, chunked=False, **httplib_request_kw
    +    ):
    +        """
    +        Perform a request on a given urllib connection object taken from our
    +        pool.
    +
    +        :param conn:
    +            a connection from one of our connection pools
    +
    +        :param timeout:
    +            Socket timeout in seconds for the request. This can be a
    +            float or integer, which will set the same timeout value for
    +            the socket connect and the socket read, or an instance of
    +            :class:`urllib3.util.Timeout`, which gives you more fine-grained
    +            control over your timeouts.
    +        """
    +        self.num_requests += 1
    +
    +        timeout_obj = self._get_timeout(timeout)
    +        timeout_obj.start_connect()
    +        conn.timeout = timeout_obj.connect_timeout
    +
    +        # Trigger any extra validation we need to do.
    +        try:
    +            self._validate_conn(conn)
    +        except (SocketTimeout, BaseSSLError) as e:
    +            # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout.
    +            self._raise_timeout(err=e, url=url, timeout_value=conn.timeout)
    +            raise
    +
    +        # conn.request() calls http.client.*.request, not the method in
    +        # urllib3.request. It also calls makefile (recv) on the socket.
    +        try:
    +            if chunked:
    +                conn.request_chunked(method, url, **httplib_request_kw)
    +            else:
    +                conn.request(method, url, **httplib_request_kw)
    +
    +        # We are swallowing BrokenPipeError (errno.EPIPE) since the server is
    +        # legitimately able to close the connection after sending a valid response.
    +        # With this behaviour, the received response is still readable.
    +        except BrokenPipeError:
    +            # Python 3
    +            pass
    +        except IOError as e:
    +            # Python 2 and macOS/Linux
    +            # EPIPE and ESHUTDOWN are BrokenPipeError on Python 2, and EPROTOTYPE is needed on macOS
    +            # https://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/
    +            if e.errno not in {
    +                errno.EPIPE,
    +                errno.ESHUTDOWN,
    +                errno.EPROTOTYPE,
    +            }:
    +                raise
    +
    +        # Reset the timeout for the recv() on the socket
    +        read_timeout = timeout_obj.read_timeout
    +
    +        # App Engine doesn't have a sock attr
    +        if getattr(conn, "sock", None):
    +            # In Python 3 socket.py will catch EAGAIN and return None when you
    +            # try and read into the file pointer created by http.client, which
    +            # instead raises a BadStatusLine exception. Instead of catching
    +            # the exception and assuming all BadStatusLine exceptions are read
    +            # timeouts, check for a zero timeout before making the request.
    +            if read_timeout == 0:
    +                raise ReadTimeoutError(
    +                    self, url, "Read timed out. (read timeout=%s)" % read_timeout
    +                )
    +            if read_timeout is Timeout.DEFAULT_TIMEOUT:
    +                conn.sock.settimeout(socket.getdefaulttimeout())
    +            else:  # None or a value
    +                conn.sock.settimeout(read_timeout)
    +
    +        # Receive the response from the server
    +        try:
    +            try:
    +                # Python 2.7, use buffering of HTTP responses
    +                httplib_response = conn.getresponse(buffering=True)
    +            except TypeError:
    +                # Python 3
    +                try:
    +                    httplib_response = conn.getresponse()
    +                except BaseException as e:
    +                    # Remove the TypeError from the exception chain in
    +                    # Python 3 (including for exceptions like SystemExit).
    +                    # Otherwise it looks like a bug in the code.
    +                    six.raise_from(e, None)
    +        except (SocketTimeout, BaseSSLError, SocketError) as e:
    +            self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
    +            raise
    +
    +        # AppEngine doesn't have a version attr.
    +        http_version = getattr(conn, "_http_vsn_str", "HTTP/?")
    +        log.debug(
    +            '%s://%s:%s "%s %s %s" %s %s',
    +            self.scheme,
    +            self.host,
    +            self.port,
    +            method,
    +            url,
    +            http_version,
    +            httplib_response.status,
    +            httplib_response.length,
    +        )
    +
    +        try:
    +            assert_header_parsing(httplib_response.msg)
    +        except (HeaderParsingError, TypeError) as hpe:  # Platform-specific: Python 3
    +            log.warning(
    +                "Failed to parse headers (url=%s): %s",
    +                self._absolute_url(url),
    +                hpe,
    +                exc_info=True,
    +            )
    +
    +        return httplib_response
    +
    +    def _absolute_url(self, path):
    +        return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url
    +
    +    def close(self):
    +        """
    +        Close all pooled connections and disable the pool.
    +        """
    +        if self.pool is None:
    +            return
    +        # Disable access to the pool
    +        old_pool, self.pool = self.pool, None
    +
    +        try:
    +            while True:
    +                conn = old_pool.get(block=False)
    +                if conn:
    +                    conn.close()
    +
    +        except queue.Empty:
    +            pass  # Done.
    +
    +    def is_same_host(self, url):
    +        """
    +        Check if the given ``url`` is a member of the same host as this
    +        connection pool.
    +        """
    +        if url.startswith("/"):
    +            return True
    +
    +        # TODO: Add optional support for socket.gethostbyname checking.
    +        scheme, host, port = get_host(url)
    +        if host is not None:
    +            host = _normalize_host(host, scheme=scheme)
    +
    +        # Use explicit default port for comparison when none is given
    +        if self.port and not port:
    +            port = port_by_scheme.get(scheme)
    +        elif not self.port and port == port_by_scheme.get(scheme):
    +            port = None
    +
    +        return (scheme, host, port) == (self.scheme, self.host, self.port)
    +
    +    def urlopen(
    +        self,
    +        method,
    +        url,
    +        body=None,
    +        headers=None,
    +        retries=None,
    +        redirect=True,
    +        assert_same_host=True,
    +        timeout=_Default,
    +        pool_timeout=None,
    +        release_conn=None,
    +        chunked=False,
    +        body_pos=None,
    +        **response_kw
    +    ):
    +        """
    +        Get a connection from the pool and perform an HTTP request. This is the
    +        lowest level call for making a request, so you'll need to specify all
    +        the raw details.
    +
    +        .. note::
    +
    +           More commonly, it's appropriate to use a convenience method provided
    +           by :class:`.RequestMethods`, such as :meth:`request`.
    +
    +        .. note::
    +
    +           `release_conn` will only behave as expected if
    +           `preload_content=False` because we want to make
    +           `preload_content=False` the default behaviour someday soon without
    +           breaking backwards compatibility.
    +
    +        :param method:
    +            HTTP request method (such as GET, POST, PUT, etc.)
    +
    +        :param url:
    +            The URL to perform the request on.
    +
    +        :param body:
    +            Data to send in the request body, either :class:`str`, :class:`bytes`,
    +            an iterable of :class:`str`/:class:`bytes`, or a file-like object.
    +
    +        :param headers:
    +            Dictionary of custom headers to send, such as User-Agent,
    +            If-None-Match, etc. If None, pool headers are used. If provided,
    +            these headers completely replace any pool-specific headers.
    +
    +        :param retries:
    +            Configure the number of retries to allow before raising a
    +            :class:`~urllib3.exceptions.MaxRetryError` exception.
    +
    +            Pass ``None`` to retry until you receive a response. Pass a
    +            :class:`~urllib3.util.retry.Retry` object for fine-grained control
    +            over different types of retries.
    +            Pass an integer number to retry connection errors that many times,
    +            but no other types of errors. Pass zero to never retry.
    +
    +            If ``False``, then retries are disabled and any exception is raised
    +            immediately. Also, instead of raising a MaxRetryError on redirects,
    +            the redirect response will be returned.
    +
    +        :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.
    +
    +        :param redirect:
    +            If True, automatically handle redirects (status codes 301, 302,
    +            303, 307, 308). Each redirect counts as a retry. Disabling retries
    +            will disable redirect, too.
    +
    +        :param assert_same_host:
    +            If ``True``, will make sure that the host of the pool requests is
    +            consistent else will raise HostChangedError. When ``False``, you can
    +            use the pool on an HTTP proxy and request foreign hosts.
    +
    +        :param timeout:
    +            If specified, overrides the default timeout for this one
    +            request. It may be a float (in seconds) or an instance of
    +            :class:`urllib3.util.Timeout`.
    +
    +        :param pool_timeout:
    +            If set and the pool is set to block=True, then this method will
    +            block for ``pool_timeout`` seconds and raise EmptyPoolError if no
    +            connection is available within the time period.
    +
    +        :param release_conn:
    +            If False, then the urlopen call will not release the connection
    +            back into the pool once a response is received (but will release if
    +            you read the entire contents of the response such as when
    +            `preload_content=True`). This is useful if you're not preloading
    +            the response's content immediately. You will need to call
    +            ``r.release_conn()`` on the response ``r`` to return the connection
    +            back into the pool. If None, it takes the value of
    +            ``response_kw.get('preload_content', True)``.
    +
    +        :param chunked:
    +            If True, urllib3 will send the body using chunked transfer
    +            encoding. Otherwise, urllib3 will send the body using the standard
    +            content-length form. Defaults to False.
    +
    +        :param int body_pos:
    +            Position to seek to in file-like body in the event of a retry or
    +            redirect. Typically this won't need to be set because urllib3 will
    +            auto-populate the value when needed.
    +
    +        :param \\**response_kw:
    +            Additional parameters are passed to
    +            :meth:`urllib3.response.HTTPResponse.from_httplib`
    +        """
    +
    +        parsed_url = parse_url(url)
    +        destination_scheme = parsed_url.scheme
    +
    +        if headers is None:
    +            headers = self.headers
    +
    +        if not isinstance(retries, Retry):
    +            retries = Retry.from_int(retries, redirect=redirect, default=self.retries)
    +
    +        if release_conn is None:
    +            release_conn = response_kw.get("preload_content", True)
    +
    +        # Check host
    +        if assert_same_host and not self.is_same_host(url):
    +            raise HostChangedError(self, url, retries)
    +
    +        # Ensure that the URL we're connecting to is properly encoded
    +        if url.startswith("/"):
    +            url = six.ensure_str(_encode_target(url))
    +        else:
    +            url = six.ensure_str(parsed_url.url)
    +
    +        conn = None
    +
    +        # Track whether `conn` needs to be released before
    +        # returning/raising/recursing. Update this variable if necessary, and
    +        # leave `release_conn` constant throughout the function. That way, if
    +        # the function recurses, the original value of `release_conn` will be
    +        # passed down into the recursive call, and its value will be respected.
    +        #
    +        # See issue #651 [1] for details.
    +        #
    +        # [1] <https://github.com/urllib3/urllib3/issues/651>
    +        release_this_conn = release_conn
    +
    +        http_tunnel_required = connection_requires_http_tunnel(
    +            self.proxy, self.proxy_config, destination_scheme
    +        )
    +
    +        # Merge the proxy headers. Only done when not using HTTP CONNECT. We
    +        # have to copy the headers dict so we can safely change it without those
    +        # changes being reflected in anyone else's copy.
    +        if not http_tunnel_required:
    +            headers = headers.copy()
    +            headers.update(self.proxy_headers)
    +
    +        # Must keep the exception bound to a separate variable or else Python 3
    +        # complains about UnboundLocalError.
    +        err = None
    +
    +        # Keep track of whether we cleanly exited the except block. This
    +        # ensures we do proper cleanup in finally.
    +        clean_exit = False
    +
    +        # Rewind body position, if needed. Record current position
    +        # for future rewinds in the event of a redirect/retry.
    +        body_pos = set_file_position(body, body_pos)
    +
    +        try:
    +            # Request a connection from the queue.
    +            timeout_obj = self._get_timeout(timeout)
    +            conn = self._get_conn(timeout=pool_timeout)
    +
    +            conn.timeout = timeout_obj.connect_timeout
    +
    +            is_new_proxy_conn = self.proxy is not None and not getattr(
    +                conn, "sock", None
    +            )
    +            if is_new_proxy_conn and http_tunnel_required:
    +                self._prepare_proxy(conn)
    +
    +            # Make the request on the httplib connection object.
    +            httplib_response = self._make_request(
    +                conn,
    +                method,
    +                url,
    +                timeout=timeout_obj,
    +                body=body,
    +                headers=headers,
    +                chunked=chunked,
    +            )
    +
    +            # If we're going to release the connection in ``finally:``, then
    +            # the response doesn't need to know about the connection. Otherwise
    +            # it will also try to release it and we'll have a double-release
    +            # mess.
    +            response_conn = conn if not release_conn else None
    +
    +            # Pass method to Response for length checking
    +            response_kw["request_method"] = method
    +
    +            # Import httplib's response into our own wrapper object
    +            response = self.ResponseCls.from_httplib(
    +                httplib_response,
    +                pool=self,
    +                connection=response_conn,
    +                retries=retries,
    +                **response_kw
    +            )
    +
    +            # Everything went great!
    +            clean_exit = True
    +
    +        except EmptyPoolError:
    +            # Didn't get a connection from the pool, no need to clean up
    +            clean_exit = True
    +            release_this_conn = False
    +            raise
    +
    +        except (
    +            TimeoutError,
    +            HTTPException,
    +            SocketError,
    +            ProtocolError,
    +            BaseSSLError,
    +            SSLError,
    +            CertificateError,
    +        ) as e:
    +            # Discard the connection for these exceptions. It will be
    +            # replaced during the next _get_conn() call.
    +            clean_exit = False
    +
    +            def _is_ssl_error_message_from_http_proxy(ssl_error):
    +                # We're trying to detect the message 'WRONG_VERSION_NUMBER' but
    +                # SSLErrors are kinda all over the place when it comes to the message,
    +                # so we try to cover our bases here!
    +                message = " ".join(re.split("[^a-z]", str(ssl_error).lower()))
    +                return (
    +                    "wrong version number" in message or "unknown protocol" in message
    +                )
    +
    +            # Try to detect a common user error with proxies which is to
    +            # set an HTTP proxy to be HTTPS when it should be 'http://'
    +            # (ie {'http': 'http://proxy', 'https': 'https://proxy'})
    +            # Instead we add a nice error message and point to a URL.
    +            if (
    +                isinstance(e, BaseSSLError)
    +                and self.proxy
    +                and _is_ssl_error_message_from_http_proxy(e)
    +                and conn.proxy
    +                and conn.proxy.scheme == "https"
    +            ):
    +                e = ProxyError(
    +                    "Your proxy appears to only use HTTP and not HTTPS, "
    +                    "try changing your proxy URL to be HTTP. See: "
    +                    "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html"
    +                    "#https-proxy-error-http-proxy",
    +                    SSLError(e),
    +                )
    +            elif isinstance(e, (BaseSSLError, CertificateError)):
    +                e = SSLError(e)
    +            elif isinstance(e, (SocketError, NewConnectionError)) and self.proxy:
    +                e = ProxyError("Cannot connect to proxy.", e)
    +            elif isinstance(e, (SocketError, HTTPException)):
    +                e = ProtocolError("Connection aborted.", e)
    +
    +            retries = retries.increment(
    +                method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
    +            )
    +            retries.sleep()
    +
    +            # Keep track of the error for the retry warning.
    +            err = e
    +
    +        finally:
    +            if not clean_exit:
    +                # We hit some kind of exception, handled or otherwise. We need
    +                # to throw the connection away unless explicitly told not to.
    +                # Close the connection, set the variable to None, and make sure
    +                # we put the None back in the pool to avoid leaking it.
    +                conn = conn and conn.close()
    +                release_this_conn = True
    +
    +            if release_this_conn:
    +                # Put the connection back to be reused. If the connection is
    +                # expired then it will be None, which will get replaced with a
    +                # fresh connection during _get_conn.
    +                self._put_conn(conn)
    +
    +        if not conn:
    +            # Try again
    +            log.warning(
    +                "Retrying (%r) after connection broken by '%r': %s", retries, err, url
    +            )
    +            return self.urlopen(
    +                method,
    +                url,
    +                body,
    +                headers,
    +                retries,
    +                redirect,
    +                assert_same_host,
    +                timeout=timeout,
    +                pool_timeout=pool_timeout,
    +                release_conn=release_conn,
    +                chunked=chunked,
    +                body_pos=body_pos,
    +                **response_kw
    +            )
    +
    +        # Handle redirect?
    +        redirect_location = redirect and response.get_redirect_location()
    +        if redirect_location:
    +            if response.status == 303:
    +                method = "GET"
    +
    +            try:
    +                retries = retries.increment(method, url, response=response, _pool=self)
    +            except MaxRetryError:
    +                if retries.raise_on_redirect:
    +                    response.drain_conn()
    +                    raise
    +                return response
    +
    +            response.drain_conn()
    +            retries.sleep_for_retry(response)
    +            log.debug("Redirecting %s -> %s", url, redirect_location)
    +            return self.urlopen(
    +                method,
    +                redirect_location,
    +                body,
    +                headers,
    +                retries=retries,
    +                redirect=redirect,
    +                assert_same_host=assert_same_host,
    +                timeout=timeout,
    +                pool_timeout=pool_timeout,
    +                release_conn=release_conn,
    +                chunked=chunked,
    +                body_pos=body_pos,
    +                **response_kw
    +            )
    +
    +        # Check if we should retry the HTTP response.
    +        has_retry_after = bool(response.headers.get("Retry-After"))
    +        if retries.is_retry(method, response.status, has_retry_after):
    +            try:
    +                retries = retries.increment(method, url, response=response, _pool=self)
    +            except MaxRetryError:
    +                if retries.raise_on_status:
    +                    response.drain_conn()
    +                    raise
    +                return response
    +
    +            response.drain_conn()
    +            retries.sleep(response)
    +            log.debug("Retry: %s", url)
    +            return self.urlopen(
    +                method,
    +                url,
    +                body,
    +                headers,
    +                retries=retries,
    +                redirect=redirect,
    +                assert_same_host=assert_same_host,
    +                timeout=timeout,
    +                pool_timeout=pool_timeout,
    +                release_conn=release_conn,
    +                chunked=chunked,
    +                body_pos=body_pos,
    +                **response_kw
    +            )
    +
    +        return response
    +
    +
    +class HTTPSConnectionPool(HTTPConnectionPool):
    +    """
    +    Same as :class:`.HTTPConnectionPool`, but HTTPS.
    +
    +    :class:`.HTTPSConnection` uses one of ``assert_fingerprint``,
    +    ``assert_hostname`` and ``host`` in this order to verify connections.
    +    If ``assert_hostname`` is False, no verification is done.
    +
    +    The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``,
    +    ``ca_cert_dir``, ``ssl_version``, ``key_password`` are only used if :mod:`ssl`
    +    is available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade
    +    the connection socket into an SSL socket.
    +    """
    +
    +    scheme = "https"
    +    ConnectionCls = HTTPSConnection
    +
    +    def __init__(
    +        self,
    +        host,
    +        port=None,
    +        strict=False,
    +        timeout=Timeout.DEFAULT_TIMEOUT,
    +        maxsize=1,
    +        block=False,
    +        headers=None,
    +        retries=None,
    +        _proxy=None,
    +        _proxy_headers=None,
    +        key_file=None,
    +        cert_file=None,
    +        cert_reqs=None,
    +        key_password=None,
    +        ca_certs=None,
    +        ssl_version=None,
    +        assert_hostname=None,
    +        assert_fingerprint=None,
    +        ca_cert_dir=None,
    +        **conn_kw
    +    ):
    +
    +        HTTPConnectionPool.__init__(
    +            self,
    +            host,
    +            port,
    +            strict,
    +            timeout,
    +            maxsize,
    +            block,
    +            headers,
    +            retries,
    +            _proxy,
    +            _proxy_headers,
    +            **conn_kw
    +        )
    +
    +        self.key_file = key_file
    +        self.cert_file = cert_file
    +        self.cert_reqs = cert_reqs
    +        self.key_password = key_password
    +        self.ca_certs = ca_certs
    +        self.ca_cert_dir = ca_cert_dir
    +        self.ssl_version = ssl_version
    +        self.assert_hostname = assert_hostname
    +        self.assert_fingerprint = assert_fingerprint
    +
    +    def _prepare_conn(self, conn):
    +        """
    +        Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket`
    +        and establish the tunnel if proxy is used.
    +        """
    +
    +        if isinstance(conn, VerifiedHTTPSConnection):
    +            conn.set_cert(
    +                key_file=self.key_file,
    +                key_password=self.key_password,
    +                cert_file=self.cert_file,
    +                cert_reqs=self.cert_reqs,
    +                ca_certs=self.ca_certs,
    +                ca_cert_dir=self.ca_cert_dir,
    +                assert_hostname=self.assert_hostname,
    +                assert_fingerprint=self.assert_fingerprint,
    +            )
    +            conn.ssl_version = self.ssl_version
    +        return conn
    +
    +    def _prepare_proxy(self, conn):
    +        """
    +        Establishes a tunnel connection through HTTP CONNECT.
    +
    +        Tunnel connection is established early because otherwise httplib would
    +        improperly set Host: header to proxy's IP:port.
    +        """
    +
    +        conn.set_tunnel(self._proxy_host, self.port, self.proxy_headers)
    +
    +        if self.proxy.scheme == "https":
    +            conn.tls_in_tls_required = True
    +
    +        conn.connect()
    +
    +    def _new_conn(self):
    +        """
    +        Return a fresh :class:`http.client.HTTPSConnection`.
    +        """
    +        self.num_connections += 1
    +        log.debug(
    +            "Starting new HTTPS connection (%d): %s:%s",
    +            self.num_connections,
    +            self.host,
    +            self.port or "443",
    +        )
    +
    +        if not self.ConnectionCls or self.ConnectionCls is DummyConnection:
    +            raise SSLError(
    +                "Can't connect to HTTPS URL because the SSL module is not available."
    +            )
    +
    +        actual_host = self.host
    +        actual_port = self.port
    +        if self.proxy is not None:
    +            actual_host = self.proxy.host
    +            actual_port = self.proxy.port
    +
    +        conn = self.ConnectionCls(
    +            host=actual_host,
    +            port=actual_port,
    +            timeout=self.timeout.connect_timeout,
    +            strict=self.strict,
    +            cert_file=self.cert_file,
    +            key_file=self.key_file,
    +            key_password=self.key_password,
    +            **self.conn_kw
    +        )
    +
    +        return self._prepare_conn(conn)
    +
    +    def _validate_conn(self, conn):
    +        """
    +        Called right before a request is made, after the socket is created.
    +        """
    +        super(HTTPSConnectionPool, self)._validate_conn(conn)
    +
    +        # Force connect early to allow us to validate the connection.
    +        if not getattr(conn, "sock", None):  # AppEngine might not have  `.sock`
    +            conn.connect()
    +
    +        if not conn.is_verified:
    +            warnings.warn(
    +                (
    +                    "Unverified HTTPS request is being made to host '%s'. "
    +                    "Adding certificate verification is strongly advised. See: "
    +                    "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html"
    +                    "#ssl-warnings" % conn.host
    +                ),
    +                InsecureRequestWarning,
    +            )
    +
    +        if getattr(conn, "proxy_is_verified", None) is False:
    +            warnings.warn(
    +                (
    +                    "Unverified HTTPS connection done to an HTTPS proxy. "
    +                    "Adding certificate verification is strongly advised. See: "
    +                    "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html"
    +                    "#ssl-warnings"
    +                ),
    +                InsecureRequestWarning,
    +            )
    +
    +
    +def connection_from_url(url, **kw):
    +    """
    +    Given a url, return an :class:`.ConnectionPool` instance of its host.
    +
    +    This is a shortcut for not having to parse out the scheme, host, and port
    +    of the url before creating an :class:`.ConnectionPool` instance.
    +
    +    :param url:
    +        Absolute URL string that must include the scheme. Port is optional.
    +
    +    :param \\**kw:
    +        Passes additional parameters to the constructor of the appropriate
    +        :class:`.ConnectionPool`. Useful for specifying things like
    +        timeout, maxsize, headers, etc.
    +
    +    Example::
    +
    +        >>> conn = connection_from_url('http://google.com/')
    +        >>> r = conn.request('GET', '/')
    +    """
    +    scheme, host, port = get_host(url)
    +    port = port or port_by_scheme.get(scheme, 80)
    +    if scheme == "https":
    +        return HTTPSConnectionPool(host, port=port, **kw)
    +    else:
    +        return HTTPConnectionPool(host, port=port, **kw)
    +
    +
    +def _normalize_host(host, scheme):
    +    """
    +    Normalize hosts for comparisons and use with sockets.
    +    """
    +
    +    host = normalize_host(host, scheme)
    +
    +    # httplib doesn't like it when we include brackets in IPv6 addresses
    +    # Specifically, if we include brackets but also pass the port then
    +    # httplib crazily doubles up the square brackets on the Host header.
    +    # Instead, we need to make sure we never pass ``None`` as the port.
    +    # However, for backward compatibility reasons we can't actually
    +    # *assert* that.  See http://bugs.python.org/issue28539
    +    if host.startswith("[") and host.endswith("]"):
    +        host = host[1:-1]
    +    return host
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/__init__.py b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/_appengine_environ.py b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/_appengine_environ.py
    new file mode 100644
    index 0000000..8765b90
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/_appengine_environ.py
    @@ -0,0 +1,36 @@
    +"""
    +This module provides means to detect the App Engine environment.
    +"""
    +
    +import os
    +
    +
    +def is_appengine():
    +    return is_local_appengine() or is_prod_appengine()
    +
    +
    +def is_appengine_sandbox():
    +    """Reports if the app is running in the first generation sandbox.
    +
    +    The second generation runtimes are technically still in a sandbox, but it
    +    is much less restrictive, so generally you shouldn't need to check for it.
    +    see https://cloud.google.com/appengine/docs/standard/runtimes
    +    """
    +    return is_appengine() and os.environ["APPENGINE_RUNTIME"] == "python27"
    +
    +
    +def is_local_appengine():
    +    return "APPENGINE_RUNTIME" in os.environ and os.environ.get(
    +        "SERVER_SOFTWARE", ""
    +    ).startswith("Development/")
    +
    +
    +def is_prod_appengine():
    +    return "APPENGINE_RUNTIME" in os.environ and os.environ.get(
    +        "SERVER_SOFTWARE", ""
    +    ).startswith("Google App Engine/")
    +
    +
    +def is_prod_appengine_mvms():
    +    """Deprecated."""
    +    return False
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/_securetransport/__init__.py b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/_securetransport/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/_securetransport/bindings.py b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/_securetransport/bindings.py
    new file mode 100644
    index 0000000..264d564
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/_securetransport/bindings.py
    @@ -0,0 +1,519 @@
    +"""
    +This module uses ctypes to bind a whole bunch of functions and constants from
    +SecureTransport. The goal here is to provide the low-level API to
    +SecureTransport. These are essentially the C-level functions and constants, and
    +they're pretty gross to work with.
    +
    +This code is a bastardised version of the code found in Will Bond's oscrypto
    +library. An enormous debt is owed to him for blazing this trail for us. For
    +that reason, this code should be considered to be covered both by urllib3's
    +license and by oscrypto's:
    +
    +    Copyright (c) 2015-2016 Will Bond <will@wbond.net>
    +
    +    Permission is hereby granted, free of charge, to any person obtaining a
    +    copy of this software and associated documentation files (the "Software"),
    +    to deal in the Software without restriction, including without limitation
    +    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    +    and/or sell copies of the Software, and to permit persons to whom the
    +    Software is furnished to do so, subject to the following conditions:
    +
    +    The above copyright notice and this permission notice shall be included in
    +    all copies or substantial portions of the Software.
    +
    +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    +    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    +    DEALINGS IN THE SOFTWARE.
    +"""
    +from __future__ import absolute_import
    +
    +import platform
    +from ctypes import (
    +    CDLL,
    +    CFUNCTYPE,
    +    POINTER,
    +    c_bool,
    +    c_byte,
    +    c_char_p,
    +    c_int32,
    +    c_long,
    +    c_size_t,
    +    c_uint32,
    +    c_ulong,
    +    c_void_p,
    +)
    +from ctypes.util import find_library
    +
    +from ...packages.six import raise_from
    +
    +if platform.system() != "Darwin":
    +    raise ImportError("Only macOS is supported")
    +
    +version = platform.mac_ver()[0]
    +version_info = tuple(map(int, version.split(".")))
    +if version_info < (10, 8):
    +    raise OSError(
    +        "Only OS X 10.8 and newer are supported, not %s.%s"
    +        % (version_info[0], version_info[1])
    +    )
    +
    +
    +def load_cdll(name, macos10_16_path):
    +    """Loads a CDLL by name, falling back to known path on 10.16+"""
    +    try:
    +        # Big Sur is technically 11 but we use 10.16 due to the Big Sur
    +        # beta being labeled as 10.16.
    +        if version_info >= (10, 16):
    +            path = macos10_16_path
    +        else:
    +            path = find_library(name)
    +        if not path:
    +            raise OSError  # Caught and reraised as 'ImportError'
    +        return CDLL(path, use_errno=True)
    +    except OSError:
    +        raise_from(ImportError("The library %s failed to load" % name), None)
    +
    +
    +Security = load_cdll(
    +    "Security", "/System/Library/Frameworks/Security.framework/Security"
    +)
    +CoreFoundation = load_cdll(
    +    "CoreFoundation",
    +    "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation",
    +)
    +
    +
    +Boolean = c_bool
    +CFIndex = c_long
    +CFStringEncoding = c_uint32
    +CFData = c_void_p
    +CFString = c_void_p
    +CFArray = c_void_p
    +CFMutableArray = c_void_p
    +CFDictionary = c_void_p
    +CFError = c_void_p
    +CFType = c_void_p
    +CFTypeID = c_ulong
    +
    +CFTypeRef = POINTER(CFType)
    +CFAllocatorRef = c_void_p
    +
    +OSStatus = c_int32
    +
    +CFDataRef = POINTER(CFData)
    +CFStringRef = POINTER(CFString)
    +CFArrayRef = POINTER(CFArray)
    +CFMutableArrayRef = POINTER(CFMutableArray)
    +CFDictionaryRef = POINTER(CFDictionary)
    +CFArrayCallBacks = c_void_p
    +CFDictionaryKeyCallBacks = c_void_p
    +CFDictionaryValueCallBacks = c_void_p
    +
    +SecCertificateRef = POINTER(c_void_p)
    +SecExternalFormat = c_uint32
    +SecExternalItemType = c_uint32
    +SecIdentityRef = POINTER(c_void_p)
    +SecItemImportExportFlags = c_uint32
    +SecItemImportExportKeyParameters = c_void_p
    +SecKeychainRef = POINTER(c_void_p)
    +SSLProtocol = c_uint32
    +SSLCipherSuite = c_uint32
    +SSLContextRef = POINTER(c_void_p)
    +SecTrustRef = POINTER(c_void_p)
    +SSLConnectionRef = c_uint32
    +SecTrustResultType = c_uint32
    +SecTrustOptionFlags = c_uint32
    +SSLProtocolSide = c_uint32
    +SSLConnectionType = c_uint32
    +SSLSessionOption = c_uint32
    +
    +
    +try:
    +    Security.SecItemImport.argtypes = [
    +        CFDataRef,
    +        CFStringRef,
    +        POINTER(SecExternalFormat),
    +        POINTER(SecExternalItemType),
    +        SecItemImportExportFlags,
    +        POINTER(SecItemImportExportKeyParameters),
    +        SecKeychainRef,
    +        POINTER(CFArrayRef),
    +    ]
    +    Security.SecItemImport.restype = OSStatus
    +
    +    Security.SecCertificateGetTypeID.argtypes = []
    +    Security.SecCertificateGetTypeID.restype = CFTypeID
    +
    +    Security.SecIdentityGetTypeID.argtypes = []
    +    Security.SecIdentityGetTypeID.restype = CFTypeID
    +
    +    Security.SecKeyGetTypeID.argtypes = []
    +    Security.SecKeyGetTypeID.restype = CFTypeID
    +
    +    Security.SecCertificateCreateWithData.argtypes = [CFAllocatorRef, CFDataRef]
    +    Security.SecCertificateCreateWithData.restype = SecCertificateRef
    +
    +    Security.SecCertificateCopyData.argtypes = [SecCertificateRef]
    +    Security.SecCertificateCopyData.restype = CFDataRef
    +
    +    Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p]
    +    Security.SecCopyErrorMessageString.restype = CFStringRef
    +
    +    Security.SecIdentityCreateWithCertificate.argtypes = [
    +        CFTypeRef,
    +        SecCertificateRef,
    +        POINTER(SecIdentityRef),
    +    ]
    +    Security.SecIdentityCreateWithCertificate.restype = OSStatus
    +
    +    Security.SecKeychainCreate.argtypes = [
    +        c_char_p,
    +        c_uint32,
    +        c_void_p,
    +        Boolean,
    +        c_void_p,
    +        POINTER(SecKeychainRef),
    +    ]
    +    Security.SecKeychainCreate.restype = OSStatus
    +
    +    Security.SecKeychainDelete.argtypes = [SecKeychainRef]
    +    Security.SecKeychainDelete.restype = OSStatus
    +
    +    Security.SecPKCS12Import.argtypes = [
    +        CFDataRef,
    +        CFDictionaryRef,
    +        POINTER(CFArrayRef),
    +    ]
    +    Security.SecPKCS12Import.restype = OSStatus
    +
    +    SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t))
    +    SSLWriteFunc = CFUNCTYPE(
    +        OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)
    +    )
    +
    +    Security.SSLSetIOFuncs.argtypes = [SSLContextRef, SSLReadFunc, SSLWriteFunc]
    +    Security.SSLSetIOFuncs.restype = OSStatus
    +
    +    Security.SSLSetPeerID.argtypes = [SSLContextRef, c_char_p, c_size_t]
    +    Security.SSLSetPeerID.restype = OSStatus
    +
    +    Security.SSLSetCertificate.argtypes = [SSLContextRef, CFArrayRef]
    +    Security.SSLSetCertificate.restype = OSStatus
    +
    +    Security.SSLSetCertificateAuthorities.argtypes = [SSLContextRef, CFTypeRef, Boolean]
    +    Security.SSLSetCertificateAuthorities.restype = OSStatus
    +
    +    Security.SSLSetConnection.argtypes = [SSLContextRef, SSLConnectionRef]
    +    Security.SSLSetConnection.restype = OSStatus
    +
    +    Security.SSLSetPeerDomainName.argtypes = [SSLContextRef, c_char_p, c_size_t]
    +    Security.SSLSetPeerDomainName.restype = OSStatus
    +
    +    Security.SSLHandshake.argtypes = [SSLContextRef]
    +    Security.SSLHandshake.restype = OSStatus
    +
    +    Security.SSLRead.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)]
    +    Security.SSLRead.restype = OSStatus
    +
    +    Security.SSLWrite.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)]
    +    Security.SSLWrite.restype = OSStatus
    +
    +    Security.SSLClose.argtypes = [SSLContextRef]
    +    Security.SSLClose.restype = OSStatus
    +
    +    Security.SSLGetNumberSupportedCiphers.argtypes = [SSLContextRef, POINTER(c_size_t)]
    +    Security.SSLGetNumberSupportedCiphers.restype = OSStatus
    +
    +    Security.SSLGetSupportedCiphers.argtypes = [
    +        SSLContextRef,
    +        POINTER(SSLCipherSuite),
    +        POINTER(c_size_t),
    +    ]
    +    Security.SSLGetSupportedCiphers.restype = OSStatus
    +
    +    Security.SSLSetEnabledCiphers.argtypes = [
    +        SSLContextRef,
    +        POINTER(SSLCipherSuite),
    +        c_size_t,
    +    ]
    +    Security.SSLSetEnabledCiphers.restype = OSStatus
    +
    +    Security.SSLGetNumberEnabledCiphers.argtype = [SSLContextRef, POINTER(c_size_t)]
    +    Security.SSLGetNumberEnabledCiphers.restype = OSStatus
    +
    +    Security.SSLGetEnabledCiphers.argtypes = [
    +        SSLContextRef,
    +        POINTER(SSLCipherSuite),
    +        POINTER(c_size_t),
    +    ]
    +    Security.SSLGetEnabledCiphers.restype = OSStatus
    +
    +    Security.SSLGetNegotiatedCipher.argtypes = [SSLContextRef, POINTER(SSLCipherSuite)]
    +    Security.SSLGetNegotiatedCipher.restype = OSStatus
    +
    +    Security.SSLGetNegotiatedProtocolVersion.argtypes = [
    +        SSLContextRef,
    +        POINTER(SSLProtocol),
    +    ]
    +    Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus
    +
    +    Security.SSLCopyPeerTrust.argtypes = [SSLContextRef, POINTER(SecTrustRef)]
    +    Security.SSLCopyPeerTrust.restype = OSStatus
    +
    +    Security.SecTrustSetAnchorCertificates.argtypes = [SecTrustRef, CFArrayRef]
    +    Security.SecTrustSetAnchorCertificates.restype = OSStatus
    +
    +    Security.SecTrustSetAnchorCertificatesOnly.argstypes = [SecTrustRef, Boolean]
    +    Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus
    +
    +    Security.SecTrustEvaluate.argtypes = [SecTrustRef, POINTER(SecTrustResultType)]
    +    Security.SecTrustEvaluate.restype = OSStatus
    +
    +    Security.SecTrustGetCertificateCount.argtypes = [SecTrustRef]
    +    Security.SecTrustGetCertificateCount.restype = CFIndex
    +
    +    Security.SecTrustGetCertificateAtIndex.argtypes = [SecTrustRef, CFIndex]
    +    Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef
    +
    +    Security.SSLCreateContext.argtypes = [
    +        CFAllocatorRef,
    +        SSLProtocolSide,
    +        SSLConnectionType,
    +    ]
    +    Security.SSLCreateContext.restype = SSLContextRef
    +
    +    Security.SSLSetSessionOption.argtypes = [SSLContextRef, SSLSessionOption, Boolean]
    +    Security.SSLSetSessionOption.restype = OSStatus
    +
    +    Security.SSLSetProtocolVersionMin.argtypes = [SSLContextRef, SSLProtocol]
    +    Security.SSLSetProtocolVersionMin.restype = OSStatus
    +
    +    Security.SSLSetProtocolVersionMax.argtypes = [SSLContextRef, SSLProtocol]
    +    Security.SSLSetProtocolVersionMax.restype = OSStatus
    +
    +    try:
    +        Security.SSLSetALPNProtocols.argtypes = [SSLContextRef, CFArrayRef]
    +        Security.SSLSetALPNProtocols.restype = OSStatus
    +    except AttributeError:
    +        # Supported only in 10.12+
    +        pass
    +
    +    Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p]
    +    Security.SecCopyErrorMessageString.restype = CFStringRef
    +
    +    Security.SSLReadFunc = SSLReadFunc
    +    Security.SSLWriteFunc = SSLWriteFunc
    +    Security.SSLContextRef = SSLContextRef
    +    Security.SSLProtocol = SSLProtocol
    +    Security.SSLCipherSuite = SSLCipherSuite
    +    Security.SecIdentityRef = SecIdentityRef
    +    Security.SecKeychainRef = SecKeychainRef
    +    Security.SecTrustRef = SecTrustRef
    +    Security.SecTrustResultType = SecTrustResultType
    +    Security.SecExternalFormat = SecExternalFormat
    +    Security.OSStatus = OSStatus
    +
    +    Security.kSecImportExportPassphrase = CFStringRef.in_dll(
    +        Security, "kSecImportExportPassphrase"
    +    )
    +    Security.kSecImportItemIdentity = CFStringRef.in_dll(
    +        Security, "kSecImportItemIdentity"
    +    )
    +
    +    # CoreFoundation time!
    +    CoreFoundation.CFRetain.argtypes = [CFTypeRef]
    +    CoreFoundation.CFRetain.restype = CFTypeRef
    +
    +    CoreFoundation.CFRelease.argtypes = [CFTypeRef]
    +    CoreFoundation.CFRelease.restype = None
    +
    +    CoreFoundation.CFGetTypeID.argtypes = [CFTypeRef]
    +    CoreFoundation.CFGetTypeID.restype = CFTypeID
    +
    +    CoreFoundation.CFStringCreateWithCString.argtypes = [
    +        CFAllocatorRef,
    +        c_char_p,
    +        CFStringEncoding,
    +    ]
    +    CoreFoundation.CFStringCreateWithCString.restype = CFStringRef
    +
    +    CoreFoundation.CFStringGetCStringPtr.argtypes = [CFStringRef, CFStringEncoding]
    +    CoreFoundation.CFStringGetCStringPtr.restype = c_char_p
    +
    +    CoreFoundation.CFStringGetCString.argtypes = [
    +        CFStringRef,
    +        c_char_p,
    +        CFIndex,
    +        CFStringEncoding,
    +    ]
    +    CoreFoundation.CFStringGetCString.restype = c_bool
    +
    +    CoreFoundation.CFDataCreate.argtypes = [CFAllocatorRef, c_char_p, CFIndex]
    +    CoreFoundation.CFDataCreate.restype = CFDataRef
    +
    +    CoreFoundation.CFDataGetLength.argtypes = [CFDataRef]
    +    CoreFoundation.CFDataGetLength.restype = CFIndex
    +
    +    CoreFoundation.CFDataGetBytePtr.argtypes = [CFDataRef]
    +    CoreFoundation.CFDataGetBytePtr.restype = c_void_p
    +
    +    CoreFoundation.CFDictionaryCreate.argtypes = [
    +        CFAllocatorRef,
    +        POINTER(CFTypeRef),
    +        POINTER(CFTypeRef),
    +        CFIndex,
    +        CFDictionaryKeyCallBacks,
    +        CFDictionaryValueCallBacks,
    +    ]
    +    CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef
    +
    +    CoreFoundation.CFDictionaryGetValue.argtypes = [CFDictionaryRef, CFTypeRef]
    +    CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef
    +
    +    CoreFoundation.CFArrayCreate.argtypes = [
    +        CFAllocatorRef,
    +        POINTER(CFTypeRef),
    +        CFIndex,
    +        CFArrayCallBacks,
    +    ]
    +    CoreFoundation.CFArrayCreate.restype = CFArrayRef
    +
    +    CoreFoundation.CFArrayCreateMutable.argtypes = [
    +        CFAllocatorRef,
    +        CFIndex,
    +        CFArrayCallBacks,
    +    ]
    +    CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef
    +
    +    CoreFoundation.CFArrayAppendValue.argtypes = [CFMutableArrayRef, c_void_p]
    +    CoreFoundation.CFArrayAppendValue.restype = None
    +
    +    CoreFoundation.CFArrayGetCount.argtypes = [CFArrayRef]
    +    CoreFoundation.CFArrayGetCount.restype = CFIndex
    +
    +    CoreFoundation.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex]
    +    CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p
    +
    +    CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll(
    +        CoreFoundation, "kCFAllocatorDefault"
    +    )
    +    CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(
    +        CoreFoundation, "kCFTypeArrayCallBacks"
    +    )
    +    CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll(
    +        CoreFoundation, "kCFTypeDictionaryKeyCallBacks"
    +    )
    +    CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll(
    +        CoreFoundation, "kCFTypeDictionaryValueCallBacks"
    +    )
    +
    +    CoreFoundation.CFTypeRef = CFTypeRef
    +    CoreFoundation.CFArrayRef = CFArrayRef
    +    CoreFoundation.CFStringRef = CFStringRef
    +    CoreFoundation.CFDictionaryRef = CFDictionaryRef
    +
    +except (AttributeError):
    +    raise ImportError("Error initializing ctypes")
    +
    +
    +class CFConst(object):
    +    """
    +    A class object that acts as essentially a namespace for CoreFoundation
    +    constants.
    +    """
    +
    +    kCFStringEncodingUTF8 = CFStringEncoding(0x08000100)
    +
    +
    +class SecurityConst(object):
    +    """
    +    A class object that acts as essentially a namespace for Security constants.
    +    """
    +
    +    kSSLSessionOptionBreakOnServerAuth = 0
    +
    +    kSSLProtocol2 = 1
    +    kSSLProtocol3 = 2
    +    kTLSProtocol1 = 4
    +    kTLSProtocol11 = 7
    +    kTLSProtocol12 = 8
    +    # SecureTransport does not support TLS 1.3 even if there's a constant for it
    +    kTLSProtocol13 = 10
    +    kTLSProtocolMaxSupported = 999
    +
    +    kSSLClientSide = 1
    +    kSSLStreamType = 0
    +
    +    kSecFormatPEMSequence = 10
    +
    +    kSecTrustResultInvalid = 0
    +    kSecTrustResultProceed = 1
    +    # This gap is present on purpose: this was kSecTrustResultConfirm, which
    +    # is deprecated.
    +    kSecTrustResultDeny = 3
    +    kSecTrustResultUnspecified = 4
    +    kSecTrustResultRecoverableTrustFailure = 5
    +    kSecTrustResultFatalTrustFailure = 6
    +    kSecTrustResultOtherError = 7
    +
    +    errSSLProtocol = -9800
    +    errSSLWouldBlock = -9803
    +    errSSLClosedGraceful = -9805
    +    errSSLClosedNoNotify = -9816
    +    errSSLClosedAbort = -9806
    +
    +    errSSLXCertChainInvalid = -9807
    +    errSSLCrypto = -9809
    +    errSSLInternal = -9810
    +    errSSLCertExpired = -9814
    +    errSSLCertNotYetValid = -9815
    +    errSSLUnknownRootCert = -9812
    +    errSSLNoRootCert = -9813
    +    errSSLHostNameMismatch = -9843
    +    errSSLPeerHandshakeFail = -9824
    +    errSSLPeerUserCancelled = -9839
    +    errSSLWeakPeerEphemeralDHKey = -9850
    +    errSSLServerAuthCompleted = -9841
    +    errSSLRecordOverflow = -9847
    +
    +    errSecVerifyFailed = -67808
    +    errSecNoTrustSettings = -25263
    +    errSecItemNotFound = -25300
    +    errSecInvalidTrustSettings = -25262
    +
    +    # Cipher suites. We only pick the ones our default cipher string allows.
    +    # Source: https://developer.apple.com/documentation/security/1550981-ssl_cipher_suite_values
    +    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C
    +    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030
    +    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B
    +    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F
    +    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9
    +    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8
    +    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F
    +    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E
    +    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024
    +    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028
    +    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A
    +    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014
    +    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B
    +    TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039
    +    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023
    +    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027
    +    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009
    +    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013
    +    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067
    +    TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033
    +    TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D
    +    TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C
    +    TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D
    +    TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C
    +    TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035
    +    TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F
    +    TLS_AES_128_GCM_SHA256 = 0x1301
    +    TLS_AES_256_GCM_SHA384 = 0x1302
    +    TLS_AES_128_CCM_8_SHA256 = 0x1305
    +    TLS_AES_128_CCM_SHA256 = 0x1304
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/_securetransport/low_level.py b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/_securetransport/low_level.py
    new file mode 100644
    index 0000000..fa0b245
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/_securetransport/low_level.py
    @@ -0,0 +1,397 @@
    +"""
    +Low-level helpers for the SecureTransport bindings.
    +
    +These are Python functions that are not directly related to the high-level APIs
    +but are necessary to get them to work. They include a whole bunch of low-level
    +CoreFoundation messing about and memory management. The concerns in this module
    +are almost entirely about trying to avoid memory leaks and providing
    +appropriate and useful assistance to the higher-level code.
    +"""
    +import base64
    +import ctypes
    +import itertools
    +import os
    +import re
    +import ssl
    +import struct
    +import tempfile
    +
    +from .bindings import CFConst, CoreFoundation, Security
    +
    +# This regular expression is used to grab PEM data out of a PEM bundle.
    +_PEM_CERTS_RE = re.compile(
    +    b"-----BEGIN CERTIFICATE-----\n(.*?)\n-----END CERTIFICATE-----", re.DOTALL
    +)
    +
    +
    +def _cf_data_from_bytes(bytestring):
    +    """
    +    Given a bytestring, create a CFData object from it. This CFData object must
    +    be CFReleased by the caller.
    +    """
    +    return CoreFoundation.CFDataCreate(
    +        CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring)
    +    )
    +
    +
    +def _cf_dictionary_from_tuples(tuples):
    +    """
    +    Given a list of Python tuples, create an associated CFDictionary.
    +    """
    +    dictionary_size = len(tuples)
    +
    +    # We need to get the dictionary keys and values out in the same order.
    +    keys = (t[0] for t in tuples)
    +    values = (t[1] for t in tuples)
    +    cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys)
    +    cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values)
    +
    +    return CoreFoundation.CFDictionaryCreate(
    +        CoreFoundation.kCFAllocatorDefault,
    +        cf_keys,
    +        cf_values,
    +        dictionary_size,
    +        CoreFoundation.kCFTypeDictionaryKeyCallBacks,
    +        CoreFoundation.kCFTypeDictionaryValueCallBacks,
    +    )
    +
    +
    +def _cfstr(py_bstr):
    +    """
    +    Given a Python binary data, create a CFString.
    +    The string must be CFReleased by the caller.
    +    """
    +    c_str = ctypes.c_char_p(py_bstr)
    +    cf_str = CoreFoundation.CFStringCreateWithCString(
    +        CoreFoundation.kCFAllocatorDefault,
    +        c_str,
    +        CFConst.kCFStringEncodingUTF8,
    +    )
    +    return cf_str
    +
    +
    +def _create_cfstring_array(lst):
    +    """
    +    Given a list of Python binary data, create an associated CFMutableArray.
    +    The array must be CFReleased by the caller.
    +
    +    Raises an ssl.SSLError on failure.
    +    """
    +    cf_arr = None
    +    try:
    +        cf_arr = CoreFoundation.CFArrayCreateMutable(
    +            CoreFoundation.kCFAllocatorDefault,
    +            0,
    +            ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks),
    +        )
    +        if not cf_arr:
    +            raise MemoryError("Unable to allocate memory!")
    +        for item in lst:
    +            cf_str = _cfstr(item)
    +            if not cf_str:
    +                raise MemoryError("Unable to allocate memory!")
    +            try:
    +                CoreFoundation.CFArrayAppendValue(cf_arr, cf_str)
    +            finally:
    +                CoreFoundation.CFRelease(cf_str)
    +    except BaseException as e:
    +        if cf_arr:
    +            CoreFoundation.CFRelease(cf_arr)
    +        raise ssl.SSLError("Unable to allocate array: %s" % (e,))
    +    return cf_arr
    +
    +
    +def _cf_string_to_unicode(value):
    +    """
    +    Creates a Unicode string from a CFString object. Used entirely for error
    +    reporting.
    +
    +    Yes, it annoys me quite a lot that this function is this complex.
    +    """
    +    value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p))
    +
    +    string = CoreFoundation.CFStringGetCStringPtr(
    +        value_as_void_p, CFConst.kCFStringEncodingUTF8
    +    )
    +    if string is None:
    +        buffer = ctypes.create_string_buffer(1024)
    +        result = CoreFoundation.CFStringGetCString(
    +            value_as_void_p, buffer, 1024, CFConst.kCFStringEncodingUTF8
    +        )
    +        if not result:
    +            raise OSError("Error copying C string from CFStringRef")
    +        string = buffer.value
    +    if string is not None:
    +        string = string.decode("utf-8")
    +    return string
    +
    +
    +def _assert_no_error(error, exception_class=None):
    +    """
    +    Checks the return code and throws an exception if there is an error to
    +    report
    +    """
    +    if error == 0:
    +        return
    +
    +    cf_error_string = Security.SecCopyErrorMessageString(error, None)
    +    output = _cf_string_to_unicode(cf_error_string)
    +    CoreFoundation.CFRelease(cf_error_string)
    +
    +    if output is None or output == u"":
    +        output = u"OSStatus %s" % error
    +
    +    if exception_class is None:
    +        exception_class = ssl.SSLError
    +
    +    raise exception_class(output)
    +
    +
    +def _cert_array_from_pem(pem_bundle):
    +    """
    +    Given a bundle of certs in PEM format, turns them into a CFArray of certs
    +    that can be used to validate a cert chain.
    +    """
    +    # Normalize the PEM bundle's line endings.
    +    pem_bundle = pem_bundle.replace(b"\r\n", b"\n")
    +
    +    der_certs = [
    +        base64.b64decode(match.group(1)) for match in _PEM_CERTS_RE.finditer(pem_bundle)
    +    ]
    +    if not der_certs:
    +        raise ssl.SSLError("No root certificates specified")
    +
    +    cert_array = CoreFoundation.CFArrayCreateMutable(
    +        CoreFoundation.kCFAllocatorDefault,
    +        0,
    +        ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks),
    +    )
    +    if not cert_array:
    +        raise ssl.SSLError("Unable to allocate memory!")
    +
    +    try:
    +        for der_bytes in der_certs:
    +            certdata = _cf_data_from_bytes(der_bytes)
    +            if not certdata:
    +                raise ssl.SSLError("Unable to allocate memory!")
    +            cert = Security.SecCertificateCreateWithData(
    +                CoreFoundation.kCFAllocatorDefault, certdata
    +            )
    +            CoreFoundation.CFRelease(certdata)
    +            if not cert:
    +                raise ssl.SSLError("Unable to build cert object!")
    +
    +            CoreFoundation.CFArrayAppendValue(cert_array, cert)
    +            CoreFoundation.CFRelease(cert)
    +    except Exception:
    +        # We need to free the array before the exception bubbles further.
    +        # We only want to do that if an error occurs: otherwise, the caller
    +        # should free.
    +        CoreFoundation.CFRelease(cert_array)
    +        raise
    +
    +    return cert_array
    +
    +
    +def _is_cert(item):
    +    """
    +    Returns True if a given CFTypeRef is a certificate.
    +    """
    +    expected = Security.SecCertificateGetTypeID()
    +    return CoreFoundation.CFGetTypeID(item) == expected
    +
    +
    +def _is_identity(item):
    +    """
    +    Returns True if a given CFTypeRef is an identity.
    +    """
    +    expected = Security.SecIdentityGetTypeID()
    +    return CoreFoundation.CFGetTypeID(item) == expected
    +
    +
    +def _temporary_keychain():
    +    """
    +    This function creates a temporary Mac keychain that we can use to work with
    +    credentials. This keychain uses a one-time password and a temporary file to
    +    store the data. We expect to have one keychain per socket. The returned
    +    SecKeychainRef must be freed by the caller, including calling
    +    SecKeychainDelete.
    +
    +    Returns a tuple of the SecKeychainRef and the path to the temporary
    +    directory that contains it.
    +    """
    +    # Unfortunately, SecKeychainCreate requires a path to a keychain. This
    +    # means we cannot use mkstemp to use a generic temporary file. Instead,
    +    # we're going to create a temporary directory and a filename to use there.
    +    # This filename will be 8 random bytes expanded into base64. We also need
    +    # some random bytes to password-protect the keychain we're creating, so we
    +    # ask for 40 random bytes.
    +    random_bytes = os.urandom(40)
    +    filename = base64.b16encode(random_bytes[:8]).decode("utf-8")
    +    password = base64.b16encode(random_bytes[8:])  # Must be valid UTF-8
    +    tempdirectory = tempfile.mkdtemp()
    +
    +    keychain_path = os.path.join(tempdirectory, filename).encode("utf-8")
    +
    +    # We now want to create the keychain itself.
    +    keychain = Security.SecKeychainRef()
    +    status = Security.SecKeychainCreate(
    +        keychain_path, len(password), password, False, None, ctypes.byref(keychain)
    +    )
    +    _assert_no_error(status)
    +
    +    # Having created the keychain, we want to pass it off to the caller.
    +    return keychain, tempdirectory
    +
    +
    +def _load_items_from_file(keychain, path):
    +    """
    +    Given a single file, loads all the trust objects from it into arrays and
    +    the keychain.
    +    Returns a tuple of lists: the first list is a list of identities, the
    +    second a list of certs.
    +    """
    +    certificates = []
    +    identities = []
    +    result_array = None
    +
    +    with open(path, "rb") as f:
    +        raw_filedata = f.read()
    +
    +    try:
    +        filedata = CoreFoundation.CFDataCreate(
    +            CoreFoundation.kCFAllocatorDefault, raw_filedata, len(raw_filedata)
    +        )
    +        result_array = CoreFoundation.CFArrayRef()
    +        result = Security.SecItemImport(
    +            filedata,  # cert data
    +            None,  # Filename, leaving it out for now
    +            None,  # What the type of the file is, we don't care
    +            None,  # what's in the file, we don't care
    +            0,  # import flags
    +            None,  # key params, can include passphrase in the future
    +            keychain,  # The keychain to insert into
    +            ctypes.byref(result_array),  # Results
    +        )
    +        _assert_no_error(result)
    +
    +        # A CFArray is not very useful to us as an intermediary
    +        # representation, so we are going to extract the objects we want
    +        # and then free the array. We don't need to keep hold of keys: the
    +        # keychain already has them!
    +        result_count = CoreFoundation.CFArrayGetCount(result_array)
    +        for index in range(result_count):
    +            item = CoreFoundation.CFArrayGetValueAtIndex(result_array, index)
    +            item = ctypes.cast(item, CoreFoundation.CFTypeRef)
    +
    +            if _is_cert(item):
    +                CoreFoundation.CFRetain(item)
    +                certificates.append(item)
    +            elif _is_identity(item):
    +                CoreFoundation.CFRetain(item)
    +                identities.append(item)
    +    finally:
    +        if result_array:
    +            CoreFoundation.CFRelease(result_array)
    +
    +        CoreFoundation.CFRelease(filedata)
    +
    +    return (identities, certificates)
    +
    +
    +def _load_client_cert_chain(keychain, *paths):
    +    """
    +    Load certificates and maybe keys from a number of files. Has the end goal
    +    of returning a CFArray containing one SecIdentityRef, and then zero or more
    +    SecCertificateRef objects, suitable for use as a client certificate trust
    +    chain.
    +    """
    +    # Ok, the strategy.
    +    #
    +    # This relies on knowing that macOS will not give you a SecIdentityRef
    +    # unless you have imported a key into a keychain. This is a somewhat
    +    # artificial limitation of macOS (for example, it doesn't necessarily
    +    # affect iOS), but there is nothing inside Security.framework that lets you
    +    # get a SecIdentityRef without having a key in a keychain.
    +    #
    +    # So the policy here is we take all the files and iterate them in order.
    +    # Each one will use SecItemImport to have one or more objects loaded from
    +    # it. We will also point at a keychain that macOS can use to work with the
    +    # private key.
    +    #
    +    # Once we have all the objects, we'll check what we actually have. If we
    +    # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise,
    +    # we'll take the first certificate (which we assume to be our leaf) and
    +    # ask the keychain to give us a SecIdentityRef with that cert's associated
    +    # key.
    +    #
    +    # We'll then return a CFArray containing the trust chain: one
    +    # SecIdentityRef and then zero-or-more SecCertificateRef objects. The
    +    # responsibility for freeing this CFArray will be with the caller. This
    +    # CFArray must remain alive for the entire connection, so in practice it
    +    # will be stored with a single SSLSocket, along with the reference to the
    +    # keychain.
    +    certificates = []
    +    identities = []
    +
    +    # Filter out bad paths.
    +    paths = (path for path in paths if path)
    +
    +    try:
    +        for file_path in paths:
    +            new_identities, new_certs = _load_items_from_file(keychain, file_path)
    +            identities.extend(new_identities)
    +            certificates.extend(new_certs)
    +
    +        # Ok, we have everything. The question is: do we have an identity? If
    +        # not, we want to grab one from the first cert we have.
    +        if not identities:
    +            new_identity = Security.SecIdentityRef()
    +            status = Security.SecIdentityCreateWithCertificate(
    +                keychain, certificates[0], ctypes.byref(new_identity)
    +            )
    +            _assert_no_error(status)
    +            identities.append(new_identity)
    +
    +            # We now want to release the original certificate, as we no longer
    +            # need it.
    +            CoreFoundation.CFRelease(certificates.pop(0))
    +
    +        # We now need to build a new CFArray that holds the trust chain.
    +        trust_chain = CoreFoundation.CFArrayCreateMutable(
    +            CoreFoundation.kCFAllocatorDefault,
    +            0,
    +            ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks),
    +        )
    +        for item in itertools.chain(identities, certificates):
    +            # ArrayAppendValue does a CFRetain on the item. That's fine,
    +            # because the finally block will release our other refs to them.
    +            CoreFoundation.CFArrayAppendValue(trust_chain, item)
    +
    +        return trust_chain
    +    finally:
    +        for obj in itertools.chain(identities, certificates):
    +            CoreFoundation.CFRelease(obj)
    +
    +
    +TLS_PROTOCOL_VERSIONS = {
    +    "SSLv2": (0, 2),
    +    "SSLv3": (3, 0),
    +    "TLSv1": (3, 1),
    +    "TLSv1.1": (3, 2),
    +    "TLSv1.2": (3, 3),
    +}
    +
    +
    +def _build_tls_unknown_ca_alert(version):
    +    """
    +    Builds a TLS alert record for an unknown CA.
    +    """
    +    ver_maj, ver_min = TLS_PROTOCOL_VERSIONS[version]
    +    severity_fatal = 0x02
    +    description_unknown_ca = 0x30
    +    msg = struct.pack(">BB", severity_fatal, description_unknown_ca)
    +    msg_len = len(msg)
    +    record_type_alert = 0x15
    +    record = struct.pack(">BBBH", record_type_alert, ver_maj, ver_min, msg_len) + msg
    +    return record
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/appengine.py b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/appengine.py
    new file mode 100644
    index 0000000..a5a6d91
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/appengine.py
    @@ -0,0 +1,314 @@
    +"""
    +This module provides a pool manager that uses Google App Engine's
    +`URLFetch Service <https://cloud.google.com/appengine/docs/python/urlfetch>`_.
    +
    +Example usage::
    +
    +    from urllib3 import PoolManager
    +    from urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox
    +
    +    if is_appengine_sandbox():
    +        # AppEngineManager uses AppEngine's URLFetch API behind the scenes
    +        http = AppEngineManager()
    +    else:
    +        # PoolManager uses a socket-level API behind the scenes
    +        http = PoolManager()
    +
    +    r = http.request('GET', 'https://google.com/')
    +
    +There are `limitations <https://cloud.google.com/appengine/docs/python/\
    +urlfetch/#Python_Quotas_and_limits>`_ to the URLFetch service and it may not be
    +the best choice for your application. There are three options for using
    +urllib3 on Google App Engine:
    +
    +1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is
    +   cost-effective in many circumstances as long as your usage is within the
    +   limitations.
    +2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets.
    +   Sockets also have `limitations and restrictions
    +   <https://cloud.google.com/appengine/docs/python/sockets/\
    +   #limitations-and-restrictions>`_ and have a lower free quota than URLFetch.
    +   To use sockets, be sure to specify the following in your ``app.yaml``::
    +
    +        env_variables:
    +            GAE_USE_SOCKETS_HTTPLIB : 'true'
    +
    +3. If you are using `App Engine Flexible
    +<https://cloud.google.com/appengine/docs/flexible/>`_, you can use the standard
    +:class:`PoolManager` without any configuration or special environment variables.
    +"""
    +
    +from __future__ import absolute_import
    +
    +import io
    +import logging
    +import warnings
    +
    +from ..exceptions import (
    +    HTTPError,
    +    HTTPWarning,
    +    MaxRetryError,
    +    ProtocolError,
    +    SSLError,
    +    TimeoutError,
    +)
    +from ..packages.six.moves.urllib.parse import urljoin
    +from ..request import RequestMethods
    +from ..response import HTTPResponse
    +from ..util.retry import Retry
    +from ..util.timeout import Timeout
    +from . import _appengine_environ
    +
    +try:
    +    from google.appengine.api import urlfetch
    +except ImportError:
    +    urlfetch = None
    +
    +
    +log = logging.getLogger(__name__)
    +
    +
    +class AppEnginePlatformWarning(HTTPWarning):
    +    pass
    +
    +
    +class AppEnginePlatformError(HTTPError):
    +    pass
    +
    +
    +class AppEngineManager(RequestMethods):
    +    """
    +    Connection manager for Google App Engine sandbox applications.
    +
    +    This manager uses the URLFetch service directly instead of using the
    +    emulated httplib, and is subject to URLFetch limitations as described in
    +    the App Engine documentation `here
    +    <https://cloud.google.com/appengine/docs/python/urlfetch>`_.
    +
    +    Notably it will raise an :class:`AppEnginePlatformError` if:
    +        * URLFetch is not available.
    +        * If you attempt to use this on App Engine Flexible, as full socket
    +          support is available.
    +        * If a request size is more than 10 megabytes.
    +        * If a response size is more than 32 megabytes.
    +        * If you use an unsupported request method such as OPTIONS.
    +
    +    Beyond those cases, it will raise normal urllib3 errors.
    +    """
    +
    +    def __init__(
    +        self,
    +        headers=None,
    +        retries=None,
    +        validate_certificate=True,
    +        urlfetch_retries=True,
    +    ):
    +        if not urlfetch:
    +            raise AppEnginePlatformError(
    +                "URLFetch is not available in this environment."
    +            )
    +
    +        warnings.warn(
    +            "urllib3 is using URLFetch on Google App Engine sandbox instead "
    +            "of sockets. To use sockets directly instead of URLFetch see "
    +            "https://urllib3.readthedocs.io/en/1.26.x/reference/urllib3.contrib.html.",
    +            AppEnginePlatformWarning,
    +        )
    +
    +        RequestMethods.__init__(self, headers)
    +        self.validate_certificate = validate_certificate
    +        self.urlfetch_retries = urlfetch_retries
    +
    +        self.retries = retries or Retry.DEFAULT
    +
    +    def __enter__(self):
    +        return self
    +
    +    def __exit__(self, exc_type, exc_val, exc_tb):
    +        # Return False to re-raise any potential exceptions
    +        return False
    +
    +    def urlopen(
    +        self,
    +        method,
    +        url,
    +        body=None,
    +        headers=None,
    +        retries=None,
    +        redirect=True,
    +        timeout=Timeout.DEFAULT_TIMEOUT,
    +        **response_kw
    +    ):
    +
    +        retries = self._get_retries(retries, redirect)
    +
    +        try:
    +            follow_redirects = redirect and retries.redirect != 0 and retries.total
    +            response = urlfetch.fetch(
    +                url,
    +                payload=body,
    +                method=method,
    +                headers=headers or {},
    +                allow_truncated=False,
    +                follow_redirects=self.urlfetch_retries and follow_redirects,
    +                deadline=self._get_absolute_timeout(timeout),
    +                validate_certificate=self.validate_certificate,
    +            )
    +        except urlfetch.DeadlineExceededError as e:
    +            raise TimeoutError(self, e)
    +
    +        except urlfetch.InvalidURLError as e:
    +            if "too large" in str(e):
    +                raise AppEnginePlatformError(
    +                    "URLFetch request too large, URLFetch only "
    +                    "supports requests up to 10mb in size.",
    +                    e,
    +                )
    +            raise ProtocolError(e)
    +
    +        except urlfetch.DownloadError as e:
    +            if "Too many redirects" in str(e):
    +                raise MaxRetryError(self, url, reason=e)
    +            raise ProtocolError(e)
    +
    +        except urlfetch.ResponseTooLargeError as e:
    +            raise AppEnginePlatformError(
    +                "URLFetch response too large, URLFetch only supports"
    +                "responses up to 32mb in size.",
    +                e,
    +            )
    +
    +        except urlfetch.SSLCertificateError as e:
    +            raise SSLError(e)
    +
    +        except urlfetch.InvalidMethodError as e:
    +            raise AppEnginePlatformError(
    +                "URLFetch does not support method: %s" % method, e
    +            )
    +
    +        http_response = self._urlfetch_response_to_http_response(
    +            response, retries=retries, **response_kw
    +        )
    +
    +        # Handle redirect?
    +        redirect_location = redirect and http_response.get_redirect_location()
    +        if redirect_location:
    +            # Check for redirect response
    +            if self.urlfetch_retries and retries.raise_on_redirect:
    +                raise MaxRetryError(self, url, "too many redirects")
    +            else:
    +                if http_response.status == 303:
    +                    method = "GET"
    +
    +                try:
    +                    retries = retries.increment(
    +                        method, url, response=http_response, _pool=self
    +                    )
    +                except MaxRetryError:
    +                    if retries.raise_on_redirect:
    +                        raise MaxRetryError(self, url, "too many redirects")
    +                    return http_response
    +
    +                retries.sleep_for_retry(http_response)
    +                log.debug("Redirecting %s -> %s", url, redirect_location)
    +                redirect_url = urljoin(url, redirect_location)
    +                return self.urlopen(
    +                    method,
    +                    redirect_url,
    +                    body,
    +                    headers,
    +                    retries=retries,
    +                    redirect=redirect,
    +                    timeout=timeout,
    +                    **response_kw
    +                )
    +
    +        # Check if we should retry the HTTP response.
    +        has_retry_after = bool(http_response.headers.get("Retry-After"))
    +        if retries.is_retry(method, http_response.status, has_retry_after):
    +            retries = retries.increment(method, url, response=http_response, _pool=self)
    +            log.debug("Retry: %s", url)
    +            retries.sleep(http_response)
    +            return self.urlopen(
    +                method,
    +                url,
    +                body=body,
    +                headers=headers,
    +                retries=retries,
    +                redirect=redirect,
    +                timeout=timeout,
    +                **response_kw
    +            )
    +
    +        return http_response
    +
    +    def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw):
    +
    +        if is_prod_appengine():
    +            # Production GAE handles deflate encoding automatically, but does
    +            # not remove the encoding header.
    +            content_encoding = urlfetch_resp.headers.get("content-encoding")
    +
    +            if content_encoding == "deflate":
    +                del urlfetch_resp.headers["content-encoding"]
    +
    +        transfer_encoding = urlfetch_resp.headers.get("transfer-encoding")
    +        # We have a full response's content,
    +        # so let's make sure we don't report ourselves as chunked data.
    +        if transfer_encoding == "chunked":
    +            encodings = transfer_encoding.split(",")
    +            encodings.remove("chunked")
    +            urlfetch_resp.headers["transfer-encoding"] = ",".join(encodings)
    +
    +        original_response = HTTPResponse(
    +            # In order for decoding to work, we must present the content as
    +            # a file-like object.
    +            body=io.BytesIO(urlfetch_resp.content),
    +            msg=urlfetch_resp.header_msg,
    +            headers=urlfetch_resp.headers,
    +            status=urlfetch_resp.status_code,
    +            **response_kw
    +        )
    +
    +        return HTTPResponse(
    +            body=io.BytesIO(urlfetch_resp.content),
    +            headers=urlfetch_resp.headers,
    +            status=urlfetch_resp.status_code,
    +            original_response=original_response,
    +            **response_kw
    +        )
    +
    +    def _get_absolute_timeout(self, timeout):
    +        if timeout is Timeout.DEFAULT_TIMEOUT:
    +            return None  # Defer to URLFetch's default.
    +        if isinstance(timeout, Timeout):
    +            if timeout._read is not None or timeout._connect is not None:
    +                warnings.warn(
    +                    "URLFetch does not support granular timeout settings, "
    +                    "reverting to total or default URLFetch timeout.",
    +                    AppEnginePlatformWarning,
    +                )
    +            return timeout.total
    +        return timeout
    +
    +    def _get_retries(self, retries, redirect):
    +        if not isinstance(retries, Retry):
    +            retries = Retry.from_int(retries, redirect=redirect, default=self.retries)
    +
    +        if retries.connect or retries.read or retries.redirect:
    +            warnings.warn(
    +                "URLFetch only supports total retries and does not "
    +                "recognize connect, read, or redirect retry parameters.",
    +                AppEnginePlatformWarning,
    +            )
    +
    +        return retries
    +
    +
    +# Alias methods from _appengine_environ to maintain public API interface.
    +
    +is_appengine = _appengine_environ.is_appengine
    +is_appengine_sandbox = _appengine_environ.is_appengine_sandbox
    +is_local_appengine = _appengine_environ.is_local_appengine
    +is_prod_appengine = _appengine_environ.is_prod_appengine
    +is_prod_appengine_mvms = _appengine_environ.is_prod_appengine_mvms
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/ntlmpool.py b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/ntlmpool.py
    new file mode 100644
    index 0000000..4716657
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/ntlmpool.py
    @@ -0,0 +1,130 @@
    +"""
    +NTLM authenticating pool, contributed by erikcederstran
    +
    +Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10
    +"""
    +from __future__ import absolute_import
    +
    +import warnings
    +from logging import getLogger
    +
    +from ntlm import ntlm
    +
    +from .. import HTTPSConnectionPool
    +from ..packages.six.moves.http_client import HTTPSConnection
    +
    +warnings.warn(
    +    "The 'urllib3.contrib.ntlmpool' module is deprecated and will be removed "
    +    "in urllib3 v2.0 release, urllib3 is not able to support it properly due "
    +    "to reasons listed in issue: https://github.com/urllib3/urllib3/issues/2282. "
    +    "If you are a user of this module please comment in the mentioned issue.",
    +    DeprecationWarning,
    +)
    +
    +log = getLogger(__name__)
    +
    +
    +class NTLMConnectionPool(HTTPSConnectionPool):
    +    """
    +    Implements an NTLM authentication version of an urllib3 connection pool
    +    """
    +
    +    scheme = "https"
    +
    +    def __init__(self, user, pw, authurl, *args, **kwargs):
    +        """
    +        authurl is a random URL on the server that is protected by NTLM.
    +        user is the Windows user, probably in the DOMAIN\\username format.
    +        pw is the password for the user.
    +        """
    +        super(NTLMConnectionPool, self).__init__(*args, **kwargs)
    +        self.authurl = authurl
    +        self.rawuser = user
    +        user_parts = user.split("\\", 1)
    +        self.domain = user_parts[0].upper()
    +        self.user = user_parts[1]
    +        self.pw = pw
    +
    +    def _new_conn(self):
    +        # Performs the NTLM handshake that secures the connection. The socket
    +        # must be kept open while requests are performed.
    +        self.num_connections += 1
    +        log.debug(
    +            "Starting NTLM HTTPS connection no. %d: https://%s%s",
    +            self.num_connections,
    +            self.host,
    +            self.authurl,
    +        )
    +
    +        headers = {"Connection": "Keep-Alive"}
    +        req_header = "Authorization"
    +        resp_header = "www-authenticate"
    +
    +        conn = HTTPSConnection(host=self.host, port=self.port)
    +
    +        # Send negotiation message
    +        headers[req_header] = "NTLM %s" % ntlm.create_NTLM_NEGOTIATE_MESSAGE(
    +            self.rawuser
    +        )
    +        log.debug("Request headers: %s", headers)
    +        conn.request("GET", self.authurl, None, headers)
    +        res = conn.getresponse()
    +        reshdr = dict(res.headers)
    +        log.debug("Response status: %s %s", res.status, res.reason)
    +        log.debug("Response headers: %s", reshdr)
    +        log.debug("Response data: %s [...]", res.read(100))
    +
    +        # Remove the reference to the socket, so that it can not be closed by
    +        # the response object (we want to keep the socket open)
    +        res.fp = None
    +
    +        # Server should respond with a challenge message
    +        auth_header_values = reshdr[resp_header].split(", ")
    +        auth_header_value = None
    +        for s in auth_header_values:
    +            if s[:5] == "NTLM ":
    +                auth_header_value = s[5:]
    +        if auth_header_value is None:
    +            raise Exception(
    +                "Unexpected %s response header: %s" % (resp_header, reshdr[resp_header])
    +            )
    +
    +        # Send authentication message
    +        ServerChallenge, NegotiateFlags = ntlm.parse_NTLM_CHALLENGE_MESSAGE(
    +            auth_header_value
    +        )
    +        auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(
    +            ServerChallenge, self.user, self.domain, self.pw, NegotiateFlags
    +        )
    +        headers[req_header] = "NTLM %s" % auth_msg
    +        log.debug("Request headers: %s", headers)
    +        conn.request("GET", self.authurl, None, headers)
    +        res = conn.getresponse()
    +        log.debug("Response status: %s %s", res.status, res.reason)
    +        log.debug("Response headers: %s", dict(res.headers))
    +        log.debug("Response data: %s [...]", res.read()[:100])
    +        if res.status != 200:
    +            if res.status == 401:
    +                raise Exception("Server rejected request: wrong username or password")
    +            raise Exception("Wrong server response: %s %s" % (res.status, res.reason))
    +
    +        res.fp = None
    +        log.debug("Connection established")
    +        return conn
    +
    +    def urlopen(
    +        self,
    +        method,
    +        url,
    +        body=None,
    +        headers=None,
    +        retries=3,
    +        redirect=True,
    +        assert_same_host=True,
    +    ):
    +        if headers is None:
    +            headers = {}
    +        headers["Connection"] = "Keep-Alive"
    +        return super(NTLMConnectionPool, self).urlopen(
    +            method, url, body, headers, retries, redirect, assert_same_host
    +        )
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/pyopenssl.py b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/pyopenssl.py
    new file mode 100644
    index 0000000..1ed214b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/pyopenssl.py
    @@ -0,0 +1,518 @@
    +"""
    +TLS with SNI_-support for Python 2. Follow these instructions if you would
    +like to verify TLS certificates in Python 2. Note, the default libraries do
    +*not* do certificate checking; you need to do additional work to validate
    +certificates yourself.
    +
    +This needs the following packages installed:
    +
    +* `pyOpenSSL`_ (tested with 16.0.0)
    +* `cryptography`_ (minimum 1.3.4, from pyopenssl)
    +* `idna`_ (minimum 2.0, from cryptography)
    +
    +However, pyopenssl depends on cryptography, which depends on idna, so while we
    +use all three directly here we end up having relatively few packages required.
    +
    +You can install them with the following command:
    +
    +.. code-block:: bash
    +
    +    $ python -m pip install pyopenssl cryptography idna
    +
    +To activate certificate checking, call
    +:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code
    +before you begin making HTTP requests. This can be done in a ``sitecustomize``
    +module, or at any other time before your application begins using ``urllib3``,
    +like this:
    +
    +.. code-block:: python
    +
    +    try:
    +        import urllib3.contrib.pyopenssl
    +        urllib3.contrib.pyopenssl.inject_into_urllib3()
    +    except ImportError:
    +        pass
    +
    +Now you can use :mod:`urllib3` as you normally would, and it will support SNI
    +when the required modules are installed.
    +
    +Activating this module also has the positive side effect of disabling SSL/TLS
    +compression in Python 2 (see `CRIME attack`_).
    +
    +.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication
    +.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit)
    +.. _pyopenssl: https://www.pyopenssl.org
    +.. _cryptography: https://cryptography.io
    +.. _idna: https://github.com/kjd/idna
    +"""
    +from __future__ import absolute_import
    +
    +import OpenSSL.crypto
    +import OpenSSL.SSL
    +from cryptography import x509
    +from cryptography.hazmat.backends.openssl import backend as openssl_backend
    +
    +try:
    +    from cryptography.x509 import UnsupportedExtension
    +except ImportError:
    +    # UnsupportedExtension is gone in cryptography >= 2.1.0
    +    class UnsupportedExtension(Exception):
    +        pass
    +
    +
    +from io import BytesIO
    +from socket import error as SocketError
    +from socket import timeout
    +
    +try:  # Platform-specific: Python 2
    +    from socket import _fileobject
    +except ImportError:  # Platform-specific: Python 3
    +    _fileobject = None
    +    from ..packages.backports.makefile import backport_makefile
    +
    +import logging
    +import ssl
    +import sys
    +import warnings
    +
    +from .. import util
    +from ..packages import six
    +from ..util.ssl_ import PROTOCOL_TLS_CLIENT
    +
    +warnings.warn(
    +    "'urllib3.contrib.pyopenssl' module is deprecated and will be removed "
    +    "in a future release of urllib3 2.x. Read more in this issue: "
    +    "https://github.com/urllib3/urllib3/issues/2680",
    +    category=DeprecationWarning,
    +    stacklevel=2,
    +)
    +
    +__all__ = ["inject_into_urllib3", "extract_from_urllib3"]
    +
    +# SNI always works.
    +HAS_SNI = True
    +
    +# Map from urllib3 to PyOpenSSL compatible parameter-values.
    +_openssl_versions = {
    +    util.PROTOCOL_TLS: OpenSSL.SSL.SSLv23_METHOD,
    +    PROTOCOL_TLS_CLIENT: OpenSSL.SSL.SSLv23_METHOD,
    +    ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,
    +}
    +
    +if hasattr(ssl, "PROTOCOL_SSLv3") and hasattr(OpenSSL.SSL, "SSLv3_METHOD"):
    +    _openssl_versions[ssl.PROTOCOL_SSLv3] = OpenSSL.SSL.SSLv3_METHOD
    +
    +if hasattr(ssl, "PROTOCOL_TLSv1_1") and hasattr(OpenSSL.SSL, "TLSv1_1_METHOD"):
    +    _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD
    +
    +if hasattr(ssl, "PROTOCOL_TLSv1_2") and hasattr(OpenSSL.SSL, "TLSv1_2_METHOD"):
    +    _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD
    +
    +
    +_stdlib_to_openssl_verify = {
    +    ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE,
    +    ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER,
    +    ssl.CERT_REQUIRED: OpenSSL.SSL.VERIFY_PEER
    +    + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
    +}
    +_openssl_to_stdlib_verify = dict((v, k) for k, v in _stdlib_to_openssl_verify.items())
    +
    +# OpenSSL will only write 16K at a time
    +SSL_WRITE_BLOCKSIZE = 16384
    +
    +orig_util_HAS_SNI = util.HAS_SNI
    +orig_util_SSLContext = util.ssl_.SSLContext
    +
    +
    +log = logging.getLogger(__name__)
    +
    +
    +def inject_into_urllib3():
    +    "Monkey-patch urllib3 with PyOpenSSL-backed SSL-support."
    +
    +    _validate_dependencies_met()
    +
    +    util.SSLContext = PyOpenSSLContext
    +    util.ssl_.SSLContext = PyOpenSSLContext
    +    util.HAS_SNI = HAS_SNI
    +    util.ssl_.HAS_SNI = HAS_SNI
    +    util.IS_PYOPENSSL = True
    +    util.ssl_.IS_PYOPENSSL = True
    +
    +
    +def extract_from_urllib3():
    +    "Undo monkey-patching by :func:`inject_into_urllib3`."
    +
    +    util.SSLContext = orig_util_SSLContext
    +    util.ssl_.SSLContext = orig_util_SSLContext
    +    util.HAS_SNI = orig_util_HAS_SNI
    +    util.ssl_.HAS_SNI = orig_util_HAS_SNI
    +    util.IS_PYOPENSSL = False
    +    util.ssl_.IS_PYOPENSSL = False
    +
    +
    +def _validate_dependencies_met():
    +    """
    +    Verifies that PyOpenSSL's package-level dependencies have been met.
    +    Throws `ImportError` if they are not met.
    +    """
    +    # Method added in `cryptography==1.1`; not available in older versions
    +    from cryptography.x509.extensions import Extensions
    +
    +    if getattr(Extensions, "get_extension_for_class", None) is None:
    +        raise ImportError(
    +            "'cryptography' module missing required functionality.  "
    +            "Try upgrading to v1.3.4 or newer."
    +        )
    +
    +    # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509
    +    # attribute is only present on those versions.
    +    from OpenSSL.crypto import X509
    +
    +    x509 = X509()
    +    if getattr(x509, "_x509", None) is None:
    +        raise ImportError(
    +            "'pyOpenSSL' module missing required functionality. "
    +            "Try upgrading to v0.14 or newer."
    +        )
    +
    +
    +def _dnsname_to_stdlib(name):
    +    """
    +    Converts a dNSName SubjectAlternativeName field to the form used by the
    +    standard library on the given Python version.
    +
    +    Cryptography produces a dNSName as a unicode string that was idna-decoded
    +    from ASCII bytes. We need to idna-encode that string to get it back, and
    +    then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib
    +    uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8).
    +
    +    If the name cannot be idna-encoded then we return None signalling that
    +    the name given should be skipped.
    +    """
    +
    +    def idna_encode(name):
    +        """
    +        Borrowed wholesale from the Python Cryptography Project. It turns out
    +        that we can't just safely call `idna.encode`: it can explode for
    +        wildcard names. This avoids that problem.
    +        """
    +        import idna
    +
    +        try:
    +            for prefix in [u"*.", u"."]:
    +                if name.startswith(prefix):
    +                    name = name[len(prefix) :]
    +                    return prefix.encode("ascii") + idna.encode(name)
    +            return idna.encode(name)
    +        except idna.core.IDNAError:
    +            return None
    +
    +    # Don't send IPv6 addresses through the IDNA encoder.
    +    if ":" in name:
    +        return name
    +
    +    name = idna_encode(name)
    +    if name is None:
    +        return None
    +    elif sys.version_info >= (3, 0):
    +        name = name.decode("utf-8")
    +    return name
    +
    +
    +def get_subj_alt_name(peer_cert):
    +    """
    +    Given an PyOpenSSL certificate, provides all the subject alternative names.
    +    """
    +    # Pass the cert to cryptography, which has much better APIs for this.
    +    if hasattr(peer_cert, "to_cryptography"):
    +        cert = peer_cert.to_cryptography()
    +    else:
    +        der = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_ASN1, peer_cert)
    +        cert = x509.load_der_x509_certificate(der, openssl_backend)
    +
    +    # We want to find the SAN extension. Ask Cryptography to locate it (it's
    +    # faster than looping in Python)
    +    try:
    +        ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName).value
    +    except x509.ExtensionNotFound:
    +        # No such extension, return the empty list.
    +        return []
    +    except (
    +        x509.DuplicateExtension,
    +        UnsupportedExtension,
    +        x509.UnsupportedGeneralNameType,
    +        UnicodeError,
    +    ) as e:
    +        # A problem has been found with the quality of the certificate. Assume
    +        # no SAN field is present.
    +        log.warning(
    +            "A problem was encountered with the certificate that prevented "
    +            "urllib3 from finding the SubjectAlternativeName field. This can "
    +            "affect certificate validation. The error was %s",
    +            e,
    +        )
    +        return []
    +
    +    # We want to return dNSName and iPAddress fields. We need to cast the IPs
    +    # back to strings because the match_hostname function wants them as
    +    # strings.
    +    # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8
    +    # decoded. This is pretty frustrating, but that's what the standard library
    +    # does with certificates, and so we need to attempt to do the same.
    +    # We also want to skip over names which cannot be idna encoded.
    +    names = [
    +        ("DNS", name)
    +        for name in map(_dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName))
    +        if name is not None
    +    ]
    +    names.extend(
    +        ("IP Address", str(name)) for name in ext.get_values_for_type(x509.IPAddress)
    +    )
    +
    +    return names
    +
    +
    +class WrappedSocket(object):
    +    """API-compatibility wrapper for Python OpenSSL's Connection-class.
    +
    +    Note: _makefile_refs, _drop() and _reuse() are needed for the garbage
    +    collector of pypy.
    +    """
    +
    +    def __init__(self, connection, socket, suppress_ragged_eofs=True):
    +        self.connection = connection
    +        self.socket = socket
    +        self.suppress_ragged_eofs = suppress_ragged_eofs
    +        self._makefile_refs = 0
    +        self._closed = False
    +
    +    def fileno(self):
    +        return self.socket.fileno()
    +
    +    # Copy-pasted from Python 3.5 source code
    +    def _decref_socketios(self):
    +        if self._makefile_refs > 0:
    +            self._makefile_refs -= 1
    +        if self._closed:
    +            self.close()
    +
    +    def recv(self, *args, **kwargs):
    +        try:
    +            data = self.connection.recv(*args, **kwargs)
    +        except OpenSSL.SSL.SysCallError as e:
    +            if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"):
    +                return b""
    +            else:
    +                raise SocketError(str(e))
    +        except OpenSSL.SSL.ZeroReturnError:
    +            if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
    +                return b""
    +            else:
    +                raise
    +        except OpenSSL.SSL.WantReadError:
    +            if not util.wait_for_read(self.socket, self.socket.gettimeout()):
    +                raise timeout("The read operation timed out")
    +            else:
    +                return self.recv(*args, **kwargs)
    +
    +        # TLS 1.3 post-handshake authentication
    +        except OpenSSL.SSL.Error as e:
    +            raise ssl.SSLError("read error: %r" % e)
    +        else:
    +            return data
    +
    +    def recv_into(self, *args, **kwargs):
    +        try:
    +            return self.connection.recv_into(*args, **kwargs)
    +        except OpenSSL.SSL.SysCallError as e:
    +            if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"):
    +                return 0
    +            else:
    +                raise SocketError(str(e))
    +        except OpenSSL.SSL.ZeroReturnError:
    +            if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
    +                return 0
    +            else:
    +                raise
    +        except OpenSSL.SSL.WantReadError:
    +            if not util.wait_for_read(self.socket, self.socket.gettimeout()):
    +                raise timeout("The read operation timed out")
    +            else:
    +                return self.recv_into(*args, **kwargs)
    +
    +        # TLS 1.3 post-handshake authentication
    +        except OpenSSL.SSL.Error as e:
    +            raise ssl.SSLError("read error: %r" % e)
    +
    +    def settimeout(self, timeout):
    +        return self.socket.settimeout(timeout)
    +
    +    def _send_until_done(self, data):
    +        while True:
    +            try:
    +                return self.connection.send(data)
    +            except OpenSSL.SSL.WantWriteError:
    +                if not util.wait_for_write(self.socket, self.socket.gettimeout()):
    +                    raise timeout()
    +                continue
    +            except OpenSSL.SSL.SysCallError as e:
    +                raise SocketError(str(e))
    +
    +    def sendall(self, data):
    +        total_sent = 0
    +        while total_sent < len(data):
    +            sent = self._send_until_done(
    +                data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE]
    +            )
    +            total_sent += sent
    +
    +    def shutdown(self):
    +        # FIXME rethrow compatible exceptions should we ever use this
    +        self.connection.shutdown()
    +
    +    def close(self):
    +        if self._makefile_refs < 1:
    +            try:
    +                self._closed = True
    +                return self.connection.close()
    +            except OpenSSL.SSL.Error:
    +                return
    +        else:
    +            self._makefile_refs -= 1
    +
    +    def getpeercert(self, binary_form=False):
    +        x509 = self.connection.get_peer_certificate()
    +
    +        if not x509:
    +            return x509
    +
    +        if binary_form:
    +            return OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_ASN1, x509)
    +
    +        return {
    +            "subject": ((("commonName", x509.get_subject().CN),),),
    +            "subjectAltName": get_subj_alt_name(x509),
    +        }
    +
    +    def version(self):
    +        return self.connection.get_protocol_version_name()
    +
    +    def _reuse(self):
    +        self._makefile_refs += 1
    +
    +    def _drop(self):
    +        if self._makefile_refs < 1:
    +            self.close()
    +        else:
    +            self._makefile_refs -= 1
    +
    +
    +if _fileobject:  # Platform-specific: Python 2
    +
    +    def makefile(self, mode, bufsize=-1):
    +        self._makefile_refs += 1
    +        return _fileobject(self, mode, bufsize, close=True)
    +
    +else:  # Platform-specific: Python 3
    +    makefile = backport_makefile
    +
    +WrappedSocket.makefile = makefile
    +
    +
    +class PyOpenSSLContext(object):
    +    """
    +    I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible
    +    for translating the interface of the standard library ``SSLContext`` object
    +    to calls into PyOpenSSL.
    +    """
    +
    +    def __init__(self, protocol):
    +        self.protocol = _openssl_versions[protocol]
    +        self._ctx = OpenSSL.SSL.Context(self.protocol)
    +        self._options = 0
    +        self.check_hostname = False
    +
    +    @property
    +    def options(self):
    +        return self._options
    +
    +    @options.setter
    +    def options(self, value):
    +        self._options = value
    +        self._ctx.set_options(value)
    +
    +    @property
    +    def verify_mode(self):
    +        return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()]
    +
    +    @verify_mode.setter
    +    def verify_mode(self, value):
    +        self._ctx.set_verify(_stdlib_to_openssl_verify[value], _verify_callback)
    +
    +    def set_default_verify_paths(self):
    +        self._ctx.set_default_verify_paths()
    +
    +    def set_ciphers(self, ciphers):
    +        if isinstance(ciphers, six.text_type):
    +            ciphers = ciphers.encode("utf-8")
    +        self._ctx.set_cipher_list(ciphers)
    +
    +    def load_verify_locations(self, cafile=None, capath=None, cadata=None):
    +        if cafile is not None:
    +            cafile = cafile.encode("utf-8")
    +        if capath is not None:
    +            capath = capath.encode("utf-8")
    +        try:
    +            self._ctx.load_verify_locations(cafile, capath)
    +            if cadata is not None:
    +                self._ctx.load_verify_locations(BytesIO(cadata))
    +        except OpenSSL.SSL.Error as e:
    +            raise ssl.SSLError("unable to load trusted certificates: %r" % e)
    +
    +    def load_cert_chain(self, certfile, keyfile=None, password=None):
    +        self._ctx.use_certificate_chain_file(certfile)
    +        if password is not None:
    +            if not isinstance(password, six.binary_type):
    +                password = password.encode("utf-8")
    +            self._ctx.set_passwd_cb(lambda *_: password)
    +        self._ctx.use_privatekey_file(keyfile or certfile)
    +
    +    def set_alpn_protocols(self, protocols):
    +        protocols = [six.ensure_binary(p) for p in protocols]
    +        return self._ctx.set_alpn_protos(protocols)
    +
    +    def wrap_socket(
    +        self,
    +        sock,
    +        server_side=False,
    +        do_handshake_on_connect=True,
    +        suppress_ragged_eofs=True,
    +        server_hostname=None,
    +    ):
    +        cnx = OpenSSL.SSL.Connection(self._ctx, sock)
    +
    +        if isinstance(server_hostname, six.text_type):  # Platform-specific: Python 3
    +            server_hostname = server_hostname.encode("utf-8")
    +
    +        if server_hostname is not None:
    +            cnx.set_tlsext_host_name(server_hostname)
    +
    +        cnx.set_connect_state()
    +
    +        while True:
    +            try:
    +                cnx.do_handshake()
    +            except OpenSSL.SSL.WantReadError:
    +                if not util.wait_for_read(sock, sock.gettimeout()):
    +                    raise timeout("select timed out")
    +                continue
    +            except OpenSSL.SSL.Error as e:
    +                raise ssl.SSLError("bad handshake: %r" % e)
    +            break
    +
    +        return WrappedSocket(cnx, sock)
    +
    +
    +def _verify_callback(cnx, x509, err_no, err_depth, return_code):
    +    return err_no == 0
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/securetransport.py b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/securetransport.py
    new file mode 100644
    index 0000000..6c46a3b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/securetransport.py
    @@ -0,0 +1,921 @@
    +"""
    +SecureTranport support for urllib3 via ctypes.
    +
    +This makes platform-native TLS available to urllib3 users on macOS without the
    +use of a compiler. This is an important feature because the Python Package
    +Index is moving to become a TLSv1.2-or-higher server, and the default OpenSSL
    +that ships with macOS is not capable of doing TLSv1.2. The only way to resolve
    +this is to give macOS users an alternative solution to the problem, and that
    +solution is to use SecureTransport.
    +
    +We use ctypes here because this solution must not require a compiler. That's
    +because pip is not allowed to require a compiler either.
    +
    +This is not intended to be a seriously long-term solution to this problem.
    +The hope is that PEP 543 will eventually solve this issue for us, at which
    +point we can retire this contrib module. But in the short term, we need to
    +solve the impending tire fire that is Python on Mac without this kind of
    +contrib module. So...here we are.
    +
    +To use this module, simply import and inject it::
    +
    +    import urllib3.contrib.securetransport
    +    urllib3.contrib.securetransport.inject_into_urllib3()
    +
    +Happy TLSing!
    +
    +This code is a bastardised version of the code found in Will Bond's oscrypto
    +library. An enormous debt is owed to him for blazing this trail for us. For
    +that reason, this code should be considered to be covered both by urllib3's
    +license and by oscrypto's:
    +
    +.. code-block::
    +
    +    Copyright (c) 2015-2016 Will Bond <will@wbond.net>
    +
    +    Permission is hereby granted, free of charge, to any person obtaining a
    +    copy of this software and associated documentation files (the "Software"),
    +    to deal in the Software without restriction, including without limitation
    +    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    +    and/or sell copies of the Software, and to permit persons to whom the
    +    Software is furnished to do so, subject to the following conditions:
    +
    +    The above copyright notice and this permission notice shall be included in
    +    all copies or substantial portions of the Software.
    +
    +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    +    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    +    DEALINGS IN THE SOFTWARE.
    +"""
    +from __future__ import absolute_import
    +
    +import contextlib
    +import ctypes
    +import errno
    +import os.path
    +import shutil
    +import socket
    +import ssl
    +import struct
    +import threading
    +import weakref
    +
    +import six
    +
    +from .. import util
    +from ..util.ssl_ import PROTOCOL_TLS_CLIENT
    +from ._securetransport.bindings import CoreFoundation, Security, SecurityConst
    +from ._securetransport.low_level import (
    +    _assert_no_error,
    +    _build_tls_unknown_ca_alert,
    +    _cert_array_from_pem,
    +    _create_cfstring_array,
    +    _load_client_cert_chain,
    +    _temporary_keychain,
    +)
    +
    +try:  # Platform-specific: Python 2
    +    from socket import _fileobject
    +except ImportError:  # Platform-specific: Python 3
    +    _fileobject = None
    +    from ..packages.backports.makefile import backport_makefile
    +
    +__all__ = ["inject_into_urllib3", "extract_from_urllib3"]
    +
    +# SNI always works
    +HAS_SNI = True
    +
    +orig_util_HAS_SNI = util.HAS_SNI
    +orig_util_SSLContext = util.ssl_.SSLContext
    +
    +# This dictionary is used by the read callback to obtain a handle to the
    +# calling wrapped socket. This is a pretty silly approach, but for now it'll
    +# do. I feel like I should be able to smuggle a handle to the wrapped socket
    +# directly in the SSLConnectionRef, but for now this approach will work I
    +# guess.
    +#
    +# We need to lock around this structure for inserts, but we don't do it for
    +# reads/writes in the callbacks. The reasoning here goes as follows:
    +#
    +#    1. It is not possible to call into the callbacks before the dictionary is
    +#       populated, so once in the callback the id must be in the dictionary.
    +#    2. The callbacks don't mutate the dictionary, they only read from it, and
    +#       so cannot conflict with any of the insertions.
    +#
    +# This is good: if we had to lock in the callbacks we'd drastically slow down
    +# the performance of this code.
    +_connection_refs = weakref.WeakValueDictionary()
    +_connection_ref_lock = threading.Lock()
    +
    +# Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over
    +# for no better reason than we need *a* limit, and this one is right there.
    +SSL_WRITE_BLOCKSIZE = 16384
    +
    +# This is our equivalent of util.ssl_.DEFAULT_CIPHERS, but expanded out to
    +# individual cipher suites. We need to do this because this is how
    +# SecureTransport wants them.
    +CIPHER_SUITES = [
    +    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
    +    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
    +    SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
    +    SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
    +    SecurityConst.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
    +    SecurityConst.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
    +    SecurityConst.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
    +    SecurityConst.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
    +    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
    +    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
    +    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
    +    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
    +    SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
    +    SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
    +    SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
    +    SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
    +    SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
    +    SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
    +    SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
    +    SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
    +    SecurityConst.TLS_AES_256_GCM_SHA384,
    +    SecurityConst.TLS_AES_128_GCM_SHA256,
    +    SecurityConst.TLS_RSA_WITH_AES_256_GCM_SHA384,
    +    SecurityConst.TLS_RSA_WITH_AES_128_GCM_SHA256,
    +    SecurityConst.TLS_AES_128_CCM_8_SHA256,
    +    SecurityConst.TLS_AES_128_CCM_SHA256,
    +    SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA256,
    +    SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA256,
    +    SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA,
    +    SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA,
    +]
    +
    +# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of
    +# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version.
    +# TLSv1 to 1.2 are supported on macOS 10.8+
    +_protocol_to_min_max = {
    +    util.PROTOCOL_TLS: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12),
    +    PROTOCOL_TLS_CLIENT: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12),
    +}
    +
    +if hasattr(ssl, "PROTOCOL_SSLv2"):
    +    _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = (
    +        SecurityConst.kSSLProtocol2,
    +        SecurityConst.kSSLProtocol2,
    +    )
    +if hasattr(ssl, "PROTOCOL_SSLv3"):
    +    _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = (
    +        SecurityConst.kSSLProtocol3,
    +        SecurityConst.kSSLProtocol3,
    +    )
    +if hasattr(ssl, "PROTOCOL_TLSv1"):
    +    _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = (
    +        SecurityConst.kTLSProtocol1,
    +        SecurityConst.kTLSProtocol1,
    +    )
    +if hasattr(ssl, "PROTOCOL_TLSv1_1"):
    +    _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = (
    +        SecurityConst.kTLSProtocol11,
    +        SecurityConst.kTLSProtocol11,
    +    )
    +if hasattr(ssl, "PROTOCOL_TLSv1_2"):
    +    _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = (
    +        SecurityConst.kTLSProtocol12,
    +        SecurityConst.kTLSProtocol12,
    +    )
    +
    +
    +def inject_into_urllib3():
    +    """
    +    Monkey-patch urllib3 with SecureTransport-backed SSL-support.
    +    """
    +    util.SSLContext = SecureTransportContext
    +    util.ssl_.SSLContext = SecureTransportContext
    +    util.HAS_SNI = HAS_SNI
    +    util.ssl_.HAS_SNI = HAS_SNI
    +    util.IS_SECURETRANSPORT = True
    +    util.ssl_.IS_SECURETRANSPORT = True
    +
    +
    +def extract_from_urllib3():
    +    """
    +    Undo monkey-patching by :func:`inject_into_urllib3`.
    +    """
    +    util.SSLContext = orig_util_SSLContext
    +    util.ssl_.SSLContext = orig_util_SSLContext
    +    util.HAS_SNI = orig_util_HAS_SNI
    +    util.ssl_.HAS_SNI = orig_util_HAS_SNI
    +    util.IS_SECURETRANSPORT = False
    +    util.ssl_.IS_SECURETRANSPORT = False
    +
    +
    +def _read_callback(connection_id, data_buffer, data_length_pointer):
    +    """
    +    SecureTransport read callback. This is called by ST to request that data
    +    be returned from the socket.
    +    """
    +    wrapped_socket = None
    +    try:
    +        wrapped_socket = _connection_refs.get(connection_id)
    +        if wrapped_socket is None:
    +            return SecurityConst.errSSLInternal
    +        base_socket = wrapped_socket.socket
    +
    +        requested_length = data_length_pointer[0]
    +
    +        timeout = wrapped_socket.gettimeout()
    +        error = None
    +        read_count = 0
    +
    +        try:
    +            while read_count < requested_length:
    +                if timeout is None or timeout >= 0:
    +                    if not util.wait_for_read(base_socket, timeout):
    +                        raise socket.error(errno.EAGAIN, "timed out")
    +
    +                remaining = requested_length - read_count
    +                buffer = (ctypes.c_char * remaining).from_address(
    +                    data_buffer + read_count
    +                )
    +                chunk_size = base_socket.recv_into(buffer, remaining)
    +                read_count += chunk_size
    +                if not chunk_size:
    +                    if not read_count:
    +                        return SecurityConst.errSSLClosedGraceful
    +                    break
    +        except (socket.error) as e:
    +            error = e.errno
    +
    +            if error is not None and error != errno.EAGAIN:
    +                data_length_pointer[0] = read_count
    +                if error == errno.ECONNRESET or error == errno.EPIPE:
    +                    return SecurityConst.errSSLClosedAbort
    +                raise
    +
    +        data_length_pointer[0] = read_count
    +
    +        if read_count != requested_length:
    +            return SecurityConst.errSSLWouldBlock
    +
    +        return 0
    +    except Exception as e:
    +        if wrapped_socket is not None:
    +            wrapped_socket._exception = e
    +        return SecurityConst.errSSLInternal
    +
    +
    +def _write_callback(connection_id, data_buffer, data_length_pointer):
    +    """
    +    SecureTransport write callback. This is called by ST to request that data
    +    actually be sent on the network.
    +    """
    +    wrapped_socket = None
    +    try:
    +        wrapped_socket = _connection_refs.get(connection_id)
    +        if wrapped_socket is None:
    +            return SecurityConst.errSSLInternal
    +        base_socket = wrapped_socket.socket
    +
    +        bytes_to_write = data_length_pointer[0]
    +        data = ctypes.string_at(data_buffer, bytes_to_write)
    +
    +        timeout = wrapped_socket.gettimeout()
    +        error = None
    +        sent = 0
    +
    +        try:
    +            while sent < bytes_to_write:
    +                if timeout is None or timeout >= 0:
    +                    if not util.wait_for_write(base_socket, timeout):
    +                        raise socket.error(errno.EAGAIN, "timed out")
    +                chunk_sent = base_socket.send(data)
    +                sent += chunk_sent
    +
    +                # This has some needless copying here, but I'm not sure there's
    +                # much value in optimising this data path.
    +                data = data[chunk_sent:]
    +        except (socket.error) as e:
    +            error = e.errno
    +
    +            if error is not None and error != errno.EAGAIN:
    +                data_length_pointer[0] = sent
    +                if error == errno.ECONNRESET or error == errno.EPIPE:
    +                    return SecurityConst.errSSLClosedAbort
    +                raise
    +
    +        data_length_pointer[0] = sent
    +
    +        if sent != bytes_to_write:
    +            return SecurityConst.errSSLWouldBlock
    +
    +        return 0
    +    except Exception as e:
    +        if wrapped_socket is not None:
    +            wrapped_socket._exception = e
    +        return SecurityConst.errSSLInternal
    +
    +
    +# We need to keep these two objects references alive: if they get GC'd while
    +# in use then SecureTransport could attempt to call a function that is in freed
    +# memory. That would be...uh...bad. Yeah, that's the word. Bad.
    +_read_callback_pointer = Security.SSLReadFunc(_read_callback)
    +_write_callback_pointer = Security.SSLWriteFunc(_write_callback)
    +
    +
    +class WrappedSocket(object):
    +    """
    +    API-compatibility wrapper for Python's OpenSSL wrapped socket object.
    +
    +    Note: _makefile_refs, _drop(), and _reuse() are needed for the garbage
    +    collector of PyPy.
    +    """
    +
    +    def __init__(self, socket):
    +        self.socket = socket
    +        self.context = None
    +        self._makefile_refs = 0
    +        self._closed = False
    +        self._exception = None
    +        self._keychain = None
    +        self._keychain_dir = None
    +        self._client_cert_chain = None
    +
    +        # We save off the previously-configured timeout and then set it to
    +        # zero. This is done because we use select and friends to handle the
    +        # timeouts, but if we leave the timeout set on the lower socket then
    +        # Python will "kindly" call select on that socket again for us. Avoid
    +        # that by forcing the timeout to zero.
    +        self._timeout = self.socket.gettimeout()
    +        self.socket.settimeout(0)
    +
    +    @contextlib.contextmanager
    +    def _raise_on_error(self):
    +        """
    +        A context manager that can be used to wrap calls that do I/O from
    +        SecureTransport. If any of the I/O callbacks hit an exception, this
    +        context manager will correctly propagate the exception after the fact.
    +        This avoids silently swallowing those exceptions.
    +
    +        It also correctly forces the socket closed.
    +        """
    +        self._exception = None
    +
    +        # We explicitly don't catch around this yield because in the unlikely
    +        # event that an exception was hit in the block we don't want to swallow
    +        # it.
    +        yield
    +        if self._exception is not None:
    +            exception, self._exception = self._exception, None
    +            self.close()
    +            raise exception
    +
    +    def _set_ciphers(self):
    +        """
    +        Sets up the allowed ciphers. By default this matches the set in
    +        util.ssl_.DEFAULT_CIPHERS, at least as supported by macOS. This is done
    +        custom and doesn't allow changing at this time, mostly because parsing
    +        OpenSSL cipher strings is going to be a freaking nightmare.
    +        """
    +        ciphers = (Security.SSLCipherSuite * len(CIPHER_SUITES))(*CIPHER_SUITES)
    +        result = Security.SSLSetEnabledCiphers(
    +            self.context, ciphers, len(CIPHER_SUITES)
    +        )
    +        _assert_no_error(result)
    +
    +    def _set_alpn_protocols(self, protocols):
    +        """
    +        Sets up the ALPN protocols on the context.
    +        """
    +        if not protocols:
    +            return
    +        protocols_arr = _create_cfstring_array(protocols)
    +        try:
    +            result = Security.SSLSetALPNProtocols(self.context, protocols_arr)
    +            _assert_no_error(result)
    +        finally:
    +            CoreFoundation.CFRelease(protocols_arr)
    +
    +    def _custom_validate(self, verify, trust_bundle):
    +        """
    +        Called when we have set custom validation. We do this in two cases:
    +        first, when cert validation is entirely disabled; and second, when
    +        using a custom trust DB.
    +        Raises an SSLError if the connection is not trusted.
    +        """
    +        # If we disabled cert validation, just say: cool.
    +        if not verify:
    +            return
    +
    +        successes = (
    +            SecurityConst.kSecTrustResultUnspecified,
    +            SecurityConst.kSecTrustResultProceed,
    +        )
    +        try:
    +            trust_result = self._evaluate_trust(trust_bundle)
    +            if trust_result in successes:
    +                return
    +            reason = "error code: %d" % (trust_result,)
    +        except Exception as e:
    +            # Do not trust on error
    +            reason = "exception: %r" % (e,)
    +
    +        # SecureTransport does not send an alert nor shuts down the connection.
    +        rec = _build_tls_unknown_ca_alert(self.version())
    +        self.socket.sendall(rec)
    +        # close the connection immediately
    +        # l_onoff = 1, activate linger
    +        # l_linger = 0, linger for 0 seoncds
    +        opts = struct.pack("ii", 1, 0)
    +        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, opts)
    +        self.close()
    +        raise ssl.SSLError("certificate verify failed, %s" % reason)
    +
    +    def _evaluate_trust(self, trust_bundle):
    +        # We want data in memory, so load it up.
    +        if os.path.isfile(trust_bundle):
    +            with open(trust_bundle, "rb") as f:
    +                trust_bundle = f.read()
    +
    +        cert_array = None
    +        trust = Security.SecTrustRef()
    +
    +        try:
    +            # Get a CFArray that contains the certs we want.
    +            cert_array = _cert_array_from_pem(trust_bundle)
    +
    +            # Ok, now the hard part. We want to get the SecTrustRef that ST has
    +            # created for this connection, shove our CAs into it, tell ST to
    +            # ignore everything else it knows, and then ask if it can build a
    +            # chain. This is a buuuunch of code.
    +            result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust))
    +            _assert_no_error(result)
    +            if not trust:
    +                raise ssl.SSLError("Failed to copy trust reference")
    +
    +            result = Security.SecTrustSetAnchorCertificates(trust, cert_array)
    +            _assert_no_error(result)
    +
    +            result = Security.SecTrustSetAnchorCertificatesOnly(trust, True)
    +            _assert_no_error(result)
    +
    +            trust_result = Security.SecTrustResultType()
    +            result = Security.SecTrustEvaluate(trust, ctypes.byref(trust_result))
    +            _assert_no_error(result)
    +        finally:
    +            if trust:
    +                CoreFoundation.CFRelease(trust)
    +
    +            if cert_array is not None:
    +                CoreFoundation.CFRelease(cert_array)
    +
    +        return trust_result.value
    +
    +    def handshake(
    +        self,
    +        server_hostname,
    +        verify,
    +        trust_bundle,
    +        min_version,
    +        max_version,
    +        client_cert,
    +        client_key,
    +        client_key_passphrase,
    +        alpn_protocols,
    +    ):
    +        """
    +        Actually performs the TLS handshake. This is run automatically by
    +        wrapped socket, and shouldn't be needed in user code.
    +        """
    +        # First, we do the initial bits of connection setup. We need to create
    +        # a context, set its I/O funcs, and set the connection reference.
    +        self.context = Security.SSLCreateContext(
    +            None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType
    +        )
    +        result = Security.SSLSetIOFuncs(
    +            self.context, _read_callback_pointer, _write_callback_pointer
    +        )
    +        _assert_no_error(result)
    +
    +        # Here we need to compute the handle to use. We do this by taking the
    +        # id of self modulo 2**31 - 1. If this is already in the dictionary, we
    +        # just keep incrementing by one until we find a free space.
    +        with _connection_ref_lock:
    +            handle = id(self) % 2147483647
    +            while handle in _connection_refs:
    +                handle = (handle + 1) % 2147483647
    +            _connection_refs[handle] = self
    +
    +        result = Security.SSLSetConnection(self.context, handle)
    +        _assert_no_error(result)
    +
    +        # If we have a server hostname, we should set that too.
    +        if server_hostname:
    +            if not isinstance(server_hostname, bytes):
    +                server_hostname = server_hostname.encode("utf-8")
    +
    +            result = Security.SSLSetPeerDomainName(
    +                self.context, server_hostname, len(server_hostname)
    +            )
    +            _assert_no_error(result)
    +
    +        # Setup the ciphers.
    +        self._set_ciphers()
    +
    +        # Setup the ALPN protocols.
    +        self._set_alpn_protocols(alpn_protocols)
    +
    +        # Set the minimum and maximum TLS versions.
    +        result = Security.SSLSetProtocolVersionMin(self.context, min_version)
    +        _assert_no_error(result)
    +
    +        result = Security.SSLSetProtocolVersionMax(self.context, max_version)
    +        _assert_no_error(result)
    +
    +        # If there's a trust DB, we need to use it. We do that by telling
    +        # SecureTransport to break on server auth. We also do that if we don't
    +        # want to validate the certs at all: we just won't actually do any
    +        # authing in that case.
    +        if not verify or trust_bundle is not None:
    +            result = Security.SSLSetSessionOption(
    +                self.context, SecurityConst.kSSLSessionOptionBreakOnServerAuth, True
    +            )
    +            _assert_no_error(result)
    +
    +        # If there's a client cert, we need to use it.
    +        if client_cert:
    +            self._keychain, self._keychain_dir = _temporary_keychain()
    +            self._client_cert_chain = _load_client_cert_chain(
    +                self._keychain, client_cert, client_key
    +            )
    +            result = Security.SSLSetCertificate(self.context, self._client_cert_chain)
    +            _assert_no_error(result)
    +
    +        while True:
    +            with self._raise_on_error():
    +                result = Security.SSLHandshake(self.context)
    +
    +                if result == SecurityConst.errSSLWouldBlock:
    +                    raise socket.timeout("handshake timed out")
    +                elif result == SecurityConst.errSSLServerAuthCompleted:
    +                    self._custom_validate(verify, trust_bundle)
    +                    continue
    +                else:
    +                    _assert_no_error(result)
    +                    break
    +
    +    def fileno(self):
    +        return self.socket.fileno()
    +
    +    # Copy-pasted from Python 3.5 source code
    +    def _decref_socketios(self):
    +        if self._makefile_refs > 0:
    +            self._makefile_refs -= 1
    +        if self._closed:
    +            self.close()
    +
    +    def recv(self, bufsiz):
    +        buffer = ctypes.create_string_buffer(bufsiz)
    +        bytes_read = self.recv_into(buffer, bufsiz)
    +        data = buffer[:bytes_read]
    +        return data
    +
    +    def recv_into(self, buffer, nbytes=None):
    +        # Read short on EOF.
    +        if self._closed:
    +            return 0
    +
    +        if nbytes is None:
    +            nbytes = len(buffer)
    +
    +        buffer = (ctypes.c_char * nbytes).from_buffer(buffer)
    +        processed_bytes = ctypes.c_size_t(0)
    +
    +        with self._raise_on_error():
    +            result = Security.SSLRead(
    +                self.context, buffer, nbytes, ctypes.byref(processed_bytes)
    +            )
    +
    +        # There are some result codes that we want to treat as "not always
    +        # errors". Specifically, those are errSSLWouldBlock,
    +        # errSSLClosedGraceful, and errSSLClosedNoNotify.
    +        if result == SecurityConst.errSSLWouldBlock:
    +            # If we didn't process any bytes, then this was just a time out.
    +            # However, we can get errSSLWouldBlock in situations when we *did*
    +            # read some data, and in those cases we should just read "short"
    +            # and return.
    +            if processed_bytes.value == 0:
    +                # Timed out, no data read.
    +                raise socket.timeout("recv timed out")
    +        elif result in (
    +            SecurityConst.errSSLClosedGraceful,
    +            SecurityConst.errSSLClosedNoNotify,
    +        ):
    +            # The remote peer has closed this connection. We should do so as
    +            # well. Note that we don't actually return here because in
    +            # principle this could actually be fired along with return data.
    +            # It's unlikely though.
    +            self.close()
    +        else:
    +            _assert_no_error(result)
    +
    +        # Ok, we read and probably succeeded. We should return whatever data
    +        # was actually read.
    +        return processed_bytes.value
    +
    +    def settimeout(self, timeout):
    +        self._timeout = timeout
    +
    +    def gettimeout(self):
    +        return self._timeout
    +
    +    def send(self, data):
    +        processed_bytes = ctypes.c_size_t(0)
    +
    +        with self._raise_on_error():
    +            result = Security.SSLWrite(
    +                self.context, data, len(data), ctypes.byref(processed_bytes)
    +            )
    +
    +        if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0:
    +            # Timed out
    +            raise socket.timeout("send timed out")
    +        else:
    +            _assert_no_error(result)
    +
    +        # We sent, and probably succeeded. Tell them how much we sent.
    +        return processed_bytes.value
    +
    +    def sendall(self, data):
    +        total_sent = 0
    +        while total_sent < len(data):
    +            sent = self.send(data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE])
    +            total_sent += sent
    +
    +    def shutdown(self):
    +        with self._raise_on_error():
    +            Security.SSLClose(self.context)
    +
    +    def close(self):
    +        # TODO: should I do clean shutdown here? Do I have to?
    +        if self._makefile_refs < 1:
    +            self._closed = True
    +            if self.context:
    +                CoreFoundation.CFRelease(self.context)
    +                self.context = None
    +            if self._client_cert_chain:
    +                CoreFoundation.CFRelease(self._client_cert_chain)
    +                self._client_cert_chain = None
    +            if self._keychain:
    +                Security.SecKeychainDelete(self._keychain)
    +                CoreFoundation.CFRelease(self._keychain)
    +                shutil.rmtree(self._keychain_dir)
    +                self._keychain = self._keychain_dir = None
    +            return self.socket.close()
    +        else:
    +            self._makefile_refs -= 1
    +
    +    def getpeercert(self, binary_form=False):
    +        # Urgh, annoying.
    +        #
    +        # Here's how we do this:
    +        #
    +        # 1. Call SSLCopyPeerTrust to get hold of the trust object for this
    +        #    connection.
    +        # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf.
    +        # 3. To get the CN, call SecCertificateCopyCommonName and process that
    +        #    string so that it's of the appropriate type.
    +        # 4. To get the SAN, we need to do something a bit more complex:
    +        #    a. Call SecCertificateCopyValues to get the data, requesting
    +        #       kSecOIDSubjectAltName.
    +        #    b. Mess about with this dictionary to try to get the SANs out.
    +        #
    +        # This is gross. Really gross. It's going to be a few hundred LoC extra
    +        # just to repeat something that SecureTransport can *already do*. So my
    +        # operating assumption at this time is that what we want to do is
    +        # instead to just flag to urllib3 that it shouldn't do its own hostname
    +        # validation when using SecureTransport.
    +        if not binary_form:
    +            raise ValueError("SecureTransport only supports dumping binary certs")
    +        trust = Security.SecTrustRef()
    +        certdata = None
    +        der_bytes = None
    +
    +        try:
    +            # Grab the trust store.
    +            result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust))
    +            _assert_no_error(result)
    +            if not trust:
    +                # Probably we haven't done the handshake yet. No biggie.
    +                return None
    +
    +            cert_count = Security.SecTrustGetCertificateCount(trust)
    +            if not cert_count:
    +                # Also a case that might happen if we haven't handshaked.
    +                # Handshook? Handshaken?
    +                return None
    +
    +            leaf = Security.SecTrustGetCertificateAtIndex(trust, 0)
    +            assert leaf
    +
    +            # Ok, now we want the DER bytes.
    +            certdata = Security.SecCertificateCopyData(leaf)
    +            assert certdata
    +
    +            data_length = CoreFoundation.CFDataGetLength(certdata)
    +            data_buffer = CoreFoundation.CFDataGetBytePtr(certdata)
    +            der_bytes = ctypes.string_at(data_buffer, data_length)
    +        finally:
    +            if certdata:
    +                CoreFoundation.CFRelease(certdata)
    +            if trust:
    +                CoreFoundation.CFRelease(trust)
    +
    +        return der_bytes
    +
    +    def version(self):
    +        protocol = Security.SSLProtocol()
    +        result = Security.SSLGetNegotiatedProtocolVersion(
    +            self.context, ctypes.byref(protocol)
    +        )
    +        _assert_no_error(result)
    +        if protocol.value == SecurityConst.kTLSProtocol13:
    +            raise ssl.SSLError("SecureTransport does not support TLS 1.3")
    +        elif protocol.value == SecurityConst.kTLSProtocol12:
    +            return "TLSv1.2"
    +        elif protocol.value == SecurityConst.kTLSProtocol11:
    +            return "TLSv1.1"
    +        elif protocol.value == SecurityConst.kTLSProtocol1:
    +            return "TLSv1"
    +        elif protocol.value == SecurityConst.kSSLProtocol3:
    +            return "SSLv3"
    +        elif protocol.value == SecurityConst.kSSLProtocol2:
    +            return "SSLv2"
    +        else:
    +            raise ssl.SSLError("Unknown TLS version: %r" % protocol)
    +
    +    def _reuse(self):
    +        self._makefile_refs += 1
    +
    +    def _drop(self):
    +        if self._makefile_refs < 1:
    +            self.close()
    +        else:
    +            self._makefile_refs -= 1
    +
    +
    +if _fileobject:  # Platform-specific: Python 2
    +
    +    def makefile(self, mode, bufsize=-1):
    +        self._makefile_refs += 1
    +        return _fileobject(self, mode, bufsize, close=True)
    +
    +else:  # Platform-specific: Python 3
    +
    +    def makefile(self, mode="r", buffering=None, *args, **kwargs):
    +        # We disable buffering with SecureTransport because it conflicts with
    +        # the buffering that ST does internally (see issue #1153 for more).
    +        buffering = 0
    +        return backport_makefile(self, mode, buffering, *args, **kwargs)
    +
    +
    +WrappedSocket.makefile = makefile
    +
    +
    +class SecureTransportContext(object):
    +    """
    +    I am a wrapper class for the SecureTransport library, to translate the
    +    interface of the standard library ``SSLContext`` object to calls into
    +    SecureTransport.
    +    """
    +
    +    def __init__(self, protocol):
    +        self._min_version, self._max_version = _protocol_to_min_max[protocol]
    +        self._options = 0
    +        self._verify = False
    +        self._trust_bundle = None
    +        self._client_cert = None
    +        self._client_key = None
    +        self._client_key_passphrase = None
    +        self._alpn_protocols = None
    +
    +    @property
    +    def check_hostname(self):
    +        """
    +        SecureTransport cannot have its hostname checking disabled. For more,
    +        see the comment on getpeercert() in this file.
    +        """
    +        return True
    +
    +    @check_hostname.setter
    +    def check_hostname(self, value):
    +        """
    +        SecureTransport cannot have its hostname checking disabled. For more,
    +        see the comment on getpeercert() in this file.
    +        """
    +        pass
    +
    +    @property
    +    def options(self):
    +        # TODO: Well, crap.
    +        #
    +        # So this is the bit of the code that is the most likely to cause us
    +        # trouble. Essentially we need to enumerate all of the SSL options that
    +        # users might want to use and try to see if we can sensibly translate
    +        # them, or whether we should just ignore them.
    +        return self._options
    +
    +    @options.setter
    +    def options(self, value):
    +        # TODO: Update in line with above.
    +        self._options = value
    +
    +    @property
    +    def verify_mode(self):
    +        return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE
    +
    +    @verify_mode.setter
    +    def verify_mode(self, value):
    +        self._verify = True if value == ssl.CERT_REQUIRED else False
    +
    +    def set_default_verify_paths(self):
    +        # So, this has to do something a bit weird. Specifically, what it does
    +        # is nothing.
    +        #
    +        # This means that, if we had previously had load_verify_locations
    +        # called, this does not undo that. We need to do that because it turns
    +        # out that the rest of the urllib3 code will attempt to load the
    +        # default verify paths if it hasn't been told about any paths, even if
    +        # the context itself was sometime earlier. We resolve that by just
    +        # ignoring it.
    +        pass
    +
    +    def load_default_certs(self):
    +        return self.set_default_verify_paths()
    +
    +    def set_ciphers(self, ciphers):
    +        # For now, we just require the default cipher string.
    +        if ciphers != util.ssl_.DEFAULT_CIPHERS:
    +            raise ValueError("SecureTransport doesn't support custom cipher strings")
    +
    +    def load_verify_locations(self, cafile=None, capath=None, cadata=None):
    +        # OK, we only really support cadata and cafile.
    +        if capath is not None:
    +            raise ValueError("SecureTransport does not support cert directories")
    +
    +        # Raise if cafile does not exist.
    +        if cafile is not None:
    +            with open(cafile):
    +                pass
    +
    +        self._trust_bundle = cafile or cadata
    +
    +    def load_cert_chain(self, certfile, keyfile=None, password=None):
    +        self._client_cert = certfile
    +        self._client_key = keyfile
    +        self._client_cert_passphrase = password
    +
    +    def set_alpn_protocols(self, protocols):
    +        """
    +        Sets the ALPN protocols that will later be set on the context.
    +
    +        Raises a NotImplementedError if ALPN is not supported.
    +        """
    +        if not hasattr(Security, "SSLSetALPNProtocols"):
    +            raise NotImplementedError(
    +                "SecureTransport supports ALPN only in macOS 10.12+"
    +            )
    +        self._alpn_protocols = [six.ensure_binary(p) for p in protocols]
    +
    +    def wrap_socket(
    +        self,
    +        sock,
    +        server_side=False,
    +        do_handshake_on_connect=True,
    +        suppress_ragged_eofs=True,
    +        server_hostname=None,
    +    ):
    +        # So, what do we do here? Firstly, we assert some properties. This is a
    +        # stripped down shim, so there is some functionality we don't support.
    +        # See PEP 543 for the real deal.
    +        assert not server_side
    +        assert do_handshake_on_connect
    +        assert suppress_ragged_eofs
    +
    +        # Ok, we're good to go. Now we want to create the wrapped socket object
    +        # and store it in the appropriate place.
    +        wrapped_socket = WrappedSocket(sock)
    +
    +        # Now we can handshake
    +        wrapped_socket.handshake(
    +            server_hostname,
    +            self._verify,
    +            self._trust_bundle,
    +            self._min_version,
    +            self._max_version,
    +            self._client_cert,
    +            self._client_key,
    +            self._client_key_passphrase,
    +            self._alpn_protocols,
    +        )
    +        return wrapped_socket
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/socks.py b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/socks.py
    new file mode 100644
    index 0000000..c326e80
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/contrib/socks.py
    @@ -0,0 +1,216 @@
    +# -*- coding: utf-8 -*-
    +"""
    +This module contains provisional support for SOCKS proxies from within
    +urllib3. This module supports SOCKS4, SOCKS4A (an extension of SOCKS4), and
    +SOCKS5. To enable its functionality, either install PySocks or install this
    +module with the ``socks`` extra.
    +
    +The SOCKS implementation supports the full range of urllib3 features. It also
    +supports the following SOCKS features:
    +
    +- SOCKS4A (``proxy_url='socks4a://...``)
    +- SOCKS4 (``proxy_url='socks4://...``)
    +- SOCKS5 with remote DNS (``proxy_url='socks5h://...``)
    +- SOCKS5 with local DNS (``proxy_url='socks5://...``)
    +- Usernames and passwords for the SOCKS proxy
    +
    +.. note::
    +   It is recommended to use ``socks5h://`` or ``socks4a://`` schemes in
    +   your ``proxy_url`` to ensure that DNS resolution is done from the remote
    +   server instead of client-side when connecting to a domain name.
    +
    +SOCKS4 supports IPv4 and domain names with the SOCKS4A extension. SOCKS5
    +supports IPv4, IPv6, and domain names.
    +
    +When connecting to a SOCKS4 proxy the ``username`` portion of the ``proxy_url``
    +will be sent as the ``userid`` section of the SOCKS request:
    +
    +.. code-block:: python
    +
    +    proxy_url="socks4a://<userid>@proxy-host"
    +
    +When connecting to a SOCKS5 proxy the ``username`` and ``password`` portion
    +of the ``proxy_url`` will be sent as the username/password to authenticate
    +with the proxy:
    +
    +.. code-block:: python
    +
    +    proxy_url="socks5h://<username>:<password>@proxy-host"
    +
    +"""
    +from __future__ import absolute_import
    +
    +try:
    +    import socks
    +except ImportError:
    +    import warnings
    +
    +    from ..exceptions import DependencyWarning
    +
    +    warnings.warn(
    +        (
    +            "SOCKS support in urllib3 requires the installation of optional "
    +            "dependencies: specifically, PySocks.  For more information, see "
    +            "https://urllib3.readthedocs.io/en/1.26.x/contrib.html#socks-proxies"
    +        ),
    +        DependencyWarning,
    +    )
    +    raise
    +
    +from socket import error as SocketError
    +from socket import timeout as SocketTimeout
    +
    +from ..connection import HTTPConnection, HTTPSConnection
    +from ..connectionpool import HTTPConnectionPool, HTTPSConnectionPool
    +from ..exceptions import ConnectTimeoutError, NewConnectionError
    +from ..poolmanager import PoolManager
    +from ..util.url import parse_url
    +
    +try:
    +    import ssl
    +except ImportError:
    +    ssl = None
    +
    +
    +class SOCKSConnection(HTTPConnection):
    +    """
    +    A plain-text HTTP connection that connects via a SOCKS proxy.
    +    """
    +
    +    def __init__(self, *args, **kwargs):
    +        self._socks_options = kwargs.pop("_socks_options")
    +        super(SOCKSConnection, self).__init__(*args, **kwargs)
    +
    +    def _new_conn(self):
    +        """
    +        Establish a new connection via the SOCKS proxy.
    +        """
    +        extra_kw = {}
    +        if self.source_address:
    +            extra_kw["source_address"] = self.source_address
    +
    +        if self.socket_options:
    +            extra_kw["socket_options"] = self.socket_options
    +
    +        try:
    +            conn = socks.create_connection(
    +                (self.host, self.port),
    +                proxy_type=self._socks_options["socks_version"],
    +                proxy_addr=self._socks_options["proxy_host"],
    +                proxy_port=self._socks_options["proxy_port"],
    +                proxy_username=self._socks_options["username"],
    +                proxy_password=self._socks_options["password"],
    +                proxy_rdns=self._socks_options["rdns"],
    +                timeout=self.timeout,
    +                **extra_kw
    +            )
    +
    +        except SocketTimeout:
    +            raise ConnectTimeoutError(
    +                self,
    +                "Connection to %s timed out. (connect timeout=%s)"
    +                % (self.host, self.timeout),
    +            )
    +
    +        except socks.ProxyError as e:
    +            # This is fragile as hell, but it seems to be the only way to raise
    +            # useful errors here.
    +            if e.socket_err:
    +                error = e.socket_err
    +                if isinstance(error, SocketTimeout):
    +                    raise ConnectTimeoutError(
    +                        self,
    +                        "Connection to %s timed out. (connect timeout=%s)"
    +                        % (self.host, self.timeout),
    +                    )
    +                else:
    +                    raise NewConnectionError(
    +                        self, "Failed to establish a new connection: %s" % error
    +                    )
    +            else:
    +                raise NewConnectionError(
    +                    self, "Failed to establish a new connection: %s" % e
    +                )
    +
    +        except SocketError as e:  # Defensive: PySocks should catch all these.
    +            raise NewConnectionError(
    +                self, "Failed to establish a new connection: %s" % e
    +            )
    +
    +        return conn
    +
    +
    +# We don't need to duplicate the Verified/Unverified distinction from
    +# urllib3/connection.py here because the HTTPSConnection will already have been
    +# correctly set to either the Verified or Unverified form by that module. This
    +# means the SOCKSHTTPSConnection will automatically be the correct type.
    +class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection):
    +    pass
    +
    +
    +class SOCKSHTTPConnectionPool(HTTPConnectionPool):
    +    ConnectionCls = SOCKSConnection
    +
    +
    +class SOCKSHTTPSConnectionPool(HTTPSConnectionPool):
    +    ConnectionCls = SOCKSHTTPSConnection
    +
    +
    +class SOCKSProxyManager(PoolManager):
    +    """
    +    A version of the urllib3 ProxyManager that routes connections via the
    +    defined SOCKS proxy.
    +    """
    +
    +    pool_classes_by_scheme = {
    +        "http": SOCKSHTTPConnectionPool,
    +        "https": SOCKSHTTPSConnectionPool,
    +    }
    +
    +    def __init__(
    +        self,
    +        proxy_url,
    +        username=None,
    +        password=None,
    +        num_pools=10,
    +        headers=None,
    +        **connection_pool_kw
    +    ):
    +        parsed = parse_url(proxy_url)
    +
    +        if username is None and password is None and parsed.auth is not None:
    +            split = parsed.auth.split(":")
    +            if len(split) == 2:
    +                username, password = split
    +        if parsed.scheme == "socks5":
    +            socks_version = socks.PROXY_TYPE_SOCKS5
    +            rdns = False
    +        elif parsed.scheme == "socks5h":
    +            socks_version = socks.PROXY_TYPE_SOCKS5
    +            rdns = True
    +        elif parsed.scheme == "socks4":
    +            socks_version = socks.PROXY_TYPE_SOCKS4
    +            rdns = False
    +        elif parsed.scheme == "socks4a":
    +            socks_version = socks.PROXY_TYPE_SOCKS4
    +            rdns = True
    +        else:
    +            raise ValueError("Unable to determine SOCKS version from %s" % proxy_url)
    +
    +        self.proxy_url = proxy_url
    +
    +        socks_options = {
    +            "socks_version": socks_version,
    +            "proxy_host": parsed.host,
    +            "proxy_port": parsed.port,
    +            "username": username,
    +            "password": password,
    +            "rdns": rdns,
    +        }
    +        connection_pool_kw["_socks_options"] = socks_options
    +
    +        super(SOCKSProxyManager, self).__init__(
    +            num_pools, headers, **connection_pool_kw
    +        )
    +
    +        self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/exceptions.py b/deployment-apps/metricator-for-nmon/lib/urllib3/exceptions.py
    new file mode 100644
    index 0000000..cba6f3f
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/exceptions.py
    @@ -0,0 +1,323 @@
    +from __future__ import absolute_import
    +
    +from .packages.six.moves.http_client import IncompleteRead as httplib_IncompleteRead
    +
    +# Base Exceptions
    +
    +
    +class HTTPError(Exception):
    +    """Base exception used by this module."""
    +
    +    pass
    +
    +
    +class HTTPWarning(Warning):
    +    """Base warning used by this module."""
    +
    +    pass
    +
    +
    +class PoolError(HTTPError):
    +    """Base exception for errors caused within a pool."""
    +
    +    def __init__(self, pool, message):
    +        self.pool = pool
    +        HTTPError.__init__(self, "%s: %s" % (pool, message))
    +
    +    def __reduce__(self):
    +        # For pickling purposes.
    +        return self.__class__, (None, None)
    +
    +
    +class RequestError(PoolError):
    +    """Base exception for PoolErrors that have associated URLs."""
    +
    +    def __init__(self, pool, url, message):
    +        self.url = url
    +        PoolError.__init__(self, pool, message)
    +
    +    def __reduce__(self):
    +        # For pickling purposes.
    +        return self.__class__, (None, self.url, None)
    +
    +
    +class SSLError(HTTPError):
    +    """Raised when SSL certificate fails in an HTTPS connection."""
    +
    +    pass
    +
    +
    +class ProxyError(HTTPError):
    +    """Raised when the connection to a proxy fails."""
    +
    +    def __init__(self, message, error, *args):
    +        super(ProxyError, self).__init__(message, error, *args)
    +        self.original_error = error
    +
    +
    +class DecodeError(HTTPError):
    +    """Raised when automatic decoding based on Content-Type fails."""
    +
    +    pass
    +
    +
    +class ProtocolError(HTTPError):
    +    """Raised when something unexpected happens mid-request/response."""
    +
    +    pass
    +
    +
    +#: Renamed to ProtocolError but aliased for backwards compatibility.
    +ConnectionError = ProtocolError
    +
    +
    +# Leaf Exceptions
    +
    +
    +class MaxRetryError(RequestError):
    +    """Raised when the maximum number of retries is exceeded.
    +
    +    :param pool: The connection pool
    +    :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool`
    +    :param string url: The requested Url
    +    :param exceptions.Exception reason: The underlying error
    +
    +    """
    +
    +    def __init__(self, pool, url, reason=None):
    +        self.reason = reason
    +
    +        message = "Max retries exceeded with url: %s (Caused by %r)" % (url, reason)
    +
    +        RequestError.__init__(self, pool, url, message)
    +
    +
    +class HostChangedError(RequestError):
    +    """Raised when an existing pool gets a request for a foreign host."""
    +
    +    def __init__(self, pool, url, retries=3):
    +        message = "Tried to open a foreign host with url: %s" % url
    +        RequestError.__init__(self, pool, url, message)
    +        self.retries = retries
    +
    +
    +class TimeoutStateError(HTTPError):
    +    """Raised when passing an invalid state to a timeout"""
    +
    +    pass
    +
    +
    +class TimeoutError(HTTPError):
    +    """Raised when a socket timeout error occurs.
    +
    +    Catching this error will catch both :exc:`ReadTimeoutErrors
    +    <ReadTimeoutError>` and :exc:`ConnectTimeoutErrors <ConnectTimeoutError>`.
    +    """
    +
    +    pass
    +
    +
    +class ReadTimeoutError(TimeoutError, RequestError):
    +    """Raised when a socket timeout occurs while receiving data from a server"""
    +
    +    pass
    +
    +
    +# This timeout error does not have a URL attached and needs to inherit from the
    +# base HTTPError
    +class ConnectTimeoutError(TimeoutError):
    +    """Raised when a socket timeout occurs while connecting to a server"""
    +
    +    pass
    +
    +
    +class NewConnectionError(ConnectTimeoutError, PoolError):
    +    """Raised when we fail to establish a new connection. Usually ECONNREFUSED."""
    +
    +    pass
    +
    +
    +class EmptyPoolError(PoolError):
    +    """Raised when a pool runs out of connections and no more are allowed."""
    +
    +    pass
    +
    +
    +class ClosedPoolError(PoolError):
    +    """Raised when a request enters a pool after the pool has been closed."""
    +
    +    pass
    +
    +
    +class LocationValueError(ValueError, HTTPError):
    +    """Raised when there is something wrong with a given URL input."""
    +
    +    pass
    +
    +
    +class LocationParseError(LocationValueError):
    +    """Raised when get_host or similar fails to parse the URL input."""
    +
    +    def __init__(self, location):
    +        message = "Failed to parse: %s" % location
    +        HTTPError.__init__(self, message)
    +
    +        self.location = location
    +
    +
    +class URLSchemeUnknown(LocationValueError):
    +    """Raised when a URL input has an unsupported scheme."""
    +
    +    def __init__(self, scheme):
    +        message = "Not supported URL scheme %s" % scheme
    +        super(URLSchemeUnknown, self).__init__(message)
    +
    +        self.scheme = scheme
    +
    +
    +class ResponseError(HTTPError):
    +    """Used as a container for an error reason supplied in a MaxRetryError."""
    +
    +    GENERIC_ERROR = "too many error responses"
    +    SPECIFIC_ERROR = "too many {status_code} error responses"
    +
    +
    +class SecurityWarning(HTTPWarning):
    +    """Warned when performing security reducing actions"""
    +
    +    pass
    +
    +
    +class SubjectAltNameWarning(SecurityWarning):
    +    """Warned when connecting to a host with a certificate missing a SAN."""
    +
    +    pass
    +
    +
    +class InsecureRequestWarning(SecurityWarning):
    +    """Warned when making an unverified HTTPS request."""
    +
    +    pass
    +
    +
    +class SystemTimeWarning(SecurityWarning):
    +    """Warned when system time is suspected to be wrong"""
    +
    +    pass
    +
    +
    +class InsecurePlatformWarning(SecurityWarning):
    +    """Warned when certain TLS/SSL configuration is not available on a platform."""
    +
    +    pass
    +
    +
    +class SNIMissingWarning(HTTPWarning):
    +    """Warned when making a HTTPS request without SNI available."""
    +
    +    pass
    +
    +
    +class DependencyWarning(HTTPWarning):
    +    """
    +    Warned when an attempt is made to import a module with missing optional
    +    dependencies.
    +    """
    +
    +    pass
    +
    +
    +class ResponseNotChunked(ProtocolError, ValueError):
    +    """Response needs to be chunked in order to read it as chunks."""
    +
    +    pass
    +
    +
    +class BodyNotHttplibCompatible(HTTPError):
    +    """
    +    Body should be :class:`http.client.HTTPResponse` like
    +    (have an fp attribute which returns raw chunks) for read_chunked().
    +    """
    +
    +    pass
    +
    +
    +class IncompleteRead(HTTPError, httplib_IncompleteRead):
    +    """
    +    Response length doesn't match expected Content-Length
    +
    +    Subclass of :class:`http.client.IncompleteRead` to allow int value
    +    for ``partial`` to avoid creating large objects on streamed reads.
    +    """
    +
    +    def __init__(self, partial, expected):
    +        super(IncompleteRead, self).__init__(partial, expected)
    +
    +    def __repr__(self):
    +        return "IncompleteRead(%i bytes read, %i more expected)" % (
    +            self.partial,
    +            self.expected,
    +        )
    +
    +
    +class InvalidChunkLength(HTTPError, httplib_IncompleteRead):
    +    """Invalid chunk length in a chunked response."""
    +
    +    def __init__(self, response, length):
    +        super(InvalidChunkLength, self).__init__(
    +            response.tell(), response.length_remaining
    +        )
    +        self.response = response
    +        self.length = length
    +
    +    def __repr__(self):
    +        return "InvalidChunkLength(got length %r, %i bytes read)" % (
    +            self.length,
    +            self.partial,
    +        )
    +
    +
    +class InvalidHeader(HTTPError):
    +    """The header provided was somehow invalid."""
    +
    +    pass
    +
    +
    +class ProxySchemeUnknown(AssertionError, URLSchemeUnknown):
    +    """ProxyManager does not support the supplied scheme"""
    +
    +    # TODO(t-8ch): Stop inheriting from AssertionError in v2.0.
    +
    +    def __init__(self, scheme):
    +        # 'localhost' is here because our URL parser parses
    +        # localhost:8080 -> scheme=localhost, remove if we fix this.
    +        if scheme == "localhost":
    +            scheme = None
    +        if scheme is None:
    +            message = "Proxy URL had no scheme, should start with http:// or https://"
    +        else:
    +            message = (
    +                "Proxy URL had unsupported scheme %s, should use http:// or https://"
    +                % scheme
    +            )
    +        super(ProxySchemeUnknown, self).__init__(message)
    +
    +
    +class ProxySchemeUnsupported(ValueError):
    +    """Fetching HTTPS resources through HTTPS proxies is unsupported"""
    +
    +    pass
    +
    +
    +class HeaderParsingError(HTTPError):
    +    """Raised by assert_header_parsing, but we convert it to a log.warning statement."""
    +
    +    def __init__(self, defects, unparsed_data):
    +        message = "%s, unparsed data: %r" % (defects or "Unknown", unparsed_data)
    +        super(HeaderParsingError, self).__init__(message)
    +
    +
    +class UnrewindableBodyError(HTTPError):
    +    """urllib3 encountered an error when trying to rewind a body"""
    +
    +    pass
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/fields.py b/deployment-apps/metricator-for-nmon/lib/urllib3/fields.py
    new file mode 100644
    index 0000000..9d630f4
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/fields.py
    @@ -0,0 +1,274 @@
    +from __future__ import absolute_import
    +
    +import email.utils
    +import mimetypes
    +import re
    +
    +from .packages import six
    +
    +
    +def guess_content_type(filename, default="application/octet-stream"):
    +    """
    +    Guess the "Content-Type" of a file.
    +
    +    :param filename:
    +        The filename to guess the "Content-Type" of using :mod:`mimetypes`.
    +    :param default:
    +        If no "Content-Type" can be guessed, default to `default`.
    +    """
    +    if filename:
    +        return mimetypes.guess_type(filename)[0] or default
    +    return default
    +
    +
    +def format_header_param_rfc2231(name, value):
    +    """
    +    Helper function to format and quote a single header parameter using the
    +    strategy defined in RFC 2231.
    +
    +    Particularly useful for header parameters which might contain
    +    non-ASCII values, like file names. This follows
    +    `RFC 2388 Section 4.4 <https://tools.ietf.org/html/rfc2388#section-4.4>`_.
    +
    +    :param name:
    +        The name of the parameter, a string expected to be ASCII only.
    +    :param value:
    +        The value of the parameter, provided as ``bytes`` or `str``.
    +    :ret:
    +        An RFC-2231-formatted unicode string.
    +    """
    +    if isinstance(value, six.binary_type):
    +        value = value.decode("utf-8")
    +
    +    if not any(ch in value for ch in '"\\\r\n'):
    +        result = u'%s="%s"' % (name, value)
    +        try:
    +            result.encode("ascii")
    +        except (UnicodeEncodeError, UnicodeDecodeError):
    +            pass
    +        else:
    +            return result
    +
    +    if six.PY2:  # Python 2:
    +        value = value.encode("utf-8")
    +
    +    # encode_rfc2231 accepts an encoded string and returns an ascii-encoded
    +    # string in Python 2 but accepts and returns unicode strings in Python 3
    +    value = email.utils.encode_rfc2231(value, "utf-8")
    +    value = "%s*=%s" % (name, value)
    +
    +    if six.PY2:  # Python 2:
    +        value = value.decode("utf-8")
    +
    +    return value
    +
    +
    +_HTML5_REPLACEMENTS = {
    +    u"\u0022": u"%22",
    +    # Replace "\" with "\\".
    +    u"\u005C": u"\u005C\u005C",
    +}
    +
    +# All control characters from 0x00 to 0x1F *except* 0x1B.
    +_HTML5_REPLACEMENTS.update(
    +    {
    +        six.unichr(cc): u"%{:02X}".format(cc)
    +        for cc in range(0x00, 0x1F + 1)
    +        if cc not in (0x1B,)
    +    }
    +)
    +
    +
    +def _replace_multiple(value, needles_and_replacements):
    +    def replacer(match):
    +        return needles_and_replacements[match.group(0)]
    +
    +    pattern = re.compile(
    +        r"|".join([re.escape(needle) for needle in needles_and_replacements.keys()])
    +    )
    +
    +    result = pattern.sub(replacer, value)
    +
    +    return result
    +
    +
    +def format_header_param_html5(name, value):
    +    """
    +    Helper function to format and quote a single header parameter using the
    +    HTML5 strategy.
    +
    +    Particularly useful for header parameters which might contain
    +    non-ASCII values, like file names. This follows the `HTML5 Working Draft
    +    Section 4.10.22.7`_ and matches the behavior of curl and modern browsers.
    +
    +    .. _HTML5 Working Draft Section 4.10.22.7:
    +        https://w3c.github.io/html/sec-forms.html#multipart-form-data
    +
    +    :param name:
    +        The name of the parameter, a string expected to be ASCII only.
    +    :param value:
    +        The value of the parameter, provided as ``bytes`` or `str``.
    +    :ret:
    +        A unicode string, stripped of troublesome characters.
    +    """
    +    if isinstance(value, six.binary_type):
    +        value = value.decode("utf-8")
    +
    +    value = _replace_multiple(value, _HTML5_REPLACEMENTS)
    +
    +    return u'%s="%s"' % (name, value)
    +
    +
    +# For backwards-compatibility.
    +format_header_param = format_header_param_html5
    +
    +
    +class RequestField(object):
    +    """
    +    A data container for request body parameters.
    +
    +    :param name:
    +        The name of this request field. Must be unicode.
    +    :param data:
    +        The data/value body.
    +    :param filename:
    +        An optional filename of the request field. Must be unicode.
    +    :param headers:
    +        An optional dict-like object of headers to initially use for the field.
    +    :param header_formatter:
    +        An optional callable that is used to encode and format the headers. By
    +        default, this is :func:`format_header_param_html5`.
    +    """
    +
    +    def __init__(
    +        self,
    +        name,
    +        data,
    +        filename=None,
    +        headers=None,
    +        header_formatter=format_header_param_html5,
    +    ):
    +        self._name = name
    +        self._filename = filename
    +        self.data = data
    +        self.headers = {}
    +        if headers:
    +            self.headers = dict(headers)
    +        self.header_formatter = header_formatter
    +
    +    @classmethod
    +    def from_tuples(cls, fieldname, value, header_formatter=format_header_param_html5):
    +        """
    +        A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters.
    +
    +        Supports constructing :class:`~urllib3.fields.RequestField` from
    +        parameter of key/value strings AND key/filetuple. A filetuple is a
    +        (filename, data, MIME type) tuple where the MIME type is optional.
    +        For example::
    +
    +            'foo': 'bar',
    +            'fakefile': ('foofile.txt', 'contents of foofile'),
    +            'realfile': ('barfile.txt', open('realfile').read()),
    +            'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'),
    +            'nonamefile': 'contents of nonamefile field',
    +
    +        Field names and filenames must be unicode.
    +        """
    +        if isinstance(value, tuple):
    +            if len(value) == 3:
    +                filename, data, content_type = value
    +            else:
    +                filename, data = value
    +                content_type = guess_content_type(filename)
    +        else:
    +            filename = None
    +            content_type = None
    +            data = value
    +
    +        request_param = cls(
    +            fieldname, data, filename=filename, header_formatter=header_formatter
    +        )
    +        request_param.make_multipart(content_type=content_type)
    +
    +        return request_param
    +
    +    def _render_part(self, name, value):
    +        """
    +        Overridable helper function to format a single header parameter. By
    +        default, this calls ``self.header_formatter``.
    +
    +        :param name:
    +            The name of the parameter, a string expected to be ASCII only.
    +        :param value:
    +            The value of the parameter, provided as a unicode string.
    +        """
    +
    +        return self.header_formatter(name, value)
    +
    +    def _render_parts(self, header_parts):
    +        """
    +        Helper function to format and quote a single header.
    +
    +        Useful for single headers that are composed of multiple items. E.g.,
    +        'Content-Disposition' fields.
    +
    +        :param header_parts:
    +            A sequence of (k, v) tuples or a :class:`dict` of (k, v) to format
    +            as `k1="v1"; k2="v2"; ...`.
    +        """
    +        parts = []
    +        iterable = header_parts
    +        if isinstance(header_parts, dict):
    +            iterable = header_parts.items()
    +
    +        for name, value in iterable:
    +            if value is not None:
    +                parts.append(self._render_part(name, value))
    +
    +        return u"; ".join(parts)
    +
    +    def render_headers(self):
    +        """
    +        Renders the headers for this request field.
    +        """
    +        lines = []
    +
    +        sort_keys = ["Content-Disposition", "Content-Type", "Content-Location"]
    +        for sort_key in sort_keys:
    +            if self.headers.get(sort_key, False):
    +                lines.append(u"%s: %s" % (sort_key, self.headers[sort_key]))
    +
    +        for header_name, header_value in self.headers.items():
    +            if header_name not in sort_keys:
    +                if header_value:
    +                    lines.append(u"%s: %s" % (header_name, header_value))
    +
    +        lines.append(u"\r\n")
    +        return u"\r\n".join(lines)
    +
    +    def make_multipart(
    +        self, content_disposition=None, content_type=None, content_location=None
    +    ):
    +        """
    +        Makes this request field into a multipart request field.
    +
    +        This method overrides "Content-Disposition", "Content-Type" and
    +        "Content-Location" headers to the request parameter.
    +
    +        :param content_type:
    +            The 'Content-Type' of the request body.
    +        :param content_location:
    +            The 'Content-Location' of the request body.
    +
    +        """
    +        self.headers["Content-Disposition"] = content_disposition or u"form-data"
    +        self.headers["Content-Disposition"] += u"; ".join(
    +            [
    +                u"",
    +                self._render_parts(
    +                    ((u"name", self._name), (u"filename", self._filename))
    +                ),
    +            ]
    +        )
    +        self.headers["Content-Type"] = content_type
    +        self.headers["Content-Location"] = content_location
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/filepost.py b/deployment-apps/metricator-for-nmon/lib/urllib3/filepost.py
    new file mode 100644
    index 0000000..36c9252
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/filepost.py
    @@ -0,0 +1,98 @@
    +from __future__ import absolute_import
    +
    +import binascii
    +import codecs
    +import os
    +from io import BytesIO
    +
    +from .fields import RequestField
    +from .packages import six
    +from .packages.six import b
    +
    +writer = codecs.lookup("utf-8")[3]
    +
    +
    +def choose_boundary():
    +    """
    +    Our embarrassingly-simple replacement for mimetools.choose_boundary.
    +    """
    +    boundary = binascii.hexlify(os.urandom(16))
    +    if not six.PY2:
    +        boundary = boundary.decode("ascii")
    +    return boundary
    +
    +
    +def iter_field_objects(fields):
    +    """
    +    Iterate over fields.
    +
    +    Supports list of (k, v) tuples and dicts, and lists of
    +    :class:`~urllib3.fields.RequestField`.
    +
    +    """
    +    if isinstance(fields, dict):
    +        i = six.iteritems(fields)
    +    else:
    +        i = iter(fields)
    +
    +    for field in i:
    +        if isinstance(field, RequestField):
    +            yield field
    +        else:
    +            yield RequestField.from_tuples(*field)
    +
    +
    +def iter_fields(fields):
    +    """
    +    .. deprecated:: 1.6
    +
    +    Iterate over fields.
    +
    +    The addition of :class:`~urllib3.fields.RequestField` makes this function
    +    obsolete. Instead, use :func:`iter_field_objects`, which returns
    +    :class:`~urllib3.fields.RequestField` objects.
    +
    +    Supports list of (k, v) tuples and dicts.
    +    """
    +    if isinstance(fields, dict):
    +        return ((k, v) for k, v in six.iteritems(fields))
    +
    +    return ((k, v) for k, v in fields)
    +
    +
    +def encode_multipart_formdata(fields, boundary=None):
    +    """
    +    Encode a dictionary of ``fields`` using the multipart/form-data MIME format.
    +
    +    :param fields:
    +        Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`).
    +
    +    :param boundary:
    +        If not specified, then a random boundary will be generated using
    +        :func:`urllib3.filepost.choose_boundary`.
    +    """
    +    body = BytesIO()
    +    if boundary is None:
    +        boundary = choose_boundary()
    +
    +    for field in iter_field_objects(fields):
    +        body.write(b("--%s\r\n" % (boundary)))
    +
    +        writer(body).write(field.render_headers())
    +        data = field.data
    +
    +        if isinstance(data, int):
    +            data = str(data)  # Backwards compatibility
    +
    +        if isinstance(data, six.text_type):
    +            writer(body).write(data)
    +        else:
    +            body.write(data)
    +
    +        body.write(b"\r\n")
    +
    +    body.write(b("--%s--\r\n" % (boundary)))
    +
    +    content_type = str("multipart/form-data; boundary=%s" % boundary)
    +
    +    return body.getvalue(), content_type
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/packages/__init__.py b/deployment-apps/metricator-for-nmon/lib/urllib3/packages/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/packages/backports/__init__.py b/deployment-apps/metricator-for-nmon/lib/urllib3/packages/backports/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/packages/backports/makefile.py b/deployment-apps/metricator-for-nmon/lib/urllib3/packages/backports/makefile.py
    new file mode 100644
    index 0000000..b8fb215
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/packages/backports/makefile.py
    @@ -0,0 +1,51 @@
    +# -*- coding: utf-8 -*-
    +"""
    +backports.makefile
    +~~~~~~~~~~~~~~~~~~
    +
    +Backports the Python 3 ``socket.makefile`` method for use with anything that
    +wants to create a "fake" socket object.
    +"""
    +import io
    +from socket import SocketIO
    +
    +
    +def backport_makefile(
    +    self, mode="r", buffering=None, encoding=None, errors=None, newline=None
    +):
    +    """
    +    Backport of ``socket.makefile`` from Python 3.5.
    +    """
    +    if not set(mode) <= {"r", "w", "b"}:
    +        raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,))
    +    writing = "w" in mode
    +    reading = "r" in mode or not writing
    +    assert reading or writing
    +    binary = "b" in mode
    +    rawmode = ""
    +    if reading:
    +        rawmode += "r"
    +    if writing:
    +        rawmode += "w"
    +    raw = SocketIO(self, rawmode)
    +    self._makefile_refs += 1
    +    if buffering is None:
    +        buffering = -1
    +    if buffering < 0:
    +        buffering = io.DEFAULT_BUFFER_SIZE
    +    if buffering == 0:
    +        if not binary:
    +            raise ValueError("unbuffered streams must be binary")
    +        return raw
    +    if reading and writing:
    +        buffer = io.BufferedRWPair(raw, raw, buffering)
    +    elif reading:
    +        buffer = io.BufferedReader(raw, buffering)
    +    else:
    +        assert writing
    +        buffer = io.BufferedWriter(raw, buffering)
    +    if binary:
    +        return buffer
    +    text = io.TextIOWrapper(buffer, encoding, errors, newline)
    +    text.mode = mode
    +    return text
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/packages/six.py b/deployment-apps/metricator-for-nmon/lib/urllib3/packages/six.py
    new file mode 100644
    index 0000000..f099a3d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/packages/six.py
    @@ -0,0 +1,1076 @@
    +# Copyright (c) 2010-2020 Benjamin Peterson
    +#
    +# Permission is hereby granted, free of charge, to any person obtaining a copy
    +# of this software and associated documentation files (the "Software"), to deal
    +# in the Software without restriction, including without limitation the rights
    +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +# copies of the Software, and to permit persons to whom the Software is
    +# furnished to do so, subject to the following conditions:
    +#
    +# The above copyright notice and this permission notice shall be included in all
    +# copies or substantial portions of the Software.
    +#
    +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    +# SOFTWARE.
    +
    +"""Utilities for writing code that runs on Python 2 and 3"""
    +
    +from __future__ import absolute_import
    +
    +import functools
    +import itertools
    +import operator
    +import sys
    +import types
    +
    +__author__ = "Benjamin Peterson <benjamin@python.org>"
    +__version__ = "1.16.0"
    +
    +
    +# Useful for very coarse version differentiation.
    +PY2 = sys.version_info[0] == 2
    +PY3 = sys.version_info[0] == 3
    +PY34 = sys.version_info[0:2] >= (3, 4)
    +
    +if PY3:
    +    string_types = (str,)
    +    integer_types = (int,)
    +    class_types = (type,)
    +    text_type = str
    +    binary_type = bytes
    +
    +    MAXSIZE = sys.maxsize
    +else:
    +    string_types = (basestring,)
    +    integer_types = (int, long)
    +    class_types = (type, types.ClassType)
    +    text_type = unicode
    +    binary_type = str
    +
    +    if sys.platform.startswith("java"):
    +        # Jython always uses 32 bits.
    +        MAXSIZE = int((1 << 31) - 1)
    +    else:
    +        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
    +        class X(object):
    +            def __len__(self):
    +                return 1 << 31
    +
    +        try:
    +            len(X())
    +        except OverflowError:
    +            # 32-bit
    +            MAXSIZE = int((1 << 31) - 1)
    +        else:
    +            # 64-bit
    +            MAXSIZE = int((1 << 63) - 1)
    +        del X
    +
    +if PY34:
    +    from importlib.util import spec_from_loader
    +else:
    +    spec_from_loader = None
    +
    +
    +def _add_doc(func, doc):
    +    """Add documentation to a function."""
    +    func.__doc__ = doc
    +
    +
    +def _import_module(name):
    +    """Import module, returning the module after the last dot."""
    +    __import__(name)
    +    return sys.modules[name]
    +
    +
    +class _LazyDescr(object):
    +    def __init__(self, name):
    +        self.name = name
    +
    +    def __get__(self, obj, tp):
    +        result = self._resolve()
    +        setattr(obj, self.name, result)  # Invokes __set__.
    +        try:
    +            # This is a bit ugly, but it avoids running this again by
    +            # removing this descriptor.
    +            delattr(obj.__class__, self.name)
    +        except AttributeError:
    +            pass
    +        return result
    +
    +
    +class MovedModule(_LazyDescr):
    +    def __init__(self, name, old, new=None):
    +        super(MovedModule, self).__init__(name)
    +        if PY3:
    +            if new is None:
    +                new = name
    +            self.mod = new
    +        else:
    +            self.mod = old
    +
    +    def _resolve(self):
    +        return _import_module(self.mod)
    +
    +    def __getattr__(self, attr):
    +        _module = self._resolve()
    +        value = getattr(_module, attr)
    +        setattr(self, attr, value)
    +        return value
    +
    +
    +class _LazyModule(types.ModuleType):
    +    def __init__(self, name):
    +        super(_LazyModule, self).__init__(name)
    +        self.__doc__ = self.__class__.__doc__
    +
    +    def __dir__(self):
    +        attrs = ["__doc__", "__name__"]
    +        attrs += [attr.name for attr in self._moved_attributes]
    +        return attrs
    +
    +    # Subclasses should override this
    +    _moved_attributes = []
    +
    +
    +class MovedAttribute(_LazyDescr):
    +    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
    +        super(MovedAttribute, self).__init__(name)
    +        if PY3:
    +            if new_mod is None:
    +                new_mod = name
    +            self.mod = new_mod
    +            if new_attr is None:
    +                if old_attr is None:
    +                    new_attr = name
    +                else:
    +                    new_attr = old_attr
    +            self.attr = new_attr
    +        else:
    +            self.mod = old_mod
    +            if old_attr is None:
    +                old_attr = name
    +            self.attr = old_attr
    +
    +    def _resolve(self):
    +        module = _import_module(self.mod)
    +        return getattr(module, self.attr)
    +
    +
    +class _SixMetaPathImporter(object):
    +
    +    """
    +    A meta path importer to import six.moves and its submodules.
    +
    +    This class implements a PEP302 finder and loader. It should be compatible
    +    with Python 2.5 and all existing versions of Python3
    +    """
    +
    +    def __init__(self, six_module_name):
    +        self.name = six_module_name
    +        self.known_modules = {}
    +
    +    def _add_module(self, mod, *fullnames):
    +        for fullname in fullnames:
    +            self.known_modules[self.name + "." + fullname] = mod
    +
    +    def _get_module(self, fullname):
    +        return self.known_modules[self.name + "." + fullname]
    +
    +    def find_module(self, fullname, path=None):
    +        if fullname in self.known_modules:
    +            return self
    +        return None
    +
    +    def find_spec(self, fullname, path, target=None):
    +        if fullname in self.known_modules:
    +            return spec_from_loader(fullname, self)
    +        return None
    +
    +    def __get_module(self, fullname):
    +        try:
    +            return self.known_modules[fullname]
    +        except KeyError:
    +            raise ImportError("This loader does not know module " + fullname)
    +
    +    def load_module(self, fullname):
    +        try:
    +            # in case of a reload
    +            return sys.modules[fullname]
    +        except KeyError:
    +            pass
    +        mod = self.__get_module(fullname)
    +        if isinstance(mod, MovedModule):
    +            mod = mod._resolve()
    +        else:
    +            mod.__loader__ = self
    +        sys.modules[fullname] = mod
    +        return mod
    +
    +    def is_package(self, fullname):
    +        """
    +        Return true, if the named module is a package.
    +
    +        We need this method to get correct spec objects with
    +        Python 3.4 (see PEP451)
    +        """
    +        return hasattr(self.__get_module(fullname), "__path__")
    +
    +    def get_code(self, fullname):
    +        """Return None
    +
    +        Required, if is_package is implemented"""
    +        self.__get_module(fullname)  # eventually raises ImportError
    +        return None
    +
    +    get_source = get_code  # same as get_code
    +
    +    def create_module(self, spec):
    +        return self.load_module(spec.name)
    +
    +    def exec_module(self, module):
    +        pass
    +
    +
    +_importer = _SixMetaPathImporter(__name__)
    +
    +
    +class _MovedItems(_LazyModule):
    +
    +    """Lazy loading of moved objects"""
    +
    +    __path__ = []  # mark as package
    +
    +
    +_moved_attributes = [
    +    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
    +    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
    +    MovedAttribute(
    +        "filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"
    +    ),
    +    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
    +    MovedAttribute("intern", "__builtin__", "sys"),
    +    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
    +    MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
    +    MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
    +    MovedAttribute("getoutput", "commands", "subprocess"),
    +    MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
    +    MovedAttribute(
    +        "reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"
    +    ),
    +    MovedAttribute("reduce", "__builtin__", "functools"),
    +    MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
    +    MovedAttribute("StringIO", "StringIO", "io"),
    +    MovedAttribute("UserDict", "UserDict", "collections"),
    +    MovedAttribute("UserList", "UserList", "collections"),
    +    MovedAttribute("UserString", "UserString", "collections"),
    +    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
    +    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
    +    MovedAttribute(
    +        "zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"
    +    ),
    +    MovedModule("builtins", "__builtin__"),
    +    MovedModule("configparser", "ConfigParser"),
    +    MovedModule(
    +        "collections_abc",
    +        "collections",
    +        "collections.abc" if sys.version_info >= (3, 3) else "collections",
    +    ),
    +    MovedModule("copyreg", "copy_reg"),
    +    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
    +    MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
    +    MovedModule(
    +        "_dummy_thread",
    +        "dummy_thread",
    +        "_dummy_thread" if sys.version_info < (3, 9) else "_thread",
    +    ),
    +    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
    +    MovedModule("http_cookies", "Cookie", "http.cookies"),
    +    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
    +    MovedModule("html_parser", "HTMLParser", "html.parser"),
    +    MovedModule("http_client", "httplib", "http.client"),
    +    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
    +    MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
    +    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
    +    MovedModule(
    +        "email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"
    +    ),
    +    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
    +    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
    +    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
    +    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
    +    MovedModule("cPickle", "cPickle", "pickle"),
    +    MovedModule("queue", "Queue"),
    +    MovedModule("reprlib", "repr"),
    +    MovedModule("socketserver", "SocketServer"),
    +    MovedModule("_thread", "thread", "_thread"),
    +    MovedModule("tkinter", "Tkinter"),
    +    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
    +    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
    +    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
    +    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
    +    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
    +    MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
    +    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
    +    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
    +    MovedModule("tkinter_colorchooser", "tkColorChooser", "tkinter.colorchooser"),
    +    MovedModule("tkinter_commondialog", "tkCommonDialog", "tkinter.commondialog"),
    +    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
    +    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
    +    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
    +    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", "tkinter.simpledialog"),
    +    MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
    +    MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
    +    MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
    +    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
    +    MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
    +    MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
    +]
    +# Add windows specific modules.
    +if sys.platform == "win32":
    +    _moved_attributes += [
    +        MovedModule("winreg", "_winreg"),
    +    ]
    +
    +for attr in _moved_attributes:
    +    setattr(_MovedItems, attr.name, attr)
    +    if isinstance(attr, MovedModule):
    +        _importer._add_module(attr, "moves." + attr.name)
    +del attr
    +
    +_MovedItems._moved_attributes = _moved_attributes
    +
    +moves = _MovedItems(__name__ + ".moves")
    +_importer._add_module(moves, "moves")
    +
    +
    +class Module_six_moves_urllib_parse(_LazyModule):
    +
    +    """Lazy loading of moved objects in six.moves.urllib_parse"""
    +
    +
    +_urllib_parse_moved_attributes = [
    +    MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
    +    MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
    +    MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
    +    MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
    +    MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
    +    MovedAttribute("urljoin", "urlparse", "urllib.parse"),
    +    MovedAttribute("urlparse", "urlparse", "urllib.parse"),
    +    MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
    +    MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
    +    MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
    +    MovedAttribute("quote", "urllib", "urllib.parse"),
    +    MovedAttribute("quote_plus", "urllib", "urllib.parse"),
    +    MovedAttribute("unquote", "urllib", "urllib.parse"),
    +    MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
    +    MovedAttribute(
    +        "unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"
    +    ),
    +    MovedAttribute("urlencode", "urllib", "urllib.parse"),
    +    MovedAttribute("splitquery", "urllib", "urllib.parse"),
    +    MovedAttribute("splittag", "urllib", "urllib.parse"),
    +    MovedAttribute("splituser", "urllib", "urllib.parse"),
    +    MovedAttribute("splitvalue", "urllib", "urllib.parse"),
    +    MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
    +    MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
    +    MovedAttribute("uses_params", "urlparse", "urllib.parse"),
    +    MovedAttribute("uses_query", "urlparse", "urllib.parse"),
    +    MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
    +]
    +for attr in _urllib_parse_moved_attributes:
    +    setattr(Module_six_moves_urllib_parse, attr.name, attr)
    +del attr
    +
    +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
    +
    +_importer._add_module(
    +    Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
    +    "moves.urllib_parse",
    +    "moves.urllib.parse",
    +)
    +
    +
    +class Module_six_moves_urllib_error(_LazyModule):
    +
    +    """Lazy loading of moved objects in six.moves.urllib_error"""
    +
    +
    +_urllib_error_moved_attributes = [
    +    MovedAttribute("URLError", "urllib2", "urllib.error"),
    +    MovedAttribute("HTTPError", "urllib2", "urllib.error"),
    +    MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
    +]
    +for attr in _urllib_error_moved_attributes:
    +    setattr(Module_six_moves_urllib_error, attr.name, attr)
    +del attr
    +
    +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
    +
    +_importer._add_module(
    +    Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
    +    "moves.urllib_error",
    +    "moves.urllib.error",
    +)
    +
    +
    +class Module_six_moves_urllib_request(_LazyModule):
    +
    +    """Lazy loading of moved objects in six.moves.urllib_request"""
    +
    +
    +_urllib_request_moved_attributes = [
    +    MovedAttribute("urlopen", "urllib2", "urllib.request"),
    +    MovedAttribute("install_opener", "urllib2", "urllib.request"),
    +    MovedAttribute("build_opener", "urllib2", "urllib.request"),
    +    MovedAttribute("pathname2url", "urllib", "urllib.request"),
    +    MovedAttribute("url2pathname", "urllib", "urllib.request"),
    +    MovedAttribute("getproxies", "urllib", "urllib.request"),
    +    MovedAttribute("Request", "urllib2", "urllib.request"),
    +    MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
    +    MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
    +    MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("FileHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
    +    MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
    +    MovedAttribute("urlretrieve", "urllib", "urllib.request"),
    +    MovedAttribute("urlcleanup", "urllib", "urllib.request"),
    +    MovedAttribute("URLopener", "urllib", "urllib.request"),
    +    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
    +    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
    +    MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
    +    MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
    +]
    +for attr in _urllib_request_moved_attributes:
    +    setattr(Module_six_moves_urllib_request, attr.name, attr)
    +del attr
    +
    +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
    +
    +_importer._add_module(
    +    Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
    +    "moves.urllib_request",
    +    "moves.urllib.request",
    +)
    +
    +
    +class Module_six_moves_urllib_response(_LazyModule):
    +
    +    """Lazy loading of moved objects in six.moves.urllib_response"""
    +
    +
    +_urllib_response_moved_attributes = [
    +    MovedAttribute("addbase", "urllib", "urllib.response"),
    +    MovedAttribute("addclosehook", "urllib", "urllib.response"),
    +    MovedAttribute("addinfo", "urllib", "urllib.response"),
    +    MovedAttribute("addinfourl", "urllib", "urllib.response"),
    +]
    +for attr in _urllib_response_moved_attributes:
    +    setattr(Module_six_moves_urllib_response, attr.name, attr)
    +del attr
    +
    +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
    +
    +_importer._add_module(
    +    Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
    +    "moves.urllib_response",
    +    "moves.urllib.response",
    +)
    +
    +
    +class Module_six_moves_urllib_robotparser(_LazyModule):
    +
    +    """Lazy loading of moved objects in six.moves.urllib_robotparser"""
    +
    +
    +_urllib_robotparser_moved_attributes = [
    +    MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
    +]
    +for attr in _urllib_robotparser_moved_attributes:
    +    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
    +del attr
    +
    +Module_six_moves_urllib_robotparser._moved_attributes = (
    +    _urllib_robotparser_moved_attributes
    +)
    +
    +_importer._add_module(
    +    Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
    +    "moves.urllib_robotparser",
    +    "moves.urllib.robotparser",
    +)
    +
    +
    +class Module_six_moves_urllib(types.ModuleType):
    +
    +    """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
    +
    +    __path__ = []  # mark as package
    +    parse = _importer._get_module("moves.urllib_parse")
    +    error = _importer._get_module("moves.urllib_error")
    +    request = _importer._get_module("moves.urllib_request")
    +    response = _importer._get_module("moves.urllib_response")
    +    robotparser = _importer._get_module("moves.urllib_robotparser")
    +
    +    def __dir__(self):
    +        return ["parse", "error", "request", "response", "robotparser"]
    +
    +
    +_importer._add_module(
    +    Module_six_moves_urllib(__name__ + ".moves.urllib"), "moves.urllib"
    +)
    +
    +
    +def add_move(move):
    +    """Add an item to six.moves."""
    +    setattr(_MovedItems, move.name, move)
    +
    +
    +def remove_move(name):
    +    """Remove item from six.moves."""
    +    try:
    +        delattr(_MovedItems, name)
    +    except AttributeError:
    +        try:
    +            del moves.__dict__[name]
    +        except KeyError:
    +            raise AttributeError("no such move, %r" % (name,))
    +
    +
    +if PY3:
    +    _meth_func = "__func__"
    +    _meth_self = "__self__"
    +
    +    _func_closure = "__closure__"
    +    _func_code = "__code__"
    +    _func_defaults = "__defaults__"
    +    _func_globals = "__globals__"
    +else:
    +    _meth_func = "im_func"
    +    _meth_self = "im_self"
    +
    +    _func_closure = "func_closure"
    +    _func_code = "func_code"
    +    _func_defaults = "func_defaults"
    +    _func_globals = "func_globals"
    +
    +
    +try:
    +    advance_iterator = next
    +except NameError:
    +
    +    def advance_iterator(it):
    +        return it.next()
    +
    +
    +next = advance_iterator
    +
    +
    +try:
    +    callable = callable
    +except NameError:
    +
    +    def callable(obj):
    +        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
    +
    +
    +if PY3:
    +
    +    def get_unbound_function(unbound):
    +        return unbound
    +
    +    create_bound_method = types.MethodType
    +
    +    def create_unbound_method(func, cls):
    +        return func
    +
    +    Iterator = object
    +else:
    +
    +    def get_unbound_function(unbound):
    +        return unbound.im_func
    +
    +    def create_bound_method(func, obj):
    +        return types.MethodType(func, obj, obj.__class__)
    +
    +    def create_unbound_method(func, cls):
    +        return types.MethodType(func, None, cls)
    +
    +    class Iterator(object):
    +        def next(self):
    +            return type(self).__next__(self)
    +
    +    callable = callable
    +_add_doc(
    +    get_unbound_function, """Get the function out of a possibly unbound function"""
    +)
    +
    +
    +get_method_function = operator.attrgetter(_meth_func)
    +get_method_self = operator.attrgetter(_meth_self)
    +get_function_closure = operator.attrgetter(_func_closure)
    +get_function_code = operator.attrgetter(_func_code)
    +get_function_defaults = operator.attrgetter(_func_defaults)
    +get_function_globals = operator.attrgetter(_func_globals)
    +
    +
    +if PY3:
    +
    +    def iterkeys(d, **kw):
    +        return iter(d.keys(**kw))
    +
    +    def itervalues(d, **kw):
    +        return iter(d.values(**kw))
    +
    +    def iteritems(d, **kw):
    +        return iter(d.items(**kw))
    +
    +    def iterlists(d, **kw):
    +        return iter(d.lists(**kw))
    +
    +    viewkeys = operator.methodcaller("keys")
    +
    +    viewvalues = operator.methodcaller("values")
    +
    +    viewitems = operator.methodcaller("items")
    +else:
    +
    +    def iterkeys(d, **kw):
    +        return d.iterkeys(**kw)
    +
    +    def itervalues(d, **kw):
    +        return d.itervalues(**kw)
    +
    +    def iteritems(d, **kw):
    +        return d.iteritems(**kw)
    +
    +    def iterlists(d, **kw):
    +        return d.iterlists(**kw)
    +
    +    viewkeys = operator.methodcaller("viewkeys")
    +
    +    viewvalues = operator.methodcaller("viewvalues")
    +
    +    viewitems = operator.methodcaller("viewitems")
    +
    +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
    +_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
    +_add_doc(iteritems, "Return an iterator over the (key, value) pairs of a dictionary.")
    +_add_doc(
    +    iterlists, "Return an iterator over the (key, [values]) pairs of a dictionary."
    +)
    +
    +
    +if PY3:
    +
    +    def b(s):
    +        return s.encode("latin-1")
    +
    +    def u(s):
    +        return s
    +
    +    unichr = chr
    +    import struct
    +
    +    int2byte = struct.Struct(">B").pack
    +    del struct
    +    byte2int = operator.itemgetter(0)
    +    indexbytes = operator.getitem
    +    iterbytes = iter
    +    import io
    +
    +    StringIO = io.StringIO
    +    BytesIO = io.BytesIO
    +    del io
    +    _assertCountEqual = "assertCountEqual"
    +    if sys.version_info[1] <= 1:
    +        _assertRaisesRegex = "assertRaisesRegexp"
    +        _assertRegex = "assertRegexpMatches"
    +        _assertNotRegex = "assertNotRegexpMatches"
    +    else:
    +        _assertRaisesRegex = "assertRaisesRegex"
    +        _assertRegex = "assertRegex"
    +        _assertNotRegex = "assertNotRegex"
    +else:
    +
    +    def b(s):
    +        return s
    +
    +    # Workaround for standalone backslash
    +
    +    def u(s):
    +        return unicode(s.replace(r"\\", r"\\\\"), "unicode_escape")
    +
    +    unichr = unichr
    +    int2byte = chr
    +
    +    def byte2int(bs):
    +        return ord(bs[0])
    +
    +    def indexbytes(buf, i):
    +        return ord(buf[i])
    +
    +    iterbytes = functools.partial(itertools.imap, ord)
    +    import StringIO
    +
    +    StringIO = BytesIO = StringIO.StringIO
    +    _assertCountEqual = "assertItemsEqual"
    +    _assertRaisesRegex = "assertRaisesRegexp"
    +    _assertRegex = "assertRegexpMatches"
    +    _assertNotRegex = "assertNotRegexpMatches"
    +_add_doc(b, """Byte literal""")
    +_add_doc(u, """Text literal""")
    +
    +
    +def assertCountEqual(self, *args, **kwargs):
    +    return getattr(self, _assertCountEqual)(*args, **kwargs)
    +
    +
    +def assertRaisesRegex(self, *args, **kwargs):
    +    return getattr(self, _assertRaisesRegex)(*args, **kwargs)
    +
    +
    +def assertRegex(self, *args, **kwargs):
    +    return getattr(self, _assertRegex)(*args, **kwargs)
    +
    +
    +def assertNotRegex(self, *args, **kwargs):
    +    return getattr(self, _assertNotRegex)(*args, **kwargs)
    +
    +
    +if PY3:
    +    exec_ = getattr(moves.builtins, "exec")
    +
    +    def reraise(tp, value, tb=None):
    +        try:
    +            if value is None:
    +                value = tp()
    +            if value.__traceback__ is not tb:
    +                raise value.with_traceback(tb)
    +            raise value
    +        finally:
    +            value = None
    +            tb = None
    +
    +else:
    +
    +    def exec_(_code_, _globs_=None, _locs_=None):
    +        """Execute code in a namespace."""
    +        if _globs_ is None:
    +            frame = sys._getframe(1)
    +            _globs_ = frame.f_globals
    +            if _locs_ is None:
    +                _locs_ = frame.f_locals
    +            del frame
    +        elif _locs_ is None:
    +            _locs_ = _globs_
    +        exec ("""exec _code_ in _globs_, _locs_""")
    +
    +    exec_(
    +        """def reraise(tp, value, tb=None):
    +    try:
    +        raise tp, value, tb
    +    finally:
    +        tb = None
    +"""
    +    )
    +
    +
    +if sys.version_info[:2] > (3,):
    +    exec_(
    +        """def raise_from(value, from_value):
    +    try:
    +        raise value from from_value
    +    finally:
    +        value = None
    +"""
    +    )
    +else:
    +
    +    def raise_from(value, from_value):
    +        raise value
    +
    +
    +print_ = getattr(moves.builtins, "print", None)
    +if print_ is None:
    +
    +    def print_(*args, **kwargs):
    +        """The new-style print function for Python 2.4 and 2.5."""
    +        fp = kwargs.pop("file", sys.stdout)
    +        if fp is None:
    +            return
    +
    +        def write(data):
    +            if not isinstance(data, basestring):
    +                data = str(data)
    +            # If the file has an encoding, encode unicode with it.
    +            if (
    +                isinstance(fp, file)
    +                and isinstance(data, unicode)
    +                and fp.encoding is not None
    +            ):
    +                errors = getattr(fp, "errors", None)
    +                if errors is None:
    +                    errors = "strict"
    +                data = data.encode(fp.encoding, errors)
    +            fp.write(data)
    +
    +        want_unicode = False
    +        sep = kwargs.pop("sep", None)
    +        if sep is not None:
    +            if isinstance(sep, unicode):
    +                want_unicode = True
    +            elif not isinstance(sep, str):
    +                raise TypeError("sep must be None or a string")
    +        end = kwargs.pop("end", None)
    +        if end is not None:
    +            if isinstance(end, unicode):
    +                want_unicode = True
    +            elif not isinstance(end, str):
    +                raise TypeError("end must be None or a string")
    +        if kwargs:
    +            raise TypeError("invalid keyword arguments to print()")
    +        if not want_unicode:
    +            for arg in args:
    +                if isinstance(arg, unicode):
    +                    want_unicode = True
    +                    break
    +        if want_unicode:
    +            newline = unicode("\n")
    +            space = unicode(" ")
    +        else:
    +            newline = "\n"
    +            space = " "
    +        if sep is None:
    +            sep = space
    +        if end is None:
    +            end = newline
    +        for i, arg in enumerate(args):
    +            if i:
    +                write(sep)
    +            write(arg)
    +        write(end)
    +
    +
    +if sys.version_info[:2] < (3, 3):
    +    _print = print_
    +
    +    def print_(*args, **kwargs):
    +        fp = kwargs.get("file", sys.stdout)
    +        flush = kwargs.pop("flush", False)
    +        _print(*args, **kwargs)
    +        if flush and fp is not None:
    +            fp.flush()
    +
    +
    +_add_doc(reraise, """Reraise an exception.""")
    +
    +if sys.version_info[0:2] < (3, 4):
    +    # This does exactly the same what the :func:`py3:functools.update_wrapper`
    +    # function does on Python versions after 3.2. It sets the ``__wrapped__``
    +    # attribute on ``wrapper`` object and it doesn't raise an error if any of
    +    # the attributes mentioned in ``assigned`` and ``updated`` are missing on
    +    # ``wrapped`` object.
    +    def _update_wrapper(
    +        wrapper,
    +        wrapped,
    +        assigned=functools.WRAPPER_ASSIGNMENTS,
    +        updated=functools.WRAPPER_UPDATES,
    +    ):
    +        for attr in assigned:
    +            try:
    +                value = getattr(wrapped, attr)
    +            except AttributeError:
    +                continue
    +            else:
    +                setattr(wrapper, attr, value)
    +        for attr in updated:
    +            getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
    +        wrapper.__wrapped__ = wrapped
    +        return wrapper
    +
    +    _update_wrapper.__doc__ = functools.update_wrapper.__doc__
    +
    +    def wraps(
    +        wrapped,
    +        assigned=functools.WRAPPER_ASSIGNMENTS,
    +        updated=functools.WRAPPER_UPDATES,
    +    ):
    +        return functools.partial(
    +            _update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated
    +        )
    +
    +    wraps.__doc__ = functools.wraps.__doc__
    +
    +else:
    +    wraps = functools.wraps
    +
    +
    +def with_metaclass(meta, *bases):
    +    """Create a base class with a metaclass."""
    +    # This requires a bit of explanation: the basic idea is to make a dummy
    +    # metaclass for one level of class instantiation that replaces itself with
    +    # the actual metaclass.
    +    class metaclass(type):
    +        def __new__(cls, name, this_bases, d):
    +            if sys.version_info[:2] >= (3, 7):
    +                # This version introduced PEP 560 that requires a bit
    +                # of extra care (we mimic what is done by __build_class__).
    +                resolved_bases = types.resolve_bases(bases)
    +                if resolved_bases is not bases:
    +                    d["__orig_bases__"] = bases
    +            else:
    +                resolved_bases = bases
    +            return meta(name, resolved_bases, d)
    +
    +        @classmethod
    +        def __prepare__(cls, name, this_bases):
    +            return meta.__prepare__(name, bases)
    +
    +    return type.__new__(metaclass, "temporary_class", (), {})
    +
    +
    +def add_metaclass(metaclass):
    +    """Class decorator for creating a class with a metaclass."""
    +
    +    def wrapper(cls):
    +        orig_vars = cls.__dict__.copy()
    +        slots = orig_vars.get("__slots__")
    +        if slots is not None:
    +            if isinstance(slots, str):
    +                slots = [slots]
    +            for slots_var in slots:
    +                orig_vars.pop(slots_var)
    +        orig_vars.pop("__dict__", None)
    +        orig_vars.pop("__weakref__", None)
    +        if hasattr(cls, "__qualname__"):
    +            orig_vars["__qualname__"] = cls.__qualname__
    +        return metaclass(cls.__name__, cls.__bases__, orig_vars)
    +
    +    return wrapper
    +
    +
    +def ensure_binary(s, encoding="utf-8", errors="strict"):
    +    """Coerce **s** to six.binary_type.
    +
    +    For Python 2:
    +      - `unicode` -> encoded to `str`
    +      - `str` -> `str`
    +
    +    For Python 3:
    +      - `str` -> encoded to `bytes`
    +      - `bytes` -> `bytes`
    +    """
    +    if isinstance(s, binary_type):
    +        return s
    +    if isinstance(s, text_type):
    +        return s.encode(encoding, errors)
    +    raise TypeError("not expecting type '%s'" % type(s))
    +
    +
    +def ensure_str(s, encoding="utf-8", errors="strict"):
    +    """Coerce *s* to `str`.
    +
    +    For Python 2:
    +      - `unicode` -> encoded to `str`
    +      - `str` -> `str`
    +
    +    For Python 3:
    +      - `str` -> `str`
    +      - `bytes` -> decoded to `str`
    +    """
    +    # Optimization: Fast return for the common case.
    +    if type(s) is str:
    +        return s
    +    if PY2 and isinstance(s, text_type):
    +        return s.encode(encoding, errors)
    +    elif PY3 and isinstance(s, binary_type):
    +        return s.decode(encoding, errors)
    +    elif not isinstance(s, (text_type, binary_type)):
    +        raise TypeError("not expecting type '%s'" % type(s))
    +    return s
    +
    +
    +def ensure_text(s, encoding="utf-8", errors="strict"):
    +    """Coerce *s* to six.text_type.
    +
    +    For Python 2:
    +      - `unicode` -> `unicode`
    +      - `str` -> `unicode`
    +
    +    For Python 3:
    +      - `str` -> `str`
    +      - `bytes` -> decoded to `str`
    +    """
    +    if isinstance(s, binary_type):
    +        return s.decode(encoding, errors)
    +    elif isinstance(s, text_type):
    +        return s
    +    else:
    +        raise TypeError("not expecting type '%s'" % type(s))
    +
    +
    +def python_2_unicode_compatible(klass):
    +    """
    +    A class decorator that defines __unicode__ and __str__ methods under Python 2.
    +    Under Python 3 it does nothing.
    +
    +    To support Python 2 and 3 with a single code base, define a __str__ method
    +    returning text and apply this decorator to the class.
    +    """
    +    if PY2:
    +        if "__str__" not in klass.__dict__:
    +            raise ValueError(
    +                "@python_2_unicode_compatible cannot be applied "
    +                "to %s because it doesn't define __str__()." % klass.__name__
    +            )
    +        klass.__unicode__ = klass.__str__
    +        klass.__str__ = lambda self: self.__unicode__().encode("utf-8")
    +    return klass
    +
    +
    +# Complete the moves implementation.
    +# This code is at the end of this module to speed up module loading.
    +# Turn this module into a package.
    +__path__ = []  # required for PEP 302 and PEP 451
    +__package__ = __name__  # see PEP 366 @ReservedAssignment
    +if globals().get("__spec__") is not None:
    +    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
    +# Remove other six meta path importers, since they cause problems. This can
    +# happen if six is removed from sys.modules and then reloaded. (Setuptools does
    +# this for some reason.)
    +if sys.meta_path:
    +    for i, importer in enumerate(sys.meta_path):
    +        # Here's some real nastiness: Another "instance" of the six module might
    +        # be floating around. Therefore, we can't use isinstance() to check for
    +        # the six meta path importer, since the other six instance will have
    +        # inserted an importer with different class.
    +        if (
    +            type(importer).__name__ == "_SixMetaPathImporter"
    +            and importer.name == __name__
    +        ):
    +            del sys.meta_path[i]
    +            break
    +    del i, importer
    +# Finally, add the importer to the meta path import hook.
    +sys.meta_path.append(_importer)
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/poolmanager.py b/deployment-apps/metricator-for-nmon/lib/urllib3/poolmanager.py
    new file mode 100644
    index 0000000..ca4ec34
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/poolmanager.py
    @@ -0,0 +1,537 @@
    +from __future__ import absolute_import
    +
    +import collections
    +import functools
    +import logging
    +
    +from ._collections import RecentlyUsedContainer
    +from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme
    +from .exceptions import (
    +    LocationValueError,
    +    MaxRetryError,
    +    ProxySchemeUnknown,
    +    ProxySchemeUnsupported,
    +    URLSchemeUnknown,
    +)
    +from .packages import six
    +from .packages.six.moves.urllib.parse import urljoin
    +from .request import RequestMethods
    +from .util.proxy import connection_requires_http_tunnel
    +from .util.retry import Retry
    +from .util.url import parse_url
    +
    +__all__ = ["PoolManager", "ProxyManager", "proxy_from_url"]
    +
    +
    +log = logging.getLogger(__name__)
    +
    +SSL_KEYWORDS = (
    +    "key_file",
    +    "cert_file",
    +    "cert_reqs",
    +    "ca_certs",
    +    "ssl_version",
    +    "ca_cert_dir",
    +    "ssl_context",
    +    "key_password",
    +    "server_hostname",
    +)
    +
    +# All known keyword arguments that could be provided to the pool manager, its
    +# pools, or the underlying connections. This is used to construct a pool key.
    +_key_fields = (
    +    "key_scheme",  # str
    +    "key_host",  # str
    +    "key_port",  # int
    +    "key_timeout",  # int or float or Timeout
    +    "key_retries",  # int or Retry
    +    "key_strict",  # bool
    +    "key_block",  # bool
    +    "key_source_address",  # str
    +    "key_key_file",  # str
    +    "key_key_password",  # str
    +    "key_cert_file",  # str
    +    "key_cert_reqs",  # str
    +    "key_ca_certs",  # str
    +    "key_ssl_version",  # str
    +    "key_ca_cert_dir",  # str
    +    "key_ssl_context",  # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext
    +    "key_maxsize",  # int
    +    "key_headers",  # dict
    +    "key__proxy",  # parsed proxy url
    +    "key__proxy_headers",  # dict
    +    "key__proxy_config",  # class
    +    "key_socket_options",  # list of (level (int), optname (int), value (int or str)) tuples
    +    "key__socks_options",  # dict
    +    "key_assert_hostname",  # bool or string
    +    "key_assert_fingerprint",  # str
    +    "key_server_hostname",  # str
    +)
    +
    +#: The namedtuple class used to construct keys for the connection pool.
    +#: All custom key schemes should include the fields in this key at a minimum.
    +PoolKey = collections.namedtuple("PoolKey", _key_fields)
    +
    +_proxy_config_fields = ("ssl_context", "use_forwarding_for_https")
    +ProxyConfig = collections.namedtuple("ProxyConfig", _proxy_config_fields)
    +
    +
    +def _default_key_normalizer(key_class, request_context):
    +    """
    +    Create a pool key out of a request context dictionary.
    +
    +    According to RFC 3986, both the scheme and host are case-insensitive.
    +    Therefore, this function normalizes both before constructing the pool
    +    key for an HTTPS request. If you wish to change this behaviour, provide
    +    alternate callables to ``key_fn_by_scheme``.
    +
    +    :param key_class:
    +        The class to use when constructing the key. This should be a namedtuple
    +        with the ``scheme`` and ``host`` keys at a minimum.
    +    :type  key_class: namedtuple
    +    :param request_context:
    +        A dictionary-like object that contain the context for a request.
    +    :type  request_context: dict
    +
    +    :return: A namedtuple that can be used as a connection pool key.
    +    :rtype:  PoolKey
    +    """
    +    # Since we mutate the dictionary, make a copy first
    +    context = request_context.copy()
    +    context["scheme"] = context["scheme"].lower()
    +    context["host"] = context["host"].lower()
    +
    +    # These are both dictionaries and need to be transformed into frozensets
    +    for key in ("headers", "_proxy_headers", "_socks_options"):
    +        if key in context and context[key] is not None:
    +            context[key] = frozenset(context[key].items())
    +
    +    # The socket_options key may be a list and needs to be transformed into a
    +    # tuple.
    +    socket_opts = context.get("socket_options")
    +    if socket_opts is not None:
    +        context["socket_options"] = tuple(socket_opts)
    +
    +    # Map the kwargs to the names in the namedtuple - this is necessary since
    +    # namedtuples can't have fields starting with '_'.
    +    for key in list(context.keys()):
    +        context["key_" + key] = context.pop(key)
    +
    +    # Default to ``None`` for keys missing from the context
    +    for field in key_class._fields:
    +        if field not in context:
    +            context[field] = None
    +
    +    return key_class(**context)
    +
    +
    +#: A dictionary that maps a scheme to a callable that creates a pool key.
    +#: This can be used to alter the way pool keys are constructed, if desired.
    +#: Each PoolManager makes a copy of this dictionary so they can be configured
    +#: globally here, or individually on the instance.
    +key_fn_by_scheme = {
    +    "http": functools.partial(_default_key_normalizer, PoolKey),
    +    "https": functools.partial(_default_key_normalizer, PoolKey),
    +}
    +
    +pool_classes_by_scheme = {"http": HTTPConnectionPool, "https": HTTPSConnectionPool}
    +
    +
    +class PoolManager(RequestMethods):
    +    """
    +    Allows for arbitrary requests while transparently keeping track of
    +    necessary connection pools for you.
    +
    +    :param num_pools:
    +        Number of connection pools to cache before discarding the least
    +        recently used pool.
    +
    +    :param headers:
    +        Headers to include with all requests, unless other headers are given
    +        explicitly.
    +
    +    :param \\**connection_pool_kw:
    +        Additional parameters are used to create fresh
    +        :class:`urllib3.connectionpool.ConnectionPool` instances.
    +
    +    Example::
    +
    +        >>> manager = PoolManager(num_pools=2)
    +        >>> r = manager.request('GET', 'http://google.com/')
    +        >>> r = manager.request('GET', 'http://google.com/mail')
    +        >>> r = manager.request('GET', 'http://yahoo.com/')
    +        >>> len(manager.pools)
    +        2
    +
    +    """
    +
    +    proxy = None
    +    proxy_config = None
    +
    +    def __init__(self, num_pools=10, headers=None, **connection_pool_kw):
    +        RequestMethods.__init__(self, headers)
    +        self.connection_pool_kw = connection_pool_kw
    +        self.pools = RecentlyUsedContainer(num_pools, dispose_func=lambda p: p.close())
    +
    +        # Locally set the pool classes and keys so other PoolManagers can
    +        # override them.
    +        self.pool_classes_by_scheme = pool_classes_by_scheme
    +        self.key_fn_by_scheme = key_fn_by_scheme.copy()
    +
    +    def __enter__(self):
    +        return self
    +
    +    def __exit__(self, exc_type, exc_val, exc_tb):
    +        self.clear()
    +        # Return False to re-raise any potential exceptions
    +        return False
    +
    +    def _new_pool(self, scheme, host, port, request_context=None):
    +        """
    +        Create a new :class:`urllib3.connectionpool.ConnectionPool` based on host, port, scheme, and
    +        any additional pool keyword arguments.
    +
    +        If ``request_context`` is provided, it is provided as keyword arguments
    +        to the pool class used. This method is used to actually create the
    +        connection pools handed out by :meth:`connection_from_url` and
    +        companion methods. It is intended to be overridden for customization.
    +        """
    +        pool_cls = self.pool_classes_by_scheme[scheme]
    +        if request_context is None:
    +            request_context = self.connection_pool_kw.copy()
    +
    +        # Although the context has everything necessary to create the pool,
    +        # this function has historically only used the scheme, host, and port
    +        # in the positional args. When an API change is acceptable these can
    +        # be removed.
    +        for key in ("scheme", "host", "port"):
    +            request_context.pop(key, None)
    +
    +        if scheme == "http":
    +            for kw in SSL_KEYWORDS:
    +                request_context.pop(kw, None)
    +
    +        return pool_cls(host, port, **request_context)
    +
    +    def clear(self):
    +        """
    +        Empty our store of pools and direct them all to close.
    +
    +        This will not affect in-flight connections, but they will not be
    +        re-used after completion.
    +        """
    +        self.pools.clear()
    +
    +    def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None):
    +        """
    +        Get a :class:`urllib3.connectionpool.ConnectionPool` based on the host, port, and scheme.
    +
    +        If ``port`` isn't given, it will be derived from the ``scheme`` using
    +        ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is
    +        provided, it is merged with the instance's ``connection_pool_kw``
    +        variable and used to create the new connection pool, if one is
    +        needed.
    +        """
    +
    +        if not host:
    +            raise LocationValueError("No host specified.")
    +
    +        request_context = self._merge_pool_kwargs(pool_kwargs)
    +        request_context["scheme"] = scheme or "http"
    +        if not port:
    +            port = port_by_scheme.get(request_context["scheme"].lower(), 80)
    +        request_context["port"] = port
    +        request_context["host"] = host
    +
    +        return self.connection_from_context(request_context)
    +
    +    def connection_from_context(self, request_context):
    +        """
    +        Get a :class:`urllib3.connectionpool.ConnectionPool` based on the request context.
    +
    +        ``request_context`` must at least contain the ``scheme`` key and its
    +        value must be a key in ``key_fn_by_scheme`` instance variable.
    +        """
    +        scheme = request_context["scheme"].lower()
    +        pool_key_constructor = self.key_fn_by_scheme.get(scheme)
    +        if not pool_key_constructor:
    +            raise URLSchemeUnknown(scheme)
    +        pool_key = pool_key_constructor(request_context)
    +
    +        return self.connection_from_pool_key(pool_key, request_context=request_context)
    +
    +    def connection_from_pool_key(self, pool_key, request_context=None):
    +        """
    +        Get a :class:`urllib3.connectionpool.ConnectionPool` based on the provided pool key.
    +
    +        ``pool_key`` should be a namedtuple that only contains immutable
    +        objects. At a minimum it must have the ``scheme``, ``host``, and
    +        ``port`` fields.
    +        """
    +        with self.pools.lock:
    +            # If the scheme, host, or port doesn't match existing open
    +            # connections, open a new ConnectionPool.
    +            pool = self.pools.get(pool_key)
    +            if pool:
    +                return pool
    +
    +            # Make a fresh ConnectionPool of the desired type
    +            scheme = request_context["scheme"]
    +            host = request_context["host"]
    +            port = request_context["port"]
    +            pool = self._new_pool(scheme, host, port, request_context=request_context)
    +            self.pools[pool_key] = pool
    +
    +        return pool
    +
    +    def connection_from_url(self, url, pool_kwargs=None):
    +        """
    +        Similar to :func:`urllib3.connectionpool.connection_from_url`.
    +
    +        If ``pool_kwargs`` is not provided and a new pool needs to be
    +        constructed, ``self.connection_pool_kw`` is used to initialize
    +        the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs``
    +        is provided, it is used instead. Note that if a new pool does not
    +        need to be created for the request, the provided ``pool_kwargs`` are
    +        not used.
    +        """
    +        u = parse_url(url)
    +        return self.connection_from_host(
    +            u.host, port=u.port, scheme=u.scheme, pool_kwargs=pool_kwargs
    +        )
    +
    +    def _merge_pool_kwargs(self, override):
    +        """
    +        Merge a dictionary of override values for self.connection_pool_kw.
    +
    +        This does not modify self.connection_pool_kw and returns a new dict.
    +        Any keys in the override dictionary with a value of ``None`` are
    +        removed from the merged dictionary.
    +        """
    +        base_pool_kwargs = self.connection_pool_kw.copy()
    +        if override:
    +            for key, value in override.items():
    +                if value is None:
    +                    try:
    +                        del base_pool_kwargs[key]
    +                    except KeyError:
    +                        pass
    +                else:
    +                    base_pool_kwargs[key] = value
    +        return base_pool_kwargs
    +
    +    def _proxy_requires_url_absolute_form(self, parsed_url):
    +        """
    +        Indicates if the proxy requires the complete destination URL in the
    +        request.  Normally this is only needed when not using an HTTP CONNECT
    +        tunnel.
    +        """
    +        if self.proxy is None:
    +            return False
    +
    +        return not connection_requires_http_tunnel(
    +            self.proxy, self.proxy_config, parsed_url.scheme
    +        )
    +
    +    def _validate_proxy_scheme_url_selection(self, url_scheme):
    +        """
    +        Validates that were not attempting to do TLS in TLS connections on
    +        Python2 or with unsupported SSL implementations.
    +        """
    +        if self.proxy is None or url_scheme != "https":
    +            return
    +
    +        if self.proxy.scheme != "https":
    +            return
    +
    +        if six.PY2 and not self.proxy_config.use_forwarding_for_https:
    +            raise ProxySchemeUnsupported(
    +                "Contacting HTTPS destinations through HTTPS proxies "
    +                "'via CONNECT tunnels' is not supported in Python 2"
    +            )
    +
    +    def urlopen(self, method, url, redirect=True, **kw):
    +        """
    +        Same as :meth:`urllib3.HTTPConnectionPool.urlopen`
    +        with custom cross-host redirect logic and only sends the request-uri
    +        portion of the ``url``.
    +
    +        The given ``url`` parameter must be absolute, such that an appropriate
    +        :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it.
    +        """
    +        u = parse_url(url)
    +        self._validate_proxy_scheme_url_selection(u.scheme)
    +
    +        conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
    +
    +        kw["assert_same_host"] = False
    +        kw["redirect"] = False
    +
    +        if "headers" not in kw:
    +            kw["headers"] = self.headers.copy()
    +
    +        if self._proxy_requires_url_absolute_form(u):
    +            response = conn.urlopen(method, url, **kw)
    +        else:
    +            response = conn.urlopen(method, u.request_uri, **kw)
    +
    +        redirect_location = redirect and response.get_redirect_location()
    +        if not redirect_location:
    +            return response
    +
    +        # Support relative URLs for redirecting.
    +        redirect_location = urljoin(url, redirect_location)
    +
    +        # RFC 7231, Section 6.4.4
    +        if response.status == 303:
    +            method = "GET"
    +
    +        retries = kw.get("retries")
    +        if not isinstance(retries, Retry):
    +            retries = Retry.from_int(retries, redirect=redirect)
    +
    +        # Strip headers marked as unsafe to forward to the redirected location.
    +        # Check remove_headers_on_redirect to avoid a potential network call within
    +        # conn.is_same_host() which may use socket.gethostbyname() in the future.
    +        if retries.remove_headers_on_redirect and not conn.is_same_host(
    +            redirect_location
    +        ):
    +            headers = list(six.iterkeys(kw["headers"]))
    +            for header in headers:
    +                if header.lower() in retries.remove_headers_on_redirect:
    +                    kw["headers"].pop(header, None)
    +
    +        try:
    +            retries = retries.increment(method, url, response=response, _pool=conn)
    +        except MaxRetryError:
    +            if retries.raise_on_redirect:
    +                response.drain_conn()
    +                raise
    +            return response
    +
    +        kw["retries"] = retries
    +        kw["redirect"] = redirect
    +
    +        log.info("Redirecting %s -> %s", url, redirect_location)
    +
    +        response.drain_conn()
    +        return self.urlopen(method, redirect_location, **kw)
    +
    +
    +class ProxyManager(PoolManager):
    +    """
    +    Behaves just like :class:`PoolManager`, but sends all requests through
    +    the defined proxy, using the CONNECT method for HTTPS URLs.
    +
    +    :param proxy_url:
    +        The URL of the proxy to be used.
    +
    +    :param proxy_headers:
    +        A dictionary containing headers that will be sent to the proxy. In case
    +        of HTTP they are being sent with each request, while in the
    +        HTTPS/CONNECT case they are sent only once. Could be used for proxy
    +        authentication.
    +
    +    :param proxy_ssl_context:
    +        The proxy SSL context is used to establish the TLS connection to the
    +        proxy when using HTTPS proxies.
    +
    +    :param use_forwarding_for_https:
    +        (Defaults to False) If set to True will forward requests to the HTTPS
    +        proxy to be made on behalf of the client instead of creating a TLS
    +        tunnel via the CONNECT method. **Enabling this flag means that request
    +        and response headers and content will be visible from the HTTPS proxy**
    +        whereas tunneling keeps request and response headers and content
    +        private.  IP address, target hostname, SNI, and port are always visible
    +        to an HTTPS proxy even when this flag is disabled.
    +
    +    Example:
    +        >>> proxy = urllib3.ProxyManager('http://localhost:3128/')
    +        >>> r1 = proxy.request('GET', 'http://google.com/')
    +        >>> r2 = proxy.request('GET', 'http://httpbin.org/')
    +        >>> len(proxy.pools)
    +        1
    +        >>> r3 = proxy.request('GET', 'https://httpbin.org/')
    +        >>> r4 = proxy.request('GET', 'https://twitter.com/')
    +        >>> len(proxy.pools)
    +        3
    +
    +    """
    +
    +    def __init__(
    +        self,
    +        proxy_url,
    +        num_pools=10,
    +        headers=None,
    +        proxy_headers=None,
    +        proxy_ssl_context=None,
    +        use_forwarding_for_https=False,
    +        **connection_pool_kw
    +    ):
    +
    +        if isinstance(proxy_url, HTTPConnectionPool):
    +            proxy_url = "%s://%s:%i" % (
    +                proxy_url.scheme,
    +                proxy_url.host,
    +                proxy_url.port,
    +            )
    +        proxy = parse_url(proxy_url)
    +
    +        if proxy.scheme not in ("http", "https"):
    +            raise ProxySchemeUnknown(proxy.scheme)
    +
    +        if not proxy.port:
    +            port = port_by_scheme.get(proxy.scheme, 80)
    +            proxy = proxy._replace(port=port)
    +
    +        self.proxy = proxy
    +        self.proxy_headers = proxy_headers or {}
    +        self.proxy_ssl_context = proxy_ssl_context
    +        self.proxy_config = ProxyConfig(proxy_ssl_context, use_forwarding_for_https)
    +
    +        connection_pool_kw["_proxy"] = self.proxy
    +        connection_pool_kw["_proxy_headers"] = self.proxy_headers
    +        connection_pool_kw["_proxy_config"] = self.proxy_config
    +
    +        super(ProxyManager, self).__init__(num_pools, headers, **connection_pool_kw)
    +
    +    def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None):
    +        if scheme == "https":
    +            return super(ProxyManager, self).connection_from_host(
    +                host, port, scheme, pool_kwargs=pool_kwargs
    +            )
    +
    +        return super(ProxyManager, self).connection_from_host(
    +            self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs
    +        )
    +
    +    def _set_proxy_headers(self, url, headers=None):
    +        """
    +        Sets headers needed by proxies: specifically, the Accept and Host
    +        headers. Only sets headers not provided by the user.
    +        """
    +        headers_ = {"Accept": "*/*"}
    +
    +        netloc = parse_url(url).netloc
    +        if netloc:
    +            headers_["Host"] = netloc
    +
    +        if headers:
    +            headers_.update(headers)
    +        return headers_
    +
    +    def urlopen(self, method, url, redirect=True, **kw):
    +        "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute."
    +        u = parse_url(url)
    +        if not connection_requires_http_tunnel(self.proxy, self.proxy_config, u.scheme):
    +            # For connections using HTTP CONNECT, httplib sets the necessary
    +            # headers on the CONNECT to the proxy. If we're not using CONNECT,
    +            # we'll definitely need to set 'Host' at the very least.
    +            headers = kw.get("headers", self.headers)
    +            kw["headers"] = self._set_proxy_headers(url, headers)
    +
    +        return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw)
    +
    +
    +def proxy_from_url(url, **kw):
    +    return ProxyManager(proxy_url=url, **kw)
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/request.py b/deployment-apps/metricator-for-nmon/lib/urllib3/request.py
    new file mode 100644
    index 0000000..398386a
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/request.py
    @@ -0,0 +1,170 @@
    +from __future__ import absolute_import
    +
    +from .filepost import encode_multipart_formdata
    +from .packages.six.moves.urllib.parse import urlencode
    +
    +__all__ = ["RequestMethods"]
    +
    +
    +class RequestMethods(object):
    +    """
    +    Convenience mixin for classes who implement a :meth:`urlopen` method, such
    +    as :class:`urllib3.HTTPConnectionPool` and
    +    :class:`urllib3.PoolManager`.
    +
    +    Provides behavior for making common types of HTTP request methods and
    +    decides which type of request field encoding to use.
    +
    +    Specifically,
    +
    +    :meth:`.request_encode_url` is for sending requests whose fields are
    +    encoded in the URL (such as GET, HEAD, DELETE).
    +
    +    :meth:`.request_encode_body` is for sending requests whose fields are
    +    encoded in the *body* of the request using multipart or www-form-urlencoded
    +    (such as for POST, PUT, PATCH).
    +
    +    :meth:`.request` is for making any kind of request, it will look up the
    +    appropriate encoding format and use one of the above two methods to make
    +    the request.
    +
    +    Initializer parameters:
    +
    +    :param headers:
    +        Headers to include with all requests, unless other headers are given
    +        explicitly.
    +    """
    +
    +    _encode_url_methods = {"DELETE", "GET", "HEAD", "OPTIONS"}
    +
    +    def __init__(self, headers=None):
    +        self.headers = headers or {}
    +
    +    def urlopen(
    +        self,
    +        method,
    +        url,
    +        body=None,
    +        headers=None,
    +        encode_multipart=True,
    +        multipart_boundary=None,
    +        **kw
    +    ):  # Abstract
    +        raise NotImplementedError(
    +            "Classes extending RequestMethods must implement "
    +            "their own ``urlopen`` method."
    +        )
    +
    +    def request(self, method, url, fields=None, headers=None, **urlopen_kw):
    +        """
    +        Make a request using :meth:`urlopen` with the appropriate encoding of
    +        ``fields`` based on the ``method`` used.
    +
    +        This is a convenience method that requires the least amount of manual
    +        effort. It can be used in most situations, while still having the
    +        option to drop down to more specific methods when necessary, such as
    +        :meth:`request_encode_url`, :meth:`request_encode_body`,
    +        or even the lowest level :meth:`urlopen`.
    +        """
    +        method = method.upper()
    +
    +        urlopen_kw["request_url"] = url
    +
    +        if method in self._encode_url_methods:
    +            return self.request_encode_url(
    +                method, url, fields=fields, headers=headers, **urlopen_kw
    +            )
    +        else:
    +            return self.request_encode_body(
    +                method, url, fields=fields, headers=headers, **urlopen_kw
    +            )
    +
    +    def request_encode_url(self, method, url, fields=None, headers=None, **urlopen_kw):
    +        """
    +        Make a request using :meth:`urlopen` with the ``fields`` encoded in
    +        the url. This is useful for request methods like GET, HEAD, DELETE, etc.
    +        """
    +        if headers is None:
    +            headers = self.headers
    +
    +        extra_kw = {"headers": headers}
    +        extra_kw.update(urlopen_kw)
    +
    +        if fields:
    +            url += "?" + urlencode(fields)
    +
    +        return self.urlopen(method, url, **extra_kw)
    +
    +    def request_encode_body(
    +        self,
    +        method,
    +        url,
    +        fields=None,
    +        headers=None,
    +        encode_multipart=True,
    +        multipart_boundary=None,
    +        **urlopen_kw
    +    ):
    +        """
    +        Make a request using :meth:`urlopen` with the ``fields`` encoded in
    +        the body. This is useful for request methods like POST, PUT, PATCH, etc.
    +
    +        When ``encode_multipart=True`` (default), then
    +        :func:`urllib3.encode_multipart_formdata` is used to encode
    +        the payload with the appropriate content type. Otherwise
    +        :func:`urllib.parse.urlencode` is used with the
    +        'application/x-www-form-urlencoded' content type.
    +
    +        Multipart encoding must be used when posting files, and it's reasonably
    +        safe to use it in other times too. However, it may break request
    +        signing, such as with OAuth.
    +
    +        Supports an optional ``fields`` parameter of key/value strings AND
    +        key/filetuple. A filetuple is a (filename, data, MIME type) tuple where
    +        the MIME type is optional. For example::
    +
    +            fields = {
    +                'foo': 'bar',
    +                'fakefile': ('foofile.txt', 'contents of foofile'),
    +                'realfile': ('barfile.txt', open('realfile').read()),
    +                'typedfile': ('bazfile.bin', open('bazfile').read(),
    +                              'image/jpeg'),
    +                'nonamefile': 'contents of nonamefile field',
    +            }
    +
    +        When uploading a file, providing a filename (the first parameter of the
    +        tuple) is optional but recommended to best mimic behavior of browsers.
    +
    +        Note that if ``headers`` are supplied, the 'Content-Type' header will
    +        be overwritten because it depends on the dynamic random boundary string
    +        which is used to compose the body of the request. The random boundary
    +        string can be explicitly set with the ``multipart_boundary`` parameter.
    +        """
    +        if headers is None:
    +            headers = self.headers
    +
    +        extra_kw = {"headers": {}}
    +
    +        if fields:
    +            if "body" in urlopen_kw:
    +                raise TypeError(
    +                    "request got values for both 'fields' and 'body', can only specify one."
    +                )
    +
    +            if encode_multipart:
    +                body, content_type = encode_multipart_formdata(
    +                    fields, boundary=multipart_boundary
    +                )
    +            else:
    +                body, content_type = (
    +                    urlencode(fields),
    +                    "application/x-www-form-urlencoded",
    +                )
    +
    +            extra_kw["body"] = body
    +            extra_kw["headers"] = {"Content-Type": content_type}
    +
    +        extra_kw["headers"].update(headers)
    +        extra_kw.update(urlopen_kw)
    +
    +        return self.urlopen(method, url, **extra_kw)
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/response.py b/deployment-apps/metricator-for-nmon/lib/urllib3/response.py
    new file mode 100644
    index 0000000..0bd13d4
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/response.py
    @@ -0,0 +1,885 @@
    +from __future__ import absolute_import
    +
    +import io
    +import logging
    +import sys
    +import warnings
    +import zlib
    +from contextlib import contextmanager
    +from socket import error as SocketError
    +from socket import timeout as SocketTimeout
    +
    +try:
    +    try:
    +        import brotlicffi as brotli
    +    except ImportError:
    +        import brotli
    +except ImportError:
    +    brotli = None
    +
    +from . import util
    +from ._collections import HTTPHeaderDict
    +from .connection import BaseSSLError, HTTPException
    +from .exceptions import (
    +    BodyNotHttplibCompatible,
    +    DecodeError,
    +    HTTPError,
    +    IncompleteRead,
    +    InvalidChunkLength,
    +    InvalidHeader,
    +    ProtocolError,
    +    ReadTimeoutError,
    +    ResponseNotChunked,
    +    SSLError,
    +)
    +from .packages import six
    +from .util.response import is_fp_closed, is_response_to_head
    +
    +log = logging.getLogger(__name__)
    +
    +
    +class DeflateDecoder(object):
    +    def __init__(self):
    +        self._first_try = True
    +        self._data = b""
    +        self._obj = zlib.decompressobj()
    +
    +    def __getattr__(self, name):
    +        return getattr(self._obj, name)
    +
    +    def decompress(self, data):
    +        if not data:
    +            return data
    +
    +        if not self._first_try:
    +            return self._obj.decompress(data)
    +
    +        self._data += data
    +        try:
    +            decompressed = self._obj.decompress(data)
    +            if decompressed:
    +                self._first_try = False
    +                self._data = None
    +            return decompressed
    +        except zlib.error:
    +            self._first_try = False
    +            self._obj = zlib.decompressobj(-zlib.MAX_WBITS)
    +            try:
    +                return self.decompress(self._data)
    +            finally:
    +                self._data = None
    +
    +
    +class GzipDecoderState(object):
    +
    +    FIRST_MEMBER = 0
    +    OTHER_MEMBERS = 1
    +    SWALLOW_DATA = 2
    +
    +
    +class GzipDecoder(object):
    +    def __init__(self):
    +        self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
    +        self._state = GzipDecoderState.FIRST_MEMBER
    +
    +    def __getattr__(self, name):
    +        return getattr(self._obj, name)
    +
    +    def decompress(self, data):
    +        ret = bytearray()
    +        if self._state == GzipDecoderState.SWALLOW_DATA or not data:
    +            return bytes(ret)
    +        while True:
    +            try:
    +                ret += self._obj.decompress(data)
    +            except zlib.error:
    +                previous_state = self._state
    +                # Ignore data after the first error
    +                self._state = GzipDecoderState.SWALLOW_DATA
    +                if previous_state == GzipDecoderState.OTHER_MEMBERS:
    +                    # Allow trailing garbage acceptable in other gzip clients
    +                    return bytes(ret)
    +                raise
    +            data = self._obj.unused_data
    +            if not data:
    +                return bytes(ret)
    +            self._state = GzipDecoderState.OTHER_MEMBERS
    +            self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
    +
    +
    +if brotli is not None:
    +
    +    class BrotliDecoder(object):
    +        # Supports both 'brotlipy' and 'Brotli' packages
    +        # since they share an import name. The top branches
    +        # are for 'brotlipy' and bottom branches for 'Brotli'
    +        def __init__(self):
    +            self._obj = brotli.Decompressor()
    +            if hasattr(self._obj, "decompress"):
    +                self.decompress = self._obj.decompress
    +            else:
    +                self.decompress = self._obj.process
    +
    +        def flush(self):
    +            if hasattr(self._obj, "flush"):
    +                return self._obj.flush()
    +            return b""
    +
    +
    +class MultiDecoder(object):
    +    """
    +    From RFC7231:
    +        If one or more encodings have been applied to a representation, the
    +        sender that applied the encodings MUST generate a Content-Encoding
    +        header field that lists the content codings in the order in which
    +        they were applied.
    +    """
    +
    +    def __init__(self, modes):
    +        self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")]
    +
    +    def flush(self):
    +        return self._decoders[0].flush()
    +
    +    def decompress(self, data):
    +        for d in reversed(self._decoders):
    +            data = d.decompress(data)
    +        return data
    +
    +
    +def _get_decoder(mode):
    +    if "," in mode:
    +        return MultiDecoder(mode)
    +
    +    if mode == "gzip":
    +        return GzipDecoder()
    +
    +    if brotli is not None and mode == "br":
    +        return BrotliDecoder()
    +
    +    return DeflateDecoder()
    +
    +
    +class HTTPResponse(io.IOBase):
    +    """
    +    HTTP Response container.
    +
    +    Backwards-compatible with :class:`http.client.HTTPResponse` but the response ``body`` is
    +    loaded and decoded on-demand when the ``data`` property is accessed.  This
    +    class is also compatible with the Python standard library's :mod:`io`
    +    module, and can hence be treated as a readable object in the context of that
    +    framework.
    +
    +    Extra parameters for behaviour not present in :class:`http.client.HTTPResponse`:
    +
    +    :param preload_content:
    +        If True, the response's body will be preloaded during construction.
    +
    +    :param decode_content:
    +        If True, will attempt to decode the body based on the
    +        'content-encoding' header.
    +
    +    :param original_response:
    +        When this HTTPResponse wrapper is generated from an :class:`http.client.HTTPResponse`
    +        object, it's convenient to include the original for debug purposes. It's
    +        otherwise unused.
    +
    +    :param retries:
    +        The retries contains the last :class:`~urllib3.util.retry.Retry` that
    +        was used during the request.
    +
    +    :param enforce_content_length:
    +        Enforce content length checking. Body returned by server must match
    +        value of Content-Length header, if present. Otherwise, raise error.
    +    """
    +
    +    CONTENT_DECODERS = ["gzip", "deflate"]
    +    if brotli is not None:
    +        CONTENT_DECODERS += ["br"]
    +    REDIRECT_STATUSES = [301, 302, 303, 307, 308]
    +
    +    def __init__(
    +        self,
    +        body="",
    +        headers=None,
    +        status=0,
    +        version=0,
    +        reason=None,
    +        strict=0,
    +        preload_content=True,
    +        decode_content=True,
    +        original_response=None,
    +        pool=None,
    +        connection=None,
    +        msg=None,
    +        retries=None,
    +        enforce_content_length=False,
    +        request_method=None,
    +        request_url=None,
    +        auto_close=True,
    +    ):
    +
    +        if isinstance(headers, HTTPHeaderDict):
    +            self.headers = headers
    +        else:
    +            self.headers = HTTPHeaderDict(headers)
    +        self.status = status
    +        self.version = version
    +        self.reason = reason
    +        self.strict = strict
    +        self.decode_content = decode_content
    +        self.retries = retries
    +        self.enforce_content_length = enforce_content_length
    +        self.auto_close = auto_close
    +
    +        self._decoder = None
    +        self._body = None
    +        self._fp = None
    +        self._original_response = original_response
    +        self._fp_bytes_read = 0
    +        self.msg = msg
    +        self._request_url = request_url
    +
    +        if body and isinstance(body, (six.string_types, bytes)):
    +            self._body = body
    +
    +        self._pool = pool
    +        self._connection = connection
    +
    +        if hasattr(body, "read"):
    +            self._fp = body
    +
    +        # Are we using the chunked-style of transfer encoding?
    +        self.chunked = False
    +        self.chunk_left = None
    +        tr_enc = self.headers.get("transfer-encoding", "").lower()
    +        # Don't incur the penalty of creating a list and then discarding it
    +        encodings = (enc.strip() for enc in tr_enc.split(","))
    +        if "chunked" in encodings:
    +            self.chunked = True
    +
    +        # Determine length of response
    +        self.length_remaining = self._init_length(request_method)
    +
    +        # If requested, preload the body.
    +        if preload_content and not self._body:
    +            self._body = self.read(decode_content=decode_content)
    +
    +    def get_redirect_location(self):
    +        """
    +        Should we redirect and where to?
    +
    +        :returns: Truthy redirect location string if we got a redirect status
    +            code and valid location. ``None`` if redirect status and no
    +            location. ``False`` if not a redirect status code.
    +        """
    +        if self.status in self.REDIRECT_STATUSES:
    +            return self.headers.get("location")
    +
    +        return False
    +
    +    def release_conn(self):
    +        if not self._pool or not self._connection:
    +            return
    +
    +        self._pool._put_conn(self._connection)
    +        self._connection = None
    +
    +    def drain_conn(self):
    +        """
    +        Read and discard any remaining HTTP response data in the response connection.
    +
    +        Unread data in the HTTPResponse connection blocks the connection from being released back to the pool.
    +        """
    +        try:
    +            self.read()
    +        except (HTTPError, SocketError, BaseSSLError, HTTPException):
    +            pass
    +
    +    @property
    +    def data(self):
    +        # For backwards-compat with earlier urllib3 0.4 and earlier.
    +        if self._body:
    +            return self._body
    +
    +        if self._fp:
    +            return self.read(cache_content=True)
    +
    +    @property
    +    def connection(self):
    +        return self._connection
    +
    +    def isclosed(self):
    +        return is_fp_closed(self._fp)
    +
    +    def tell(self):
    +        """
    +        Obtain the number of bytes pulled over the wire so far. May differ from
    +        the amount of content returned by :meth:``urllib3.response.HTTPResponse.read``
    +        if bytes are encoded on the wire (e.g, compressed).
    +        """
    +        return self._fp_bytes_read
    +
    +    def _init_length(self, request_method):
    +        """
    +        Set initial length value for Response content if available.
    +        """
    +        length = self.headers.get("content-length")
    +
    +        if length is not None:
    +            if self.chunked:
    +                # This Response will fail with an IncompleteRead if it can't be
    +                # received as chunked. This method falls back to attempt reading
    +                # the response before raising an exception.
    +                log.warning(
    +                    "Received response with both Content-Length and "
    +                    "Transfer-Encoding set. This is expressly forbidden "
    +                    "by RFC 7230 sec 3.3.2. Ignoring Content-Length and "
    +                    "attempting to process response as Transfer-Encoding: "
    +                    "chunked."
    +                )
    +                return None
    +
    +            try:
    +                # RFC 7230 section 3.3.2 specifies multiple content lengths can
    +                # be sent in a single Content-Length header
    +                # (e.g. Content-Length: 42, 42). This line ensures the values
    +                # are all valid ints and that as long as the `set` length is 1,
    +                # all values are the same. Otherwise, the header is invalid.
    +                lengths = set([int(val) for val in length.split(",")])
    +                if len(lengths) > 1:
    +                    raise InvalidHeader(
    +                        "Content-Length contained multiple "
    +                        "unmatching values (%s)" % length
    +                    )
    +                length = lengths.pop()
    +            except ValueError:
    +                length = None
    +            else:
    +                if length < 0:
    +                    length = None
    +
    +        # Convert status to int for comparison
    +        # In some cases, httplib returns a status of "_UNKNOWN"
    +        try:
    +            status = int(self.status)
    +        except ValueError:
    +            status = 0
    +
    +        # Check for responses that shouldn't include a body
    +        if status in (204, 304) or 100 <= status < 200 or request_method == "HEAD":
    +            length = 0
    +
    +        return length
    +
    +    def _init_decoder(self):
    +        """
    +        Set-up the _decoder attribute if necessary.
    +        """
    +        # Note: content-encoding value should be case-insensitive, per RFC 7230
    +        # Section 3.2
    +        content_encoding = self.headers.get("content-encoding", "").lower()
    +        if self._decoder is None:
    +            if content_encoding in self.CONTENT_DECODERS:
    +                self._decoder = _get_decoder(content_encoding)
    +            elif "," in content_encoding:
    +                encodings = [
    +                    e.strip()
    +                    for e in content_encoding.split(",")
    +                    if e.strip() in self.CONTENT_DECODERS
    +                ]
    +                if len(encodings):
    +                    self._decoder = _get_decoder(content_encoding)
    +
    +    DECODER_ERROR_CLASSES = (IOError, zlib.error)
    +    if brotli is not None:
    +        DECODER_ERROR_CLASSES += (brotli.error,)
    +
    +    def _decode(self, data, decode_content, flush_decoder):
    +        """
    +        Decode the data passed in and potentially flush the decoder.
    +        """
    +        if not decode_content:
    +            return data
    +
    +        try:
    +            if self._decoder:
    +                data = self._decoder.decompress(data)
    +        except self.DECODER_ERROR_CLASSES as e:
    +            content_encoding = self.headers.get("content-encoding", "").lower()
    +            raise DecodeError(
    +                "Received response with content-encoding: %s, but "
    +                "failed to decode it." % content_encoding,
    +                e,
    +            )
    +        if flush_decoder:
    +            data += self._flush_decoder()
    +
    +        return data
    +
    +    def _flush_decoder(self):
    +        """
    +        Flushes the decoder. Should only be called if the decoder is actually
    +        being used.
    +        """
    +        if self._decoder:
    +            buf = self._decoder.decompress(b"")
    +            return buf + self._decoder.flush()
    +
    +        return b""
    +
    +    @contextmanager
    +    def _error_catcher(self):
    +        """
    +        Catch low-level python exceptions, instead re-raising urllib3
    +        variants, so that low-level exceptions are not leaked in the
    +        high-level api.
    +
    +        On exit, release the connection back to the pool.
    +        """
    +        clean_exit = False
    +
    +        try:
    +            try:
    +                yield
    +
    +            except SocketTimeout:
    +                # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but
    +                # there is yet no clean way to get at it from this context.
    +                raise ReadTimeoutError(self._pool, None, "Read timed out.")
    +
    +            except BaseSSLError as e:
    +                # FIXME: Is there a better way to differentiate between SSLErrors?
    +                if "read operation timed out" not in str(e):
    +                    # SSL errors related to framing/MAC get wrapped and reraised here
    +                    raise SSLError(e)
    +
    +                raise ReadTimeoutError(self._pool, None, "Read timed out.")
    +
    +            except (HTTPException, SocketError) as e:
    +                # This includes IncompleteRead.
    +                raise ProtocolError("Connection broken: %r" % e, e)
    +
    +            # If no exception is thrown, we should avoid cleaning up
    +            # unnecessarily.
    +            clean_exit = True
    +        finally:
    +            # If we didn't terminate cleanly, we need to throw away our
    +            # connection.
    +            if not clean_exit:
    +                # The response may not be closed but we're not going to use it
    +                # anymore so close it now to ensure that the connection is
    +                # released back to the pool.
    +                if self._original_response:
    +                    self._original_response.close()
    +
    +                # Closing the response may not actually be sufficient to close
    +                # everything, so if we have a hold of the connection close that
    +                # too.
    +                if self._connection:
    +                    self._connection.close()
    +
    +            # If we hold the original response but it's closed now, we should
    +            # return the connection back to the pool.
    +            if self._original_response and self._original_response.isclosed():
    +                self.release_conn()
    +
    +    def _fp_read(self, amt):
    +        """
    +        Read a response with the thought that reading the number of bytes
    +        larger than can fit in a 32-bit int at a time via SSL in some
    +        known cases leads to an overflow error that has to be prevented
    +        if `amt` or `self.length_remaining` indicate that a problem may
    +        happen.
    +
    +        The known cases:
    +          * 3.8 <= CPython < 3.9.7 because of a bug
    +            https://github.com/urllib3/urllib3/issues/2513#issuecomment-1152559900.
    +          * urllib3 injected with pyOpenSSL-backed SSL-support.
    +          * CPython < 3.10 only when `amt` does not fit 32-bit int.
    +        """
    +        assert self._fp
    +        c_int_max = 2 ** 31 - 1
    +        if (
    +            (
    +                (amt and amt > c_int_max)
    +                or (self.length_remaining and self.length_remaining > c_int_max)
    +            )
    +            and not util.IS_SECURETRANSPORT
    +            and (util.IS_PYOPENSSL or sys.version_info < (3, 10))
    +        ):
    +            buffer = io.BytesIO()
    +            # Besides `max_chunk_amt` being a maximum chunk size, it
    +            # affects memory overhead of reading a response by this
    +            # method in CPython.
    +            # `c_int_max` equal to 2 GiB - 1 byte is the actual maximum
    +            # chunk size that does not lead to an overflow error, but
    +            # 256 MiB is a compromise.
    +            max_chunk_amt = 2 ** 28
    +            while amt is None or amt != 0:
    +                if amt is not None:
    +                    chunk_amt = min(amt, max_chunk_amt)
    +                    amt -= chunk_amt
    +                else:
    +                    chunk_amt = max_chunk_amt
    +                data = self._fp.read(chunk_amt)
    +                if not data:
    +                    break
    +                buffer.write(data)
    +                del data  # to reduce peak memory usage by `max_chunk_amt`.
    +            return buffer.getvalue()
    +        else:
    +            # StringIO doesn't like amt=None
    +            return self._fp.read(amt) if amt is not None else self._fp.read()
    +
    +    def read(self, amt=None, decode_content=None, cache_content=False):
    +        """
    +        Similar to :meth:`http.client.HTTPResponse.read`, but with two additional
    +        parameters: ``decode_content`` and ``cache_content``.
    +
    +        :param amt:
    +            How much of the content to read. If specified, caching is skipped
    +            because it doesn't make sense to cache partial content as the full
    +            response.
    +
    +        :param decode_content:
    +            If True, will attempt to decode the body based on the
    +            'content-encoding' header.
    +
    +        :param cache_content:
    +            If True, will save the returned data such that the same result is
    +            returned despite of the state of the underlying file object. This
    +            is useful if you want the ``.data`` property to continue working
    +            after having ``.read()`` the file object. (Overridden if ``amt`` is
    +            set.)
    +        """
    +        self._init_decoder()
    +        if decode_content is None:
    +            decode_content = self.decode_content
    +
    +        if self._fp is None:
    +            return
    +
    +        flush_decoder = False
    +        fp_closed = getattr(self._fp, "closed", False)
    +
    +        with self._error_catcher():
    +            data = self._fp_read(amt) if not fp_closed else b""
    +            if amt is None:
    +                flush_decoder = True
    +            else:
    +                cache_content = False
    +                if (
    +                    amt != 0 and not data
    +                ):  # Platform-specific: Buggy versions of Python.
    +                    # Close the connection when no data is returned
    +                    #
    +                    # This is redundant to what httplib/http.client _should_
    +                    # already do.  However, versions of python released before
    +                    # December 15, 2012 (http://bugs.python.org/issue16298) do
    +                    # not properly close the connection in all cases. There is
    +                    # no harm in redundantly calling close.
    +                    self._fp.close()
    +                    flush_decoder = True
    +                    if self.enforce_content_length and self.length_remaining not in (
    +                        0,
    +                        None,
    +                    ):
    +                        # This is an edge case that httplib failed to cover due
    +                        # to concerns of backward compatibility. We're
    +                        # addressing it here to make sure IncompleteRead is
    +                        # raised during streaming, so all calls with incorrect
    +                        # Content-Length are caught.
    +                        raise IncompleteRead(self._fp_bytes_read, self.length_remaining)
    +
    +        if data:
    +            self._fp_bytes_read += len(data)
    +            if self.length_remaining is not None:
    +                self.length_remaining -= len(data)
    +
    +            data = self._decode(data, decode_content, flush_decoder)
    +
    +            if cache_content:
    +                self._body = data
    +
    +        return data
    +
    +    def stream(self, amt=2 ** 16, decode_content=None):
    +        """
    +        A generator wrapper for the read() method. A call will block until
    +        ``amt`` bytes have been read from the connection or until the
    +        connection is closed.
    +
    +        :param amt:
    +            How much of the content to read. The generator will return up to
    +            much data per iteration, but may return less. This is particularly
    +            likely when using compressed data. However, the empty string will
    +            never be returned.
    +
    +        :param decode_content:
    +            If True, will attempt to decode the body based on the
    +            'content-encoding' header.
    +        """
    +        if self.chunked and self.supports_chunked_reads():
    +            for line in self.read_chunked(amt, decode_content=decode_content):
    +                yield line
    +        else:
    +            while not is_fp_closed(self._fp):
    +                data = self.read(amt=amt, decode_content=decode_content)
    +
    +                if data:
    +                    yield data
    +
    +    @classmethod
    +    def from_httplib(ResponseCls, r, **response_kw):
    +        """
    +        Given an :class:`http.client.HTTPResponse` instance ``r``, return a
    +        corresponding :class:`urllib3.response.HTTPResponse` object.
    +
    +        Remaining parameters are passed to the HTTPResponse constructor, along
    +        with ``original_response=r``.
    +        """
    +        headers = r.msg
    +
    +        if not isinstance(headers, HTTPHeaderDict):
    +            if six.PY2:
    +                # Python 2.7
    +                headers = HTTPHeaderDict.from_httplib(headers)
    +            else:
    +                headers = HTTPHeaderDict(headers.items())
    +
    +        # HTTPResponse objects in Python 3 don't have a .strict attribute
    +        strict = getattr(r, "strict", 0)
    +        resp = ResponseCls(
    +            body=r,
    +            headers=headers,
    +            status=r.status,
    +            version=r.version,
    +            reason=r.reason,
    +            strict=strict,
    +            original_response=r,
    +            **response_kw
    +        )
    +        return resp
    +
    +    # Backwards-compatibility methods for http.client.HTTPResponse
    +    def getheaders(self):
    +        warnings.warn(
    +            "HTTPResponse.getheaders() is deprecated and will be removed "
    +            "in urllib3 v2.1.0. Instead access HTTPResponse.headers directly.",
    +            category=DeprecationWarning,
    +            stacklevel=2,
    +        )
    +        return self.headers
    +
    +    def getheader(self, name, default=None):
    +        warnings.warn(
    +            "HTTPResponse.getheader() is deprecated and will be removed "
    +            "in urllib3 v2.1.0. Instead use HTTPResponse.headers.get(name, default).",
    +            category=DeprecationWarning,
    +            stacklevel=2,
    +        )
    +        return self.headers.get(name, default)
    +
    +    # Backwards compatibility for http.cookiejar
    +    def info(self):
    +        return self.headers
    +
    +    # Overrides from io.IOBase
    +    def close(self):
    +        if not self.closed:
    +            self._fp.close()
    +
    +        if self._connection:
    +            self._connection.close()
    +
    +        if not self.auto_close:
    +            io.IOBase.close(self)
    +
    +    @property
    +    def closed(self):
    +        if not self.auto_close:
    +            return io.IOBase.closed.__get__(self)
    +        elif self._fp is None:
    +            return True
    +        elif hasattr(self._fp, "isclosed"):
    +            return self._fp.isclosed()
    +        elif hasattr(self._fp, "closed"):
    +            return self._fp.closed
    +        else:
    +            return True
    +
    +    def fileno(self):
    +        if self._fp is None:
    +            raise IOError("HTTPResponse has no file to get a fileno from")
    +        elif hasattr(self._fp, "fileno"):
    +            return self._fp.fileno()
    +        else:
    +            raise IOError(
    +                "The file-like object this HTTPResponse is wrapped "
    +                "around has no file descriptor"
    +            )
    +
    +    def flush(self):
    +        if (
    +            self._fp is not None
    +            and hasattr(self._fp, "flush")
    +            and not getattr(self._fp, "closed", False)
    +        ):
    +            return self._fp.flush()
    +
    +    def readable(self):
    +        # This method is required for `io` module compatibility.
    +        return True
    +
    +    def readinto(self, b):
    +        # This method is required for `io` module compatibility.
    +        temp = self.read(len(b))
    +        if len(temp) == 0:
    +            return 0
    +        else:
    +            b[: len(temp)] = temp
    +            return len(temp)
    +
    +    def supports_chunked_reads(self):
    +        """
    +        Checks if the underlying file-like object looks like a
    +        :class:`http.client.HTTPResponse` object. We do this by testing for
    +        the fp attribute. If it is present we assume it returns raw chunks as
    +        processed by read_chunked().
    +        """
    +        return hasattr(self._fp, "fp")
    +
    +    def _update_chunk_length(self):
    +        # First, we'll figure out length of a chunk and then
    +        # we'll try to read it from socket.
    +        if self.chunk_left is not None:
    +            return
    +        line = self._fp.fp.readline()
    +        line = line.split(b";", 1)[0]
    +        try:
    +            self.chunk_left = int(line, 16)
    +        except ValueError:
    +            # Invalid chunked protocol response, abort.
    +            self.close()
    +            raise InvalidChunkLength(self, line)
    +
    +    def _handle_chunk(self, amt):
    +        returned_chunk = None
    +        if amt is None:
    +            chunk = self._fp._safe_read(self.chunk_left)
    +            returned_chunk = chunk
    +            self._fp._safe_read(2)  # Toss the CRLF at the end of the chunk.
    +            self.chunk_left = None
    +        elif amt < self.chunk_left:
    +            value = self._fp._safe_read(amt)
    +            self.chunk_left = self.chunk_left - amt
    +            returned_chunk = value
    +        elif amt == self.chunk_left:
    +            value = self._fp._safe_read(amt)
    +            self._fp._safe_read(2)  # Toss the CRLF at the end of the chunk.
    +            self.chunk_left = None
    +            returned_chunk = value
    +        else:  # amt > self.chunk_left
    +            returned_chunk = self._fp._safe_read(self.chunk_left)
    +            self._fp._safe_read(2)  # Toss the CRLF at the end of the chunk.
    +            self.chunk_left = None
    +        return returned_chunk
    +
    +    def read_chunked(self, amt=None, decode_content=None):
    +        """
    +        Similar to :meth:`HTTPResponse.read`, but with an additional
    +        parameter: ``decode_content``.
    +
    +        :param amt:
    +            How much of the content to read. If specified, caching is skipped
    +            because it doesn't make sense to cache partial content as the full
    +            response.
    +
    +        :param decode_content:
    +            If True, will attempt to decode the body based on the
    +            'content-encoding' header.
    +        """
    +        self._init_decoder()
    +        # FIXME: Rewrite this method and make it a class with a better structured logic.
    +        if not self.chunked:
    +            raise ResponseNotChunked(
    +                "Response is not chunked. "
    +                "Header 'transfer-encoding: chunked' is missing."
    +            )
    +        if not self.supports_chunked_reads():
    +            raise BodyNotHttplibCompatible(
    +                "Body should be http.client.HTTPResponse like. "
    +                "It should have have an fp attribute which returns raw chunks."
    +            )
    +
    +        with self._error_catcher():
    +            # Don't bother reading the body of a HEAD request.
    +            if self._original_response and is_response_to_head(self._original_response):
    +                self._original_response.close()
    +                return
    +
    +            # If a response is already read and closed
    +            # then return immediately.
    +            if self._fp.fp is None:
    +                return
    +
    +            while True:
    +                self._update_chunk_length()
    +                if self.chunk_left == 0:
    +                    break
    +                chunk = self._handle_chunk(amt)
    +                decoded = self._decode(
    +                    chunk, decode_content=decode_content, flush_decoder=False
    +                )
    +                if decoded:
    +                    yield decoded
    +
    +            if decode_content:
    +                # On CPython and PyPy, we should never need to flush the
    +                # decoder. However, on Jython we *might* need to, so
    +                # lets defensively do it anyway.
    +                decoded = self._flush_decoder()
    +                if decoded:  # Platform-specific: Jython.
    +                    yield decoded
    +
    +            # Chunk content ends with \r\n: discard it.
    +            while True:
    +                line = self._fp.fp.readline()
    +                if not line:
    +                    # Some sites may not end with '\r\n'.
    +                    break
    +                if line == b"\r\n":
    +                    break
    +
    +            # We read everything; close the "file".
    +            if self._original_response:
    +                self._original_response.close()
    +
    +    def geturl(self):
    +        """
    +        Returns the URL that was the source of this response.
    +        If the request that generated this response redirected, this method
    +        will return the final redirect location.
    +        """
    +        if self.retries is not None and len(self.retries.history):
    +            return self.retries.history[-1].redirect_location
    +        else:
    +            return self._request_url
    +
    +    def __iter__(self):
    +        buffer = []
    +        for chunk in self.stream(decode_content=True):
    +            if b"\n" in chunk:
    +                chunk = chunk.split(b"\n")
    +                yield b"".join(buffer) + chunk[0] + b"\n"
    +                for x in chunk[1:-1]:
    +                    yield x + b"\n"
    +                if chunk[-1]:
    +                    buffer = [chunk[-1]]
    +                else:
    +                    buffer = []
    +            else:
    +                buffer.append(chunk)
    +        if buffer:
    +            yield b"".join(buffer)
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/__init__.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/__init__.py
    new file mode 100644
    index 0000000..4547fc5
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/__init__.py
    @@ -0,0 +1,49 @@
    +from __future__ import absolute_import
    +
    +# For backwards compatibility, provide imports that used to be here.
    +from .connection import is_connection_dropped
    +from .request import SKIP_HEADER, SKIPPABLE_HEADERS, make_headers
    +from .response import is_fp_closed
    +from .retry import Retry
    +from .ssl_ import (
    +    ALPN_PROTOCOLS,
    +    HAS_SNI,
    +    IS_PYOPENSSL,
    +    IS_SECURETRANSPORT,
    +    PROTOCOL_TLS,
    +    SSLContext,
    +    assert_fingerprint,
    +    resolve_cert_reqs,
    +    resolve_ssl_version,
    +    ssl_wrap_socket,
    +)
    +from .timeout import Timeout, current_time
    +from .url import Url, get_host, parse_url, split_first
    +from .wait import wait_for_read, wait_for_write
    +
    +__all__ = (
    +    "HAS_SNI",
    +    "IS_PYOPENSSL",
    +    "IS_SECURETRANSPORT",
    +    "SSLContext",
    +    "PROTOCOL_TLS",
    +    "ALPN_PROTOCOLS",
    +    "Retry",
    +    "Timeout",
    +    "Url",
    +    "assert_fingerprint",
    +    "current_time",
    +    "is_connection_dropped",
    +    "is_fp_closed",
    +    "get_host",
    +    "parse_url",
    +    "make_headers",
    +    "resolve_cert_reqs",
    +    "resolve_ssl_version",
    +    "split_first",
    +    "ssl_wrap_socket",
    +    "wait_for_read",
    +    "wait_for_write",
    +    "SKIP_HEADER",
    +    "SKIPPABLE_HEADERS",
    +)
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/connection.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/connection.py
    new file mode 100644
    index 0000000..6af1138
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/connection.py
    @@ -0,0 +1,149 @@
    +from __future__ import absolute_import
    +
    +import socket
    +
    +from ..contrib import _appengine_environ
    +from ..exceptions import LocationParseError
    +from ..packages import six
    +from .wait import NoWayToWaitForSocketError, wait_for_read
    +
    +
    +def is_connection_dropped(conn):  # Platform-specific
    +    """
    +    Returns True if the connection is dropped and should be closed.
    +
    +    :param conn:
    +        :class:`http.client.HTTPConnection` object.
    +
    +    Note: For platforms like AppEngine, this will always return ``False`` to
    +    let the platform handle connection recycling transparently for us.
    +    """
    +    sock = getattr(conn, "sock", False)
    +    if sock is False:  # Platform-specific: AppEngine
    +        return False
    +    if sock is None:  # Connection already closed (such as by httplib).
    +        return True
    +    try:
    +        # Returns True if readable, which here means it's been dropped
    +        return wait_for_read(sock, timeout=0.0)
    +    except NoWayToWaitForSocketError:  # Platform-specific: AppEngine
    +        return False
    +
    +
    +# This function is copied from socket.py in the Python 2.7 standard
    +# library test suite. Added to its signature is only `socket_options`.
    +# One additional modification is that we avoid binding to IPv6 servers
    +# discovered in DNS if the system doesn't have IPv6 functionality.
    +def create_connection(
    +    address,
    +    timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
    +    source_address=None,
    +    socket_options=None,
    +):
    +    """Connect to *address* and return the socket object.
    +
    +    Convenience function.  Connect to *address* (a 2-tuple ``(host,
    +    port)``) and return the socket object.  Passing the optional
    +    *timeout* parameter will set the timeout on the socket instance
    +    before attempting to connect.  If no *timeout* is supplied, the
    +    global default timeout setting returned by :func:`socket.getdefaulttimeout`
    +    is used.  If *source_address* is set it must be a tuple of (host, port)
    +    for the socket to bind as a source address before making the connection.
    +    An host of '' or port 0 tells the OS to use the default.
    +    """
    +
    +    host, port = address
    +    if host.startswith("["):
    +        host = host.strip("[]")
    +    err = None
    +
    +    # Using the value from allowed_gai_family() in the context of getaddrinfo lets
    +    # us select whether to work with IPv4 DNS records, IPv6 records, or both.
    +    # The original create_connection function always returns all records.
    +    family = allowed_gai_family()
    +
    +    try:
    +        host.encode("idna")
    +    except UnicodeError:
    +        return six.raise_from(
    +            LocationParseError(u"'%s', label empty or too long" % host), None
    +        )
    +
    +    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
    +        af, socktype, proto, canonname, sa = res
    +        sock = None
    +        try:
    +            sock = socket.socket(af, socktype, proto)
    +
    +            # If provided, set socket level options before connecting.
    +            _set_socket_options(sock, socket_options)
    +
    +            if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT:
    +                sock.settimeout(timeout)
    +            if source_address:
    +                sock.bind(source_address)
    +            sock.connect(sa)
    +            return sock
    +
    +        except socket.error as e:
    +            err = e
    +            if sock is not None:
    +                sock.close()
    +                sock = None
    +
    +    if err is not None:
    +        raise err
    +
    +    raise socket.error("getaddrinfo returns an empty list")
    +
    +
    +def _set_socket_options(sock, options):
    +    if options is None:
    +        return
    +
    +    for opt in options:
    +        sock.setsockopt(*opt)
    +
    +
    +def allowed_gai_family():
    +    """This function is designed to work in the context of
    +    getaddrinfo, where family=socket.AF_UNSPEC is the default and
    +    will perform a DNS search for both IPv6 and IPv4 records."""
    +
    +    family = socket.AF_INET
    +    if HAS_IPV6:
    +        family = socket.AF_UNSPEC
    +    return family
    +
    +
    +def _has_ipv6(host):
    +    """Returns True if the system can bind an IPv6 address."""
    +    sock = None
    +    has_ipv6 = False
    +
    +    # App Engine doesn't support IPV6 sockets and actually has a quota on the
    +    # number of sockets that can be used, so just early out here instead of
    +    # creating a socket needlessly.
    +    # See https://github.com/urllib3/urllib3/issues/1446
    +    if _appengine_environ.is_appengine_sandbox():
    +        return False
    +
    +    if socket.has_ipv6:
    +        # has_ipv6 returns true if cPython was compiled with IPv6 support.
    +        # It does not tell us if the system has IPv6 support enabled. To
    +        # determine that we must bind to an IPv6 address.
    +        # https://github.com/urllib3/urllib3/pull/611
    +        # https://bugs.python.org/issue658327
    +        try:
    +            sock = socket.socket(socket.AF_INET6)
    +            sock.bind((host, 0))
    +            has_ipv6 = True
    +        except Exception:
    +            pass
    +
    +    if sock:
    +        sock.close()
    +    return has_ipv6
    +
    +
    +HAS_IPV6 = _has_ipv6("::1")
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/proxy.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/proxy.py
    new file mode 100644
    index 0000000..2199cc7
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/proxy.py
    @@ -0,0 +1,57 @@
    +from .ssl_ import create_urllib3_context, resolve_cert_reqs, resolve_ssl_version
    +
    +
    +def connection_requires_http_tunnel(
    +    proxy_url=None, proxy_config=None, destination_scheme=None
    +):
    +    """
    +    Returns True if the connection requires an HTTP CONNECT through the proxy.
    +
    +    :param URL proxy_url:
    +        URL of the proxy.
    +    :param ProxyConfig proxy_config:
    +        Proxy configuration from poolmanager.py
    +    :param str destination_scheme:
    +        The scheme of the destination. (i.e https, http, etc)
    +    """
    +    # If we're not using a proxy, no way to use a tunnel.
    +    if proxy_url is None:
    +        return False
    +
    +    # HTTP destinations never require tunneling, we always forward.
    +    if destination_scheme == "http":
    +        return False
    +
    +    # Support for forwarding with HTTPS proxies and HTTPS destinations.
    +    if (
    +        proxy_url.scheme == "https"
    +        and proxy_config
    +        and proxy_config.use_forwarding_for_https
    +    ):
    +        return False
    +
    +    # Otherwise always use a tunnel.
    +    return True
    +
    +
    +def create_proxy_ssl_context(
    +    ssl_version, cert_reqs, ca_certs=None, ca_cert_dir=None, ca_cert_data=None
    +):
    +    """
    +    Generates a default proxy ssl context if one hasn't been provided by the
    +    user.
    +    """
    +    ssl_context = create_urllib3_context(
    +        ssl_version=resolve_ssl_version(ssl_version),
    +        cert_reqs=resolve_cert_reqs(cert_reqs),
    +    )
    +
    +    if (
    +        not ca_certs
    +        and not ca_cert_dir
    +        and not ca_cert_data
    +        and hasattr(ssl_context, "load_default_certs")
    +    ):
    +        ssl_context.load_default_certs()
    +
    +    return ssl_context
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/queue.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/queue.py
    new file mode 100644
    index 0000000..4178410
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/queue.py
    @@ -0,0 +1,22 @@
    +import collections
    +
    +from ..packages import six
    +from ..packages.six.moves import queue
    +
    +if six.PY2:
    +    # Queue is imported for side effects on MS Windows. See issue #229.
    +    import Queue as _unused_module_Queue  # noqa: F401
    +
    +
    +class LifoQueue(queue.Queue):
    +    def _init(self, _):
    +        self.queue = collections.deque()
    +
    +    def _qsize(self, len=len):
    +        return len(self.queue)
    +
    +    def _put(self, item):
    +        self.queue.append(item)
    +
    +    def _get(self):
    +        return self.queue.pop()
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/request.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/request.py
    new file mode 100644
    index 0000000..b574b08
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/request.py
    @@ -0,0 +1,146 @@
    +from __future__ import absolute_import
    +
    +from base64 import b64encode
    +
    +from ..exceptions import UnrewindableBodyError
    +from ..packages.six import b, integer_types
    +
    +# Pass as a value within ``headers`` to skip
    +# emitting some HTTP headers that are added automatically.
    +# The only headers that are supported are ``Accept-Encoding``,
    +# ``Host``, and ``User-Agent``.
    +SKIP_HEADER = "@@@SKIP_HEADER@@@"
    +SKIPPABLE_HEADERS = frozenset(["accept-encoding", "host", "user-agent"])
    +
    +ACCEPT_ENCODING = "gzip,deflate"
    +try:
    +    try:
    +        import brotlicffi as _unused_module_brotli  # noqa: F401
    +    except ImportError:
    +        import brotli as _unused_module_brotli  # noqa: F401
    +except ImportError:
    +    pass
    +else:
    +    ACCEPT_ENCODING += ",br"
    +
    +_FAILEDTELL = object()
    +
    +
    +def make_headers(
    +    keep_alive=None,
    +    accept_encoding=None,
    +    user_agent=None,
    +    basic_auth=None,
    +    proxy_basic_auth=None,
    +    disable_cache=None,
    +):
    +    """
    +    Shortcuts for generating request headers.
    +
    +    :param keep_alive:
    +        If ``True``, adds 'connection: keep-alive' header.
    +
    +    :param accept_encoding:
    +        Can be a boolean, list, or string.
    +        ``True`` translates to 'gzip,deflate'.
    +        List will get joined by comma.
    +        String will be used as provided.
    +
    +    :param user_agent:
    +        String representing the user-agent you want, such as
    +        "python-urllib3/0.6"
    +
    +    :param basic_auth:
    +        Colon-separated username:password string for 'authorization: basic ...'
    +        auth header.
    +
    +    :param proxy_basic_auth:
    +        Colon-separated username:password string for 'proxy-authorization: basic ...'
    +        auth header.
    +
    +    :param disable_cache:
    +        If ``True``, adds 'cache-control: no-cache' header.
    +
    +    Example::
    +
    +        >>> make_headers(keep_alive=True, user_agent="Batman/1.0")
    +        {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'}
    +        >>> make_headers(accept_encoding=True)
    +        {'accept-encoding': 'gzip,deflate'}
    +    """
    +    headers = {}
    +    if accept_encoding:
    +        if isinstance(accept_encoding, str):
    +            pass
    +        elif isinstance(accept_encoding, list):
    +            accept_encoding = ",".join(accept_encoding)
    +        else:
    +            accept_encoding = ACCEPT_ENCODING
    +        headers["accept-encoding"] = accept_encoding
    +
    +    if user_agent:
    +        headers["user-agent"] = user_agent
    +
    +    if keep_alive:
    +        headers["connection"] = "keep-alive"
    +
    +    if basic_auth:
    +        headers["authorization"] = "Basic " + b64encode(b(basic_auth)).decode("utf-8")
    +
    +    if proxy_basic_auth:
    +        headers["proxy-authorization"] = "Basic " + b64encode(
    +            b(proxy_basic_auth)
    +        ).decode("utf-8")
    +
    +    if disable_cache:
    +        headers["cache-control"] = "no-cache"
    +
    +    return headers
    +
    +
    +def set_file_position(body, pos):
    +    """
    +    If a position is provided, move file to that point.
    +    Otherwise, we'll attempt to record a position for future use.
    +    """
    +    if pos is not None:
    +        rewind_body(body, pos)
    +    elif getattr(body, "tell", None) is not None:
    +        try:
    +            pos = body.tell()
    +        except (IOError, OSError):
    +            # This differentiates from None, allowing us to catch
    +            # a failed `tell()` later when trying to rewind the body.
    +            pos = _FAILEDTELL
    +
    +    return pos
    +
    +
    +def rewind_body(body, body_pos):
    +    """
    +    Attempt to rewind body to a certain position.
    +    Primarily used for request redirects and retries.
    +
    +    :param body:
    +        File-like object that supports seek.
    +
    +    :param int pos:
    +        Position to seek to in file.
    +    """
    +    body_seek = getattr(body, "seek", None)
    +    if body_seek is not None and isinstance(body_pos, integer_types):
    +        try:
    +            body_seek(body_pos)
    +        except (IOError, OSError):
    +            raise UnrewindableBodyError(
    +                "An error occurred when rewinding request body for redirect/retry."
    +            )
    +    elif body_pos is _FAILEDTELL:
    +        raise UnrewindableBodyError(
    +            "Unable to record file position for rewinding "
    +            "request body during a redirect/retry."
    +        )
    +    else:
    +        raise ValueError(
    +            "body_pos must be of type integer, instead it was %s." % type(body_pos)
    +        )
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/response.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/response.py
    new file mode 100644
    index 0000000..5ea609c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/response.py
    @@ -0,0 +1,107 @@
    +from __future__ import absolute_import
    +
    +from email.errors import MultipartInvariantViolationDefect, StartBoundaryNotFoundDefect
    +
    +from ..exceptions import HeaderParsingError
    +from ..packages.six.moves import http_client as httplib
    +
    +
    +def is_fp_closed(obj):
    +    """
    +    Checks whether a given file-like object is closed.
    +
    +    :param obj:
    +        The file-like object to check.
    +    """
    +
    +    try:
    +        # Check `isclosed()` first, in case Python3 doesn't set `closed`.
    +        # GH Issue #928
    +        return obj.isclosed()
    +    except AttributeError:
    +        pass
    +
    +    try:
    +        # Check via the official file-like-object way.
    +        return obj.closed
    +    except AttributeError:
    +        pass
    +
    +    try:
    +        # Check if the object is a container for another file-like object that
    +        # gets released on exhaustion (e.g. HTTPResponse).
    +        return obj.fp is None
    +    except AttributeError:
    +        pass
    +
    +    raise ValueError("Unable to determine whether fp is closed.")
    +
    +
    +def assert_header_parsing(headers):
    +    """
    +    Asserts whether all headers have been successfully parsed.
    +    Extracts encountered errors from the result of parsing headers.
    +
    +    Only works on Python 3.
    +
    +    :param http.client.HTTPMessage headers: Headers to verify.
    +
    +    :raises urllib3.exceptions.HeaderParsingError:
    +        If parsing errors are found.
    +    """
    +
    +    # This will fail silently if we pass in the wrong kind of parameter.
    +    # To make debugging easier add an explicit check.
    +    if not isinstance(headers, httplib.HTTPMessage):
    +        raise TypeError("expected httplib.Message, got {0}.".format(type(headers)))
    +
    +    defects = getattr(headers, "defects", None)
    +    get_payload = getattr(headers, "get_payload", None)
    +
    +    unparsed_data = None
    +    if get_payload:
    +        # get_payload is actually email.message.Message.get_payload;
    +        # we're only interested in the result if it's not a multipart message
    +        if not headers.is_multipart():
    +            payload = get_payload()
    +
    +            if isinstance(payload, (bytes, str)):
    +                unparsed_data = payload
    +    if defects:
    +        # httplib is assuming a response body is available
    +        # when parsing headers even when httplib only sends
    +        # header data to parse_headers() This results in
    +        # defects on multipart responses in particular.
    +        # See: https://github.com/urllib3/urllib3/issues/800
    +
    +        # So we ignore the following defects:
    +        # - StartBoundaryNotFoundDefect:
    +        #     The claimed start boundary was never found.
    +        # - MultipartInvariantViolationDefect:
    +        #     A message claimed to be a multipart but no subparts were found.
    +        defects = [
    +            defect
    +            for defect in defects
    +            if not isinstance(
    +                defect, (StartBoundaryNotFoundDefect, MultipartInvariantViolationDefect)
    +            )
    +        ]
    +
    +    if defects or unparsed_data:
    +        raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data)
    +
    +
    +def is_response_to_head(response):
    +    """
    +    Checks whether the request of a response has been a HEAD-request.
    +    Handles the quirks of AppEngine.
    +
    +    :param http.client.HTTPResponse response:
    +        Response to check if the originating request
    +        used 'HEAD' as a method.
    +    """
    +    # FIXME: Can we do this somehow without accessing private httplib _method?
    +    method = response._method
    +    if isinstance(method, int):  # Platform-specific: Appengine
    +        return method == 3
    +    return method.upper() == "HEAD"
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/retry.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/retry.py
    new file mode 100644
    index 0000000..2490d5e
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/retry.py
    @@ -0,0 +1,620 @@
    +from __future__ import absolute_import
    +
    +import email
    +import logging
    +import re
    +import time
    +import warnings
    +from collections import namedtuple
    +from itertools import takewhile
    +
    +from ..exceptions import (
    +    ConnectTimeoutError,
    +    InvalidHeader,
    +    MaxRetryError,
    +    ProtocolError,
    +    ProxyError,
    +    ReadTimeoutError,
    +    ResponseError,
    +)
    +from ..packages import six
    +
    +log = logging.getLogger(__name__)
    +
    +
    +# Data structure for representing the metadata of requests that result in a retry.
    +RequestHistory = namedtuple(
    +    "RequestHistory", ["method", "url", "error", "status", "redirect_location"]
    +)
    +
    +
    +# TODO: In v2 we can remove this sentinel and metaclass with deprecated options.
    +_Default = object()
    +
    +
    +class _RetryMeta(type):
    +    @property
    +    def DEFAULT_METHOD_WHITELIST(cls):
    +        warnings.warn(
    +            "Using 'Retry.DEFAULT_METHOD_WHITELIST' is deprecated and "
    +            "will be removed in v2.0. Use 'Retry.DEFAULT_ALLOWED_METHODS' instead",
    +            DeprecationWarning,
    +        )
    +        return cls.DEFAULT_ALLOWED_METHODS
    +
    +    @DEFAULT_METHOD_WHITELIST.setter
    +    def DEFAULT_METHOD_WHITELIST(cls, value):
    +        warnings.warn(
    +            "Using 'Retry.DEFAULT_METHOD_WHITELIST' is deprecated and "
    +            "will be removed in v2.0. Use 'Retry.DEFAULT_ALLOWED_METHODS' instead",
    +            DeprecationWarning,
    +        )
    +        cls.DEFAULT_ALLOWED_METHODS = value
    +
    +    @property
    +    def DEFAULT_REDIRECT_HEADERS_BLACKLIST(cls):
    +        warnings.warn(
    +            "Using 'Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST' is deprecated and "
    +            "will be removed in v2.0. Use 'Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT' instead",
    +            DeprecationWarning,
    +        )
    +        return cls.DEFAULT_REMOVE_HEADERS_ON_REDIRECT
    +
    +    @DEFAULT_REDIRECT_HEADERS_BLACKLIST.setter
    +    def DEFAULT_REDIRECT_HEADERS_BLACKLIST(cls, value):
    +        warnings.warn(
    +            "Using 'Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST' is deprecated and "
    +            "will be removed in v2.0. Use 'Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT' instead",
    +            DeprecationWarning,
    +        )
    +        cls.DEFAULT_REMOVE_HEADERS_ON_REDIRECT = value
    +
    +    @property
    +    def BACKOFF_MAX(cls):
    +        warnings.warn(
    +            "Using 'Retry.BACKOFF_MAX' is deprecated and "
    +            "will be removed in v2.0. Use 'Retry.DEFAULT_BACKOFF_MAX' instead",
    +            DeprecationWarning,
    +        )
    +        return cls.DEFAULT_BACKOFF_MAX
    +
    +    @BACKOFF_MAX.setter
    +    def BACKOFF_MAX(cls, value):
    +        warnings.warn(
    +            "Using 'Retry.BACKOFF_MAX' is deprecated and "
    +            "will be removed in v2.0. Use 'Retry.DEFAULT_BACKOFF_MAX' instead",
    +            DeprecationWarning,
    +        )
    +        cls.DEFAULT_BACKOFF_MAX = value
    +
    +
    +@six.add_metaclass(_RetryMeta)
    +class Retry(object):
    +    """Retry configuration.
    +
    +    Each retry attempt will create a new Retry object with updated values, so
    +    they can be safely reused.
    +
    +    Retries can be defined as a default for a pool::
    +
    +        retries = Retry(connect=5, read=2, redirect=5)
    +        http = PoolManager(retries=retries)
    +        response = http.request('GET', 'http://example.com/')
    +
    +    Or per-request (which overrides the default for the pool)::
    +
    +        response = http.request('GET', 'http://example.com/', retries=Retry(10))
    +
    +    Retries can be disabled by passing ``False``::
    +
    +        response = http.request('GET', 'http://example.com/', retries=False)
    +
    +    Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless
    +    retries are disabled, in which case the causing exception will be raised.
    +
    +    :param int total:
    +        Total number of retries to allow. Takes precedence over other counts.
    +
    +        Set to ``None`` to remove this constraint and fall back on other
    +        counts.
    +
    +        Set to ``0`` to fail on the first retry.
    +
    +        Set to ``False`` to disable and imply ``raise_on_redirect=False``.
    +
    +    :param int connect:
    +        How many connection-related errors to retry on.
    +
    +        These are errors raised before the request is sent to the remote server,
    +        which we assume has not triggered the server to process the request.
    +
    +        Set to ``0`` to fail on the first retry of this type.
    +
    +    :param int read:
    +        How many times to retry on read errors.
    +
    +        These errors are raised after the request was sent to the server, so the
    +        request may have side-effects.
    +
    +        Set to ``0`` to fail on the first retry of this type.
    +
    +    :param int redirect:
    +        How many redirects to perform. Limit this to avoid infinite redirect
    +        loops.
    +
    +        A redirect is a HTTP response with a status code 301, 302, 303, 307 or
    +        308.
    +
    +        Set to ``0`` to fail on the first retry of this type.
    +
    +        Set to ``False`` to disable and imply ``raise_on_redirect=False``.
    +
    +    :param int status:
    +        How many times to retry on bad status codes.
    +
    +        These are retries made on responses, where status code matches
    +        ``status_forcelist``.
    +
    +        Set to ``0`` to fail on the first retry of this type.
    +
    +    :param int other:
    +        How many times to retry on other errors.
    +
    +        Other errors are errors that are not connect, read, redirect or status errors.
    +        These errors might be raised after the request was sent to the server, so the
    +        request might have side-effects.
    +
    +        Set to ``0`` to fail on the first retry of this type.
    +
    +        If ``total`` is not set, it's a good idea to set this to 0 to account
    +        for unexpected edge cases and avoid infinite retry loops.
    +
    +    :param iterable allowed_methods:
    +        Set of uppercased HTTP method verbs that we should retry on.
    +
    +        By default, we only retry on methods which are considered to be
    +        idempotent (multiple requests with the same parameters end with the
    +        same state). See :attr:`Retry.DEFAULT_ALLOWED_METHODS`.
    +
    +        Set to a ``False`` value to retry on any verb.
    +
    +        .. warning::
    +
    +            Previously this parameter was named ``method_whitelist``, that
    +            usage is deprecated in v1.26.0 and will be removed in v2.0.
    +
    +    :param iterable status_forcelist:
    +        A set of integer HTTP status codes that we should force a retry on.
    +        A retry is initiated if the request method is in ``allowed_methods``
    +        and the response status code is in ``status_forcelist``.
    +
    +        By default, this is disabled with ``None``.
    +
    +    :param float backoff_factor:
    +        A backoff factor to apply between attempts after the second try
    +        (most errors are resolved immediately by a second try without a
    +        delay). urllib3 will sleep for::
    +
    +            {backoff factor} * (2 ** ({number of total retries} - 1))
    +
    +        seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep
    +        for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer
    +        than :attr:`Retry.DEFAULT_BACKOFF_MAX`.
    +
    +        By default, backoff is disabled (set to 0).
    +
    +    :param bool raise_on_redirect: Whether, if the number of redirects is
    +        exhausted, to raise a MaxRetryError, or to return a response with a
    +        response code in the 3xx range.
    +
    +    :param bool raise_on_status: Similar meaning to ``raise_on_redirect``:
    +        whether we should raise an exception, or return a response,
    +        if status falls in ``status_forcelist`` range and retries have
    +        been exhausted.
    +
    +    :param tuple history: The history of the request encountered during
    +        each call to :meth:`~Retry.increment`. The list is in the order
    +        the requests occurred. Each list item is of class :class:`RequestHistory`.
    +
    +    :param bool respect_retry_after_header:
    +        Whether to respect Retry-After header on status codes defined as
    +        :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not.
    +
    +    :param iterable remove_headers_on_redirect:
    +        Sequence of headers to remove from the request when a response
    +        indicating a redirect is returned before firing off the redirected
    +        request.
    +    """
    +
    +    #: Default methods to be used for ``allowed_methods``
    +    DEFAULT_ALLOWED_METHODS = frozenset(
    +        ["HEAD", "GET", "PUT", "DELETE", "OPTIONS", "TRACE"]
    +    )
    +
    +    #: Default status codes to be used for ``status_forcelist``
    +    RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503])
    +
    +    #: Default headers to be used for ``remove_headers_on_redirect``
    +    DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Authorization"])
    +
    +    #: Maximum backoff time.
    +    DEFAULT_BACKOFF_MAX = 120
    +
    +    def __init__(
    +        self,
    +        total=10,
    +        connect=None,
    +        read=None,
    +        redirect=None,
    +        status=None,
    +        other=None,
    +        allowed_methods=_Default,
    +        status_forcelist=None,
    +        backoff_factor=0,
    +        raise_on_redirect=True,
    +        raise_on_status=True,
    +        history=None,
    +        respect_retry_after_header=True,
    +        remove_headers_on_redirect=_Default,
    +        # TODO: Deprecated, remove in v2.0
    +        method_whitelist=_Default,
    +    ):
    +
    +        if method_whitelist is not _Default:
    +            if allowed_methods is not _Default:
    +                raise ValueError(
    +                    "Using both 'allowed_methods' and "
    +                    "'method_whitelist' together is not allowed. "
    +                    "Instead only use 'allowed_methods'"
    +                )
    +            warnings.warn(
    +                "Using 'method_whitelist' with Retry is deprecated and "
    +                "will be removed in v2.0. Use 'allowed_methods' instead",
    +                DeprecationWarning,
    +                stacklevel=2,
    +            )
    +            allowed_methods = method_whitelist
    +        if allowed_methods is _Default:
    +            allowed_methods = self.DEFAULT_ALLOWED_METHODS
    +        if remove_headers_on_redirect is _Default:
    +            remove_headers_on_redirect = self.DEFAULT_REMOVE_HEADERS_ON_REDIRECT
    +
    +        self.total = total
    +        self.connect = connect
    +        self.read = read
    +        self.status = status
    +        self.other = other
    +
    +        if redirect is False or total is False:
    +            redirect = 0
    +            raise_on_redirect = False
    +
    +        self.redirect = redirect
    +        self.status_forcelist = status_forcelist or set()
    +        self.allowed_methods = allowed_methods
    +        self.backoff_factor = backoff_factor
    +        self.raise_on_redirect = raise_on_redirect
    +        self.raise_on_status = raise_on_status
    +        self.history = history or tuple()
    +        self.respect_retry_after_header = respect_retry_after_header
    +        self.remove_headers_on_redirect = frozenset(
    +            [h.lower() for h in remove_headers_on_redirect]
    +        )
    +
    +    def new(self, **kw):
    +        params = dict(
    +            total=self.total,
    +            connect=self.connect,
    +            read=self.read,
    +            redirect=self.redirect,
    +            status=self.status,
    +            other=self.other,
    +            status_forcelist=self.status_forcelist,
    +            backoff_factor=self.backoff_factor,
    +            raise_on_redirect=self.raise_on_redirect,
    +            raise_on_status=self.raise_on_status,
    +            history=self.history,
    +            remove_headers_on_redirect=self.remove_headers_on_redirect,
    +            respect_retry_after_header=self.respect_retry_after_header,
    +        )
    +
    +        # TODO: If already given in **kw we use what's given to us
    +        # If not given we need to figure out what to pass. We decide
    +        # based on whether our class has the 'method_whitelist' property
    +        # and if so we pass the deprecated 'method_whitelist' otherwise
    +        # we use 'allowed_methods'. Remove in v2.0
    +        if "method_whitelist" not in kw and "allowed_methods" not in kw:
    +            if "method_whitelist" in self.__dict__:
    +                warnings.warn(
    +                    "Using 'method_whitelist' with Retry is deprecated and "
    +                    "will be removed in v2.0. Use 'allowed_methods' instead",
    +                    DeprecationWarning,
    +                )
    +                params["method_whitelist"] = self.allowed_methods
    +            else:
    +                params["allowed_methods"] = self.allowed_methods
    +
    +        params.update(kw)
    +        return type(self)(**params)
    +
    +    @classmethod
    +    def from_int(cls, retries, redirect=True, default=None):
    +        """Backwards-compatibility for the old retries format."""
    +        if retries is None:
    +            retries = default if default is not None else cls.DEFAULT
    +
    +        if isinstance(retries, Retry):
    +            return retries
    +
    +        redirect = bool(redirect) and None
    +        new_retries = cls(retries, redirect=redirect)
    +        log.debug("Converted retries value: %r -> %r", retries, new_retries)
    +        return new_retries
    +
    +    def get_backoff_time(self):
    +        """Formula for computing the current backoff
    +
    +        :rtype: float
    +        """
    +        # We want to consider only the last consecutive errors sequence (Ignore redirects).
    +        consecutive_errors_len = len(
    +            list(
    +                takewhile(lambda x: x.redirect_location is None, reversed(self.history))
    +            )
    +        )
    +        if consecutive_errors_len <= 1:
    +            return 0
    +
    +        backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1))
    +        return min(self.DEFAULT_BACKOFF_MAX, backoff_value)
    +
    +    def parse_retry_after(self, retry_after):
    +        # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4
    +        if re.match(r"^\s*[0-9]+\s*$", retry_after):
    +            seconds = int(retry_after)
    +        else:
    +            retry_date_tuple = email.utils.parsedate_tz(retry_after)
    +            if retry_date_tuple is None:
    +                raise InvalidHeader("Invalid Retry-After header: %s" % retry_after)
    +            if retry_date_tuple[9] is None:  # Python 2
    +                # Assume UTC if no timezone was specified
    +                # On Python2.7, parsedate_tz returns None for a timezone offset
    +                # instead of 0 if no timezone is given, where mktime_tz treats
    +                # a None timezone offset as local time.
    +                retry_date_tuple = retry_date_tuple[:9] + (0,) + retry_date_tuple[10:]
    +
    +            retry_date = email.utils.mktime_tz(retry_date_tuple)
    +            seconds = retry_date - time.time()
    +
    +        if seconds < 0:
    +            seconds = 0
    +
    +        return seconds
    +
    +    def get_retry_after(self, response):
    +        """Get the value of Retry-After in seconds."""
    +
    +        retry_after = response.headers.get("Retry-After")
    +
    +        if retry_after is None:
    +            return None
    +
    +        return self.parse_retry_after(retry_after)
    +
    +    def sleep_for_retry(self, response=None):
    +        retry_after = self.get_retry_after(response)
    +        if retry_after:
    +            time.sleep(retry_after)
    +            return True
    +
    +        return False
    +
    +    def _sleep_backoff(self):
    +        backoff = self.get_backoff_time()
    +        if backoff <= 0:
    +            return
    +        time.sleep(backoff)
    +
    +    def sleep(self, response=None):
    +        """Sleep between retry attempts.
    +
    +        This method will respect a server's ``Retry-After`` response header
    +        and sleep the duration of the time requested. If that is not present, it
    +        will use an exponential backoff. By default, the backoff factor is 0 and
    +        this method will return immediately.
    +        """
    +
    +        if self.respect_retry_after_header and response:
    +            slept = self.sleep_for_retry(response)
    +            if slept:
    +                return
    +
    +        self._sleep_backoff()
    +
    +    def _is_connection_error(self, err):
    +        """Errors when we're fairly sure that the server did not receive the
    +        request, so it should be safe to retry.
    +        """
    +        if isinstance(err, ProxyError):
    +            err = err.original_error
    +        return isinstance(err, ConnectTimeoutError)
    +
    +    def _is_read_error(self, err):
    +        """Errors that occur after the request has been started, so we should
    +        assume that the server began processing it.
    +        """
    +        return isinstance(err, (ReadTimeoutError, ProtocolError))
    +
    +    def _is_method_retryable(self, method):
    +        """Checks if a given HTTP method should be retried upon, depending if
    +        it is included in the allowed_methods
    +        """
    +        # TODO: For now favor if the Retry implementation sets its own method_whitelist
    +        # property outside of our constructor to avoid breaking custom implementations.
    +        if "method_whitelist" in self.__dict__:
    +            warnings.warn(
    +                "Using 'method_whitelist' with Retry is deprecated and "
    +                "will be removed in v2.0. Use 'allowed_methods' instead",
    +                DeprecationWarning,
    +            )
    +            allowed_methods = self.method_whitelist
    +        else:
    +            allowed_methods = self.allowed_methods
    +
    +        if allowed_methods and method.upper() not in allowed_methods:
    +            return False
    +        return True
    +
    +    def is_retry(self, method, status_code, has_retry_after=False):
    +        """Is this method/status code retryable? (Based on allowlists and control
    +        variables such as the number of total retries to allow, whether to
    +        respect the Retry-After header, whether this header is present, and
    +        whether the returned status code is on the list of status codes to
    +        be retried upon on the presence of the aforementioned header)
    +        """
    +        if not self._is_method_retryable(method):
    +            return False
    +
    +        if self.status_forcelist and status_code in self.status_forcelist:
    +            return True
    +
    +        return (
    +            self.total
    +            and self.respect_retry_after_header
    +            and has_retry_after
    +            and (status_code in self.RETRY_AFTER_STATUS_CODES)
    +        )
    +
    +    def is_exhausted(self):
    +        """Are we out of retries?"""
    +        retry_counts = (
    +            self.total,
    +            self.connect,
    +            self.read,
    +            self.redirect,
    +            self.status,
    +            self.other,
    +        )
    +        retry_counts = list(filter(None, retry_counts))
    +        if not retry_counts:
    +            return False
    +
    +        return min(retry_counts) < 0
    +
    +    def increment(
    +        self,
    +        method=None,
    +        url=None,
    +        response=None,
    +        error=None,
    +        _pool=None,
    +        _stacktrace=None,
    +    ):
    +        """Return a new Retry object with incremented retry counters.
    +
    +        :param response: A response object, or None, if the server did not
    +            return a response.
    +        :type response: :class:`~urllib3.response.HTTPResponse`
    +        :param Exception error: An error encountered during the request, or
    +            None if the response was received successfully.
    +
    +        :return: A new ``Retry`` object.
    +        """
    +        if self.total is False and error:
    +            # Disabled, indicate to re-raise the error.
    +            raise six.reraise(type(error), error, _stacktrace)
    +
    +        total = self.total
    +        if total is not None:
    +            total -= 1
    +
    +        connect = self.connect
    +        read = self.read
    +        redirect = self.redirect
    +        status_count = self.status
    +        other = self.other
    +        cause = "unknown"
    +        status = None
    +        redirect_location = None
    +
    +        if error and self._is_connection_error(error):
    +            # Connect retry?
    +            if connect is False:
    +                raise six.reraise(type(error), error, _stacktrace)
    +            elif connect is not None:
    +                connect -= 1
    +
    +        elif error and self._is_read_error(error):
    +            # Read retry?
    +            if read is False or not self._is_method_retryable(method):
    +                raise six.reraise(type(error), error, _stacktrace)
    +            elif read is not None:
    +                read -= 1
    +
    +        elif error:
    +            # Other retry?
    +            if other is not None:
    +                other -= 1
    +
    +        elif response and response.get_redirect_location():
    +            # Redirect retry?
    +            if redirect is not None:
    +                redirect -= 1
    +            cause = "too many redirects"
    +            redirect_location = response.get_redirect_location()
    +            status = response.status
    +
    +        else:
    +            # Incrementing because of a server error like a 500 in
    +            # status_forcelist and the given method is in the allowed_methods
    +            cause = ResponseError.GENERIC_ERROR
    +            if response and response.status:
    +                if status_count is not None:
    +                    status_count -= 1
    +                cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status)
    +                status = response.status
    +
    +        history = self.history + (
    +            RequestHistory(method, url, error, status, redirect_location),
    +        )
    +
    +        new_retry = self.new(
    +            total=total,
    +            connect=connect,
    +            read=read,
    +            redirect=redirect,
    +            status=status_count,
    +            other=other,
    +            history=history,
    +        )
    +
    +        if new_retry.is_exhausted():
    +            raise MaxRetryError(_pool, url, error or ResponseError(cause))
    +
    +        log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)
    +
    +        return new_retry
    +
    +    def __repr__(self):
    +        return (
    +            "{cls.__name__}(total={self.total}, connect={self.connect}, "
    +            "read={self.read}, redirect={self.redirect}, status={self.status})"
    +        ).format(cls=type(self), self=self)
    +
    +    def __getattr__(self, item):
    +        if item == "method_whitelist":
    +            # TODO: Remove this deprecated alias in v2.0
    +            warnings.warn(
    +                "Using 'method_whitelist' with Retry is deprecated and "
    +                "will be removed in v2.0. Use 'allowed_methods' instead",
    +                DeprecationWarning,
    +            )
    +            return self.allowed_methods
    +        try:
    +            return getattr(super(Retry, self), item)
    +        except AttributeError:
    +            return getattr(Retry, item)
    +
    +
    +# For backwards compatibility (equivalent to pre-v1.9):
    +Retry.DEFAULT = Retry(3)
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/ssl_.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/ssl_.py
    new file mode 100644
    index 0000000..8f86781
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/ssl_.py
    @@ -0,0 +1,495 @@
    +from __future__ import absolute_import
    +
    +import hmac
    +import os
    +import sys
    +import warnings
    +from binascii import hexlify, unhexlify
    +from hashlib import md5, sha1, sha256
    +
    +from ..exceptions import (
    +    InsecurePlatformWarning,
    +    ProxySchemeUnsupported,
    +    SNIMissingWarning,
    +    SSLError,
    +)
    +from ..packages import six
    +from .url import BRACELESS_IPV6_ADDRZ_RE, IPV4_RE
    +
    +SSLContext = None
    +SSLTransport = None
    +HAS_SNI = False
    +IS_PYOPENSSL = False
    +IS_SECURETRANSPORT = False
    +ALPN_PROTOCOLS = ["http/1.1"]
    +
    +# Maps the length of a digest to a possible hash function producing this digest
    +HASHFUNC_MAP = {32: md5, 40: sha1, 64: sha256}
    +
    +
    +def _const_compare_digest_backport(a, b):
    +    """
    +    Compare two digests of equal length in constant time.
    +
    +    The digests must be of type str/bytes.
    +    Returns True if the digests match, and False otherwise.
    +    """
    +    result = abs(len(a) - len(b))
    +    for left, right in zip(bytearray(a), bytearray(b)):
    +        result |= left ^ right
    +    return result == 0
    +
    +
    +_const_compare_digest = getattr(hmac, "compare_digest", _const_compare_digest_backport)
    +
    +try:  # Test for SSL features
    +    import ssl
    +    from ssl import CERT_REQUIRED, wrap_socket
    +except ImportError:
    +    pass
    +
    +try:
    +    from ssl import HAS_SNI  # Has SNI?
    +except ImportError:
    +    pass
    +
    +try:
    +    from .ssltransport import SSLTransport
    +except ImportError:
    +    pass
    +
    +
    +try:  # Platform-specific: Python 3.6
    +    from ssl import PROTOCOL_TLS
    +
    +    PROTOCOL_SSLv23 = PROTOCOL_TLS
    +except ImportError:
    +    try:
    +        from ssl import PROTOCOL_SSLv23 as PROTOCOL_TLS
    +
    +        PROTOCOL_SSLv23 = PROTOCOL_TLS
    +    except ImportError:
    +        PROTOCOL_SSLv23 = PROTOCOL_TLS = 2
    +
    +try:
    +    from ssl import PROTOCOL_TLS_CLIENT
    +except ImportError:
    +    PROTOCOL_TLS_CLIENT = PROTOCOL_TLS
    +
    +
    +try:
    +    from ssl import OP_NO_COMPRESSION, OP_NO_SSLv2, OP_NO_SSLv3
    +except ImportError:
    +    OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000
    +    OP_NO_COMPRESSION = 0x20000
    +
    +
    +try:  # OP_NO_TICKET was added in Python 3.6
    +    from ssl import OP_NO_TICKET
    +except ImportError:
    +    OP_NO_TICKET = 0x4000
    +
    +
    +# A secure default.
    +# Sources for more information on TLS ciphers:
    +#
    +# - https://wiki.mozilla.org/Security/Server_Side_TLS
    +# - https://www.ssllabs.com/projects/best-practices/index.html
    +# - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    +#
    +# The general intent is:
    +# - prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE),
    +# - prefer ECDHE over DHE for better performance,
    +# - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and
    +#   security,
    +# - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common,
    +# - disable NULL authentication, MD5 MACs, DSS, and other
    +#   insecure ciphers for security reasons.
    +# - NOTE: TLS 1.3 cipher suites are managed through a different interface
    +#   not exposed by CPython (yet!) and are enabled by default if they're available.
    +DEFAULT_CIPHERS = ":".join(
    +    [
    +        "ECDHE+AESGCM",
    +        "ECDHE+CHACHA20",
    +        "DHE+AESGCM",
    +        "DHE+CHACHA20",
    +        "ECDH+AESGCM",
    +        "DH+AESGCM",
    +        "ECDH+AES",
    +        "DH+AES",
    +        "RSA+AESGCM",
    +        "RSA+AES",
    +        "!aNULL",
    +        "!eNULL",
    +        "!MD5",
    +        "!DSS",
    +    ]
    +)
    +
    +try:
    +    from ssl import SSLContext  # Modern SSL?
    +except ImportError:
    +
    +    class SSLContext(object):  # Platform-specific: Python 2
    +        def __init__(self, protocol_version):
    +            self.protocol = protocol_version
    +            # Use default values from a real SSLContext
    +            self.check_hostname = False
    +            self.verify_mode = ssl.CERT_NONE
    +            self.ca_certs = None
    +            self.options = 0
    +            self.certfile = None
    +            self.keyfile = None
    +            self.ciphers = None
    +
    +        def load_cert_chain(self, certfile, keyfile):
    +            self.certfile = certfile
    +            self.keyfile = keyfile
    +
    +        def load_verify_locations(self, cafile=None, capath=None, cadata=None):
    +            self.ca_certs = cafile
    +
    +            if capath is not None:
    +                raise SSLError("CA directories not supported in older Pythons")
    +
    +            if cadata is not None:
    +                raise SSLError("CA data not supported in older Pythons")
    +
    +        def set_ciphers(self, cipher_suite):
    +            self.ciphers = cipher_suite
    +
    +        def wrap_socket(self, socket, server_hostname=None, server_side=False):
    +            warnings.warn(
    +                "A true SSLContext object is not available. This prevents "
    +                "urllib3 from configuring SSL appropriately and may cause "
    +                "certain SSL connections to fail. You can upgrade to a newer "
    +                "version of Python to solve this. For more information, see "
    +                "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html"
    +                "#ssl-warnings",
    +                InsecurePlatformWarning,
    +            )
    +            kwargs = {
    +                "keyfile": self.keyfile,
    +                "certfile": self.certfile,
    +                "ca_certs": self.ca_certs,
    +                "cert_reqs": self.verify_mode,
    +                "ssl_version": self.protocol,
    +                "server_side": server_side,
    +            }
    +            return wrap_socket(socket, ciphers=self.ciphers, **kwargs)
    +
    +
    +def assert_fingerprint(cert, fingerprint):
    +    """
    +    Checks if given fingerprint matches the supplied certificate.
    +
    +    :param cert:
    +        Certificate as bytes object.
    +    :param fingerprint:
    +        Fingerprint as string of hexdigits, can be interspersed by colons.
    +    """
    +
    +    fingerprint = fingerprint.replace(":", "").lower()
    +    digest_length = len(fingerprint)
    +    hashfunc = HASHFUNC_MAP.get(digest_length)
    +    if not hashfunc:
    +        raise SSLError("Fingerprint of invalid length: {0}".format(fingerprint))
    +
    +    # We need encode() here for py32; works on py2 and p33.
    +    fingerprint_bytes = unhexlify(fingerprint.encode())
    +
    +    cert_digest = hashfunc(cert).digest()
    +
    +    if not _const_compare_digest(cert_digest, fingerprint_bytes):
    +        raise SSLError(
    +            'Fingerprints did not match. Expected "{0}", got "{1}".'.format(
    +                fingerprint, hexlify(cert_digest)
    +            )
    +        )
    +
    +
    +def resolve_cert_reqs(candidate):
    +    """
    +    Resolves the argument to a numeric constant, which can be passed to
    +    the wrap_socket function/method from the ssl module.
    +    Defaults to :data:`ssl.CERT_REQUIRED`.
    +    If given a string it is assumed to be the name of the constant in the
    +    :mod:`ssl` module or its abbreviation.
    +    (So you can specify `REQUIRED` instead of `CERT_REQUIRED`.
    +    If it's neither `None` nor a string we assume it is already the numeric
    +    constant which can directly be passed to wrap_socket.
    +    """
    +    if candidate is None:
    +        return CERT_REQUIRED
    +
    +    if isinstance(candidate, str):
    +        res = getattr(ssl, candidate, None)
    +        if res is None:
    +            res = getattr(ssl, "CERT_" + candidate)
    +        return res
    +
    +    return candidate
    +
    +
    +def resolve_ssl_version(candidate):
    +    """
    +    like resolve_cert_reqs
    +    """
    +    if candidate is None:
    +        return PROTOCOL_TLS
    +
    +    if isinstance(candidate, str):
    +        res = getattr(ssl, candidate, None)
    +        if res is None:
    +            res = getattr(ssl, "PROTOCOL_" + candidate)
    +        return res
    +
    +    return candidate
    +
    +
    +def create_urllib3_context(
    +    ssl_version=None, cert_reqs=None, options=None, ciphers=None
    +):
    +    """All arguments have the same meaning as ``ssl_wrap_socket``.
    +
    +    By default, this function does a lot of the same work that
    +    ``ssl.create_default_context`` does on Python 3.4+. It:
    +
    +    - Disables SSLv2, SSLv3, and compression
    +    - Sets a restricted set of server ciphers
    +
    +    If you wish to enable SSLv3, you can do::
    +
    +        from urllib3.util import ssl_
    +        context = ssl_.create_urllib3_context()
    +        context.options &= ~ssl_.OP_NO_SSLv3
    +
    +    You can do the same to enable compression (substituting ``COMPRESSION``
    +    for ``SSLv3`` in the last line above).
    +
    +    :param ssl_version:
    +        The desired protocol version to use. This will default to
    +        PROTOCOL_SSLv23 which will negotiate the highest protocol that both
    +        the server and your installation of OpenSSL support.
    +    :param cert_reqs:
    +        Whether to require the certificate verification. This defaults to
    +        ``ssl.CERT_REQUIRED``.
    +    :param options:
    +        Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
    +        ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``, and ``ssl.OP_NO_TICKET``.
    +    :param ciphers:
    +        Which cipher suites to allow the server to select.
    +    :returns:
    +        Constructed SSLContext object with specified options
    +    :rtype: SSLContext
    +    """
    +    # PROTOCOL_TLS is deprecated in Python 3.10
    +    if not ssl_version or ssl_version == PROTOCOL_TLS:
    +        ssl_version = PROTOCOL_TLS_CLIENT
    +
    +    context = SSLContext(ssl_version)
    +
    +    context.set_ciphers(ciphers or DEFAULT_CIPHERS)
    +
    +    # Setting the default here, as we may have no ssl module on import
    +    cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs
    +
    +    if options is None:
    +        options = 0
    +        # SSLv2 is easily broken and is considered harmful and dangerous
    +        options |= OP_NO_SSLv2
    +        # SSLv3 has several problems and is now dangerous
    +        options |= OP_NO_SSLv3
    +        # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
    +        # (issue #309)
    +        options |= OP_NO_COMPRESSION
    +        # TLSv1.2 only. Unless set explicitly, do not request tickets.
    +        # This may save some bandwidth on wire, and although the ticket is encrypted,
    +        # there is a risk associated with it being on wire,
    +        # if the server is not rotating its ticketing keys properly.
    +        options |= OP_NO_TICKET
    +
    +    context.options |= options
    +
    +    # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is
    +    # necessary for conditional client cert authentication with TLS 1.3.
    +    # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older
    +    # versions of Python.  We only enable on Python 3.7.4+ or if certificate
    +    # verification is enabled to work around Python issue #37428
    +    # See: https://bugs.python.org/issue37428
    +    if (cert_reqs == ssl.CERT_REQUIRED or sys.version_info >= (3, 7, 4)) and getattr(
    +        context, "post_handshake_auth", None
    +    ) is not None:
    +        context.post_handshake_auth = True
    +
    +    def disable_check_hostname():
    +        if (
    +            getattr(context, "check_hostname", None) is not None
    +        ):  # Platform-specific: Python 3.2
    +            # We do our own verification, including fingerprints and alternative
    +            # hostnames. So disable it here
    +            context.check_hostname = False
    +
    +    # The order of the below lines setting verify_mode and check_hostname
    +    # matter due to safe-guards SSLContext has to prevent an SSLContext with
    +    # check_hostname=True, verify_mode=NONE/OPTIONAL. This is made even more
    +    # complex because we don't know whether PROTOCOL_TLS_CLIENT will be used
    +    # or not so we don't know the initial state of the freshly created SSLContext.
    +    if cert_reqs == ssl.CERT_REQUIRED:
    +        context.verify_mode = cert_reqs
    +        disable_check_hostname()
    +    else:
    +        disable_check_hostname()
    +        context.verify_mode = cert_reqs
    +
    +    # Enable logging of TLS session keys via defacto standard environment variable
    +    # 'SSLKEYLOGFILE', if the feature is available (Python 3.8+). Skip empty values.
    +    if hasattr(context, "keylog_filename"):
    +        sslkeylogfile = os.environ.get("SSLKEYLOGFILE")
    +        if sslkeylogfile:
    +            context.keylog_filename = sslkeylogfile
    +
    +    return context
    +
    +
    +def ssl_wrap_socket(
    +    sock,
    +    keyfile=None,
    +    certfile=None,
    +    cert_reqs=None,
    +    ca_certs=None,
    +    server_hostname=None,
    +    ssl_version=None,
    +    ciphers=None,
    +    ssl_context=None,
    +    ca_cert_dir=None,
    +    key_password=None,
    +    ca_cert_data=None,
    +    tls_in_tls=False,
    +):
    +    """
    +    All arguments except for server_hostname, ssl_context, and ca_cert_dir have
    +    the same meaning as they do when using :func:`ssl.wrap_socket`.
    +
    +    :param server_hostname:
    +        When SNI is supported, the expected hostname of the certificate
    +    :param ssl_context:
    +        A pre-made :class:`SSLContext` object. If none is provided, one will
    +        be created using :func:`create_urllib3_context`.
    +    :param ciphers:
    +        A string of ciphers we wish the client to support.
    +    :param ca_cert_dir:
    +        A directory containing CA certificates in multiple separate files, as
    +        supported by OpenSSL's -CApath flag or the capath argument to
    +        SSLContext.load_verify_locations().
    +    :param key_password:
    +        Optional password if the keyfile is encrypted.
    +    :param ca_cert_data:
    +        Optional string containing CA certificates in PEM format suitable for
    +        passing as the cadata parameter to SSLContext.load_verify_locations()
    +    :param tls_in_tls:
    +        Use SSLTransport to wrap the existing socket.
    +    """
    +    context = ssl_context
    +    if context is None:
    +        # Note: This branch of code and all the variables in it are no longer
    +        # used by urllib3 itself. We should consider deprecating and removing
    +        # this code.
    +        context = create_urllib3_context(ssl_version, cert_reqs, ciphers=ciphers)
    +
    +    if ca_certs or ca_cert_dir or ca_cert_data:
    +        try:
    +            context.load_verify_locations(ca_certs, ca_cert_dir, ca_cert_data)
    +        except (IOError, OSError) as e:
    +            raise SSLError(e)
    +
    +    elif ssl_context is None and hasattr(context, "load_default_certs"):
    +        # try to load OS default certs; works well on Windows (require Python3.4+)
    +        context.load_default_certs()
    +
    +    # Attempt to detect if we get the goofy behavior of the
    +    # keyfile being encrypted and OpenSSL asking for the
    +    # passphrase via the terminal and instead error out.
    +    if keyfile and key_password is None and _is_key_file_encrypted(keyfile):
    +        raise SSLError("Client private key is encrypted, password is required")
    +
    +    if certfile:
    +        if key_password is None:
    +            context.load_cert_chain(certfile, keyfile)
    +        else:
    +            context.load_cert_chain(certfile, keyfile, key_password)
    +
    +    try:
    +        if hasattr(context, "set_alpn_protocols"):
    +            context.set_alpn_protocols(ALPN_PROTOCOLS)
    +    except NotImplementedError:  # Defensive: in CI, we always have set_alpn_protocols
    +        pass
    +
    +    # If we detect server_hostname is an IP address then the SNI
    +    # extension should not be used according to RFC3546 Section 3.1
    +    use_sni_hostname = server_hostname and not is_ipaddress(server_hostname)
    +    # SecureTransport uses server_hostname in certificate verification.
    +    send_sni = (use_sni_hostname and HAS_SNI) or (
    +        IS_SECURETRANSPORT and server_hostname
    +    )
    +    # Do not warn the user if server_hostname is an invalid SNI hostname.
    +    if not HAS_SNI and use_sni_hostname:
    +        warnings.warn(
    +            "An HTTPS request has been made, but the SNI (Server Name "
    +            "Indication) extension to TLS is not available on this platform. "
    +            "This may cause the server to present an incorrect TLS "
    +            "certificate, which can cause validation failures. You can upgrade to "
    +            "a newer version of Python to solve this. For more information, see "
    +            "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html"
    +            "#ssl-warnings",
    +            SNIMissingWarning,
    +        )
    +
    +    if send_sni:
    +        ssl_sock = _ssl_wrap_socket_impl(
    +            sock, context, tls_in_tls, server_hostname=server_hostname
    +        )
    +    else:
    +        ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls)
    +    return ssl_sock
    +
    +
    +def is_ipaddress(hostname):
    +    """Detects whether the hostname given is an IPv4 or IPv6 address.
    +    Also detects IPv6 addresses with Zone IDs.
    +
    +    :param str hostname: Hostname to examine.
    +    :return: True if the hostname is an IP address, False otherwise.
    +    """
    +    if not six.PY2 and isinstance(hostname, bytes):
    +        # IDN A-label bytes are ASCII compatible.
    +        hostname = hostname.decode("ascii")
    +    return bool(IPV4_RE.match(hostname) or BRACELESS_IPV6_ADDRZ_RE.match(hostname))
    +
    +
    +def _is_key_file_encrypted(key_file):
    +    """Detects if a key file is encrypted or not."""
    +    with open(key_file, "r") as f:
    +        for line in f:
    +            # Look for Proc-Type: 4,ENCRYPTED
    +            if "ENCRYPTED" in line:
    +                return True
    +
    +    return False
    +
    +
    +def _ssl_wrap_socket_impl(sock, ssl_context, tls_in_tls, server_hostname=None):
    +    if tls_in_tls:
    +        if not SSLTransport:
    +            # Import error, ssl is not available.
    +            raise ProxySchemeUnsupported(
    +                "TLS in TLS requires support for the 'ssl' module"
    +            )
    +
    +        SSLTransport._validate_ssl_context_for_tls_in_tls(ssl_context)
    +        return SSLTransport(sock, ssl_context, server_hostname)
    +
    +    if server_hostname:
    +        return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
    +    else:
    +        return ssl_context.wrap_socket(sock)
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/ssl_match_hostname.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/ssl_match_hostname.py
    new file mode 100644
    index 0000000..1dd950c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/ssl_match_hostname.py
    @@ -0,0 +1,159 @@
    +"""The match_hostname() function from Python 3.3.3, essential when using SSL."""
    +
    +# Note: This file is under the PSF license as the code comes from the python
    +# stdlib.   http://docs.python.org/3/license.html
    +
    +import re
    +import sys
    +
    +# ipaddress has been backported to 2.6+ in pypi.  If it is installed on the
    +# system, use it to handle IPAddress ServerAltnames (this was added in
    +# python-3.5) otherwise only do DNS matching.  This allows
    +# util.ssl_match_hostname to continue to be used in Python 2.7.
    +try:
    +    import ipaddress
    +except ImportError:
    +    ipaddress = None
    +
    +__version__ = "3.5.0.1"
    +
    +
    +class CertificateError(ValueError):
    +    pass
    +
    +
    +def _dnsname_match(dn, hostname, max_wildcards=1):
    +    """Matching according to RFC 6125, section 6.4.3
    +
    +    http://tools.ietf.org/html/rfc6125#section-6.4.3
    +    """
    +    pats = []
    +    if not dn:
    +        return False
    +
    +    # Ported from python3-syntax:
    +    # leftmost, *remainder = dn.split(r'.')
    +    parts = dn.split(r".")
    +    leftmost = parts[0]
    +    remainder = parts[1:]
    +
    +    wildcards = leftmost.count("*")
    +    if wildcards > max_wildcards:
    +        # Issue #17980: avoid denials of service by refusing more
    +        # than one wildcard per fragment.  A survey of established
    +        # policy among SSL implementations showed it to be a
    +        # reasonable choice.
    +        raise CertificateError(
    +            "too many wildcards in certificate DNS name: " + repr(dn)
    +        )
    +
    +    # speed up common case w/o wildcards
    +    if not wildcards:
    +        return dn.lower() == hostname.lower()
    +
    +    # RFC 6125, section 6.4.3, subitem 1.
    +    # The client SHOULD NOT attempt to match a presented identifier in which
    +    # the wildcard character comprises a label other than the left-most label.
    +    if leftmost == "*":
    +        # When '*' is a fragment by itself, it matches a non-empty dotless
    +        # fragment.
    +        pats.append("[^.]+")
    +    elif leftmost.startswith("xn--") or hostname.startswith("xn--"):
    +        # RFC 6125, section 6.4.3, subitem 3.
    +        # The client SHOULD NOT attempt to match a presented identifier
    +        # where the wildcard character is embedded within an A-label or
    +        # U-label of an internationalized domain name.
    +        pats.append(re.escape(leftmost))
    +    else:
    +        # Otherwise, '*' matches any dotless string, e.g. www*
    +        pats.append(re.escape(leftmost).replace(r"\*", "[^.]*"))
    +
    +    # add the remaining fragments, ignore any wildcards
    +    for frag in remainder:
    +        pats.append(re.escape(frag))
    +
    +    pat = re.compile(r"\A" + r"\.".join(pats) + r"\Z", re.IGNORECASE)
    +    return pat.match(hostname)
    +
    +
    +def _to_unicode(obj):
    +    if isinstance(obj, str) and sys.version_info < (3,):
    +        # ignored flake8 # F821 to support python 2.7 function
    +        obj = unicode(obj, encoding="ascii", errors="strict")  # noqa: F821
    +    return obj
    +
    +
    +def _ipaddress_match(ipname, host_ip):
    +    """Exact matching of IP addresses.
    +
    +    RFC 6125 explicitly doesn't define an algorithm for this
    +    (section 1.7.2 - "Out of Scope").
    +    """
    +    # OpenSSL may add a trailing newline to a subjectAltName's IP address
    +    # Divergence from upstream: ipaddress can't handle byte str
    +    ip = ipaddress.ip_address(_to_unicode(ipname).rstrip())
    +    return ip == host_ip
    +
    +
    +def match_hostname(cert, hostname):
    +    """Verify that *cert* (in decoded format as returned by
    +    SSLSocket.getpeercert()) matches the *hostname*.  RFC 2818 and RFC 6125
    +    rules are followed, but IP addresses are not accepted for *hostname*.
    +
    +    CertificateError is raised on failure. On success, the function
    +    returns nothing.
    +    """
    +    if not cert:
    +        raise ValueError(
    +            "empty or no certificate, match_hostname needs a "
    +            "SSL socket or SSL context with either "
    +            "CERT_OPTIONAL or CERT_REQUIRED"
    +        )
    +    try:
    +        # Divergence from upstream: ipaddress can't handle byte str
    +        host_ip = ipaddress.ip_address(_to_unicode(hostname))
    +    except (UnicodeError, ValueError):
    +        # ValueError: Not an IP address (common case)
    +        # UnicodeError: Divergence from upstream: Have to deal with ipaddress not taking
    +        # byte strings.  addresses should be all ascii, so we consider it not
    +        # an ipaddress in this case
    +        host_ip = None
    +    except AttributeError:
    +        # Divergence from upstream: Make ipaddress library optional
    +        if ipaddress is None:
    +            host_ip = None
    +        else:  # Defensive
    +            raise
    +    dnsnames = []
    +    san = cert.get("subjectAltName", ())
    +    for key, value in san:
    +        if key == "DNS":
    +            if host_ip is None and _dnsname_match(value, hostname):
    +                return
    +            dnsnames.append(value)
    +        elif key == "IP Address":
    +            if host_ip is not None and _ipaddress_match(value, host_ip):
    +                return
    +            dnsnames.append(value)
    +    if not dnsnames:
    +        # The subject is only checked when there is no dNSName entry
    +        # in subjectAltName
    +        for sub in cert.get("subject", ()):
    +            for key, value in sub:
    +                # XXX according to RFC 2818, the most specific Common Name
    +                # must be used.
    +                if key == "commonName":
    +                    if _dnsname_match(value, hostname):
    +                        return
    +                    dnsnames.append(value)
    +    if len(dnsnames) > 1:
    +        raise CertificateError(
    +            "hostname %r "
    +            "doesn't match either of %s" % (hostname, ", ".join(map(repr, dnsnames)))
    +        )
    +    elif len(dnsnames) == 1:
    +        raise CertificateError("hostname %r doesn't match %r" % (hostname, dnsnames[0]))
    +    else:
    +        raise CertificateError(
    +            "no appropriate commonName or subjectAltName fields were found"
    +        )
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/ssltransport.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/ssltransport.py
    new file mode 100644
    index 0000000..4a7105d
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/ssltransport.py
    @@ -0,0 +1,221 @@
    +import io
    +import socket
    +import ssl
    +
    +from ..exceptions import ProxySchemeUnsupported
    +from ..packages import six
    +
    +SSL_BLOCKSIZE = 16384
    +
    +
    +class SSLTransport:
    +    """
    +    The SSLTransport wraps an existing socket and establishes an SSL connection.
    +
    +    Contrary to Python's implementation of SSLSocket, it allows you to chain
    +    multiple TLS connections together. It's particularly useful if you need to
    +    implement TLS within TLS.
    +
    +    The class supports most of the socket API operations.
    +    """
    +
    +    @staticmethod
    +    def _validate_ssl_context_for_tls_in_tls(ssl_context):
    +        """
    +        Raises a ProxySchemeUnsupported if the provided ssl_context can't be used
    +        for TLS in TLS.
    +
    +        The only requirement is that the ssl_context provides the 'wrap_bio'
    +        methods.
    +        """
    +
    +        if not hasattr(ssl_context, "wrap_bio"):
    +            if six.PY2:
    +                raise ProxySchemeUnsupported(
    +                    "TLS in TLS requires SSLContext.wrap_bio() which isn't "
    +                    "supported on Python 2"
    +                )
    +            else:
    +                raise ProxySchemeUnsupported(
    +                    "TLS in TLS requires SSLContext.wrap_bio() which isn't "
    +                    "available on non-native SSLContext"
    +                )
    +
    +    def __init__(
    +        self, socket, ssl_context, server_hostname=None, suppress_ragged_eofs=True
    +    ):
    +        """
    +        Create an SSLTransport around socket using the provided ssl_context.
    +        """
    +        self.incoming = ssl.MemoryBIO()
    +        self.outgoing = ssl.MemoryBIO()
    +
    +        self.suppress_ragged_eofs = suppress_ragged_eofs
    +        self.socket = socket
    +
    +        self.sslobj = ssl_context.wrap_bio(
    +            self.incoming, self.outgoing, server_hostname=server_hostname
    +        )
    +
    +        # Perform initial handshake.
    +        self._ssl_io_loop(self.sslobj.do_handshake)
    +
    +    def __enter__(self):
    +        return self
    +
    +    def __exit__(self, *_):
    +        self.close()
    +
    +    def fileno(self):
    +        return self.socket.fileno()
    +
    +    def read(self, len=1024, buffer=None):
    +        return self._wrap_ssl_read(len, buffer)
    +
    +    def recv(self, len=1024, flags=0):
    +        if flags != 0:
    +            raise ValueError("non-zero flags not allowed in calls to recv")
    +        return self._wrap_ssl_read(len)
    +
    +    def recv_into(self, buffer, nbytes=None, flags=0):
    +        if flags != 0:
    +            raise ValueError("non-zero flags not allowed in calls to recv_into")
    +        if buffer and (nbytes is None):
    +            nbytes = len(buffer)
    +        elif nbytes is None:
    +            nbytes = 1024
    +        return self.read(nbytes, buffer)
    +
    +    def sendall(self, data, flags=0):
    +        if flags != 0:
    +            raise ValueError("non-zero flags not allowed in calls to sendall")
    +        count = 0
    +        with memoryview(data) as view, view.cast("B") as byte_view:
    +            amount = len(byte_view)
    +            while count < amount:
    +                v = self.send(byte_view[count:])
    +                count += v
    +
    +    def send(self, data, flags=0):
    +        if flags != 0:
    +            raise ValueError("non-zero flags not allowed in calls to send")
    +        response = self._ssl_io_loop(self.sslobj.write, data)
    +        return response
    +
    +    def makefile(
    +        self, mode="r", buffering=None, encoding=None, errors=None, newline=None
    +    ):
    +        """
    +        Python's httpclient uses makefile and buffered io when reading HTTP
    +        messages and we need to support it.
    +
    +        This is unfortunately a copy and paste of socket.py makefile with small
    +        changes to point to the socket directly.
    +        """
    +        if not set(mode) <= {"r", "w", "b"}:
    +            raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,))
    +
    +        writing = "w" in mode
    +        reading = "r" in mode or not writing
    +        assert reading or writing
    +        binary = "b" in mode
    +        rawmode = ""
    +        if reading:
    +            rawmode += "r"
    +        if writing:
    +            rawmode += "w"
    +        raw = socket.SocketIO(self, rawmode)
    +        self.socket._io_refs += 1
    +        if buffering is None:
    +            buffering = -1
    +        if buffering < 0:
    +            buffering = io.DEFAULT_BUFFER_SIZE
    +        if buffering == 0:
    +            if not binary:
    +                raise ValueError("unbuffered streams must be binary")
    +            return raw
    +        if reading and writing:
    +            buffer = io.BufferedRWPair(raw, raw, buffering)
    +        elif reading:
    +            buffer = io.BufferedReader(raw, buffering)
    +        else:
    +            assert writing
    +            buffer = io.BufferedWriter(raw, buffering)
    +        if binary:
    +            return buffer
    +        text = io.TextIOWrapper(buffer, encoding, errors, newline)
    +        text.mode = mode
    +        return text
    +
    +    def unwrap(self):
    +        self._ssl_io_loop(self.sslobj.unwrap)
    +
    +    def close(self):
    +        self.socket.close()
    +
    +    def getpeercert(self, binary_form=False):
    +        return self.sslobj.getpeercert(binary_form)
    +
    +    def version(self):
    +        return self.sslobj.version()
    +
    +    def cipher(self):
    +        return self.sslobj.cipher()
    +
    +    def selected_alpn_protocol(self):
    +        return self.sslobj.selected_alpn_protocol()
    +
    +    def selected_npn_protocol(self):
    +        return self.sslobj.selected_npn_protocol()
    +
    +    def shared_ciphers(self):
    +        return self.sslobj.shared_ciphers()
    +
    +    def compression(self):
    +        return self.sslobj.compression()
    +
    +    def settimeout(self, value):
    +        self.socket.settimeout(value)
    +
    +    def gettimeout(self):
    +        return self.socket.gettimeout()
    +
    +    def _decref_socketios(self):
    +        self.socket._decref_socketios()
    +
    +    def _wrap_ssl_read(self, len, buffer=None):
    +        try:
    +            return self._ssl_io_loop(self.sslobj.read, len, buffer)
    +        except ssl.SSLError as e:
    +            if e.errno == ssl.SSL_ERROR_EOF and self.suppress_ragged_eofs:
    +                return 0  # eof, return 0.
    +            else:
    +                raise
    +
    +    def _ssl_io_loop(self, func, *args):
    +        """Performs an I/O loop between incoming/outgoing and the socket."""
    +        should_loop = True
    +        ret = None
    +
    +        while should_loop:
    +            errno = None
    +            try:
    +                ret = func(*args)
    +            except ssl.SSLError as e:
    +                if e.errno not in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE):
    +                    # WANT_READ, and WANT_WRITE are expected, others are not.
    +                    raise e
    +                errno = e.errno
    +
    +            buf = self.outgoing.read()
    +            self.socket.sendall(buf)
    +
    +            if errno is None:
    +                should_loop = False
    +            elif errno == ssl.SSL_ERROR_WANT_READ:
    +                buf = self.socket.recv(SSL_BLOCKSIZE)
    +                if buf:
    +                    self.incoming.write(buf)
    +                else:
    +                    self.incoming.write_eof()
    +        return ret
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/timeout.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/timeout.py
    new file mode 100644
    index 0000000..ff69593
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/timeout.py
    @@ -0,0 +1,268 @@
    +from __future__ import absolute_import
    +
    +import time
    +
    +# The default socket timeout, used by httplib to indicate that no timeout was
    +# specified by the user
    +from socket import _GLOBAL_DEFAULT_TIMEOUT
    +
    +from ..exceptions import TimeoutStateError
    +
    +# A sentinel value to indicate that no timeout was specified by the user in
    +# urllib3
    +_Default = object()
    +
    +
    +# Use time.monotonic if available.
    +current_time = getattr(time, "monotonic", time.time)
    +
    +
    +class Timeout(object):
    +    """Timeout configuration.
    +
    +    Timeouts can be defined as a default for a pool:
    +
    +    .. code-block:: python
    +
    +       timeout = Timeout(connect=2.0, read=7.0)
    +       http = PoolManager(timeout=timeout)
    +       response = http.request('GET', 'http://example.com/')
    +
    +    Or per-request (which overrides the default for the pool):
    +
    +    .. code-block:: python
    +
    +       response = http.request('GET', 'http://example.com/', timeout=Timeout(10))
    +
    +    Timeouts can be disabled by setting all the parameters to ``None``:
    +
    +    .. code-block:: python
    +
    +       no_timeout = Timeout(connect=None, read=None)
    +       response = http.request('GET', 'http://example.com/, timeout=no_timeout)
    +
    +
    +    :param total:
    +        This combines the connect and read timeouts into one; the read timeout
    +        will be set to the time leftover from the connect attempt. In the
    +        event that both a connect timeout and a total are specified, or a read
    +        timeout and a total are specified, the shorter timeout will be applied.
    +
    +        Defaults to None.
    +
    +    :type total: int, float, or None
    +
    +    :param connect:
    +        The maximum amount of time (in seconds) to wait for a connection
    +        attempt to a server to succeed. Omitting the parameter will default the
    +        connect timeout to the system default, probably `the global default
    +        timeout in socket.py
    +        <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_.
    +        None will set an infinite timeout for connection attempts.
    +
    +    :type connect: int, float, or None
    +
    +    :param read:
    +        The maximum amount of time (in seconds) to wait between consecutive
    +        read operations for a response from the server. Omitting the parameter
    +        will default the read timeout to the system default, probably `the
    +        global default timeout in socket.py
    +        <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_.
    +        None will set an infinite timeout.
    +
    +    :type read: int, float, or None
    +
    +    .. note::
    +
    +        Many factors can affect the total amount of time for urllib3 to return
    +        an HTTP response.
    +
    +        For example, Python's DNS resolver does not obey the timeout specified
    +        on the socket. Other factors that can affect total request time include
    +        high CPU load, high swap, the program running at a low priority level,
    +        or other behaviors.
    +
    +        In addition, the read and total timeouts only measure the time between
    +        read operations on the socket connecting the client and the server,
    +        not the total amount of time for the request to return a complete
    +        response. For most requests, the timeout is raised because the server
    +        has not sent the first byte in the specified time. This is not always
    +        the case; if a server streams one byte every fifteen seconds, a timeout
    +        of 20 seconds will not trigger, even though the request will take
    +        several minutes to complete.
    +
    +        If your goal is to cut off any request after a set amount of wall clock
    +        time, consider having a second "watcher" thread to cut off a slow
    +        request.
    +    """
    +
    +    #: A sentinel object representing the default timeout value
    +    DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT
    +
    +    def __init__(self, total=None, connect=_Default, read=_Default):
    +        self._connect = self._validate_timeout(connect, "connect")
    +        self._read = self._validate_timeout(read, "read")
    +        self.total = self._validate_timeout(total, "total")
    +        self._start_connect = None
    +
    +    def __repr__(self):
    +        return "%s(connect=%r, read=%r, total=%r)" % (
    +            type(self).__name__,
    +            self._connect,
    +            self._read,
    +            self.total,
    +        )
    +
    +    # __str__ provided for backwards compatibility
    +    __str__ = __repr__
    +
    +    @classmethod
    +    def _validate_timeout(cls, value, name):
    +        """Check that a timeout attribute is valid.
    +
    +        :param value: The timeout value to validate
    +        :param name: The name of the timeout attribute to validate. This is
    +            used to specify in error messages.
    +        :return: The validated and casted version of the given value.
    +        :raises ValueError: If it is a numeric value less than or equal to
    +            zero, or the type is not an integer, float, or None.
    +        """
    +        if value is _Default:
    +            return cls.DEFAULT_TIMEOUT
    +
    +        if value is None or value is cls.DEFAULT_TIMEOUT:
    +            return value
    +
    +        if isinstance(value, bool):
    +            raise ValueError(
    +                "Timeout cannot be a boolean value. It must "
    +                "be an int, float or None."
    +            )
    +        try:
    +            float(value)
    +        except (TypeError, ValueError):
    +            raise ValueError(
    +                "Timeout value %s was %s, but it must be an "
    +                "int, float or None." % (name, value)
    +            )
    +
    +        try:
    +            if value <= 0:
    +                raise ValueError(
    +                    "Attempted to set %s timeout to %s, but the "
    +                    "timeout cannot be set to a value less "
    +                    "than or equal to 0." % (name, value)
    +                )
    +        except TypeError:
    +            # Python 3
    +            raise ValueError(
    +                "Timeout value %s was %s, but it must be an "
    +                "int, float or None." % (name, value)
    +            )
    +
    +        return value
    +
    +    @classmethod
    +    def from_float(cls, timeout):
    +        """Create a new Timeout from a legacy timeout value.
    +
    +        The timeout value used by httplib.py sets the same timeout on the
    +        connect(), and recv() socket requests. This creates a :class:`Timeout`
    +        object that sets the individual timeouts to the ``timeout`` value
    +        passed to this function.
    +
    +        :param timeout: The legacy timeout value.
    +        :type timeout: integer, float, sentinel default object, or None
    +        :return: Timeout object
    +        :rtype: :class:`Timeout`
    +        """
    +        return Timeout(read=timeout, connect=timeout)
    +
    +    def clone(self):
    +        """Create a copy of the timeout object
    +
    +        Timeout properties are stored per-pool but each request needs a fresh
    +        Timeout object to ensure each one has its own start/stop configured.
    +
    +        :return: a copy of the timeout object
    +        :rtype: :class:`Timeout`
    +        """
    +        # We can't use copy.deepcopy because that will also create a new object
    +        # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to
    +        # detect the user default.
    +        return Timeout(connect=self._connect, read=self._read, total=self.total)
    +
    +    def start_connect(self):
    +        """Start the timeout clock, used during a connect() attempt
    +
    +        :raises urllib3.exceptions.TimeoutStateError: if you attempt
    +            to start a timer that has been started already.
    +        """
    +        if self._start_connect is not None:
    +            raise TimeoutStateError("Timeout timer has already been started.")
    +        self._start_connect = current_time()
    +        return self._start_connect
    +
    +    def get_connect_duration(self):
    +        """Gets the time elapsed since the call to :meth:`start_connect`.
    +
    +        :return: Elapsed time in seconds.
    +        :rtype: float
    +        :raises urllib3.exceptions.TimeoutStateError: if you attempt
    +            to get duration for a timer that hasn't been started.
    +        """
    +        if self._start_connect is None:
    +            raise TimeoutStateError(
    +                "Can't get connect duration for timer that has not started."
    +            )
    +        return current_time() - self._start_connect
    +
    +    @property
    +    def connect_timeout(self):
    +        """Get the value to use when setting a connection timeout.
    +
    +        This will be a positive float or integer, the value None
    +        (never timeout), or the default system timeout.
    +
    +        :return: Connect timeout.
    +        :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None
    +        """
    +        if self.total is None:
    +            return self._connect
    +
    +        if self._connect is None or self._connect is self.DEFAULT_TIMEOUT:
    +            return self.total
    +
    +        return min(self._connect, self.total)
    +
    +    @property
    +    def read_timeout(self):
    +        """Get the value for the read timeout.
    +
    +        This assumes some time has elapsed in the connection timeout and
    +        computes the read timeout appropriately.
    +
    +        If self.total is set, the read timeout is dependent on the amount of
    +        time taken by the connect timeout. If the connection time has not been
    +        established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be
    +        raised.
    +
    +        :return: Value to use for the read timeout.
    +        :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None
    +        :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect`
    +            has not yet been called on this object.
    +        """
    +        if (
    +            self.total is not None
    +            and self.total is not self.DEFAULT_TIMEOUT
    +            and self._read is not None
    +            and self._read is not self.DEFAULT_TIMEOUT
    +        ):
    +            # In case the connect timeout has not yet been established.
    +            if self._start_connect is None:
    +                return self._read
    +            return max(0, min(self.total - self.get_connect_duration(), self._read))
    +        elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT:
    +            return max(0, self.total - self.get_connect_duration())
    +        else:
    +            return self._read
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/url.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/url.py
    new file mode 100644
    index 0000000..3a169a4
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/url.py
    @@ -0,0 +1,435 @@
    +from __future__ import absolute_import
    +
    +import re
    +from collections import namedtuple
    +
    +from ..exceptions import LocationParseError
    +from ..packages import six
    +
    +url_attrs = ["scheme", "auth", "host", "port", "path", "query", "fragment"]
    +
    +# We only want to normalize urls with an HTTP(S) scheme.
    +# urllib3 infers URLs without a scheme (None) to be http.
    +NORMALIZABLE_SCHEMES = ("http", "https", None)
    +
    +# Almost all of these patterns were derived from the
    +# 'rfc3986' module: https://github.com/python-hyper/rfc3986
    +PERCENT_RE = re.compile(r"%[a-fA-F0-9]{2}")
    +SCHEME_RE = re.compile(r"^(?:[a-zA-Z][a-zA-Z0-9+-]*:|/)")
    +URI_RE = re.compile(
    +    r"^(?:([a-zA-Z][a-zA-Z0-9+.-]*):)?"
    +    r"(?://([^\\/?#]*))?"
    +    r"([^?#]*)"
    +    r"(?:\?([^#]*))?"
    +    r"(?:#(.*))?$",
    +    re.UNICODE | re.DOTALL,
    +)
    +
    +IPV4_PAT = r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}"
    +HEX_PAT = "[0-9A-Fa-f]{1,4}"
    +LS32_PAT = "(?:{hex}:{hex}|{ipv4})".format(hex=HEX_PAT, ipv4=IPV4_PAT)
    +_subs = {"hex": HEX_PAT, "ls32": LS32_PAT}
    +_variations = [
    +    #                            6( h16 ":" ) ls32
    +    "(?:%(hex)s:){6}%(ls32)s",
    +    #                       "::" 5( h16 ":" ) ls32
    +    "::(?:%(hex)s:){5}%(ls32)s",
    +    # [               h16 ] "::" 4( h16 ":" ) ls32
    +    "(?:%(hex)s)?::(?:%(hex)s:){4}%(ls32)s",
    +    # [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
    +    "(?:(?:%(hex)s:)?%(hex)s)?::(?:%(hex)s:){3}%(ls32)s",
    +    # [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
    +    "(?:(?:%(hex)s:){0,2}%(hex)s)?::(?:%(hex)s:){2}%(ls32)s",
    +    # [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
    +    "(?:(?:%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s",
    +    # [ *4( h16 ":" ) h16 ] "::"              ls32
    +    "(?:(?:%(hex)s:){0,4}%(hex)s)?::%(ls32)s",
    +    # [ *5( h16 ":" ) h16 ] "::"              h16
    +    "(?:(?:%(hex)s:){0,5}%(hex)s)?::%(hex)s",
    +    # [ *6( h16 ":" ) h16 ] "::"
    +    "(?:(?:%(hex)s:){0,6}%(hex)s)?::",
    +]
    +
    +UNRESERVED_PAT = r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._!\-~"
    +IPV6_PAT = "(?:" + "|".join([x % _subs for x in _variations]) + ")"
    +ZONE_ID_PAT = "(?:%25|%)(?:[" + UNRESERVED_PAT + "]|%[a-fA-F0-9]{2})+"
    +IPV6_ADDRZ_PAT = r"\[" + IPV6_PAT + r"(?:" + ZONE_ID_PAT + r")?\]"
    +REG_NAME_PAT = r"(?:[^\[\]%:/?#]|%[a-fA-F0-9]{2})*"
    +TARGET_RE = re.compile(r"^(/[^?#]*)(?:\?([^#]*))?(?:#.*)?$")
    +
    +IPV4_RE = re.compile("^" + IPV4_PAT + "$")
    +IPV6_RE = re.compile("^" + IPV6_PAT + "$")
    +IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT + "$")
    +BRACELESS_IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT[2:-2] + "$")
    +ZONE_ID_RE = re.compile("(" + ZONE_ID_PAT + r")\]$")
    +
    +_HOST_PORT_PAT = ("^(%s|%s|%s)(?::0*?(|0|[1-9][0-9]{0,4}))?$") % (
    +    REG_NAME_PAT,
    +    IPV4_PAT,
    +    IPV6_ADDRZ_PAT,
    +)
    +_HOST_PORT_RE = re.compile(_HOST_PORT_PAT, re.UNICODE | re.DOTALL)
    +
    +UNRESERVED_CHARS = set(
    +    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-~"
    +)
    +SUB_DELIM_CHARS = set("!$&'()*+,;=")
    +USERINFO_CHARS = UNRESERVED_CHARS | SUB_DELIM_CHARS | {":"}
    +PATH_CHARS = USERINFO_CHARS | {"@", "/"}
    +QUERY_CHARS = FRAGMENT_CHARS = PATH_CHARS | {"?"}
    +
    +
    +class Url(namedtuple("Url", url_attrs)):
    +    """
    +    Data structure for representing an HTTP URL. Used as a return value for
    +    :func:`parse_url`. Both the scheme and host are normalized as they are
    +    both case-insensitive according to RFC 3986.
    +    """
    +
    +    __slots__ = ()
    +
    +    def __new__(
    +        cls,
    +        scheme=None,
    +        auth=None,
    +        host=None,
    +        port=None,
    +        path=None,
    +        query=None,
    +        fragment=None,
    +    ):
    +        if path and not path.startswith("/"):
    +            path = "/" + path
    +        if scheme is not None:
    +            scheme = scheme.lower()
    +        return super(Url, cls).__new__(
    +            cls, scheme, auth, host, port, path, query, fragment
    +        )
    +
    +    @property
    +    def hostname(self):
    +        """For backwards-compatibility with urlparse. We're nice like that."""
    +        return self.host
    +
    +    @property
    +    def request_uri(self):
    +        """Absolute path including the query string."""
    +        uri = self.path or "/"
    +
    +        if self.query is not None:
    +            uri += "?" + self.query
    +
    +        return uri
    +
    +    @property
    +    def netloc(self):
    +        """Network location including host and port"""
    +        if self.port:
    +            return "%s:%d" % (self.host, self.port)
    +        return self.host
    +
    +    @property
    +    def url(self):
    +        """
    +        Convert self into a url
    +
    +        This function should more or less round-trip with :func:`.parse_url`. The
    +        returned url may not be exactly the same as the url inputted to
    +        :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls
    +        with a blank port will have : removed).
    +
    +        Example: ::
    +
    +            >>> U = parse_url('http://google.com/mail/')
    +            >>> U.url
    +            'http://google.com/mail/'
    +            >>> Url('http', 'username:password', 'host.com', 80,
    +            ... '/path', 'query', 'fragment').url
    +            'http://username:password@host.com:80/path?query#fragment'
    +        """
    +        scheme, auth, host, port, path, query, fragment = self
    +        url = u""
    +
    +        # We use "is not None" we want things to happen with empty strings (or 0 port)
    +        if scheme is not None:
    +            url += scheme + u"://"
    +        if auth is not None:
    +            url += auth + u"@"
    +        if host is not None:
    +            url += host
    +        if port is not None:
    +            url += u":" + str(port)
    +        if path is not None:
    +            url += path
    +        if query is not None:
    +            url += u"?" + query
    +        if fragment is not None:
    +            url += u"#" + fragment
    +
    +        return url
    +
    +    def __str__(self):
    +        return self.url
    +
    +
    +def split_first(s, delims):
    +    """
    +    .. deprecated:: 1.25
    +
    +    Given a string and an iterable of delimiters, split on the first found
    +    delimiter. Return two split parts and the matched delimiter.
    +
    +    If not found, then the first part is the full input string.
    +
    +    Example::
    +
    +        >>> split_first('foo/bar?baz', '?/=')
    +        ('foo', 'bar?baz', '/')
    +        >>> split_first('foo/bar?baz', '123')
    +        ('foo/bar?baz', '', None)
    +
    +    Scales linearly with number of delims. Not ideal for large number of delims.
    +    """
    +    min_idx = None
    +    min_delim = None
    +    for d in delims:
    +        idx = s.find(d)
    +        if idx < 0:
    +            continue
    +
    +        if min_idx is None or idx < min_idx:
    +            min_idx = idx
    +            min_delim = d
    +
    +    if min_idx is None or min_idx < 0:
    +        return s, "", None
    +
    +    return s[:min_idx], s[min_idx + 1 :], min_delim
    +
    +
    +def _encode_invalid_chars(component, allowed_chars, encoding="utf-8"):
    +    """Percent-encodes a URI component without reapplying
    +    onto an already percent-encoded component.
    +    """
    +    if component is None:
    +        return component
    +
    +    component = six.ensure_text(component)
    +
    +    # Normalize existing percent-encoded bytes.
    +    # Try to see if the component we're encoding is already percent-encoded
    +    # so we can skip all '%' characters but still encode all others.
    +    component, percent_encodings = PERCENT_RE.subn(
    +        lambda match: match.group(0).upper(), component
    +    )
    +
    +    uri_bytes = component.encode("utf-8", "surrogatepass")
    +    is_percent_encoded = percent_encodings == uri_bytes.count(b"%")
    +    encoded_component = bytearray()
    +
    +    for i in range(0, len(uri_bytes)):
    +        # Will return a single character bytestring on both Python 2 & 3
    +        byte = uri_bytes[i : i + 1]
    +        byte_ord = ord(byte)
    +        if (is_percent_encoded and byte == b"%") or (
    +            byte_ord < 128 and byte.decode() in allowed_chars
    +        ):
    +            encoded_component += byte
    +            continue
    +        encoded_component.extend(b"%" + (hex(byte_ord)[2:].encode().zfill(2).upper()))
    +
    +    return encoded_component.decode(encoding)
    +
    +
    +def _remove_path_dot_segments(path):
    +    # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code
    +    segments = path.split("/")  # Turn the path into a list of segments
    +    output = []  # Initialize the variable to use to store output
    +
    +    for segment in segments:
    +        # '.' is the current directory, so ignore it, it is superfluous
    +        if segment == ".":
    +            continue
    +        # Anything other than '..', should be appended to the output
    +        elif segment != "..":
    +            output.append(segment)
    +        # In this case segment == '..', if we can, we should pop the last
    +        # element
    +        elif output:
    +            output.pop()
    +
    +    # If the path starts with '/' and the output is empty or the first string
    +    # is non-empty
    +    if path.startswith("/") and (not output or output[0]):
    +        output.insert(0, "")
    +
    +    # If the path starts with '/.' or '/..' ensure we add one more empty
    +    # string to add a trailing '/'
    +    if path.endswith(("/.", "/..")):
    +        output.append("")
    +
    +    return "/".join(output)
    +
    +
    +def _normalize_host(host, scheme):
    +    if host:
    +        if isinstance(host, six.binary_type):
    +            host = six.ensure_str(host)
    +
    +        if scheme in NORMALIZABLE_SCHEMES:
    +            is_ipv6 = IPV6_ADDRZ_RE.match(host)
    +            if is_ipv6:
    +                # IPv6 hosts of the form 'a::b%zone' are encoded in a URL as
    +                # such per RFC 6874: 'a::b%25zone'. Unquote the ZoneID
    +                # separator as necessary to return a valid RFC 4007 scoped IP.
    +                match = ZONE_ID_RE.search(host)
    +                if match:
    +                    start, end = match.span(1)
    +                    zone_id = host[start:end]
    +
    +                    if zone_id.startswith("%25") and zone_id != "%25":
    +                        zone_id = zone_id[3:]
    +                    else:
    +                        zone_id = zone_id[1:]
    +                    zone_id = "%" + _encode_invalid_chars(zone_id, UNRESERVED_CHARS)
    +                    return host[:start].lower() + zone_id + host[end:]
    +                else:
    +                    return host.lower()
    +            elif not IPV4_RE.match(host):
    +                return six.ensure_str(
    +                    b".".join([_idna_encode(label) for label in host.split(".")])
    +                )
    +    return host
    +
    +
    +def _idna_encode(name):
    +    if name and any([ord(x) > 128 for x in name]):
    +        try:
    +            import idna
    +        except ImportError:
    +            six.raise_from(
    +                LocationParseError("Unable to parse URL without the 'idna' module"),
    +                None,
    +            )
    +        try:
    +            return idna.encode(name.lower(), strict=True, std3_rules=True)
    +        except idna.IDNAError:
    +            six.raise_from(
    +                LocationParseError(u"Name '%s' is not a valid IDNA label" % name), None
    +            )
    +    return name.lower().encode("ascii")
    +
    +
    +def _encode_target(target):
    +    """Percent-encodes a request target so that there are no invalid characters"""
    +    path, query = TARGET_RE.match(target).groups()
    +    target = _encode_invalid_chars(path, PATH_CHARS)
    +    query = _encode_invalid_chars(query, QUERY_CHARS)
    +    if query is not None:
    +        target += "?" + query
    +    return target
    +
    +
    +def parse_url(url):
    +    """
    +    Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is
    +    performed to parse incomplete urls. Fields not provided will be None.
    +    This parser is RFC 3986 and RFC 6874 compliant.
    +
    +    The parser logic and helper functions are based heavily on
    +    work done in the ``rfc3986`` module.
    +
    +    :param str url: URL to parse into a :class:`.Url` namedtuple.
    +
    +    Partly backwards-compatible with :mod:`urlparse`.
    +
    +    Example::
    +
    +        >>> parse_url('http://google.com/mail/')
    +        Url(scheme='http', host='google.com', port=None, path='/mail/', ...)
    +        >>> parse_url('google.com:80')
    +        Url(scheme=None, host='google.com', port=80, path=None, ...)
    +        >>> parse_url('/foo?bar')
    +        Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...)
    +    """
    +    if not url:
    +        # Empty
    +        return Url()
    +
    +    source_url = url
    +    if not SCHEME_RE.search(url):
    +        url = "//" + url
    +
    +    try:
    +        scheme, authority, path, query, fragment = URI_RE.match(url).groups()
    +        normalize_uri = scheme is None or scheme.lower() in NORMALIZABLE_SCHEMES
    +
    +        if scheme:
    +            scheme = scheme.lower()
    +
    +        if authority:
    +            auth, _, host_port = authority.rpartition("@")
    +            auth = auth or None
    +            host, port = _HOST_PORT_RE.match(host_port).groups()
    +            if auth and normalize_uri:
    +                auth = _encode_invalid_chars(auth, USERINFO_CHARS)
    +            if port == "":
    +                port = None
    +        else:
    +            auth, host, port = None, None, None
    +
    +        if port is not None:
    +            port = int(port)
    +            if not (0 <= port <= 65535):
    +                raise LocationParseError(url)
    +
    +        host = _normalize_host(host, scheme)
    +
    +        if normalize_uri and path:
    +            path = _remove_path_dot_segments(path)
    +            path = _encode_invalid_chars(path, PATH_CHARS)
    +        if normalize_uri and query:
    +            query = _encode_invalid_chars(query, QUERY_CHARS)
    +        if normalize_uri and fragment:
    +            fragment = _encode_invalid_chars(fragment, FRAGMENT_CHARS)
    +
    +    except (ValueError, AttributeError):
    +        return six.raise_from(LocationParseError(source_url), None)
    +
    +    # For the sake of backwards compatibility we put empty
    +    # string values for path if there are any defined values
    +    # beyond the path in the URL.
    +    # TODO: Remove this when we break backwards compatibility.
    +    if not path:
    +        if query is not None or fragment is not None:
    +            path = ""
    +        else:
    +            path = None
    +
    +    # Ensure that each part of the URL is a `str` for
    +    # backwards compatibility.
    +    if isinstance(url, six.text_type):
    +        ensure_func = six.ensure_text
    +    else:
    +        ensure_func = six.ensure_str
    +
    +    def ensure_type(x):
    +        return x if x is None else ensure_func(x)
    +
    +    return Url(
    +        scheme=ensure_type(scheme),
    +        auth=ensure_type(auth),
    +        host=ensure_type(host),
    +        port=port,
    +        path=ensure_type(path),
    +        query=ensure_type(query),
    +        fragment=ensure_type(fragment),
    +    )
    +
    +
    +def get_host(url):
    +    """
    +    Deprecated. Use :func:`parse_url` instead.
    +    """
    +    p = parse_url(url)
    +    return p.scheme or "http", p.hostname, p.port
    diff --git a/deployment-apps/metricator-for-nmon/lib/urllib3/util/wait.py b/deployment-apps/metricator-for-nmon/lib/urllib3/util/wait.py
    new file mode 100644
    index 0000000..21b4590
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lib/urllib3/util/wait.py
    @@ -0,0 +1,152 @@
    +import errno
    +import select
    +import sys
    +from functools import partial
    +
    +try:
    +    from time import monotonic
    +except ImportError:
    +    from time import time as monotonic
    +
    +__all__ = ["NoWayToWaitForSocketError", "wait_for_read", "wait_for_write"]
    +
    +
    +class NoWayToWaitForSocketError(Exception):
    +    pass
    +
    +
    +# How should we wait on sockets?
    +#
    +# There are two types of APIs you can use for waiting on sockets: the fancy
    +# modern stateful APIs like epoll/kqueue, and the older stateless APIs like
    +# select/poll. The stateful APIs are more efficient when you have a lots of
    +# sockets to keep track of, because you can set them up once and then use them
    +# lots of times. But we only ever want to wait on a single socket at a time
    +# and don't want to keep track of state, so the stateless APIs are actually
    +# more efficient. So we want to use select() or poll().
    +#
    +# Now, how do we choose between select() and poll()? On traditional Unixes,
    +# select() has a strange calling convention that makes it slow, or fail
    +# altogether, for high-numbered file descriptors. The point of poll() is to fix
    +# that, so on Unixes, we prefer poll().
    +#
    +# On Windows, there is no poll() (or at least Python doesn't provide a wrapper
    +# for it), but that's OK, because on Windows, select() doesn't have this
    +# strange calling convention; plain select() works fine.
    +#
    +# So: on Windows we use select(), and everywhere else we use poll(). We also
    +# fall back to select() in case poll() is somehow broken or missing.
    +
    +if sys.version_info >= (3, 5):
    +    # Modern Python, that retries syscalls by default
    +    def _retry_on_intr(fn, timeout):
    +        return fn(timeout)
    +
    +else:
    +    # Old and broken Pythons.
    +    def _retry_on_intr(fn, timeout):
    +        if timeout is None:
    +            deadline = float("inf")
    +        else:
    +            deadline = monotonic() + timeout
    +
    +        while True:
    +            try:
    +                return fn(timeout)
    +            # OSError for 3 <= pyver < 3.5, select.error for pyver <= 2.7
    +            except (OSError, select.error) as e:
    +                # 'e.args[0]' incantation works for both OSError and select.error
    +                if e.args[0] != errno.EINTR:
    +                    raise
    +                else:
    +                    timeout = deadline - monotonic()
    +                    if timeout < 0:
    +                        timeout = 0
    +                    if timeout == float("inf"):
    +                        timeout = None
    +                    continue
    +
    +
    +def select_wait_for_socket(sock, read=False, write=False, timeout=None):
    +    if not read and not write:
    +        raise RuntimeError("must specify at least one of read=True, write=True")
    +    rcheck = []
    +    wcheck = []
    +    if read:
    +        rcheck.append(sock)
    +    if write:
    +        wcheck.append(sock)
    +    # When doing a non-blocking connect, most systems signal success by
    +    # marking the socket writable. Windows, though, signals success by marked
    +    # it as "exceptional". We paper over the difference by checking the write
    +    # sockets for both conditions. (The stdlib selectors module does the same
    +    # thing.)
    +    fn = partial(select.select, rcheck, wcheck, wcheck)
    +    rready, wready, xready = _retry_on_intr(fn, timeout)
    +    return bool(rready or wready or xready)
    +
    +
    +def poll_wait_for_socket(sock, read=False, write=False, timeout=None):
    +    if not read and not write:
    +        raise RuntimeError("must specify at least one of read=True, write=True")
    +    mask = 0
    +    if read:
    +        mask |= select.POLLIN
    +    if write:
    +        mask |= select.POLLOUT
    +    poll_obj = select.poll()
    +    poll_obj.register(sock, mask)
    +
    +    # For some reason, poll() takes timeout in milliseconds
    +    def do_poll(t):
    +        if t is not None:
    +            t *= 1000
    +        return poll_obj.poll(t)
    +
    +    return bool(_retry_on_intr(do_poll, timeout))
    +
    +
    +def null_wait_for_socket(*args, **kwargs):
    +    raise NoWayToWaitForSocketError("no select-equivalent available")
    +
    +
    +def _have_working_poll():
    +    # Apparently some systems have a select.poll that fails as soon as you try
    +    # to use it, either due to strange configuration or broken monkeypatching
    +    # from libraries like eventlet/greenlet.
    +    try:
    +        poll_obj = select.poll()
    +        _retry_on_intr(poll_obj.poll, 0)
    +    except (AttributeError, OSError):
    +        return False
    +    else:
    +        return True
    +
    +
    +def wait_for_socket(*args, **kwargs):
    +    # We delay choosing which implementation to use until the first time we're
    +    # called. We could do it at import time, but then we might make the wrong
    +    # decision if someone goes wild with monkeypatching select.poll after
    +    # we're imported.
    +    global wait_for_socket
    +    if _have_working_poll():
    +        wait_for_socket = poll_wait_for_socket
    +    elif hasattr(select, "select"):
    +        wait_for_socket = select_wait_for_socket
    +    else:  # Platform-specific: Appengine.
    +        wait_for_socket = null_wait_for_socket
    +    return wait_for_socket(*args, **kwargs)
    +
    +
    +def wait_for_read(sock, timeout=None):
    +    """Waits for reading to be available on a given socket.
    +    Returns True if the socket is readable, or False if the timeout expired.
    +    """
    +    return wait_for_socket(sock, read=True, timeout=timeout)
    +
    +
    +def wait_for_write(sock, timeout=None):
    +    """Waits for writing to be available on a given socket.
    +    Returns True if the socket is readable, or False if the timeout expired.
    +    """
    +    return wait_for_socket(sock, write=True, timeout=timeout)
    diff --git a/deployment-apps/metricator-for-nmon/lookups/nmon_metric_catalog.csv b/deployment-apps/metricator-for-nmon/lookups/nmon_metric_catalog.csv
    new file mode 100644
    index 0000000..e2ac738
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lookups/nmon_metric_catalog.csv
    @@ -0,0 +1,16 @@
    +"metric_name","metric_filter","metric_calculation","metric_type_of_calculation","metric_data_field","metric_primary_statsmode","metric_groupby","metric_table_groupby","metric_timechart_groupby","metric_charting_chart","metric_charting_stackmode","is_AIX","is_Linux","is_Solaris"
    +"os.unix.nmon.cpu.cpu_all.cpu_load_percent","metric_name=os.unix.nmon.cpu.cpu_all.Sys_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.User_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Wait_PCT OR metric_name=os.unix.nmon.cpu.cpu_all.Steal_PCT","`def_cpu_load_percent`","02 – extended metric","cpu_load_percent","avg","metric_name, host","host","host","line","default","True","True","True"
    +"os.unix.nmon.cpu.lpar.lpar_load_percent","metric_name=os.unix.nmon.cpu.lpar.*","`def_lpar_load_percent`","02 – extended metric","lpar_load_percent","avg","OStype, metric_name, host","host","host","line","default","True","False","False"
    +"os.unix.nmon.cpu.lpar.lpar_vp_usage","metric_name=os.unix.nmon.cpu.lpar.*","`def_lpar_load_cores`","02 – extended metric","lpar_load_cores","avg","OStype, metric_name, host","host","host","line","default","True","False","False"
    +"os.unix.nmon.cpu.lpar.lpar_pool_vp_usage","metric_name=os.unix.nmon.cpu.lpar.*","`def_lpar_pool_load_aix_cores`","02 – extended metric","lpar_pool_usage","avg","OStype, metric_name, host","host","host","line","default","True","False","False"
    +"os.unix.nmon.cpu.lpar.lpar_pool_vp_usage_percent","metric_name=os.unix.nmon.cpu.lpar.*","`def_all_os_lpar_pool_load_percent`","02 – extended metric","lpar_pool_vp_usage_PCT","avg","OStype, metric_name, host","host","host","line","default","True","False","False"
    +"os.unix.nmon.memory.mem.mem_used_effective_PCT","metric_name=os.unix.nmon.memory.mem.*","`def_memory_load_percent`","02 – extended metric","mem_used_effective_PCT","avg","metric_name, host","host","host","line","default","True","True","True"
    +"os.unix.nmon.memory.mem.swap_used_effective_PCT","metric_name=os.unix.nmon.memory.mem.*","`def_memory_load_percent`","02 – extended metric","swap_used_effective_PCT","avg","metric_name, host","host","host","line","default","True","True","True"
    +"os.unix.nmon.memory.mem.mem_used_effective","metric_name=os.unix.nmon.memory.mem.*","`def_memory_volume_MB`","02 – extended metric","mem_used_effective","avg","metric_name, host","host","host","line","default","True","True","True"
    +"os.unix.nmon.memory.mem.swap_used_effective","metric_name=os.unix.nmon.memory.mem.*","`def_memory_volume_MB`","02 – extended metric","swap_used_effective","avg","metric_name, host","host","host","line","default","True","True","True"
    +"os.unix.nmon.processes.top.aggreg_cpu_cores_per_process","metric_name=os.unix.nmon.processes.top.pct_CPU","eval usage_per_core=(value/100)","02 – extended metric","usage_per_core","sum","dimension_Command, host","host, dimension_Command","dimension_Command","column","stacked","True","True","True"
    +"os.unix.nmon.processes.top.aggreg_mem_MB_per_process","metric_name=os.unix.nmon.processes.top.Res*","`def_all_os_top_memory`","02 – extended metric","mem_usage_mb","sum","OStype, metric_name, dimension_Command,host","host, dimension_Command","dimension_Command","column","stacked","True","True","True"
    +"os.unix.nmon.storage.diskreadxfer","metric_name=os.unix.nmon.storage.diskread OR metric_name=os.unix.nmon.storage.diskbsize","`def_disk_read_xfer_by_device` | setfields metric_name=os.unix.nmon.storage.diskreadxfer","02 – extended metric","disk_read_iops","avg","metric_name, dimension_device, host","host","host","line","default","True","True","True"
    +"os.unix.nmon.storage.diskwritexfer","metric_name=os.unix.nmon.storage.diskwrite OR metric_name=os.unix.nmon.storage.diskbsize","`def_disk_write_xfer_by_device` | setfields metric_name=os.unix.nmon.storage.diskwritexfer","02 – extended metric","disk_write_iops","avg","metric_name, dimension_device, host","host","host","line","default","True","True","True"
    +"os.unix.nmon.storage.dgreadxfer","metric_name=os.unix.nmon.storage.dgread OR metric_name=os.unix.nmon.storage.dgsize","`def_dg_read_xfer_by_device` | setfields metric_name=os.unix.nmon.storage.dgreadxfer","02 – extended metric","disk_read_iops","avg","metric_name, dimension_device, host","host","host","line","default","False","True","False"
    +"os.unix.nmon.storage.dgwritexfer","metric_name=os.unix.nmon.storage.dgwrite OR metric_name=os.unix.nmon.storage.dgsize","`def_dg_write_xfer_by_device` | setfields metric_name=os.unix.nmon.storage.dgwritexfer","02 – extended metric","disk_write_iops","avg","metric_name, dimension_device, host","host","host","line","default","False","True","False"
    diff --git a/deployment-apps/metricator-for-nmon/lookups/static_dictionary_VM_Linux.csv b/deployment-apps/metricator-for-nmon/lookups/static_dictionary_VM_Linux.csv
    new file mode 100644
    index 0000000..bad9bd8
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/lookups/static_dictionary_VM_Linux.csv
    @@ -0,0 +1,44 @@
    +"perf_item","nmon_section","formula (or field name if not evaluated)","long_description",unity
    +"KERNEL STATISTICS",VM,allocstall,"allocstall: Number of direct reclaim calls (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"kswapd_inodesteal","kswapd_inodesteal: Number of pages reclaimed by kswapd via inode freeing (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"kswapd_steal","kswapd_steal: Number of pages reclaimed by kswapd (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"nr_bounce","nr_bounce: Miscellaneous statistics","Pages/sec"
    +"KERNEL STATISTICS",VM,"nr_dirty","nr_dirty: Number of pages that are dirty","Pages/sec"
    +"KERNEL STATISTICS",VM,"nr_mapped","nr_mapped: Number of pages mapped by files","Pages/sec"
    +"KERNEL STATISTICS",VM,"nr_page_table_pages","nr_page_table_pages: Number of pages allocated to page tables","Pages/sec"
    +"KERNEL STATISTICS",VM,"nr_slab","nr_slab: allocated by the kernel slab allocator","Pages/sec"
    +"KERNEL STATISTICS",VM,"nr_unstable","nr_unstable: Number of pages that are unstable","Pages/sec"
    +"KERNEL STATISTICS",VM,"nr_writeback","nr_writeback: Number of pages that are under writeback","Pages/sec"
    +"KERNEL STATISTICS",VM,pageoutrun,"pageoutrun: Number of kswapd's calls to page reclaim (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,pgactivate,"pgactivate: Number of page activations (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgalloc_dma","pgalloc_dma: Number of page allocations per zone (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgalloc_dma32","pgalloc_dma32: Number of page allocations per zone (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgalloc_high","pgalloc_high: Number of page allocations per zone (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgalloc_normal","pgalloc_normal: Number of page allocations per zone (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,pgdeactivate,"pgdeactivate: Number of page deactivations (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,pgfault,"pgfault: Number of minor page faults (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,pgfree,"pgfree: Number of page frees (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,pginodesteal,"pginodesteal: Number of pages reclaimed via inode freeing (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,pgmajfault,"pgmajfault: Number of major page faults (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,pgpgin,"pgpgin: Number of pageins (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,pgpgout,"pgpgout: Number of pageouts (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgrefill_dma","pgrefill_dma: Number of page refills (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgrefill_dma32","pgrefill_dma32: Number of page refills (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgrefill_high","pgrefill_high: Number of page refills (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgrefill_normal","pgrefill_normal: Number of page refills (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,pgrotated,"pgrotated: Miscellaneous statistics","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgscan_direct_dma","pgscan_direct_dma: Number of pages reclaimed directly (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgscan_direct_dma32","pgscan_direct_dma32: Number of pages reclaimed directly (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgscan_direct_high","pgscan_direct_high: Number of pages reclaimed directly (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgscan_direct_normal","pgscan_direct_normal: Number of pages reclaimed directly (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgscan_kswapd_dma","pgscan_kswapd_dma: Number of pages scanned by the kswapd daemon (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgscan_kswapd_dma32","pgscan_kswapd_dma32: Number of pages scanned by the kswapd daemon (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgscan_kswapd_high","pgscan_kswapd_high: Number of pages scanned by the kswapd daemon (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgscan_kswapd_normal","pgscan_kswapd_normal: Number of pages scanned by the kswapd daemon (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgsteal_dma","pgsteal_dma: Number of page steals (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgsteal_dma32","pgsteal_dma32: Number of page steals (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgsteal_high","pgsteal_high: Number of page steals (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"pgsteal_normal","pgsteal_normal: Number of page steals (per zone, since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,pswpin,"pswpin: Number of swapins (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,pswpout,"pswpout: Number of swapouts (since the last boot)","Pages/sec"
    +"KERNEL STATISTICS",VM,"slabs_scanned","slabs_scanned: Number of slab objects scanned (since the last boot)","Pages/sec"
    diff --git a/deployment-apps/metricator-for-nmon/metadata/default.meta b/deployment-apps/metricator-for-nmon/metadata/default.meta
    new file mode 100644
    index 0000000..f68362c
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/metadata/default.meta
    @@ -0,0 +1,138 @@
    +
    +# Application-level permissions
    +
    +[]
    +owner = admin
    +access = read : [ * ], write : [ admin ]
    +
    +### EVENT TYPES
    +
    +[eventtypes]
    +export = system
    +
    +
    +### PROPS
    +
    +[props]
    +export = system
    +
    +
    +### MACROS
    +
    +[macros]
    +export = system
    +
    +
    +### TRANSFORMS
    +
    +[transforms]
    +export = system
    +
    +
    +### LOOKUPS
    +
    +[lookups]
    +export = system
    +
    +### TAGS
    +
    +[tags]
    +export = system
    +
    +### VIEWSTATES: even normal users should be able to create shared viewstates
    +
    +[viewstates]
    +access = read : [ * ], write : [ * ]
    +export = system
    +
    +### Special permissions
    +
    +# KVstore collections used for configuration purposes should be explicitly mentioned
    +# Only users with the relevant privileges should be able to update the collections, by default this the admin role but you can customize it to your needs:
    +
    +# If you need a very granular permissions management and do not import admin role or similar capabilities, you can copy/paste this block in local.meta and customize up to your needs
    +
    +# KVstore based lookups permissions must be configured for both transforms and collections
    +
    +# nmon_alerting_filesystem_global_exclusion
    +
    +[transforms/nmon_alerting_filesystem_global_exclusion]
    +access = read : [ * ], write : [ admin ]
    +
    +[collections/kv_nmon_alerting_filesystem_global_exclusion]
    +access = read : [ * ], write : [ admin ]
    +
    +# nmon_alerting_filesystem_per_server_exclusion
    +
    +[transforms/nmon_alerting_filesystem_per_server_exclusion]
    +access = read : [ * ], write : [ admin ]
    +
    +[collections/kv_nmon_alerting_filesystem_per_server_exclusion]
    +access = read : [ * ], write : [ admin ]
    +
    +# nmon alerting threshold management
    +
    +[transforms/nmon_alerting_threshold]
    +access = read : [ * ], write : [ admin ]
    +
    +[collections/kv_nmon_alerting_threshold]
    +access = read : [ * ], write : [ admin ]
    +
    +# nmon alerting threshold management for file-systems
    +
    +[transforms/nmon_alerting_threshold_filesystem]
    +access = read : [ * ], write : [ admin ]
    +
    +[collections/kv_nmon_alerting_threshold_filesystem]
    +access = read : [ * ], write : [ admin ]
    +
    +# nmon_inventory
    +
    +[transforms/nmon_inventory]
    +access = read : [ * ], write : [ admin ]
    +
    +[collections/kv_nmon_inventory]
    +access = read : [ * ], write : [ admin ]
    +
    +# nmon_frameID_mapping
    +
    +[transforms/nmon_frameID_mapping]
    +access = read : [ * ], write : [ admin ]
    +
    +[collections/kv_nmon_frameID_mapping]
    +access = read : [ * ], write : [ admin ]
    +
    +# nmon_hosts_last_7days
    +[transforms/nmon_hosts_last_7days]
    +access = read : [ * ], write : [ admin ]
    +
    +[collections/kv_nmon_hosts_last_7days]
    +access = read : [ * ], write : [ admin ]
    +
    +# nmon_baseline_CPU_ALL
    +[transforms/nmon_baseline_CPU_ALL]
    +access = read : [ * ], write : [ admin ]
    +
    +[collections/kv_nmon_baseline_CPU_ALL]
    +access = read : [ * ], write : [ admin ]
    +
    +# nmon_baseline_LPAR
    +[transforms/nmon_baseline_LPAR]
    +access = read : [ * ], write : [ admin ]
    +
    +[collections/kv_nmon_baseline_LPAR]
    +access = read : [ * ], write : [ admin ]
    +
    +# nmon_baseline_MEM
    +[transforms/nmon_baseline_MEM]
    +access = read : [ * ], write : [ admin ]
    +
    +[collections/kv_nmon_baseline_MEM]
    +access = read : [ * ], write : [ admin ]
    +
    +# nmon_baseline_DISKXFER
    +[transforms/nmon_baseline_DISKXFER]
    +access = read : [ * ], write : [ admin ]
    +
    +[collections/kv_nmon_baseline_DISKXFER]
    +access = read : [ * ], write : [ admin ]
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/splunkbase.manifest b/deployment-apps/metricator-for-nmon/splunkbase.manifest
    new file mode 100644
    index 0000000..e73758b
    --- /dev/null
    +++ b/deployment-apps/metricator-for-nmon/splunkbase.manifest
    @@ -0,0 +1,2589 @@
    +{
    +  "version": "1.0",
    +  "date": "2023-02-20T11:46:21.71171569Z",
    +  "hashAlgorithm": "SHA-256",
    +  "app": {
    +    "id": 3947,
    +    "version": "2.0.0",
    +    "files": [
    +      {
    +        "path": "VERSION",
    +        "hash": "7852e746baf4c54dd0302dfceebdfc6899ebf9b5e90b32df54076ad759baf431"
    +      },
    +      {
    +        "path": "metadata/default.meta",
    +        "hash": "41a1eba456dd09229993784c8644cf90181380e3501409cf8416df3fe13e635c"
    +      },
    +      {
    +        "path": "app.manifest",
    +        "hash": "dc14aba1aa3d5dc2c6d5cb26b69a4b8d46ce1056a63abf0188b9b1a0e06b3911"
    +      },
    +      {
    +        "path": "appserver/static/Octamis/Octamis_Logo_v3_no_bg.png",
    +        "hash": "d01abf6f2ffb85dde60bc0ed28f737fde603a9d949401169cb363ea3b352bab7"
    +      },
    +      {
    +        "path": "appserver/static/hide_footer.css",
    +        "hash": "4597b81a73c3d62a56b669e0225f464f98458f58e2a9ef113e5a2a16ada9ccf0"
    +      },
    +      {
    +        "path": "appserver/static/panel_resize.js",
    +        "hash": "d5b69448d86db51fe5675cd356ec389eecef57370b444e8418795ebf4d8a3602"
    +      },
    +      {
    +        "path": "appserver/static/modal_msg.js",
    +        "hash": "db5d31b2122f68a0ff3df287647771592663f6f433fd3df7c3dd29781bb90cd0"
    +      },
    +      {
    +        "path": "appserver/static/manage_file_systems_template_exclusion_v2.css",
    +        "hash": "f450a772736898592e1b9526dfc8fef2cfb2ff24d0b5bbf84cb8f1e3d4e0e74b"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/predict.png",
    +        "hash": "7757d3d87e860849849cc90adbdd4df591362ee8eb5e948bbbf1d084e0fe191c"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/cpu.png",
    +        "hash": "3781ba7de9e613233d513f892ef97727c84b4eb1f0f9afec2dacd708f1aa5940"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/link.png",
    +        "hash": "060852748ef4aac1ff2f9d922987caf4ab0a6f92eb61dd5b2e2934f9bc048a74"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/memory.png",
    +        "hash": "bc12ffba07e86cf919811804098b681b35cf94991723c742477a70058b2d5fd4"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/dictionary.png",
    +        "hash": "9946990011919444f745289a6eab98c5683d55bcae8b92c7e0be85bef4a0d331"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/filesystem.png",
    +        "hash": "78a1b252f464a3a2d193d8321b97ba475d2f86de58c0668e71a90717154e8e82"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/bug.png",
    +        "hash": "d5fd7f3990e7cdb43e8fb6055d91a1c6f8e57f3460004a001ed7aaf83b000573"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/dollar.png",
    +        "hash": "fa9140dcf836b6f7f69226a340a9266b29b0ffc4fbd11077e96414d61001a08f"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/server_info.png",
    +        "hash": "14d34fad4300e6f3f4ef928dabd38b32025d734cb54c7eeb9c2a8780ad246a20"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/drive.png",
    +        "hash": "c594ab247884f22f7d849f60d4e43015c80364d7b0c620442331496d23061c47"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/minidatabase.png",
    +        "hash": "003234111df5c079b5a546eb0e4a83eef8fda83d425e66999125db4fb82ccb50"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/settings.png",
    +        "hash": "5926e34b968dd370a73d18c1c41d6585f0189011c476efae16237611356df917"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/network.png",
    +        "hash": "368d411e5405479c4658b7a9c669acefe6e559f9e49c9fe4bb50b077be97ccc2"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/calendar.png",
    +        "hash": "ff5bdb5d7ef4f4c5b350de579662747d6be89dd23732b2e1a9318828360631c1"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/info.png",
    +        "hash": "3f6340908ce2c4d8d7b010884a1b1bf7f6a7cf61715ecd0e7d2faabc33326896"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/dashboard.png",
    +        "hash": "8c011c2692bf632749e950af2de585447bb360688dec1dd549a74bdf6f0a29bf"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/people.png",
    +        "hash": "2ad5a472259de4d6de2918dc5cb09305090c9a1b2cb93d6e93e7644bb5c350ab"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/compare.png",
    +        "hash": "796175c2a2b805e3e4f9f0c9c05e98aa25f0a850fe75d35124eeb187424efe21"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/inventory.png",
    +        "hash": "f88ed4913319956a064effe369062d7dc8b46de3c1422f2c2dc7d93bb0fee7fe"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/process.png",
    +        "hash": "e9989cd12b696dbbdad63c2d86bbac427c1f6d1222829df7b1f9f4e340130211"
    +      },
    +      {
    +        "path": "appserver/static/icons/dark_theme/minihelp.png",
    +        "hash": "e79ebb89e410b99f1f59a3ff10f35c133d7165e6240e1c5d045a6401326a1f94"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/predict.png",
    +        "hash": "a2930fe72c69ab418d143636271942eeb3bb459aaf875fe8a54e33b2f0e1992a"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/arrow_red_decrease_48px.png",
    +        "hash": "b7ad4bf50617a0d72891a84173ad0d2a071f52fce50743b1a0949e2582ddf128"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/cpu.png",
    +        "hash": "7182558f2ad3ae46a79d55da329aff15c5e0fff5ad070d06253175b0e97a707b"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/redcross.png",
    +        "hash": "729bfaae5642f7c62680cd0b154b94098e3a7637570211cccc220bb891128aa8"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/memory.png",
    +        "hash": "86a73d8692ecdde004505d15c04fa4b6c3727e4ceaa685256737c7b1183b2820"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/arrow_green_decrease_48px.png",
    +        "hash": "ee8fc4a63831f61b35b5dadb20fae797356b4760516e75e72b1dc5e3871d9b79"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/warning.png",
    +        "hash": "da95d26858b8213b028688816c4fa3e17ca63715344c4244024cabea6020270c"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/arrow_red_increase_48px.png",
    +        "hash": "fbe461f2e62d1bc0677d017f28ebe51ca9e64bea9e59761d9d13ac8fdbb0b857"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/arrow_green_increase_48px.png",
    +        "hash": "838423f12dfbc96d38adfdbb9396647ac6ef7fff75c50901d8cf80772b9ee57b"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/drive.png",
    +        "hash": "53b218ec545123ea8545371cadc8d458f419821cffd7ce6351abe15a85864e82"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/executive-search.png",
    +        "hash": "158e0165d4f7c358e549d197ce36a48454c172c56e341efe57c9d5eb1b94e8e1"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/info2.png",
    +        "hash": "86773720cff27c159c3125f1ee6e36119984846781a46df40428f65dc699680c"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/calendar.png",
    +        "hash": "80dbe1e823702d8051778814f2de103299be297d05601ec277f10d6e67981974"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/info.png",
    +        "hash": "ec577f29b9e27064df1b0a1f97419db2b6daf17876d605fe1da7f0757565ef4e"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/dashboard.png",
    +        "hash": "519cf62c0579ad5bd6d382f26e1fce095b9a58826709c5643b2352308d2e56d1"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/compare.png",
    +        "hash": "25b969d2cc0151e99ad9e4eeef400cbf6f1840a8f4dd159b9bd6bec66da9e2f3"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/equal-sign-48px.png",
    +        "hash": "fe03f8307c9d9ec7da285efd240307a2cf236fa3b4c4bfe6ebe5ac35a00aa4e9"
    +      },
    +      {
    +        "path": "appserver/static/icons/color_theme/process.png",
    +        "hash": "56c3a2631d1261c278aefaef79ae65b35ce9b2b7b9ccc1223882d73879839491"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/predict.png",
    +        "hash": "bceff8f9df5d35aa4d62cf70b279873a1a0da9e7a6c508d0cbb42f9d49597199"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/cpu.png",
    +        "hash": "b179234872076d739627172560a29b03cd563adf686af2277d5cf0cb86e4b236"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/link.png",
    +        "hash": "ee4f813c44e74577200bf00b57d8ed6c8d0eb383307aa83c7d252b164658435a"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/memory.png",
    +        "hash": "7e9fb25643162c0ea8ac99b9795cbaf84370c52c9f8761797829df07ff9ef629"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/dictionary.png",
    +        "hash": "b7936009cdc20b7efd7f7ab77d5be10365e78810fc34788364077ca82f513e95"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/filesystem.png",
    +        "hash": "7d99cb2bd2f783f28353a831e039f21e752a02678130ce36620a392e13fc1297"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/bug.png",
    +        "hash": "2ffec1e667a6f0f87f4df3862926d46fa8f32885df99828fb3acedbf1c3d7134"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/dollar.png",
    +        "hash": "4e95ce5bef0ab7a30d1ea4212cd89417d08bc65f048a972ee8e76f394410a0eb"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/server_info.png",
    +        "hash": "d608a1414a724a16d1705e16cc79049f41b010a6f76823e85ed5716e800d78a2"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/drive.png",
    +        "hash": "fc53efd6a1fd86bd424e1f3d4efa60cb4ae00e48c43b3be3dee7c0fa5ecad6d8"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/minidatabase.png",
    +        "hash": "cb56fb36939f7ac1b18fa70a810cf001f66c83f45c85f221a90941ef649d34e9"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/settings.png",
    +        "hash": "dbda6b67076d5e39536bb018dbda8decae87c4cdee5fada31cf38862cee72bf2"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/network.png",
    +        "hash": "30a34bdd768bbfc9a1ad3cd4e341374f7aeca31c837796ef04cf89b37f40b932"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/calendar.png",
    +        "hash": "178dab12aed9dfce910598aeb1eae7ff4b1d7ebb27ca0fc3089a9b433274f6e3"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/info.png",
    +        "hash": "3dc9d43c82aeb75c7fb815ec95f002a389c1d756f1ef83d5f8dcfb6acc02ea8b"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/dashboard.png",
    +        "hash": "67f4cd095bd6b7be730e1ff412df8ad661644c323b12cff1e1c2437036a88736"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/people.png",
    +        "hash": "c7a872f3bce0472378dad7279ea2f704e086df50492d70b584f51424ddf2abbc"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/compare.png",
    +        "hash": "254cfecbb833b75d43dfe6de018620bbff8c4dcce8edf068624dd798b028f770"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/inventory.png",
    +        "hash": "030cc182312770cf7465002a56851815e3a42b20fb69446b6f8e6adb3b949a92"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/process.png",
    +        "hash": "9d47b8ae96bd11af5eacd3670365f0722de9431ace835ca8a3ba16772ba5cd43"
    +      },
    +      {
    +        "path": "appserver/static/icons/grey_theme/minihelp.png",
    +        "hash": "1328f30a4f1441cb6e8e6a831209a78bcd6281bdb07e3756ef396dd39d3abbb0"
    +      },
    +      {
    +        "path": "appserver/static/dashboard.js",
    +        "hash": "ad21b064208c96575ccc6835358f8ecfda1a8f90d240c2ca971a979f9e7110a5"
    +      },
    +      {
    +        "path": "appserver/static/screenshot5.png",
    +        "hash": "ea0b6ae8bf5709a5c143210466e15407867eeb5ca65259d3a143711e6762b4e8"
    +      },
    +      {
    +        "path": "appserver/static/screenshot4.png",
    +        "hash": "1fea3270c3727828d6d34a1b8fd0fd94e4e37fed76bbd0df300079815de71f7e"
    +      },
    +      {
    +        "path": "appserver/static/manage_frameid_mapping_v2.js",
    +        "hash": "4df91b851b988bf12e2ae318f5e7e8db2414b97ea0504b8992632f68b3602a82"
    +      },
    +      {
    +        "path": "appserver/static/manage_file_systems_global_exclusion_v2.css",
    +        "hash": "f450a772736898592e1b9526dfc8fef2cfb2ff24d0b5bbf84cb8f1e3d4e0e74b"
    +      },
    +      {
    +        "path": "appserver/static/manage_alerting_threshold_table_bar.js",
    +        "hash": "b18292f0f5a841f30bbe422c823bd5fa3c63415dce9f24010b1c9594fc85e638"
    +      },
    +      {
    +        "path": "appserver/static/autodiscover.js",
    +        "hash": "32f465cd0fd7371f726c83d33fb3bf649a2b1563dc07d0bde955423522869321"
    +      },
    +      {
    +        "path": "appserver/static/manage_template_alerting_threshold_table_bar.js",
    +        "hash": "b18292f0f5a841f30bbe422c823bd5fa3c63415dce9f24010b1c9594fc85e638"
    +      },
    +      {
    +        "path": "appserver/static/screenshot.png",
    +        "hash": "680fff44022858878693e88293ef67eabc8d67788b38380cf4cf8bff9c9d8d3f"
    +      },
    +      {
    +        "path": "appserver/static/table_icons_rangemap.js",
    +        "hash": "e34d276a70ff18782f0878af335e96654fc9ecbb3fe79d686a0257a7ad8757a5"
    +      },
    +      {
    +        "path": "appserver/static/dashboard.css",
    +        "hash": "8e05cfd3d9c90813b66892c9d93f7f677dad4d0eb091c4cdb25b887d0a95316c"
    +      },
    +      {
    +        "path": "appserver/static/table_decorations.css",
    +        "hash": "8f0b6d0a372574866c852abee238fe50bdf1e5d9059f63c01bc0f6cceb8e20f9"
    +      },
    +      {
    +        "path": "appserver/static/take_the_tour/thresholds.png",
    +        "hash": "c648e5ba89782ee4b94c6cd46519bf9279561a302457aac418255b7b3f12cdb3"
    +      },
    +      {
    +        "path": "appserver/static/take_the_tour/OS_logos.png",
    +        "hash": "a403931f5cc24388285aae1705e0236d30b3bbefc22d1fe008b0f99c27c50241"
    +      },
    +      {
    +        "path": "appserver/static/take_the_tour/metrics_showcase.png",
    +        "hash": "7f69bb8748a743af196e29071c85184695d3104cabe7e8350ae011d396873e1c"
    +      },
    +      {
    +        "path": "appserver/static/take_the_tour/main.png",
    +        "hash": "2ea21d6ced12b7766cec79c60af7154d6757490c566991b3125a108958ef2633"
    +      },
    +      {
    +        "path": "appserver/static/take_the_tour/advanced_dashboards.png",
    +        "hash": "133083e8ebfe081b320c1d6099cda5fbc2df0ad5d2c07198fd5d106aa19d05ef"
    +      },
    +      {
    +        "path": "appserver/static/take_the_tour/tco.png",
    +        "hash": "fa655c77c403d70ba58655a1e90338ab9f7e965cdcf37fd3c17e7800ebef5a3b"
    +      },
    +      {
    +        "path": "appserver/static/active_button.js",
    +        "hash": "190d97628b05c826317f30af041865654c32e29a65117b75b980f152c9b0e8f9"
    +      },
    +      {
    +        "path": "appserver/static/alerting_filesystem_threshold.js",
    +        "hash": "cf6ccbd128dac0cac15db99136be545e4bd427957be2a67a51e9c8933741ef6b"
    +      },
    +      {
    +        "path": "appserver/static/Help.css",
    +        "hash": "f8945df07863ceb5f55971d26e019b7b3b49dafbe721bb8e0f9405165517db56"
    +      },
    +      {
    +        "path": "appserver/static/manage_alerting_threshold_v2.css",
    +        "hash": "53f3d7824f5b044757eff56c29ed8bf0c66b42b2ae2a039fe9e7852d68ff0d7e"
    +      },
    +      {
    +        "path": "appserver/static/table_data_bar.js",
    +        "hash": "948cd133e61f4fd20e85927a9a85bf813cb47296c46258a876edff9802a201d0"
    +      },
    +      {
    +        "path": "appserver/static/manage_alerting_threshold_filesystem_v2.css",
    +        "hash": "f450a772736898592e1b9526dfc8fef2cfb2ff24d0b5bbf84cb8f1e3d4e0e74b"
    +      },
    +      {
    +        "path": "appserver/static/dark.css",
    +        "hash": "67a2691458ebc8a8d2c7053a226c1c28323fe61fe7394019003142e81806a3da"
    +      },
    +      {
    +        "path": "appserver/static/table_data_bar.css",
    +        "hash": "797f3bc17c47d933506c15c8022c3b3b9f138899b80197f86e9d259ad8a1567d"
    +      },
    +      {
    +        "path": "appserver/static/hover.css",
    +        "hash": "a4c1e4dc4edccabdd04949980c8cb09af3df4f5f6c60ab3db6b0f35b74279f1f"
    +      },
    +      {
    +        "path": "appserver/static/modal.js",
    +        "hash": "5708c6a7d0155a8b981416a972ea5f72b5acfbd8ca9213ae989a00b443ecf11c"
    +      },
    +      {
    +        "path": "appserver/static/alerting_threshold_template.js",
    +        "hash": "5d9c1a9269dd3f3b56764f0433c5e0359ddff99bcbce17a642db349bb6bb476a"
    +      },
    +      {
    +        "path": "appserver/static/screenshot2.png",
    +        "hash": "5a8f5f951437d2c6318b6ec0f51d47820a4d6ef8fe69c616648db27061fb645d"
    +      },
    +      {
    +        "path": "appserver/static/manage_alerting_threshold_v2.js",
    +        "hash": "052cd54700cefcd50baccba6760cb552759b785f8a1fa3386c69eb91ea2d3c1e"
    +      },
    +      {
    +        "path": "appserver/static/screenshot3.png",
    +        "hash": "a507839cc08aac0bbdd34aa2abe6980056c4125fdb36b270ff6077e55dedf70e"
    +      },
    +      {
    +        "path": "appserver/static/Nmon_compare.js",
    +        "hash": "4857797295bdd9db6e9bfab74a9d51b78a34b6086a7b1e96042519c8326bfa22"
    +      },
    +      {
    +        "path": "appserver/static/manage_file_systems_template_exclusion_v2.js",
    +        "hash": "80759299696cbb98db28f6761efa90cb691781545b8857dbd08d4e5740c6c0ee"
    +      },
    +      {
    +        "path": "appserver/static/manage_template_alerting_threshold_v2.css",
    +        "hash": "ca04a47b222f4dc602b7f5868f080d2b0c43e0acefb11a1461242a8f75a82507"
    +      },
    +      {
    +        "path": "appserver/static/manage_file_systems_exclusion_v2.css",
    +        "hash": "f450a772736898592e1b9526dfc8fef2cfb2ff24d0b5bbf84cb8f1e3d4e0e74b"
    +      },
    +      {
    +        "path": "appserver/static/safecenter.css",
    +        "hash": "dff06719ae6bf0006e54efd89411ea16d4d0d4a0194936d0748cb25017c2c182"
    +      },
    +      {
    +        "path": "appserver/static/logos/Others/RT_icon.png",
    +        "hash": "70747451cf45f5b17dead866d4b777a7ff100dce95bea2ba295ca74d53953e50"
    +      },
    +      {
    +        "path": "appserver/static/logos/Others/RT_icon.xcf",
    +        "hash": "e5a970c851b74955b15b25663ddc3f23c6a031cfe7455ea39c5ebc9f793ace52"
    +      },
    +      {
    +        "path": "appserver/static/logos/appIconAlt_2x.png",
    +        "hash": "c03c8a587f9ed78aad18d88e4977164246fc7997cd7ce14b6e9d03f9f8705aff"
    +      },
    +      {
    +        "path": "appserver/static/logos/manufactors/IBM_logo_72px.png",
    +        "hash": "9c1fab62e9d0d603a5e1ae1b621a61254dff1118b9bb7c82ae1dea0d3f2aeda1"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/colors/linux_alt_128px.png",
    +        "hash": "6078cff25a9d49c946b40b1193ee60b840f1586d4efc69ef41b4c2915e3d2390"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/colors/linux_72px.png",
    +        "hash": "fcf678f9a233d48a10dadac1482729effe2315c8f6fbd163007bc55758a66201"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/colors/solaris_48px.png",
    +        "hash": "2a1198b6360a2b507501aca42ffaa92fc7fd5908c96b998516bbe1bceb3d9d01"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/colors/solaris_128px.png",
    +        "hash": "608a71a093ad77d5ead4c8083a496cd8cd3418da950e354fd7502ac130834964"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/colors/linux_48px.png",
    +        "hash": "1ed67ce95718f17bddf2580d548f7584eda74977a0618fd2668ec4441071f4a0"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/colors/solaris_72px.png",
    +        "hash": "3d147ae2795bb251ecf0b9b00b817314fce0053a6d5d3be8bb759597aa6528b4"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/colors/AIX_72px.png",
    +        "hash": "dd315d6f0d90fed89aa7640ea5538fa27307622ef204a12055b8dea8096c6b25"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/colors/Windows_72px.png",
    +        "hash": "8c8fafd5fc850aebd8baaf23034216658dec5bae659fe6e92284586773ddb0f1"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/colors/AIX_48px.png",
    +        "hash": "29757543dfef0100b95af6c599bafcded3b3f40be6346f5298bc098ffd9a0a6f"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/blackandwhite/linux_alt_72px.png",
    +        "hash": "c35e86a0124b1806c220367c46c93c9098cd2e159f196410f7e9ab388ee4fae2"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/blackandwhite/solaris_alt_72px.png",
    +        "hash": "3493ba7b0ed4ca7e07b8db022a622ad9aa7af88ce887be833159fcbb7c2edf52"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/blackandwhite/linux_alt_128px.png",
    +        "hash": "173148036c0424cb5d489040f5a0ae99be80b9a0aad495ecd1bf4744541165a8"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/blackandwhite/linux_72px.png",
    +        "hash": "35da44741b9da7ec57c4f989416233ebf265fc8a87759296a723d0ed49a3a310"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/blackandwhite/solaris_48px.png",
    +        "hash": "b2b06e91e5ed9292f06eb8d290f8703971e48ee6d7422040ce502b751cba37e9"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/blackandwhite/linux_48px.png",
    +        "hash": "8d7ef08f82767aca31304940d8a0836f4ad0a0b33edea9cc8942507e2ebac287"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/blackandwhite/solaris_72px.png",
    +        "hash": "6c3763db86f9cb554b74a4ad6615cf88592f42b5bf1a81e302e3d1f208d4ff54"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/blackandwhite/solaris_alt_48px.png",
    +        "hash": "06f5267e787db6a9fd24a8c87800e4fa1e0c91838f711340c05008d2767b255b"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/blackandwhite/AIX_72px.png",
    +        "hash": "9ad684db75241cfcb92e6f6dbf7c48c09e8ca6ab485061919d7a7bdcfb10b148"
    +      },
    +      {
    +        "path": "appserver/static/logos/OS/blackandwhite/AIX_48px.png",
    +        "hash": "00f86b648a2b19d02d3f93b630e11f736a36405be02a01521e460fbbb6be3b0b"
    +      },
    +      {
    +        "path": "appserver/static/alerting_threshold_template_filesystem.js",
    +        "hash": "cb862c69a5a9f6816053b107b2f5b5f67954dc5c329955d3d1af43315c31f36e"
    +      },
    +      {
    +        "path": "appserver/static/alerting_filesystem_threshold.css",
    +        "hash": "5ee715f43c40df6537dbdbe2975d48dde375259b6c84ea0c855f2a7c4c928bc5"
    +      },
    +      {
    +        "path": "appserver/static/manage_template_alerting_threshold_filesystem_v2.css",
    +        "hash": "ca04a47b222f4dc602b7f5868f080d2b0c43e0acefb11a1461242a8f75a82507"
    +      },
    +      {
    +        "path": "appserver/static/hide_timeindicator.css",
    +        "hash": "84ffb37e216ebedb19a6fd1b35e28fe066ad39230890cb9f13183d605fb69636"
    +      },
    +      {
    +        "path": "appserver/static/howto.css",
    +        "hash": "429f3261407433453150b7620526ecfb77306ac630366f901ea70f03bc7f86e1"
    +      },
    +      {
    +        "path": "appserver/static/Home.css",
    +        "hash": "e717eafbc2d4a7c7ede18a4d7e74a555153fdbc100980a3638efedb72d1ed97b"
    +      },
    +      {
    +        "path": "appserver/static/manage_file_systems_global_exclusion_v2.js",
    +        "hash": "17c1d0f8dda3dda12a4e2073d7b56cc881992d5589ba0defcfe42a304fa8c080"
    +      },
    +      {
    +        "path": "appserver/static/manage_frameid_mapping_v2.css",
    +        "hash": "3a78948e7c871622c19725e46d856e80c48ad06cd17a2505f6bf8e16b12be849"
    +      },
    +      {
    +        "path": "appserver/static/metric_name.js",
    +        "hash": "433ce2d25607e258b9f136372cd30b9bc676bd367afccd6c5891f1329f2861f8"
    +      },
    +      {
    +        "path": "appserver/static/js/dependencies.txt",
    +        "hash": "dbb636397e2c4fa8f3df0e40572ecd5c3cfcf1dd65212a15351d614098ecb124"
    +      },
    +      {
    +        "path": "appserver/static/js/build/309.js.LICENSE.txt",
    +        "hash": "cdf963ced7d25a0f98901a547647b4d6e2dbe0197fd78c87a059a87b0e542fe2"
    +      },
    +      {
    +        "path": "appserver/static/js/build/309.js",
    +        "hash": "de7203eca56051c3126abb4eb62f701a5973f564c5a3500f40dd2aba2c82c47e"
    +      },
    +      {
    +        "path": "appserver/static/js/build/entry_page.js.LICENSE.txt",
    +        "hash": "ac79354148af0505800bc26e5beb1e72966973ba1dc8e67581f78dc7b9dfd010"
    +      },
    +      {
    +        "path": "appserver/static/js/build/656.js",
    +        "hash": "9b058308dde66dbcd2f7bc3ac4b8a9f8af27acb20d89522bd4a849132fb758fc"
    +      },
    +      {
    +        "path": "appserver/static/js/build/globalConfig.json",
    +        "hash": "69b77588db089d0928aec935614857866f379392c693f36a9d369853e3a88a46"
    +      },
    +      {
    +        "path": "appserver/static/js/build/656.licenses.txt",
    +        "hash": "9ce4346733e4c0ebc5d65337914b92ddd69e74c1a6a11ee92f30d7698c5b9d02"
    +      },
    +      {
    +        "path": "appserver/static/js/build/entry_page.js",
    +        "hash": "1969d0e15732c7958d3144897b79111e00eaffa4fa2a337d4e5de58218732c87"
    +      },
    +      {
    +        "path": "appserver/static/js/build/entry_page.licenses.txt",
    +        "hash": "16c7658fe352328091ba594f85ce4ea1b897bbf1321a708d3373dd08ed629d3a"
    +      },
    +      {
    +        "path": "appserver/static/js/build/354.licenses.txt",
    +        "hash": "9ce4346733e4c0ebc5d65337914b92ddd69e74c1a6a11ee92f30d7698c5b9d02"
    +      },
    +      {
    +        "path": "appserver/static/js/build/309.licenses.txt",
    +        "hash": "9ce4346733e4c0ebc5d65337914b92ddd69e74c1a6a11ee92f30d7698c5b9d02"
    +      },
    +      {
    +        "path": "appserver/static/js/build/772.js",
    +        "hash": "6f8df69c44354d79e71a019cee3e5682903303fb7d97aaaee8267836cb2a7423"
    +      },
    +      {
    +        "path": "appserver/static/js/build/895.js",
    +        "hash": "35095d5b26fa10bf47e9bd8a61593810a9fac32ad65834d3a86533bd7ae7d011"
    +      },
    +      {
    +        "path": "appserver/static/js/build/354.js",
    +        "hash": "5858f24895ef6fe6af3312a118279d15c3aace5794b80f3782b0ee96aabe3e6a"
    +      },
    +      {
    +        "path": "appserver/static/octamis_website.css",
    +        "hash": "e9ee36e31b18bc5089dedec7ae3c978fe4e861cc72cda4a904c019d2bb8dff90"
    +      },
    +      {
    +        "path": "appserver/static/ui_simple.css",
    +        "hash": "c56cedc8a12abff882eef61614b8d0006210a8a4fb32cbf003dd6efc5f25df3d"
    +      },
    +      {
    +        "path": "appserver/static/hide_dashboardtitle.css",
    +        "hash": "c46228a54a19636f88e988322c452241f521a904fafb52c5c428b0923600eb22"
    +      },
    +      {
    +        "path": "appserver/static/Nmon_predict.js",
    +        "hash": "57c577b20df81135fa0d5aa915a7a54f87b6f0b8befef28a2f3004952fc6269f"
    +      },
    +      {
    +        "path": "appserver/static/manage_template_alerting_threshold_filesystem_v2.js",
    +        "hash": "5259e540f0995c8c7ab1c8ac97b4c3097e5107bcb51b286ced7b236a63626e29"
    +      },
    +      {
    +        "path": "appserver/static/manage_template_alerting_threshold_v2.js",
    +        "hash": "679445067a499d940b5b18ac79bfc3d9c08ac520a9459b50768b05154f619a37"
    +      },
    +      {
    +        "path": "appserver/static/manage_alerting_threshold_filesystem_table_bar.js",
    +        "hash": "56b5795b6c66b5507ab6181a4c4b674bffa1f1f18e95296dde2d015e99a1372c"
    +      },
    +      {
    +        "path": "appserver/static/diagrams/frameID_mapping.png",
    +        "hash": "3fcf2e90eac845bc2d4b1c4990cf5b0d6c722851a665dec57174528768cd0478"
    +      },
    +      {
    +        "path": "appserver/static/diagrams/threshold_management.png",
    +        "hash": "0aaac30974c1d5b9e91b72d790ab37ae9bd8e6b5789104a7c13b71dae03599e7"
    +      },
    +      {
    +        "path": "appserver/static/custom_layout.js",
    +        "hash": "35d90a40a1d2d3c4df0db4d014d4cd21cf617a5d42532d29cb79395c473d22fa"
    +      },
    +      {
    +        "path": "appserver/static/togglepanel.js",
    +        "hash": "6f4bbb9a88e41d5cf60e961dbde2e1f22c607a2b9828df6e1a73789b8564eb01"
    +      },
    +      {
    +        "path": "appserver/static/manage_alerting_threshold_filesystem_v2.js",
    +        "hash": "3b1ccc00d3da3797dc9c204b05f5a5112bb5abec94ebbf2a9a239c9c69a9cc2f"
    +      },
    +      {
    +        "path": "appserver/static/components/d3/d3.layout.js",
    +        "hash": "d9fe990cde918ef2f214f81a273a6380037b3af4422b6df4f71f6a6a8e55b6fc"
    +      },
    +      {
    +        "path": "appserver/static/components/d3/d3.js",
    +        "hash": "90221a2b30214fa3fa5f34f72fbe979e233307161e1032e7b8c6635384fb15c4"
    +      },
    +      {
    +        "path": "appserver/static/components/d3/bower.json",
    +        "hash": "99450ef15674a4fa5bc3767baabbe844e0609d55a9434c19e4915cc40028f2e9"
    +      },
    +      {
    +        "path": "appserver/static/components/d3/LICENSE",
    +        "hash": "d2d5527321bf2ff32472b7ca6e4ef086427c03c67102984ed06a788df66c4c8b"
    +      },
    +      {
    +        "path": "appserver/static/components/togglepanel/wrapper.js",
    +        "hash": "55eb97d9cc1f9fcef91c9673df5a33e6a3b20f402d5e3238123ff78b99d53d95"
    +      },
    +      {
    +        "path": "appserver/static/components/togglepanel/togglepanel.css",
    +        "hash": "125bdf8f0d5ea938f6707844926c99abe5ee09112a370c79b37ddc5b671fae40"
    +      },
    +      {
    +        "path": "appserver/static/components/togglepanel/LICENSE",
    +        "hash": "bafaa093442ad69a8067ff7e7248bd387c1aa0dae0d11d2970fcb43cc6a92106"
    +      },
    +      {
    +        "path": "appserver/static/components/togglepanel/togglepanel.js",
    +        "hash": "8ef6c1aa878f96f4523bfd26cda4966387bf1f4761d00211a1571c6a36b44724"
    +      },
    +      {
    +        "path": "appserver/static/components/calendarheatmap/calendarheatmap.js",
    +        "hash": "8b2b1933bd73ebc3fdcbcb11c86757a4662adaa93054e5bd8e4836e9e71e67a9"
    +      },
    +      {
    +        "path": "appserver/static/components/calendarheatmap/calendarheatmap.css",
    +        "hash": "ed0f12de076834540100a706c723a86cab36fa173446a29ebfafd0a2e81336a5"
    +      },
    +      {
    +        "path": "appserver/static/components/calendarheatmap/bower.json",
    +        "hash": "b51899e28c65e99f981627c696b2cb2349870fad3589fd0a619e1e7ec25d5e66"
    +      },
    +      {
    +        "path": "appserver/static/components/calendarheatmap/contrib/cal-heatmap.js",
    +        "hash": "c73ad418cb11eb03a35160756abe3e3ec96daa8492930d30bc99f7e7688ceb5c"
    +      },
    +      {
    +        "path": "appserver/static/components/calendarheatmap/contrib/cal-heatmap.css",
    +        "hash": "07c1e1eddba74e2bb26cb781aa613a66af3d1649d82cdc7314c202f4848627b0"
    +      },
    +      {
    +        "path": "appserver/static/components/calendarheatmap/contrib/LICENSE",
    +        "hash": "6650021a7549a5b8057a45e43565e68bc57b5305d63f1c893d3bd58c33ece0b0"
    +      },
    +      {
    +        "path": "appserver/static/components/parallelcoords/bower.json",
    +        "hash": "36ab435e46ccd9ac26d5a3888e7618047b9ea5396c8920015209593829e2b7ea"
    +      },
    +      {
    +        "path": "appserver/static/components/parallelcoords/contrib/d3-parcoords.css",
    +        "hash": "91873b70f299bf82c4fdbc5248aea19142e2d87df734c52349438972b20af52c"
    +      },
    +      {
    +        "path": "appserver/static/components/parallelcoords/contrib/LICENSE",
    +        "hash": "fa1b03525a69570d6ce9dd5a4540a6cff354db32699fc4f294ea82e70633f332"
    +      },
    +      {
    +        "path": "appserver/static/components/parallelcoords/contrib/d3-parcoords.js",
    +        "hash": "bc4a631ca1a4da208a48f9084055817ddc132860b04e5905936da49e3efbd8c0"
    +      },
    +      {
    +        "path": "appserver/static/components/parallelcoords/parallelcoords.js",
    +        "hash": "3720c2d8f4d3fd880c33447e528cf3b975dea60792c19d6d4f0365f904bde8e7"
    +      },
    +      {
    +        "path": "appserver/static/components/sankey/sankey.css",
    +        "hash": "6e952ad1714fd33d157327af1a79cd39a04132d7c1ff6e8a079ab173b6da6478"
    +      },
    +      {
    +        "path": "appserver/static/components/sankey/bower.json",
    +        "hash": "7e127b0871b354b3cd007a15a565635cd814b3a6d699b61fbc8fae39d1ae5aa5"
    +      },
    +      {
    +        "path": "appserver/static/components/sankey/contrib/d3-sankey.js",
    +        "hash": "13afd27edb32fbbcb6b4ab0e78666baf4f2e6d627e656083e3b71f2ca227429f"
    +      },
    +      {
    +        "path": "appserver/static/components/sankey/contrib/LICENSE",
    +        "hash": "d2d5527321bf2ff32472b7ca6e4ef086427c03c67102984ed06a788df66c4c8b"
    +      },
    +      {
    +        "path": "appserver/static/components/sankey/sankey.js",
    +        "hash": "ed1755f2ff42568394bcbec6fb87bd0baf8657d75a584731d5850da526bbba45"
    +      },
    +      {
    +        "path": "appserver/static/components/lib/options.js",
    +        "hash": "9362c1b8447c5469ae49927bccd570f555626f97095b977f66261dcbaf8a77bc"
    +      },
    +      {
    +        "path": "appserver/static/components/lib/utils.js",
    +        "hash": "8e39da88ce92abc449634f0a3946a8a83e076cd08156446e30d0713eb2874ac9"
    +      },
    +      {
    +        "path": "appserver/static/components/srcviewer/codeview.js",
    +        "hash": "fb20cd80f06daf5f4db79c064166ba0b07966e1bcda451c55f3705b9c71db0ae"
    +      },
    +      {
    +        "path": "appserver/static/components/srcviewer/srcviewer.js",
    +        "hash": "4e40872455e46e51d81338e978d6ff7c86544198a30578328c98c57b9c356f93"
    +      },
    +      {
    +        "path": "appserver/static/components/srcviewer/contrib/prettify.js",
    +        "hash": "2ac5aa9c7869a1faafddcf850f706825f649e08c7c54b07558c1184a808b5ed1"
    +      },
    +      {
    +        "path": "appserver/static/components/srcviewer/contrib/showdown.js",
    +        "hash": "9936d1f658aa38c983f06c471ba796c4217b52201119de742a6b83a071d652b2"
    +      },
    +      {
    +        "path": "appserver/static/components/tagcloud/tagcloud.js",
    +        "hash": "521490f6c165061f4bab59895a6dccbd9348e0f2e74db2f07cb150a8fd9d8fcd"
    +      },
    +      {
    +        "path": "appserver/static/components/tagcloud/tagcloud.css",
    +        "hash": "e6b7328d631609c7716715e858324e963867d9f15220436cfc98a3bb7cfd2232"
    +      },
    +      {
    +        "path": "appserver/static/components/bubblechart/bubblechart.js",
    +        "hash": "d06e2be39d3c1cf051fc7d489e43681110e76ed46967a1fc92326207d8896598"
    +      },
    +      {
    +        "path": "appserver/static/components/bubblechart/bubblechart.css",
    +        "hash": "6b5152da9b52c9897e05e51939264d96a80c41fa7698b6d5d0bcf84b3ac0ffbc"
    +      },
    +      {
    +        "path": "appserver/static/components/bubblechart/bower.json",
    +        "hash": "223ed9bfe3cbf086bee2eec0d3ae324b0b30881ccb597c0cab8f1ce756cbae1a"
    +      },
    +      {
    +        "path": "appserver/static/components/scc_takethetour/scc_takethetour.js",
    +        "hash": "33b7d3e40f1bbc868bdc278187861a89330b0d76eeef886fb42be69dfab1ff41"
    +      },
    +      {
    +        "path": "appserver/static/components/scc_takethetour/scc_takethetour.css",
    +        "hash": "9997f8757e3f5bbd72ceebd971fb35ba94c71e55dc4a4972316bf67dbafe0fbe"
    +      },
    +      {
    +        "path": "appserver/static/components/forcedirected/forcedirected.css",
    +        "hash": "1317c46aa1bc710420302d9193b1f0919f14ea7c5933c53b1ee2440fc956065b"
    +      },
    +      {
    +        "path": "appserver/static/components/forcedirected/forcedirected.js",
    +        "hash": "581f93801afadb25e5b16fee1ab46ea1971f6e0088ab3c4d0fe3f0129c928e12"
    +      },
    +      {
    +        "path": "appserver/static/components/forcedirected/bower.json",
    +        "hash": "45a28af2336c0804d245cf47778af98c378df30d45c754857c0a2064bdbcccc0"
    +      },
    +      {
    +        "path": "appserver/static/components/modaltextmsg/modaltextmsg.js",
    +        "hash": "2747b4a4eda76cb113661fed938a7e82796851fcc1988b07e31851ad6ae12506"
    +      },
    +      {
    +        "path": "appserver/static/components/modaltextmsg/modaltextmsg.css",
    +        "hash": "8530480d9883e5bd74c352bf44415243d89a4db3e3899599899ae8fca76bdc6f"
    +      },
    +      {
    +        "path": "appserver/static/components/modaltextmsg/wrapper.js",
    +        "hash": "7d68fd388b814c035831fb9674c5f903c06276e79e948e49d2434a1942baed47"
    +      },
    +      {
    +        "path": "appserver/static/components/modaltextmsg/LICENSE",
    +        "hash": "3ede2a3f4c863436ed874d15a0eb407d050296f59aa2a599c575f0a285600444"
    +      },
    +      {
    +        "path": "appserver/static/components/dendrogram/dendrogram.css",
    +        "hash": "7e91fe2bfa8363188050f5ccfb9b0c5458f356f1b10da90135c8215f01ef7c86"
    +      },
    +      {
    +        "path": "appserver/static/components/dendrogram/dendrogram.js",
    +        "hash": "33e658b77c0633a3064e55598b2b5071a3878fd37d87b4a3da0268cf29bff643"
    +      },
    +      {
    +        "path": "appserver/static/manage_file_systems_exclusion_v2.js",
    +        "hash": "f713277c0a67e22b5e414d32aa8c2721ff9a88fae8790dac941ca05e597b8ac9"
    +      },
    +      {
    +        "path": "appserver/static/various/online_doc.png",
    +        "hash": "28802b9a786c69b66ec8dac9ae01749445439592ec07f41ccb6853c59111d07a"
    +      },
    +      {
    +        "path": "appserver/static/various/mini/single_trend.png",
    +        "hash": "364c52777c36127ff4d26d17bb292cff4d9e6d581a3ac1e6fc67c47f7cd2d79c"
    +      },
    +      {
    +        "path": "appserver/static/various/mini/minisingle.png",
    +        "hash": "ec02bafbdbc256e27d41d39bdd1baf3311842becb19735754fdec4103935d942"
    +      },
    +      {
    +        "path": "appserver/static/various/mini/minitable.png",
    +        "hash": "cc25116147b2e513252d776e9a9a702125aee65e7bb33251fa2ed7bf5bcc5d79"
    +      },
    +      {
    +        "path": "appserver/static/various/mini/minichart.png",
    +        "hash": "46b293b487b73050f40292c62062a33546043b0d20953a2b87792be16e62e84f"
    +      },
    +      {
    +        "path": "appserver/static/various/mini/minicolumn.png",
    +        "hash": "9eac09e304b709a1ae68dba288e2c67b34ef8866ea124990adbae6158559e315"
    +      },
    +      {
    +        "path": "appserver/static/various/mini/minigauge.png",
    +        "hash": "9dc491d6b205bb6e9c7a741e09b27f9e750769dac3913abe75a09c02b1ddceb1"
    +      },
    +      {
    +        "path": "appserver/static/panel_decoration.css",
    +        "hash": "65e0f91a0798b27065e6ffd99276ff94894f89debe2f57003b14d09b9d97a4fd"
    +      },
    +      {
    +        "path": "appserver/static/alerting_threshold.css",
    +        "hash": "5cdec82cf0ae023b95516b80f291d733299df85187de7ddcebe5a30a1e9f3030"
    +      },
    +      {
    +        "path": "appserver/templates/base.html",
    +        "hash": "b28de400d33417f3bdbdeb2804483f823c512b34e1e371cab85a93e16945e49c"
    +      },
    +      {
    +        "path": "default/transforms.conf",
    +        "hash": "dfab063442afbfc90356e94c792ed0be9f56e8f241166b7423eacbe5037d775e"
    +      },
    +      {
    +        "path": "default/app.conf",
    +        "hash": "4e4267f9adc89802f4ca9191bd61ea6762cc380bb9e23eda6df64582eac76108"
    +      },
    +      {
    +        "path": "default/web.conf",
    +        "hash": "8a162eb2773ce05458108b82f4b31375f316c65533d991106a8ebbab78a45d75"
    +      },
    +      {
    +        "path": "default/datamodels.conf",
    +        "hash": "d4f7a8f6f7f82981d7880a537b017561e93b573036a46ecd1c3c88dc21abdb48"
    +      },
    +      {
    +        "path": "default/savedsearches.conf",
    +        "hash": "1acd47e2e6932931890a920438db8d0cdaa1f37da7cc14b71ed3efd6e6ad97b8"
    +      },
    +      {
    +        "path": "default/metricator_for_nmon_settings.conf",
    +        "hash": "7a47958f52594fcfec4c2769b5a8404c731fd2ff1d9d657c9fef2d851d9fcc5b"
    +      },
    +      {
    +        "path": "default/macros.conf",
    +        "hash": "c8ef65930490cfd218b2edc025e49d7b395c04d9bc5aa861697240e7b741999d"
    +      },
    +      {
    +        "path": "default/eventtypes.conf",
    +        "hash": "66cfa9ca9fe2fecce3d1a15692a7fa2dad36df96773050c14316d0977b4ee72b"
    +      },
    +      {
    +        "path": "default/data/ui/views/Howto_MEM_spl.xml",
    +        "hash": "7f95cc495cf0453239b0688bd65b4e11edcd73d4d9e0c23a85dc04675a44f85b"
    +      },
    +      {
    +        "path": "default/data/ui/views/Dashboard_Bubblechart_top_processes.xml",
    +        "hash": "9bed1b4cd79b2c1925f7333e1e57a68020a8738359fcddc9bf167ba34814e415"
    +      },
    +      {
    +        "path": "default/data/ui/views/Howto_LPAR_spl.xml",
    +        "hash": "4990344b7be19b7d58d22184bf10fb47c8c9b5d3b31f98688d24e66ef58e67b7"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_UARG_SOLARIS.xml",
    +        "hash": "a831552e4b9f136f9d5a68fe37f3ae92ac39d2a8bf6b039d071bd137349a92ad"
    +      },
    +      {
    +        "path": "default/data/ui/views/Nmon_baseline.xml",
    +        "hash": "8144355ed7be1b736683bbfae46cd88b6f62a85d19ea48f772acca19752aa386"
    +      },
    +      {
    +        "path": "default/data/ui/views/Nmon_baseline_AIX.xml",
    +        "hash": "adb24dbd2d935a4975844957c9f20666dfcb3b4ada77c4f82120b931fd745a31"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_LPAR_LINUX_poolconso.xml",
    +        "hash": "378bb77a12c9e97ef969d6089c597f3adb0aa9df7c0b7b8453a9d8d4acbd6e2a"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_FILE.xml",
    +        "hash": "123a953fa1a40c16decda7a188c7e8076acbedf6dba02fa5ade4b4456156193e"
    +      },
    +      {
    +        "path": "default/data/ui/views/Nmon_ANALYSER_SOLARIS.xml",
    +        "hash": "aa5c884feaae330fbe2d009ee1924c7d9e53f42c6788aafaacad0ff769d68fdd"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_WLM_AIX.xml",
    +        "hash": "53a195db0a98f950f11db14937026acd1e4b05ccba17a02fd2bf80084a9bd7b9"
    +      },
    +      {
    +        "path": "default/data/ui/views/Home_LINUX.xml",
    +        "hash": "53b939004481b3bfbf2940db80bb6f8fc7d5b59b36afe9f8ed31c9ba164c6af1"
    +      },
    +      {
    +        "path": "default/data/ui/views/Dashboard_WLM_Solaris.xml",
    +        "hash": "1dc741a8cb0e49419947ca3bfecc84f5ae0e16a245394db3dca789cf04466fe4"
    +      },
    +      {
    +        "path": "default/data/ui/views/manage_template_alerting_threshold_v2.xml",
    +        "hash": "9668d41c44a859a22d8faa1521407d548e5539bd4a9f750110f3d5fbf58443dc"
    +      },
    +      {
    +        "path": "default/data/ui/views/manage_alerting_threshold_v2.xml",
    +        "hash": "bcf4ec0c664b01d68b21daed3dcceec8c3323f44323356f70405b516140ff09a"
    +      },
    +      {
    +        "path": "default/data/ui/views/Overview_drilldown_TOP.xml",
    +        "hash": "6d5dcdd949392dcb73624185ceefcee1ee97b25a421c18e29be0cba10c9fa53a"
    +      },
    +      {
    +        "path": "default/data/ui/views/manage_alerting_threshold_filesystem_v2.xml",
    +        "hash": "4cf1563c6857dddbff91f09c9b4367f893a6f855fd3e3d1d859336e4cc92eea5"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_MEMUSE_AIX.xml",
    +        "hash": "1458018b546d8bca33544c6ebd4ab2a429e9e3e873a945795e6834130261ccca"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_DG.xml",
    +        "hash": "f6142ac0d5e54c2de81f669adf316d3374055f7f78f2530a1ce2ca0eda2548b4"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_CONFIG_simple_inventory_AIX.xml",
    +        "hash": "9aa51a839468d9d7f11e9841f3bd90764432e46456266f013d7ed59f2a6f90b7"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_LPAR_AIX_poolconso.xml",
    +        "hash": "7ec7979516838f489152bb49cb04f1b8b4142360d49443329f1aab33196ce4fb"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_STORAGE.xml",
    +        "hash": "dacd95ecd89fca67714b833ec5053e9dfe316d66963b74b269e674dca97dbed8"
    +      },
    +      {
    +        "path": "default/data/ui/views/Dashboard_BubbleChart_top_hosts.xml",
    +        "hash": "98342847b7e657a2f7b3c2ed89374742c971fc737fb1efdc71fe75fc35202f9d"
    +      },
    +      {
    +        "path": "default/data/ui/views/Dashboard_bulletcharts.xml",
    +        "hash": "b469a42f19f5c9a6b2c586d99bdf0f235e11f1fb4d8bc45c57c4fe077cc7f578"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_WLM_SOLARIS.xml",
    +        "hash": "ff87cb12f02452352a35bfd3f2b3aae701da1457a1381793a46574e80ac0d836"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_POOLS.xml",
    +        "hash": "6015c9e8a5bd6f3a0e3fdb6d1dc84711d75b784a007b4f20e3a34a1cd3828a73"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_MEMNEW_AIX.xml",
    +        "hash": "c58e38abcd109653f9c62573cb4adf78b98ee3ab9bbc8bbf7da0179075bc128b"
    +      },
    +      {
    +        "path": "default/data/ui/views/Home_SOLARIS.xml",
    +        "hash": "35ebd73b3ca249434c5ab4d6e8b38dab29e9a112691bd3ed513bc3221dcc3749"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_TOP_SOLARIS.xml",
    +        "hash": "6b6f8318a18bd51df7e018f8296a0b22dae8f0b3e375ae63ffe88dec12ada651"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_CONFIG_simple_inventory.xml",
    +        "hash": "0cf0b29c5ac8937d0d42568cca9eb7b539ccbb154442e48018d7b918bae51049"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_VM_LINUX.xml",
    +        "hash": "22b12de986dffd542dd57c6f19f05b1dd8cc3eac21b0515d00c496bf9e41d398"
    +      },
    +      {
    +        "path": "default/data/ui/views/Nmon_WOF.xml",
    +        "hash": "220349239fb05c94e7f60606eebffe2f0d6a86d49da3fd88a0a51526b64ed21c"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_IOADAPT.xml",
    +        "hash": "5499778e7abc69840c40eb7aa122afe69c739074328687ce9313ac3838bb8c14"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_DISK.xml",
    +        "hash": "cc09a54de8fad171e0e6c5ebc14e085fcebf654d6aa79c76d1775f0b6e9267bf"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_UARG_AIX.xml",
    +        "hash": "df57f0128dded9959853f195f63d2d8966db4262624ed8ebd576a59639ed94db"
    +      },
    +      {
    +        "path": "default/data/ui/views/Dashboard_addons_reporting.xml",
    +        "hash": "52ccee88507e15bcfb2961219bbe40d8ab12afd7ea9ab9e53cc012514ee4f657"
    +      },
    +      {
    +        "path": "default/data/ui/views/Howto_CPU_ALL_spl.xml",
    +        "hash": "24b480263e373358aeff69ae631049e1c57b685e40f7fd17adf5bfef26eaf7fd"
    +      },
    +      {
    +        "path": "default/data/ui/views/Nmon_ANALYSER_LINUX.xml",
    +        "hash": "bf47ae6d54f9bed9191a6b69e03fce3e53f0f52bd6ed5075377b4caa8c50953c"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_VM_SOLARIS.xml",
    +        "hash": "b55c561e16a2cf8a6890bee913aa0b932a39a97a77f92e2b3ef481631541bfc4"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_LPAR_LINUX.xml",
    +        "hash": "3cdadfc116ef0a74030ef342984d51539f9638e2e1c53bf7283cc9df0df025a2"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_LOAD_AVG.xml",
    +        "hash": "0c7e10bc83b491f277e7d4c999f9fcf01d7ca898315197decc148fc6f5352ef0"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_FC.xml",
    +        "hash": "2f08dcccb0d34842fbe519ed31d76d3b1d9c495457a82673c4728fa92be7204b"
    +      },
    +      {
    +        "path": "default/data/ui/views/Nmon_predict.xml",
    +        "hash": "063714be3b668cc2eb8b21207e5860389eae7188c9040e4252da674d87c5f9fa"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_MEM_SOLARIS.xml",
    +        "hash": "ee03d8df04610421090a3e600aa1cfbc3f122ab158db34132e3b7de35d37ccfe"
    +      },
    +      {
    +        "path": "default/data/ui/views/Nmon_Summary.xml",
    +        "hash": "930a83646fc9e5949107fe7622f215c41814a9cdd88b5de85f479466761a4546"
    +      },
    +      {
    +        "path": "default/data/ui/views/Nmon_ANALYSER_AIX.xml",
    +        "hash": "5e4922aa3416eb850d6517bc60afd733a68cf572c379cbb1d3954affca581fee"
    +      },
    +      {
    +        "path": "default/data/ui/views/manage_file_systems_template_exclusion_v2.xml",
    +        "hash": "56ebfe2e7cd690db28a2cc324c07818a325d06d4c2ff060bd23954d40b0eed7a"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_PAGE_AIX.xml",
    +        "hash": "4df22dd63a9ccf195420be2759cbdb7e7b385d32531781f880c056f7f57b8008"
    +      },
    +      {
    +        "path": "default/data/ui/views/Nmon_Dark.xml",
    +        "hash": "658c31d663f4a72b2ece33e355f33bb3c1cbb1e6f25b68fb183f4033ddba227b"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_PROC.xml",
    +        "hash": "cf3874f11bdc3477f6229829593576959971fca3c17a2eb7911483433ec333d1"
    +      },
    +      {
    +        "path": "default/data/ui/views/manage_frameid_mapping_v2.xml",
    +        "hash": "2c088d22270526d25609b3c6ed38189a93bd231fad47ecec8c5911493de3f92d"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_MEM_AIX.xml",
    +        "hash": "9aac5d8fdc1c88c46ac0bb53a42a08c2dbc5a255815f2c3f7dd9bde52404f573"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_CONFIG_simple_inventory_SOLARIS.xml",
    +        "hash": "b1fd6885b6fd6f56d532f47c9cfb49e2a4dc3ddd391337aebd3111f415ec5d41"
    +      },
    +      {
    +        "path": "default/data/ui/views/configuration.xml",
    +        "hash": "589ae0cd8f5b2cba0b4255dd06c94ba7641f00275aa5b2ba18c8f1fefc02910f"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_PROCSOL_SOLARIS.xml",
    +        "hash": "6df87a33e95c4afd985ada29479233cb65c257499726886a63035d4591f9d450"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_CPU_ALL.xml",
    +        "hash": "ec1765ebbcc9a6aaa901482262e0b968a91abc71d0424b712c3292a96f8e5ee4"
    +      },
    +      {
    +        "path": "default/data/ui/views/Nmon_mexplorer.xml",
    +        "hash": "e1fbf11020d82eea4a86d38ae3cf86424ef1b7a1beae01dad44ad7c9c2a8f5f7"
    +      },
    +      {
    +        "path": "default/data/ui/views/manage_template_alerting_threshold_filesystem_v2.xml",
    +        "hash": "177d545296dbe21a5d8d61ee064fd4a54e4b7f8a6a8c2395662161be7dbc1fbe"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_TOP_AIX.xml",
    +        "hash": "c043e2770d8948678f20672ce516f73144c07486c8917ef472ecb67fa8c40b99"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_MEMUSE_SOLARIS.xml",
    +        "hash": "287fa2dd98b275fd6e2e69ceecef1754c79521b010306d053862b99ae9e5cce9"
    +      },
    +      {
    +        "path": "default/data/ui/views/Dashboard_heatmap_daily_usage.xml",
    +        "hash": "c4dcdb77cc5fe9caff652c240f9b9e36636aea3ebfb344ffab8961d639dcce92"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_data_dictionary.xml",
    +        "hash": "2811f515973ffbc3c7bd08654787938cf3af40d5c1bf05cc1ff023fcc5eb9158"
    +      },
    +      {
    +        "path": "default/data/ui/views/Nmon_compare.xml",
    +        "hash": "4a1a784324d28b10c7e63c3d8760d01c1df20312cb37184f8f2d936b537a78c1"
    +      },
    +      {
    +        "path": "default/data/ui/views/Dashboard_uptime.xml",
    +        "hash": "8baaa9b6c9eea2d10173ab0b140ca465b604bc5b03e31ac0cd757e6724064bd1"
    +      },
    +      {
    +        "path": "default/data/ui/views/Home_AIX.xml",
    +        "hash": "da5be91c932181ca03032a294ff79fdf569bb62c42d2b71a0b424358d08c2477"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_LPAR_AIX.xml",
    +        "hash": "13f63a0e320c5f908308f31671cb4a279194bd67cf421750dd2be44a44fc3d0d"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_NET.xml",
    +        "hash": "eb0572cb09c21f3c2e99d3109170e395863a0cc7e20b6207eb5c84388aae2613"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_CONFIG_simple_inventory_LINUX.xml",
    +        "hash": "8a512e4a8bab1b237a0ddf07cbcdb90ac99c0b3f9ecac51a6d734a01a38ad6f8"
    +      },
    +      {
    +        "path": "default/data/ui/views/Dashboard_Internal_Stats.xml",
    +        "hash": "610d091345368b8cfc0ebc14a2e5c7cade1da9ad6a50e3d0324db00302ce0ef5"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_SEA.xml",
    +        "hash": "b78c3a4ad03beebd107381658654c5b8ec45de27e994d9593dcea4694ce5e044"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_CONFIG.xml",
    +        "hash": "b4741dab22db8fe0a9f750e798387831c67f6255219ae57d69c8dea936305aae"
    +      },
    +      {
    +        "path": "default/data/ui/views/Home.xml",
    +        "hash": "2dc4a8199ec2f42a61f9fdc41247ddcf58d7adf98e200fb6f28839499dfbc080"
    +      },
    +      {
    +        "path": "default/data/ui/views/manage_file_systems_global_exclusion_v2.xml",
    +        "hash": "87a1e813daa843da346abd3249382f32bb96db2da676b0c4ae5bfd40395037d1"
    +      },
    +      {
    +        "path": "default/data/ui/views/README",
    +        "hash": "4ccd9dc2dca5bd634f7c07ad1749e4e63a7969c84e2eff83517256f7c884cd29"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_NFS.xml",
    +        "hash": "f1876be13452950429745c56468ba427a46f16d33257b702cddef11e18ee6ce1"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_UARG_LINUX.xml",
    +        "hash": "afe20d58467d38015a524c1c7a9ea86f00a8d920960ec0a860271ed1da33fa19"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_TOP_LINUX.xml",
    +        "hash": "63f63a780f40c0f949f02dfe48ce8e3df68125a0af7906ad1d225768c33546d9"
    +      },
    +      {
    +        "path": "default/data/ui/views/Howto_TOP_spl.xml",
    +        "hash": "910ff4b5b158f74b003490356cc4a25097a0e93b6ed63d1c8e83cfcd7c7e300f"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_MEM_LINUX.xml",
    +        "hash": "cbf5efd18a5ba64a52d45698385300b754f280a360e78ff70cf7f2f836763dcc"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Alert_Center.xml",
    +        "hash": "7699485b696f1ed455dd3ed483428ad495f215c0cb9e9aea3005f2c9246ae049"
    +      },
    +      {
    +        "path": "default/data/ui/views/Overview.xml",
    +        "hash": "81744f83423bba5b4a35f3c8b9faed0a4c756611861dda1efda321845b01c70a"
    +      },
    +      {
    +        "path": "default/data/ui/views/manage_file_systems_exclusion_v2.xml",
    +        "hash": "1da15d6982725e362659479b6e67579a283b91ab840e7f360b3773cb39429b2e"
    +      },
    +      {
    +        "path": "default/data/ui/views/UI_Nmon_CPUnn.xml",
    +        "hash": "af130ffee6e8886efde1c2b8adb495d5f60e028debfc711237699dcdb3e3bb8c"
    +      },
    +      {
    +        "path": "default/data/ui/nav/default.xml",
    +        "hash": "dff4ab7077c0688bea0ba2ba9521a299a1c33a86ab36ecc91c80df64133da77c"
    +      },
    +      {
    +        "path": "default/data/models/metricator-nmon-config.json",
    +        "hash": "bcc99450a73a367c1f8514a67431dc067f7d25c3462e9b575d0df988138fa200"
    +      },
    +      {
    +        "path": "default/data/models/metricator-nmon-processing.json",
    +        "hash": "7da46e8a8f25f63b704cf79dc0e170f7408019448dd64253fad30b2f09875a92"
    +      },
    +      {
    +        "path": "default/restmap.conf",
    +        "hash": "8814a5a4bdc467c4965c83351729a211520b045ae352a5ac88a07dd7bd8b7d0a"
    +      },
    +      {
    +        "path": "default/props.conf",
    +        "hash": "8100d8cde006d4087229e217bb7410b4558e89689bc9d3032d268458a4f83f89"
    +      },
    +      {
    +        "path": "default/collections.conf",
    +        "hash": "b394da415255ae150864a1bea4639ccb8f69c758f3681394de6ef68c05fa2c9a"
    +      },
    +      {
    +        "path": "license.txt",
    +        "hash": "16b42e565a723507298adfca58a3e970f87f1fdde7dc638a02fa320daf918979"
    +      },
    +      {
    +        "path": "static/appIconAlt_2x.png",
    +        "hash": "26800698f9b4e5ee55689ef0daa831e80c33eaaee607383893b8115a3f9c51f7"
    +      },
    +      {
    +        "path": "static/appIcon.png",
    +        "hash": "31917183ab37879d3193eb11733e704346878a9f32aef27c579fb2325fb7d35a"
    +      },
    +      {
    +        "path": "static/appIcon_2x.png",
    +        "hash": "98513bcef00db12f41f9c2313fdfb8dd18b2fd98df2475888b88a244c46e8b39"
    +      },
    +      {
    +        "path": "static/appIconAlt.png",
    +        "hash": "80f428f0a061355c42c5611aeb766293dd94bb3ab1f0f86655ba28e4bdce6411"
    +      },
    +      {
    +        "path": "static/appLogo_2x.png",
    +        "hash": "2eed1600192cfd9b028b2a46a8f1d866cc85962bee16c162b0cd554e6e800d0f"
    +      },
    +      {
    +        "path": "static/appLogo.png",
    +        "hash": "531325b4bab3720a6c3783db1856347dce6ca41ff2e616308735382a2cd7972d"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/__init__.py",
    +        "hash": "6806ff17d65bdb7a5be0d3ba4df21fa8b5cbbdfd4f8e72c104eb8fbd0c0f035f"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/md.cpython-310-x86_64-linux-gnu.so",
    +        "hash": "8ac4f5d751eed08e195f4c341f82f11d06ca5a1a3803a9d87b4a89de5b1292a6"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/legacy.py",
    +        "hash": "5bf2ea0f5dcf8f1c2009171c7110196deeac04d12a1745e6b017ff6bbe53c828"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/api.py",
    +        "hash": "0b84233ba73f30fede8814d72706105a91d021d8a33cc3931635fe3498d0f07b"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/md__mypyc.cpython-310-x86_64-linux-gnu.so",
    +        "hash": "5e3b10d0338ad6f578d6507029ca36b8d1620bc4e15a9555f9d03a443edd4d3e"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/py.typed",
    +        "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/md.py",
    +        "hash": "3173ca3ffa0b6ecb9bba510bff5af171829277915e11fc847cd366e4ee800e97"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/cli/__init__.py",
    +        "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/cli/normalizer.py",
    +        "hash": "43f5e03f2fe01cbc705198e2b5676059b1b709248289e016861e2720d271685b"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/version.py",
    +        "hash": "25edade7ab6346d01caa333336f9d545640cbfd12ddf08cf49db6c07b5f9c201"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/models.py",
    +        "hash": "982d75c28f38974d2eda8d374d1357ecce48b4101b3d428a5e0252171037e466"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/constant.py",
    +        "hash": "3e609ea0a5eaab765b0ad094a4a1f0c05048bfd0d7313fda9f5c9ddb8ab6f260"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/cd.py",
    +        "hash": "da04818d28185dfd0d7b2a6d63c480c12ca22c3fa50e8ac7f36e605401f7885b"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/utils.py",
    +        "hash": "75ac002ed7bf82b1c57ae998ce2629e9d666cd73354a548b1256320bc006f692"
    +      },
    +      {
    +        "path": "lib/charset_normalizer/assets/__init__.py",
    +        "hash": "c2945fba337b189b84139c071e8df0103568279a2fcd1231b089b28a60817c65"
    +      },
    +      {
    +        "path": "lib/defusedxml-0.7.1.dist-info/WHEEL",
    +        "hash": "9064fbe0b5b245466b2f85602e1ebf835d8879597ff6ef5956169dae05d95046"
    +      },
    +      {
    +        "path": "lib/defusedxml-0.7.1.dist-info/top_level.txt",
    +        "hash": "4061daf74179d2954a856485944448d23b522ada83886c9f7995fb750359000c"
    +      },
    +      {
    +        "path": "lib/defusedxml-0.7.1.dist-info/LICENSE",
    +        "hash": "b80ce9da8c42a1f91079627fbbe2bf27210ae108a0ffe5f077d5b08e076c24c8"
    +      },
    +      {
    +        "path": "lib/defusedxml-0.7.1.dist-info/RECORD",
    +        "hash": "e473693c4780fef72b51ddd4930d2c025d6846c77ca4a8b11513434027412367"
    +      },
    +      {
    +        "path": "lib/defusedxml-0.7.1.dist-info/INSTALLER",
    +        "hash": "ceebae7b8927a3227e5303cf5e0f1f7b34bb542ad7250ac03fbcde36ec2f1508"
    +      },
    +      {
    +        "path": "lib/defusedxml-0.7.1.dist-info/METADATA",
    +        "hash": "369d3cef64870daf849fba711cb8d05a7efe3c8d9ab0f763adc34079fe378bb1"
    +      },
    +      {
    +        "path": "lib/urllib3-1.26.14.dist-info/WHEEL",
    +        "hash": "6dbd8eb7db1c7251ca30e2c310763a076b227163a0ba08c529a26c4fbbf0310a"
    +      },
    +      {
    +        "path": "lib/urllib3-1.26.14.dist-info/top_level.txt",
    +        "hash": "10c8972f6b0aad3726accc481d3a9d737113e78a50236634ef62dec4511e9afa"
    +      },
    +      {
    +        "path": "lib/urllib3-1.26.14.dist-info/LICENSE.txt",
    +        "hash": "c37bf186e27cf9dbe9619e55edfe3cea7b30091ceb3da63c7dacbe0e6d77907b"
    +      },
    +      {
    +        "path": "lib/urllib3-1.26.14.dist-info/RECORD",
    +        "hash": "27bc3338aed2398c006d3b8e3618bd46b5866e13d1454613bc84e59513aacb3f"
    +      },
    +      {
    +        "path": "lib/urllib3-1.26.14.dist-info/INSTALLER",
    +        "hash": "ceebae7b8927a3227e5303cf5e0f1f7b34bb542ad7250ac03fbcde36ec2f1508"
    +      },
    +      {
    +        "path": "lib/urllib3-1.26.14.dist-info/METADATA",
    +        "hash": "5f3a69efbd7e9392a629b2768b33aeb6762bee8f10ac2dfb6a9f745e76edd688"
    +      },
    +      {
    +        "path": "lib/solnlib-4.9.1.dist-info/WHEEL",
    +        "hash": "bd50af8dc9b1b9496d7fc718849d2c24c4432ebd57b0fbb110877c603cdbc826"
    +      },
    +      {
    +        "path": "lib/solnlib-4.9.1.dist-info/LICENSE",
    +        "hash": "5efbddf3de03125f255073c478553e61ad7c456ec77362253d3652fdb1371e0b"
    +      },
    +      {
    +        "path": "lib/solnlib-4.9.1.dist-info/RECORD",
    +        "hash": "fd056b1473022bc0b4dcc67ae798d0d5059d82277d0bba1070062c1602cd4813"
    +      },
    +      {
    +        "path": "lib/solnlib-4.9.1.dist-info/INSTALLER",
    +        "hash": "ceebae7b8927a3227e5303cf5e0f1f7b34bb542ad7250ac03fbcde36ec2f1508"
    +      },
    +      {
    +        "path": "lib/solnlib-4.9.1.dist-info/METADATA",
    +        "hash": "481151708550292bc9635329a4f55678a5083a9583d6c05a547899982564387f"
    +      },
    +      {
    +        "path": "lib/splunktalib/__init__.py",
    +        "hash": "5fca22103442714784c18b066bb82b509243ca3c3392fdc712318c4f9c5d79b8"
    +      },
    +      {
    +        "path": "lib/splunktalib/concurrent/__init__.py",
    +        "hash": "4c1d56db6cd8e6ed5df755d2a2cf106b657934c0a980b4e0222576c13e21c776"
    +      },
    +      {
    +        "path": "lib/splunktalib/concurrent/concurrent_executor.py",
    +        "hash": "6a5c84c357edec47da411c03f9a5420d40cfa51b2f8667b54a13e2f98c45bd02"
    +      },
    +      {
    +        "path": "lib/splunktalib/concurrent/process_pool.py",
    +        "hash": "7352e738c7bd943778baba6403cff2f55e81a7d9ad0bbaf1be4fc4d44fcb2553"
    +      },
    +      {
    +        "path": "lib/splunktalib/concurrent/thread_pool.py",
    +        "hash": "d88aa29c02af5254b7444509c72121de3b0ae2a983103acd4c36d6db4cfc0315"
    +      },
    +      {
    +        "path": "lib/splunktalib/splunk_cluster.py",
    +        "hash": "0b1c5b38782b2ae8dbe48a6b7bc28be7c2f736bcf81dd39d7f27eb45d403ead8"
    +      },
    +      {
    +        "path": "lib/splunktalib/credentials.py",
    +        "hash": "7592caf3daee6764615595546a5299caaea584872be33e189706121b9342105e"
    +      },
    +      {
    +        "path": "lib/splunktalib/event_writer.py",
    +        "hash": "b51b0ca62141f0d57bdfb72bd2910c1dcbf34cd65d9e3f18f9bd3d882863047d"
    +      },
    +      {
    +        "path": "lib/splunktalib/timer.py",
    +        "hash": "0d0cb82e22d1cc81eeef88e94cdbbd9b89dce8f1bbfba12b1efb74a11985e556"
    +      },
    +      {
    +        "path": "lib/splunktalib/schedule/__init__.py",
    +        "hash": "4c1d56db6cd8e6ed5df755d2a2cf106b657934c0a980b4e0222576c13e21c776"
    +      },
    +      {
    +        "path": "lib/splunktalib/schedule/scheduler.py",
    +        "hash": "b113c9fb080f5df28e2011437db3d5021db2495b6d6b78aa5a8e6f8e96f91926"
    +      },
    +      {
    +        "path": "lib/splunktalib/schedule/job.py",
    +        "hash": "3f6518271c9013c6547b67aedb21b8f8f74b1feaf7d2aae39a6749c72d3357ab"
    +      },
    +      {
    +        "path": "lib/splunktalib/state_store.py",
    +        "hash": "f8f45deb8e0e5dcdc9b15fa0c4a6c98b3713db92cd6a1ee30485712ebbc483f3"
    +      },
    +      {
    +        "path": "lib/splunktalib/setting.conf",
    +        "hash": "792b0493d7303da57c31440deb768dd360183cd4a11c0a79a5c379bc21b26a7d"
    +      },
    +      {
    +        "path": "lib/splunktalib/kv_client.py",
    +        "hash": "23397c113691c63fd9dd966ee6f0b2caf0de9d4f6bf6badd3a4df314ff45dbc3"
    +      },
    +      {
    +        "path": "lib/splunktalib/timer_queue.py",
    +        "hash": "90c02e7df0b6a227a6ac2badd29e8ce3f72ea5432b1141b1bc0cf7d1ec9b38e4"
    +      },
    +      {
    +        "path": "lib/splunktalib/splunk_platform.py",
    +        "hash": "e6447ceb2d6c1ecb45f9e0b0f3eccfafe28bbd8421dfc6d7b5f58323af9d6c52"
    +      },
    +      {
    +        "path": "lib/splunktalib/conf_manager/__init__.py",
    +        "hash": "4c1d56db6cd8e6ed5df755d2a2cf106b657934c0a980b4e0222576c13e21c776"
    +      },
    +      {
    +        "path": "lib/splunktalib/conf_manager/request.py",
    +        "hash": "5e77dff3c11a8e6d987e24ab9d1dfab45296281fa2c7c4af6f82d8b123429081"
    +      },
    +      {
    +        "path": "lib/splunktalib/conf_manager/conf_manager.py",
    +        "hash": "8d0cbcd734bb3badaa946f22587fa5f74a5ecf5c3b34d72d630e6baa92dcda99"
    +      },
    +      {
    +        "path": "lib/splunktalib/conf_manager/conf_endpoints.py",
    +        "hash": "a0c1bc22024913c20ac2bdbbdcc2bd9a27d87643fc782197943fa2fa32626b46"
    +      },
    +      {
    +        "path": "lib/splunktalib/conf_manager/data_input_endpoints.py",
    +        "hash": "dcf9969c1251abd651b8a771b17cfc47fd3de15b52c65527b325e640298ce10f"
    +      },
    +      {
    +        "path": "lib/splunktalib/conf_manager/ta_conf_manager.py",
    +        "hash": "00ace755b8abfba4d1e1de14fcfa93b9b14f44498906d9efd609b6b2843a33d7"
    +      },
    +      {
    +        "path": "lib/splunktalib/conf_manager/property_endpoints.py",
    +        "hash": "9437e9021275a3366e50f5e4a4e6c96323bc02c5b2da5b9ce972f83313eb7cad"
    +      },
    +      {
    +        "path": "lib/splunktalib/rest.py",
    +        "hash": "2ef3f3c85dd8c470af8b7cd588de70946d2f0e0803101c736ca74b138e037761"
    +      },
    +      {
    +        "path": "lib/splunktalib/file_monitor.py",
    +        "hash": "46d019583fd328947deed30f0fe415285234aca7e631d9f35d65a338ac4a74a9"
    +      },
    +      {
    +        "path": "lib/splunktalib/modinput.py",
    +        "hash": "54c27225081760a0791ee5afcc7ddb556a956e7747c5eefa81beb2ac3233c5b6"
    +      },
    +      {
    +        "path": "lib/splunktalib/orphan_process_monitor.py",
    +        "hash": "0ba84010c5245fcb1a365ccacd343189835cfb42dda43b1e4388f6d56c51a3db"
    +      },
    +      {
    +        "path": "lib/splunktalib/common/__init__.py",
    +        "hash": "4c1d56db6cd8e6ed5df755d2a2cf106b657934c0a980b4e0222576c13e21c776"
    +      },
    +      {
    +        "path": "lib/splunktalib/common/consts.py",
    +        "hash": "a5bd652926a6f2d55e87ac881fa93f5cde9e1593bba128a1ba394f3cae1229a5"
    +      },
    +      {
    +        "path": "lib/splunktalib/common/xml_dom_parser.py",
    +        "hash": "57d6e8ea5d1702bd9a0c266a86ae2b36d02c70a2e1943717696136484964d393"
    +      },
    +      {
    +        "path": "lib/splunktalib/common/util.py",
    +        "hash": "1e5cefa694db4d6a10146b452c4927c24591cdbed67a57d0502be7081acc663f"
    +      },
    +      {
    +        "path": "lib/splunktalib/common/pattern.py",
    +        "hash": "fe3822d6b82d71aa12b6d65313aa552f7ecb1bba135e3fcdd529d5ddc1e1362e"
    +      },
    +      {
    +        "path": "lib/splunktalib/common/log.py",
    +        "hash": "25673eedb51b8087ee930a5cf67cd0606a5e409f560894af055a15406c1a7717"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/__init__.py",
    +        "hash": "2972ff57acc8687ef5234088920007466765dc83459bd344406451176e56eddb"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/global_config/__init__.py",
    +        "hash": "3c87d389623c6e22527609225de372cd8054afaa80d94c0e2260e8ed2d031cf1"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/global_config/schema.py",
    +        "hash": "b6fdd7fbaf5cb9e827b204be36367e76865719b5a3bdfd1855351eaf289ac53e"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/global_config/configuration.py",
    +        "hash": "ed787983063d51761d710b0d902d0becff331775dc994c34ae48d21230eddd0b"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/alert_actions_base.py",
    +        "hash": "004dac77f6165c2f7db2bd60e10afccf322f455d5ea0eb7e6b8a853b460c8fcf"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/__init__.py",
    +        "hash": "e7d3910ef0f5e08fcab1f9b41c2702e9f9d02c97fd299373413ec75e0dd901c6"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/eai.py",
    +        "hash": "b6437249932053f947d998d66267c06709fe5dba6dde1dbd0be2cbe719b62873"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/credentials.py",
    +        "hash": "ef688a70f25a67905d52a23d928f22bff947a8ec0f46dc57af07fdebd63535f0"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/poster.py",
    +        "hash": "4c5b57f727a98540eab1dd2d820d8f4664ffb98a1bfc0bcf32cc2492986d5928"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/handler.py",
    +        "hash": "da7c11949ca66c43ed6ba6167f1692b19e4ea1a419fb8eb874f723989db24595"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/validator.py",
    +        "hash": "a2d0b175a394bdda35c01859185a3b28738591e83d354d326aa9d5bee0a4bf98"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/base.py",
    +        "hash": "fc2f69866047d2b65b7e2c378e65f7e3207ab5d56fa4957eaf32ee3d804c42c5"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/cred_mgmt.py",
    +        "hash": "bde261b5f8271246023f93f157a8bcdbdcaa177165543f860c5c9c06a9095d4c"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/endpoint/__init__.py",
    +        "hash": "a28b42eb2ab0c16bf98fee61928d69a0eb23cb70c117ba480e62154943b0b06e"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/endpoint/validator.py",
    +        "hash": "7290251c6583ccc232e17d13b7e65c2fc8981b1561ae86dd4af9ca639f2a8e92"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/endpoint/field.py",
    +        "hash": "0a3aa70e7a7c671fdf252a63383980ae352d800aae5e204570dbde9d9862dd09"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/endpoint/converter.py",
    +        "hash": "0fc9f55967835f8e90dc69f1937cc14ed09831e0dd58cb381cd97c6870027a1c"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/error_ctl.py",
    +        "hash": "9aa4b3293261625056cbb3d0e47ab4f990b522bb6369d0b8b7ccd9b0951b5e17"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/teardown.py",
    +        "hash": "b2847d29442f9e5e6041c3acbc47d52dbe5bf90f9b1c2d89d24348e60e20e016"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/util.py",
    +        "hash": "3956555ed38604eca36eba24313d932934fcd3e71e4f09eaeabec8e6c24c36ab"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/base_hook_mixin.py",
    +        "hash": "f3194de1ca0b33ae0e6fc19feb60b7734340f7adea1f4f100461b6e4283bf29c"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/entity.py",
    +        "hash": "da53a3218582820e551cb6870dd36653dd15dd12739408822694883343ef1ae9"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/datainput.py",
    +        "hash": "eb9215063a1c78c87b99f952ea487493c2a09d390001e3015089d34202c5a1b6"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/error.py",
    +        "hash": "bfca17f10f4bfac850eb2d423f8447298a9b1151574a15c530df972696d6fa93"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/normaliser.py",
    +        "hash": "3677fe302dc9dff58620e09bcee1237619545f7d4e932d53223705007acf141e"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/multimodel.py",
    +        "hash": "f59b71a2dee7ca96b6fe13566b68cf1444c1bac26567e52769dc702c3fbbe181"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/schema.py",
    +        "hash": "eb680825d60e5954a7a1804b454aec52d0ec0567c34ff9f0b22143fc5b81427d"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/rest_handler/admin_external.py",
    +        "hash": "ce85da90de5134ed076edacd3acb55c514550af4527d26cda6d58aa44d625256"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/data_collection/__init__.py",
    +        "hash": "4c1d56db6cd8e6ed5df755d2a2cf106b657934c0a980b4e0222576c13e21c776"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/data_collection/ta_data_loader.py",
    +        "hash": "7b54594a60af77bf366b9bd2e5014d5d0b809d5609a3a7b370eb54097c44e148"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/data_collection/ta_config.py",
    +        "hash": "ef5a05072dfae1996129eeb999d2bef0fd568212e8cfadd7cf1ba4c4999483f7"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/data_collection/ta_data_client.py",
    +        "hash": "eb5e2c5694647f4ccaf6d3ab52e47e3a9fa36ea9dc7171bfe332330ff58b12fb"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/data_collection/ta_mod_input.py",
    +        "hash": "7c984a16494f9ecd81846fb38e5f6da7419b86b6018c01c0238592c7e219029a"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/data_collection/ta_data_collector.py",
    +        "hash": "8d148de69a746f524bac0c7477b12bd5c6dcc0b68c752877bb51e19cc53499b9"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/data_collection/ta_checkpoint_manager.py",
    +        "hash": "56942763897a2505b42f0d6af4185a8480d74b7d1caef7133387d0e957f7c631"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/data_collection/ta_consts.py",
    +        "hash": "01390241fa1bc0be1d77cc02fe6762ae7f972946c77a5e45454fa8f4e3dc1039"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/data_collection/ta_helper.py",
    +        "hash": "e50fdea497e605dd56b5758052a065738c96540d21db2a5090e2cc79421bcb13"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/modinput_wrapper/__init__.py",
    +        "hash": "4c1d56db6cd8e6ed5df755d2a2cf106b657934c0a980b4e0222576c13e21c776"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/modinput_wrapper/base_modinput.py",
    +        "hash": "7535011add7c0b98246a027b22f96bddfec68a8bdf12048c6e9e4821afa3499b"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/cim_actions.py",
    +        "hash": "c5ca32e91e3eb7de8c50fa7ffc1130ce4749446293bf14fa0f00956830e5bad0"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/config.py",
    +        "hash": "ebd003726d21834c5850a490c05bc2ce2a15b41d9438e485f8e8cfd66135f0c1"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/splunk_aoblib/__init__.py",
    +        "hash": "4c1d56db6cd8e6ed5df755d2a2cf106b657934c0a980b4e0222576c13e21c776"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/splunk_aoblib/rest_helper.py",
    +        "hash": "6cf0955a7865325fa2a3ae17297cd33343a960d86d1135123c3ef80306aaf0f7"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/splunk_aoblib/setup_util.py",
    +        "hash": "8cc99cefe62f3d9ec6cde3bd1d7d85938d304484c81673be33c3abdb5d937b97"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/splunk_aoblib/rest_migration.py",
    +        "hash": "c4b3c0d44bfdc4f91b5f28245c9d90fb37d819e963979f4c188eb2f9bab3bc64"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/splunk_aoblib/utility.py",
    +        "hash": "8fdcf7a6f4468109e61fd4523a08014b545cb6fe6514d4c3e3c11ba8aaf110d8"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/common/__init__.py",
    +        "hash": "a0cee7e5d7abc1d9e27c6e1fa6e7dc06114b5eef4db4b4110518daab91d44928"
    +      },
    +      {
    +        "path": "lib/splunktaucclib/common/log.py",
    +        "hash": "a1570c4f23cfc0089b608c8b9608b64a040c93ee4d6e9825451385219476ab15"
    +      },
    +      {
    +        "path": "lib/splunktalib-3.0.3.dist-info/WHEEL",
    +        "hash": "bd50af8dc9b1b9496d7fc718849d2c24c4432ebd57b0fbb110877c603cdbc826"
    +      },
    +      {
    +        "path": "lib/splunktalib-3.0.3.dist-info/LICENSE",
    +        "hash": "50e4396113babce2d3793aa6e5ececc4861e5209627b28b3fb89628005487d92"
    +      },
    +      {
    +        "path": "lib/splunktalib-3.0.3.dist-info/RECORD",
    +        "hash": "04cc9dfa08414598b6709aa82c97ec3f6c2cbc5e6de38b178ee4a8fab0a4c874"
    +      },
    +      {
    +        "path": "lib/splunktalib-3.0.3.dist-info/INSTALLER",
    +        "hash": "ceebae7b8927a3227e5303cf5e0f1f7b34bb542ad7250ac03fbcde36ec2f1508"
    +      },
    +      {
    +        "path": "lib/splunktalib-3.0.3.dist-info/METADATA",
    +        "hash": "683c2cb54d2954e2591881fec2ddabe1d99fd4264d08133e9f471224716f4c82"
    +      },
    +      {
    +        "path": "lib/PySocks-1.7.1.dist-info/WHEEL",
    +        "hash": "b7f329029bf7f3afbc3d5b6cd91eb0b1389f7489f4bdb5034d5bfad486ea142f"
    +      },
    +      {
    +        "path": "lib/PySocks-1.7.1.dist-info/top_level.txt",
    +        "hash": "4ca48e21f0850682bd118f050586d8a82dcf59ddfef86d79a61f67f3e4073c39"
    +      },
    +      {
    +        "path": "lib/PySocks-1.7.1.dist-info/LICENSE",
    +        "hash": "7027e214e014eb78b7adcc1ceda5aca713a79fc4f6a0c52c9da5b3e707e6ffe9"
    +      },
    +      {
    +        "path": "lib/PySocks-1.7.1.dist-info/RECORD",
    +        "hash": "ff951b4589e4f8c29ce528f59a202ca46632e33cc90a45facb862d7d2005cc0d"
    +      },
    +      {
    +        "path": "lib/PySocks-1.7.1.dist-info/INSTALLER",
    +        "hash": "ceebae7b8927a3227e5303cf5e0f1f7b34bb542ad7250ac03fbcde36ec2f1508"
    +      },
    +      {
    +        "path": "lib/PySocks-1.7.1.dist-info/METADATA",
    +        "hash": "cdb40c8b38cf38e3f80e1122117db85d78cdad8b88c45f54194a4dd2e14307a6"
    +      },
    +      {
    +        "path": "lib/requirements.txt",
    +        "hash": "b0ad9be672ffaf818676aa1ce24488c877289f4a5e3b65f0a2d74a8912c673a0"
    +      },
    +      {
    +        "path": "lib/requests-2.28.2.dist-info/WHEEL",
    +        "hash": "db07a93359e4e034b8785a58ad6d534ea3dca0635f1e184efe2e66e1c3a299ba"
    +      },
    +      {
    +        "path": "lib/requests-2.28.2.dist-info/top_level.txt",
    +        "hash": "7cc4959877dbe6b6c63a8eb1bfe3bfb545fa8fe5b28b1b2c13e4a7c1c0d1c4d4"
    +      },
    +      {
    +        "path": "lib/requests-2.28.2.dist-info/LICENSE",
    +        "hash": "09e8a9bcec8067104652c168685ab0931e7868f9c8284b66f5ae6edae5f1130b"
    +      },
    +      {
    +        "path": "lib/requests-2.28.2.dist-info/RECORD",
    +        "hash": "b9c19a242654d7feae8405eb91dc0f3aa6334cc92bb07769ba3c79c3afce2aa2"
    +      },
    +      {
    +        "path": "lib/requests-2.28.2.dist-info/INSTALLER",
    +        "hash": "ceebae7b8927a3227e5303cf5e0f1f7b34bb542ad7250ac03fbcde36ec2f1508"
    +      },
    +      {
    +        "path": "lib/requests-2.28.2.dist-info/METADATA",
    +        "hash": "ef5eb88ec1593772e587f9d7fe8051a9eb654dd7142d10638e7425cebb67e98d"
    +      },
    +      {
    +        "path": "lib/defusedxml/__init__.py",
    +        "hash": "45ccde695246eb8a76160cb58e50b36ee45d72110f9c468206bc6093c249fe93"
    +      },
    +      {
    +        "path": "lib/defusedxml/sax.py",
    +        "hash": "f92174f0cb1cda6584600330eb6a49e4533059c70e72d1529d0c032d82cb9551"
    +      },
    +      {
    +        "path": "lib/defusedxml/lxml.py",
    +        "hash": "1d6f8b14a76b7cc4731dd8b455cb9cab8fa7f32cfbbff390c04416160d494180"
    +      },
    +      {
    +        "path": "lib/defusedxml/ElementTree.py",
    +        "hash": "18b4aaa42cf9f285c63c6cb37ff1f296c3d2f7f75c1953f948de1d2bbcafc8fc"
    +      },
    +      {
    +        "path": "lib/defusedxml/expatreader.py",
    +        "hash": "28ea52af0912be3e5218e63da535ce336e839f3d34aec26ddf75ae795bf3a6f7"
    +      },
    +      {
    +        "path": "lib/defusedxml/common.py",
    +        "hash": "ddddba8cd5b87cd5f38235a1bd47ecf3701f8b3e44571143ba941bba09123197"
    +      },
    +      {
    +        "path": "lib/defusedxml/cElementTree.py",
    +        "hash": "3e968a321deb536f6c63c6a600ae1fcc740a97c81c0180f48752c2a16eb646d9"
    +      },
    +      {
    +        "path": "lib/defusedxml/pulldom.py",
    +        "hash": "0d88f60f695cef1a31677f207f3ba35e67739ddf28bf30ea1855eac976edc639"
    +      },
    +      {
    +        "path": "lib/defusedxml/minidom.py",
    +        "hash": "dd0720ca057026a7160d0dc86768a897ccec1f8731dc1457ef448f71dd1b1b68"
    +      },
    +      {
    +        "path": "lib/defusedxml/expatbuilder.py",
    +        "hash": "6f8434e6fb01309e52b6489315fe26cb6ac61a8d60672125fe10b931e1533800"
    +      },
    +      {
    +        "path": "lib/defusedxml/xmlrpc.py",
    +        "hash": "eeb6507b2deda9771cd61aeb337469ace20253a7e2167cbd07d9789e64e2a310"
    +      },
    +      {
    +        "path": "lib/splunktaucclib-6.0.7.dist-info/WHEEL",
    +        "hash": "bd50af8dc9b1b9496d7fc718849d2c24c4432ebd57b0fbb110877c603cdbc826"
    +      },
    +      {
    +        "path": "lib/splunktaucclib-6.0.7.dist-info/REQUESTED",
    +        "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    +      },
    +      {
    +        "path": "lib/splunktaucclib-6.0.7.dist-info/LICENSE",
    +        "hash": "300a09380aff55e81cdaec9de51c9a48d9234592f8a7722d34ec26eac83d3d27"
    +      },
    +      {
    +        "path": "lib/splunktaucclib-6.0.7.dist-info/RECORD",
    +        "hash": "5ed3eda89feb6631e3263e1b37a6b7fa53cc08eb6a18cc8cb63b02acf6455b94"
    +      },
    +      {
    +        "path": "lib/splunktaucclib-6.0.7.dist-info/INSTALLER",
    +        "hash": "ceebae7b8927a3227e5303cf5e0f1f7b34bb542ad7250ac03fbcde36ec2f1508"
    +      },
    +      {
    +        "path": "lib/splunktaucclib-6.0.7.dist-info/METADATA",
    +        "hash": "fd75148773d69fb9e26c07329671126fa43020d81a5cd81ab3b597c4754ab742"
    +      },
    +      {
    +        "path": "lib/charset_normalizer-3.0.1.dist-info/WHEEL",
    +        "hash": "00434f530b9373aa81f7932b9f9241e5ba177a05b0ea80e1bb0bae5f4abf38d8"
    +      },
    +      {
    +        "path": "lib/charset_normalizer-3.0.1.dist-info/top_level.txt",
    +        "hash": "ec04b2cde3ebf3fc6e65626c9ea263201b7257cbe1128d30042bf530f4518b74"
    +      },
    +      {
    +        "path": "lib/charset_normalizer-3.0.1.dist-info/entry_points.txt",
    +        "hash": "b98a3c68818b5aff188167d29dae479df63f127e29905d70e1b81ac0d017ccfd"
    +      },
    +      {
    +        "path": "lib/charset_normalizer-3.0.1.dist-info/LICENSE",
    +        "hash": "eb31a0c5a4fb09b8a4e32055d25c1e5f9c358a2752fef3cd720213d1ccfee241"
    +      },
    +      {
    +        "path": "lib/charset_normalizer-3.0.1.dist-info/RECORD",
    +        "hash": "023237fe388d6e61ed0a06ebd8e0144ec206cadc8528bf21085ec167b8ea6ae4"
    +      },
    +      {
    +        "path": "lib/charset_normalizer-3.0.1.dist-info/INSTALLER",
    +        "hash": "ceebae7b8927a3227e5303cf5e0f1f7b34bb542ad7250ac03fbcde36ec2f1508"
    +      },
    +      {
    +        "path": "lib/charset_normalizer-3.0.1.dist-info/METADATA",
    +        "hash": "81d82100b00385775ecc8abc6bcbc31ef183bb2246afcecba36c57ec24b50d42"
    +      },
    +      {
    +        "path": "lib/splunklib/__init__.py",
    +        "hash": "35602eef50003277b344450a6d4d6159bb9fc0d034c2cd51f493b42258165e8c"
    +      },
    +      {
    +        "path": "lib/splunklib/client.py",
    +        "hash": "c4da969aa7253b70d69fc90b443b46a18d4ad6f6a562fde365f9a7335dbceee2"
    +      },
    +      {
    +        "path": "lib/splunklib/searchcommands/__init__.py",
    +        "hash": "561e00361094a620ad9993b196e4f0267dcd817afdb1b2bf98cab0f8df4807e2"
    +      },
    +      {
    +        "path": "lib/splunklib/searchcommands/environment.py",
    +        "hash": "997e76b662628010e782e22bcefccc1c5bbd5f2b039068ba58d9791ae50a293b"
    +      },
    +      {
    +        "path": "lib/splunklib/searchcommands/validators.py",
    +        "hash": "074bf043dad896e02932536b71099a8dd1f16a6f9c5e0d0a096b7dab7bab5fee"
    +      },
    +      {
    +        "path": "lib/splunklib/searchcommands/streaming_command.py",
    +        "hash": "aa45695ec34a4125a84c4d592ca26f2bb68f14743274f163f533ffc7bc0b9ed7"
    +      },
    +      {
    +        "path": "lib/splunklib/searchcommands/reporting_command.py",
    +        "hash": "40537218ef844255b4d41c44130e5cec95a1e0801f866dbd4a500a8237edbb26"
    +      },
    +      {
    +        "path": "lib/splunklib/searchcommands/eventing_command.py",
    +        "hash": "471cbcf2e07de71150d86ab853b7b8e51a1cfb31913355f6cdd7c821b44d87e2"
    +      },
    +      {
    +        "path": "lib/splunklib/searchcommands/internals.py",
    +        "hash": "0962779efe5aeb0595a08eb19f9d1832cd4b192d01b3336d2afd3e037b1f308f"
    +      },
    +      {
    +        "path": "lib/splunklib/searchcommands/search_command.py",
    +        "hash": "70cb1ffee5324beb93c2270034df96a7815f3a104cb7c2e5463e1f516b06e3b4"
    +      },
    +      {
    +        "path": "lib/splunklib/searchcommands/generating_command.py",
    +        "hash": "f77c701ed408454225c5d1b6ba126fc64ea89a9e1210b79f33cc2ab1f2a95cd1"
    +      },
    +      {
    +        "path": "lib/splunklib/searchcommands/decorators.py",
    +        "hash": "c764c5209bb2c7cfeb162e0ad967fa60a8c6f2d66e0f7959d57e394da472078d"
    +      },
    +      {
    +        "path": "lib/splunklib/searchcommands/external_search_command.py",
    +        "hash": "9a5fbfe2a301671fccd0e62209ebc076945904b1bf8a1ee94d1b261256e7d9ad"
    +      },
    +      {
    +        "path": "lib/splunklib/data.py",
    +        "hash": "4e4b05736b6b176fd4397a2c42ef66760abccbbb06dbefd95a6165767454f8ae"
    +      },
    +      {
    +        "path": "lib/splunklib/six.py",
    +        "hash": "919fb50a0bd07fe1c319d98aab1cd69fd5140a43e42b50a07a5e5c91c8fec687"
    +      },
    +      {
    +        "path": "lib/splunklib/binding.py",
    +        "hash": "3da2e59beb3f50a83ab6dad92b80c083ee347b6bb9e4594173c239d730c0c59c"
    +      },
    +      {
    +        "path": "lib/splunklib/results.py",
    +        "hash": "26ee1959bc4bbff7ce1ad8e7b3b59c1a442efc2c2c95a9a7ca239e8f800621a9"
    +      },
    +      {
    +        "path": "lib/splunklib/modularinput/__init__.py",
    +        "hash": "6c7c88d29dc6b41a008db14211bb9489b1052b09c70f267364ec12e05bedd33b"
    +      },
    +      {
    +        "path": "lib/splunklib/modularinput/argument.py",
    +        "hash": "386603096d45c3b3ec3328317adc334c7d981a6d5f77312b657c5463207e58d5"
    +      },
    +      {
    +        "path": "lib/splunklib/modularinput/validation_definition.py",
    +        "hash": "a2b0f857f8589a9c6db87b2ffc685c3e785c183a079ca31253e2928539940b02"
    +      },
    +      {
    +        "path": "lib/splunklib/modularinput/event_writer.py",
    +        "hash": "44bdfc53d3dd90c0f584bad1dd74a5e6775916f83265e4858998c3bf07f506b0"
    +      },
    +      {
    +        "path": "lib/splunklib/modularinput/input_definition.py",
    +        "hash": "444fd09df04b5c0d8985d12c86f7255734c129ca6963f92d43494e0251943cd7"
    +      },
    +      {
    +        "path": "lib/splunklib/modularinput/event.py",
    +        "hash": "c55fa7dfc338c4553c381def713feef1c965586068e411c658d6174dc7c93889"
    +      },
    +      {
    +        "path": "lib/splunklib/modularinput/scheme.py",
    +        "hash": "c25945b449d5f74318f4536b3d1dcea0885dcd55386e5685ece35a11c2f77a44"
    +      },
    +      {
    +        "path": "lib/splunklib/modularinput/utils.py",
    +        "hash": "634fa07eab5a3a98506bb2c94cf3a6070b56c1a47fd86d976597a6964429c161"
    +      },
    +      {
    +        "path": "lib/splunklib/modularinput/script.py",
    +        "hash": "61933b50a205b8b924365765180b64f077dbc33675d6e7afd0883cbec315196a"
    +      },
    +      {
    +        "path": "lib/sockshandler.py",
    +        "hash": "d926068fea70b7592380ba19026c9e6845c27990d64667d54bf406ea412b1ad6"
    +      },
    +      {
    +        "path": "lib/idna-3.4.dist-info/WHEEL",
    +        "hash": "e137ca201ff1bbed386dcda22b3ebfcc5b7e80414410353fdf51c686acce084f"
    +      },
    +      {
    +        "path": "lib/idna-3.4.dist-info/LICENSE.md",
    +        "hash": "a2d6e4d940bd24dbe7b9645cde19a9792cc51db7ae0d5acd301ac860caa3e836"
    +      },
    +      {
    +        "path": "lib/idna-3.4.dist-info/RECORD",
    +        "hash": "0b17d9ef7f304e699628858386eb58a15589bb1b4abacf4233aa6939f2dc3d49"
    +      },
    +      {
    +        "path": "lib/idna-3.4.dist-info/INSTALLER",
    +        "hash": "ceebae7b8927a3227e5303cf5e0f1f7b34bb542ad7250ac03fbcde36ec2f1508"
    +      },
    +      {
    +        "path": "lib/idna-3.4.dist-info/METADATA",
    +        "hash": "f1a2d27fd3054bba01dbaa59876869ae0ede269d1425273edeba5ffdebe9e030"
    +      },
    +      {
    +        "path": "lib/idna/__init__.py",
    +        "hash": "28940dd5e401afc8882b948aac9e3b957bf11b4049ecb9b7f16e334f4bfff259"
    +      },
    +      {
    +        "path": "lib/idna/uts46data.py",
    +        "hash": "cef8d9536e2ce7cfee012f39d0c71dd0d9c3d17eff802300323cd634879425d7"
    +      },
    +      {
    +        "path": "lib/idna/codec.py",
    +        "hash": "ea5cb9a1d29faabcad293f7fed4ae51a49479dfd4348adabf42e9c48ce2c6b6f"
    +      },
    +      {
    +        "path": "lib/idna/core.py",
    +        "hash": "d49c5c8702b39310529fb47fa02135da806edde56ec74573771a2598869ddb83"
    +      },
    +      {
    +        "path": "lib/idna/py.typed",
    +        "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    +      },
    +      {
    +        "path": "lib/idna/package_data.py",
    +        "hash": "0bf8c7273997f0f238c6ad23a7399c4ccc696f9943b2ae28e55cb1433955ad91"
    +      },
    +      {
    +        "path": "lib/idna/idnadata.py",
    +        "hash": "c548ea2aa88957c1e8fd7cc1a40b6fe4916854f4aea4af92517bed8f28141eac"
    +      },
    +      {
    +        "path": "lib/idna/intranges.py",
    +        "hash": "601af87d162e587ee44ca4b6b579458ccdb8645d4f76f722afe6b2c278889ea8"
    +      },
    +      {
    +        "path": "lib/idna/compat.py",
    +        "hash": "d3fb0e114313e02570f5da03defc91857f345f5f4fc2a168501b3b816b05304e"
    +      },
    +      {
    +        "path": "lib/certifi/__init__.py",
    +        "hash": "6cafe79bd6cb27336f599736a197624f08362960f81d23c158668cd33503bccc"
    +      },
    +      {
    +        "path": "lib/certifi/__main__.py",
    +        "hash": "c410688fdd394d45812d118034e71fee88ba7beddd30fe1c1281bd3b232cd758"
    +      },
    +      {
    +        "path": "lib/certifi/core.py",
    +        "hash": "9617b0cf4cc56f66f850bb10bab1259a5a18c10a1e7235b33ea63aecff13ee23"
    +      },
    +      {
    +        "path": "lib/certifi/py.typed",
    +        "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    +      },
    +      {
    +        "path": "lib/certifi/cacert.pem",
    +        "hash": "2c11c3ce08ffc40d390319c72bc10d4f908e9c634494d65ed2cbc550731fd524"
    +      },
    +      {
    +        "path": "lib/sortedcontainers-2.4.0.dist-info/WHEEL",
    +        "hash": "9064fbe0b5b245466b2f85602e1ebf835d8879597ff6ef5956169dae05d95046"
    +      },
    +      {
    +        "path": "lib/sortedcontainers-2.4.0.dist-info/top_level.txt",
    +        "hash": "015b34abea9ffb5d20b35b645617c02dd79b268e2e3ee555057ed84fdd6b8905"
    +      },
    +      {
    +        "path": "lib/sortedcontainers-2.4.0.dist-info/LICENSE",
    +        "hash": "1db7cae7fce6452e2e608e401a0f953e0133e4c2d75db69fb8ae851d2086f5b6"
    +      },
    +      {
    +        "path": "lib/sortedcontainers-2.4.0.dist-info/RECORD",
    +        "hash": "06b90d6d0c9eaad9c80967dc80cb21ef454276ba6fe4e5a5482f0ca9c89fd5df"
    +      },
    +      {
    +        "path": "lib/sortedcontainers-2.4.0.dist-info/INSTALLER",
    +        "hash": "ceebae7b8927a3227e5303cf5e0f1f7b34bb542ad7250ac03fbcde36ec2f1508"
    +      },
    +      {
    +        "path": "lib/sortedcontainers-2.4.0.dist-info/METADATA",
    +        "hash": "eedf115109e215001e904da0882851beae50b03c0b0161a8b9e74b7cfd679473"
    +      },
    +      {
    +        "path": "lib/sortedcontainers/__init__.py",
    +        "hash": "5ff5f92ee463bdeefb2b0b8942b0d44aed13f39e7d61ca28c106c09e3b8ced31"
    +      },
    +      {
    +        "path": "lib/sortedcontainers/sortedlist.py",
    +        "hash": "af003574cf1c7b4f5e6f60cc8cb39f1e88a4842c7f45f9399ee13f352b1faf72"
    +      },
    +      {
    +        "path": "lib/sortedcontainers/sortedset.py",
    +        "hash": "e51236094246326d62837f9d85b3abcc397c68fa8378f92824f428ab444e4bb3"
    +      },
    +      {
    +        "path": "lib/sortedcontainers/sorteddict.py",
    +        "hash": "cdae4b9c43593063c89ff25912bd12d2d0d77c4b3126c7c49da9e1ea52e54d93"
    +      },
    +      {
    +        "path": "lib/requests/__init__.py",
    +        "hash": "c57d2b2c6be8963b731bca0317e658b939602ff05080aa31519d5eddca4d1d7f"
    +      },
    +      {
    +        "path": "lib/requests/packages.py",
    +        "hash": "0d782ff852487336484e6bf4bc40408568f85bee4218220dfe4b2f811d7b0efb"
    +      },
    +      {
    +        "path": "lib/requests/help.py",
    +        "hash": "80f5f977f1fb5ddf3c6830017a386a1a097d075545453b79066898bcbdcfcc84"
    +      },
    +      {
    +        "path": "lib/requests/adapters.py",
    +        "hash": "b049c71a5e26273e101c14fc8c6e9b53968f8a752d7681f7048b802334fe5fbe"
    +      },
    +      {
    +        "path": "lib/requests/_internal_utils.py",
    +        "hash": "6923e5178b8386d7cac446b264927b2a4031b68ae67937e9c0a4814b0b66014c"
    +      },
    +      {
    +        "path": "lib/requests/exceptions.py",
    +        "hash": "0e1bde1417255634d1c6145db95a4ef866cc60c203da09a374b7cd12a36923f5"
    +      },
    +      {
    +        "path": "lib/requests/auth.py",
    +        "hash": "87e1cb955c7d8fcaca57985f480c9c3f60293928254f3efb474b73eea09b6c41"
    +      },
    +      {
    +        "path": "lib/requests/__version__.py",
    +        "hash": "878f339fea05ba4697ad81e871d69da7f848b335b277f3c6ad2f048a28ba6a87"
    +      },
    +      {
    +        "path": "lib/requests/api.py",
    +        "hash": "772be40dde62b42f73da0d301e5fd87c3d727fa630a4658b3bbffff1edb59e4b"
    +      },
    +      {
    +        "path": "lib/requests/sessions.py",
    +        "hash": "294a8971144ba2f35e7d4b3b49c39749454271f49ac93156b5b889ee03929532"
    +      },
    +      {
    +        "path": "lib/requests/hooks.py",
    +        "hash": "0a2bb2b221c0dfd57951f702057148c7cdc8ac3a6ec1f37d45c4d482fdbc7ed4"
    +      },
    +      {
    +        "path": "lib/requests/status_codes.py",
    +        "hash": "16f1e64f9b87fbfba29ad473e611fd5426eded557e35e8b627dba96de8fa8fc8"
    +      },
    +      {
    +        "path": "lib/requests/cookies.py",
    +        "hash": "903de43447028fe9b16ed7f97c9b12693f3a786a046290f75f4092829ce5ec13"
    +      },
    +      {
    +        "path": "lib/requests/structures.py",
    +        "hash": "f886e6855cf4e92fb968f499b94b6167afba0fd5ce8d1b935c739a6d8d38d573"
    +      },
    +      {
    +        "path": "lib/requests/certs.py",
    +        "hash": "67d49be35d009efea35054f2b2cd23145854eb1b2df1cb442ea7f2f04bf6de0c"
    +      },
    +      {
    +        "path": "lib/requests/models.py",
    +        "hash": "f8394a8b4a2bf2014033a573bada1b5efbc15bfdb0ac9b8e17935f9dd4c875d0"
    +      },
    +      {
    +        "path": "lib/requests/utils.py",
    +        "hash": "e7fc2cf9bb0a23d10797b8f6ef28bee871733c12ae96d3e077b1df3eb513a162"
    +      },
    +      {
    +        "path": "lib/requests/compat.py",
    +        "hash": "cb19ed54e4841c632b9fb14daffdf61046a6d5934074f45d484d77ff2687cd39"
    +      },
    +      {
    +        "path": "lib/urllib3/__init__.py",
    +        "hash": "8972dc6222724a7d0635b58e3990c30298012f52603f8e0467c8b5efad12f0c7"
    +      },
    +      {
    +        "path": "lib/urllib3/request.py",
    +        "hash": "645488a97d02e968b38b179c0a1677fe8932bbb044bf4959bb5553d2cea1e123"
    +      },
    +      {
    +        "path": "lib/urllib3/util/__init__.py",
    +        "hash": "2449929a6aaa2f26b0f0fe75814226661f06c20f62d7349ef83a2a022b67da77"
    +      },
    +      {
    +        "path": "lib/urllib3/util/ssltransport.py",
    +        "hash": "340faee6b313ac3143142f10cd129410a306d39eb584e0f8a814ebdd9e29bfa1"
    +      },
    +      {
    +        "path": "lib/urllib3/util/request.py",
    +        "hash": "7d688069af29c1d2cb22aa132c1c420b67b879df349aecca5377b71d6593cc54"
    +      },
    +      {
    +        "path": "lib/urllib3/util/queue.py",
    +        "hash": "9d1817f3f797fbf564bf1a17d3de905a8cfc3ecd101d4004c482c263fecf9dc3"
    +      },
    +      {
    +        "path": "lib/urllib3/util/connection.py",
    +        "hash": "e4bc760753d6dbd2b1067d93d3190dd420604416b780654904aa10a11a201159"
    +      },
    +      {
    +        "path": "lib/urllib3/util/url.py",
    +        "hash": "ce7a1813de25f32f922afd853d2fba57b1d54a850bb0130f60ad5613c18a3d41"
    +      },
    +      {
    +        "path": "lib/urllib3/util/ssl_.py",
    +        "hash": "734b188920badbbdabeae3e4c50a68e6b60f3fd402d5e47aa08ef4d38818a99a"
    +      },
    +      {
    +        "path": "lib/urllib3/util/response.py",
    +        "hash": "189a60dc4822f6a6895d1c01879c2ff8c36e4566a7e4122ee34a117a8c563f6f"
    +      },
    +      {
    +        "path": "lib/urllib3/util/retry.py",
    +        "hash": "e256968741e9c068a32e2066741218b5b8587a4427373ce1c765bdbb2b344470"
    +      },
    +      {
    +        "path": "lib/urllib3/util/wait.py",
    +        "hash": "7ce5f4fdf6a8cc6d8fee25688d0a04d666f277078dc93726fa15c47c5ad3b4b2"
    +      },
    +      {
    +        "path": "lib/urllib3/util/proxy.py",
    +        "hash": "cd4bcf3c226ba7a74e17437818055b39c97aa3ee2e5ca4ab1a24e492be6f512e"
    +      },
    +      {
    +        "path": "lib/urllib3/util/ssl_match_hostname.py",
    +        "hash": "22be1c65512398093c8140081d64a2ef0b4e3bcdd4098001636c450f5425fd60"
    +      },
    +      {
    +        "path": "lib/urllib3/util/timeout.py",
    +        "hash": "4126c150d381f7287a0270e7eb54ab2d0d21839a33d08f7eb97106f75009b888"
    +      },
    +      {
    +        "path": "lib/urllib3/exceptions.py",
    +        "hash": "d0c9e7a372874cd7d745f63beb7f0db9f38f9146fa9973a6f8baa3fb8c76c3c0"
    +      },
    +      {
    +        "path": "lib/urllib3/packages/__init__.py",
    +        "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    +      },
    +      {
    +        "path": "lib/urllib3/packages/backports/__init__.py",
    +        "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    +      },
    +      {
    +        "path": "lib/urllib3/packages/backports/makefile.py",
    +        "hash": "9dbcedde2d1a80f54fd3b8eaaa08e16988cc9ae022fd6e44d04cb0662bd53bc1"
    +      },
    +      {
    +        "path": "lib/urllib3/packages/six.py",
    +        "hash": "6fd2ccd30057bfb13b4ab6c28c09b8c3037e86b1fe88dc6fd7c2e058d30c28fa"
    +      },
    +      {
    +        "path": "lib/urllib3/poolmanager.py",
    +        "hash": "d0a38e2440a878b6158d41efbfed21e0eab7145410db26fe1678e46e3f2024ed"
    +      },
    +      {
    +        "path": "lib/urllib3/connection.py",
    +        "hash": "f3defac0beac19e54c5b42675efc79983d34c97bbceee423c6d07dfd52fc771f"
    +      },
    +      {
    +        "path": "lib/urllib3/contrib/__init__.py",
    +        "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    +      },
    +      {
    +        "path": "lib/urllib3/contrib/securetransport.py",
    +        "hash": "40e8556d6ac541329b995fafb721baf5a99e924295c5791d8e4f68ca668ed008"
    +      },
    +      {
    +        "path": "lib/urllib3/contrib/ntlmpool.py",
    +        "hash": "3657e45bb58c756f338aab9da298c7a16dbdf688350535a2d0878889baae1709"
    +      },
    +      {
    +        "path": "lib/urllib3/contrib/_securetransport/__init__.py",
    +        "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    +      },
    +      {
    +        "path": "lib/urllib3/contrib/_securetransport/low_level.py",
    +        "hash": "076241076fcd44fd36c4ae8309ad4f6bd22ec6b3f0c730f365b8b14246fb53d3"
    +      },
    +      {
    +        "path": "lib/urllib3/contrib/_securetransport/bindings.py",
    +        "hash": "e1793ae2a2243c1b74f40e6af9120552e0e135cf665e29556a99bb5a7627cd1c"
    +      },
    +      {
    +        "path": "lib/urllib3/contrib/_appengine_environ.py",
    +        "hash": "6c36f2384856d8228b25c42a00a032ac41cdf9a925b321c52aaeaf17c645b269"
    +      },
    +      {
    +        "path": "lib/urllib3/contrib/appengine.py",
    +        "hash": "e88056ea53cea155310123f0b67e881f50004dee432b794b2427f0c9694b2801"
    +      },
    +      {
    +        "path": "lib/urllib3/contrib/socks.py",
    +        "hash": "6918bd7965e8f5911bf795d4c5e7f8676d421659e78db122028f473ac7a832de"
    +      },
    +      {
    +        "path": "lib/urllib3/contrib/pyopenssl.py",
    +        "hash": "e00240968f4d9a35a87d8e1d27045ae246d9b91b877cd271bbc3efeb2424d6cb"
    +      },
    +      {
    +        "path": "lib/urllib3/filepost.py",
    +        "hash": "e5bfeaaa04475652fbb8bb5d018073061f861e653901f255b7fd8dd174b73de6"
    +      },
    +      {
    +        "path": "lib/urllib3/response.py",
    +        "hash": "50f80b9a71e3e33ef56671fc8af60eca77004e27d33b0f4542e914a839dc9027"
    +      },
    +      {
    +        "path": "lib/urllib3/fields.py",
    +        "hash": "92f2c30a0fc9987d652e3514118fc52d2f14858ee106f0cfb951136d8f2676b3"
    +      },
    +      {
    +        "path": "lib/urllib3/_collections.py",
    +        "hash": "469d6657206073f52501ca7a3376add6c909057479278dcd6b0453bd6da0fd76"
    +      },
    +      {
    +        "path": "lib/urllib3/connectionpool.py",
    +        "hash": "bd2e146872e847dff96862d7490efbeb2fe34f182aaa3c7462c8e4624b1618ea"
    +      },
    +      {
    +        "path": "lib/urllib3/_version.py",
    +        "hash": "25613ef81515cbbfbef45b1720b38d229438de2adfb4a1a34fd8f61ff7dd1763"
    +      },
    +      {
    +        "path": "lib/splunk_sdk-1.7.3.dist-info/WHEEL",
    +        "hash": "1b5e87e00dc87a84269cead8578b9e6462928e18a95f1f3373c9eef451a5bcc0"
    +      },
    +      {
    +        "path": "lib/splunk_sdk-1.7.3.dist-info/top_level.txt",
    +        "hash": "b5aab66187ce077d6d35e7f05bbdece78c72b6207fb32f1ba5bc8101f9f492bf"
    +      },
    +      {
    +        "path": "lib/splunk_sdk-1.7.3.dist-info/RECORD",
    +        "hash": "37e36340e7442191eda773e0175cfc3daf8b276bbd42788149f3ea27969da8bc"
    +      },
    +      {
    +        "path": "lib/splunk_sdk-1.7.3.dist-info/INSTALLER",
    +        "hash": "ceebae7b8927a3227e5303cf5e0f1f7b34bb542ad7250ac03fbcde36ec2f1508"
    +      },
    +      {
    +        "path": "lib/splunk_sdk-1.7.3.dist-info/METADATA",
    +        "hash": "fb1f0ea9c1ac6b5e06bee9d73167d9d4a59e6dcf3efd30d5f4ca2d31e0834be0"
    +      },
    +      {
    +        "path": "lib/solnlib/__init__.py",
    +        "hash": "2700f122c46a8a01d2de9df392f8685d5d929dbdf20d99f40f8691a48f20f225"
    +      },
    +      {
    +        "path": "lib/solnlib/modular_input/__init__.py",
    +        "hash": "967d0ba9fe7929f219503632eefcd03af0ba639fc9d6f492ecdd4acdb3b4e103"
    +      },
    +      {
    +        "path": "lib/solnlib/modular_input/modular_input.py",
    +        "hash": "b8ecf102e052199336773b2a66f0faa733c67b658f32d22cb2b480c939b611f5"
    +      },
    +      {
    +        "path": "lib/solnlib/modular_input/event_writer.py",
    +        "hash": "23ad520436634d7843301942a5ccb61d2584d3bcf00f0cd3075862171bc3073b"
    +      },
    +      {
    +        "path": "lib/solnlib/modular_input/event.py",
    +        "hash": "5e092540fc0f9894d19f5272390e8ac7538021fe9965f700f0d9ada852d6452b"
    +      },
    +      {
    +        "path": "lib/solnlib/modular_input/checkpointer.py",
    +        "hash": "f97db677792a62baa2c9e7f0de442d73f21e4130ea693c3488a73d65189c2e26"
    +      },
    +      {
    +        "path": "lib/solnlib/credentials.py",
    +        "hash": "f26af4b7f6f1cfcc0ab7f64888592a2b17240dac5186464a3f6438f011da843f"
    +      },
    +      {
    +        "path": "lib/solnlib/splunkenv.py",
    +        "hash": "1312fa174e1b0189124e7553a7e974904d721948b3cb0fd0f018326938ebc699"
    +      },
    +      {
    +        "path": "lib/solnlib/conf_manager.py",
    +        "hash": "ce9ccd484d68717ac15cf85dfbf662a6bda62dfecccb68b1e9ef48b4cb1dd3ca"
    +      },
    +      {
    +        "path": "lib/solnlib/splunk_rest_client.py",
    +        "hash": "5a79993c82b2d4f394e0dacf5d3dfbf6d6103b68e19ffce7cd4b0e5edbf98b08"
    +      },
    +      {
    +        "path": "lib/solnlib/time_parser.py",
    +        "hash": "5d0930e5e5a8e27cf92a6688bf9cf0f1d41db6ca93893dd19630d8c366982dae"
    +      },
    +      {
    +        "path": "lib/solnlib/hec_config.py",
    +        "hash": "d50b857ce9a9200a1f5550b636f0a8e07beb7bc60447b46102b8838ccbf4b032"
    +      },
    +      {
    +        "path": "lib/solnlib/acl.py",
    +        "hash": "58b7bb5fb94189a191b544aa3a650aab7f19d2432764bf7f7cfc795e75ddfc8e"
    +      },
    +      {
    +        "path": "lib/solnlib/server_info.py",
    +        "hash": "c60421fd936d1e6f649c25c940c3d955e9ae1b344afa15ce8ebb55f1655b7d53"
    +      },
    +      {
    +        "path": "lib/solnlib/timer_queue.py",
    +        "hash": "c33a995c9dbfdae297e113e992b89eed0672294e17ba812ffd40557e5f69b87c"
    +      },
    +      {
    +        "path": "lib/solnlib/_utils.py",
    +        "hash": "83c739b0b70a62db1d2437fcc5fb9f4317847f5e778455c0f379aac35ede36b8"
    +      },
    +      {
    +        "path": "lib/solnlib/user_access.py",
    +        "hash": "b1499802b3d184f024325b380146c11c3d0a9e2cf754415a358e8d3a844da547"
    +      },
    +      {
    +        "path": "lib/solnlib/pattern.py",
    +        "hash": "a016a1b63ef156558e69a2cf7aa76ba6e77abd5525d397e1c7aaf661493d21d2"
    +      },
    +      {
    +        "path": "lib/solnlib/log.py",
    +        "hash": "d74468f517e14c3ac3777eadfed79f1fd35750dba0471e6a3bf97e1036ce3f9d"
    +      },
    +      {
    +        "path": "lib/solnlib/net_utils.py",
    +        "hash": "8056a914a2f6aeb9ff5036a39bbe8d59afdd7c06282a3176c94aafdcbbc1e404"
    +      },
    +      {
    +        "path": "lib/solnlib/utils.py",
    +        "hash": "138105bb42d81cc13a6183036df88746759294da6da8636cbc6d8fed81277137"
    +      },
    +      {
    +        "path": "lib/solnlib/file_monitor.py",
    +        "hash": "2d10cd3ad171cfcdc021c5ab866a2b3cebf52685af8e977a02db8ce7fca77a6d"
    +      },
    +      {
    +        "path": "lib/solnlib/orphan_process_monitor.py",
    +        "hash": "7afa3cc8f1fabdda0a8e594df9c07a919864c0c902be1afe76b97ce7351700b6"
    +      },
    +      {
    +        "path": "lib/certifi-2022.12.7.dist-info/WHEEL",
    +        "hash": "7b0c04b9e8a8d42d977874ef4f5ee7f1d6542603afc82582b7459534b0a53fda"
    +      },
    +      {
    +        "path": "lib/certifi-2022.12.7.dist-info/top_level.txt",
    +        "hash": "28cbb8bd409fb232eb90f6d235d81d7a44bea552730402453bffe723c345ebe5"
    +      },
    +      {
    +        "path": "lib/certifi-2022.12.7.dist-info/LICENSE",
    +        "hash": "a02f6c638f9fb84d06f7764c3ab085d8af7eda5b93c166da54312479077c6fb0"
    +      },
    +      {
    +        "path": "lib/certifi-2022.12.7.dist-info/RECORD",
    +        "hash": "cc88057527e2af0f19217f4a50d58d2f81b0373f121138c24ff19e5ca6993295"
    +      },
    +      {
    +        "path": "lib/certifi-2022.12.7.dist-info/INSTALLER",
    +        "hash": "ceebae7b8927a3227e5303cf5e0f1f7b34bb542ad7250ac03fbcde36ec2f1508"
    +      },
    +      {
    +        "path": "lib/certifi-2022.12.7.dist-info/METADATA",
    +        "hash": "7211697312a108f110dddf3e573dfacebd8c89c7f579084a905164eff26f24da"
    +      },
    +      {
    +        "path": "lib/socks.py",
    +        "hash": "c4e627dbbb7d206adb4c1cd6b1452e3dad1806ea6582253293390e0795798856"
    +      },
    +      {
    +        "path": "README.md",
    +        "hash": "45dfaed171d22ebca41a942c3971590479068c8a56f2c8c977e05900ba5800f5"
    +      },
    +      {
    +        "path": "lookups/static_dictionary_VM_Linux.csv",
    +        "hash": "1971cf27e79ec8132d57feb463c557db0dfffb761b2d1da72a7563c546cbc163"
    +      },
    +      {
    +        "path": "lookups/nmon_metric_catalog.csv",
    +        "hash": "434ea0d00cb69144009bb074e55cfd04f141dcc870e777c2361e311525ed0c91"
    +      },
    +      {
    +        "path": "bin/import_declare_test.py",
    +        "hash": "5222b6c5846b54085c1fbfcf300044f17657a68c026b96e18ad6de502694a1d6"
    +      },
    +      {
    +        "path": "bin/metricator_for_nmon_rh_settings.py",
    +        "hash": "551d633368b0576e36e50dfa14b4c566510d02db5e928bdcab6116df1789216b"
    +      },
    +      {
    +        "path": "README.txt",
    +        "hash": "2c2fb77628c82e49229e0dab1162c52e1d524a3e64e868f36b149a8409981084"
    +      },
    +      {
    +        "path": "description.txt",
    +        "hash": "366905ba197d07a383e74165b60e8e8f449342a11e783e89f1329c766b1e24bf"
    +      },
    +      {
    +        "path": "README/metricator_for_nmon_settings.conf.spec",
    +        "hash": "c707e741136f261af65ed6ffe645e75e7c0b5cf5c3c92a8ff39bdec79cb9b51d"
    +      }
    +    ]
    +  },
    +  "products": [
    +    {
    +      "platform": "splunk",
    +      "product": "enterprise",
    +      "versions": [
    +        "8.1",
    +        "8.2",
    +        "9.0"
    +      ],
    +      "architectures": [
    +        "x86_64"
    +      ],
    +      "operatingSystems": [
    +        "windows",
    +        "linux",
    +        "macos",
    +        "freebsd",
    +        "solaris",
    +        "aix"
    +      ]
    +    },
    +    {
    +      "platform": "splunk",
    +      "product": "cloud",
    +      "versions": [
    +        "8.1",
    +        "8.2",
    +        "9.0"
    +      ],
    +      "architectures": [
    +        "x86_64"
    +      ],
    +      "operatingSystems": [
    +        "windows",
    +        "linux",
    +        "macos",
    +        "freebsd",
    +        "solaris",
    +        "aix"
    +      ]
    +    }
    +  ]
    +}
    \ No newline at end of file
    diff --git a/deployment-apps/metricator-for-nmon/static/appIcon.png b/deployment-apps/metricator-for-nmon/static/appIcon.png
    new file mode 100644
    index 0000000..e6f0df4
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/static/appIcon.png differ
    diff --git a/deployment-apps/metricator-for-nmon/static/appIconAlt.png b/deployment-apps/metricator-for-nmon/static/appIconAlt.png
    new file mode 100644
    index 0000000..2125d7a
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/static/appIconAlt.png differ
    diff --git a/deployment-apps/metricator-for-nmon/static/appIconAlt_2x.png b/deployment-apps/metricator-for-nmon/static/appIconAlt_2x.png
    new file mode 100644
    index 0000000..c9c5131
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/static/appIconAlt_2x.png differ
    diff --git a/deployment-apps/metricator-for-nmon/static/appIcon_2x.png b/deployment-apps/metricator-for-nmon/static/appIcon_2x.png
    new file mode 100644
    index 0000000..71c9026
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/static/appIcon_2x.png differ
    diff --git a/deployment-apps/metricator-for-nmon/static/appLogo.png b/deployment-apps/metricator-for-nmon/static/appLogo.png
    new file mode 100644
    index 0000000..0182627
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/static/appLogo.png differ
    diff --git a/deployment-apps/metricator-for-nmon/static/appLogo_2x.png b/deployment-apps/metricator-for-nmon/static/appLogo_2x.png
    new file mode 100644
    index 0000000..4c983b9
    Binary files /dev/null and b/deployment-apps/metricator-for-nmon/static/appLogo_2x.png differ